diff options
Diffstat (limited to 'vendor/doctrine/dbal/src/Platforms/MariaDBPlatform.php')
-rw-r--r-- | vendor/doctrine/dbal/src/Platforms/MariaDBPlatform.php | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/vendor/doctrine/dbal/src/Platforms/MariaDBPlatform.php b/vendor/doctrine/dbal/src/Platforms/MariaDBPlatform.php new file mode 100644 index 0000000..d4082ae --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/MariaDBPlatform.php | |||
@@ -0,0 +1,165 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\DBAL\Platforms; | ||
6 | |||
7 | use Doctrine\DBAL\Platforms\Keywords\KeywordList; | ||
8 | use Doctrine\DBAL\Platforms\Keywords\MariaDBKeywords; | ||
9 | use Doctrine\DBAL\Schema\ForeignKeyConstraint; | ||
10 | use Doctrine\DBAL\Schema\TableDiff; | ||
11 | use Doctrine\DBAL\Types\JsonType; | ||
12 | |||
13 | use function array_diff_key; | ||
14 | use function array_merge; | ||
15 | use function count; | ||
16 | use function in_array; | ||
17 | |||
18 | /** | ||
19 | * Provides the behavior, features and SQL dialect of the MariaDB database platform of the oldest supported version. | ||
20 | */ | ||
21 | class MariaDBPlatform extends AbstractMySQLPlatform | ||
22 | { | ||
23 | /** | ||
24 | * Generate SQL snippets to reverse the aliasing of JSON to LONGTEXT. | ||
25 | * | ||
26 | * MariaDb aliases columns specified as JSON to LONGTEXT and sets a CHECK constraint to ensure the column | ||
27 | * is valid json. This function generates the SQL snippets which reverse this aliasing i.e. report a column | ||
28 | * as JSON where it was originally specified as such instead of LONGTEXT. | ||
29 | * | ||
30 | * The CHECK constraints are stored in information_schema.CHECK_CONSTRAINTS so query that table. | ||
31 | */ | ||
32 | public function getColumnTypeSQLSnippet(string $tableAlias, string $databaseName): string | ||
33 | { | ||
34 | $subQueryAlias = 'i_' . $tableAlias; | ||
35 | |||
36 | $databaseName = $this->quoteStringLiteral($databaseName); | ||
37 | |||
38 | // The check for `CONSTRAINT_SCHEMA = $databaseName` is mandatory here to prevent performance issues | ||
39 | return <<<SQL | ||
40 | IF( | ||
41 | $tableAlias.COLUMN_TYPE = 'longtext' | ||
42 | AND EXISTS( | ||
43 | SELECT * FROM information_schema.CHECK_CONSTRAINTS $subQueryAlias | ||
44 | WHERE $subQueryAlias.CONSTRAINT_SCHEMA = $databaseName | ||
45 | AND $subQueryAlias.TABLE_NAME = $tableAlias.TABLE_NAME | ||
46 | AND $subQueryAlias.CHECK_CLAUSE = CONCAT( | ||
47 | 'json_valid(`', | ||
48 | $tableAlias.COLUMN_NAME, | ||
49 | '`)' | ||
50 | ) | ||
51 | ), | ||
52 | 'json', | ||
53 | $tableAlias.COLUMN_TYPE | ||
54 | ) | ||
55 | SQL; | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * {@inheritDoc} | ||
60 | */ | ||
61 | protected function getPreAlterTableRenameIndexForeignKeySQL(TableDiff $diff): array | ||
62 | { | ||
63 | $sql = []; | ||
64 | $tableName = $diff->getOldTable()->getQuotedName($this); | ||
65 | |||
66 | $modifiedForeignKeys = $diff->getModifiedForeignKeys(); | ||
67 | |||
68 | foreach ($this->getRemainingForeignKeyConstraintsRequiringRenamedIndexes($diff) as $foreignKey) { | ||
69 | if (in_array($foreignKey, $modifiedForeignKeys, true)) { | ||
70 | continue; | ||
71 | } | ||
72 | |||
73 | $sql[] = $this->getDropForeignKeySQL($foreignKey->getQuotedName($this), $tableName); | ||
74 | } | ||
75 | |||
76 | return $sql; | ||
77 | } | ||
78 | |||
79 | /** | ||
80 | * {@inheritDoc} | ||
81 | */ | ||
82 | protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff): array | ||
83 | { | ||
84 | return array_merge( | ||
85 | parent::getPostAlterTableIndexForeignKeySQL($diff), | ||
86 | $this->getPostAlterTableRenameIndexForeignKeySQL($diff), | ||
87 | ); | ||
88 | } | ||
89 | |||
90 | /** @return list<string> */ | ||
91 | private function getPostAlterTableRenameIndexForeignKeySQL(TableDiff $diff): array | ||
92 | { | ||
93 | $sql = []; | ||
94 | |||
95 | $tableName = $diff->getOldTable()->getQuotedName($this); | ||
96 | |||
97 | $modifiedForeignKeys = $diff->getModifiedForeignKeys(); | ||
98 | |||
99 | foreach ($this->getRemainingForeignKeyConstraintsRequiringRenamedIndexes($diff) as $foreignKey) { | ||
100 | if (in_array($foreignKey, $modifiedForeignKeys, true)) { | ||
101 | continue; | ||
102 | } | ||
103 | |||
104 | $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName); | ||
105 | } | ||
106 | |||
107 | return $sql; | ||
108 | } | ||
109 | |||
110 | /** | ||
111 | * Returns the remaining foreign key constraints that require one of the renamed indexes. | ||
112 | * | ||
113 | * "Remaining" here refers to the diff between the foreign keys currently defined in the associated | ||
114 | * table and the foreign keys to be removed. | ||
115 | * | ||
116 | * @param TableDiff $diff The table diff to evaluate. | ||
117 | * | ||
118 | * @return ForeignKeyConstraint[] | ||
119 | */ | ||
120 | private function getRemainingForeignKeyConstraintsRequiringRenamedIndexes(TableDiff $diff): array | ||
121 | { | ||
122 | $renamedIndexes = $diff->getRenamedIndexes(); | ||
123 | |||
124 | if (count($renamedIndexes) === 0) { | ||
125 | return []; | ||
126 | } | ||
127 | |||
128 | $foreignKeys = []; | ||
129 | |||
130 | $remainingForeignKeys = array_diff_key( | ||
131 | $diff->getOldTable()->getForeignKeys(), | ||
132 | $diff->getDroppedForeignKeys(), | ||
133 | ); | ||
134 | |||
135 | foreach ($remainingForeignKeys as $foreignKey) { | ||
136 | foreach ($renamedIndexes as $index) { | ||
137 | if ($foreignKey->intersectsIndexColumns($index)) { | ||
138 | $foreignKeys[] = $foreignKey; | ||
139 | |||
140 | break; | ||
141 | } | ||
142 | } | ||
143 | } | ||
144 | |||
145 | return $foreignKeys; | ||
146 | } | ||
147 | |||
148 | /** {@inheritDoc} */ | ||
149 | public function getColumnDeclarationSQL(string $name, array $column): string | ||
150 | { | ||
151 | // MariaDb forces column collation to utf8mb4_bin where the column was declared as JSON so ignore | ||
152 | // collation and character set for json columns as attempting to set them can cause an error. | ||
153 | if ($this->getJsonTypeDeclarationSQL([]) === 'JSON' && ($column['type'] ?? null) instanceof JsonType) { | ||
154 | unset($column['collation']); | ||
155 | unset($column['charset']); | ||
156 | } | ||
157 | |||
158 | return parent::getColumnDeclarationSQL($name, $column); | ||
159 | } | ||
160 | |||
161 | protected function createReservedKeywordsList(): KeywordList | ||
162 | { | ||
163 | return new MariaDBKeywords(); | ||
164 | } | ||
165 | } | ||