diff options
| author | polo <ordipolo@gmx.fr> | 2024-08-13 23:45:21 +0200 |
|---|---|---|
| committer | polo <ordipolo@gmx.fr> | 2024-08-13 23:45:21 +0200 |
| commit | bf6655a534a6775d30cafa67bd801276bda1d98d (patch) | |
| tree | c6381e3f6c81c33eab72508f410b165ba05f7e9c /vendor/doctrine/dbal/src/Schema/SQLiteSchemaManager.php | |
| parent | 94d67a4b51f8e62e7d518cce26a526ae1ec48278 (diff) | |
| download | AppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.tar.gz AppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.tar.bz2 AppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.zip | |
VERSION 0.2 doctrine ORM et entités
Diffstat (limited to 'vendor/doctrine/dbal/src/Schema/SQLiteSchemaManager.php')
| -rw-r--r-- | vendor/doctrine/dbal/src/Schema/SQLiteSchemaManager.php | 620 |
1 files changed, 620 insertions, 0 deletions
diff --git a/vendor/doctrine/dbal/src/Schema/SQLiteSchemaManager.php b/vendor/doctrine/dbal/src/Schema/SQLiteSchemaManager.php new file mode 100644 index 0000000..c001c25 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/SQLiteSchemaManager.php | |||
| @@ -0,0 +1,620 @@ | |||
| 1 | <?php | ||
| 2 | |||
| 3 | declare(strict_types=1); | ||
| 4 | |||
| 5 | namespace Doctrine\DBAL\Schema; | ||
| 6 | |||
| 7 | use Doctrine\DBAL\Exception; | ||
| 8 | use Doctrine\DBAL\Platforms\SQLite; | ||
| 9 | use Doctrine\DBAL\Platforms\SQLitePlatform; | ||
| 10 | use Doctrine\DBAL\Result; | ||
| 11 | use Doctrine\DBAL\Types\StringType; | ||
| 12 | use Doctrine\DBAL\Types\TextType; | ||
| 13 | use Doctrine\DBAL\Types\Type; | ||
| 14 | |||
| 15 | use function array_change_key_case; | ||
| 16 | use function array_merge; | ||
| 17 | use function assert; | ||
| 18 | use function count; | ||
| 19 | use function implode; | ||
| 20 | use function is_string; | ||
| 21 | use function preg_match; | ||
| 22 | use function preg_match_all; | ||
| 23 | use function preg_quote; | ||
| 24 | use function preg_replace; | ||
| 25 | use function rtrim; | ||
| 26 | use function str_contains; | ||
| 27 | use function str_replace; | ||
| 28 | use function str_starts_with; | ||
| 29 | use function strcasecmp; | ||
| 30 | use function strtolower; | ||
| 31 | use function trim; | ||
| 32 | use function usort; | ||
| 33 | |||
| 34 | use const CASE_LOWER; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * SQLite SchemaManager. | ||
| 38 | * | ||
| 39 | * @extends AbstractSchemaManager<SQLitePlatform> | ||
| 40 | */ | ||
| 41 | class SQLiteSchemaManager extends AbstractSchemaManager | ||
| 42 | { | ||
| 43 | /** | ||
| 44 | * {@inheritDoc} | ||
| 45 | */ | ||
| 46 | protected function fetchForeignKeyColumnsByTable(string $databaseName): array | ||
| 47 | { | ||
| 48 | $columnsByTable = parent::fetchForeignKeyColumnsByTable($databaseName); | ||
| 49 | |||
| 50 | if (count($columnsByTable) > 0) { | ||
| 51 | foreach ($columnsByTable as $table => $columns) { | ||
| 52 | $columnsByTable[$table] = $this->addDetailsToTableForeignKeyColumns($table, $columns); | ||
| 53 | } | ||
| 54 | } | ||
| 55 | |||
| 56 | return $columnsByTable; | ||
| 57 | } | ||
| 58 | |||
| 59 | public function createForeignKey(ForeignKeyConstraint $foreignKey, string $table): void | ||
| 60 | { | ||
| 61 | $table = $this->introspectTable($table); | ||
| 62 | |||
| 63 | $this->alterTable(new TableDiff($table, [], [], [], [], [], [], [], [], [$foreignKey], [], [])); | ||
| 64 | } | ||
| 65 | |||
| 66 | public function dropForeignKey(string $name, string $table): void | ||
| 67 | { | ||
| 68 | $table = $this->introspectTable($table); | ||
| 69 | |||
| 70 | $foreignKey = $table->getForeignKey($name); | ||
| 71 | |||
| 72 | $this->alterTable(new TableDiff($table, [], [], [], [], [], [], [], [], [], [], [$foreignKey])); | ||
| 73 | } | ||
| 74 | |||
| 75 | /** | ||
| 76 | * {@inheritDoc} | ||
| 77 | */ | ||
| 78 | public function listTableForeignKeys(string $table): array | ||
| 79 | { | ||
| 80 | $table = $this->normalizeName($table); | ||
| 81 | |||
| 82 | $columns = $this->selectForeignKeyColumns('main', $table) | ||
| 83 | ->fetchAllAssociative(); | ||
| 84 | |||
| 85 | if (count($columns) > 0) { | ||
| 86 | $columns = $this->addDetailsToTableForeignKeyColumns($table, $columns); | ||
| 87 | } | ||
| 88 | |||
| 89 | return $this->_getPortableTableForeignKeysList($columns); | ||
| 90 | } | ||
| 91 | |||
| 92 | /** | ||
| 93 | * {@inheritDoc} | ||
| 94 | */ | ||
| 95 | protected function _getPortableTableDefinition(array $table): string | ||
| 96 | { | ||
| 97 | return $table['table_name']; | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * {@inheritDoc} | ||
| 102 | * | ||
| 103 | * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html | ||
| 104 | */ | ||
| 105 | protected function _getPortableTableIndexesList(array $tableIndexes, string $tableName): array | ||
| 106 | { | ||
| 107 | $indexBuffer = []; | ||
| 108 | |||
| 109 | // fetch primary | ||
| 110 | $indexArray = $this->connection->fetchAllAssociative('SELECT * FROM PRAGMA_TABLE_INFO (?)', [$tableName]); | ||
| 111 | |||
| 112 | usort( | ||
| 113 | $indexArray, | ||
| 114 | /** | ||
| 115 | * @param array<string,mixed> $a | ||
| 116 | * @param array<string,mixed> $b | ||
| 117 | */ | ||
| 118 | static function (array $a, array $b): int { | ||
| 119 | if ($a['pk'] === $b['pk']) { | ||
| 120 | return $a['cid'] - $b['cid']; | ||
| 121 | } | ||
| 122 | |||
| 123 | return $a['pk'] - $b['pk']; | ||
| 124 | }, | ||
| 125 | ); | ||
| 126 | |||
| 127 | foreach ($indexArray as $indexColumnRow) { | ||
| 128 | if ($indexColumnRow['pk'] === 0 || $indexColumnRow['pk'] === '0') { | ||
| 129 | continue; | ||
| 130 | } | ||
| 131 | |||
| 132 | $indexBuffer[] = [ | ||
| 133 | 'key_name' => 'primary', | ||
| 134 | 'primary' => true, | ||
| 135 | 'non_unique' => false, | ||
| 136 | 'column_name' => $indexColumnRow['name'], | ||
| 137 | ]; | ||
| 138 | } | ||
| 139 | |||
| 140 | // fetch regular indexes | ||
| 141 | foreach ($tableIndexes as $tableIndex) { | ||
| 142 | // Ignore indexes with reserved names, e.g. autoindexes | ||
| 143 | if (str_starts_with($tableIndex['name'], 'sqlite_')) { | ||
| 144 | continue; | ||
| 145 | } | ||
| 146 | |||
| 147 | $keyName = $tableIndex['name']; | ||
| 148 | $idx = []; | ||
| 149 | $idx['key_name'] = $keyName; | ||
| 150 | $idx['primary'] = false; | ||
| 151 | $idx['non_unique'] = ! $tableIndex['unique']; | ||
| 152 | |||
| 153 | $indexArray = $this->connection->fetchAllAssociative('SELECT * FROM PRAGMA_INDEX_INFO (?)', [$keyName]); | ||
| 154 | |||
| 155 | foreach ($indexArray as $indexColumnRow) { | ||
| 156 | $idx['column_name'] = $indexColumnRow['name']; | ||
| 157 | $indexBuffer[] = $idx; | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | return parent::_getPortableTableIndexesList($indexBuffer, $tableName); | ||
| 162 | } | ||
| 163 | |||
| 164 | /** | ||
| 165 | * {@inheritDoc} | ||
| 166 | */ | ||
| 167 | protected function _getPortableTableColumnList(string $table, string $database, array $tableColumns): array | ||
| 168 | { | ||
| 169 | $list = parent::_getPortableTableColumnList($table, $database, $tableColumns); | ||
| 170 | |||
| 171 | // find column with autoincrement | ||
| 172 | $autoincrementColumn = null; | ||
| 173 | $autoincrementCount = 0; | ||
| 174 | |||
| 175 | foreach ($tableColumns as $tableColumn) { | ||
| 176 | if ($tableColumn['pk'] === 0 || $tableColumn['pk'] === '0') { | ||
| 177 | continue; | ||
| 178 | } | ||
| 179 | |||
| 180 | $autoincrementCount++; | ||
| 181 | if ($autoincrementColumn !== null || strtolower($tableColumn['type']) !== 'integer') { | ||
| 182 | continue; | ||
| 183 | } | ||
| 184 | |||
| 185 | $autoincrementColumn = $tableColumn['name']; | ||
| 186 | } | ||
| 187 | |||
| 188 | if ($autoincrementCount === 1 && $autoincrementColumn !== null) { | ||
| 189 | foreach ($list as $column) { | ||
| 190 | if ($autoincrementColumn !== $column->getName()) { | ||
| 191 | continue; | ||
| 192 | } | ||
| 193 | |||
| 194 | $column->setAutoincrement(true); | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | // inspect column collation and comments | ||
| 199 | $createSql = $this->getCreateTableSQL($table); | ||
| 200 | |||
| 201 | foreach ($list as $columnName => $column) { | ||
| 202 | $type = $column->getType(); | ||
| 203 | |||
| 204 | if ($type instanceof StringType || $type instanceof TextType) { | ||
| 205 | $column->setPlatformOption( | ||
| 206 | 'collation', | ||
| 207 | $this->parseColumnCollationFromSQL($columnName, $createSql) ?? 'BINARY', | ||
| 208 | ); | ||
| 209 | } | ||
| 210 | |||
| 211 | $comment = $this->parseColumnCommentFromSQL($columnName, $createSql); | ||
| 212 | |||
| 213 | $column->setComment($comment); | ||
| 214 | } | ||
| 215 | |||
| 216 | return $list; | ||
| 217 | } | ||
| 218 | |||
| 219 | /** | ||
| 220 | * {@inheritDoc} | ||
| 221 | */ | ||
| 222 | protected function _getPortableTableColumnDefinition(array $tableColumn): Column | ||
| 223 | { | ||
| 224 | preg_match('/^([^()]*)\\s*(\\(((\\d+)(,\\s*(\\d+))?)\\))?/', $tableColumn['type'], $matches); | ||
| 225 | |||
| 226 | $dbType = trim(strtolower($matches[1])); | ||
| 227 | |||
| 228 | $length = $precision = $unsigned = null; | ||
| 229 | $fixed = $unsigned = false; | ||
| 230 | $scale = 0; | ||
| 231 | |||
| 232 | if (count($matches) >= 6) { | ||
| 233 | $precision = (int) $matches[4]; | ||
| 234 | $scale = (int) $matches[6]; | ||
| 235 | } elseif (count($matches) >= 4) { | ||
| 236 | $length = (int) $matches[4]; | ||
| 237 | } | ||
| 238 | |||
| 239 | if (str_contains($dbType, ' unsigned')) { | ||
| 240 | $dbType = str_replace(' unsigned', '', $dbType); | ||
| 241 | $unsigned = true; | ||
| 242 | } | ||
| 243 | |||
| 244 | $type = $this->platform->getDoctrineTypeMapping($dbType); | ||
| 245 | $default = $tableColumn['dflt_value']; | ||
| 246 | if ($default === 'NULL') { | ||
| 247 | $default = null; | ||
| 248 | } | ||
| 249 | |||
| 250 | if ($default !== null) { | ||
| 251 | // SQLite returns the default value as a literal expression, so we need to parse it | ||
| 252 | if (preg_match('/^\'(.*)\'$/s', $default, $matches) === 1) { | ||
| 253 | $default = str_replace("''", "'", $matches[1]); | ||
| 254 | } | ||
| 255 | } | ||
| 256 | |||
| 257 | $notnull = (bool) $tableColumn['notnull']; | ||
| 258 | |||
| 259 | if (! isset($tableColumn['name'])) { | ||
| 260 | $tableColumn['name'] = ''; | ||
| 261 | } | ||
| 262 | |||
| 263 | if ($dbType === 'char') { | ||
| 264 | $fixed = true; | ||
| 265 | } | ||
| 266 | |||
| 267 | $options = [ | ||
| 268 | 'length' => $length, | ||
| 269 | 'unsigned' => $unsigned, | ||
| 270 | 'fixed' => $fixed, | ||
| 271 | 'notnull' => $notnull, | ||
| 272 | 'default' => $default, | ||
| 273 | 'precision' => $precision, | ||
| 274 | 'scale' => $scale, | ||
| 275 | ]; | ||
| 276 | |||
| 277 | return new Column($tableColumn['name'], Type::getType($type), $options); | ||
| 278 | } | ||
| 279 | |||
| 280 | /** | ||
| 281 | * {@inheritDoc} | ||
| 282 | */ | ||
| 283 | protected function _getPortableViewDefinition(array $view): View | ||
| 284 | { | ||
| 285 | return new View($view['name'], $view['sql']); | ||
| 286 | } | ||
| 287 | |||
| 288 | /** | ||
| 289 | * {@inheritDoc} | ||
| 290 | */ | ||
| 291 | protected function _getPortableTableForeignKeysList(array $tableForeignKeys): array | ||
| 292 | { | ||
| 293 | $list = []; | ||
| 294 | foreach ($tableForeignKeys as $value) { | ||
| 295 | $value = array_change_key_case($value, CASE_LOWER); | ||
| 296 | $id = $value['id']; | ||
| 297 | if (! isset($list[$id])) { | ||
| 298 | if (! isset($value['on_delete']) || $value['on_delete'] === 'RESTRICT') { | ||
| 299 | $value['on_delete'] = null; | ||
| 300 | } | ||
| 301 | |||
| 302 | if (! isset($value['on_update']) || $value['on_update'] === 'RESTRICT') { | ||
| 303 | $value['on_update'] = null; | ||
| 304 | } | ||
| 305 | |||
| 306 | $list[$id] = [ | ||
| 307 | 'name' => $value['constraint_name'], | ||
| 308 | 'local' => [], | ||
| 309 | 'foreign' => [], | ||
| 310 | 'foreignTable' => $value['table'], | ||
| 311 | 'onDelete' => $value['on_delete'], | ||
| 312 | 'onUpdate' => $value['on_update'], | ||
| 313 | 'deferrable' => $value['deferrable'], | ||
| 314 | 'deferred' => $value['deferred'], | ||
| 315 | ]; | ||
| 316 | } | ||
| 317 | |||
| 318 | $list[$id]['local'][] = $value['from']; | ||
| 319 | |||
| 320 | if ($value['to'] === null) { | ||
| 321 | // Inferring a shorthand form for the foreign key constraint, where the "to" field is empty. | ||
| 322 | // @see https://www.sqlite.org/foreignkeys.html#fk_indexes. | ||
| 323 | $foreignTableIndexes = $this->_getPortableTableIndexesList([], $value['table']); | ||
| 324 | |||
| 325 | if (! isset($foreignTableIndexes['primary'])) { | ||
| 326 | continue; | ||
| 327 | } | ||
| 328 | |||
| 329 | $list[$id]['foreign'] = [...$list[$id]['foreign'], ...$foreignTableIndexes['primary']->getColumns()]; | ||
| 330 | |||
| 331 | continue; | ||
| 332 | } | ||
| 333 | |||
| 334 | $list[$id]['foreign'][] = $value['to']; | ||
| 335 | } | ||
| 336 | |||
| 337 | return parent::_getPortableTableForeignKeysList($list); | ||
| 338 | } | ||
| 339 | |||
| 340 | /** | ||
| 341 | * {@inheritDoc} | ||
| 342 | */ | ||
| 343 | protected function _getPortableTableForeignKeyDefinition(array $tableForeignKey): ForeignKeyConstraint | ||
| 344 | { | ||
| 345 | return new ForeignKeyConstraint( | ||
| 346 | $tableForeignKey['local'], | ||
| 347 | $tableForeignKey['foreignTable'], | ||
| 348 | $tableForeignKey['foreign'], | ||
| 349 | $tableForeignKey['name'], | ||
| 350 | [ | ||
| 351 | 'onDelete' => $tableForeignKey['onDelete'], | ||
| 352 | 'onUpdate' => $tableForeignKey['onUpdate'], | ||
| 353 | 'deferrable' => $tableForeignKey['deferrable'], | ||
| 354 | 'deferred' => $tableForeignKey['deferred'], | ||
| 355 | ], | ||
| 356 | ); | ||
| 357 | } | ||
| 358 | |||
| 359 | private function parseColumnCollationFromSQL(string $column, string $sql): ?string | ||
| 360 | { | ||
| 361 | $pattern = '{(?:\W' . preg_quote($column) . '\W|\W' | ||
| 362 | . preg_quote($this->platform->quoteSingleIdentifier($column)) | ||
| 363 | . '\W)[^,(]+(?:\([^()]+\)[^,]*)?(?:(?:DEFAULT|CHECK)\s*(?:\(.*?\))?[^,]*)*COLLATE\s+["\']?([^\s,"\')]+)}is'; | ||
| 364 | |||
| 365 | if (preg_match($pattern, $sql, $match) !== 1) { | ||
| 366 | return null; | ||
| 367 | } | ||
| 368 | |||
| 369 | return $match[1]; | ||
| 370 | } | ||
| 371 | |||
| 372 | private function parseTableCommentFromSQL(string $table, string $sql): ?string | ||
| 373 | { | ||
| 374 | $pattern = '/\s* # Allow whitespace characters at start of line | ||
| 375 | CREATE\sTABLE # Match "CREATE TABLE" | ||
| 376 | (?:\W"' . preg_quote($this->platform->quoteSingleIdentifier($table), '/') . '"\W|\W' . preg_quote($table, '/') | ||
| 377 | . '\W) # Match table name (quoted and unquoted) | ||
| 378 | ( # Start capture | ||
| 379 | (?:\s*--[^\n]*\n?)+ # Capture anything that starts with whitespaces followed by -- until the end of the line(s) | ||
| 380 | )/ix'; | ||
| 381 | |||
| 382 | if (preg_match($pattern, $sql, $match) !== 1) { | ||
| 383 | return null; | ||
| 384 | } | ||
| 385 | |||
| 386 | $comment = preg_replace('{^\s*--}m', '', rtrim($match[1], "\n")); | ||
| 387 | |||
| 388 | return $comment === '' ? null : $comment; | ||
| 389 | } | ||
| 390 | |||
| 391 | private function parseColumnCommentFromSQL(string $column, string $sql): string | ||
| 392 | { | ||
| 393 | $pattern = '{[\s(,](?:\W' . preg_quote($this->platform->quoteSingleIdentifier($column)) | ||
| 394 | . '\W|\W' . preg_quote($column) . '\W)(?:\([^)]*?\)|[^,(])*?,?((?:(?!\n))(?:\s*--[^\n]*\n?)+)}i'; | ||
| 395 | |||
| 396 | if (preg_match($pattern, $sql, $match) !== 1) { | ||
| 397 | return ''; | ||
| 398 | } | ||
| 399 | |||
| 400 | $comment = preg_replace('{^\s*--}m', '', rtrim($match[1], "\n")); | ||
| 401 | assert(is_string($comment)); | ||
| 402 | |||
| 403 | return $comment; | ||
| 404 | } | ||
| 405 | |||
| 406 | /** @throws Exception */ | ||
| 407 | private function getCreateTableSQL(string $table): string | ||
| 408 | { | ||
| 409 | $sql = $this->connection->fetchOne( | ||
| 410 | <<<'SQL' | ||
| 411 | SELECT sql | ||
| 412 | FROM ( | ||
| 413 | SELECT * | ||
| 414 | FROM sqlite_master | ||
| 415 | UNION ALL | ||
| 416 | SELECT * | ||
| 417 | FROM sqlite_temp_master | ||
| 418 | ) | ||
| 419 | WHERE type = 'table' | ||
| 420 | AND name = ? | ||
| 421 | SQL | ||
| 422 | , | ||
| 423 | [$table], | ||
| 424 | ); | ||
| 425 | |||
| 426 | if ($sql !== false) { | ||
| 427 | return $sql; | ||
| 428 | } | ||
| 429 | |||
| 430 | return ''; | ||
| 431 | } | ||
| 432 | |||
| 433 | /** | ||
| 434 | * @param list<array<string,mixed>> $columns | ||
| 435 | * | ||
| 436 | * @return list<array<string,mixed>> | ||
| 437 | * | ||
| 438 | * @throws Exception | ||
| 439 | */ | ||
| 440 | private function addDetailsToTableForeignKeyColumns(string $table, array $columns): array | ||
| 441 | { | ||
| 442 | $foreignKeyDetails = $this->getForeignKeyDetails($table); | ||
| 443 | $foreignKeyCount = count($foreignKeyDetails); | ||
| 444 | |||
| 445 | foreach ($columns as $i => $column) { | ||
| 446 | // SQLite identifies foreign keys in reverse order of appearance in SQL | ||
| 447 | $columns[$i] = array_merge($column, $foreignKeyDetails[$foreignKeyCount - $column['id'] - 1]); | ||
| 448 | } | ||
| 449 | |||
| 450 | return $columns; | ||
| 451 | } | ||
| 452 | |||
| 453 | /** | ||
| 454 | * @return list<array<string, mixed>> | ||
| 455 | * | ||
| 456 | * @throws Exception | ||
| 457 | */ | ||
| 458 | private function getForeignKeyDetails(string $table): array | ||
| 459 | { | ||
| 460 | $createSql = $this->getCreateTableSQL($table); | ||
| 461 | |||
| 462 | if ( | ||
| 463 | preg_match_all( | ||
| 464 | '# | ||
| 465 | (?:CONSTRAINT\s+(\S+)\s+)? | ||
| 466 | (?:FOREIGN\s+KEY[^)]+\)\s*)? | ||
| 467 | REFERENCES\s+\S+\s*(?:\([^)]+\))? | ||
| 468 | (?: | ||
| 469 | [^,]*? | ||
| 470 | (NOT\s+DEFERRABLE|DEFERRABLE) | ||
| 471 | (?:\s+INITIALLY\s+(DEFERRED|IMMEDIATE))? | ||
| 472 | )?#isx', | ||
| 473 | $createSql, | ||
| 474 | $match, | ||
| 475 | ) === 0 | ||
| 476 | ) { | ||
| 477 | return []; | ||
| 478 | } | ||
| 479 | |||
| 480 | $names = $match[1]; | ||
| 481 | $deferrable = $match[2]; | ||
| 482 | $deferred = $match[3]; | ||
| 483 | $details = []; | ||
| 484 | |||
| 485 | for ($i = 0, $count = count($match[0]); $i < $count; $i++) { | ||
| 486 | $details[] = [ | ||
| 487 | 'constraint_name' => $names[$i] ?? '', | ||
| 488 | 'deferrable' => isset($deferrable[$i]) && strcasecmp($deferrable[$i], 'deferrable') === 0, | ||
| 489 | 'deferred' => isset($deferred[$i]) && strcasecmp($deferred[$i], 'deferred') === 0, | ||
| 490 | ]; | ||
| 491 | } | ||
| 492 | |||
| 493 | return $details; | ||
| 494 | } | ||
| 495 | |||
| 496 | public function createComparator(): Comparator | ||
| 497 | { | ||
| 498 | return new SQLite\Comparator($this->platform); | ||
| 499 | } | ||
| 500 | |||
| 501 | protected function selectTableNames(string $databaseName): Result | ||
| 502 | { | ||
| 503 | $sql = <<<'SQL' | ||
| 504 | SELECT name AS table_name | ||
| 505 | FROM sqlite_master | ||
| 506 | WHERE type = 'table' | ||
| 507 | AND name != 'sqlite_sequence' | ||
| 508 | AND name != 'geometry_columns' | ||
| 509 | AND name != 'spatial_ref_sys' | ||
| 510 | UNION ALL | ||
| 511 | SELECT name | ||
| 512 | FROM sqlite_temp_master | ||
| 513 | WHERE type = 'table' | ||
| 514 | ORDER BY name | ||
| 515 | SQL; | ||
| 516 | |||
| 517 | return $this->connection->executeQuery($sql); | ||
| 518 | } | ||
| 519 | |||
| 520 | protected function selectTableColumns(string $databaseName, ?string $tableName = null): Result | ||
| 521 | { | ||
| 522 | $sql = <<<'SQL' | ||
| 523 | SELECT t.name AS table_name, | ||
| 524 | c.* | ||
| 525 | FROM sqlite_master t | ||
| 526 | JOIN pragma_table_info(t.name) c | ||
| 527 | SQL; | ||
| 528 | |||
| 529 | $conditions = [ | ||
| 530 | "t.type = 'table'", | ||
| 531 | "t.name NOT IN ('geometry_columns', 'spatial_ref_sys', 'sqlite_sequence')", | ||
| 532 | ]; | ||
| 533 | $params = []; | ||
| 534 | |||
| 535 | if ($tableName !== null) { | ||
| 536 | $conditions[] = 't.name = ?'; | ||
| 537 | $params[] = str_replace('.', '__', $tableName); | ||
| 538 | } | ||
| 539 | |||
| 540 | $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY t.name, c.cid'; | ||
| 541 | |||
| 542 | return $this->connection->executeQuery($sql, $params); | ||
| 543 | } | ||
| 544 | |||
| 545 | protected function selectIndexColumns(string $databaseName, ?string $tableName = null): Result | ||
| 546 | { | ||
| 547 | $sql = <<<'SQL' | ||
| 548 | SELECT t.name AS table_name, | ||
| 549 | i.* | ||
| 550 | FROM sqlite_master t | ||
| 551 | JOIN pragma_index_list(t.name) i | ||
| 552 | SQL; | ||
| 553 | |||
| 554 | $conditions = [ | ||
| 555 | "t.type = 'table'", | ||
| 556 | "t.name NOT IN ('geometry_columns', 'spatial_ref_sys', 'sqlite_sequence')", | ||
| 557 | ]; | ||
| 558 | $params = []; | ||
| 559 | |||
| 560 | if ($tableName !== null) { | ||
| 561 | $conditions[] = 't.name = ?'; | ||
| 562 | $params[] = str_replace('.', '__', $tableName); | ||
| 563 | } | ||
| 564 | |||
| 565 | $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY t.name, i.seq'; | ||
| 566 | |||
| 567 | return $this->connection->executeQuery($sql, $params); | ||
| 568 | } | ||
| 569 | |||
| 570 | protected function selectForeignKeyColumns(string $databaseName, ?string $tableName = null): Result | ||
| 571 | { | ||
| 572 | $sql = <<<'SQL' | ||
| 573 | SELECT t.name AS table_name, | ||
| 574 | p.* | ||
| 575 | FROM sqlite_master t | ||
| 576 | JOIN pragma_foreign_key_list(t.name) p | ||
| 577 | ON p."seq" != '-1' | ||
| 578 | SQL; | ||
| 579 | |||
| 580 | $conditions = [ | ||
| 581 | "t.type = 'table'", | ||
| 582 | "t.name NOT IN ('geometry_columns', 'spatial_ref_sys', 'sqlite_sequence')", | ||
| 583 | ]; | ||
| 584 | $params = []; | ||
| 585 | |||
| 586 | if ($tableName !== null) { | ||
| 587 | $conditions[] = 't.name = ?'; | ||
| 588 | $params[] = str_replace('.', '__', $tableName); | ||
| 589 | } | ||
| 590 | |||
| 591 | $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY t.name, p.id DESC, p.seq'; | ||
| 592 | |||
| 593 | return $this->connection->executeQuery($sql, $params); | ||
| 594 | } | ||
| 595 | |||
| 596 | /** | ||
| 597 | * {@inheritDoc} | ||
| 598 | */ | ||
| 599 | protected function fetchTableOptionsByTable(string $databaseName, ?string $tableName = null): array | ||
| 600 | { | ||
| 601 | if ($tableName === null) { | ||
| 602 | $tables = $this->listTableNames(); | ||
| 603 | } else { | ||
| 604 | $tables = [$tableName]; | ||
| 605 | } | ||
| 606 | |||
| 607 | $tableOptions = []; | ||
| 608 | foreach ($tables as $table) { | ||
| 609 | $comment = $this->parseTableCommentFromSQL($table, $this->getCreateTableSQL($table)); | ||
| 610 | |||
| 611 | if ($comment === null) { | ||
| 612 | continue; | ||
| 613 | } | ||
| 614 | |||
| 615 | $tableOptions[$table]['comment'] = $comment; | ||
| 616 | } | ||
| 617 | |||
| 618 | return $tableOptions; | ||
| 619 | } | ||
| 620 | } | ||
