123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- <?php
- define('POSTGRESQL_NEXTID_LOCK', 1000);
- class DatabaseConnection_pgsql extends DatabaseConnection {
- public function __construct(array $connection_options = array()) {
-
- $this->transactionSupport = !isset($connection_options['transactions']) || ($connection_options['transactions'] !== FALSE);
-
-
- $this->transactionalDDLSupport = $this->transactionSupport;
-
- if (empty($connection_options['port'])) {
- $connection_options['port'] = 5432;
- }
-
- if (empty($connection_options['password'])) {
- $connection_options['password'] = NULL;
- }
-
-
-
-
-
-
- else {
- $connection_options['password'] = str_replace('\\', '\\\\', $connection_options['password']);
- }
- $this->connectionOptions = $connection_options;
- $dsn = 'pgsql:host=' . $connection_options['host'] . ' dbname=' . $connection_options['database'] . ' port=' . $connection_options['port'];
-
- $connection_options += array(
- 'pdo' => array(),
- );
- $connection_options['pdo'] += array(
-
-
-
-
-
-
- PDO::ATTR_EMULATE_PREPARES => TRUE,
-
- PDO::ATTR_STRINGIFY_FETCHES => TRUE,
- );
- parent::__construct($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
-
- $this->exec("SET NAMES 'UTF8'");
-
- if (isset($connection_options['init_commands'])) {
- $this->exec(implode('; ', $connection_options['init_commands']));
- }
- }
- public function prepareQuery($query) {
-
-
-
-
-
-
-
- return parent::prepareQuery(preg_replace('/ ([^ ]+) +(I*LIKE|NOT +I*LIKE) /i', ' ${1}::text ${2} ', $query));
- }
- public function query($query, array $args = array(), $options = array()) {
- $options += $this->defaultOptions();
-
-
-
-
-
- foreach ($args as &$value) {
- if (is_bool($value)) {
- $value = (int) $value;
- }
- }
- try {
- if ($query instanceof DatabaseStatementInterface) {
- $stmt = $query;
- $stmt->execute(NULL, $options);
- }
- else {
- $this->expandArguments($query, $args);
- $stmt = $this->prepareQuery($query);
- $stmt->execute($args, $options);
- }
- switch ($options['return']) {
- case Database::RETURN_STATEMENT:
- return $stmt;
- case Database::RETURN_AFFECTED:
- return $stmt->rowCount();
- case Database::RETURN_INSERT_ID:
- return $this->lastInsertId($options['sequence_name']);
- case Database::RETURN_NULL:
- return;
- default:
- throw new PDOException('Invalid return directive: ' . $options['return']);
- }
- }
- catch (PDOException $e) {
- if ($options['throw_exception']) {
-
- if ($query instanceof DatabaseStatementInterface) {
- $e->query_string = $stmt->getQueryString();
- }
- else {
- $e->query_string = $query;
- }
- $e->args = $args;
- throw $e;
- }
- return NULL;
- }
- }
- public function queryRange($query, $from, $count, array $args = array(), array $options = array()) {
- return $this->query($query . ' LIMIT ' . (int) $count . ' OFFSET ' . (int) $from, $args, $options);
- }
- public function queryTemporary($query, array $args = array(), array $options = array()) {
- $tablename = $this->generateTemporaryTableName();
- $this->query('CREATE TEMPORARY TABLE {' . $tablename . '} AS ' . $query, $args, $options);
- return $tablename;
- }
- public function driver() {
- return 'pgsql';
- }
- public function databaseType() {
- return 'pgsql';
- }
- public function mapConditionOperator($operator) {
- static $specials;
-
- if (!isset($specials)) {
- $specials = array(
-
-
- 'LIKE' => array('operator' => 'ILIKE'),
- 'NOT LIKE' => array('operator' => 'NOT ILIKE'),
- );
- }
- return isset($specials[$operator]) ? $specials[$operator] : NULL;
- }
-
- public function nextId($existing = 0) {
-
-
- $sequence_name = $this->makeSequenceName('sequences', 'value');
-
-
- $id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField();
- if ($id > $existing) {
- return $id;
- }
-
-
-
- $this->query("SELECT pg_advisory_lock(" . POSTGRESQL_NEXTID_LOCK . ")");
-
-
- $id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField();
- if ($id > $existing) {
- $this->query("SELECT pg_advisory_unlock(" . POSTGRESQL_NEXTID_LOCK . ")");
- return $id;
- }
-
- $this->query("ALTER SEQUENCE " . $sequence_name . " RESTART WITH " . ($existing + 1));
-
- $id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField();
- $this->query("SELECT pg_advisory_unlock(" . POSTGRESQL_NEXTID_LOCK . ")");
- return $id;
- }
- public function utf8mb4IsActive() {
- return TRUE;
- }
- public function utf8mb4IsSupported() {
- return TRUE;
- }
- }
|