|
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 LGPL. For more information, see |
|
17 * <http://www.doctrine-project.org>. |
|
18 */ |
|
19 |
|
20 namespace Doctrine\DBAL\Platforms; |
|
21 |
|
22 use Doctrine\DBAL\Schema\TableDiff, |
|
23 Doctrine\DBAL\Schema\Table; |
|
24 |
|
25 /** |
|
26 * PostgreSqlPlatform. |
|
27 * |
|
28 * @since 2.0 |
|
29 * @author Roman Borschel <roman@code-factory.org> |
|
30 * @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library) |
|
31 * @author Benjamin Eberlei <kontakt@beberlei.de> |
|
32 * @todo Rename: PostgreSQLPlatform |
|
33 */ |
|
34 class PostgreSqlPlatform extends AbstractPlatform |
|
35 { |
|
36 /** |
|
37 * Returns part of a string. |
|
38 * |
|
39 * Note: Not SQL92, but common functionality. |
|
40 * |
|
41 * @param string $value the target $value the string or the string column. |
|
42 * @param int $from extract from this characeter. |
|
43 * @param int $len extract this amount of characters. |
|
44 * @return string sql that extracts part of a string. |
|
45 * @override |
|
46 */ |
|
47 public function getSubstringExpression($value, $from, $len = null) |
|
48 { |
|
49 if ($len === null) { |
|
50 return 'SUBSTR(' . $value . ', ' . $from . ')'; |
|
51 } else { |
|
52 return 'SUBSTR(' . $value . ', ' . $from . ', ' . $len . ')'; |
|
53 } |
|
54 } |
|
55 |
|
56 /** |
|
57 * Returns the SQL string to return the current system date and time. |
|
58 * |
|
59 * @return string |
|
60 */ |
|
61 public function getNowExpression() |
|
62 { |
|
63 return 'LOCALTIMESTAMP(0)'; |
|
64 } |
|
65 |
|
66 /** |
|
67 * regexp |
|
68 * |
|
69 * @return string the regular expression operator |
|
70 * @override |
|
71 */ |
|
72 public function getRegexpExpression() |
|
73 { |
|
74 return 'SIMILAR TO'; |
|
75 } |
|
76 |
|
77 /** |
|
78 * returns the position of the first occurrence of substring $substr in string $str |
|
79 * |
|
80 * @param string $substr literal string to find |
|
81 * @param string $str literal string |
|
82 * @param int $pos position to start at, beginning of string by default |
|
83 * @return integer |
|
84 */ |
|
85 public function getLocateExpression($str, $substr, $startPos = false) |
|
86 { |
|
87 if ($startPos !== false) { |
|
88 $str = $this->getSubstringExpression($str, $startPos); |
|
89 return 'CASE WHEN (POSITION('.$substr.' IN '.$str.') = 0) THEN 0 ELSE (POSITION('.$substr.' IN '.$str.') + '.($startPos-1).') END'; |
|
90 } else { |
|
91 return 'POSITION('.$substr.' IN '.$str.')'; |
|
92 } |
|
93 } |
|
94 |
|
95 public function getDateDiffExpression($date1, $date2) |
|
96 { |
|
97 return '(DATE(' . $date1 . ')-DATE(' . $date2 . '))'; |
|
98 } |
|
99 |
|
100 public function getDateAddDaysExpression($date, $days) |
|
101 { |
|
102 return "(" . $date . "+ interval '" . $days . " day')"; |
|
103 } |
|
104 |
|
105 public function getDateSubDaysExpression($date, $days) |
|
106 { |
|
107 return "(" . $date . "- interval '" . $days . " day')"; |
|
108 } |
|
109 |
|
110 public function getDateAddMonthExpression($date, $months) |
|
111 { |
|
112 return "(" . $date . "+ interval '" . $months . " month')"; |
|
113 } |
|
114 |
|
115 public function getDateSubMonthExpression($date, $months) |
|
116 { |
|
117 return "(" . $date . "- interval '" . $months . " month')"; |
|
118 } |
|
119 |
|
120 /** |
|
121 * parses a literal boolean value and returns |
|
122 * proper sql equivalent |
|
123 * |
|
124 * @param string $value boolean value to be parsed |
|
125 * @return string parsed boolean value |
|
126 */ |
|
127 /*public function parseBoolean($value) |
|
128 { |
|
129 return $value; |
|
130 }*/ |
|
131 |
|
132 /** |
|
133 * Whether the platform supports sequences. |
|
134 * Postgres has native support for sequences. |
|
135 * |
|
136 * @return boolean |
|
137 */ |
|
138 public function supportsSequences() |
|
139 { |
|
140 return true; |
|
141 } |
|
142 |
|
143 /** |
|
144 * Whether the platform supports database schemas. |
|
145 * |
|
146 * @return boolean |
|
147 */ |
|
148 public function supportsSchemas() |
|
149 { |
|
150 return true; |
|
151 } |
|
152 |
|
153 /** |
|
154 * Whether the platform supports identity columns. |
|
155 * Postgres supports these through the SERIAL keyword. |
|
156 * |
|
157 * @return boolean |
|
158 */ |
|
159 public function supportsIdentityColumns() |
|
160 { |
|
161 return true; |
|
162 } |
|
163 |
|
164 public function supportsCommentOnStatement() |
|
165 { |
|
166 return true; |
|
167 } |
|
168 |
|
169 /** |
|
170 * Whether the platform prefers sequences for ID generation. |
|
171 * |
|
172 * @return boolean |
|
173 */ |
|
174 public function prefersSequences() |
|
175 { |
|
176 return true; |
|
177 } |
|
178 |
|
179 public function getListDatabasesSQL() |
|
180 { |
|
181 return 'SELECT datname FROM pg_database'; |
|
182 } |
|
183 |
|
184 public function getListSequencesSQL($database) |
|
185 { |
|
186 return "SELECT |
|
187 c.relname, n.nspname AS schemaname |
|
188 FROM |
|
189 pg_class c, pg_namespace n |
|
190 WHERE relkind = 'S' AND n.oid = c.relnamespace AND |
|
191 (n.nspname NOT LIKE 'pg_%' AND n.nspname != 'information_schema')"; |
|
192 } |
|
193 |
|
194 public function getListTablesSQL() |
|
195 { |
|
196 return "SELECT tablename AS table_name, schemaname AS schema_name |
|
197 FROM pg_tables WHERE schemaname NOT LIKE 'pg_%' AND schemaname != 'information_schema'"; |
|
198 } |
|
199 |
|
200 public function getListViewsSQL($database) |
|
201 { |
|
202 return 'SELECT viewname, definition FROM pg_views'; |
|
203 } |
|
204 |
|
205 public function getListTableForeignKeysSQL($table, $database = null) |
|
206 { |
|
207 return "SELECT r.conname, pg_catalog.pg_get_constraintdef(r.oid, true) as condef |
|
208 FROM pg_catalog.pg_constraint r |
|
209 WHERE r.conrelid = |
|
210 ( |
|
211 SELECT c.oid |
|
212 FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n |
|
213 WHERE " .$this->getTableWhereClause($table) ." |
|
214 AND n.oid = c.relnamespace |
|
215 ) |
|
216 AND r.contype = 'f'"; |
|
217 } |
|
218 |
|
219 public function getCreateViewSQL($name, $sql) |
|
220 { |
|
221 return 'CREATE VIEW ' . $name . ' AS ' . $sql; |
|
222 } |
|
223 |
|
224 public function getDropViewSQL($name) |
|
225 { |
|
226 return 'DROP VIEW '. $name; |
|
227 } |
|
228 |
|
229 public function getListTableConstraintsSQL($table) |
|
230 { |
|
231 return "SELECT |
|
232 relname |
|
233 FROM |
|
234 pg_class |
|
235 WHERE oid IN ( |
|
236 SELECT indexrelid |
|
237 FROM pg_index, pg_class |
|
238 WHERE pg_class.relname = '$table' |
|
239 AND pg_class.oid = pg_index.indrelid |
|
240 AND (indisunique = 't' OR indisprimary = 't') |
|
241 )"; |
|
242 } |
|
243 |
|
244 /** |
|
245 * @license New BSD License |
|
246 * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html |
|
247 * @param string $table |
|
248 * @return string |
|
249 */ |
|
250 public function getListTableIndexesSQL($table, $currentDatabase = null) |
|
251 { |
|
252 return "SELECT relname, pg_index.indisunique, pg_index.indisprimary, |
|
253 pg_index.indkey, pg_index.indrelid |
|
254 FROM pg_class, pg_index |
|
255 WHERE oid IN ( |
|
256 SELECT indexrelid |
|
257 FROM pg_index si, pg_class sc, pg_namespace sn |
|
258 WHERE " . $this->getTableWhereClause($table, 'sc', 'sn')." AND sc.oid=si.indrelid AND sc.relnamespace = sn.oid |
|
259 ) AND pg_index.indexrelid = oid"; |
|
260 } |
|
261 |
|
262 private function getTableWhereClause($table, $classAlias = 'c', $namespaceAlias = 'n') |
|
263 { |
|
264 $whereClause = ""; |
|
265 if (strpos($table, ".") !== false) { |
|
266 list($schema, $table) = explode(".", $table); |
|
267 $whereClause = "$classAlias.relname = '" . $table . "' AND $namespaceAlias.nspname = '" . $schema . "'"; |
|
268 } else { |
|
269 $whereClause = "$classAlias.relname = '" . $table . "'"; |
|
270 } |
|
271 return $whereClause; |
|
272 } |
|
273 |
|
274 public function getListTableColumnsSQL($table, $database = null) |
|
275 { |
|
276 return "SELECT |
|
277 a.attnum, |
|
278 a.attname AS field, |
|
279 t.typname AS type, |
|
280 format_type(a.atttypid, a.atttypmod) AS complete_type, |
|
281 (SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype) AS domain_type, |
|
282 (SELECT format_type(t2.typbasetype, t2.typtypmod) FROM pg_catalog.pg_type t2 |
|
283 WHERE t2.typtype = 'd' AND t2.typname = format_type(a.atttypid, a.atttypmod)) AS domain_complete_type, |
|
284 a.attnotnull AS isnotnull, |
|
285 (SELECT 't' |
|
286 FROM pg_index |
|
287 WHERE c.oid = pg_index.indrelid |
|
288 AND pg_index.indkey[0] = a.attnum |
|
289 AND pg_index.indisprimary = 't' |
|
290 ) AS pri, |
|
291 (SELECT pg_attrdef.adsrc |
|
292 FROM pg_attrdef |
|
293 WHERE c.oid = pg_attrdef.adrelid |
|
294 AND pg_attrdef.adnum=a.attnum |
|
295 ) AS default, |
|
296 (SELECT pg_description.description |
|
297 FROM pg_description WHERE pg_description.objoid = c.oid AND a.attnum = pg_description.objsubid |
|
298 ) AS comment |
|
299 FROM pg_attribute a, pg_class c, pg_type t, pg_namespace n |
|
300 WHERE ".$this->getTableWhereClause($table, 'c', 'n') ." |
|
301 AND a.attnum > 0 |
|
302 AND a.attrelid = c.oid |
|
303 AND a.atttypid = t.oid |
|
304 AND n.oid = c.relnamespace |
|
305 ORDER BY a.attnum"; |
|
306 } |
|
307 |
|
308 /** |
|
309 * create a new database |
|
310 * |
|
311 * @param string $name name of the database that should be created |
|
312 * @throws PDOException |
|
313 * @return void |
|
314 * @override |
|
315 */ |
|
316 public function getCreateDatabaseSQL($name) |
|
317 { |
|
318 return 'CREATE DATABASE ' . $name; |
|
319 } |
|
320 |
|
321 /** |
|
322 * drop an existing database |
|
323 * |
|
324 * @param string $name name of the database that should be dropped |
|
325 * @throws PDOException |
|
326 * @access public |
|
327 */ |
|
328 public function getDropDatabaseSQL($name) |
|
329 { |
|
330 return 'DROP DATABASE ' . $name; |
|
331 } |
|
332 |
|
333 /** |
|
334 * Return the FOREIGN KEY query section dealing with non-standard options |
|
335 * as MATCH, INITIALLY DEFERRED, ON UPDATE, ... |
|
336 * |
|
337 * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey foreign key definition |
|
338 * @return string |
|
339 * @override |
|
340 */ |
|
341 public function getAdvancedForeignKeyOptionsSQL(\Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey) |
|
342 { |
|
343 $query = ''; |
|
344 if ($foreignKey->hasOption('match')) { |
|
345 $query .= ' MATCH ' . $foreignKey->getOption('match'); |
|
346 } |
|
347 $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey); |
|
348 if ($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false) { |
|
349 $query .= ' DEFERRABLE'; |
|
350 } else { |
|
351 $query .= ' NOT DEFERRABLE'; |
|
352 } |
|
353 if ($foreignKey->hasOption('feferred') && $foreignKey->getOption('feferred') !== false) { |
|
354 $query .= ' INITIALLY DEFERRED'; |
|
355 } else { |
|
356 $query .= ' INITIALLY IMMEDIATE'; |
|
357 } |
|
358 return $query; |
|
359 } |
|
360 |
|
361 /** |
|
362 * generates the sql for altering an existing table on postgresql |
|
363 * |
|
364 * @param string $name name of the table that is intended to be changed. |
|
365 * @param array $changes associative array that contains the details of each type * |
|
366 * @param boolean $check indicates whether the function should just check if the DBMS driver |
|
367 * can perform the requested table alterations if the value is true or |
|
368 * actually perform them otherwise. |
|
369 * @see Doctrine_Export::alterTable() |
|
370 * @return array |
|
371 * @override |
|
372 */ |
|
373 public function getAlterTableSQL(TableDiff $diff) |
|
374 { |
|
375 $sql = array(); |
|
376 $commentsSQL = array(); |
|
377 |
|
378 foreach ($diff->addedColumns as $column) { |
|
379 $query = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); |
|
380 $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query; |
|
381 if ($comment = $this->getColumnComment($column)) { |
|
382 $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment); |
|
383 } |
|
384 } |
|
385 |
|
386 foreach ($diff->removedColumns as $column) { |
|
387 $query = 'DROP ' . $column->getQuotedName($this); |
|
388 $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query; |
|
389 } |
|
390 |
|
391 foreach ($diff->changedColumns AS $columnDiff) { |
|
392 $oldColumnName = $columnDiff->oldColumnName; |
|
393 $column = $columnDiff->column; |
|
394 |
|
395 if ($columnDiff->hasChanged('type')) { |
|
396 $type = $column->getType(); |
|
397 |
|
398 // here was a server version check before, but DBAL API does not support this anymore. |
|
399 $query = 'ALTER ' . $oldColumnName . ' TYPE ' . $type->getSqlDeclaration($column->toArray(), $this); |
|
400 $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query; |
|
401 } |
|
402 if ($columnDiff->hasChanged('default')) { |
|
403 $query = 'ALTER ' . $oldColumnName . ' SET ' . $this->getDefaultValueDeclarationSQL($column->toArray()); |
|
404 $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query; |
|
405 } |
|
406 if ($columnDiff->hasChanged('notnull')) { |
|
407 $query = 'ALTER ' . $oldColumnName . ' ' . ($column->getNotNull() ? 'SET' : 'DROP') . ' NOT NULL'; |
|
408 $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query; |
|
409 } |
|
410 if ($columnDiff->hasChanged('autoincrement')) { |
|
411 if ($column->getAutoincrement()) { |
|
412 // add autoincrement |
|
413 $seqName = $diff->name . '_' . $oldColumnName . '_seq'; |
|
414 |
|
415 $sql[] = "CREATE SEQUENCE " . $seqName; |
|
416 $sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ") FROM " . $diff->name . "))"; |
|
417 $query = "ALTER " . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')"; |
|
418 $sql[] = "ALTER TABLE " . $diff->name . " " . $query; |
|
419 } else { |
|
420 // Drop autoincrement, but do NOT drop the sequence. It might be re-used by other tables or have |
|
421 $query = "ALTER " . $oldColumnName . " " . "DROP DEFAULT"; |
|
422 $sql[] = "ALTER TABLE " . $diff->name . " " . $query; |
|
423 } |
|
424 } |
|
425 if ($columnDiff->hasChanged('comment') && $comment = $this->getColumnComment($column)) { |
|
426 $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment); |
|
427 } |
|
428 } |
|
429 |
|
430 foreach ($diff->renamedColumns as $oldColumnName => $column) { |
|
431 $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME COLUMN ' . $oldColumnName . ' TO ' . $column->getQuotedName($this); |
|
432 } |
|
433 |
|
434 if ($diff->newName !== false) { |
|
435 $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME TO ' . $diff->newName; |
|
436 } |
|
437 |
|
438 return array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff), $commentsSQL); |
|
439 } |
|
440 |
|
441 /** |
|
442 * Gets the SQL to create a sequence on this platform. |
|
443 * |
|
444 * @param \Doctrine\DBAL\Schema\Sequence $sequence |
|
445 * @return string |
|
446 */ |
|
447 public function getCreateSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence) |
|
448 { |
|
449 return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) . |
|
450 ' INCREMENT BY ' . $sequence->getAllocationSize() . |
|
451 ' MINVALUE ' . $sequence->getInitialValue() . |
|
452 ' START ' . $sequence->getInitialValue(); |
|
453 } |
|
454 |
|
455 public function getAlterSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence) |
|
456 { |
|
457 return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) . |
|
458 ' INCREMENT BY ' . $sequence->getAllocationSize(); |
|
459 } |
|
460 |
|
461 /** |
|
462 * Drop existing sequence |
|
463 * @param \Doctrine\DBAL\Schema\Sequence $sequence |
|
464 * @return string |
|
465 */ |
|
466 public function getDropSequenceSQL($sequence) |
|
467 { |
|
468 if ($sequence instanceof \Doctrine\DBAL\Schema\Sequence) { |
|
469 $sequence = $sequence->getQuotedName($this); |
|
470 } |
|
471 return 'DROP SEQUENCE ' . $sequence; |
|
472 } |
|
473 |
|
474 /** |
|
475 * @param ForeignKeyConstraint|string $foreignKey |
|
476 * @param Table|string $table |
|
477 * @return string |
|
478 */ |
|
479 public function getDropForeignKeySQL($foreignKey, $table) |
|
480 { |
|
481 return $this->getDropConstraintSQL($foreignKey, $table); |
|
482 } |
|
483 |
|
484 /** |
|
485 * Gets the SQL used to create a table. |
|
486 * |
|
487 * @param unknown_type $tableName |
|
488 * @param array $columns |
|
489 * @param array $options |
|
490 * @return unknown |
|
491 */ |
|
492 protected function _getCreateTableSQL($tableName, array $columns, array $options = array()) |
|
493 { |
|
494 $queryFields = $this->getColumnDeclarationListSQL($columns); |
|
495 |
|
496 if (isset($options['primary']) && ! empty($options['primary'])) { |
|
497 $keyColumns = array_unique(array_values($options['primary'])); |
|
498 $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; |
|
499 } |
|
500 |
|
501 $query = 'CREATE TABLE ' . $tableName . ' (' . $queryFields . ')'; |
|
502 |
|
503 $sql[] = $query; |
|
504 |
|
505 if (isset($options['indexes']) && ! empty($options['indexes'])) { |
|
506 foreach ($options['indexes'] AS $index) { |
|
507 $sql[] = $this->getCreateIndexSQL($index, $tableName); |
|
508 } |
|
509 } |
|
510 |
|
511 if (isset($options['foreignKeys'])) { |
|
512 foreach ((array) $options['foreignKeys'] as $definition) { |
|
513 $sql[] = $this->getCreateForeignKeySQL($definition, $tableName); |
|
514 } |
|
515 } |
|
516 |
|
517 return $sql; |
|
518 } |
|
519 |
|
520 /** |
|
521 * Postgres wants boolean values converted to the strings 'true'/'false'. |
|
522 * |
|
523 * @param array $item |
|
524 * @override |
|
525 */ |
|
526 public function convertBooleans($item) |
|
527 { |
|
528 if (is_array($item)) { |
|
529 foreach ($item as $key => $value) { |
|
530 if (is_bool($value) || is_numeric($item)) { |
|
531 $item[$key] = ($value) ? 'true' : 'false'; |
|
532 } |
|
533 } |
|
534 } else { |
|
535 if (is_bool($item) || is_numeric($item)) { |
|
536 $item = ($item) ? 'true' : 'false'; |
|
537 } |
|
538 } |
|
539 return $item; |
|
540 } |
|
541 |
|
542 public function getSequenceNextValSQL($sequenceName) |
|
543 { |
|
544 return "SELECT NEXTVAL('" . $sequenceName . "')"; |
|
545 } |
|
546 |
|
547 public function getSetTransactionIsolationSQL($level) |
|
548 { |
|
549 return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ' |
|
550 . $this->_getTransactionIsolationLevelSQL($level); |
|
551 } |
|
552 |
|
553 /** |
|
554 * @override |
|
555 */ |
|
556 public function getBooleanTypeDeclarationSQL(array $field) |
|
557 { |
|
558 return 'BOOLEAN'; |
|
559 } |
|
560 |
|
561 /** |
|
562 * @override |
|
563 */ |
|
564 public function getIntegerTypeDeclarationSQL(array $field) |
|
565 { |
|
566 if ( ! empty($field['autoincrement'])) { |
|
567 return 'SERIAL'; |
|
568 } |
|
569 |
|
570 return 'INT'; |
|
571 } |
|
572 |
|
573 /** |
|
574 * @override |
|
575 */ |
|
576 public function getBigIntTypeDeclarationSQL(array $field) |
|
577 { |
|
578 if ( ! empty($field['autoincrement'])) { |
|
579 return 'BIGSERIAL'; |
|
580 } |
|
581 return 'BIGINT'; |
|
582 } |
|
583 |
|
584 /** |
|
585 * @override |
|
586 */ |
|
587 public function getSmallIntTypeDeclarationSQL(array $field) |
|
588 { |
|
589 return 'SMALLINT'; |
|
590 } |
|
591 |
|
592 /** |
|
593 * @override |
|
594 */ |
|
595 public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) |
|
596 { |
|
597 return 'TIMESTAMP(0) WITHOUT TIME ZONE'; |
|
598 } |
|
599 |
|
600 /** |
|
601 * @override |
|
602 */ |
|
603 public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration) |
|
604 { |
|
605 return 'TIMESTAMP(0) WITH TIME ZONE'; |
|
606 } |
|
607 |
|
608 /** |
|
609 * @override |
|
610 */ |
|
611 public function getDateTypeDeclarationSQL(array $fieldDeclaration) |
|
612 { |
|
613 return 'DATE'; |
|
614 } |
|
615 |
|
616 /** |
|
617 * @override |
|
618 */ |
|
619 public function getTimeTypeDeclarationSQL(array $fieldDeclaration) |
|
620 { |
|
621 return 'TIME(0) WITHOUT TIME ZONE'; |
|
622 } |
|
623 |
|
624 /** |
|
625 * @override |
|
626 */ |
|
627 protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) |
|
628 { |
|
629 return ''; |
|
630 } |
|
631 |
|
632 /** |
|
633 * Gets the SQL snippet used to declare a VARCHAR column on the MySql platform. |
|
634 * |
|
635 * @params array $field |
|
636 * @override |
|
637 */ |
|
638 protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) |
|
639 { |
|
640 return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') |
|
641 : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)'); |
|
642 } |
|
643 |
|
644 /** @override */ |
|
645 public function getClobTypeDeclarationSQL(array $field) |
|
646 { |
|
647 return 'TEXT'; |
|
648 } |
|
649 |
|
650 /** |
|
651 * Get the platform name for this instance |
|
652 * |
|
653 * @return string |
|
654 */ |
|
655 public function getName() |
|
656 { |
|
657 return 'postgresql'; |
|
658 } |
|
659 |
|
660 /** |
|
661 * Gets the character casing of a column in an SQL result set. |
|
662 * |
|
663 * PostgreSQL returns all column names in SQL result sets in lowercase. |
|
664 * |
|
665 * @param string $column The column name for which to get the correct character casing. |
|
666 * @return string The column name in the character casing used in SQL result sets. |
|
667 */ |
|
668 public function getSQLResultCasing($column) |
|
669 { |
|
670 return strtolower($column); |
|
671 } |
|
672 |
|
673 public function getDateTimeTzFormatString() |
|
674 { |
|
675 return 'Y-m-d H:i:sO'; |
|
676 } |
|
677 |
|
678 /** |
|
679 * Get the insert sql for an empty insert statement |
|
680 * |
|
681 * @param string $tableName |
|
682 * @param string $identifierColumnName |
|
683 * @return string $sql |
|
684 */ |
|
685 public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName) |
|
686 { |
|
687 return 'INSERT INTO ' . $quotedTableName . ' (' . $quotedIdentifierColumnName . ') VALUES (DEFAULT)'; |
|
688 } |
|
689 |
|
690 /** |
|
691 * @inheritdoc |
|
692 */ |
|
693 public function getTruncateTableSQL($tableName, $cascade = false) |
|
694 { |
|
695 return 'TRUNCATE '.$tableName.' '.(($cascade)?'CASCADE':''); |
|
696 } |
|
697 |
|
698 public function getReadLockSQL() |
|
699 { |
|
700 return 'FOR SHARE'; |
|
701 } |
|
702 |
|
703 protected function initializeDoctrineTypeMappings() |
|
704 { |
|
705 $this->doctrineTypeMapping = array( |
|
706 'smallint' => 'smallint', |
|
707 'int2' => 'smallint', |
|
708 'serial' => 'integer', |
|
709 'serial4' => 'integer', |
|
710 'int' => 'integer', |
|
711 'int4' => 'integer', |
|
712 'integer' => 'integer', |
|
713 'bigserial' => 'bigint', |
|
714 'serial8' => 'bigint', |
|
715 'bigint' => 'bigint', |
|
716 'int8' => 'bigint', |
|
717 'bool' => 'boolean', |
|
718 'boolean' => 'boolean', |
|
719 'text' => 'text', |
|
720 'varchar' => 'string', |
|
721 'interval' => 'string', |
|
722 '_varchar' => 'string', |
|
723 'char' => 'string', |
|
724 'bpchar' => 'string', |
|
725 'date' => 'date', |
|
726 'datetime' => 'datetime', |
|
727 'timestamp' => 'datetime', |
|
728 'timestamptz' => 'datetimetz', |
|
729 'time' => 'time', |
|
730 'timetz' => 'time', |
|
731 'float' => 'float', |
|
732 'float4' => 'float', |
|
733 'float8' => 'float', |
|
734 'double' => 'float', |
|
735 'double precision' => 'float', |
|
736 'real' => 'float', |
|
737 'decimal' => 'decimal', |
|
738 'money' => 'decimal', |
|
739 'numeric' => 'decimal', |
|
740 'year' => 'date', |
|
741 ); |
|
742 } |
|
743 |
|
744 public function getVarcharMaxLength() |
|
745 { |
|
746 return 65535; |
|
747 } |
|
748 |
|
749 protected function getReservedKeywordsClass() |
|
750 { |
|
751 return 'Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords'; |
|
752 } |
|
753 } |