1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace Atk4\Data\Persistence\Sql\Sqlite;
6:
7: use Doctrine\DBAL\Exception as DbalException;
8: use Doctrine\DBAL\Schema\Identifier;
9: use Doctrine\DBAL\Schema\Table;
10: use Doctrine\DBAL\Schema\TableDiff;
11:
12: trait SchemaManagerTrait
13: {
14: #[\Override]
15: public function alterTable(TableDiff $tableDiff): void
16: {
17: $hadForeignKeysEnabled = (bool) $this->_conn->executeQuery('PRAGMA foreign_keys')->fetchOne();
18: if ($hadForeignKeysEnabled) {
19: $this->_execSql('PRAGMA foreign_keys = 0');
20: }
21:
22: parent::alterTable($tableDiff);
23:
24: if ($hadForeignKeysEnabled) {
25: $this->_execSql('PRAGMA foreign_keys = 1');
26:
27: $rows = $this->_conn->executeQuery('PRAGMA foreign_key_check')->fetchAllAssociative();
28: if (count($rows) > 0) {
29: throw new DbalException('Foreign key constraints are violated');
30: }
31: }
32: }
33:
34: // fix collations unescape for SqliteSchemaManager::parseColumnCollationFromSQL() method
35: // https://github.com/doctrine/dbal/issues/6129
36:
37: #[\Override]
38: protected function _getPortableTableColumnList($table, $database, $tableColumns)
39: {
40: $res = parent::_getPortableTableColumnList($table, $database, $tableColumns);
41: foreach ($res as $column) {
42: if ($column->hasPlatformOption('collation')) {
43: $column->setPlatformOption('collation', $this->unquoteTableIdentifier($column->getPlatformOption('collation')));
44: }
45: }
46:
47: return $res;
48: }
49:
50: // fix quoted table name support for private SqliteSchemaManager::getCreateTableSQL() method
51: // https://github.com/doctrine/dbal/blob/3.3.7/src/Schema/SqliteSchemaManager.php#L539
52: // TODO submit a PR with fixed SqliteSchemaManager to DBAL
53:
54: private function unquoteTableIdentifier(string $tableName): string
55: {
56: return (new Identifier($tableName))->getName();
57: }
58:
59: #[\Override]
60: public function listTableDetails($name): Table
61: {
62: return parent::listTableDetails($this->unquoteTableIdentifier($name));
63: }
64:
65: #[\Override]
66: public function listTableIndexes($table): array
67: {
68: return parent::listTableIndexes($this->unquoteTableIdentifier($table));
69: }
70:
71: #[\Override]
72: public function listTableForeignKeys($table, $database = null): array
73: {
74: return parent::listTableForeignKeys($this->unquoteTableIdentifier($table), $database);
75: }
76: }
77: