PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.35.1
MailPoet – Newsletters, Email Marketing, and Automation v5.35.1
5.36.0 5.35.1 5.35.0 5.34.3 5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / vendor-prefixed / doctrine / dbal / src / Schema / MySQLSchemaManager.php
mailpoet / vendor-prefixed / doctrine / dbal / src / Schema Last commit date
Exception 2 years ago Visitor 9 months ago AbstractAsset.php 2 years ago AbstractSchemaManager.php 9 months ago Column.php 2 years ago ColumnDiff.php 2 years ago Comparator.php 2 years ago Constraint.php 2 years ago DB2SchemaManager.php 2 years ago DefaultSchemaManagerFactory.php 2 years ago ForeignKeyConstraint.php 9 months ago Identifier.php 2 years ago Index.php 2 years ago LegacySchemaManagerFactory.php 2 years ago MySQLSchemaManager.php 9 months ago OracleSchemaManager.php 2 years ago PostgreSQLSchemaManager.php 9 months ago SQLServerSchemaManager.php 9 months ago Schema.php 2 years ago SchemaConfig.php 2 years ago SchemaDiff.php 2 years ago SchemaException.php 2 years ago SchemaManagerFactory.php 2 years ago Sequence.php 2 years ago SqliteSchemaManager.php 8 months ago Table.php 2 years ago TableDiff.php 2 years ago UniqueConstraint.php 2 years ago View.php 2 years ago
MySQLSchemaManager.php
368 lines
1 <?php
2 namespace MailPoetVendor\Doctrine\DBAL\Schema;
3 if (!defined('ABSPATH')) exit;
4 use MailPoetVendor\Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
5 use MailPoetVendor\Doctrine\DBAL\Platforms\MariaDb1027Platform;
6 use MailPoetVendor\Doctrine\DBAL\Platforms\MySQL;
7 use MailPoetVendor\Doctrine\DBAL\Platforms\MySQL\CollationMetadataProvider\CachingCollationMetadataProvider;
8 use MailPoetVendor\Doctrine\DBAL\Platforms\MySQL\CollationMetadataProvider\ConnectionCollationMetadataProvider;
9 use MailPoetVendor\Doctrine\DBAL\Result;
10 use MailPoetVendor\Doctrine\DBAL\Types\Type;
11 use MailPoetVendor\Doctrine\Deprecations\Deprecation;
12 use function array_change_key_case;
13 use function array_shift;
14 use function assert;
15 use function explode;
16 use function implode;
17 use function is_string;
18 use function preg_match;
19 use function strpos;
20 use function strtok;
21 use function strtolower;
22 use function strtr;
23 use const CASE_LOWER;
24 class MySQLSchemaManager extends AbstractSchemaManager
25 {
26 private const MARIADB_ESCAPE_SEQUENCES = [
27 '\\0' => "\x00",
28 "\\'" => "'",
29 '\\"' => '"',
30 '\\b' => "\\b",
31 '\\n' => "\n",
32 '\\r' => "\r",
33 '\\t' => "\t",
34 '\\Z' => "\x1a",
35 '\\\\' => '\\',
36 '\\%' => '%',
37 '\\_' => '_',
38 // Internally, MariaDB escapes single quotes using the standard syntax
39 "''" => "'",
40 ];
41 public function listTableNames()
42 {
43 return $this->doListTableNames();
44 }
45 public function listTables()
46 {
47 return $this->doListTables();
48 }
49 public function listTableDetails($name)
50 {
51 Deprecation::triggerIfCalledFromOutside('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/5595', '%s is deprecated. Use introspectTable() instead.', __METHOD__);
52 return $this->doListTableDetails($name);
53 }
54 public function listTableColumns($table, $database = null)
55 {
56 return $this->doListTableColumns($table, $database);
57 }
58 public function listTableIndexes($table)
59 {
60 return $this->doListTableIndexes($table);
61 }
62 public function listTableForeignKeys($table, $database = null)
63 {
64 return $this->doListTableForeignKeys($table, $database);
65 }
66 protected function _getPortableViewDefinition($view)
67 {
68 return new View($view['TABLE_NAME'], $view['VIEW_DEFINITION']);
69 }
70 protected function _getPortableTableDefinition($table)
71 {
72 return array_shift($table);
73 }
74 protected function _getPortableTableIndexesList($tableIndexes, $tableName = null)
75 {
76 foreach ($tableIndexes as $k => $v) {
77 $v = array_change_key_case($v, CASE_LOWER);
78 if ($v['key_name'] === 'PRIMARY') {
79 $v['primary'] = \true;
80 } else {
81 $v['primary'] = \false;
82 }
83 if (strpos($v['index_type'], 'FULLTEXT') !== \false) {
84 $v['flags'] = ['FULLTEXT'];
85 } elseif (strpos($v['index_type'], 'SPATIAL') !== \false) {
86 $v['flags'] = ['SPATIAL'];
87 }
88 // Ignore prohibited prefix `length` for spatial index
89 if (strpos($v['index_type'], 'SPATIAL') === \false) {
90 $v['length'] = isset($v['sub_part']) ? (int) $v['sub_part'] : null;
91 }
92 $tableIndexes[$k] = $v;
93 }
94 return parent::_getPortableTableIndexesList($tableIndexes, $tableName);
95 }
96 protected function _getPortableDatabaseDefinition($database)
97 {
98 return $database['Database'];
99 }
100 protected function _getPortableTableColumnDefinition($tableColumn)
101 {
102 $tableColumn = array_change_key_case($tableColumn, CASE_LOWER);
103 $dbType = strtolower($tableColumn['type']);
104 $dbType = strtok($dbType, '(), ');
105 assert(is_string($dbType));
106 $length = $tableColumn['length'] ?? strtok('(), ');
107 $fixed = null;
108 if (!isset($tableColumn['name'])) {
109 $tableColumn['name'] = '';
110 }
111 $scale = null;
112 $precision = null;
113 $type = $origType = $this->_platform->getDoctrineTypeMapping($dbType);
114 // In cases where not connected to a database DESCRIBE $table does not return 'Comment'
115 if (isset($tableColumn['comment'])) {
116 $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type);
117 $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type);
118 }
119 switch ($dbType) {
120 case 'char':
121 case 'binary':
122 $fixed = \true;
123 break;
124 case 'float':
125 case 'double':
126 case 'real':
127 case 'numeric':
128 case 'decimal':
129 if (preg_match('([A-Za-z]+\\(([0-9]+),([0-9]+)\\))', $tableColumn['type'], $match) === 1) {
130 $precision = $match[1];
131 $scale = $match[2];
132 $length = null;
133 }
134 break;
135 case 'tinytext':
136 $length = AbstractMySQLPlatform::LENGTH_LIMIT_TINYTEXT;
137 break;
138 case 'text':
139 $length = AbstractMySQLPlatform::LENGTH_LIMIT_TEXT;
140 break;
141 case 'mediumtext':
142 $length = AbstractMySQLPlatform::LENGTH_LIMIT_MEDIUMTEXT;
143 break;
144 case 'tinyblob':
145 $length = AbstractMySQLPlatform::LENGTH_LIMIT_TINYBLOB;
146 break;
147 case 'blob':
148 $length = AbstractMySQLPlatform::LENGTH_LIMIT_BLOB;
149 break;
150 case 'mediumblob':
151 $length = AbstractMySQLPlatform::LENGTH_LIMIT_MEDIUMBLOB;
152 break;
153 case 'tinyint':
154 case 'smallint':
155 case 'mediumint':
156 case 'int':
157 case 'integer':
158 case 'bigint':
159 case 'year':
160 $length = null;
161 break;
162 }
163 if ($this->_platform instanceof MariaDb1027Platform) {
164 $columnDefault = $this->getMariaDb1027ColumnDefault($this->_platform, $tableColumn['default']);
165 } else {
166 $columnDefault = $tableColumn['default'];
167 }
168 $options = ['length' => $length !== null ? (int) $length : null, 'unsigned' => strpos($tableColumn['type'], 'unsigned') !== \false, 'fixed' => (bool) $fixed, 'default' => $columnDefault, 'notnull' => $tableColumn['null'] !== 'YES', 'scale' => null, 'precision' => null, 'autoincrement' => strpos($tableColumn['extra'], 'auto_increment') !== \false, 'comment' => isset($tableColumn['comment']) && $tableColumn['comment'] !== '' ? $tableColumn['comment'] : null];
169 if ($scale !== null && $precision !== null) {
170 $options['scale'] = (int) $scale;
171 $options['precision'] = (int) $precision;
172 }
173 $column = new Column($tableColumn['field'], Type::getType($type), $options);
174 if (isset($tableColumn['characterset'])) {
175 $column->setPlatformOption('charset', $tableColumn['characterset']);
176 }
177 if (isset($tableColumn['collation'])) {
178 $column->setPlatformOption('collation', $tableColumn['collation']);
179 }
180 if (isset($tableColumn['declarationMismatch'])) {
181 $column->setPlatformOption('declarationMismatch', $tableColumn['declarationMismatch']);
182 }
183 // Check underlying database type where doctrine type is inferred from DC2Type comment
184 // and set a flag if it is not as expected.
185 if ($type === 'json' && $origType !== $type && $this->expectedDbType($type, $options) !== $dbType) {
186 $column->setPlatformOption('declarationMismatch', \true);
187 }
188 return $column;
189 }
190 private function expectedDbType(string $type, array $tableColumn) : string
191 {
192 $_type = Type::getType($type);
193 $expectedDbType = strtolower($_type->getSQLDeclaration($tableColumn, $this->_platform));
194 $expectedDbType = strtok($expectedDbType, '(), ');
195 return $expectedDbType === \false ? '' : $expectedDbType;
196 }
197 private function getMariaDb1027ColumnDefault(MariaDb1027Platform $platform, ?string $columnDefault) : ?string
198 {
199 if ($columnDefault === 'NULL' || $columnDefault === null) {
200 return null;
201 }
202 if (preg_match('/^\'(.*)\'$/', $columnDefault, $matches) === 1) {
203 return strtr($matches[1], self::MARIADB_ESCAPE_SEQUENCES);
204 }
205 switch ($columnDefault) {
206 case 'current_timestamp()':
207 return $platform->getCurrentTimestampSQL();
208 case 'curdate()':
209 return $platform->getCurrentDateSQL();
210 case 'curtime()':
211 return $platform->getCurrentTimeSQL();
212 }
213 return $columnDefault;
214 }
215 protected function _getPortableTableForeignKeysList($tableForeignKeys)
216 {
217 $list = [];
218 foreach ($tableForeignKeys as $value) {
219 $value = array_change_key_case($value, CASE_LOWER);
220 if (!isset($list[$value['constraint_name']])) {
221 if (!isset($value['delete_rule']) || $value['delete_rule'] === 'RESTRICT') {
222 $value['delete_rule'] = null;
223 }
224 if (!isset($value['update_rule']) || $value['update_rule'] === 'RESTRICT') {
225 $value['update_rule'] = null;
226 }
227 $list[$value['constraint_name']] = ['name' => $value['constraint_name'], 'local' => [], 'foreign' => [], 'foreignTable' => $value['referenced_table_name'], 'onDelete' => $value['delete_rule'], 'onUpdate' => $value['update_rule']];
228 }
229 $list[$value['constraint_name']]['local'][] = $value['column_name'];
230 $list[$value['constraint_name']]['foreign'][] = $value['referenced_column_name'];
231 }
232 return parent::_getPortableTableForeignKeysList($list);
233 }
234 protected function _getPortableTableForeignKeyDefinition($tableForeignKey) : ForeignKeyConstraint
235 {
236 return new ForeignKeyConstraint($tableForeignKey['local'], $tableForeignKey['foreignTable'], $tableForeignKey['foreign'], $tableForeignKey['name'], ['onDelete' => $tableForeignKey['onDelete'], 'onUpdate' => $tableForeignKey['onUpdate']]);
237 }
238 public function createComparator() : Comparator
239 {
240 return new MySQL\Comparator($this->_platform, new CachingCollationMetadataProvider(new ConnectionCollationMetadataProvider($this->_conn)));
241 }
242 protected function selectTableNames(string $databaseName) : Result
243 {
244 $sql = <<<'SQL'
245 SELECT TABLE_NAME
246 FROM information_schema.TABLES
247 WHERE TABLE_SCHEMA = ?
248 AND TABLE_TYPE = 'BASE TABLE'
249 ORDER BY TABLE_NAME
250 SQL;
251 return $this->_conn->executeQuery($sql, [$databaseName]);
252 }
253 protected function selectTableColumns(string $databaseName, ?string $tableName = null) : Result
254 {
255 // @todo 4.0 - call getColumnTypeSQLSnippet() instead
256 [$columnTypeSQL, $joinCheckConstraintSQL] = $this->_platform->getColumnTypeSQLSnippets('c', $databaseName);
257 $sql = 'SELECT';
258 if ($tableName === null) {
259 $sql .= ' c.TABLE_NAME,';
260 }
261 $sql .= <<<SQL
262 c.COLUMN_NAME AS field,
263 {$columnTypeSQL} AS type,
264 c.IS_NULLABLE AS `null`,
265 c.COLUMN_KEY AS `key`,
266 c.COLUMN_DEFAULT AS `default`,
267 c.EXTRA,
268 c.COLUMN_COMMENT AS comment,
269 c.CHARACTER_SET_NAME AS characterset,
270 c.COLLATION_NAME AS collation
271 FROM information_schema.COLUMNS c
272 INNER JOIN information_schema.TABLES t
273 ON t.TABLE_NAME = c.TABLE_NAME
274 {$joinCheckConstraintSQL}
275 SQL;
276 // The schema name is passed multiple times as a literal in the WHERE clause instead of using a JOIN condition
277 // in order to avoid performance issues on MySQL older than 8.0 and the corresponding MariaDB versions
278 // caused by https://bugs.mysql.com/bug.php?id=81347
279 $conditions = ['c.TABLE_SCHEMA = ?', 't.TABLE_SCHEMA = ?', "t.TABLE_TYPE = 'BASE TABLE'"];
280 $params = [$databaseName, $databaseName];
281 if ($tableName !== null) {
282 $conditions[] = 't.TABLE_NAME = ?';
283 $params[] = $tableName;
284 }
285 $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY ORDINAL_POSITION';
286 return $this->_conn->executeQuery($sql, $params);
287 }
288 protected function selectIndexColumns(string $databaseName, ?string $tableName = null) : Result
289 {
290 $sql = 'SELECT';
291 if ($tableName === null) {
292 $sql .= ' TABLE_NAME,';
293 }
294 $sql .= <<<'SQL'
295 NON_UNIQUE AS Non_Unique,
296 INDEX_NAME AS Key_name,
297 COLUMN_NAME AS Column_Name,
298 SUB_PART AS Sub_Part,
299 INDEX_TYPE AS Index_Type
300 FROM information_schema.STATISTICS
301 SQL;
302 $conditions = ['TABLE_SCHEMA = ?'];
303 $params = [$databaseName];
304 if ($tableName !== null) {
305 $conditions[] = 'TABLE_NAME = ?';
306 $params[] = $tableName;
307 }
308 $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY SEQ_IN_INDEX';
309 return $this->_conn->executeQuery($sql, $params);
310 }
311 protected function selectForeignKeyColumns(string $databaseName, ?string $tableName = null) : Result
312 {
313 $sql = 'SELECT DISTINCT';
314 if ($tableName === null) {
315 $sql .= ' k.TABLE_NAME,';
316 }
317 $sql .= <<<'SQL'
318 k.CONSTRAINT_NAME,
319 k.COLUMN_NAME,
320 k.REFERENCED_TABLE_NAME,
321 k.REFERENCED_COLUMN_NAME,
322 k.ORDINAL_POSITION /*!50116,
323 c.UPDATE_RULE,
324 c.DELETE_RULE */
325 FROM information_schema.key_column_usage k /*!50116
326 INNER JOIN information_schema.referential_constraints c
327 ON c.CONSTRAINT_NAME = k.CONSTRAINT_NAME
328 AND c.TABLE_NAME = k.TABLE_NAME */
329 SQL;
330 $conditions = ['k.TABLE_SCHEMA = ?'];
331 $params = [$databaseName];
332 if ($tableName !== null) {
333 $conditions[] = 'k.TABLE_NAME = ?';
334 $params[] = $tableName;
335 }
336 $conditions[] = 'k.REFERENCED_COLUMN_NAME IS NOT NULL';
337 $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' /*!50116 AND c.CONSTRAINT_SCHEMA = ' . $this->_conn->quote($databaseName) . ' */' . ' ORDER BY k.ORDINAL_POSITION';
338 return $this->_conn->executeQuery($sql, $params);
339 }
340 protected function fetchTableOptionsByTable(string $databaseName, ?string $tableName = null) : array
341 {
342 $sql = $this->_platform->fetchTableOptionsByTable($tableName !== null);
343 $params = [$databaseName];
344 if ($tableName !== null) {
345 $params[] = $tableName;
346 }
347 $metadata = $this->_conn->executeQuery($sql, $params)->fetchAllAssociativeIndexed();
348 $tableOptions = [];
349 foreach ($metadata as $table => $data) {
350 $data = array_change_key_case($data, CASE_LOWER);
351 $tableOptions[$table] = ['engine' => $data['engine'], 'collation' => $data['table_collation'], 'charset' => $data['character_set_name'], 'autoincrement' => $data['auto_increment'], 'comment' => $data['table_comment'], 'create_options' => $this->parseCreateOptions($data['create_options'])];
352 }
353 return $tableOptions;
354 }
355 private function parseCreateOptions(?string $string) : array
356 {
357 $options = [];
358 if ($string === null || $string === '') {
359 return $options;
360 }
361 foreach (explode(' ', $string) as $pair) {
362 $parts = explode('=', $pair, 2);
363 $options[$parts[0]] = $parts[1] ?? \true;
364 }
365 return $options;
366 }
367 }
368