Skip to content

Commit 69f877f

Browse files
authored
Update according changes in db package (#377)
1 parent 6f1ada9 commit 69f877f

File tree

6 files changed

+82
-262
lines changed

6 files changed

+82
-262
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
- Chg #362: Replace column and table name quote character from ` to " (@Tigrov)
4747
- Enh #368: Provide `yiisoft/db-implementation` virtual package (@vjik)
4848
- Enh #371, #374: Adapt to conditions refactoring in `yiisoft/db` package (@vjik)
49+
- Enh #377: Remove `TableSchema` class and refactor `Schema` class (@Tigrov)
4950

5051
## 1.2.0 March 21, 2024
5152

src/Schema.php

Lines changed: 56 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,17 @@
44

55
namespace Yiisoft\Db\Sqlite;
66

7-
use Throwable;
87
use Yiisoft\Db\Constant\ColumnType;
98
use Yiisoft\Db\Constant\ReferentialAction;
109
use Yiisoft\Db\Constraint\Check;
1110
use Yiisoft\Db\Constraint\ForeignKey;
1211
use Yiisoft\Db\Constraint\Index;
1312
use Yiisoft\Db\Driver\Pdo\AbstractPdoSchema;
14-
use Yiisoft\Db\Exception\Exception;
15-
use Yiisoft\Db\Exception\InvalidConfigException;
1613
use Yiisoft\Db\Exception\NotSupportedException;
1714
use Yiisoft\Db\Helper\DbArrayHelper;
1815
use Yiisoft\Db\Schema\Column\ColumnInterface;
16+
use Yiisoft\Db\Schema\SchemaInterface;
17+
use Yiisoft\Db\Schema\TableSchema;
1918
use Yiisoft\Db\Schema\TableSchemaInterface;
2019

2120
use function array_change_key_case;
@@ -68,6 +67,15 @@
6867
*/
6968
final class Schema extends AbstractPdoSchema
7069
{
70+
protected function findConstraints(TableSchemaInterface $table): void
71+
{
72+
$tableName = $this->resolveFullName($table->getName(), $table->getSchemaName());
73+
74+
$table->checks(...$this->getTableMetadata($tableName, SchemaInterface::CHECKS));
75+
$table->foreignKeys(...$this->getTableMetadata($tableName, SchemaInterface::FOREIGN_KEYS));
76+
$table->indexes(...$this->getTableMetadata($tableName, SchemaInterface::INDEXES));
77+
}
78+
7179
protected function findTableNames(string $schema = ''): array
7280
{
7381
/** @var string[] */
@@ -78,10 +86,7 @@ protected function findTableNames(string $schema = ''): array
7886

7987
protected function loadTableSchema(string $name): TableSchemaInterface|null
8088
{
81-
$table = new TableSchema();
82-
83-
$table->name($name);
84-
$table->fullName($name);
89+
$table = new TableSchema($name);
8590

8691
if ($this->findColumns($table)) {
8792
$this->findConstraints($table);
@@ -92,12 +97,6 @@ protected function loadTableSchema(string $name): TableSchemaInterface|null
9297
return null;
9398
}
9499

95-
protected function loadTablePrimaryKey(string $tableName): Index|null
96-
{
97-
/** @var Index|null */
98-
return $this->loadTableConstraints($tableName, self::PRIMARY_KEY);
99-
}
100-
101100
protected function loadTableForeignKeys(string $tableName): array
102101
{
103102
$result = [];
@@ -138,14 +137,45 @@ protected function loadTableForeignKeys(string $tableName): array
138137

139138
protected function loadTableIndexes(string $tableName): array
140139
{
141-
/** @var Index[] */
142-
return $this->loadTableConstraints($tableName, self::INDEXES);
143-
}
140+
$indexList = $this->db
141+
->createCommand('PRAGMA INDEX_LIST(' . $this->db->getQuoter()->quoteValue($tableName) . ')')
142+
->queryAll();
144143

145-
protected function loadTableUniques(string $tableName): array
146-
{
147-
/** @var Index[] */
148-
return $this->loadTableConstraints($tableName, self::UNIQUES);
144+
/** @psalm-var IndexListInfo[] $indexes */
145+
$indexes = array_map(array_change_key_case(...), $indexList);
146+
$result = [];
147+
$hasPrimaryKey = false;
148+
149+
foreach ($indexes as $index) {
150+
$columns = $this->getPragmaIndexInfo($index['name']);
151+
152+
$result[$index['name']] = new Index(
153+
$index['name'],
154+
array_column($columns, 'name'),
155+
(bool) $index['unique'],
156+
$index['origin'] === 'pk',
157+
);
158+
159+
$hasPrimaryKey = $hasPrimaryKey || $index['origin'] === 'pk';
160+
}
161+
162+
if (!$hasPrimaryKey) {
163+
/**
164+
* Extra check for PK in case of `INTEGER PRIMARY KEY` with ROWID.
165+
*
166+
* @link https://www.sqlite.org/lang_createtable.html#primkeyconst
167+
*/
168+
$tableColumns = $this->loadTableColumnsInfo($tableName);
169+
170+
foreach ($tableColumns as $tableColumn) {
171+
if ($tableColumn['pk'] > 0) {
172+
$result[''] = new Index('', [$tableColumn['name']], true, true);
173+
break;
174+
}
175+
}
176+
}
177+
178+
return $result;
149179
}
150180

151181
protected function loadTableChecks(string $tableName): array
@@ -199,15 +229,11 @@ protected function loadTableDefaultValues(string $tableName): array
199229
*
200230
* @param TableSchemaInterface $table The table metadata.
201231
*
202-
* @throws Exception
203-
* @throws InvalidConfigException
204-
* @throws Throwable
205-
*
206232
* @return bool Whether the table exists in the database.
207233
*/
208234
protected function findColumns(TableSchemaInterface $table): bool
209235
{
210-
$columns = $this->getPragmaTableInfo($table->getName());
236+
$columns = $this->loadTableColumnsInfo($table->getName());
211237
$jsonColumns = $this->getJsonColumns($table);
212238

213239
foreach ($columns as $info) {
@@ -220,10 +246,6 @@ protected function findColumns(TableSchemaInterface $table): bool
220246

221247
$column = $this->loadColumn($info);
222248
$table->column($info['name'], $column);
223-
224-
if ($column->isPrimaryKey()) {
225-
$table->primaryKey($info['name']);
226-
}
227249
}
228250

229251
$column = count($table->getPrimaryKey()) === 1 ? $table->getColumn($table->getPrimaryKey()[0]) : null;
@@ -236,49 +258,6 @@ protected function findColumns(TableSchemaInterface $table): bool
236258
return !empty($columns);
237259
}
238260

239-
/**
240-
* Collects the foreign key column details for the given table.
241-
*
242-
* @param TableSchemaInterface $table The table metadata.
243-
*/
244-
protected function findConstraints(TableSchemaInterface $table): void
245-
{
246-
/** @psalm-var ForeignKey[] $foreignKeysList */
247-
$foreignKeysList = $this->getTableForeignKeys($table->getName(), true);
248-
249-
foreach ($foreignKeysList as $foreignKey) {
250-
/** @var array<string> $columnNames */
251-
$columnNames = $foreignKey->columnNames;
252-
$columnNames = array_combine($columnNames, $foreignKey->foreignColumnNames);
253-
254-
$foreignReference = [$foreignKey->foreignTableName, ...$columnNames];
255-
256-
/** @psalm-suppress InvalidCast */
257-
$table->foreignKey($foreignKey->name, $foreignReference);
258-
}
259-
}
260-
261-
public function findUniqueIndexes(TableSchemaInterface $table): array
262-
{
263-
/** @psalm-var IndexListInfo[] $indexList */
264-
$indexList = $this->getPragmaIndexList($table->getName());
265-
$uniqueIndexes = [];
266-
267-
foreach ($indexList as $index) {
268-
$indexName = $index['name'];
269-
$indexInfo = $this->getPragmaIndexInfo($index['name']);
270-
271-
if ($index['unique']) {
272-
$uniqueIndexes[$indexName] = [];
273-
foreach ($indexInfo as $row) {
274-
$uniqueIndexes[$indexName][] = $row['name'];
275-
}
276-
}
277-
}
278-
279-
return $uniqueIndexes;
280-
}
281-
282261
/**
283262
* @throws NotSupportedException
284263
*/
@@ -353,71 +332,14 @@ private function loadColumn(array $info): ColumnInterface
353332
*/
354333
private function loadTableColumnsInfo(string $tableName): array
355334
{
356-
$tableColumns = $this->getPragmaTableInfo($tableName);
335+
$tableColumns = $this->db->createCommand(
336+
'PRAGMA TABLE_INFO(' . $this->db->getQuoter()->quoteSimpleTableName($tableName) . ')'
337+
)->queryAll();
338+
357339
/** @psalm-var ColumnInfo[] */
358340
return array_map(array_change_key_case(...), $tableColumns);
359341
}
360342

361-
/**
362-
* Loads multiple types of constraints and returns the specified ones.
363-
*
364-
* @param string $tableName The table name.
365-
* @param string $returnType Return type: (primaryKey, indexes, uniques).
366-
*
367-
* @psalm-return Index[]|Index|null
368-
*/
369-
private function loadTableConstraints(string $tableName, string $returnType): array|Index|null
370-
{
371-
$indexList = $this->getPragmaIndexList($tableName);
372-
/** @psalm-var IndexListInfo[] $indexes */
373-
$indexes = array_map(array_change_key_case(...), $indexList);
374-
$result = [
375-
self::PRIMARY_KEY => null,
376-
self::INDEXES => [],
377-
self::UNIQUES => [],
378-
];
379-
380-
foreach ($indexes as $index) {
381-
$columns = $this->getPragmaIndexInfo($index['name']);
382-
383-
if ($index['origin'] === 'pk') {
384-
$result[self::PRIMARY_KEY] = new Index('', array_column($columns, 'name'), true, true);
385-
} elseif ($index['origin'] === 'u') {
386-
$result[self::UNIQUES][] = new Index($index['name'], array_column($columns, 'name'), true);
387-
}
388-
389-
$result[self::INDEXES][] = new Index(
390-
$index['name'],
391-
array_column($columns, 'name'),
392-
(bool) $index['unique'],
393-
$index['origin'] === 'pk',
394-
);
395-
}
396-
397-
if (!isset($result[self::PRIMARY_KEY])) {
398-
/**
399-
* Extra check for PK in case of `INTEGER PRIMARY KEY` with ROWID.
400-
*
401-
* @link https://www.sqlite.org/lang_createtable.html#primkeyconst
402-
*/
403-
$tableColumns = $this->loadTableColumnsInfo($tableName);
404-
405-
foreach ($tableColumns as $tableColumn) {
406-
if ($tableColumn['pk'] > 0) {
407-
$result[self::PRIMARY_KEY] = new Index('', [$tableColumn['name']], true, true);
408-
$result[self::INDEXES][] = $result[self::PRIMARY_KEY];
409-
break;
410-
}
411-
}
412-
}
413-
414-
foreach ($result as $type => $data) {
415-
$this->setTableMetadata($tableName, $type, $data);
416-
}
417-
418-
return $result[$returnType];
419-
}
420-
421343
/**
422344
* @psalm-return list<ForeignKeyInfo>
423345
*/
@@ -448,28 +370,6 @@ private function getPragmaIndexInfo(string $name): array
448370
return $column;
449371
}
450372

451-
/**
452-
* @psalm-return IndexListInfo[]
453-
*/
454-
private function getPragmaIndexList(string $tableName): array
455-
{
456-
/** @psalm-var IndexListInfo[] */
457-
return $this->db
458-
->createCommand('PRAGMA INDEX_LIST(' . $this->db->getQuoter()->quoteValue($tableName) . ')')
459-
->queryAll();
460-
}
461-
462-
/**
463-
* @psalm-return ColumnInfo[]
464-
*/
465-
private function getPragmaTableInfo(string $tableName): array
466-
{
467-
/** @psalm-var ColumnInfo[] */
468-
return $this->db->createCommand(
469-
'PRAGMA TABLE_INFO(' . $this->db->getQuoter()->quoteSimpleTableName($tableName) . ')'
470-
)->queryAll();
471-
}
472-
473373
protected function findViewNames(string $schema = ''): array
474374
{
475375
/** @var string[] */
@@ -484,7 +384,7 @@ private function getJsonColumns(TableSchemaInterface $table): array
484384
{
485385
$result = [];
486386
/** @psalm-var Check[] $checks */
487-
$checks = $this->getTableChecks((string) $table->getFullName());
387+
$checks = $this->getTableChecks($table->getFullName());
488388
$regexp = '/\bjson_valid\(\s*["`\[]?(.+?)["`\]]?\s*\)/i';
489389

490390
foreach ($checks as $check) {

src/TableSchema.php

Lines changed: 0 additions & 21 deletions
This file was deleted.

tests/Provider/SchemaProvider.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use DateTimeImmutable;
88
use Yiisoft\Db\Constant\ColumnType;
9+
use Yiisoft\Db\Constraint\Check;
910
use Yiisoft\Db\Expression\Expression;
1011
use Yiisoft\Db\Schema\Column\ArrayColumn;
1112
use Yiisoft\Db\Schema\Column\BinaryColumn;
@@ -218,18 +219,20 @@ public static function constraints(): array
218219
{
219220
$constraints = parent::constraints();
220221

221-
Assert::setPropertyValue($constraints['1: check'][2][0], 'columnNames', []);
222-
Assert::setPropertyValue($constraints['1: check'][2][0], 'expression', '"C_check" <> \'\'');
223-
Assert::setPropertyValue($constraints['1: unique'][2][0], 'name', 'sqlite_autoindex_T_constraints_1_2');
222+
$constraints['1: check'][2][0] = new Check('', [], '"C_check" <> \'\'');
223+
Assert::setPropertyValue($constraints['1: unique'][2][0], 'name', 'sqlite_autoindex_T_constraints_1_1');
224+
Assert::setPropertyValue($constraints['1: unique'][2][1], 'name', 'sqlite_autoindex_T_constraints_1_2');
224225
Assert::setPropertyValue($constraints['1: index'][2][0], 'name', 'sqlite_autoindex_T_constraints_1_1');
225226
Assert::setPropertyValue($constraints['1: index'][2][1], 'name', 'sqlite_autoindex_T_constraints_1_2');
226227
Assert::setPropertyValue($constraints['2: primary key'][2], 'name', '');
227-
Assert::setPropertyValue($constraints['2: unique'][2][0], 'name', 'sqlite_autoindex_T_constraints_2_2');
228+
Assert::setPropertyValue($constraints['2: unique'][2][0], 'name', 'sqlite_autoindex_T_constraints_2_1');
229+
Assert::setPropertyValue($constraints['2: unique'][2][1], 'name', 'sqlite_autoindex_T_constraints_2_2');
228230
Assert::setPropertyValue($constraints['2: index'][2][0], 'name', 'sqlite_autoindex_T_constraints_2_1');
229231
Assert::setPropertyValue($constraints['2: index'][2][2], 'name', 'sqlite_autoindex_T_constraints_2_2');
230232
Assert::setPropertyValue($constraints['3: foreign key'][2][0], 'name', '0');
231233
$constraints['3: index'][2] = [];
232-
Assert::setPropertyValue($constraints['4: unique'][2][0], 'name', 'sqlite_autoindex_T_constraints_4_2');
234+
Assert::setPropertyValue($constraints['4: unique'][2][0], 'name', 'sqlite_autoindex_T_constraints_4_1');
235+
Assert::setPropertyValue($constraints['4: unique'][2][1], 'name', 'sqlite_autoindex_T_constraints_4_2');
233236

234237
return $constraints;
235238
}

0 commit comments

Comments
 (0)