summaryrefslogtreecommitdiff
path: root/vendor/doctrine/dbal/src/Platforms/MariaDBPlatform.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/doctrine/dbal/src/Platforms/MariaDBPlatform.php')
-rw-r--r--vendor/doctrine/dbal/src/Platforms/MariaDBPlatform.php165
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
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Platforms;
6
7use Doctrine\DBAL\Platforms\Keywords\KeywordList;
8use Doctrine\DBAL\Platforms\Keywords\MariaDBKeywords;
9use Doctrine\DBAL\Schema\ForeignKeyConstraint;
10use Doctrine\DBAL\Schema\TableDiff;
11use Doctrine\DBAL\Types\JsonType;
12
13use function array_diff_key;
14use function array_merge;
15use function count;
16use function in_array;
17
18/**
19 * Provides the behavior, features and SQL dialect of the MariaDB database platform of the oldest supported version.
20 */
21class 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}