* @package Mammut\DB\Dialect */ class Postgresql extends Sql92 implements iDialect { /** * * @var resource \PDO */ protected $con = null; public function __construct($connection = null) { $this->con = $connection; } public function getName() { return DB::DIALECT_PGSQL; } public function isOffsetSupported() { return true; } public function isConstraintNameGlobal() { return true; } protected static function genNumSequence($table, $column) { $seqName = strtolower($table) . '_' . strtolower($column) . '_seq'; $preSQL = 'CREATE SEQUENCE "' . $seqName . '"'; $postSQL = 'ALTER SEQUENCE "' . $seqName . '" OWNED BY "' . $table . '"."' . $column . '"'; $result = array('name' => $seqName,'pre' => $preSQL,'post' => $postSQL); return $result; } public function getDdl() { if(!is_null($this->ddlInstance)) return $this->ddlInstance; $this->ddlInstance = new \Mammut\DB\Sql\Dialect\Ddl\PostgresqlDdl($this->con); return $this->ddlInstance; } public function quoteValue($value) { if(is_int($value)) return $value; if(is_null($value)) return 'NULL'; if(is_resource($this->con)) return '\'' . pg_escape_string($this->con, $value) . '\''; if($this->con instanceof \PDO) return $this->con->quote($value); return '\'' . addcslashes($value, "\x00\n\r\\'\"\x1a") . '\''; } public function quoteIdentInFragment($identifier, array $safeWords = array()) { $parts = preg_split('#([^0-9,a-z,A-Z$_])#', $identifier, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); if ($safeWords) { $safeWords = array_flip($safeWords); $safeWords = array_change_key_case($safeWords, CASE_LOWER); } foreach ($parts as $i => $part) { if ($safeWords && isset($safeWords[strtolower($part)])) { continue; } switch ($part) { case ' ': case '.': case '*': case 'AS': case 'As': case 'aS': case 'as': break; default: $parts[$i] = '"' . str_replace('"', '""', $part) . '"'; } } return implode('', $parts); } public function escapeString($string) { if(is_int($value)) return $value; if(is_null($value)) return 'NULL'; if(is_resource($this->con)) return pg_escape_string($this->con, $value); if($this->con instanceof \PDO) { $st = $this->con->quote($string); return substr($st, 1, -1); } return addcslashes($value, "\x00\n\r\\'\"\x1a"); } public function getSymbol($type) { switch($type) { case self::SYMB_QUOTE_VALUE: return '\''; case self::SYMB_QUOTE_IDENT: return '"'; case self::SYMB_IDENT_SEP: return '.'; } return false; } public function getExpressionSQL($param, $hint = NULL) { if (is_bool($param)) return $param ? 'TRUE' : 'FALSE'; return parent::getExpressionSQL($param, $hint); } public function getTruncateSQL($table) { $table = $this->quoteIdent($table); return "TRUNCATE TABLE {$table}"; } public function getNativeType($type) { switch($type) { case Types::TYPE_BOOLEAN: return 'BOOLEAN'; case Types::TYPE_TINY: return 'SMALLINT'; // pgsql has no tinyint type case Types::TYPE_SHORT: return 'SMALLINT'; case Types::TYPE_INT: return 'INTEGER'; case Types::TYPE_LONG: return 'BIGINT'; case Types::TYPE_FLOAT: return 'REAL'; case Types::TYPE_DOUBLE: return 'DOUBLE PRECISION'; case Types::TYPE_DECIMAL: return 'DECIMAL'; case Types::TYPE_CHAR: return 'CHAR'; case Types::TYPE_VCHAR: return 'VARCHAR'; case Types::TYPE_TEXT: return 'TEXT'; case Types::TYPE_BINARY: return 'BYTEA'; case Types::TYPE_BLOB: return 'BYTEA'; case Types::TYPE_DATE: return 'DATE'; case Types::TYPE_DATETIME: return 'TIMESTAMP'; case Types::TYPE_UTS: return 'INT'; case Types::TYPE_ENUM: throw new ImplementationException('ENUM not implemented'); } return $type; } }