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 / SQLServerSchemaManager.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
SQLServerSchemaManager.php
390 lines
1 <?php
2 namespace MailPoetVendor\Doctrine\DBAL\Schema;
3 if (!defined('ABSPATH')) exit;
4 use MailPoetVendor\Doctrine\DBAL\Exception;
5 use MailPoetVendor\Doctrine\DBAL\Platforms\SQLServer;
6 use MailPoetVendor\Doctrine\DBAL\Platforms\SQLServerPlatform;
7 use MailPoetVendor\Doctrine\DBAL\Result;
8 use MailPoetVendor\Doctrine\DBAL\Types\Type;
9 use MailPoetVendor\Doctrine\Deprecations\Deprecation;
10 use function array_change_key_case;
11 use function assert;
12 use function count;
13 use function explode;
14 use function implode;
15 use function is_string;
16 use function preg_match;
17 use function sprintf;
18 use function str_replace;
19 use function strpos;
20 use function strtok;
21 use const CASE_LOWER;
22 class SQLServerSchemaManager extends AbstractSchemaManager
23 {
24 private ?string $databaseCollation = null;
25 public function listTableNames()
26 {
27 return $this->doListTableNames();
28 }
29 public function listTables()
30 {
31 return $this->doListTables();
32 }
33 public function listTableDetails($name)
34 {
35 Deprecation::triggerIfCalledFromOutside('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/5595', '%s is deprecated. Use introspectTable() instead.', __METHOD__);
36 return $this->doListTableDetails($name);
37 }
38 public function listTableColumns($table, $database = null)
39 {
40 return $this->doListTableColumns($table, $database);
41 }
42 public function listTableIndexes($table)
43 {
44 return $this->doListTableIndexes($table);
45 }
46 public function listTableForeignKeys($table, $database = null)
47 {
48 return $this->doListTableForeignKeys($table, $database);
49 }
50 public function listSchemaNames() : array
51 {
52 return $this->_conn->fetchFirstColumn(<<<'SQL'
53 SELECT name
54 FROM sys.schemas
55 WHERE name NOT IN('guest', 'INFORMATION_SCHEMA', 'sys')
56 SQL
57 );
58 }
59 protected function _getPortableSequenceDefinition($sequence)
60 {
61 return new Sequence($sequence['name'], (int) $sequence['increment'], (int) $sequence['start_value']);
62 }
63 protected function _getPortableTableColumnDefinition($tableColumn)
64 {
65 $dbType = strtok($tableColumn['type'], '(), ');
66 assert(is_string($dbType));
67 $fixed = null;
68 $length = (int) $tableColumn['length'];
69 $default = $tableColumn['default'];
70 if (!isset($tableColumn['name'])) {
71 $tableColumn['name'] = '';
72 }
73 if ($default !== null) {
74 $default = $this->parseDefaultExpression($default);
75 }
76 switch ($dbType) {
77 case 'nchar':
78 case 'ntext':
79 // Unicode data requires 2 bytes per character
80 $length /= 2;
81 break;
82 case 'nvarchar':
83 if ($length === -1) {
84 break;
85 }
86 // Unicode data requires 2 bytes per character
87 $length /= 2;
88 break;
89 case 'varchar':
90 // TEXT type is returned as VARCHAR(MAX) with a length of -1
91 if ($length === -1) {
92 $dbType = 'text';
93 }
94 break;
95 case 'varbinary':
96 if ($length === -1) {
97 $dbType = 'blob';
98 }
99 break;
100 }
101 if ($dbType === 'char' || $dbType === 'nchar' || $dbType === 'binary') {
102 $fixed = \true;
103 }
104 $type = $this->_platform->getDoctrineTypeMapping($dbType);
105 $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type);
106 $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type);
107 $options = ['unsigned' => \false, 'fixed' => (bool) $fixed, 'default' => $default, 'notnull' => (bool) $tableColumn['notnull'], 'scale' => $tableColumn['scale'], 'precision' => $tableColumn['precision'], 'autoincrement' => (bool) $tableColumn['autoincrement'], 'comment' => $tableColumn['comment'] !== '' ? $tableColumn['comment'] : null];
108 if ($length !== 0 && ($type === 'text' || $type === 'string' || $type === 'binary')) {
109 $options['length'] = $length;
110 }
111 $column = new Column($tableColumn['name'], Type::getType($type), $options);
112 if (isset($tableColumn['collation']) && $tableColumn['collation'] !== 'NULL') {
113 $column->setPlatformOption('collation', $tableColumn['collation']);
114 }
115 return $column;
116 }
117 private function parseDefaultExpression(string $value) : ?string
118 {
119 while (preg_match('/^\\((.*)\\)$/s', $value, $matches) === 1) {
120 $value = $matches[1];
121 }
122 if ($value === 'NULL') {
123 return null;
124 }
125 if (preg_match('/^\'(.*)\'$/s', $value, $matches) === 1) {
126 $value = str_replace("''", "'", $matches[1]);
127 }
128 if ($value === 'getdate()') {
129 return $this->_platform->getCurrentTimestampSQL();
130 }
131 return $value;
132 }
133 protected function _getPortableTableForeignKeysList($tableForeignKeys)
134 {
135 $foreignKeys = [];
136 foreach ($tableForeignKeys as $tableForeignKey) {
137 $name = $tableForeignKey['ForeignKey'];
138 if (!isset($foreignKeys[$name])) {
139 $referencedTableName = $tableForeignKey['ReferenceTableName'];
140 if ($tableForeignKey['ReferenceSchemaName'] !== 'dbo') {
141 $referencedTableName = $tableForeignKey['ReferenceSchemaName'] . '.' . $referencedTableName;
142 }
143 $foreignKeys[$name] = ['local_columns' => [$tableForeignKey['ColumnName']], 'foreign_table' => $referencedTableName, 'foreign_columns' => [$tableForeignKey['ReferenceColumnName']], 'name' => $name, 'options' => ['onUpdate' => str_replace('_', ' ', $tableForeignKey['update_referential_action_desc']), 'onDelete' => str_replace('_', ' ', $tableForeignKey['delete_referential_action_desc'])]];
144 } else {
145 $foreignKeys[$name]['local_columns'][] = $tableForeignKey['ColumnName'];
146 $foreignKeys[$name]['foreign_columns'][] = $tableForeignKey['ReferenceColumnName'];
147 }
148 }
149 return parent::_getPortableTableForeignKeysList($foreignKeys);
150 }
151 protected function _getPortableTableIndexesList($tableIndexes, $tableName = null)
152 {
153 foreach ($tableIndexes as &$tableIndex) {
154 $tableIndex['non_unique'] = (bool) $tableIndex['non_unique'];
155 $tableIndex['primary'] = (bool) $tableIndex['primary'];
156 $tableIndex['flags'] = $tableIndex['flags'] ? [$tableIndex['flags']] : null;
157 }
158 return parent::_getPortableTableIndexesList($tableIndexes, $tableName);
159 }
160 protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
161 {
162 return new ForeignKeyConstraint($tableForeignKey['local_columns'], $tableForeignKey['foreign_table'], $tableForeignKey['foreign_columns'], $tableForeignKey['name'], $tableForeignKey['options']);
163 }
164 protected function _getPortableTableDefinition($table)
165 {
166 if ($table['schema_name'] !== 'dbo') {
167 return $table['schema_name'] . '.' . $table['table_name'];
168 }
169 return $table['table_name'];
170 }
171 protected function _getPortableDatabaseDefinition($database)
172 {
173 return $database['name'];
174 }
175 protected function getPortableNamespaceDefinition(array $namespace)
176 {
177 Deprecation::triggerIfCalledFromOutside('doctrine/dbal', 'https://github.com/doctrine/dbal/issues/4503', 'SQLServerSchemaManager::getPortableNamespaceDefinition() is deprecated,' . ' use SQLServerSchemaManager::listSchemaNames() instead.');
178 return $namespace['name'];
179 }
180 protected function _getPortableViewDefinition($view)
181 {
182 // @todo
183 return new View($view['name'], $view['definition']);
184 }
185 public function alterTable(TableDiff $tableDiff)
186 {
187 $droppedColumns = $tableDiff->getDroppedColumns();
188 if (count($droppedColumns) > 0) {
189 $tableName = ($tableDiff->getOldTable() ?? $tableDiff->getName($this->_platform))->getName();
190 foreach ($droppedColumns as $col) {
191 foreach ($this->getColumnConstraints($tableName, $col->getName()) as $constraint) {
192 $this->_conn->executeStatement(sprintf('ALTER TABLE %s DROP CONSTRAINT %s', $tableName, $constraint));
193 }
194 }
195 }
196 parent::alterTable($tableDiff);
197 }
198 private function getColumnConstraints(string $table, string $column) : iterable
199 {
200 return $this->_conn->iterateColumn(<<<'SQL'
201 SELECT o.name
202 FROM sys.objects o
203 INNER JOIN sys.objects t
204 ON t.object_id = o.parent_object_id
205 AND t.type = 'U'
206 INNER JOIN sys.default_constraints dc
207 ON dc.object_id = o.object_id
208 INNER JOIN sys.columns c
209 ON c.column_id = dc.parent_column_id
210 AND c.object_id = t.object_id
211 WHERE t.name = ?
212 AND c.name = ?
213 SQL
214 , [$table, $column]);
215 }
216 public function createComparator() : Comparator
217 {
218 return new SQLServer\Comparator($this->_platform, $this->getDatabaseCollation());
219 }
220 private function getDatabaseCollation() : string
221 {
222 if ($this->databaseCollation === null) {
223 $databaseCollation = $this->_conn->fetchOne('SELECT collation_name FROM sys.databases WHERE name = ' . $this->_platform->getCurrentDatabaseExpression());
224 // a database is always selected, even if omitted in the connection parameters
225 assert(is_string($databaseCollation));
226 $this->databaseCollation = $databaseCollation;
227 }
228 return $this->databaseCollation;
229 }
230 protected function selectTableNames(string $databaseName) : Result
231 {
232 // The "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams
233 $sql = <<<'SQL'
234 SELECT name AS table_name,
235 SCHEMA_NAME(schema_id) AS schema_name
236 FROM sys.objects
237 WHERE type = 'U'
238 AND name != 'sysdiagrams'
239 ORDER BY name
240 SQL;
241 return $this->_conn->executeQuery($sql);
242 }
243 protected function selectTableColumns(string $databaseName, ?string $tableName = null) : Result
244 {
245 $sql = 'SELECT';
246 if ($tableName === null) {
247 $sql .= ' obj.name AS table_name, scm.name AS schema_name,';
248 }
249 $sql .= <<<'SQL'
250 col.name,
251 type.name AS type,
252 col.max_length AS length,
253 ~col.is_nullable AS notnull,
254 def.definition AS [default],
255 col.scale,
256 col.precision,
257 col.is_identity AS autoincrement,
258 col.collation_name AS collation,
259 -- CAST avoids driver error for sql_variant type
260 CAST(prop.value AS NVARCHAR(MAX)) AS comment
261 FROM sys.columns AS col
262 JOIN sys.types AS type
263 ON col.user_type_id = type.user_type_id
264 JOIN sys.objects AS obj
265 ON col.object_id = obj.object_id
266 JOIN sys.schemas AS scm
267 ON obj.schema_id = scm.schema_id
268 LEFT JOIN sys.default_constraints def
269 ON col.default_object_id = def.object_id
270 AND col.object_id = def.parent_object_id
271 LEFT JOIN sys.extended_properties AS prop
272 ON obj.object_id = prop.major_id
273 AND col.column_id = prop.minor_id
274 AND prop.name = 'MS_Description'
275 SQL;
276 // The "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams
277 $conditions = ["obj.type = 'U'", "obj.name != 'sysdiagrams'"];
278 $params = [];
279 if ($tableName !== null) {
280 $conditions[] = $this->getTableWhereClause($tableName, 'scm.name', 'obj.name');
281 }
282 $sql .= ' WHERE ' . implode(' AND ', $conditions);
283 return $this->_conn->executeQuery($sql, $params);
284 }
285 protected function selectIndexColumns(string $databaseName, ?string $tableName = null) : Result
286 {
287 $sql = 'SELECT';
288 if ($tableName === null) {
289 $sql .= ' tbl.name AS table_name, scm.name AS schema_name,';
290 }
291 $sql .= <<<'SQL'
292 idx.name AS key_name,
293 col.name AS column_name,
294 ~idx.is_unique AS non_unique,
295 idx.is_primary_key AS [primary],
296 CASE idx.type
297 WHEN '1' THEN 'clustered'
298 WHEN '2' THEN 'nonclustered'
299 ELSE NULL
300 END AS flags
301 FROM sys.tables AS tbl
302 JOIN sys.schemas AS scm
303 ON tbl.schema_id = scm.schema_id
304 JOIN sys.indexes AS idx
305 ON tbl.object_id = idx.object_id
306 JOIN sys.index_columns AS idxcol
307 ON idx.object_id = idxcol.object_id
308 AND idx.index_id = idxcol.index_id
309 JOIN sys.columns AS col
310 ON idxcol.object_id = col.object_id
311 AND idxcol.column_id = col.column_id
312 SQL;
313 $conditions = [];
314 $params = [];
315 if ($tableName !== null) {
316 $conditions[] = $this->getTableWhereClause($tableName, 'scm.name', 'tbl.name');
317 $sql .= ' WHERE ' . implode(' AND ', $conditions);
318 }
319 $sql .= ' ORDER BY idx.index_id, idxcol.key_ordinal';
320 return $this->_conn->executeQuery($sql, $params);
321 }
322 protected function selectForeignKeyColumns(string $databaseName, ?string $tableName = null) : Result
323 {
324 $sql = 'SELECT';
325 if ($tableName === null) {
326 $sql .= ' OBJECT_NAME (f.parent_object_id) AS table_name, SCHEMA_NAME(f.schema_id) AS schema_name,';
327 }
328 $sql .= <<<'SQL'
329 f.name AS ForeignKey,
330 SCHEMA_NAME (f.SCHEMA_ID) AS SchemaName,
331 OBJECT_NAME (f.parent_object_id) AS TableName,
332 COL_NAME (fc.parent_object_id,fc.parent_column_id) AS ColumnName,
333 SCHEMA_NAME (o.SCHEMA_ID) ReferenceSchemaName,
334 OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
335 COL_NAME(fc.referenced_object_id,fc.referenced_column_id) AS ReferenceColumnName,
336 f.delete_referential_action_desc,
337 f.update_referential_action_desc
338 FROM sys.foreign_keys AS f
339 INNER JOIN sys.foreign_key_columns AS fc
340 INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id
341 ON f.OBJECT_ID = fc.constraint_object_id
342 SQL;
343 $conditions = [];
344 $params = [];
345 if ($tableName !== null) {
346 $conditions[] = $this->getTableWhereClause($tableName, 'SCHEMA_NAME(f.schema_id)', 'OBJECT_NAME(f.parent_object_id)');
347 $sql .= ' WHERE ' . implode(' AND ', $conditions);
348 }
349 $sql .= ' ORDER BY fc.constraint_column_id';
350 return $this->_conn->executeQuery($sql, $params);
351 }
352 protected function fetchTableOptionsByTable(string $databaseName, ?string $tableName = null) : array
353 {
354 $sql = <<<'SQL'
355 SELECT
356 scm.name AS schema_name,
357 tbl.name AS table_name,
358 p.value AS [table_comment]
359 FROM
360 sys.tables AS tbl
361 JOIN sys.schemas AS scm
362 ON tbl.schema_id = scm.schema_id
363 INNER JOIN sys.extended_properties AS p ON p.major_id=tbl.object_id AND p.minor_id=0 AND p.class=1
364 SQL;
365 $conditions = ["p.name = N'MS_Description'"];
366 if ($tableName !== null) {
367 $conditions[] = $this->getTableWhereClause($tableName, 'scm.name', 'tbl.name');
368 }
369 $sql .= ' WHERE ' . implode(' AND ', $conditions);
370 $tableOptions = [];
371 foreach ($this->_conn->iterateAssociative($sql) as $data) {
372 $data = array_change_key_case($data, CASE_LOWER);
373 $tableOptions[$this->_getPortableTableDefinition($data)] = ['comment' => $data['table_comment']];
374 }
375 return $tableOptions;
376 }
377 private function getTableWhereClause($table, $schemaColumn, $tableColumn) : string
378 {
379 if (strpos($table, '.') !== \false) {
380 [$schema, $table] = explode('.', $table);
381 $schema = $this->_platform->quoteStringLiteral($schema);
382 $table = $this->_platform->quoteStringLiteral($table);
383 } else {
384 $schema = 'SCHEMA_NAME()';
385 $table = $this->_platform->quoteStringLiteral($table);
386 }
387 return sprintf('(%s = %s AND %s = %s)', $tableColumn, $table, $schemaColumn, $schema);
388 }
389 }
390