source: pro-violet-viettel/sourcecode/application/libraries/Doctrine/DBAL/Platforms/SQLServerPlatform.php @ 345

Last change on this file since 345 was 345, checked in by quyenla, 11 years ago

collaborator page

File size: 23.3 KB
Line 
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
21namespace Doctrine\DBAL\Platforms;
22
23use Doctrine\DBAL\Schema\TableDiff;
24use Doctrine\DBAL\DBALException;
25use Doctrine\DBAL\Schema\Index,
26    Doctrine\DBAL\Schema\Table;
27
28/**
29 * The SQLServerPlatform provides the behavior, features and SQL dialect of the
30 * Microsoft SQL Server database platform.
31 *
32 * @since 2.0
33 * @author Roman Borschel <roman@code-factory.org>
34 * @author Jonathan H. Wage <jonwage@gmail.com>
35 * @author Benjamin Eberlei <kontakt@beberlei.de>
36 */
37class SQLServerPlatform extends AbstractPlatform
38{
39    /**
40     * {@inheritDoc}
41     */
42    public function getDateDiffExpression($date1, $date2)
43    {
44        return 'DATEDIFF(day, ' . $date2 . ',' . $date1 . ')';
45    }
46
47    public function getDateAddDaysExpression($date, $days)
48    {
49        return 'DATEADD(day, ' . $days . ', ' . $date . ')';
50    }
51
52    public function getDateSubDaysExpression($date, $days)
53    {
54        return 'DATEADD(day, -1 * ' . $days . ', ' . $date . ')';
55    }
56
57    public function getDateAddMonthExpression($date, $months)
58    {
59        return 'DATEADD(month, ' . $months . ', ' . $date . ')';
60    }
61
62    public function getDateSubMonthExpression($date, $months)
63    {
64        return 'DATEADD(month, -1 * ' . $months . ', ' . $date . ')';
65    }
66
67    /**
68     * Whether the platform prefers identity columns for ID generation.
69     * MsSql prefers "autoincrement" identity columns since sequences can only
70     * be emulated with a table.
71     *
72     * @return boolean
73     * @override
74     */
75    public function prefersIdentityColumns()
76    {
77        return true;
78    }
79
80    /**
81     * Whether the platform supports identity columns.
82     * MsSql supports this through AUTO_INCREMENT columns.
83     *
84     * @return boolean
85     * @override
86     */
87    public function supportsIdentityColumns()
88    {
89        return true;
90    }
91
92    /**
93     * Whether the platform supports releasing savepoints.
94     *
95     * @return boolean
96     */
97    public function supportsReleaseSavepoints()
98    {
99        return false;
100    }
101
102    /**
103     * create a new database
104     *
105     * @param string $name name of the database that should be created
106     * @return string
107     * @override
108     */
109    public function getCreateDatabaseSQL($name)
110    {
111        return 'CREATE DATABASE ' . $name;
112    }
113
114    /**
115     * drop an existing database
116     *
117     * @param string $name name of the database that should be dropped
118     * @return string
119     * @override
120     */
121    public function getDropDatabaseSQL($name)
122    {
123        return 'DROP DATABASE ' . $name;
124    }
125
126    /**
127     * @override
128     */
129    public function supportsCreateDropDatabase()
130    {
131        return false;
132    }
133
134    /**
135     * @override
136     */
137    public function getDropForeignKeySQL($foreignKey, $table)
138    {
139        if ($foreignKey instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) {
140            $foreignKey = $foreignKey->getQuotedName($this);
141        }
142
143        if ($table instanceof \Doctrine\DBAL\Schema\Table) {
144            $table = $table->getQuotedName($this);
145        }
146
147        return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey;
148    }
149
150    /**
151     * @override
152     */
153    public function getDropIndexSQL($index, $table=null)
154    {
155        if ($index instanceof \Doctrine\DBAL\Schema\Index) {
156            $index_ = $index;
157            $index = $index->getQuotedName($this);
158        } else if (!is_string($index)) {
159            throw new \InvalidArgumentException('AbstractPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.');
160        }
161
162        if (!isset($table)) {
163            return 'DROP INDEX ' . $index;
164        } else {
165            if ($table instanceof \Doctrine\DBAL\Schema\Table) {
166                $table = $table->getQuotedName($this);
167            }
168
169            return "IF EXISTS (SELECT * FROM sysobjects WHERE name = '$index')
170                                                ALTER TABLE " . $table . " DROP CONSTRAINT " . $index . "
171                                        ELSE
172                                                DROP INDEX " . $index . " ON " . $table;
173        }
174    }
175
176    /**
177     * @override
178     */
179    protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
180    {
181        // @todo does other code breaks because of this?
182        // foce primary keys to be not null
183        foreach ($columns as &$column) {
184            if (isset($column['primary']) && $column['primary']) {
185                $column['notnull'] = true;
186            }
187        }
188
189        $columnListSql = $this->getColumnDeclarationListSQL($columns);
190
191        if (isset($options['uniqueConstraints']) && !empty($options['uniqueConstraints'])) {
192            foreach ($options['uniqueConstraints'] as $name => $definition) {
193                $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition);
194            }
195        }
196
197        if (isset($options['primary']) && !empty($options['primary'])) {
198            $columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')';
199        }
200
201        $query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql;
202
203        $check = $this->getCheckDeclarationSQL($columns);
204        if (!empty($check)) {
205            $query .= ', ' . $check;
206        }
207        $query .= ')';
208
209        $sql[] = $query;
210
211        if (isset($options['indexes']) && !empty($options['indexes'])) {
212            foreach ($options['indexes'] AS $index) {
213                $sql[] = $this->getCreateIndexSQL($index, $tableName);
214            }
215        }
216
217        if (isset($options['foreignKeys'])) {
218            foreach ((array) $options['foreignKeys'] AS $definition) {
219                $sql[] = $this->getCreateForeignKeySQL($definition, $tableName);
220            }
221        }
222
223        return $sql;
224    }
225
226    /**
227     * @override
228     */
229    public function getUniqueConstraintDeclarationSQL($name, Index $index)
230    {
231        $constraint = parent::getUniqueConstraintDeclarationSQL($name, $index);
232
233        $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index);
234
235        return $constraint;
236    }
237
238    /**
239     * @override
240     */
241    public function getCreateIndexSQL(Index $index, $table)
242    {
243        $constraint = parent::getCreateIndexSQL($index, $table);
244
245        if ($index->isUnique()) {
246            $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index);
247        }
248
249        return $constraint;
250    }
251
252    /**
253     * Extend unique key constraint with required filters
254     *
255     * @param string $sql
256     * @param Index $index
257     * @return string
258     */
259    private function _appendUniqueConstraintDefinition($sql, Index $index)
260    {
261        $fields = array();
262        foreach ($index->getColumns() as $field => $definition) {
263            if (!is_array($definition)) {
264                $field = $definition;
265            }
266
267            $fields[] = $field . ' IS NOT NULL';
268        }
269
270        return $sql . ' WHERE ' . implode(' AND ', $fields);
271    }
272
273    /**
274     * @override
275     */
276    public function getAlterTableSQL(TableDiff $diff)
277    {
278        $queryParts = array();
279        $sql = array();
280        $columnSql = array();
281
282        if ($diff->newName !== false) {
283            $queryParts[] = 'RENAME TO ' . $diff->newName;
284        }
285
286        foreach ($diff->addedColumns AS $fieldName => $column) {
287            if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
288                continue;
289            }
290
291            $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
292        }
293
294        foreach ($diff->removedColumns AS $column) {
295            if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
296                continue;
297            }
298
299            $queryParts[] = 'DROP COLUMN ' . $column->getQuotedName($this);
300        }
301
302        foreach ($diff->changedColumns AS $columnDiff) {
303            if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
304                continue;
305            }
306
307            /* @var $columnDiff Doctrine\DBAL\Schema\ColumnDiff */
308            $column = $columnDiff->column;
309            $queryParts[] = 'ALTER COLUMN ' .
310                    $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
311        }
312
313        foreach ($diff->renamedColumns AS $oldColumnName => $column) {
314            if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
315                continue;
316            }
317
318            $sql[] = "sp_RENAME '". $diff->name. ".". $oldColumnName . "' , '".$column->getQuotedName($this)."', 'COLUMN'";
319            $queryParts[] = 'ALTER COLUMN ' .
320                    $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
321        }
322
323        $tableSql = array();
324
325        if ($this->onSchemaAlterTable($diff, $tableSql)) {
326            return array_merge($tableSql, $columnSql);
327        }
328
329        foreach ($queryParts as $query) {
330            $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
331        }
332
333        $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff));
334
335        return array_merge($sql, $tableSql, $columnSql);
336    }
337
338    /**
339     * @override
340     */
341    public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
342    {
343        return 'INSERT INTO ' . $quotedTableName . ' DEFAULT VALUES';
344    }
345
346    /**
347     * @override
348     */
349    public function getShowDatabasesSQL()
350    {
351        return 'SHOW DATABASES';
352    }
353
354    /**
355     * @override
356     */
357    public function getListTablesSQL()
358    {
359        // "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams
360        return "SELECT name FROM sysobjects WHERE type = 'U' AND name != 'sysdiagrams' ORDER BY name";
361    }
362
363    /**
364     * @override
365     */
366    public function getListTableColumnsSQL($table, $database = null)
367    {
368        return "exec sp_columns @table_name = '" . $table . "'";
369    }
370
371    /**
372     * @override
373     */
374    public function getListTableForeignKeysSQL($table, $database = null)
375    {
376        return "SELECT f.name AS ForeignKey,
377                SCHEMA_NAME (f.SCHEMA_ID) AS SchemaName,
378                OBJECT_NAME (f.parent_object_id) AS TableName,
379                COL_NAME (fc.parent_object_id,fc.parent_column_id) AS ColumnName,
380                SCHEMA_NAME (o.SCHEMA_ID) ReferenceSchemaName,
381                OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
382                COL_NAME(fc.referenced_object_id,fc.referenced_column_id) AS ReferenceColumnName,
383                f.delete_referential_action_desc,
384                f.update_referential_action_desc
385                FROM sys.foreign_keys AS f
386                INNER JOIN sys.foreign_key_columns AS fc
387                INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id
388                ON f.OBJECT_ID = fc.constraint_object_id
389                WHERE OBJECT_NAME (f.parent_object_id) = '" . $table . "'";
390    }
391
392    /**
393     * @override
394     */
395    public function getListTableIndexesSQL($table, $currentDatabase = null)
396    {
397        return "exec sp_helpindex '" . $table . "'";
398    }
399
400    /**
401     * @override
402     */
403    public function getCreateViewSQL($name, $sql)
404    {
405        return 'CREATE VIEW ' . $name . ' AS ' . $sql;
406    }
407
408    /**
409     * @override
410     */
411    public function getListViewsSQL($database)
412    {
413        return "SELECT name FROM sysobjects WHERE type = 'V' ORDER BY name";
414    }
415
416    /**
417     * @override
418     */
419    public function getDropViewSQL($name)
420    {
421        return 'DROP VIEW ' . $name;
422    }
423
424    /**
425     * Returns the regular expression operator.
426     *
427     * @return string
428     * @override
429     */
430    public function getRegexpExpression()
431    {
432        return 'RLIKE';
433    }
434
435    /**
436     * Returns global unique identifier
437     *
438     * @return string to get global unique identifier
439     * @override
440     */
441    public function getGuidExpression()
442    {
443        return 'UUID()';
444    }
445
446    /**
447     * @override
448     */
449    public function getLocateExpression($str, $substr, $startPos = false)
450    {
451        if ($startPos == false) {
452            return 'CHARINDEX(' . $substr . ', ' . $str . ')';
453        } else {
454            return 'CHARINDEX(' . $substr . ', ' . $str . ', ' . $startPos . ')';
455        }
456    }
457
458    /**
459     * @override
460     */
461    public function getModExpression($expression1, $expression2)
462    {
463        return $expression1 . ' % ' . $expression2;
464    }
465
466    /**
467     * @override
468     */
469    public function getTrimExpression($str, $pos = self::TRIM_UNSPECIFIED, $char = false)
470    {
471        $trimFn = '';
472
473        if (!$char) {
474            if ($pos == self::TRIM_LEADING) {
475                $trimFn = 'LTRIM';
476            } else if ($pos == self::TRIM_TRAILING) {
477                $trimFn = 'RTRIM';
478            } else {
479                return 'LTRIM(RTRIM(' . $str . '))';
480            }
481
482            return $trimFn . '(' . $str . ')';
483        } else {
484            /** Original query used to get those expressions
485              declare @c varchar(100) = 'xxxBarxxx', @trim_char char(1) = 'x';
486              declare @pat varchar(10) = '%[^' + @trim_char + ']%';
487              select @c as string
488              , @trim_char as trim_char
489              , stuff(@c, 1, patindex(@pat, @c) - 1, null) as trim_leading
490              , reverse(stuff(reverse(@c), 1, patindex(@pat, reverse(@c)) - 1, null)) as trim_trailing
491              , reverse(stuff(reverse(stuff(@c, 1, patindex(@pat, @c) - 1, null)), 1, patindex(@pat, reverse(stuff(@c, 1, patindex(@pat, @c) - 1, null))) - 1, null)) as trim_both;
492             */
493            $pattern = "'%[^' + $char + ']%'";
494
495            if ($pos == self::TRIM_LEADING) {
496                return 'stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)';
497            } else if ($pos == self::TRIM_TRAILING) {
498                return 'reverse(stuff(reverse(' . $str . '), 1, patindex(' . $pattern . ', reverse(' . $str . ')) - 1, null))';
499            } else {
500                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))';
501            }
502        }
503    }
504
505    /**
506     * @override
507     */
508    public function getConcatExpression()
509    {
510        $args = func_get_args();
511        return '(' . implode(' + ', $args) . ')';
512    }
513
514    public function getListDatabasesSQL()
515    {
516        return 'SELECT * FROM SYS.DATABASES';
517    }
518
519    /**
520     * @override
521     */
522    public function getSubstringExpression($value, $from, $len = null)
523    {
524        if (!is_null($len)) {
525            return 'SUBSTRING(' . $value . ', ' . $from . ', ' . $len . ')';
526        }
527        return 'SUBSTRING(' . $value . ', ' . $from . ', LEN(' . $value . ') - ' . $from . ' + 1)';
528    }
529
530    /**
531     * @override
532     */
533    public function getLengthExpression($column)
534    {
535        return 'LEN(' . $column . ')';
536    }
537
538    /**
539     * @override
540     */
541    public function getSetTransactionIsolationSQL($level)
542    {
543        return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level);
544    }
545
546    /**
547     * @override
548     */
549    public function getIntegerTypeDeclarationSQL(array $field)
550    {
551        return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
552    }
553
554    /**
555     * @override
556     */
557    public function getBigIntTypeDeclarationSQL(array $field)
558    {
559        return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
560    }
561
562    /**
563     * @override
564     */
565    public function getSmallIntTypeDeclarationSQL(array $field)
566    {
567        return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
568    }
569
570    /** @override */
571    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
572    {
573        return $fixed ? ($length ? 'NCHAR(' . $length . ')' : 'CHAR(255)') : ($length ? 'NVARCHAR(' . $length . ')' : 'NVARCHAR(255)');
574    }
575
576    /** @override */
577    public function getClobTypeDeclarationSQL(array $field)
578    {
579        return 'TEXT';
580    }
581
582    /**
583     * @override
584     */
585    protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
586    {
587        $autoinc = '';
588        if (!empty($columnDef['autoincrement'])) {
589            $autoinc = ' IDENTITY';
590        }
591        $unsigned = (isset($columnDef['unsigned']) && $columnDef['unsigned']) ? ' UNSIGNED' : '';
592
593        return $unsigned . $autoinc;
594    }
595
596    /**
597     * @override
598     */
599    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
600    {
601        return 'DATETIME';
602    }
603
604    /**
605     * @override
606     */
607    public function getDateTypeDeclarationSQL(array $fieldDeclaration)
608    {
609        return 'DATETIME';
610    }
611
612    /**
613     * @override
614     */
615    public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
616    {
617        return 'DATETIME';
618    }
619
620    /**
621     * @override
622     */
623    public function getBooleanTypeDeclarationSQL(array $field)
624    {
625        return 'BIT';
626    }
627
628    /**
629     * Adds an adapter-specific LIMIT clause to the SELECT statement.
630     *
631     * @param string $query
632     * @param integer $limit
633     * @param integer $offset
634     * @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html
635     * @return string
636     */
637    protected function doModifyLimitQuery($query, $limit, $offset = null)
638    {
639        if ($limit > 0) {
640            if ($offset == 0) {
641                $query = preg_replace('/^(SELECT\s(DISTINCT\s)?)/i', '\1TOP ' . $limit . ' ', $query);
642            } else {
643                $orderby = stristr($query, 'ORDER BY');
644
645                if (!$orderby) {
646                    $over = 'ORDER BY (SELECT 0)';
647                } else {
648                    $over = preg_replace('/\"[^,]*\".\"([^,]*)\"/i', '"inner_tbl"."$1"', $orderby);
649                }
650
651                // Remove ORDER BY clause from $query
652                $query = preg_replace('/\s+ORDER BY(.*)/', '', $query);
653                $query = preg_replace('/^SELECT\s/', '', $query);
654
655                $start = $offset + 1;
656                $end = $offset + $limit;
657
658                $query = "SELECT * FROM (SELECT ROW_NUMBER() OVER ($over) AS \"doctrine_rownum\", $query) AS doctrine_tbl WHERE \"doctrine_rownum\" BETWEEN $start AND $end";
659            }
660        }
661
662        return $query;
663    }
664
665    /**
666     * @override
667     */
668    public function supportsLimitOffset()
669    {
670        return false;
671    }
672
673    /**
674     * @override
675     */
676    public function convertBooleans($item)
677    {
678        if (is_array($item)) {
679            foreach ($item as $key => $value) {
680                if (is_bool($value) || is_numeric($item)) {
681                    $item[$key] = ($value) ? 1 : 0;
682                }
683            }
684        } else {
685            if (is_bool($item) || is_numeric($item)) {
686                $item = ($item) ? 1 : 0;
687            }
688        }
689        return $item;
690    }
691
692    /**
693     * @override
694     */
695    public function getCreateTemporaryTableSnippetSQL()
696    {
697        return "CREATE TABLE";
698    }
699
700    /**
701     * @override
702     */
703    public function getTemporaryTableName($tableName)
704    {
705        return '#' . $tableName;
706    }
707
708    /**
709     * @override
710     */
711    public function getDateTimeFormatString()
712    {
713        return 'Y-m-d H:i:s.000';
714    }
715
716    /**
717     * @override
718     */
719    public function getDateFormatString()
720    {
721        return 'Y-m-d H:i:s.000';
722    }
723
724    /**
725     * @override
726     */
727    public function getTimeFormatString()
728    {
729        return 'Y-m-d H:i:s.000';
730    }
731
732    /**
733     * @override
734     */
735    public function getDateTimeTzFormatString()
736    {
737        return $this->getDateTimeFormatString();
738    }
739
740    /**
741     * Get the platform name for this instance
742     *
743     * @return string
744     */
745    public function getName()
746    {
747        return 'mssql';
748    }
749
750    /**
751     * @override
752     */
753    protected function initializeDoctrineTypeMappings()
754    {
755        $this->doctrineTypeMapping = array(
756            'bigint' => 'bigint',
757            'numeric' => 'decimal',
758            'bit' => 'boolean',
759            'smallint' => 'smallint',
760            'decimal' => 'decimal',
761            'smallmoney' => 'integer',
762            'int' => 'integer',
763            'tinyint' => 'smallint',
764            'money' => 'integer',
765            'float' => 'float',
766            'real' => 'float',
767            'double' => 'float',
768            'double precision' => 'float',
769            'datetimeoffset' => 'datetimetz',
770            'smalldatetime' => 'datetime',
771            'datetime' => 'datetime',
772            'char' => 'string',
773            'varchar' => 'string',
774            'text' => 'text',
775            'nchar' => 'string',
776            'nvarchar' => 'string',
777            'ntext' => 'text',
778            'binary' => 'text',
779            'varbinary' => 'blob',
780            'image' => 'text',
781        );
782    }
783
784    /**
785     * Generate SQL to create a new savepoint
786     *
787     * @param string $savepoint
788     * @return string
789     */
790    public function createSavePoint($savepoint)
791    {
792        return 'SAVE TRANSACTION ' . $savepoint;
793    }
794
795    /**
796     * Generate SQL to release a savepoint
797     *
798     * @param string $savepoint
799     * @return string
800     */
801    public function releaseSavePoint($savepoint)
802    {
803        return '';
804    }
805
806    /**
807     * Generate SQL to rollback a savepoint
808     *
809     * @param string $savepoint
810     * @return string
811     */
812    public function rollbackSavePoint($savepoint)
813    {
814        return 'ROLLBACK TRANSACTION ' . $savepoint;
815    }
816
817    /**
818     * @override
819     */
820    public function appendLockHint($fromClause, $lockMode)
821    {
822        // @todo coorect
823        if ($lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_READ) {
824            return $fromClause . ' WITH (tablockx)';
825        } else if ($lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE) {
826            return $fromClause . ' WITH (tablockx)';
827        } else {
828            return $fromClause;
829        }
830    }
831
832    /**
833     * @override
834     */
835    public function getForUpdateSQL()
836    {
837        return ' ';
838    }
839
840    protected function getReservedKeywordsClass()
841    {
842        return 'Doctrine\DBAL\Platforms\Keywords\MsSQLKeywords';
843    }
844
845    /**
846     * {@inheritDoc}
847     */
848    public function quoteSingleIdentifier($str)
849    {
850        return "[" . str_replace("]", "][", $str) . "]";
851    }
852
853    public function getTruncateTableSQL($tableName, $cascade = false)
854    {
855        return 'TRUNCATE TABLE '.$tableName;
856    }
857
858    /**
859     * Gets the SQL Snippet used to declare a BLOB column type.
860     */
861    public function getBlobTypeDeclarationSQL(array $field)
862    {
863        return 'VARBINARY(MAX)';
864    }
865}
Note: See TracBrowser for help on using the repository browser.