MIOLO20
Carregando...
Procurando...
Nenhuma entrada encontrada
MsSqlPlatform.php
Ir para a documentação deste ficheiro.
1<?php
2
3/*
4 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15 *
16 * This software consists of voluntary contributions made by many individuals
17 * and is licensed under the LGPL. For more information, see
18 * <http://www.doctrine-project.org>.
19 */
20
22
26
38{
39
48 public function prefersIdentityColumns()
49 {
50 return true;
51 }
52
60 public function supportsIdentityColumns()
61 {
62 return true;
63 }
64
70 public function supportsReleaseSavepoints()
71 {
72 return false;
73 }
74
82 public function getCreateDatabaseSQL($name)
83 {
84 return 'CREATE DATABASE ' . $name;
85 }
86
94 public function getDropDatabaseSQL($name)
95 {
96 return 'DROP DATABASE ' . $name;
97 }
98
103 {
104 return false;
105 }
106
110 public function getDropForeignKeySQL($foreignKey, $table)
111 {
112 if ($foreignKey instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) {
113 $foreignKey = $foreignKey->getQuotedName($this);
114 }
115
116 if ($table instanceof \Doctrine\DBAL\Schema\Table) {
117 $table = $table->getQuotedName($this);
118 }
119
120 return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey;
121 }
122
126 public function getDropIndexSQL($index, $table=null)
127 {
128 if ($index instanceof \Doctrine\DBAL\Schema\Index) {
129 $index_ = $index;
130 $index = $index->getQuotedName($this);
131 } else if (!is_string($index)) {
132 throw new \InvalidArgumentException('AbstractPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.');
133 }
134
135 if (!isset($table)) {
136 return 'DROP INDEX ' . $index;
137 } else {
138 if ($table instanceof \Doctrine\DBAL\Schema\Table) {
139 $table = $table->getQuotedName($this);
140 }
141
142 return "IF EXISTS (SELECT * FROM sysobjects WHERE name = '$index')
143 ALTER TABLE " . $table . " DROP CONSTRAINT " . $index . "
144 ELSE
145 DROP INDEX " . $index . " ON " . $table;
146 }
147 }
148
152 protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
153 {
154 // @todo does other code breaks because of this?
155 // foce primary keys to be not null
156 foreach ($columns as &$column) {
157 if (isset($column['primary']) && $column['primary']) {
158 $column['notnull'] = true;
159 }
160 }
161
162 $columnListSql = $this->getColumnDeclarationListSQL($columns);
163
164 if (isset($options['uniqueConstraints']) && !empty($options['uniqueConstraints'])) {
165 foreach ($options['uniqueConstraints'] as $name => $definition) {
166 $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition);
167 }
168 }
169
170 if (isset($options['primary']) && !empty($options['primary'])) {
171 $columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')';
172 }
173
174 $query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql;
175
176 $check = $this->getCheckDeclarationSQL($columns);
177 if (!empty($check)) {
178 $query .= ', ' . $check;
179 }
180 $query .= ')';
181
182 $sql[] = $query;
183
184 if (isset($options['indexes']) && !empty($options['indexes'])) {
185 foreach ($options['indexes'] AS $index) {
186 $sql[] = $this->getCreateIndexSQL($index, $tableName);
187 }
188 }
189
190 if (isset($options['foreignKeys'])) {
191 foreach ((array) $options['foreignKeys'] AS $definition) {
192 $sql[] = $this->getCreateForeignKeySQL($definition, $tableName);
193 }
194 }
195
196 return $sql;
197 }
198
202 public function getUniqueConstraintDeclarationSQL($name, Index $index)
203 {
204 $constraint = parent::getUniqueConstraintDeclarationSQL($name, $index);
205
206 $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index);
207
208 return $constraint;
209 }
210
214 public function getCreateIndexSQL(Index $index, $table)
215 {
216 $constraint = parent::getCreateIndexSQL($index, $table);
217
218 if ($index->isUnique()) {
219 $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index);
220 }
221
222 return $constraint;
223 }
224
232 private function _appendUniqueConstraintDefinition($sql, Index $index)
233 {
234 $fields = array();
235 foreach ($index->getColumns() as $field => $definition) {
236 if (!is_array($definition)) {
237 $field = $definition;
238 }
239
240 $fields[] = $field . ' IS NOT NULL';
241 }
242
243 return $sql . ' WHERE ' . implode(' AND ', $fields);
244 }
245
249 public function getAlterTableSQL(TableDiff $diff)
250 {
251 $queryParts = array();
252 if ($diff->newName !== false) {
253 $queryParts[] = 'RENAME TO ' . $diff->newName;
254 }
255
256 foreach ($diff->addedColumns AS $fieldName => $column) {
257 $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
258 }
259
260 foreach ($diff->removedColumns AS $column) {
261 $queryParts[] = 'DROP COLUMN ' . $column->getQuotedName($this);
262 }
263
264 foreach ($diff->changedColumns AS $columnDiff) {
265 /* @var $columnDiff Doctrine\DBAL\Schema\ColumnDiff */
266 $column = $columnDiff->column;
267 $queryParts[] = 'CHANGE ' . ($columnDiff->oldColumnName) . ' '
268 . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
269 }
270
271 foreach ($diff->renamedColumns AS $oldColumnName => $column) {
272 $queryParts[] = 'CHANGE ' . $oldColumnName . ' '
273 . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
274 }
275
276 $sql = array();
277
278 foreach ($queryParts as $query) {
279 $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
280 }
281
282 $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff));
283
284 return $sql;
285 }
286
290 public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
291 {
292 return 'INSERT INTO ' . $quotedTableName . ' DEFAULT VALUES';
293 }
294
298 public function getShowDatabasesSQL()
299 {
300 return 'SHOW DATABASES';
301 }
302
306 public function getListTablesSQL()
307 {
308 return "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
309 }
310
314 public function getListTableColumnsSQL($table)
315 {
316 return 'exec sp_columns @table_name = ' . $table;
317 }
318
322 public function getListTableForeignKeysSQL($table, $database = null)
323 {
324 return "SELECT f.name AS ForeignKey,
325 SCHEMA_NAME (f.SCHEMA_ID) AS SchemaName,
326 OBJECT_NAME (f.parent_object_id) AS TableName,
327 COL_NAME (fc.parent_object_id,fc.parent_column_id) AS ColumnName,
328 SCHEMA_NAME (o.SCHEMA_ID) ReferenceSchemaName,
329 OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
330 COL_NAME(fc.referenced_object_id,fc.referenced_column_id) AS ReferenceColumnName,
331 f.delete_referential_action_desc,
332 f.update_referential_action_desc
333 FROM sys.foreign_keys AS f
334 INNER JOIN sys.foreign_key_columns AS fc
335 INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id
336 ON f.OBJECT_ID = fc.constraint_object_id
337 WHERE OBJECT_NAME (f.parent_object_id) = '" . $table . "'";
338 }
339
343 public function getListTableIndexesSQL($table)
344 {
345 return "exec sp_helpindex '" . $table . "'";
346 }
347
351 public function getCreateViewSQL($name, $sql)
352 {
353 return 'CREATE VIEW ' . $name . ' AS ' . $sql;
354 }
355
359 public function getListViewsSQL($database)
360 {
361 return "SELECT name FROM sysobjects WHERE type = 'V' ORDER BY name";
362 }
363
367 public function getDropViewSQL($name)
368 {
369 return 'DROP VIEW ' . $name;
370 }
371
378 public function getRegexpExpression()
379 {
380 return 'RLIKE';
381 }
382
389 public function getGuidExpression()
390 {
391 return 'UUID()';
392 }
393
397 public function getLocateExpression($str, $substr, $startPos = false)
398 {
399 if ($startPos == false) {
400 return 'CHARINDEX(' . $substr . ', ' . $str . ')';
401 } else {
402 return 'CHARINDEX(' . $substr . ', ' . $str . ', ' . $startPos . ')';
403 }
404 }
405
409 public function getModExpression($expression1, $expression2)
410 {
411 return $expression1 . ' % ' . $expression2;
412 }
413
417 public function getTrimExpression($str, $pos = self::TRIM_UNSPECIFIED, $char = false)
418 {
419 $trimFn = '';
420
421 if (!$char) {
422 if ($pos == self::TRIM_LEADING) {
423 $trimFn = 'LTRIM';
424 } else if ($pos == self::TRIM_TRAILING) {
425 $trimFn = 'RTRIM';
426 } else {
427 return 'LTRIM(RTRIM(' . $str . '))';
428 }
429
430 return $trimFn . '(' . $str . ')';
431 } else {
441 $pattern = "'%[^' + $char + ']%'";
442
443 if ($pos == self::TRIM_LEADING) {
444 return 'stuff(' . $str . ', 1, patindex(' . $pattern .', ' . $str . ') - 1, null)';
445 } else if ($pos == self::TRIM_TRAILING) {
446 return 'reverse(stuff(reverse(' . $str . '), 1, patindex(' . $pattern .', reverse(' . $str . ')) - 1, null))';
447 } else {
448 return 'reverse(stuff(reverse(stuff(' . $str . ', 1, patindex(' . $pattern .', ' . $str . ') - 1, null)), 1, patindex(' . $pattern .', reverse(stuff(' . $str . ', 1, patindex(' . $pattern .', ' . $str . ') - 1, null))) - 1, null))';
449 }
450 }
451 }
452
456 public function getConcatExpression()
457 {
458 $args = func_get_args();
459 return '(' . implode(' + ', $args) . ')';
460 }
461
462 public function getListDatabasesSQL()
463 {
464 return 'SELECT * FROM SYS.DATABASES';
465 }
466
470 public function getSubstringExpression($value, $from, $len = null)
471 {
472 if (!is_null($len)) {
473 return 'SUBSTRING(' . $value . ', ' . $from . ', ' . $len . ')';
474 }
475 return 'SUBSTRING(' . $value . ', ' . $from . ', LEN(' . $value . ') - ' . $from . ' + 1)';
476 }
477
481 public function getLengthExpression($column)
482 {
483 return 'LEN(' . $column . ')';
484 }
485
489 public function getSetTransactionIsolationSQL($level)
490 {
491 return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level);
492 }
493
497 public function getIntegerTypeDeclarationSQL(array $field)
498 {
499 return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
500 }
501
505 public function getBigIntTypeDeclarationSQL(array $field)
506 {
507 return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
508 }
509
513 public function getSmallIntTypeDeclarationSQL(array $field)
514 {
515 return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
516 }
517
519 public function getVarcharTypeDeclarationSQL(array $field)
520 {
521 if (!isset($field['length'])) {
522 if (array_key_exists('default', $field)) {
523 $field['length'] = $this->getVarcharDefaultLength();
524 } else {
525 $field['length'] = false;
526 }
527 }
528
529 $length = ($field['length'] <= $this->getVarcharMaxLength()) ? $field['length'] : false;
530 $fixed = (isset($field['fixed'])) ? $field['fixed'] : false;
531
532 return $fixed ? ($length ? 'NCHAR(' . $length . ')' : 'CHAR(255)') : ($length ? 'NVARCHAR(' . $length . ')' : 'NTEXT');
533 }
534
536 public function getClobTypeDeclarationSQL(array $field)
537 {
538 return 'TEXT';
539 }
540
544 protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
545 {
546 $autoinc = '';
547 if (!empty($columnDef['autoincrement'])) {
548 $autoinc = ' IDENTITY';
549 }
550 $unsigned = (isset($columnDef['unsigned']) && $columnDef['unsigned']) ? ' UNSIGNED' : '';
551
552 return $unsigned . $autoinc;
553 }
554
558 public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
559 {
560 // 6 - microseconds precision length
561 return 'DATETIME2(6)';
562 }
563
567 public function getDateTypeDeclarationSQL(array $fieldDeclaration)
568 {
569 return 'DATE';
570 }
571
575 public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
576 {
577 return 'TIME(0)';
578 }
579
583 public function getBooleanTypeDeclarationSQL(array $field)
584 {
585 return 'BIT';
586 }
587
597 public function modifyLimitQuery($query, $limit, $offset = null)
598 {
599 if ($limit > 0) {
600 $count = intval($limit);
601 $offset = intval($offset);
602
603 if ($offset < 0) {
604 throw new Doctrine_Connection_Exception("LIMIT argument offset=$offset is not valid");
605 }
606
607 if ($offset == 0) {
608 $query = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . $count . ' ', $query);
609 } else {
610 $orderby = stristr($query, 'ORDER BY');
611
612 if (!$orderby) {
613 $over = 'ORDER BY (SELECT 0)';
614 } else {
615 $over = preg_replace('/\"[^,]*\".\"([^,]*)\"/i', '"inner_tbl"."$1"', $orderby);
616 }
617
618 // Remove ORDER BY clause from $query
619 $query = preg_replace('/\s+ORDER BY(.*)/', '', $query);
620
621 // Add ORDER BY clause as an argument for ROW_NUMBER()
622 $query = "SELECT ROW_NUMBER() OVER ($over) AS \"doctrine_rownum\", * FROM ($query) AS inner_tbl";
623
624 $start = $offset + 1;
625 $end = $offset + $count;
626
627 $query = "WITH outer_tbl AS ($query) SELECT * FROM outer_tbl WHERE \"doctrine_rownum\" BETWEEN $start AND $end";
628 }
629 }
630
631 return $query;
632 }
633
637 public function convertBooleans($item)
638 {
639 if (is_array($item)) {
640 foreach ($item as $key => $value) {
641 if (is_bool($value) || is_numeric($item)) {
642 $item[$key] = ($value) ? 'TRUE' : 'FALSE';
643 }
644 }
645 } else {
646 if (is_bool($item) || is_numeric($item)) {
647 $item = ($item) ? 'TRUE' : 'FALSE';
648 }
649 }
650 return $item;
651 }
652
657 {
658 return "CREATE TABLE";
659 }
660
664 public function getTemporaryTableName($tableName)
665 {
666 return '#' . $tableName;
667 }
668
672 public function getDateTimeFormatString()
673 {
674 return 'Y-m-d H:i:s.u';
675 }
676
681 {
682 return $this->getDateTimeFormatString();
683 }
684
690 public function getName()
691 {
692 return 'mssql';
693 }
694
699 {
700 $this->doctrineTypeMapping = array(
701 'bigint' => 'bigint',
702 'numeric' => 'decimal',
703 'bit' => 'boolean',
704 'smallint' => 'smallint',
705 'decimal' => 'decimal',
706 'smallmoney' => 'integer',
707 'int' => 'integer',
708 'tinyint' => 'smallint',
709 'money' => 'integer',
710 'float' => 'float',
711 'real' => 'float',
712 'double' => 'float',
713 'double precision' => 'float',
714 'date' => 'date',
715 'datetimeoffset' => 'datetimetz',
716 'datetime2' => 'datetime',
717 'smalldatetime' => 'datetime',
718 'datetime' => 'datetime',
719 'time' => 'time',
720 'char' => 'string',
721 'varchar' => 'string',
722 'text' => 'text',
723 'nchar' => 'string',
724 'nvarchar' => 'string',
725 'ntext' => 'text',
726 'binary' => 'text',
727 'varbinary' => 'text',
728 'image' => 'text',
729 );
730 }
731
738 public function createSavePoint($savepoint)
739 {
740 return 'SAVE TRANSACTION ' . $savepoint;
741 }
742
749 public function releaseSavePoint($savepoint)
750 {
751 return '';
752 }
753
760 public function rollbackSavePoint($savepoint)
761 {
762 return 'ROLLBACK TRANSACTION ' . $savepoint;
763 }
764
768 public function appendLockHint($fromClause, $lockMode)
769 {
770 // @todo coorect
771 if ($lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_READ) {
772 return $fromClause . ' WITH (tablockx)';
773 } else if ($lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE) {
774 return $fromClause . ' WITH (tablockx)';
775 }
776 else {
777 return $fromClause;
778 }
779 }
780
784 public function getForUpdateSQL()
785 {
786 return ' ';
787 }
788}
getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table)
getTimeTypeDeclarationSQL(array $fieldDeclaration)
modifyLimitQuery($query, $limit, $offset=null)
getDropForeignKeySQL($foreignKey, $table)
getLocateExpression($str, $substr, $startPos=false)
getUniqueConstraintDeclarationSQL($name, Index $index)
appendLockHint($fromClause, $lockMode)
_getCommonIntegerTypeDeclarationSQL(array $columnDef)
getTrimExpression($str, $pos=self::TRIM_UNSPECIFIED, $char=false)
getModExpression($expression1, $expression2)
getListTableForeignKeysSQL($table, $database=null)
getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
getDateTypeDeclarationSQL(array $fieldDeclaration)
getCreateIndexSQL(Index $index, $table)
getSubstringExpression($value, $from, $len=null)
_getCreateTableSQL($tableName, array $columns, array $options=array())
getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)