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\DBALException; |
||||
23 | use Doctrine\DBAL\Types\StringType; |
||||
24 | use Doctrine\DBAL\Types\TextType; |
||||
25 | use Doctrine\DBAL\Types\Type; |
||||
26 | |||||
27 | /** |
||||
28 | * Sqlite SchemaManager. |
||||
29 | * |
||||
30 | * @author Konsta Vesterinen <[email protected]> |
||||
31 | * @author Lukas Smith <[email protected]> (PEAR MDB2 library) |
||||
32 | * @author Jonathan H. Wage <[email protected]> |
||||
33 | * @author Martin Hasoň <[email protected]> |
||||
34 | * @since 2.0 |
||||
35 | */ |
||||
36 | class SqliteSchemaManager extends AbstractSchemaManager |
||||
37 | { |
||||
38 | /** |
||||
39 | * {@inheritdoc} |
||||
40 | */ |
||||
41 | 2 | public function dropDatabase($database) |
|||
42 | { |
||||
43 | 2 | if (file_exists($database)) { |
|||
44 | 2 | unlink($database); |
|||
45 | } |
||||
46 | 2 | } |
|||
47 | |||||
48 | /** |
||||
49 | * {@inheritdoc} |
||||
50 | */ |
||||
51 | 2 | public function createDatabase($database) |
|||
52 | { |
||||
53 | 2 | $params = $this->_conn->getParams(); |
|||
54 | 2 | $driver = $params['driver']; |
|||
55 | $options = [ |
||||
56 | 2 | 'driver' => $driver, |
|||
57 | 2 | 'path' => $database |
|||
58 | ]; |
||||
59 | 2 | $conn = \Doctrine\DBAL\DriverManager::getConnection($options); |
|||
60 | 2 | $conn->connect(); |
|||
61 | 2 | $conn->close(); |
|||
62 | 2 | } |
|||
63 | |||||
64 | /** |
||||
65 | * {@inheritdoc} |
||||
66 | */ |
||||
67 | 1 | public function renameTable($name, $newName) |
|||
68 | { |
||||
69 | 1 | $tableDiff = new TableDiff($name); |
|||
70 | 1 | $tableDiff->fromTable = $this->listTableDetails($name); |
|||
71 | 1 | $tableDiff->newName = $newName; |
|||
72 | 1 | $this->alterTable($tableDiff); |
|||
73 | 1 | } |
|||
74 | |||||
75 | /** |
||||
76 | * {@inheritdoc} |
||||
77 | */ |
||||
78 | public function createForeignKey(ForeignKeyConstraint $foreignKey, $table) |
||||
79 | { |
||||
80 | $tableDiff = $this->getTableDiffForAlterForeignKey($foreignKey, $table); |
||||
81 | $tableDiff->addedForeignKeys[] = $foreignKey; |
||||
82 | |||||
83 | $this->alterTable($tableDiff); |
||||
84 | } |
||||
85 | |||||
86 | /** |
||||
87 | * {@inheritdoc} |
||||
88 | */ |
||||
89 | public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table) |
||||
90 | { |
||||
91 | $tableDiff = $this->getTableDiffForAlterForeignKey($foreignKey, $table); |
||||
92 | $tableDiff->changedForeignKeys[] = $foreignKey; |
||||
93 | |||||
94 | $this->alterTable($tableDiff); |
||||
95 | } |
||||
96 | |||||
97 | /** |
||||
98 | * {@inheritdoc} |
||||
99 | */ |
||||
100 | public function dropForeignKey($foreignKey, $table) |
||||
101 | { |
||||
102 | $tableDiff = $this->getTableDiffForAlterForeignKey($foreignKey, $table); |
||||
103 | $tableDiff->removedForeignKeys[] = $foreignKey; |
||||
104 | |||||
105 | $this->alterTable($tableDiff); |
||||
106 | } |
||||
107 | |||||
108 | /** |
||||
109 | * {@inheritdoc} |
||||
110 | */ |
||||
111 | 1 | public function listTableForeignKeys($table, $database = null) |
|||
112 | { |
||||
113 | 1 | if (null === $database) { |
|||
114 | 1 | $database = $this->_conn->getDatabase(); |
|||
115 | } |
||||
116 | 1 | $sql = $this->_platform->getListTableForeignKeysSQL($table, $database); |
|||
0 ignored issues
–
show
|
|||||
117 | 1 | $tableForeignKeys = $this->_conn->fetchAll($sql); |
|||
118 | |||||
119 | 1 | if ( ! empty($tableForeignKeys)) { |
|||
120 | 1 | $createSql = $this->_conn->fetchAll("SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE type = 'table' AND name = '$table'"); |
|||
121 | 1 | $createSql = isset($createSql[0]['sql']) ? $createSql[0]['sql'] : ''; |
|||
122 | |||||
123 | 1 | if (preg_match_all('# |
|||
124 | (?:CONSTRAINT\s+([^\s]+)\s+)? |
||||
125 | (?:FOREIGN\s+KEY[^\)]+\)\s*)? |
||||
126 | REFERENCES\s+[^\s]+\s+(?:\([^\)]+\))? |
||||
127 | (?: |
||||
128 | [^,]*? |
||||
129 | (NOT\s+DEFERRABLE|DEFERRABLE) |
||||
130 | (?:\s+INITIALLY\s+(DEFERRED|IMMEDIATE))? |
||||
131 | )?#isx', |
||||
132 | 1 | $createSql, $match)) { |
|||
133 | |||||
134 | 1 | $names = array_reverse($match[1]); |
|||
135 | 1 | $deferrable = array_reverse($match[2]); |
|||
136 | 1 | $deferred = array_reverse($match[3]); |
|||
137 | } else { |
||||
138 | $names = $deferrable = $deferred = []; |
||||
139 | } |
||||
140 | |||||
141 | 1 | foreach ($tableForeignKeys as $key => $value) { |
|||
142 | 1 | $id = $value['id']; |
|||
143 | 1 | $tableForeignKeys[$key]['constraint_name'] = isset($names[$id]) && '' != $names[$id] ? $names[$id] : $id; |
|||
144 | 1 | $tableForeignKeys[$key]['deferrable'] = isset($deferrable[$id]) && 'deferrable' == strtolower($deferrable[$id]) ? true : false; |
|||
145 | 1 | $tableForeignKeys[$key]['deferred'] = isset($deferred[$id]) && 'deferred' == strtolower($deferred[$id]) ? true : false; |
|||
146 | } |
||||
147 | } |
||||
148 | |||||
149 | 1 | return $this->_getPortableTableForeignKeysList($tableForeignKeys); |
|||
150 | } |
||||
151 | |||||
152 | /** |
||||
153 | * {@inheritdoc} |
||||
154 | */ |
||||
155 | 57 | protected function _getPortableTableDefinition($table) |
|||
156 | { |
||||
157 | 57 | return $table['name']; |
|||
158 | } |
||||
159 | |||||
160 | /** |
||||
161 | * {@inheritdoc} |
||||
162 | * |
||||
163 | * @license New BSD License |
||||
164 | * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html |
||||
165 | */ |
||||
166 | 33 | protected function _getPortableTableIndexesList($tableIndexes, $tableName=null) |
|||
167 | { |
||||
168 | 33 | $indexBuffer = []; |
|||
169 | |||||
170 | // fetch primary |
||||
171 | 33 | $stmt = $this->_conn->executeQuery("PRAGMA TABLE_INFO ('$tableName')"); |
|||
172 | 33 | $indexArray = $stmt->fetchAll(\PDO::FETCH_ASSOC); |
|||
173 | |||||
174 | 33 | usort($indexArray, function($a, $b) { |
|||
175 | 22 | if ($a['pk'] == $b['pk']) { |
|||
176 | 18 | return $a['cid'] - $b['cid']; |
|||
177 | } |
||||
178 | |||||
179 | 12 | return $a['pk'] - $b['pk']; |
|||
180 | 33 | }); |
|||
181 | 33 | foreach ($indexArray as $indexColumnRow) { |
|||
182 | 33 | if ($indexColumnRow['pk'] != "0") { |
|||
183 | 21 | $indexBuffer[] = [ |
|||
184 | 21 | 'key_name' => 'primary', |
|||
185 | 'primary' => true, |
||||
186 | 'non_unique' => false, |
||||
187 | 33 | 'column_name' => $indexColumnRow['name'] |
|||
188 | ]; |
||||
189 | } |
||||
190 | } |
||||
191 | |||||
192 | // fetch regular indexes |
||||
193 | 33 | foreach ($tableIndexes as $tableIndex) { |
|||
194 | // Ignore indexes with reserved names, e.g. autoindexes |
||||
195 | 8 | if (strpos($tableIndex['name'], 'sqlite_') !== 0) { |
|||
196 | 6 | $keyName = $tableIndex['name']; |
|||
197 | 6 | $idx = []; |
|||
198 | 6 | $idx['key_name'] = $keyName; |
|||
199 | 6 | $idx['primary'] = false; |
|||
200 | 6 | $idx['non_unique'] = $tableIndex['unique']?false:true; |
|||
201 | |||||
202 | 6 | $stmt = $this->_conn->executeQuery("PRAGMA INDEX_INFO ('{$keyName}')"); |
|||
203 | 6 | $indexArray = $stmt->fetchAll(\PDO::FETCH_ASSOC); |
|||
204 | |||||
205 | 6 | foreach ($indexArray as $indexColumnRow) { |
|||
206 | 6 | $idx['column_name'] = $indexColumnRow['name']; |
|||
207 | 8 | $indexBuffer[] = $idx; |
|||
208 | } |
||||
209 | } |
||||
210 | } |
||||
211 | |||||
212 | 33 | return parent::_getPortableTableIndexesList($indexBuffer, $tableName); |
|||
213 | } |
||||
214 | |||||
215 | /** |
||||
216 | * {@inheritdoc} |
||||
217 | */ |
||||
218 | protected function _getPortableTableIndexDefinition($tableIndex) |
||||
219 | { |
||||
220 | return [ |
||||
221 | 'name' => $tableIndex['name'], |
||||
222 | 'unique' => (bool) $tableIndex['unique'] |
||||
223 | ]; |
||||
224 | } |
||||
225 | |||||
226 | /** |
||||
227 | * {@inheritdoc} |
||||
228 | */ |
||||
229 | 40 | protected function _getPortableTableColumnList($table, $database, $tableColumns) |
|||
230 | { |
||||
231 | 40 | $list = parent::_getPortableTableColumnList($table, $database, $tableColumns); |
|||
232 | |||||
233 | // find column with autoincrement |
||||
234 | 40 | $autoincrementColumn = null; |
|||
235 | 40 | $autoincrementCount = 0; |
|||
236 | |||||
237 | 40 | foreach ($tableColumns as $tableColumn) { |
|||
238 | 40 | if ('0' != $tableColumn['pk']) { |
|||
239 | 24 | $autoincrementCount++; |
|||
240 | 24 | if (null === $autoincrementColumn && 'integer' == strtolower($tableColumn['type'])) { |
|||
241 | 40 | $autoincrementColumn = $tableColumn['name']; |
|||
242 | } |
||||
243 | } |
||||
244 | } |
||||
245 | |||||
246 | 40 | if (1 == $autoincrementCount && null !== $autoincrementColumn) { |
|||
247 | 23 | foreach ($list as $column) { |
|||
248 | 23 | if ($autoincrementColumn == $column->getName()) { |
|||
249 | 23 | $column->setAutoincrement(true); |
|||
250 | } |
||||
251 | } |
||||
252 | } |
||||
253 | |||||
254 | // inspect column collation and comments |
||||
255 | 40 | $createSql = $this->_conn->fetchAll("SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE type = 'table' AND name = '$table'"); |
|||
256 | 40 | $createSql = isset($createSql[0]['sql']) ? $createSql[0]['sql'] : ''; |
|||
257 | |||||
258 | 40 | foreach ($list as $columnName => $column) { |
|||
259 | 40 | $type = $column->getType(); |
|||
260 | |||||
261 | 40 | if ($type instanceof StringType || $type instanceof TextType) { |
|||
262 | 16 | $column->setPlatformOption('collation', $this->parseColumnCollationFromSQL($columnName, $createSql) ?: 'BINARY'); |
|||
263 | } |
||||
264 | |||||
265 | 40 | $comment = $this->parseColumnCommentFromSQL($columnName, $createSql); |
|||
266 | |||||
267 | 40 | if (false !== $comment) { |
|||
268 | 16 | $type = $this->extractDoctrineTypeFromComment($comment, null); |
|||
269 | |||||
270 | 16 | if (null !== $type) { |
|||
271 | 4 | $column->setType(Type::getType($type)); |
|||
272 | |||||
273 | 4 | $comment = $this->removeDoctrineTypeFromComment($comment, $type); |
|||
274 | } |
||||
275 | |||||
276 | 40 | $column->setComment($comment); |
|||
277 | } |
||||
278 | } |
||||
279 | |||||
280 | 40 | return $list; |
|||
281 | } |
||||
282 | |||||
283 | /** |
||||
284 | * {@inheritdoc} |
||||
285 | */ |
||||
286 | 40 | protected function _getPortableTableColumnDefinition($tableColumn) |
|||
287 | { |
||||
288 | 40 | $parts = explode('(', $tableColumn['type']); |
|||
289 | 40 | $tableColumn['type'] = trim($parts[0]); |
|||
290 | 40 | if (isset($parts[1])) { |
|||
291 | 12 | $length = trim($parts[1], ')'); |
|||
292 | 12 | $tableColumn['length'] = $length; |
|||
293 | } |
||||
294 | |||||
295 | 40 | $dbType = strtolower($tableColumn['type']); |
|||
296 | 40 | $length = isset($tableColumn['length']) ? $tableColumn['length'] : null; |
|||
297 | 40 | $unsigned = false; |
|||
298 | |||||
299 | 40 | if (strpos($dbType, ' unsigned') !== false) { |
|||
300 | 1 | $dbType = str_replace(' unsigned', '', $dbType); |
|||
301 | 1 | $unsigned = true; |
|||
302 | } |
||||
303 | |||||
304 | 40 | $fixed = false; |
|||
305 | 40 | $type = $this->_platform->getDoctrineTypeMapping($dbType); |
|||
306 | 40 | $default = $tableColumn['dflt_value']; |
|||
307 | 40 | if ($default == 'NULL') { |
|||
308 | 4 | $default = null; |
|||
309 | } |
||||
310 | 40 | if ($default !== null) { |
|||
311 | // SQLite returns strings wrapped in single quotes, so we need to strip them |
||||
312 | 6 | $default = preg_replace("/^'(.*)'$/", '\1', $default); |
|||
313 | } |
||||
314 | 40 | $notnull = (bool) $tableColumn['notnull']; |
|||
315 | |||||
316 | 40 | if ( ! isset($tableColumn['name'])) { |
|||
317 | $tableColumn['name'] = ''; |
||||
318 | } |
||||
319 | |||||
320 | 40 | $precision = null; |
|||
321 | 40 | $scale = null; |
|||
322 | |||||
323 | switch ($dbType) { |
||||
324 | 40 | case 'char': |
|||
325 | 4 | $fixed = true; |
|||
326 | 4 | break; |
|||
327 | 39 | case 'float': |
|||
328 | 39 | case 'double': |
|||
329 | 39 | case 'real': |
|||
330 | 39 | case 'decimal': |
|||
331 | 39 | case 'numeric': |
|||
332 | 4 | if (isset($tableColumn['length'])) { |
|||
333 | 4 | if (strpos($tableColumn['length'], ',') === false) { |
|||
334 | $tableColumn['length'] .= ",0"; |
||||
335 | } |
||||
336 | 4 | list($precision, $scale) = array_map('trim', explode(',', $tableColumn['length'])); |
|||
337 | } |
||||
338 | 4 | $length = null; |
|||
339 | 4 | break; |
|||
340 | } |
||||
341 | |||||
342 | $options = [ |
||||
343 | 40 | 'length' => $length, |
|||
344 | 40 | 'unsigned' => (bool) $unsigned, |
|||
345 | 40 | 'fixed' => $fixed, |
|||
346 | 40 | 'notnull' => $notnull, |
|||
347 | 40 | 'default' => $default, |
|||
348 | 40 | 'precision' => $precision, |
|||
349 | 40 | 'scale' => $scale, |
|||
350 | 'autoincrement' => false, |
||||
351 | ]; |
||||
352 | |||||
353 | 40 | return new Column($tableColumn['name'], \Doctrine\DBAL\Types\Type::getType($type), $options); |
|||
354 | } |
||||
355 | |||||
356 | /** |
||||
357 | * {@inheritdoc} |
||||
358 | */ |
||||
359 | 1 | protected function _getPortableViewDefinition($view) |
|||
360 | { |
||||
361 | 1 | return new View($view['name'], $view['sql']); |
|||
362 | } |
||||
363 | |||||
364 | /** |
||||
365 | * {@inheritdoc} |
||||
366 | */ |
||||
367 | 1 | protected function _getPortableTableForeignKeysList($tableForeignKeys) |
|||
368 | { |
||||
369 | 1 | $list = []; |
|||
370 | 1 | foreach ($tableForeignKeys as $value) { |
|||
371 | 1 | $value = array_change_key_case($value, CASE_LOWER); |
|||
372 | 1 | $name = $value['constraint_name']; |
|||
373 | 1 | if ( ! isset($list[$name])) { |
|||
374 | 1 | if ( ! isset($value['on_delete']) || $value['on_delete'] == "RESTRICT") { |
|||
375 | $value['on_delete'] = null; |
||||
376 | } |
||||
377 | 1 | if ( ! isset($value['on_update']) || $value['on_update'] == "RESTRICT") { |
|||
378 | $value['on_update'] = null; |
||||
379 | } |
||||
380 | |||||
381 | 1 | $list[$name] = [ |
|||
382 | 1 | 'name' => $name, |
|||
383 | 'local' => [], |
||||
384 | 'foreign' => [], |
||||
385 | 1 | 'foreignTable' => $value['table'], |
|||
386 | 1 | 'onDelete' => $value['on_delete'], |
|||
387 | 1 | 'onUpdate' => $value['on_update'], |
|||
388 | 1 | 'deferrable' => $value['deferrable'], |
|||
389 | 1 | 'deferred'=> $value['deferred'], |
|||
390 | ]; |
||||
391 | } |
||||
392 | 1 | $list[$name]['local'][] = $value['from']; |
|||
393 | 1 | $list[$name]['foreign'][] = $value['to']; |
|||
394 | } |
||||
395 | |||||
396 | 1 | $result = []; |
|||
397 | 1 | foreach ($list as $constraint) { |
|||
398 | 1 | $result[] = new ForeignKeyConstraint( |
|||
399 | 1 | array_values($constraint['local']), $constraint['foreignTable'], |
|||
400 | 1 | array_values($constraint['foreign']), $constraint['name'], |
|||
401 | [ |
||||
402 | 1 | 'onDelete' => $constraint['onDelete'], |
|||
403 | 1 | 'onUpdate' => $constraint['onUpdate'], |
|||
404 | 1 | 'deferrable' => $constraint['deferrable'], |
|||
405 | 1 | 'deferred'=> $constraint['deferred'], |
|||
406 | ] |
||||
407 | ); |
||||
408 | } |
||||
409 | |||||
410 | 1 | return $result; |
|||
411 | } |
||||
412 | |||||
413 | /** |
||||
414 | * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey |
||||
415 | * @param \Doctrine\DBAL\Schema\Table|string $table |
||||
416 | * |
||||
417 | * @return \Doctrine\DBAL\Schema\TableDiff |
||||
418 | * |
||||
419 | * @throws \Doctrine\DBAL\DBALException |
||||
420 | */ |
||||
421 | private function getTableDiffForAlterForeignKey(ForeignKeyConstraint $foreignKey, $table) |
||||
0 ignored issues
–
show
The parameter
$foreignKey is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.
Loading history...
|
|||||
422 | { |
||||
423 | if ( ! $table instanceof Table) { |
||||
424 | $tableDetails = $this->tryMethod('listTableDetails', $table); |
||||
425 | if (false === $table) { |
||||
426 | throw new DBALException(sprintf('Sqlite schema manager requires to modify foreign keys table definition "%s".', $table)); |
||||
427 | } |
||||
428 | |||||
429 | $table = $tableDetails; |
||||
430 | } |
||||
431 | |||||
432 | $tableDiff = new TableDiff($table->getName()); |
||||
433 | $tableDiff->fromTable = $table; |
||||
0 ignored issues
–
show
It seems like
$table can also be of type false . However, the property $fromTable is declared as type Doctrine\DBAL\Schema\Table . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
Loading history...
|
|||||
434 | |||||
435 | return $tableDiff; |
||||
436 | } |
||||
437 | |||||
438 | /** |
||||
439 | * @param string $column |
||||
440 | * @param string $sql |
||||
441 | * |
||||
442 | * @return string|false |
||||
443 | */ |
||||
444 | 21 | private function parseColumnCollationFromSQL($column, $sql) |
|||
445 | { |
||||
446 | 21 | if (preg_match( |
|||
447 | 21 | '{(?:'.preg_quote($column).'|'.preg_quote($this->_platform->quoteSingleIdentifier($column)).') |
|||
448 | [^,(]+(?:\([^()]+\)[^,]*)? |
||||
449 | (?:(?:DEFAULT|CHECK)\s*(?:\(.*?\))?[^,]*)* |
||||
450 | 21 | COLLATE\s+["\']?([^\s,"\')]+)}isx', $sql, $match)) { |
|||
451 | 7 | return $match[1]; |
|||
452 | } |
||||
453 | |||||
454 | 17 | return false; |
|||
455 | } |
||||
456 | |||||
457 | /** |
||||
458 | * @param string $column |
||||
459 | * @param string $sql |
||||
460 | * |
||||
461 | * @return string|false |
||||
462 | */ |
||||
463 | 40 | private function parseColumnCommentFromSQL($column, $sql) |
|||
464 | { |
||||
465 | 40 | if (preg_match( |
|||
466 | 40 | '{[\s(,](?:'.preg_quote($this->_platform->quoteSingleIdentifier($column)).'|'.preg_quote($column).') |
|||
467 | (?:\(.*?\)|[^,(])*?,?((?:\s*--[^\n]*\n?)+) |
||||
468 | 40 | }isx', $sql, $match |
|||
469 | )) { |
||||
470 | 16 | $comment = preg_replace('{^\s*--}m', '', rtrim($match[1], "\n")); |
|||
471 | |||||
472 | 16 | return '' === $comment ? false : $comment; |
|||
473 | } |
||||
474 | |||||
475 | 35 | return false; |
|||
476 | } |
||||
477 | } |
||||
478 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.