doctrine /
dbal
| 1 | <?php |
||
| 2 | |||
| 3 | declare(strict_types=1); |
||
| 4 | |||
| 5 | namespace Doctrine\DBAL\Schema; |
||
| 6 | |||
| 7 | use Doctrine\DBAL\DriverManager; |
||
| 8 | use Doctrine\DBAL\FetchMode; |
||
| 9 | use Doctrine\DBAL\Types\StringType; |
||
| 10 | use Doctrine\DBAL\Types\TextType; |
||
| 11 | use Doctrine\DBAL\Types\Type; |
||
| 12 | use function array_change_key_case; |
||
| 13 | use function array_reverse; |
||
| 14 | use function array_values; |
||
| 15 | use function assert; |
||
| 16 | use function count; |
||
| 17 | use function file_exists; |
||
| 18 | use function is_string; |
||
| 19 | use function preg_match; |
||
| 20 | use function preg_match_all; |
||
| 21 | use function preg_quote; |
||
| 22 | use function preg_replace; |
||
| 23 | use function rtrim; |
||
| 24 | use function sprintf; |
||
| 25 | use function str_replace; |
||
| 26 | use function strpos; |
||
| 27 | use function strtolower; |
||
| 28 | use function trim; |
||
| 29 | use function unlink; |
||
| 30 | use function usort; |
||
| 31 | use const CASE_LOWER; |
||
| 32 | |||
| 33 | /** |
||
| 34 | * Sqlite SchemaManager. |
||
| 35 | */ |
||
| 36 | class SqliteSchemaManager extends AbstractSchemaManager |
||
| 37 | { |
||
| 38 | 2 | public function dropDatabase(string $database) : void |
|
| 39 | { |
||
| 40 | 2 | if (! file_exists($database)) { |
|
| 41 | 1 | return; |
|
| 42 | } |
||
| 43 | |||
| 44 | 2 | unlink($database); |
|
| 45 | 2 | } |
|
| 46 | |||
| 47 | 2 | public function createDatabase(string $database) : void |
|
| 48 | { |
||
| 49 | 2 | $params = $this->_conn->getParams(); |
|
| 50 | 2 | $driver = $params['driver']; |
|
| 51 | $options = [ |
||
| 52 | 2 | 'driver' => $driver, |
|
| 53 | 2 | 'path' => $database, |
|
| 54 | ]; |
||
| 55 | 2 | $conn = DriverManager::getConnection($options); |
|
| 56 | 2 | $conn->connect(); |
|
| 57 | 2 | $conn->close(); |
|
| 58 | 2 | } |
|
| 59 | |||
| 60 | 1 | public function renameTable(string $name, string $newName) : void |
|
| 61 | { |
||
| 62 | 1 | $tableDiff = new TableDiff($name); |
|
| 63 | 1 | $tableDiff->fromTable = $this->listTableDetails($name); |
|
| 64 | 1 | $tableDiff->newName = $newName; |
|
| 65 | 1 | $this->alterTable($tableDiff); |
|
| 66 | 1 | } |
|
| 67 | |||
| 68 | /** |
||
| 69 | * {@inheritdoc} |
||
| 70 | */ |
||
| 71 | 2 | public function createForeignKey(ForeignKeyConstraint $foreignKey, $table) : void |
|
| 72 | { |
||
| 73 | 2 | $table = $this->ensureTable($table); |
|
| 74 | |||
| 75 | 2 | $tableDiff = $this->getTableDiffForAlterForeignKey($table); |
|
| 76 | |||
| 77 | 2 | $tableDiff->addedForeignKeys[] = $foreignKey; |
|
| 78 | |||
| 79 | 2 | $this->alterTable($tableDiff); |
|
| 80 | 2 | } |
|
| 81 | |||
| 82 | /** |
||
| 83 | * {@inheritdoc} |
||
| 84 | */ |
||
| 85 | public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table) : void |
||
| 86 | { |
||
| 87 | $table = $this->ensureTable($table); |
||
| 88 | |||
| 89 | $tableDiff = $this->getTableDiffForAlterForeignKey($table); |
||
| 90 | |||
| 91 | $tableDiff->changedForeignKeys[] = $foreignKey; |
||
| 92 | |||
| 93 | $this->alterTable($tableDiff); |
||
| 94 | } |
||
| 95 | |||
| 96 | /** |
||
| 97 | * {@inheritdoc} |
||
| 98 | */ |
||
| 99 | public function dropForeignKey($foreignKey, $table) : void |
||
| 100 | { |
||
| 101 | $table = $this->ensureTable($table); |
||
| 102 | |||
| 103 | $tableDiff = $this->getTableDiffForAlterForeignKey($table); |
||
| 104 | |||
| 105 | if (is_string($foreignKey)) { |
||
| 106 | $tableDiff->removedForeignKeys[] = $table->getForeignKey($foreignKey); |
||
| 107 | } else { |
||
| 108 | $tableDiff->removedForeignKeys[] = $foreignKey; |
||
| 109 | } |
||
| 110 | |||
| 111 | $this->alterTable($tableDiff); |
||
| 112 | } |
||
| 113 | |||
| 114 | /** |
||
| 115 | * {@inheritdoc} |
||
| 116 | */ |
||
| 117 | 104 | public function listTableForeignKeys(string $table, ?string $database = null) : array |
|
| 118 | { |
||
| 119 | 104 | if ($database === null) { |
|
| 120 | 104 | $database = $this->_conn->getDatabase(); |
|
| 121 | } |
||
| 122 | |||
| 123 | 104 | $sql = $this->_platform->getListTableForeignKeysSQL($table, $database); |
|
| 124 | 104 | $tableForeignKeys = $this->_conn->fetchAll($sql); |
|
| 125 | |||
| 126 | 104 | if (! empty($tableForeignKeys)) { |
|
| 127 | 11 | $createSql = $this->getCreateTableSQL($table); |
|
| 128 | |||
| 129 | 11 | if (preg_match_all( |
|
| 130 | '# |
||
| 131 | (?:CONSTRAINT\s+([^\s]+)\s+)? |
||
| 132 | (?:FOREIGN\s+KEY[^\)]+\)\s*)? |
||
| 133 | REFERENCES\s+[^\s]+\s+(?:\([^\)]+\))? |
||
| 134 | (?: |
||
| 135 | [^,]*? |
||
| 136 | (NOT\s+DEFERRABLE|DEFERRABLE) |
||
| 137 | (?:\s+INITIALLY\s+(DEFERRED|IMMEDIATE))? |
||
| 138 | )?#isx', |
||
| 139 | 11 | $createSql, |
|
| 140 | 11 | $match |
|
| 141 | 11 | ) > 0) { |
|
| 142 | 11 | $names = array_reverse($match[1]); |
|
| 143 | 11 | $deferrable = array_reverse($match[2]); |
|
| 144 | 11 | $deferred = array_reverse($match[3]); |
|
| 145 | } else { |
||
| 146 | $names = $deferrable = $deferred = []; |
||
| 147 | } |
||
| 148 | |||
| 149 | 11 | foreach ($tableForeignKeys as $key => $value) { |
|
| 150 | 11 | $id = $value['id']; |
|
| 151 | 11 | $tableForeignKeys[$key]['constraint_name'] = isset($names[$id]) && $names[$id] !== '' ? $names[$id] : $id; |
|
| 152 | 11 | $tableForeignKeys[$key]['deferrable'] = isset($deferrable[$id]) && strtolower($deferrable[$id]) === 'deferrable'; |
|
| 153 | 11 | $tableForeignKeys[$key]['deferred'] = isset($deferred[$id]) && strtolower($deferred[$id]) === 'deferred'; |
|
| 154 | } |
||
| 155 | } |
||
| 156 | |||
| 157 | 104 | return $this->_getPortableTableForeignKeysList($tableForeignKeys); |
|
| 158 | } |
||
| 159 | |||
| 160 | /** |
||
| 161 | * {@inheritdoc} |
||
| 162 | */ |
||
| 163 | 55 | protected function _getPortableTableDefinition(array $table) : string |
|
| 164 | { |
||
| 165 | 55 | return $table['name']; |
|
| 166 | } |
||
| 167 | |||
| 168 | /** |
||
| 169 | * {@inheritdoc} |
||
| 170 | * |
||
| 171 | * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html |
||
| 172 | */ |
||
| 173 | 107 | protected function _getPortableTableIndexesList(array $tableIndexRows, string $tableName) : array |
|
| 174 | { |
||
| 175 | 107 | $indexBuffer = []; |
|
| 176 | |||
| 177 | // fetch primary |
||
| 178 | 107 | $stmt = $this->_conn->executeQuery(sprintf( |
|
| 179 | 2 | 'PRAGMA TABLE_INFO (%s)', |
|
| 180 | 107 | $this->_conn->quote($tableName) |
|
| 181 | )); |
||
| 182 | 107 | $indexArray = $stmt->fetchAll(FetchMode::ASSOCIATIVE); |
|
| 183 | |||
| 184 | usort($indexArray, static function ($a, $b) { |
||
| 185 | 47 | if ($a['pk'] === $b['pk']) { |
|
| 186 | 41 | return $a['cid'] - $b['cid']; |
|
| 187 | } |
||
| 188 | |||
| 189 | 17 | return $a['pk'] - $b['pk']; |
|
| 190 | 107 | }); |
|
| 191 | 107 | foreach ($indexArray as $indexColumnRow) { |
|
| 192 | 107 | if ($indexColumnRow['pk'] === '0') { |
|
| 193 | 54 | continue; |
|
| 194 | } |
||
| 195 | |||
| 196 | 68 | $indexBuffer[] = [ |
|
| 197 | 68 | 'key_name' => 'primary', |
|
| 198 | 'primary' => true, |
||
| 199 | 'non_unique' => false, |
||
| 200 | 68 | 'column_name' => $indexColumnRow['name'], |
|
| 201 | ]; |
||
| 202 | } |
||
| 203 | |||
| 204 | // fetch regular indexes |
||
| 205 | 107 | foreach ($tableIndexRows as $tableIndex) { |
|
| 206 | // Ignore indexes with reserved names, e.g. autoindexes |
||
| 207 | 13 | if (strpos($tableIndex['name'], 'sqlite_') === 0) { |
|
| 208 | 5 | continue; |
|
| 209 | } |
||
| 210 | |||
| 211 | 11 | $keyName = $tableIndex['name']; |
|
| 212 | 11 | $idx = []; |
|
| 213 | 11 | $idx['key_name'] = $keyName; |
|
| 214 | 11 | $idx['primary'] = false; |
|
| 215 | 11 | $idx['non_unique'] = ! $tableIndex['unique']; |
|
| 216 | |||
| 217 | 11 | $stmt = $this->_conn->executeQuery(sprintf( |
|
| 218 | 'PRAGMA INDEX_INFO (%s)', |
||
| 219 | 11 | $this->_conn->quote($keyName) |
|
| 220 | )); |
||
| 221 | 11 | $indexArray = $stmt->fetchAll(FetchMode::ASSOCIATIVE); |
|
| 222 | |||
| 223 | 11 | foreach ($indexArray as $indexColumnRow) { |
|
| 224 | 11 | $idx['column_name'] = $indexColumnRow['name']; |
|
| 225 | 11 | $indexBuffer[] = $idx; |
|
| 226 | } |
||
| 227 | } |
||
| 228 | |||
| 229 | 107 | return parent::_getPortableTableIndexesList($indexBuffer, $tableName); |
|
| 230 | } |
||
| 231 | |||
| 232 | /** |
||
| 233 | * {@inheritdoc} |
||
| 234 | */ |
||
| 235 | 109 | protected function _getPortableTableColumnList(string $table, string $database, array $tableColumns) : array |
|
| 236 | { |
||
| 237 | 109 | $list = parent::_getPortableTableColumnList($table, $database, $tableColumns); |
|
| 238 | |||
| 239 | // find column with autoincrement |
||
| 240 | 109 | $autoincrementColumn = null; |
|
| 241 | 109 | $autoincrementCount = 0; |
|
| 242 | |||
| 243 | 109 | foreach ($tableColumns as $tableColumn) { |
|
| 244 | 109 | if ($tableColumn['pk'] === '0') { |
|
| 245 | 57 | continue; |
|
| 246 | } |
||
| 247 | |||
| 248 | 67 | $autoincrementCount++; |
|
| 249 | 67 | if ($autoincrementColumn !== null || strtolower($tableColumn['type']) !== 'integer') { |
|
| 250 | 3 | continue; |
|
| 251 | } |
||
| 252 | |||
| 253 | 67 | $autoincrementColumn = $tableColumn['name']; |
|
| 254 | } |
||
| 255 | |||
| 256 | 109 | if ($autoincrementCount === 1 && $autoincrementColumn !== null) { |
|
|
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
| 257 | 66 | foreach ($list as $column) { |
|
| 258 | 66 | if ($autoincrementColumn !== $column->getName()) { |
|
| 259 | 15 | continue; |
|
| 260 | } |
||
| 261 | |||
| 262 | 66 | $column->setAutoincrement(true); |
|
| 263 | } |
||
| 264 | } |
||
| 265 | |||
| 266 | // inspect column collation and comments |
||
| 267 | 109 | $createSql = $this->getCreateTableSQL($table); |
|
| 268 | |||
| 269 | 109 | foreach ($list as $columnName => $column) { |
|
| 270 | 109 | $type = $column->getType(); |
|
| 271 | |||
| 272 | 109 | if ($type instanceof StringType || $type instanceof TextType) { |
|
| 273 | 43 | $column->setPlatformOption( |
|
| 274 | 43 | 'collation', |
|
| 275 | 43 | $this->parseColumnCollationFromSQL($columnName, $createSql) ?? 'BINARY' |
|
| 276 | ); |
||
| 277 | } |
||
| 278 | |||
| 279 | 109 | $comment = $this->parseColumnCommentFromSQL($columnName, $createSql); |
|
| 280 | |||
| 281 | 109 | $type = $this->extractDoctrineTypeFromComment($comment); |
|
| 282 | |||
| 283 | 109 | if ($type !== null) { |
|
| 284 | 10 | $column->setType(Type::getType($type)); |
|
| 285 | } |
||
| 286 | |||
| 287 | 109 | $column->setComment($comment); |
|
| 288 | } |
||
| 289 | |||
| 290 | 109 | return $list; |
|
| 291 | } |
||
| 292 | |||
| 293 | /** |
||
| 294 | * {@inheritdoc} |
||
| 295 | */ |
||
| 296 | 109 | protected function _getPortableTableColumnDefinition(array $tableColumn) : Column |
|
| 297 | { |
||
| 298 | 109 | preg_match('/^([^()]*)\\s*(\\(((\\d+)(,\\s*(\\d+))?)\\))?/', $tableColumn['type'], $matches); |
|
| 299 | |||
| 300 | 109 | $dbType = trim(strtolower($matches[1])); |
|
| 301 | |||
| 302 | 109 | $length = $precision = $unsigned = null; |
|
|
0 ignored issues
–
show
|
|||
| 303 | 109 | $fixed = $unsigned = false; |
|
| 304 | 109 | $scale = 0; |
|
| 305 | |||
| 306 | 109 | if (count($matches) >= 6) { |
|
| 307 | 4 | $precision = (int) $matches[4]; |
|
| 308 | 4 | $scale = (int) $matches[6]; |
|
| 309 | 109 | } elseif (count($matches) >= 4) { |
|
| 310 | 42 | $length = (int) $matches[4]; |
|
| 311 | } |
||
| 312 | |||
| 313 | 109 | if (strpos($dbType, ' unsigned') !== false) { |
|
| 314 | 1 | $dbType = str_replace(' unsigned', '', $dbType); |
|
| 315 | 1 | $unsigned = true; |
|
| 316 | } |
||
| 317 | |||
| 318 | 109 | $type = $this->_platform->getDoctrineTypeMapping($dbType); |
|
| 319 | 109 | $default = $tableColumn['dflt_value']; |
|
| 320 | 109 | if ($default === 'NULL') { |
|
| 321 | 22 | $default = null; |
|
| 322 | } |
||
| 323 | |||
| 324 | 109 | if ($default !== null) { |
|
| 325 | // SQLite returns the default value as a literal expression, so we need to parse it |
||
| 326 | 26 | if (preg_match('/^\'(.*)\'$/s', $default, $matches) === 1) { |
|
| 327 | 25 | $default = str_replace("''", "'", $matches[1]); |
|
| 328 | } |
||
| 329 | } |
||
| 330 | |||
| 331 | 109 | $notnull = (bool) $tableColumn['notnull']; |
|
| 332 | |||
| 333 | 109 | if (! isset($tableColumn['name'])) { |
|
| 334 | $tableColumn['name'] = ''; |
||
| 335 | } |
||
| 336 | |||
| 337 | 109 | if ($dbType === 'char') { |
|
| 338 | 3 | $fixed = true; |
|
| 339 | } |
||
| 340 | |||
| 341 | $options = [ |
||
| 342 | 109 | 'length' => $length, |
|
| 343 | 109 | 'unsigned' => $unsigned, |
|
| 344 | 109 | 'fixed' => $fixed, |
|
| 345 | 109 | 'notnull' => $notnull, |
|
| 346 | 109 | 'default' => $default, |
|
| 347 | 109 | 'precision' => $precision, |
|
| 348 | 109 | 'scale' => $scale, |
|
| 349 | 'autoincrement' => false, |
||
| 350 | ]; |
||
| 351 | |||
| 352 | 109 | return new Column($tableColumn['name'], Type::getType($type), $options); |
|
| 353 | } |
||
| 354 | |||
| 355 | /** |
||
| 356 | * {@inheritdoc} |
||
| 357 | */ |
||
| 358 | 1 | protected function _getPortableViewDefinition(array $view) : View |
|
| 359 | { |
||
| 360 | 1 | return new View($view['name'], $view['sql']); |
|
| 361 | } |
||
| 362 | |||
| 363 | /** |
||
| 364 | * {@inheritdoc} |
||
| 365 | */ |
||
| 366 | 104 | protected function _getPortableTableForeignKeysList(array $tableForeignKeys) : array |
|
| 367 | { |
||
| 368 | 104 | $list = []; |
|
| 369 | 104 | foreach ($tableForeignKeys as $value) { |
|
| 370 | 11 | $value = array_change_key_case($value, CASE_LOWER); |
|
| 371 | 11 | $name = $value['constraint_name']; |
|
| 372 | 11 | if (! isset($list[$name])) { |
|
| 373 | 11 | if (! isset($value['on_delete']) || $value['on_delete'] === 'RESTRICT') { |
|
| 374 | $value['on_delete'] = null; |
||
| 375 | } |
||
| 376 | |||
| 377 | 11 | if (! isset($value['on_update']) || $value['on_update'] === 'RESTRICT') { |
|
| 378 | $value['on_update'] = null; |
||
| 379 | } |
||
| 380 | |||
| 381 | 11 | $list[$name] = [ |
|
| 382 | 11 | 'name' => $name, |
|
| 383 | 'local' => [], |
||
| 384 | 'foreign' => [], |
||
| 385 | 11 | 'foreignTable' => $value['table'], |
|
| 386 | 11 | 'onDelete' => $value['on_delete'], |
|
| 387 | 11 | 'onUpdate' => $value['on_update'], |
|
| 388 | 11 | 'deferrable' => $value['deferrable'], |
|
| 389 | 11 | 'deferred'=> $value['deferred'], |
|
| 390 | ]; |
||
| 391 | } |
||
| 392 | |||
| 393 | 11 | $list[$name]['local'][] = $value['from']; |
|
| 394 | 11 | $list[$name]['foreign'][] = $value['to']; |
|
| 395 | } |
||
| 396 | |||
| 397 | 104 | $result = []; |
|
| 398 | 104 | foreach ($list as $constraint) { |
|
| 399 | 11 | $result[] = new ForeignKeyConstraint( |
|
| 400 | 11 | array_values($constraint['local']), |
|
| 401 | 11 | $constraint['foreignTable'], |
|
| 402 | 11 | array_values($constraint['foreign']), |
|
| 403 | 11 | $constraint['name'], |
|
| 404 | [ |
||
| 405 | 11 | 'onDelete' => $constraint['onDelete'], |
|
| 406 | 11 | 'onUpdate' => $constraint['onUpdate'], |
|
| 407 | 11 | 'deferrable' => $constraint['deferrable'], |
|
| 408 | 11 | 'deferred'=> $constraint['deferred'], |
|
| 409 | ] |
||
| 410 | ); |
||
| 411 | } |
||
| 412 | |||
| 413 | 104 | return $result; |
|
| 414 | } |
||
| 415 | |||
| 416 | 2 | private function getTableDiffForAlterForeignKey(Table $table) : TableDiff |
|
| 417 | { |
||
| 418 | 2 | $tableDiff = new TableDiff($table->getName()); |
|
| 419 | 2 | $tableDiff->fromTable = $table; |
|
| 420 | |||
| 421 | 2 | return $tableDiff; |
|
| 422 | } |
||
| 423 | |||
| 424 | /** |
||
| 425 | * @param string|Table $table |
||
| 426 | */ |
||
| 427 | 2 | private function ensureTable($table) : Table |
|
| 428 | { |
||
| 429 | 2 | if (is_string($table)) { |
|
| 430 | 2 | $table = $this->listTableDetails($table); |
|
| 431 | } |
||
| 432 | |||
| 433 | 2 | return $table; |
|
| 434 | } |
||
| 435 | |||
| 436 | 395 | private function parseColumnCollationFromSQL(string $column, string $sql) : ?string |
|
| 437 | { |
||
| 438 | 395 | $pattern = '{(?:\W' . preg_quote($column) . '\W|\W' . preg_quote($this->_platform->quoteSingleIdentifier($column)) |
|
| 439 | 395 | . '\W)[^,(]+(?:\([^()]+\)[^,]*)?(?:(?:DEFAULT|CHECK)\s*(?:\(.*?\))?[^,]*)*COLLATE\s+["\']?([^\s,"\')]+)}is'; |
|
| 440 | |||
| 441 | 395 | if (preg_match($pattern, $sql, $match) !== 1) { |
|
| 442 | 153 | return null; |
|
| 443 | } |
||
| 444 | |||
| 445 | 245 | return $match[1]; |
|
| 446 | } |
||
| 447 | |||
| 448 | 102 | private function parseTableCommentFromSQL(string $table, string $sql) : ?string |
|
| 449 | { |
||
| 450 | $pattern = '/\s* # Allow whitespace characters at start of line |
||
| 451 | CREATE\sTABLE # Match "CREATE TABLE" |
||
| 452 | 102 | (?:\W"' . preg_quote($this->_platform->quoteSingleIdentifier($table), '/') . '"\W|\W' . preg_quote($table, '/') |
|
| 453 | 102 | . '\W) # Match table name (quoted and unquoted) |
|
| 454 | ( # Start capture |
||
| 455 | (?:\s*--[^\n]*\n?)+ # Capture anything that starts with whitespaces followed by -- until the end of the line(s) |
||
| 456 | )/ix'; |
||
| 457 | |||
| 458 | 102 | if (preg_match($pattern, $sql, $match) !== 1) { |
|
| 459 | 101 | return null; |
|
| 460 | } |
||
| 461 | |||
| 462 | 1 | $comment = preg_replace('{^\s*--}m', '', rtrim($match[1], "\n")); |
|
| 463 | |||
| 464 | 1 | return $comment === '' ? null : $comment; |
|
| 465 | } |
||
| 466 | |||
| 467 | 593 | private function parseColumnCommentFromSQL(string $column, string $sql) : string |
|
| 468 | { |
||
| 469 | 593 | $pattern = '{[\s(,](?:\W' . preg_quote($this->_platform->quoteSingleIdentifier($column)) . '\W|\W' . preg_quote($column) |
|
| 470 | 593 | . '\W)(?:\([^)]*?\)|[^,(])*?,?((?:(?!\n))(?:\s*--[^\n]*\n?)+)}i'; |
|
| 471 | |||
| 472 | 593 | if (preg_match($pattern, $sql, $match) !== 1) { |
|
| 473 | 348 | return ''; |
|
| 474 | } |
||
| 475 | |||
| 476 | 275 | $comment = preg_replace('{^\s*--}m', '', rtrim($match[1], "\n")); |
|
| 477 | 275 | assert(is_string($comment)); |
|
| 478 | |||
| 479 | 275 | return $comment; |
|
| 480 | } |
||
| 481 | |||
| 482 | 111 | private function getCreateTableSQL(string $table) : string |
|
| 483 | { |
||
| 484 | 111 | $sql = $this->_conn->fetchColumn( |
|
| 485 | <<<'SQL' |
||
| 486 | 111 | SELECT sql |
|
| 487 | FROM ( |
||
| 488 | SELECT * |
||
| 489 | FROM sqlite_master |
||
| 490 | UNION ALL |
||
| 491 | SELECT * |
||
| 492 | FROM sqlite_temp_master |
||
| 493 | ) |
||
| 494 | WHERE type = 'table' |
||
| 495 | AND name = ? |
||
| 496 | SQL |
||
| 497 | , |
||
| 498 | 111 | [$table] |
|
| 499 | ); |
||
| 500 | |||
| 501 | 111 | if ($sql !== false) { |
|
| 502 | 111 | return $sql; |
|
| 503 | } |
||
| 504 | |||
| 505 | return ''; |
||
| 506 | } |
||
| 507 | |||
| 508 | 102 | public function listTableDetails(string $tableName) : Table |
|
| 509 | { |
||
| 510 | 102 | $table = parent::listTableDetails($tableName); |
|
| 511 | |||
| 512 | 102 | $tableCreateSql = $this->getCreateTableSQL($tableName); |
|
| 513 | |||
| 514 | 102 | $comment = $this->parseTableCommentFromSQL($tableName, $tableCreateSql); |
|
| 515 | |||
| 516 | 102 | if ($comment !== null) { |
|
| 517 | 1 | $table->addOption('comment', $comment); |
|
| 518 | } |
||
| 519 | |||
| 520 | 102 | return $table; |
|
| 521 | } |
||
| 522 | } |
||
| 523 |