1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
4
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
5
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
6
|
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
7
|
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
8
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
9
|
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
10
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
11
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
12
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
13
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
14
|
|
|
* |
15
|
|
|
* This software consists of voluntary contributions made by many individuals |
16
|
|
|
* and is licensed under the MIT license. For more information, see |
17
|
|
|
* <http://www.doctrine-project.org>. |
18
|
|
|
*/ |
19
|
|
|
|
20
|
|
|
namespace Doctrine\DBAL\Platforms; |
21
|
|
|
|
22
|
|
|
use Doctrine\DBAL\Connection; |
23
|
|
|
use Doctrine\DBAL\DBALException; |
24
|
|
|
use Doctrine\DBAL\LockMode; |
25
|
|
|
use Doctrine\DBAL\Schema\Column; |
26
|
|
|
use Doctrine\DBAL\Schema\ColumnDiff; |
27
|
|
|
use Doctrine\DBAL\Schema\Constraint; |
28
|
|
|
use Doctrine\DBAL\Schema\ForeignKeyConstraint; |
29
|
|
|
use Doctrine\DBAL\Schema\Identifier; |
30
|
|
|
use Doctrine\DBAL\Schema\Index; |
31
|
|
|
use Doctrine\DBAL\Schema\Table; |
32
|
|
|
use Doctrine\DBAL\Schema\TableDiff; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* The SQLAnywherePlatform provides the behavior, features and SQL dialect of the |
36
|
|
|
* SAP Sybase SQL Anywhere 10 database platform. |
37
|
|
|
* |
38
|
|
|
* @author Steve Müller <[email protected]> |
39
|
|
|
* @link www.doctrine-project.org |
40
|
|
|
* @since 2.5 |
41
|
|
|
*/ |
42
|
|
|
class SQLAnywherePlatform extends AbstractPlatform |
43
|
|
|
{ |
44
|
|
|
/** |
45
|
|
|
* @var integer |
46
|
|
|
*/ |
47
|
|
|
const FOREIGN_KEY_MATCH_SIMPLE = 1; |
48
|
|
|
/** |
49
|
|
|
* @var integer |
50
|
|
|
*/ |
51
|
|
|
const FOREIGN_KEY_MATCH_FULL = 2; |
52
|
|
|
/** |
53
|
|
|
* @var integer |
54
|
|
|
*/ |
55
|
|
|
const FOREIGN_KEY_MATCH_SIMPLE_UNIQUE = 129; |
56
|
|
|
/** |
57
|
|
|
* @var integer |
58
|
|
|
*/ |
59
|
|
|
const FOREIGN_KEY_MATCH_FULL_UNIQUE = 130; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* {@inheritdoc} |
63
|
|
|
*/ |
64
|
28 |
View Code Duplication |
public function appendLockHint($fromClause, $lockMode) |
|
|
|
|
65
|
|
|
{ |
66
|
|
|
switch (true) { |
67
|
28 |
|
case $lockMode === LockMode::NONE: |
68
|
4 |
|
return $fromClause . ' WITH (NOLOCK)'; |
69
|
|
|
|
70
|
24 |
|
case $lockMode === LockMode::PESSIMISTIC_READ: |
71
|
4 |
|
return $fromClause . ' WITH (UPDLOCK)'; |
72
|
|
|
|
73
|
20 |
|
case $lockMode === LockMode::PESSIMISTIC_WRITE: |
74
|
4 |
|
return $fromClause . ' WITH (XLOCK)'; |
75
|
|
|
|
76
|
|
|
default: |
77
|
16 |
|
return $fromClause; |
78
|
|
|
} |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* {@inheritdoc} |
83
|
|
|
* |
84
|
|
|
* SQL Anywhere supports a maximum length of 128 bytes for identifiers. |
85
|
|
|
*/ |
86
|
4 |
|
public function fixSchemaElementName($schemaElementName) |
87
|
|
|
{ |
88
|
4 |
|
$maxIdentifierLength = $this->getMaxIdentifierLength(); |
89
|
|
|
|
90
|
4 |
|
if (strlen($schemaElementName) > $maxIdentifierLength) { |
91
|
4 |
|
return substr($schemaElementName, 0, $maxIdentifierLength); |
92
|
|
|
} |
93
|
|
|
|
94
|
4 |
|
return $schemaElementName; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* {@inheritdoc} |
99
|
|
|
*/ |
100
|
28 |
|
public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) |
101
|
|
|
{ |
102
|
28 |
|
$query = ''; |
103
|
|
|
|
104
|
28 |
|
if ($foreignKey->hasOption('match')) { |
105
|
4 |
|
$query = ' MATCH ' . $this->getForeignKeyMatchClauseSQL($foreignKey->getOption('match')); |
106
|
|
|
} |
107
|
|
|
|
108
|
28 |
|
$query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey); |
109
|
|
|
|
110
|
28 |
|
if ($foreignKey->hasOption('check_on_commit') && (boolean) $foreignKey->getOption('check_on_commit')) { |
111
|
4 |
|
$query .= ' CHECK ON COMMIT'; |
112
|
|
|
} |
113
|
|
|
|
114
|
28 |
|
if ($foreignKey->hasOption('clustered') && (boolean) $foreignKey->getOption('clustered')) { |
115
|
4 |
|
$query .= ' CLUSTERED'; |
116
|
|
|
} |
117
|
|
|
|
118
|
28 |
|
if ($foreignKey->hasOption('for_olap_workload') && (boolean) $foreignKey->getOption('for_olap_workload')) { |
119
|
4 |
|
$query .= ' FOR OLAP WORKLOAD'; |
120
|
|
|
} |
121
|
|
|
|
122
|
28 |
|
return $query; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* {@inheritdoc} |
127
|
|
|
*/ |
128
|
60 |
|
public function getAlterTableSQL(TableDiff $diff) |
129
|
|
|
{ |
130
|
60 |
|
$sql = []; |
131
|
60 |
|
$columnSql = []; |
132
|
60 |
|
$commentsSQL = []; |
133
|
60 |
|
$tableSql = []; |
134
|
60 |
|
$alterClauses = []; |
135
|
|
|
|
136
|
|
|
/** @var \Doctrine\DBAL\Schema\Column $column */ |
137
|
60 |
|
foreach ($diff->addedColumns as $column) { |
138
|
16 |
|
if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { |
139
|
|
|
continue; |
140
|
|
|
} |
141
|
|
|
|
142
|
16 |
|
$alterClauses[] = $this->getAlterTableAddColumnClause($column); |
143
|
|
|
|
144
|
16 |
|
$comment = $this->getColumnComment($column); |
145
|
|
|
|
146
|
16 |
View Code Duplication |
if (null !== $comment && '' !== $comment) { |
|
|
|
|
147
|
4 |
|
$commentsSQL[] = $this->getCommentOnColumnSQL( |
148
|
4 |
|
$diff->getName($this)->getQuotedName($this), |
149
|
4 |
|
$column->getQuotedName($this), |
150
|
16 |
|
$comment |
151
|
|
|
); |
152
|
|
|
} |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** @var \Doctrine\DBAL\Schema\Column $column */ |
156
|
60 |
|
foreach ($diff->removedColumns as $column) { |
157
|
12 |
|
if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { |
158
|
|
|
continue; |
159
|
|
|
} |
160
|
|
|
|
161
|
12 |
|
$alterClauses[] = $this->getAlterTableRemoveColumnClause($column); |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
/** @var \Doctrine\DBAL\Schema\ColumnDiff $columnDiff */ |
165
|
60 |
|
foreach ($diff->changedColumns as $columnDiff) { |
166
|
32 |
|
if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { |
167
|
|
|
continue; |
168
|
|
|
} |
169
|
|
|
|
170
|
32 |
|
$alterClause = $this->getAlterTableChangeColumnClause($columnDiff); |
171
|
|
|
|
172
|
32 |
|
if (null !== $alterClause) { |
173
|
20 |
|
$alterClauses[] = $alterClause; |
174
|
|
|
} |
175
|
|
|
|
176
|
32 |
View Code Duplication |
if ($columnDiff->hasChanged('comment')) { |
|
|
|
|
177
|
12 |
|
$column = $columnDiff->column; |
178
|
|
|
|
179
|
12 |
|
$commentsSQL[] = $this->getCommentOnColumnSQL( |
180
|
12 |
|
$diff->getName($this)->getQuotedName($this), |
181
|
12 |
|
$column->getQuotedName($this), |
182
|
32 |
|
$this->getColumnComment($column) |
183
|
|
|
); |
184
|
|
|
} |
185
|
|
|
} |
186
|
|
|
|
187
|
60 |
View Code Duplication |
foreach ($diff->renamedColumns as $oldColumnName => $column) { |
|
|
|
|
188
|
16 |
|
if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { |
189
|
|
|
continue; |
190
|
|
|
} |
191
|
|
|
|
192
|
16 |
|
$sql[] = $this->getAlterTableClause($diff->getName($this)) . ' ' . |
193
|
16 |
|
$this->getAlterTableRenameColumnClause($oldColumnName, $column); |
194
|
|
|
} |
195
|
|
|
|
196
|
60 |
|
if ( ! $this->onSchemaAlterTable($diff, $tableSql)) { |
197
|
60 |
|
if ( ! empty($alterClauses)) { |
198
|
24 |
|
$sql[] = $this->getAlterTableClause($diff->getName($this)) . ' ' . implode(", ", $alterClauses); |
199
|
|
|
} |
200
|
|
|
|
201
|
60 |
|
$sql = array_merge($sql, $commentsSQL); |
202
|
|
|
|
203
|
60 |
|
if ($diff->newName !== false) { |
204
|
8 |
|
$sql[] = $this->getAlterTableClause($diff->getName($this)) . ' ' . |
205
|
8 |
|
$this->getAlterTableRenameTableClause($diff->getNewName()); |
206
|
|
|
} |
207
|
|
|
|
208
|
60 |
|
$sql = array_merge( |
209
|
60 |
|
$this->getPreAlterTableIndexForeignKeySQL($diff), |
210
|
60 |
|
$sql, |
211
|
60 |
|
$this->getPostAlterTableIndexForeignKeySQL($diff) |
212
|
|
|
); |
213
|
|
|
} |
214
|
|
|
|
215
|
60 |
|
return array_merge($sql, $tableSql, $columnSql); |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* Returns the SQL clause for creating a column in a table alteration. |
220
|
|
|
* |
221
|
|
|
* @param Column $column The column to add. |
222
|
|
|
* |
223
|
|
|
* @return string |
224
|
|
|
*/ |
225
|
16 |
|
protected function getAlterTableAddColumnClause(Column $column) |
226
|
|
|
{ |
227
|
16 |
|
return 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* Returns the SQL clause for altering a table. |
232
|
|
|
* |
233
|
|
|
* @param Identifier $tableName The quoted name of the table to alter. |
234
|
|
|
* |
235
|
|
|
* @return string |
236
|
|
|
*/ |
237
|
32 |
|
protected function getAlterTableClause(Identifier $tableName) |
238
|
|
|
{ |
239
|
32 |
|
return 'ALTER TABLE ' . $tableName->getQuotedName($this); |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* Returns the SQL clause for dropping a column in a table alteration. |
244
|
|
|
* |
245
|
|
|
* @param Column $column The column to drop. |
246
|
|
|
* |
247
|
|
|
* @return string |
248
|
|
|
*/ |
249
|
12 |
|
protected function getAlterTableRemoveColumnClause(Column $column) |
250
|
|
|
{ |
251
|
12 |
|
return 'DROP ' . $column->getQuotedName($this); |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* Returns the SQL clause for renaming a column in a table alteration. |
256
|
|
|
* |
257
|
|
|
* @param string $oldColumnName The quoted name of the column to rename. |
258
|
|
|
* @param Column $column The column to rename to. |
259
|
|
|
* |
260
|
|
|
* @return string |
261
|
|
|
*/ |
262
|
16 |
|
protected function getAlterTableRenameColumnClause($oldColumnName, Column $column) |
263
|
|
|
{ |
264
|
16 |
|
$oldColumnName = new Identifier($oldColumnName); |
265
|
|
|
|
266
|
16 |
|
return 'RENAME ' . $oldColumnName->getQuotedName($this) .' TO ' . $column->getQuotedName($this); |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
/** |
270
|
|
|
* Returns the SQL clause for renaming a table in a table alteration. |
271
|
|
|
* |
272
|
|
|
* @param Identifier $newTableName The quoted name of the table to rename to. |
273
|
|
|
* |
274
|
|
|
* @return string |
275
|
|
|
*/ |
276
|
8 |
|
protected function getAlterTableRenameTableClause(Identifier $newTableName) |
277
|
|
|
{ |
278
|
8 |
|
return 'RENAME ' . $newTableName->getQuotedName($this); |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
/** |
282
|
|
|
* Returns the SQL clause for altering a column in a table alteration. |
283
|
|
|
* |
284
|
|
|
* This method returns null in case that only the column comment has changed. |
285
|
|
|
* Changes in column comments have to be handled differently. |
286
|
|
|
* |
287
|
|
|
* @param ColumnDiff $columnDiff The diff of the column to alter. |
288
|
|
|
* |
289
|
|
|
* @return string|null |
290
|
|
|
*/ |
291
|
32 |
|
protected function getAlterTableChangeColumnClause(ColumnDiff $columnDiff) |
292
|
|
|
{ |
293
|
32 |
|
$column = $columnDiff->column; |
294
|
|
|
|
295
|
|
|
// Do not return alter clause if only comment has changed. |
296
|
32 |
|
if ( ! ($columnDiff->hasChanged('comment') && count($columnDiff->changedProperties) === 1)) { |
297
|
|
|
$columnAlterationClause = 'ALTER ' . |
298
|
20 |
|
$this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); |
299
|
|
|
|
300
|
20 |
|
if ($columnDiff->hasChanged('default') && null === $column->getDefault()) { |
301
|
|
|
$columnAlterationClause .= ', ALTER ' . $column->getQuotedName($this) . ' DROP DEFAULT'; |
302
|
|
|
} |
303
|
|
|
|
304
|
20 |
|
return $columnAlterationClause; |
305
|
|
|
} |
306
|
|
|
|
307
|
12 |
|
return null; |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
/** |
311
|
|
|
* {@inheritdoc} |
312
|
|
|
*/ |
313
|
4 |
|
public function getBigIntTypeDeclarationSQL(array $columnDef) |
314
|
|
|
{ |
315
|
4 |
|
$columnDef['integer_type'] = 'BIGINT'; |
316
|
|
|
|
317
|
4 |
|
return $this->_getCommonIntegerTypeDeclarationSQL($columnDef); |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* {@inheritdoc} |
322
|
|
|
*/ |
323
|
8 |
|
public function getBinaryDefaultLength() |
324
|
|
|
{ |
325
|
8 |
|
return 1; |
326
|
|
|
} |
327
|
|
|
|
328
|
|
|
/** |
329
|
|
|
* {@inheritdoc} |
330
|
|
|
*/ |
331
|
8 |
|
public function getBinaryMaxLength() |
332
|
|
|
{ |
333
|
8 |
|
return 32767; |
334
|
|
|
} |
335
|
|
|
|
336
|
|
|
/** |
337
|
|
|
* {@inheritdoc} |
338
|
|
|
*/ |
339
|
8 |
|
public function getBlobTypeDeclarationSQL(array $field) |
340
|
|
|
{ |
341
|
8 |
|
return 'LONG BINARY'; |
342
|
|
|
} |
343
|
|
|
|
344
|
|
|
/** |
345
|
|
|
* {@inheritdoc} |
346
|
|
|
* |
347
|
|
|
* BIT type columns require an explicit NULL declaration |
348
|
|
|
* in SQL Anywhere if they shall be nullable. |
349
|
|
|
* Otherwise by just omitting the NOT NULL clause, |
350
|
|
|
* SQL Anywhere will declare them NOT NULL nonetheless. |
351
|
|
|
*/ |
352
|
8 |
|
public function getBooleanTypeDeclarationSQL(array $columnDef) |
353
|
|
|
{ |
354
|
8 |
|
$nullClause = isset($columnDef['notnull']) && (boolean) $columnDef['notnull'] === false ? ' NULL' : ''; |
355
|
|
|
|
356
|
8 |
|
return 'BIT' . $nullClause; |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
/** |
360
|
|
|
* {@inheritdoc} |
361
|
|
|
*/ |
362
|
12 |
|
public function getClobTypeDeclarationSQL(array $field) |
363
|
|
|
{ |
364
|
12 |
|
return 'TEXT'; |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
/** |
368
|
|
|
* {@inheritdoc} |
369
|
|
|
*/ |
370
|
32 |
View Code Duplication |
public function getCommentOnColumnSQL($tableName, $columnName, $comment) |
|
|
|
|
371
|
|
|
{ |
372
|
32 |
|
$tableName = new Identifier($tableName); |
373
|
32 |
|
$columnName = new Identifier($columnName); |
374
|
32 |
|
$comment = $comment === null ? 'NULL' : $this->quoteStringLiteral($comment); |
375
|
|
|
|
376
|
32 |
|
return "COMMENT ON COLUMN " . $tableName->getQuotedName($this) . '.' . $columnName->getQuotedName($this) . |
377
|
32 |
|
" IS $comment"; |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
/** |
381
|
|
|
* {@inheritdoc} |
382
|
|
|
*/ |
383
|
4 |
|
public function getConcatExpression() |
384
|
|
|
{ |
385
|
4 |
|
return 'STRING(' . implode(', ', (array) func_get_args()) . ')'; |
386
|
|
|
} |
387
|
|
|
|
388
|
|
|
/** |
389
|
|
|
* {@inheritdoc} |
390
|
|
|
*/ |
391
|
12 |
|
public function getCreateConstraintSQL(Constraint $constraint, $table) |
392
|
|
|
{ |
393
|
12 |
|
if ($constraint instanceof ForeignKeyConstraint) { |
394
|
4 |
|
return $this->getCreateForeignKeySQL($constraint, $table); |
395
|
|
|
} |
396
|
|
|
|
397
|
12 |
|
if ($table instanceof Table) { |
398
|
4 |
|
$table = $table->getQuotedName($this); |
399
|
|
|
} |
400
|
|
|
|
401
|
12 |
|
return 'ALTER TABLE ' . $table . |
402
|
12 |
|
' ADD ' . $this->getTableConstraintDeclarationSQL($constraint, $constraint->getQuotedName($this)); |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
/** |
406
|
|
|
* {@inheritdoc} |
407
|
|
|
*/ |
408
|
4 |
|
public function getCreateDatabaseSQL($database) |
409
|
|
|
{ |
410
|
4 |
|
$database = new Identifier($database); |
411
|
|
|
|
412
|
4 |
|
return "CREATE DATABASE '" . $database->getName() . "'"; |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
/** |
416
|
|
|
* {@inheritdoc} |
417
|
|
|
* |
418
|
|
|
* Appends SQL Anywhere specific flags if given. |
419
|
|
|
*/ |
420
|
33 |
|
public function getCreateIndexSQL(Index $index, $table) |
421
|
|
|
{ |
422
|
33 |
|
return parent::getCreateIndexSQL($index, $table). $this->getAdvancedIndexOptionsSQL($index); |
423
|
|
|
} |
424
|
|
|
|
425
|
|
|
/** |
426
|
|
|
* {@inheritdoc} |
427
|
|
|
*/ |
428
|
6 |
|
public function getCreatePrimaryKeySQL(Index $index, $table) |
429
|
|
|
{ |
430
|
6 |
|
if ($table instanceof Table) { |
431
|
4 |
|
$table = $table->getQuotedName($this); |
432
|
|
|
} |
433
|
|
|
|
434
|
6 |
|
return 'ALTER TABLE ' . $table . ' ADD ' . $this->getPrimaryKeyDeclarationSQL($index); |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
/** |
438
|
|
|
* {@inheritdoc} |
439
|
|
|
*/ |
440
|
4 |
|
public function getCreateTemporaryTableSnippetSQL() |
441
|
|
|
{ |
442
|
4 |
|
return 'CREATE ' . $this->getTemporaryTableSQL() . ' TABLE'; |
443
|
|
|
} |
444
|
|
|
|
445
|
|
|
/** |
446
|
|
|
* {@inheritdoc} |
447
|
|
|
*/ |
448
|
4 |
|
public function getCreateViewSQL($name, $sql) |
449
|
|
|
{ |
450
|
4 |
|
return 'CREATE VIEW ' . $name . ' AS ' . $sql; |
451
|
|
|
} |
452
|
|
|
|
453
|
|
|
/** |
454
|
|
|
* {@inheritdoc} |
455
|
|
|
*/ |
456
|
8 |
|
public function getCurrentDateSQL() |
457
|
|
|
{ |
458
|
8 |
|
return 'CURRENT DATE'; |
459
|
|
|
} |
460
|
|
|
|
461
|
|
|
/** |
462
|
|
|
* {@inheritdoc} |
463
|
|
|
*/ |
464
|
4 |
|
public function getCurrentTimeSQL() |
465
|
|
|
{ |
466
|
4 |
|
return 'CURRENT TIME'; |
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
/** |
470
|
|
|
* {@inheritdoc} |
471
|
|
|
*/ |
472
|
8 |
|
public function getCurrentTimestampSQL() |
473
|
|
|
{ |
474
|
8 |
|
return 'CURRENT TIMESTAMP'; |
475
|
|
|
} |
476
|
|
|
|
477
|
|
|
/** |
478
|
|
|
* {@inheritdoc} |
479
|
|
|
*/ |
480
|
4 |
View Code Duplication |
protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) |
|
|
|
|
481
|
|
|
{ |
482
|
4 |
|
$factorClause = ''; |
483
|
|
|
|
484
|
4 |
|
if ('-' === $operator) { |
485
|
4 |
|
$factorClause = '-1 * '; |
486
|
|
|
} |
487
|
|
|
|
488
|
4 |
|
return 'DATEADD(' . $unit . ', ' . $factorClause . $interval . ', ' . $date . ')'; |
489
|
|
|
} |
490
|
|
|
|
491
|
|
|
/** |
492
|
|
|
* {@inheritdoc} |
493
|
|
|
*/ |
494
|
4 |
|
public function getDateDiffExpression($date1, $date2) |
495
|
|
|
{ |
496
|
4 |
|
return 'DATEDIFF(day, ' . $date2 . ', ' . $date1 . ')'; |
497
|
|
|
} |
498
|
|
|
|
499
|
|
|
/** |
500
|
|
|
* {@inheritdoc} |
501
|
|
|
*/ |
502
|
6 |
|
public function getDateTimeFormatString() |
503
|
|
|
{ |
504
|
6 |
|
return 'Y-m-d H:i:s.u'; |
505
|
|
|
} |
506
|
|
|
|
507
|
|
|
/** |
508
|
|
|
* {@inheritdoc} |
509
|
|
|
*/ |
510
|
4 |
|
public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) |
511
|
|
|
{ |
512
|
4 |
|
return 'DATETIME'; |
513
|
|
|
} |
514
|
|
|
|
515
|
|
|
/** |
516
|
|
|
* {@inheritdoc} |
517
|
|
|
*/ |
518
|
2 |
|
public function getDateTimeTzFormatString() |
519
|
|
|
{ |
520
|
2 |
|
return $this->getDateTimeFormatString(); |
521
|
|
|
} |
522
|
|
|
|
523
|
|
|
/** |
524
|
|
|
* {@inheritdoc} |
525
|
|
|
*/ |
526
|
4 |
|
public function getDateTypeDeclarationSQL(array $fieldDeclaration) |
527
|
|
|
{ |
528
|
4 |
|
return 'DATE'; |
529
|
|
|
} |
530
|
|
|
|
531
|
|
|
/** |
532
|
|
|
* {@inheritdoc} |
533
|
|
|
*/ |
534
|
4 |
|
public function getDefaultTransactionIsolationLevel() |
535
|
|
|
{ |
536
|
4 |
|
return Connection::TRANSACTION_READ_UNCOMMITTED; |
537
|
|
|
} |
538
|
|
|
|
539
|
|
|
/** |
540
|
|
|
* {@inheritdoc} |
541
|
|
|
*/ |
542
|
4 |
|
public function getDropDatabaseSQL($database) |
543
|
|
|
{ |
544
|
4 |
|
$database = new Identifier($database); |
545
|
|
|
|
546
|
4 |
|
return "DROP DATABASE '" . $database->getName() . "'"; |
547
|
|
|
} |
548
|
|
|
|
549
|
|
|
/** |
550
|
|
|
* {@inheritdoc} |
551
|
|
|
*/ |
552
|
12 |
|
public function getDropIndexSQL($index, $table = null) |
553
|
|
|
{ |
554
|
12 |
|
if ($index instanceof Index) { |
555
|
4 |
|
$index = $index->getQuotedName($this); |
556
|
|
|
} |
557
|
|
|
|
558
|
12 |
|
if ( ! is_string($index)) { |
559
|
4 |
|
throw new \InvalidArgumentException( |
560
|
|
|
'SQLAnywherePlatform::getDropIndexSQL() expects $index parameter to be string or ' . |
561
|
4 |
|
'\Doctrine\DBAL\Schema\Index.' |
562
|
|
|
); |
563
|
|
|
} |
564
|
|
|
|
565
|
8 |
|
if ( ! isset($table)) { |
566
|
4 |
|
return 'DROP INDEX ' . $index; |
567
|
|
|
} |
568
|
|
|
|
569
|
8 |
|
if ($table instanceof Table) { |
570
|
4 |
|
$table = $table->getQuotedName($this); |
571
|
|
|
} |
572
|
|
|
|
573
|
8 |
|
if ( ! is_string($table)) { |
574
|
4 |
|
throw new \InvalidArgumentException( |
575
|
|
|
'SQLAnywherePlatform::getDropIndexSQL() expects $table parameter to be string or ' . |
576
|
4 |
|
'\Doctrine\DBAL\Schema\Table.' |
577
|
|
|
); |
578
|
|
|
} |
579
|
|
|
|
580
|
4 |
|
return 'DROP INDEX ' . $table . '.' . $index; |
581
|
|
|
} |
582
|
|
|
|
583
|
|
|
/** |
584
|
|
|
* {@inheritdoc} |
585
|
|
|
*/ |
586
|
4 |
|
public function getDropViewSQL($name) |
587
|
|
|
{ |
588
|
4 |
|
return 'DROP VIEW ' . $name; |
589
|
|
|
} |
590
|
|
|
|
591
|
|
|
/** |
592
|
|
|
* {@inheritdoc} |
593
|
|
|
*/ |
594
|
40 |
|
public function getForeignKeyBaseDeclarationSQL(ForeignKeyConstraint $foreignKey) |
595
|
|
|
{ |
596
|
40 |
|
$sql = ''; |
597
|
40 |
|
$foreignKeyName = $foreignKey->getName(); |
598
|
40 |
|
$localColumns = $foreignKey->getQuotedLocalColumns($this); |
599
|
40 |
|
$foreignColumns = $foreignKey->getQuotedForeignColumns($this); |
600
|
40 |
|
$foreignTableName = $foreignKey->getQuotedForeignTableName($this); |
601
|
|
|
|
602
|
40 |
|
if ( ! empty($foreignKeyName)) { |
603
|
24 |
|
$sql .= 'CONSTRAINT ' . $foreignKey->getQuotedName($this) . ' '; |
604
|
|
|
} |
605
|
|
|
|
606
|
40 |
|
if (empty($localColumns)) { |
607
|
4 |
|
throw new \InvalidArgumentException("Incomplete definition. 'local' required."); |
608
|
|
|
} |
609
|
|
|
|
610
|
36 |
|
if (empty($foreignColumns)) { |
611
|
4 |
|
throw new \InvalidArgumentException("Incomplete definition. 'foreign' required."); |
612
|
|
|
} |
613
|
|
|
|
614
|
32 |
|
if (empty($foreignTableName)) { |
615
|
4 |
|
throw new \InvalidArgumentException("Incomplete definition. 'foreignTable' required."); |
616
|
|
|
} |
617
|
|
|
|
618
|
28 |
|
if ($foreignKey->hasOption('notnull') && (boolean) $foreignKey->getOption('notnull')) { |
619
|
4 |
|
$sql .= 'NOT NULL '; |
620
|
|
|
} |
621
|
|
|
|
622
|
|
|
return $sql . |
623
|
28 |
|
'FOREIGN KEY (' . $this->getIndexFieldDeclarationListSQL($localColumns) . ') ' . |
624
|
28 |
|
'REFERENCES ' . $foreignKey->getQuotedForeignTableName($this) . |
625
|
28 |
|
' (' . $this->getIndexFieldDeclarationListSQL($foreignColumns) . ')'; |
626
|
|
|
} |
627
|
|
|
|
628
|
|
|
/** |
629
|
|
|
* Returns foreign key MATCH clause for given type. |
630
|
|
|
* |
631
|
|
|
* @param integer $type The foreign key match type |
632
|
|
|
* |
633
|
|
|
* @return string |
634
|
|
|
* |
635
|
|
|
* @throws \InvalidArgumentException if unknown match type given |
636
|
|
|
*/ |
637
|
12 |
|
public function getForeignKeyMatchClauseSQL($type) |
638
|
|
|
{ |
639
|
12 |
|
switch ((int) $type) { |
640
|
12 |
|
case self::FOREIGN_KEY_MATCH_SIMPLE: |
641
|
4 |
|
return 'SIMPLE'; |
642
|
|
|
break; |
|
|
|
|
643
|
12 |
|
case self::FOREIGN_KEY_MATCH_FULL: |
644
|
4 |
|
return 'FULL'; |
645
|
|
|
break; |
646
|
12 |
|
case self::FOREIGN_KEY_MATCH_SIMPLE_UNIQUE: |
647
|
8 |
|
return 'UNIQUE SIMPLE'; |
648
|
|
|
break; |
649
|
8 |
|
case self::FOREIGN_KEY_MATCH_FULL_UNIQUE: |
650
|
4 |
|
return 'UNIQUE FULL'; |
651
|
|
|
default: |
652
|
4 |
|
throw new \InvalidArgumentException('Invalid foreign key match type: ' . $type); |
653
|
|
|
} |
654
|
|
|
} |
655
|
|
|
|
656
|
|
|
/** |
657
|
|
|
* {@inheritdoc} |
658
|
|
|
*/ |
659
|
32 |
|
public function getForeignKeyReferentialActionSQL($action) |
660
|
|
|
{ |
661
|
|
|
// NO ACTION is not supported, therefore falling back to RESTRICT. |
662
|
32 |
|
if (strtoupper($action) === 'NO ACTION') { |
663
|
4 |
|
return 'RESTRICT'; |
664
|
|
|
} |
665
|
|
|
|
666
|
28 |
|
return parent::getForeignKeyReferentialActionSQL($action); |
667
|
|
|
} |
668
|
|
|
|
669
|
|
|
/** |
670
|
|
|
* {@inheritdoc} |
671
|
|
|
*/ |
672
|
4 |
|
public function getForUpdateSQL() |
673
|
|
|
{ |
674
|
4 |
|
return ''; |
675
|
|
|
} |
676
|
|
|
|
677
|
|
|
/** |
678
|
|
|
* {@inheritdoc} |
679
|
|
|
*/ |
680
|
4 |
|
public function getGuidExpression() |
681
|
|
|
{ |
682
|
4 |
|
return 'NEWID()'; |
683
|
|
|
} |
684
|
|
|
|
685
|
|
|
/** |
686
|
|
|
* {@inheritdoc} |
687
|
|
|
*/ |
688
|
8 |
|
public function getGuidTypeDeclarationSQL(array $field) |
689
|
|
|
{ |
690
|
8 |
|
return 'UNIQUEIDENTIFIER'; |
691
|
|
|
} |
692
|
|
|
|
693
|
|
|
/** |
694
|
|
|
* {@inheritdoc} |
695
|
|
|
*/ |
696
|
8 |
|
public function getIndexDeclarationSQL($name, Index $index) |
697
|
|
|
{ |
698
|
|
|
// Index declaration in statements like CREATE TABLE is not supported. |
699
|
8 |
|
throw DBALException::notSupported(__METHOD__); |
700
|
|
|
} |
701
|
|
|
|
702
|
|
|
/** |
703
|
|
|
* {@inheritdoc} |
704
|
|
|
*/ |
705
|
44 |
|
public function getIntegerTypeDeclarationSQL(array $columnDef) |
706
|
|
|
{ |
707
|
44 |
|
$columnDef['integer_type'] = 'INT'; |
708
|
|
|
|
709
|
44 |
|
return $this->_getCommonIntegerTypeDeclarationSQL($columnDef); |
710
|
|
|
} |
711
|
|
|
|
712
|
|
|
/** |
713
|
|
|
* {@inheritdoc} |
714
|
|
|
*/ |
715
|
|
|
public function getListDatabasesSQL() |
716
|
|
|
{ |
717
|
|
|
return 'SELECT db_name(number) AS name FROM sa_db_list()'; |
718
|
|
|
} |
719
|
|
|
|
720
|
|
|
/** |
721
|
|
|
* {@inheritdoc} |
722
|
|
|
*/ |
723
|
4 |
|
public function getListTableColumnsSQL($table, $database = null) |
724
|
|
|
{ |
725
|
4 |
|
$user = 'USER_NAME()'; |
726
|
|
|
|
727
|
4 |
View Code Duplication |
if (strpos($table, '.') !== false) { |
|
|
|
|
728
|
4 |
|
list($user, $table) = explode('.', $table); |
729
|
4 |
|
$user = $this->quoteStringLiteral($user); |
730
|
|
|
} |
731
|
|
|
|
732
|
|
|
return "SELECT col.column_name, |
733
|
|
|
COALESCE(def.user_type_name, def.domain_name) AS 'type', |
734
|
|
|
def.declared_width AS 'length', |
735
|
|
|
def.scale, |
736
|
|
|
CHARINDEX('unsigned', def.domain_name) AS 'unsigned', |
737
|
|
|
IF col.nulls = 'Y' THEN 0 ELSE 1 ENDIF AS 'notnull', |
738
|
|
|
col.\"default\", |
739
|
|
|
def.is_autoincrement AS 'autoincrement', |
740
|
|
|
rem.remarks AS 'comment' |
741
|
4 |
|
FROM sa_describe_query('SELECT * FROM \"$table\"') AS def |
742
|
|
|
JOIN SYS.SYSTABCOL AS col |
743
|
|
|
ON col.table_id = def.base_table_id AND col.column_id = def.base_column_id |
744
|
|
|
LEFT JOIN SYS.SYSREMARK AS rem |
745
|
|
|
ON col.object_id = rem.object_id |
746
|
4 |
|
WHERE def.base_owner_name = $user |
747
|
|
|
ORDER BY def.base_column_id ASC"; |
748
|
|
|
} |
749
|
|
|
|
750
|
|
|
/** |
751
|
|
|
* {@inheritdoc} |
752
|
|
|
* |
753
|
|
|
* @todo Where is this used? Which information should be retrieved? |
754
|
|
|
*/ |
755
|
8 |
View Code Duplication |
public function getListTableConstraintsSQL($table) |
|
|
|
|
756
|
|
|
{ |
757
|
8 |
|
$user = ''; |
758
|
|
|
|
759
|
8 |
|
if (strpos($table, '.') !== false) { |
760
|
4 |
|
list($user, $table) = explode('.', $table); |
761
|
4 |
|
$user = $this->quoteStringLiteral($user); |
762
|
4 |
|
$table = $this->quoteStringLiteral($table); |
763
|
|
|
} else { |
764
|
4 |
|
$table = $this->quoteStringLiteral($table); |
765
|
|
|
} |
766
|
|
|
|
767
|
|
|
return "SELECT con.* |
768
|
|
|
FROM SYS.SYSCONSTRAINT AS con |
769
|
|
|
JOIN SYS.SYSTAB AS tab ON con.table_object_id = tab.object_id |
770
|
8 |
|
WHERE tab.table_name = $table |
771
|
8 |
|
AND tab.creator = USER_ID($user)"; |
772
|
|
|
} |
773
|
|
|
|
774
|
|
|
/** |
775
|
|
|
* {@inheritdoc} |
776
|
|
|
*/ |
777
|
8 |
View Code Duplication |
public function getListTableForeignKeysSQL($table) |
|
|
|
|
778
|
|
|
{ |
779
|
8 |
|
$user = ''; |
780
|
|
|
|
781
|
8 |
|
if (strpos($table, '.') !== false) { |
782
|
4 |
|
list($user, $table) = explode('.', $table); |
783
|
4 |
|
$user = $this->quoteStringLiteral($user); |
784
|
4 |
|
$table = $this->quoteStringLiteral($table); |
785
|
|
|
} else { |
786
|
4 |
|
$table = $this->quoteStringLiteral($table); |
787
|
|
|
} |
788
|
|
|
|
789
|
|
|
return "SELECT fcol.column_name AS local_column, |
790
|
|
|
ptbl.table_name AS foreign_table, |
791
|
|
|
pcol.column_name AS foreign_column, |
792
|
|
|
idx.index_name, |
793
|
|
|
IF fk.nulls = 'N' |
794
|
|
|
THEN 1 |
795
|
|
|
ELSE NULL |
796
|
|
|
ENDIF AS notnull, |
797
|
|
|
CASE ut.referential_action |
798
|
|
|
WHEN 'C' THEN 'CASCADE' |
799
|
|
|
WHEN 'D' THEN 'SET DEFAULT' |
800
|
|
|
WHEN 'N' THEN 'SET NULL' |
801
|
|
|
WHEN 'R' THEN 'RESTRICT' |
802
|
|
|
ELSE NULL |
803
|
|
|
END AS on_update, |
804
|
|
|
CASE dt.referential_action |
805
|
|
|
WHEN 'C' THEN 'CASCADE' |
806
|
|
|
WHEN 'D' THEN 'SET DEFAULT' |
807
|
|
|
WHEN 'N' THEN 'SET NULL' |
808
|
|
|
WHEN 'R' THEN 'RESTRICT' |
809
|
|
|
ELSE NULL |
810
|
|
|
END AS on_delete, |
811
|
|
|
IF fk.check_on_commit = 'Y' |
812
|
|
|
THEN 1 |
813
|
|
|
ELSE NULL |
814
|
|
|
ENDIF AS check_on_commit, -- check_on_commit flag |
815
|
|
|
IF ftbl.clustered_index_id = idx.index_id |
816
|
|
|
THEN 1 |
817
|
|
|
ELSE NULL |
818
|
|
|
ENDIF AS 'clustered', -- clustered flag |
819
|
|
|
IF fk.match_type = 0 |
820
|
|
|
THEN NULL |
821
|
|
|
ELSE fk.match_type |
822
|
|
|
ENDIF AS 'match', -- match option |
823
|
|
|
IF pidx.max_key_distance = 1 |
824
|
|
|
THEN 1 |
825
|
|
|
ELSE NULL |
826
|
|
|
ENDIF AS for_olap_workload -- for_olap_workload flag |
827
|
|
|
FROM SYS.SYSFKEY AS fk |
828
|
|
|
JOIN SYS.SYSIDX AS idx |
829
|
|
|
ON fk.foreign_table_id = idx.table_id |
830
|
|
|
AND fk.foreign_index_id = idx.index_id |
831
|
|
|
JOIN SYS.SYSPHYSIDX pidx |
832
|
|
|
ON idx.table_id = pidx.table_id |
833
|
|
|
AND idx.phys_index_id = pidx.phys_index_id |
834
|
|
|
JOIN SYS.SYSTAB AS ptbl |
835
|
|
|
ON fk.primary_table_id = ptbl.table_id |
836
|
|
|
JOIN SYS.SYSTAB AS ftbl |
837
|
|
|
ON fk.foreign_table_id = ftbl.table_id |
838
|
|
|
JOIN SYS.SYSIDXCOL AS idxcol |
839
|
|
|
ON idx.table_id = idxcol.table_id |
840
|
|
|
AND idx.index_id = idxcol.index_id |
841
|
|
|
JOIN SYS.SYSTABCOL AS pcol |
842
|
|
|
ON ptbl.table_id = pcol.table_id |
843
|
|
|
AND idxcol.primary_column_id = pcol.column_id |
844
|
|
|
JOIN SYS.SYSTABCOL AS fcol |
845
|
|
|
ON ftbl.table_id = fcol.table_id |
846
|
|
|
AND idxcol.column_id = fcol.column_id |
847
|
|
|
LEFT JOIN SYS.SYSTRIGGER ut |
848
|
|
|
ON fk.foreign_table_id = ut.foreign_table_id |
849
|
|
|
AND fk.foreign_index_id = ut.foreign_key_id |
850
|
|
|
AND ut.event = 'C' |
851
|
|
|
LEFT JOIN SYS.SYSTRIGGER dt |
852
|
|
|
ON fk.foreign_table_id = dt.foreign_table_id |
853
|
|
|
AND fk.foreign_index_id = dt.foreign_key_id |
854
|
|
|
AND dt.event = 'D' |
855
|
8 |
|
WHERE ftbl.table_name = $table |
856
|
8 |
|
AND ftbl.creator = USER_ID($user) |
857
|
|
|
ORDER BY fk.foreign_index_id ASC, idxcol.sequence ASC"; |
858
|
|
|
} |
859
|
|
|
|
860
|
|
|
/** |
861
|
|
|
* {@inheritdoc} |
862
|
|
|
*/ |
863
|
8 |
View Code Duplication |
public function getListTableIndexesSQL($table, $currentDatabase = null) |
|
|
|
|
864
|
|
|
{ |
865
|
8 |
|
$user = ''; |
866
|
|
|
|
867
|
8 |
|
if (strpos($table, '.') !== false) { |
868
|
4 |
|
list($user, $table) = explode('.', $table); |
869
|
4 |
|
$user = $this->quoteStringLiteral($user); |
870
|
4 |
|
$table = $this->quoteStringLiteral($table); |
871
|
|
|
} else { |
872
|
4 |
|
$table = $this->quoteStringLiteral($table); |
873
|
|
|
} |
874
|
|
|
|
875
|
|
|
return "SELECT idx.index_name AS key_name, |
876
|
|
|
IF idx.index_category = 1 |
877
|
|
|
THEN 1 |
878
|
|
|
ELSE 0 |
879
|
|
|
ENDIF AS 'primary', |
880
|
|
|
col.column_name, |
881
|
|
|
IF idx.\"unique\" IN(1, 2, 5) |
882
|
|
|
THEN 0 |
883
|
|
|
ELSE 1 |
884
|
|
|
ENDIF AS non_unique, |
885
|
|
|
IF tbl.clustered_index_id = idx.index_id |
886
|
|
|
THEN 1 |
887
|
|
|
ELSE NULL |
888
|
|
|
ENDIF AS 'clustered', -- clustered flag |
889
|
|
|
IF idx.\"unique\" = 5 |
890
|
|
|
THEN 1 |
891
|
|
|
ELSE NULL |
892
|
|
|
ENDIF AS with_nulls_not_distinct, -- with_nulls_not_distinct flag |
893
|
|
|
IF pidx.max_key_distance = 1 |
894
|
|
|
THEN 1 |
895
|
|
|
ELSE NULL |
896
|
|
|
ENDIF AS for_olap_workload -- for_olap_workload flag |
897
|
|
|
FROM SYS.SYSIDX AS idx |
898
|
|
|
JOIN SYS.SYSPHYSIDX pidx |
899
|
|
|
ON idx.table_id = pidx.table_id |
900
|
|
|
AND idx.phys_index_id = pidx.phys_index_id |
901
|
|
|
JOIN SYS.SYSIDXCOL AS idxcol |
902
|
|
|
ON idx.table_id = idxcol.table_id AND idx.index_id = idxcol.index_id |
903
|
|
|
JOIN SYS.SYSTABCOL AS col |
904
|
|
|
ON idxcol.table_id = col.table_id AND idxcol.column_id = col.column_id |
905
|
|
|
JOIN SYS.SYSTAB AS tbl |
906
|
|
|
ON idx.table_id = tbl.table_id |
907
|
8 |
|
WHERE tbl.table_name = $table |
908
|
8 |
|
AND tbl.creator = USER_ID($user) |
909
|
|
|
AND idx.index_category != 2 -- exclude indexes implicitly created by foreign key constraints |
910
|
|
|
ORDER BY idx.index_id ASC, idxcol.sequence ASC"; |
911
|
|
|
} |
912
|
|
|
|
913
|
|
|
/** |
914
|
|
|
* {@inheritdoc} |
915
|
|
|
*/ |
916
|
|
|
public function getListTablesSQL() |
917
|
|
|
{ |
918
|
|
|
return "SELECT tbl.table_name |
919
|
|
|
FROM SYS.SYSTAB AS tbl |
920
|
|
|
JOIN SYS.SYSUSER AS usr ON tbl.creator = usr.user_id |
921
|
|
|
JOIN dbo.SYSOBJECTS AS obj ON tbl.object_id = obj.id |
922
|
|
|
WHERE tbl.table_type IN(1, 3) -- 'BASE', 'GBL TEMP' |
923
|
|
|
AND usr.user_name NOT IN('SYS', 'dbo', 'rs_systabgroup') -- exclude system users |
924
|
|
|
AND obj.type = 'U' -- user created tables only |
925
|
|
|
ORDER BY tbl.table_name ASC"; |
926
|
|
|
} |
927
|
|
|
|
928
|
|
|
/** |
929
|
|
|
* {@inheritdoc} |
930
|
|
|
* |
931
|
|
|
* @todo Where is this used? Which information should be retrieved? |
932
|
|
|
*/ |
933
|
|
|
public function getListUsersSQL() |
934
|
|
|
{ |
935
|
|
|
return 'SELECT * FROM SYS.SYSUSER ORDER BY user_name ASC'; |
936
|
|
|
} |
937
|
|
|
|
938
|
|
|
/** |
939
|
|
|
* {@inheritdoc} |
940
|
|
|
*/ |
941
|
|
|
public function getListViewsSQL($database) |
942
|
|
|
{ |
943
|
|
|
return "SELECT tbl.table_name, v.view_def |
944
|
|
|
FROM SYS.SYSVIEW v |
945
|
|
|
JOIN SYS.SYSTAB tbl ON v.view_object_id = tbl.object_id |
946
|
|
|
JOIN SYS.SYSUSER usr ON tbl.creator = usr.user_id |
947
|
|
|
JOIN dbo.SYSOBJECTS obj ON tbl.object_id = obj.id |
948
|
|
|
WHERE usr.user_name NOT IN('SYS', 'dbo', 'rs_systabgroup') -- exclude system users |
949
|
|
|
ORDER BY tbl.table_name ASC"; |
950
|
|
|
} |
951
|
|
|
|
952
|
|
|
/** |
953
|
|
|
* {@inheritdoc} |
954
|
|
|
*/ |
955
|
4 |
View Code Duplication |
public function getLocateExpression($str, $substr, $startPos = false) |
|
|
|
|
956
|
|
|
{ |
957
|
4 |
|
if ($startPos == false) { |
958
|
4 |
|
return 'LOCATE(' . $str . ', ' . $substr . ')'; |
959
|
|
|
} |
960
|
|
|
|
961
|
4 |
|
return 'LOCATE(' . $str . ', ' . $substr . ', ' . $startPos . ')'; |
962
|
|
|
} |
963
|
|
|
|
964
|
|
|
/** |
965
|
|
|
* {@inheritdoc} |
966
|
|
|
*/ |
967
|
8 |
|
public function getMaxIdentifierLength() |
968
|
|
|
{ |
969
|
8 |
|
return 128; |
970
|
|
|
} |
971
|
|
|
|
972
|
|
|
/** |
973
|
|
|
* {@inheritdoc} |
974
|
|
|
*/ |
975
|
4 |
|
public function getMd5Expression($column) |
976
|
|
|
{ |
977
|
4 |
|
return "HASH(" . $column . ", 'MD5')"; |
978
|
|
|
} |
979
|
|
|
|
980
|
|
|
/** |
981
|
|
|
* {@inheritdoc} |
982
|
|
|
*/ |
983
|
12 |
|
public function getName() |
984
|
|
|
{ |
985
|
12 |
|
return 'sqlanywhere'; |
986
|
|
|
} |
987
|
|
|
|
988
|
|
|
/** |
989
|
|
|
* Obtain DBMS specific SQL code portion needed to set a primary key |
990
|
|
|
* declaration to be used in statements like ALTER TABLE. |
991
|
|
|
* |
992
|
|
|
* @param Index $index Index definition |
993
|
|
|
* @param string $name Name of the primary key |
994
|
|
|
* |
995
|
|
|
* @return string DBMS specific SQL code portion needed to set a primary key |
996
|
|
|
* |
997
|
|
|
* @throws \InvalidArgumentException if the given index is not a primary key. |
998
|
|
|
*/ |
999
|
14 |
|
public function getPrimaryKeyDeclarationSQL(Index $index, $name = null) |
1000
|
|
|
{ |
1001
|
14 |
|
if ( ! $index->isPrimary()) { |
1002
|
|
|
throw new \InvalidArgumentException( |
1003
|
|
|
'Can only create primary key declarations with getPrimaryKeyDeclarationSQL()' |
1004
|
|
|
); |
1005
|
|
|
} |
1006
|
|
|
|
1007
|
14 |
|
return $this->getTableConstraintDeclarationSQL($index, $name); |
1008
|
|
|
} |
1009
|
|
|
|
1010
|
|
|
/** |
1011
|
|
|
* {@inheritdoc} |
1012
|
|
|
*/ |
1013
|
8 |
|
public function getSetTransactionIsolationSQL($level) |
1014
|
|
|
{ |
1015
|
8 |
|
return 'SET TEMPORARY OPTION isolation_level = ' . $this->_getTransactionIsolationLevelSQL($level); |
1016
|
|
|
} |
1017
|
|
|
|
1018
|
|
|
/** |
1019
|
|
|
* {@inheritdoc} |
1020
|
|
|
*/ |
1021
|
4 |
|
public function getSmallIntTypeDeclarationSQL(array $columnDef) |
1022
|
|
|
{ |
1023
|
4 |
|
$columnDef['integer_type'] = 'SMALLINT'; |
1024
|
|
|
|
1025
|
4 |
|
return $this->_getCommonIntegerTypeDeclarationSQL($columnDef); |
1026
|
|
|
} |
1027
|
|
|
|
1028
|
|
|
/** |
1029
|
|
|
* Returns the SQL statement for starting an existing database. |
1030
|
|
|
* |
1031
|
|
|
* In SQL Anywhere you can start and stop databases on a |
1032
|
|
|
* database server instance. |
1033
|
|
|
* This is a required statement after having created a new database |
1034
|
|
|
* as it has to be explicitly started to be usable. |
1035
|
|
|
* SQL Anywhere does not automatically start a database after creation! |
1036
|
|
|
* |
1037
|
|
|
* @param string $database Name of the database to start. |
1038
|
|
|
* |
1039
|
|
|
* @return string |
1040
|
|
|
*/ |
1041
|
4 |
|
public function getStartDatabaseSQL($database) |
1042
|
|
|
{ |
1043
|
4 |
|
$database = new Identifier($database); |
1044
|
|
|
|
1045
|
4 |
|
return "START DATABASE '" . $database->getName() . "' AUTOSTOP OFF"; |
1046
|
|
|
} |
1047
|
|
|
|
1048
|
|
|
/** |
1049
|
|
|
* Returns the SQL statement for stopping a running database. |
1050
|
|
|
* |
1051
|
|
|
* In SQL Anywhere you can start and stop databases on a |
1052
|
|
|
* database server instance. |
1053
|
|
|
* This is a required statement before dropping an existing database |
1054
|
|
|
* as it has to be explicitly stopped before it can be dropped. |
1055
|
|
|
* |
1056
|
|
|
* @param string $database Name of the database to stop. |
1057
|
|
|
* |
1058
|
|
|
* @return string |
1059
|
|
|
*/ |
1060
|
4 |
|
public function getStopDatabaseSQL($database) |
1061
|
|
|
{ |
1062
|
4 |
|
$database = new Identifier($database); |
1063
|
|
|
|
1064
|
4 |
|
return 'STOP DATABASE "' . $database->getName() . '" UNCONDITIONALLY'; |
1065
|
|
|
} |
1066
|
|
|
|
1067
|
|
|
/** |
1068
|
|
|
* {@inheritdoc} |
1069
|
|
|
*/ |
1070
|
4 |
View Code Duplication |
public function getSubstringExpression($value, $from, $length = null) |
|
|
|
|
1071
|
|
|
{ |
1072
|
4 |
|
if (null === $length) { |
1073
|
4 |
|
return 'SUBSTRING(' . $value . ', ' . $from . ')'; |
1074
|
|
|
} |
1075
|
|
|
|
1076
|
4 |
|
return 'SUBSTRING(' . $value . ', ' . $from . ', ' . $length . ')'; |
1077
|
|
|
} |
1078
|
|
|
|
1079
|
|
|
/** |
1080
|
|
|
* {@inheritdoc} |
1081
|
|
|
*/ |
1082
|
8 |
|
public function getTemporaryTableSQL() |
1083
|
|
|
{ |
1084
|
8 |
|
return 'GLOBAL TEMPORARY'; |
1085
|
|
|
} |
1086
|
|
|
|
1087
|
|
|
/** |
1088
|
|
|
* {@inheritdoc} |
1089
|
|
|
*/ |
1090
|
4 |
|
public function getTimeFormatString() |
1091
|
|
|
{ |
1092
|
4 |
|
return 'H:i:s.u'; |
1093
|
|
|
} |
1094
|
|
|
|
1095
|
|
|
/** |
1096
|
|
|
* {@inheritdoc} |
1097
|
|
|
*/ |
1098
|
4 |
|
public function getTimeTypeDeclarationSQL(array $fieldDeclaration) |
1099
|
|
|
{ |
1100
|
4 |
|
return 'TIME'; |
1101
|
|
|
} |
1102
|
|
|
|
1103
|
|
|
/** |
1104
|
|
|
* {@inheritdoc} |
1105
|
|
|
*/ |
1106
|
4 |
|
public function getTrimExpression($str, $pos = self::TRIM_UNSPECIFIED, $char = false) |
1107
|
|
|
{ |
1108
|
4 |
|
if ( ! $char) { |
1109
|
|
|
switch ($pos) { |
1110
|
4 |
|
case self::TRIM_LEADING: |
1111
|
4 |
|
return $this->getLtrimExpression($str); |
1112
|
4 |
|
case self::TRIM_TRAILING: |
1113
|
4 |
|
return $this->getRtrimExpression($str); |
1114
|
|
|
default: |
1115
|
4 |
|
return 'TRIM(' . $str . ')'; |
1116
|
|
|
} |
1117
|
|
|
} |
1118
|
|
|
|
1119
|
4 |
|
$pattern = "'%[^' + $char + ']%'"; |
1120
|
|
|
|
1121
|
|
|
switch ($pos) { |
1122
|
4 |
View Code Duplication |
case self::TRIM_LEADING: |
|
|
|
|
1123
|
4 |
|
return 'SUBSTR(' . $str . ', PATINDEX(' . $pattern . ', ' . $str . '))'; |
1124
|
4 |
View Code Duplication |
case self::TRIM_TRAILING: |
|
|
|
|
1125
|
4 |
|
return 'REVERSE(SUBSTR(REVERSE(' . $str . '), PATINDEX(' . $pattern . ', REVERSE(' . $str . '))))'; |
1126
|
|
|
default: |
1127
|
|
|
return |
1128
|
4 |
|
'REVERSE(SUBSTR(REVERSE(SUBSTR(' . $str . ', PATINDEX(' . $pattern . ', ' . $str . '))), ' . |
1129
|
4 |
|
'PATINDEX(' . $pattern . ', REVERSE(SUBSTR(' . $str . ', PATINDEX(' . $pattern . ', ' . $str . '))))))'; |
1130
|
|
|
} |
1131
|
|
|
} |
1132
|
|
|
|
1133
|
|
|
/** |
1134
|
|
|
* {@inheritdoc} |
1135
|
|
|
*/ |
1136
|
8 |
|
public function getTruncateTableSQL($tableName, $cascade = false) |
1137
|
|
|
{ |
1138
|
8 |
|
$tableIdentifier = new Identifier($tableName); |
1139
|
|
|
|
1140
|
8 |
|
return 'TRUNCATE TABLE ' . $tableIdentifier->getQuotedName($this); |
1141
|
|
|
} |
1142
|
|
|
|
1143
|
|
|
/** |
1144
|
|
|
* {@inheritdoc} |
1145
|
|
|
*/ |
1146
|
16 |
|
public function getUniqueConstraintDeclarationSQL($name, Index $index) |
1147
|
|
|
{ |
1148
|
16 |
|
if ($index->isPrimary()) { |
1149
|
|
|
throw new \InvalidArgumentException( |
1150
|
|
|
'Cannot create primary key constraint declarations with getUniqueConstraintDeclarationSQL().' |
1151
|
|
|
); |
1152
|
|
|
} |
1153
|
|
|
|
1154
|
16 |
|
if ( ! $index->isUnique()) { |
1155
|
|
|
throw new \InvalidArgumentException( |
1156
|
|
|
'Can only create unique constraint declarations, no common index declarations with ' . |
1157
|
|
|
'getUniqueConstraintDeclarationSQL().' |
1158
|
|
|
); |
1159
|
|
|
} |
1160
|
|
|
|
1161
|
16 |
|
return $this->getTableConstraintDeclarationSQL($index, $name); |
1162
|
|
|
} |
1163
|
|
|
|
1164
|
|
|
/** |
1165
|
|
|
* {@inheritdoc} |
1166
|
|
|
*/ |
1167
|
16 |
|
public function getVarcharDefaultLength() |
1168
|
|
|
{ |
1169
|
16 |
|
return 1; |
1170
|
|
|
} |
1171
|
|
|
|
1172
|
|
|
/** |
1173
|
|
|
* {@inheritdoc} |
1174
|
|
|
*/ |
1175
|
52 |
|
public function getVarcharMaxLength() |
1176
|
|
|
{ |
1177
|
52 |
|
return 32767; |
1178
|
|
|
} |
1179
|
|
|
|
1180
|
|
|
/** |
1181
|
|
|
* {@inheritdoc} |
1182
|
|
|
*/ |
1183
|
180 |
|
public function hasNativeGuidType() |
1184
|
|
|
{ |
1185
|
180 |
|
return true; |
1186
|
|
|
} |
1187
|
|
|
|
1188
|
|
|
/** |
1189
|
|
|
* {@inheritdoc} |
1190
|
|
|
*/ |
1191
|
4 |
|
public function prefersIdentityColumns() |
1192
|
|
|
{ |
1193
|
4 |
|
return true; |
1194
|
|
|
} |
1195
|
|
|
|
1196
|
|
|
/** |
1197
|
|
|
* {@inheritdoc} |
1198
|
|
|
*/ |
1199
|
52 |
|
public function supportsCommentOnStatement() |
1200
|
|
|
{ |
1201
|
52 |
|
return true; |
1202
|
|
|
} |
1203
|
|
|
|
1204
|
|
|
/** |
1205
|
|
|
* {@inheritdoc} |
1206
|
|
|
*/ |
1207
|
4 |
|
public function supportsIdentityColumns() |
1208
|
|
|
{ |
1209
|
4 |
|
return true; |
1210
|
|
|
} |
1211
|
|
|
|
1212
|
|
|
/** |
1213
|
|
|
* {@inheritdoc} |
1214
|
|
|
*/ |
1215
|
44 |
|
protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) |
1216
|
|
|
{ |
1217
|
44 |
|
$unsigned = ! empty($columnDef['unsigned']) ? 'UNSIGNED ' : ''; |
1218
|
44 |
|
$autoincrement = ! empty($columnDef['autoincrement']) ? ' IDENTITY' : ''; |
1219
|
|
|
|
1220
|
44 |
|
return $unsigned . $columnDef['integer_type'] . $autoincrement; |
1221
|
|
|
} |
1222
|
|
|
|
1223
|
|
|
/** |
1224
|
|
|
* {@inheritdoc} |
1225
|
|
|
*/ |
1226
|
48 |
|
protected function _getCreateTableSQL($tableName, array $columns, array $options = []) |
1227
|
|
|
{ |
1228
|
48 |
|
$columnListSql = $this->getColumnDeclarationListSQL($columns); |
1229
|
48 |
|
$indexSql = []; |
1230
|
|
|
|
1231
|
48 |
|
if ( ! empty($options['uniqueConstraints'])) { |
1232
|
|
|
foreach ((array) $options['uniqueConstraints'] as $name => $definition) { |
1233
|
|
|
$columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition); |
1234
|
|
|
} |
1235
|
|
|
} |
1236
|
|
|
|
1237
|
48 |
|
if ( ! empty($options['indexes'])) { |
1238
|
|
|
/** @var \Doctrine\DBAL\Schema\Index $index */ |
1239
|
16 |
|
foreach ((array) $options['indexes'] as $index) { |
1240
|
16 |
|
$indexSql[] = $this->getCreateIndexSQL($index, $tableName); |
1241
|
|
|
} |
1242
|
|
|
} |
1243
|
|
|
|
1244
|
48 |
View Code Duplication |
if ( ! empty($options['primary'])) { |
|
|
|
|
1245
|
24 |
|
$flags = ''; |
1246
|
|
|
|
1247
|
24 |
|
if (isset($options['primary_index']) && $options['primary_index']->hasFlag('clustered')) { |
1248
|
|
|
$flags = ' CLUSTERED '; |
1249
|
|
|
} |
1250
|
|
|
|
1251
|
24 |
|
$columnListSql .= ', PRIMARY KEY' . $flags . ' (' . implode(', ', array_unique(array_values((array) $options['primary']))) . ')'; |
1252
|
|
|
} |
1253
|
|
|
|
1254
|
48 |
|
if ( ! empty($options['foreignKeys'])) { |
1255
|
8 |
|
foreach ((array) $options['foreignKeys'] as $definition) { |
1256
|
8 |
|
$columnListSql .= ', ' . $this->getForeignKeyDeclarationSQL($definition); |
1257
|
|
|
} |
1258
|
|
|
} |
1259
|
|
|
|
1260
|
48 |
|
$query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql; |
1261
|
48 |
|
$check = $this->getCheckDeclarationSQL($columns); |
1262
|
|
|
|
1263
|
48 |
|
if ( ! empty($check)) { |
1264
|
4 |
|
$query .= ', ' . $check; |
1265
|
|
|
} |
1266
|
|
|
|
1267
|
48 |
|
$query .= ')'; |
1268
|
|
|
|
1269
|
48 |
|
return array_merge([$query], $indexSql); |
1270
|
|
|
} |
1271
|
|
|
|
1272
|
|
|
/** |
1273
|
|
|
* {@inheritdoc} |
1274
|
|
|
*/ |
1275
|
8 |
|
protected function _getTransactionIsolationLevelSQL($level) |
1276
|
|
|
{ |
1277
|
|
|
switch ($level) { |
1278
|
8 |
|
case Connection::TRANSACTION_READ_UNCOMMITTED: |
1279
|
4 |
|
return 0; |
1280
|
8 |
|
case Connection::TRANSACTION_READ_COMMITTED: |
1281
|
4 |
|
return 1; |
1282
|
8 |
|
case Connection::TRANSACTION_REPEATABLE_READ: |
1283
|
4 |
|
return 2; |
1284
|
8 |
|
case Connection::TRANSACTION_SERIALIZABLE: |
1285
|
4 |
|
return 3; |
1286
|
|
|
default: |
1287
|
4 |
|
throw new \InvalidArgumentException('Invalid isolation level:' . $level); |
1288
|
|
|
} |
1289
|
|
|
} |
1290
|
|
|
|
1291
|
|
|
/** |
1292
|
|
|
* {@inheritdoc} |
1293
|
|
|
*/ |
1294
|
16 |
|
protected function doModifyLimitQuery($query, $limit, $offset) |
1295
|
|
|
{ |
1296
|
16 |
|
$limitOffsetClause = ''; |
1297
|
|
|
|
1298
|
16 |
|
if ($limit > 0) { |
1299
|
16 |
|
$limitOffsetClause = 'TOP ' . $limit . ' '; |
1300
|
|
|
} |
1301
|
|
|
|
1302
|
16 |
|
if ($offset > 0) { |
1303
|
4 |
|
if ($limit == 0) { |
1304
|
4 |
|
$limitOffsetClause = 'TOP ALL '; |
1305
|
|
|
} |
1306
|
|
|
|
1307
|
4 |
|
$limitOffsetClause .= 'START AT ' . ($offset + 1) . ' '; |
1308
|
|
|
} |
1309
|
|
|
|
1310
|
16 |
|
if ($limitOffsetClause) { |
1311
|
16 |
|
return preg_replace('/^\s*(SELECT\s+(DISTINCT\s+)?)/i', '\1' . $limitOffsetClause, $query); |
1312
|
|
|
} |
1313
|
|
|
|
1314
|
|
|
return $query; |
1315
|
|
|
} |
1316
|
|
|
|
1317
|
|
|
/** |
1318
|
|
|
* Return the INDEX query section dealing with non-standard |
1319
|
|
|
* SQL Anywhere options. |
1320
|
|
|
* |
1321
|
|
|
* @param Index $index Index definition |
1322
|
|
|
* |
1323
|
|
|
* @return string |
1324
|
|
|
*/ |
1325
|
32 |
|
protected function getAdvancedIndexOptionsSQL(Index $index) |
1326
|
|
|
{ |
1327
|
32 |
|
$sql = ''; |
1328
|
|
|
|
1329
|
32 |
|
if ( ! $index->isPrimary() && $index->hasFlag('for_olap_workload')) { |
1330
|
4 |
|
$sql .= ' FOR OLAP WORKLOAD'; |
1331
|
|
|
} |
1332
|
|
|
|
1333
|
32 |
|
return $sql; |
1334
|
|
|
} |
1335
|
|
|
|
1336
|
|
|
/** |
1337
|
|
|
* {@inheritdoc} |
1338
|
|
|
*/ |
1339
|
4 |
|
protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed) |
1340
|
|
|
{ |
1341
|
4 |
|
return $fixed |
1342
|
4 |
|
? 'BINARY(' . ($length ?: $this->getBinaryDefaultLength()) . ')' |
1343
|
4 |
|
: 'VARBINARY(' . ($length ?: $this->getBinaryDefaultLength()) . ')'; |
1344
|
|
|
} |
1345
|
|
|
|
1346
|
|
|
/** |
1347
|
|
|
* Returns the SQL snippet for creating a table constraint. |
1348
|
|
|
* |
1349
|
|
|
* @param Constraint $constraint The table constraint to create the SQL snippet for. |
1350
|
|
|
* @param string|null $name The table constraint name to use if any. |
1351
|
|
|
* |
1352
|
|
|
* @return string |
1353
|
|
|
* |
1354
|
|
|
* @throws \InvalidArgumentException if the given table constraint type is not supported by this method. |
1355
|
|
|
*/ |
1356
|
42 |
|
protected function getTableConstraintDeclarationSQL(Constraint $constraint, $name = null) |
1357
|
|
|
{ |
1358
|
42 |
|
if ($constraint instanceof ForeignKeyConstraint) { |
1359
|
|
|
return $this->getForeignKeyDeclarationSQL($constraint); |
1360
|
|
|
} |
1361
|
|
|
|
1362
|
42 |
|
if ( ! $constraint instanceof Index) { |
1363
|
4 |
|
throw new \InvalidArgumentException('Unsupported constraint type: ' . get_class($constraint)); |
1364
|
|
|
} |
1365
|
|
|
|
1366
|
38 |
|
if ( ! $constraint->isPrimary() && ! $constraint->isUnique()) { |
1367
|
4 |
|
throw new \InvalidArgumentException( |
1368
|
|
|
'Can only create primary, unique or foreign key constraint declarations, no common index declarations ' . |
1369
|
4 |
|
'with getTableConstraintDeclarationSQL().' |
1370
|
|
|
); |
1371
|
|
|
} |
1372
|
|
|
|
1373
|
34 |
|
$constraintColumns = $constraint->getQuotedColumns($this); |
1374
|
|
|
|
1375
|
34 |
|
if (empty($constraintColumns)) { |
1376
|
8 |
|
throw new \InvalidArgumentException("Incomplete definition. 'columns' required."); |
1377
|
|
|
} |
1378
|
|
|
|
1379
|
26 |
|
$sql = ''; |
1380
|
26 |
|
$flags = ''; |
1381
|
|
|
|
1382
|
26 |
|
if ( ! empty($name)) { |
1383
|
20 |
|
$name = new Identifier($name); |
1384
|
20 |
|
$sql .= 'CONSTRAINT ' . $name->getQuotedName($this) . ' '; |
1385
|
|
|
} |
1386
|
|
|
|
1387
|
26 |
|
if ($constraint->hasFlag('clustered')) { |
1388
|
12 |
|
$flags = 'CLUSTERED '; |
1389
|
|
|
} |
1390
|
|
|
|
1391
|
26 |
|
if ($constraint->isPrimary()) { |
1392
|
14 |
|
return $sql . 'PRIMARY KEY ' . $flags . '('. $this->getIndexFieldDeclarationListSQL($constraintColumns) . ')'; |
1393
|
|
|
} |
1394
|
|
|
|
1395
|
16 |
|
return $sql . 'UNIQUE ' . $flags . '('. $this->getIndexFieldDeclarationListSQL($constraintColumns) . ')'; |
1396
|
|
|
} |
1397
|
|
|
|
1398
|
|
|
/** |
1399
|
|
|
* {@inheritdoc} |
1400
|
|
|
*/ |
1401
|
33 |
View Code Duplication |
protected function getCreateIndexSQLFlags(Index $index) |
|
|
|
|
1402
|
|
|
{ |
1403
|
33 |
|
$type = ''; |
1404
|
33 |
|
if ($index->hasFlag('virtual')) { |
1405
|
4 |
|
$type .= 'VIRTUAL '; |
1406
|
|
|
} |
1407
|
|
|
|
1408
|
33 |
|
if ($index->isUnique()) { |
1409
|
12 |
|
$type .= 'UNIQUE '; |
1410
|
|
|
} |
1411
|
|
|
|
1412
|
33 |
|
if ($index->hasFlag('clustered')) { |
1413
|
4 |
|
$type .= 'CLUSTERED '; |
1414
|
|
|
} |
1415
|
|
|
|
1416
|
33 |
|
return $type; |
1417
|
|
|
} |
1418
|
|
|
|
1419
|
|
|
/** |
1420
|
|
|
* {@inheritdoc} |
1421
|
|
|
*/ |
1422
|
20 |
|
protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) |
1423
|
|
|
{ |
1424
|
|
|
return [ |
1425
|
20 |
|
'ALTER INDEX ' . $oldIndexName . ' ON ' . $tableName . ' RENAME TO ' . $index->getQuotedName($this) |
1426
|
|
|
]; |
1427
|
|
|
} |
1428
|
|
|
|
1429
|
|
|
/** |
1430
|
|
|
* {@inheritdoc} |
1431
|
|
|
*/ |
1432
|
52 |
|
protected function getReservedKeywordsClass() |
1433
|
|
|
{ |
1434
|
52 |
|
return Keywords\SQLAnywhereKeywords::class; |
1435
|
|
|
} |
1436
|
|
|
|
1437
|
|
|
/** |
1438
|
|
|
* {@inheritdoc} |
1439
|
|
|
*/ |
1440
|
48 |
|
protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) |
1441
|
|
|
{ |
1442
|
48 |
|
return $fixed |
1443
|
4 |
|
? ($length ? 'CHAR(' . $length . ')' : 'CHAR(' . $this->getVarcharDefaultLength() . ')') |
1444
|
48 |
|
: ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(' . $this->getVarcharDefaultLength() . ')'); |
1445
|
|
|
} |
1446
|
|
|
|
1447
|
|
|
/** |
1448
|
|
|
* {@inheritdoc} |
1449
|
|
|
*/ |
1450
|
22 |
View Code Duplication |
protected function initializeDoctrineTypeMappings() |
|
|
|
|
1451
|
|
|
{ |
1452
|
22 |
|
$this->doctrineTypeMapping = [ |
1453
|
|
|
'char' => 'string', |
1454
|
|
|
'long nvarchar' => 'text', |
1455
|
|
|
'long varchar' => 'text', |
1456
|
|
|
'nchar' => 'string', |
1457
|
|
|
'ntext' => 'text', |
1458
|
|
|
'nvarchar' => 'string', |
1459
|
|
|
'text' => 'text', |
1460
|
|
|
'uniqueidentifierstr' => 'guid', |
1461
|
|
|
'varchar' => 'string', |
1462
|
|
|
'xml' => 'text', |
1463
|
|
|
'bigint' => 'bigint', |
1464
|
|
|
'unsigned bigint' => 'bigint', |
1465
|
|
|
'bit' => 'boolean', |
1466
|
|
|
'decimal' => 'decimal', |
1467
|
|
|
'double' => 'float', |
1468
|
|
|
'float' => 'float', |
1469
|
|
|
'int' => 'integer', |
1470
|
|
|
'integer' => 'integer', |
1471
|
|
|
'unsigned int' => 'integer', |
1472
|
|
|
'numeric' => 'decimal', |
1473
|
|
|
'smallint' => 'smallint', |
1474
|
|
|
'unsigned smallint', 'smallint', |
1475
|
|
|
'tinyint' => 'smallint', |
1476
|
|
|
'unsigned tinyint', 'smallint', |
1477
|
|
|
'money' => 'decimal', |
1478
|
|
|
'smallmoney' => 'decimal', |
1479
|
|
|
'long varbit' => 'text', |
1480
|
|
|
'varbit' => 'string', |
1481
|
|
|
'date' => 'date', |
1482
|
|
|
'datetime' => 'datetime', |
1483
|
|
|
'smalldatetime' => 'datetime', |
1484
|
|
|
'time' => 'time', |
1485
|
|
|
'timestamp' => 'datetime', |
1486
|
|
|
'binary' => 'binary', |
1487
|
|
|
'image' => 'blob', |
1488
|
|
|
'long binary' => 'blob', |
1489
|
|
|
'uniqueidentifier' => 'guid', |
1490
|
|
|
'varbinary' => 'binary', |
1491
|
|
|
]; |
1492
|
22 |
|
} |
1493
|
|
|
} |
1494
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.