Completed
Push — master ( c7757e...39cb21 )
by Luís
16s
created

lib/Doctrine/DBAL/Schema/AbstractAsset.php (2 issues)

1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\DBAL\Schema;
21
22
use Doctrine\DBAL\Platforms\AbstractPlatform;
23
24
/**
25
 * The abstract asset allows to reset the name of all assets without publishing this to the public userland.
26
 *
27
 * This encapsulation hack is necessary to keep a consistent state of the database schema. Say we have a list of tables
28
 * array($tableName => Table($tableName)); if you want to rename the table, you have to make sure
29
 *
30
 * @link   www.doctrine-project.org
31
 * @since  2.0
32
 * @author Benjamin Eberlei <[email protected]>
33
 */
34
abstract class AbstractAsset
35
{
36
    /**
37
     * @var string
38
     */
39
    protected $_name;
40
41
    /**
42
     * Namespace of the asset. If none isset the default namespace is assumed.
43
     *
44
     * @var string|null
45
     */
46
    protected $_namespace = null;
47
48
    /**
49
     * @var boolean
50
     */
51
    protected $_quoted = false;
52
53
    /**
54
     * Sets the name of this asset.
55
     *
56
     * @param string $name
57
     *
58
     * @return void
59
     */
60 1218
    protected function _setName($name)
61
    {
62 1218
        if ($this->isIdentifierQuoted($name)) {
63 215
            $this->_quoted = true;
64 215
            $name = $this->trimQuotes($name);
65
        }
66 1218
        if (strpos($name, ".") !== false) {
67 49
            $parts = explode(".", $name);
68 49
            $this->_namespace = $parts[0];
69 49
            $name = $parts[1];
70
        }
71 1218
        $this->_name = $name;
72 1218
    }
73
74
    /**
75
     * Is this asset in the default namespace?
76
     *
77
     * @param string $defaultNamespaceName
78
     *
79
     * @return boolean
80
     */
81 62
    public function isInDefaultNamespace($defaultNamespaceName)
82
    {
83 62
        return $this->_namespace == $defaultNamespaceName || $this->_namespace === null;
84
    }
85
86
    /**
87
     * Gets the namespace name of this asset.
88
     *
89
     * If NULL is returned this means the default namespace is used.
90
     *
91
     * @return string|null
92
     */
93 65
    public function getNamespaceName()
94
    {
95 65
        return $this->_namespace;
96
    }
97
98
    /**
99
     * The shortest name is stripped of the default namespace. All other
100
     * namespaced elements are returned as full-qualified names.
101
     *
102
     * @param string $defaultNamespaceName
103
     *
104
     * @return string
105
     */
106 29
    public function getShortestName($defaultNamespaceName)
107
    {
108 29
        $shortestName = $this->getName();
109 29
        if ($this->_namespace == $defaultNamespaceName) {
110 7
            $shortestName = $this->_name;
111
        }
112
113 29
        return strtolower($shortestName);
114
    }
115
116
    /**
117
     * The normalized name is full-qualified and lowerspaced. Lowerspacing is
118
     * actually wrong, but we have to do it to keep our sanity. If you are
119
     * using database objects that only differentiate in the casing (FOO vs
120
     * Foo) then you will NOT be able to use Doctrine Schema abstraction.
121
     *
122
     * Every non-namespaced element is prefixed with the default namespace
123
     * name which is passed as argument to this method.
124
     *
125
     * @param string $defaultNamespaceName
126
     *
127
     * @return string
128
     */
129 63
    public function getFullQualifiedName($defaultNamespaceName)
130
    {
131 63
        $name = $this->getName();
132 63
        if ( ! $this->_namespace) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->_namespace of type null|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
133 60
            $name = $defaultNamespaceName . "." . $name;
134
        }
135
136 63
        return strtolower($name);
137
    }
138
139
    /**
140
     * Checks if this asset's name is quoted.
141
     *
142
     * @return boolean
143
     */
144 37
    public function isQuoted()
145
    {
146 37
        return $this->_quoted;
147
    }
148
149
    /**
150
     * Checks if this identifier is quoted.
151
     *
152
     * @param string $identifier
153
     *
154
     * @return boolean
155
     */
156 1218
    protected function isIdentifierQuoted($identifier)
157
    {
158 1218
        return (isset($identifier[0]) && ($identifier[0] == '`' || $identifier[0] == '"' || $identifier[0] == '['));
159
    }
160
161
    /**
162
     * Trim quotes from the identifier.
163
     *
164
     * @param string $identifier
165
     *
166
     * @return string
167
     */
168 713
    protected function trimQuotes($identifier)
169
    {
170 713
        return str_replace(['`', '"', '[', ']'], '', $identifier);
171
    }
172
173
    /**
174
     * Returns the name of this schema asset.
175
     *
176
     * @return string
177
     */
178 1136
    public function getName()
179
    {
180 1136
        if ($this->_namespace) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->_namespace of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
181 49
            return $this->_namespace . "." . $this->_name;
182
        }
183
184 1133
        return $this->_name;
185
    }
186
187
    /**
188
     * Gets the quoted representation of this asset but only if it was defined with one. Otherwise
189
     * return the plain unquoted value as inserted.
190
     *
191
     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
192
     *
193
     * @return string
194
     */
195 940
    public function getQuotedName(AbstractPlatform $platform)
196
    {
197 940
        $keywords = $platform->getReservedKeywordsList();
198 940
        $parts = explode(".", $this->getName());
199 940
        foreach ($parts as $k => $v) {
200 940
            $parts[$k] = ($this->_quoted || $keywords->isKeyword($v)) ? $platform->quoteIdentifier($v) : $v;
201
        }
202
203 940
        return implode(".", $parts);
204
    }
205
206
    /**
207
     * Generates an identifier from a list of column names obeying a certain string length.
208
     *
209
     * This is especially important for Oracle, since it does not allow identifiers larger than 30 chars,
210
     * however building idents automatically for foreign keys, composite keys or such can easily create
211
     * very long names.
212
     *
213
     * @param array   $columnNames
214
     * @param string  $prefix
215
     * @param integer $maxSize
216
     *
217
     * @return string
218
     */
219
    protected function _generateIdentifierName($columnNames, $prefix='', $maxSize=30)
220
    {
221 144
        $hash = implode("", array_map(function ($column) {
222 144
            return dechex(crc32($column));
223 144
        }, $columnNames));
224
225
        return substr(strtoupper($prefix . "_" . $hash), 0, $maxSize);
226
    }
227
}
228