Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / dbal / lib / Doctrine / DBAL / Platforms / DB2Platform.php
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\DBALException;
23 use Doctrine\DBAL\Schema\Index;
24 use Doctrine\DBAL\Schema\TableDiff;
25
26 class DB2Platform extends AbstractPlatform
27 {
28     /**
29      * {@inheritDoc}
30      */
31     public function getBlobTypeDeclarationSQL(array $field)
32     {
33         throw DBALException::notSupported(__METHOD__);
34     }
35
36     /**
37      * {@inheritDoc}
38      */
39     public function initializeDoctrineTypeMappings()
40     {
41         $this->doctrineTypeMapping = array(
42             'smallint'      => 'smallint',
43             'bigint'        => 'bigint',
44             'integer'       => 'integer',
45             'time'          => 'time',
46             'date'          => 'date',
47             'varchar'       => 'string',
48             'character'     => 'string',
49             'clob'          => 'text',
50             'decimal'       => 'decimal',
51             'double'        => 'float',
52             'real'          => 'float',
53             'timestamp'     => 'datetime',
54         );
55     }
56
57     /**
58      * {@inheritDoc}
59      */
60     protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
61     {
62         return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
63                 : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
64     }
65
66     /**
67      * {@inheritDoc}
68      */
69     public function getClobTypeDeclarationSQL(array $field)
70     {
71         // todo clob(n) with $field['length'];
72         return 'CLOB(1M)';
73     }
74
75     /**
76      * {@inheritDoc}
77      */
78     public function getName()
79     {
80         return 'db2';
81     }
82
83     /**
84      * {@inheritDoc}
85      */
86     public function getBooleanTypeDeclarationSQL(array $columnDef)
87     {
88         return 'SMALLINT';
89     }
90
91     /**
92      * {@inheritDoc}
93      */
94     public function getIntegerTypeDeclarationSQL(array $columnDef)
95     {
96         return 'INTEGER' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef);
97     }
98
99     /**
100      * {@inheritDoc}
101      */
102     public function getBigIntTypeDeclarationSQL(array $columnDef)
103     {
104         return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef);
105     }
106
107     /**
108      * {@inheritDoc}
109      */
110     public function getSmallIntTypeDeclarationSQL(array $columnDef)
111     {
112         return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef);
113     }
114
115     /**
116      * {@inheritDoc}
117      */
118     protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
119     {
120         $autoinc = '';
121         if ( ! empty($columnDef['autoincrement'])) {
122             $autoinc = ' GENERATED BY DEFAULT AS IDENTITY';
123         }
124
125         return $autoinc;
126     }
127
128     /**
129      * {@inheritDoc}
130      */
131     public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
132     {
133         if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] == true) {
134             return "TIMESTAMP(0) WITH DEFAULT";
135         }
136
137         return 'TIMESTAMP(0)';
138     }
139
140     /**
141      * {@inheritDoc}
142      */
143     public function getDateTypeDeclarationSQL(array $fieldDeclaration)
144     {
145         return 'DATE';
146     }
147
148     /**
149      * {@inheritDoc}
150      */
151     public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
152     {
153         return 'TIME';
154     }
155
156     public function getListDatabasesSQL()
157     {
158         throw DBALException::notSupported(__METHOD__);
159     }
160
161     public function getListSequencesSQL($database)
162     {
163         throw DBALException::notSupported(__METHOD__);
164     }
165
166     public function getListTableConstraintsSQL($table)
167     {
168         throw DBALException::notSupported(__METHOD__);
169     }
170
171     /**
172      * This code fragment is originally from the Zend_Db_Adapter_Db2 class.
173      *
174      * @license New BSD License
175      * @param  string $table
176      * @param string $database
177      * @return string
178      */
179     public function getListTableColumnsSQL($table, $database = null)
180     {
181         return "SELECT DISTINCT c.tabschema, c.tabname, c.colname, c.colno,
182                 c.typename, c.default, c.nulls, c.length, c.scale,
183                 c.identity, tc.type AS tabconsttype, k.colseq
184                 FROM syscat.columns c
185                 LEFT JOIN (syscat.keycoluse k JOIN syscat.tabconst tc
186                 ON (k.tabschema = tc.tabschema
187                     AND k.tabname = tc.tabname
188                     AND tc.type = 'P'))
189                 ON (c.tabschema = k.tabschema
190                     AND c.tabname = k.tabname
191                     AND c.colname = k.colname)
192                 WHERE UPPER(c.tabname) = UPPER('" . $table . "') ORDER BY c.colno";
193     }
194
195     public function getListTablesSQL()
196     {
197         return "SELECT NAME FROM SYSIBM.SYSTABLES WHERE TYPE = 'T'";
198     }
199
200     public function getListUsersSQL()
201     {
202         throw DBALException::notSupported(__METHOD__);
203     }
204
205     /**
206      * {@inheritDoc}
207      */
208     public function getListViewsSQL($database)
209     {
210         return "SELECT NAME, TEXT FROM SYSIBM.SYSVIEWS";
211     }
212
213     /**
214      * {@inheritDoc}
215      */
216     public function getListTableIndexesSQL($table, $currentDatabase = null)
217     {
218         return "SELECT NAME, COLNAMES, UNIQUERULE FROM SYSIBM.SYSINDEXES WHERE TBNAME = UPPER('" . $table . "')";
219     }
220
221     public function getListTableForeignKeysSQL($table)
222     {
223         return "SELECT TBNAME, RELNAME, REFTBNAME, DELETERULE, UPDATERULE, FKCOLNAMES, PKCOLNAMES ".
224                "FROM SYSIBM.SYSRELS WHERE TBNAME = UPPER('".$table."')";
225     }
226
227     public function getCreateViewSQL($name, $sql)
228     {
229         return "CREATE VIEW ".$name." AS ".$sql;
230     }
231
232     public function getDropViewSQL($name)
233     {
234         return "DROP VIEW ".$name;
235     }
236
237     /**
238      * {@inheritDoc}
239      */
240     public function getDropSequenceSQL($sequence)
241     {
242         throw DBALException::notSupported(__METHOD__);
243     }
244
245     public function getSequenceNextValSQL($sequenceName)
246     {
247         throw DBALException::notSupported(__METHOD__);
248     }
249
250     /**
251      * {@inheritDoc}
252      */
253     public function getCreateDatabaseSQL($database)
254     {
255         return "CREATE DATABASE ".$database;
256     }
257
258     /**
259      * {@inheritDoc}
260      */
261     public function getDropDatabaseSQL($database)
262     {
263         return "DROP DATABASE ".$database.";";
264     }
265
266     /**
267      * {@inheritDoc}
268      */
269     public function supportsCreateDropDatabase()
270     {
271         return false;
272     }
273
274     /**
275      * {@inheritDoc}
276      */
277     public function supportsReleaseSavepoints()
278     {
279         return false;
280     }
281
282     /**
283      * {@inheritDoc}
284      */
285     public function getCurrentDateSQL()
286     {
287         return 'VALUES CURRENT DATE';
288     }
289
290     /**
291      * {@inheritDoc}
292      */
293     public function getCurrentTimeSQL()
294     {
295         return 'VALUES CURRENT TIME';
296     }
297
298     /**
299      * {@inheritDoc}
300      */
301     public function getCurrentTimestampSQL()
302     {
303         return "VALUES CURRENT TIMESTAMP";
304     }
305
306     /**
307      * {@inheritDoc}
308      */
309     public function getIndexDeclarationSQL($name, Index $index)
310     {
311         return $this->getUniqueConstraintDeclarationSQL($name, $index);
312     }
313
314     /**
315      * {@inheritDoc}
316      */
317     protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
318     {
319         $indexes = array();
320         if (isset($options['indexes'])) {
321             $indexes = $options['indexes'];
322         }
323         $options['indexes'] = array();
324
325         $sqls = parent::_getCreateTableSQL($tableName, $columns, $options);
326
327         foreach ($indexes as $definition) {
328             $sqls[] = $this->getCreateIndexSQL($definition, $tableName);
329         }
330         return $sqls;
331     }
332
333     /**
334      * {@inheritDoc}
335      */
336     public function getAlterTableSQL(TableDiff $diff)
337     {
338         $sql = array();
339         $columnSql = array();
340
341         $queryParts = array();
342         foreach ($diff->addedColumns as $column) {
343             if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
344                 continue;
345             }
346
347             $queryParts[] = 'ADD COLUMN ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
348         }
349
350         foreach ($diff->removedColumns as $column) {
351             if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
352                 continue;
353             }
354
355             $queryParts[] =  'DROP COLUMN ' . $column->getQuotedName($this);
356         }
357
358         foreach ($diff->changedColumns as $columnDiff) {
359             if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
360                 continue;
361             }
362
363             /* @var $columnDiff \Doctrine\DBAL\Schema\ColumnDiff */
364             $column = $columnDiff->column;
365             $queryParts[] =  'ALTER ' . ($columnDiff->oldColumnName) . ' '
366                     . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
367         }
368
369         foreach ($diff->renamedColumns as $oldColumnName => $column) {
370             if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
371                 continue;
372             }
373
374             $queryParts[] =  'RENAME ' . $oldColumnName . ' TO ' . $column->getQuotedName($this);
375         }
376
377         $tableSql = array();
378
379         if ( ! $this->onSchemaAlterTable($diff, $tableSql)) {
380             if (count($queryParts) > 0) {
381                 $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . implode(" ", $queryParts);
382             }
383
384             $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff));
385
386             if ($diff->newName !== false) {
387                 $sql[] =  'RENAME TABLE TO ' . $diff->newName;
388             }
389         }
390
391         return array_merge($sql, $tableSql, $columnSql);
392     }
393
394     /**
395      * {@inheritDoc}
396      */
397     public function getDefaultValueDeclarationSQL($field)
398     {
399         if (isset($field['notnull']) && $field['notnull'] && !isset($field['default'])) {
400             if (in_array((string)$field['type'], array("Integer", "BigInteger", "SmallInteger"))) {
401                 $field['default'] = 0;
402             } else if((string)$field['type'] == "DateTime") {
403                 $field['default'] = "00-00-00 00:00:00";
404             } else if ((string)$field['type'] == "Date") {
405                 $field['default'] = "00-00-00";
406             } else if((string)$field['type'] == "Time") {
407                 $field['default'] = "00:00:00";
408             } else {
409                 $field['default'] = '';
410             }
411         }
412
413         unset($field['default']); // @todo this needs fixing
414         if (isset($field['version']) && $field['version']) {
415             if ((string)$field['type'] != "DateTime") {
416                 $field['default'] = "1";
417             }
418         }
419
420         return parent::getDefaultValueDeclarationSQL($field);
421     }
422
423     /**
424      * {@inheritDoc}
425      */
426     public function getEmptyIdentityInsertSQL($tableName, $identifierColumnName)
427     {
428         return 'INSERT INTO ' . $tableName . ' (' . $identifierColumnName . ') VALUES (DEFAULT)';
429     }
430
431     public function getCreateTemporaryTableSnippetSQL()
432     {
433         return "DECLARE GLOBAL TEMPORARY TABLE";
434     }
435
436     /**
437      * {@inheritDoc}
438      */
439     public function getTemporaryTableName($tableName)
440     {
441         return "SESSION." . $tableName;
442     }
443
444     /**
445      * {@inheritDoc}
446      */
447     protected function doModifyLimitQuery($query, $limit, $offset = null)
448     {
449         if ($limit === null && $offset === null) {
450             return $query;
451         }
452
453         $limit = (int)$limit;
454         $offset = (int)(($offset)?:0);
455
456         // Todo OVER() needs ORDER BY data!
457         $sql = 'SELECT db22.* FROM (SELECT ROW_NUMBER() OVER() AS DC_ROWNUM, db21.* '.
458                'FROM (' . $query . ') db21) db22 WHERE db22.DC_ROWNUM BETWEEN ' . ($offset+1) .' AND ' . ($offset+$limit);
459
460         return $sql;
461     }
462
463     /**
464      * {@inheritDoc}
465      */
466     public function getLocateExpression($str, $substr, $startPos = false)
467     {
468         if ($startPos == false) {
469             return 'LOCATE(' . $substr . ', ' . $str . ')';
470         }
471
472         return 'LOCATE(' . $substr . ', ' . $str . ', '.$startPos.')';
473     }
474
475     /**
476      * {@inheritDoc}
477      */
478     public function getSubstringExpression($value, $from, $length = null)
479     {
480         if ($length === null) {
481             return 'SUBSTR(' . $value . ', ' . $from . ')';
482         }
483
484         return 'SUBSTR(' . $value . ', ' . $from . ', ' . $length . ')';
485     }
486
487     /**
488      * {@inheritDoc}
489      */
490     public function supportsIdentityColumns()
491     {
492         return true;
493     }
494
495     /**
496      * {@inheritDoc}
497      */
498     public function prefersIdentityColumns()
499     {
500         return true;
501     }
502
503     /**
504      * {@inheritDoc}
505      *
506      * DB2 returns all column names in SQL result sets in uppercase.
507      */
508     public function getSQLResultCasing($column)
509     {
510         return strtoupper($column);
511     }
512
513     public function getForUpdateSQL()
514     {
515         return ' WITH RR USE AND KEEP UPDATE LOCKS';
516     }
517
518     /**
519      * {@inheritDoc}
520      */
521     public function getDummySelectSQL()
522     {
523         return 'SELECT 1 FROM sysibm.sysdummy1';
524     }
525
526     /**
527      * {@inheritDoc}
528      *
529      * DB2 supports savepoints, but they work semantically different than on other vendor platforms.
530      *
531      * TODO: We have to investigate how to get DB2 up and running with savepoints.
532      */
533     public function supportsSavepoints()
534     {
535         return false;
536     }
537
538     /**
539      * {@inheritDoc}
540      */
541     protected function getReservedKeywordsClass()
542     {
543         return 'Doctrine\DBAL\Platforms\Keywords\DB2Keywords';
544     }
545 }