alecpl
2008-05-02 d1403fd7268ccf96ab6e7d04506ea1b1802c7eb2
program/lib/MDB2/Driver/pgsql.php
@@ -3,7 +3,7 @@
// +----------------------------------------------------------------------+
// | PHP versions 4 and 5                                                 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox,                 |
// | Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox,                 |
// | Stig. S. Bakken, Lukas Smith                                         |
// | All rights reserved.                                                 |
// +----------------------------------------------------------------------+
@@ -43,7 +43,7 @@
// | Author: Paul Cooper <pgc@ucecom.com>                                 |
// +----------------------------------------------------------------------+
//
// $Id: pgsql.php,v 1.186 2007/11/10 13:27:03 quipo Exp $
// $Id: pgsql.php,v 1.197 2008/03/08 14:18:39 quipo Exp $
/**
 * MDB2 PostGreSQL driver
@@ -83,6 +83,7 @@
        $this->supported['LOBs'] = true;
        $this->supported['replace'] = 'emulated';
        $this->supported['sub_selects'] = true;
        $this->supported['triggers'] = true;
        $this->supported['auto_increment'] = 'emulated';
        $this->supported['primary_key'] = true;
        $this->supported['result_introspection'] = true;
@@ -91,8 +92,11 @@
        $this->supported['pattern_escaping'] = true;
        $this->supported['new_link'] = true;
        $this->options['DBA_username'] = false;
        $this->options['DBA_password'] = false;
        $this->options['multi_query'] = false;
        $this->options['disable_smart_seqname'] = false;
        $this->options['max_identifiers_length'] = 63;
    }
    // }}}
@@ -119,6 +123,8 @@
                $native_msg = 'Database connection has been lost.';
                $error_code = MDB2_ERROR_CONNECT_FAILED;
            }
        } else {
            $native_msg = @pg_last_error();
        }
        static $error_regexps;
@@ -128,8 +134,12 @@
                    => MDB2_ERROR_NOSUCHFIELD,
                '/(relation|sequence|table).*does not exist|class .* not found/i'
                    => MDB2_ERROR_NOSUCHTABLE,
                '/database .* does not exist/'
                    => MDB2_ERROR_NOT_FOUND,
                '/index .* does not exist/'
                    => MDB2_ERROR_NOT_FOUND,
                '/database .* already exists/i'
                    => MDB2_ERROR_ALREADY_EXISTS,
                '/relation .* already exists/i'
                    => MDB2_ERROR_ALREADY_EXISTS,
                '/(divide|division) by zero$/i'
@@ -202,7 +212,7 @@
        if (PEAR::isError($connection)) {
            return $connection;
        }
        if (version_compare(PHP_VERSION, '5.2.0RC5', '>=')) {
        if (is_resource($connection) && version_compare(PHP_VERSION, '5.2.0RC5', '>=')) {
            $text = @pg_escape_string($connection, $text);
        } else {
            $text = @pg_escape_string($text);
@@ -353,13 +363,18 @@
    // {{{ _doConnect()
    /**
     * Does the grunt work of connecting to the database
     * Do the grunt work of connecting to the database
     *
     * @return mixed connection resource on success, MDB2 Error Object on failure
     * @access protected
     **/
    function _doConnect($database_name, $persistent = false)
     */
    function _doConnect($username, $password, $database_name, $persistent = false)
    {
        if (!PEAR::loadExtension($this->phptype)) {
            return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
                'extension '.$this->phptype.' is not compiled into PHP', __FUNCTION__);
        }
        if ($database_name == '') {
            $database_name = 'template1';
        }
@@ -386,11 +401,11 @@
        if ($database_name) {
            $params[0].= ' dbname=\'' . addslashes($database_name) . '\'';
        }
        if ($this->dsn['username']) {
            $params[0].= ' user=\'' . addslashes($this->dsn['username']) . '\'';
        if ($username) {
            $params[0].= ' user=\'' . addslashes($username) . '\'';
        }
        if ($this->dsn['password']) {
            $params[0].= ' password=\'' . addslashes($this->dsn['password']) . '\'';
        if ($password) {
            $params[0].= ' password=\'' . addslashes($password) . '\'';
        }
        if (!empty($this->dsn['options'])) {
            $params[0].= ' options=' . $this->dsn['options'];
@@ -417,7 +432,6 @@
        }
        $connect_function = $persistent ? 'pg_pconnect' : 'pg_connect';
        $connection = @call_user_func_array($connect_function, $params);
        if (!$connection) {
            return $this->raiseError(MDB2_ERROR_CONNECT_FAILED, null, null,
@@ -449,7 +463,7 @@
     *
     * @return true on success, MDB2 Error Object on failure
     * @access public
     **/
     */
    function connect()
    {
        if (is_resource($this->connection)) {
@@ -463,22 +477,22 @@
            $this->disconnect(false);
        }
        if (!PEAR::loadExtension($this->phptype)) {
            return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
                'extension '.$this->phptype.' is not compiled into PHP', __FUNCTION__);
        }
        if ($this->database_name) {
            $connection = $this->_doConnect($this->database_name, $this->options['persistent']);
            $connection = $this->_doConnect($this->dsn['username'],
                                            $this->dsn['password'],
                                            $this->database_name,
                                            $this->options['persistent']);
            if (PEAR::isError($connection)) {
                return $connection;
            }
            $this->connection = $connection;
            $this->connected_dsn = $this->dsn;
            $this->connected_database_name = $this->database_name;
            $this->opened_persistent = $this->options['persistent'];
            $this->dbsyntax = $this->dsn['dbsyntax'] ? $this->dsn['dbsyntax'] : $this->phptype;
        }
        return MDB2_OK;
    }
@@ -501,13 +515,40 @@
                return $connection;
            }
        }
        if (is_array($charset)) {
            $charset   = array_shift($charset);
            $this->warnings[] = 'postgresql does not support setting client collation';
        }
        $result = @pg_set_client_encoding($connection, $charset);
        if ($result == -1) {
            return $this->raiseError(null, null, null,
                'Unable to set client charset: '.$charset, __FUNCTION__);
        }
        return MDB2_OK;
    }
    // }}}
    // {{{ databaseExists()
    /**
     * check if given database name is exists?
     *
     * @param string $name    name of the database that should be checked
     *
     * @return mixed true/false on success, a MDB2 error on failure
     * @access public
     */
    function databaseExists($name)
    {
        $res = $this->_doConnect($this->dsn['username'],
                                 $this->dsn['password'],
                                 $this->escape($name),
                                 $this->options['persistent']);
        if (!PEAR::isError($res)) {
            return true;
        }
        return false;
    }
    // }}}
@@ -560,11 +601,11 @@
     */
    function &standaloneQuery($query, $types = null, $is_manip = false)
    {
        $connection = $this->_doConnect('template1', false);
        $user = $this->options['DBA_username']? $this->options['DBA_username'] : $this->dsn['username'];
        $pass = $this->options['DBA_password']? $this->options['DBA_password'] : $this->dsn['password'];
        $connection = $this->_doConnect($user, $pass, $this->database_name, $this->options['persistent']);
        if (PEAR::isError($connection)) {
            $err =& $this->raiseError(MDB2_ERROR_CONNECT_FAILED, null, null,
                'Cannot connect to template1', __FUNCTION__);
            return $err;
            return $connection;
        }
        $offset = $this->offset;
@@ -572,17 +613,16 @@
        $this->offset = $this->limit = 0;
        $query = $this->_modifyQuery($query, $is_manip, $limit, $offset);
        $result =& $this->_doQuery($query, $is_manip, $connection, false);
        @pg_close($connection);
        if (PEAR::isError($result)) {
            return $result;
        $result =& $this->_doQuery($query, $is_manip, $connection, $this->database_name);
        if (!PEAR::isError($result)) {
            if ($is_manip) {
                $result =  $this->_affectedRows($connection, $result);
            } else {
                $result =& $this->_wrapResult($result, $types, true, false, $limit, $offset);
            }
        }
        if ($is_manip) {
            $affected_rows =  $this->_affectedRows($connection, $result);
            return $affected_rows;
        }
        $result =& $this->_wrapResult($result, $types, true, false, $limit, $offset);
        @pg_close($connection);
        return $result;
    }
@@ -910,8 +950,8 @@
            return $connection;
        }
        static $prep_statement_counter = 1;
        $statement_name = sprintf($this->options['statement_format'], $this->phptype, sha1(microtime() + mt_rand())) . $prep_statement_counter++;
        $statement_name = strtolower($statement_name);
        $statement_name = sprintf($this->options['statement_format'], $this->phptype, $prep_statement_counter++ . sha1(microtime() + mt_rand()));
        $statement_name = substr(strtolower($statement_name), 0, $this->options['max_identifiers_length']);
        if ($pgtypes === false) {
            $result = @pg_prepare($connection, $statement_name, $query);
            if (!$result) {
@@ -975,7 +1015,7 @@
                          WHERE d.adrelid = a.attrelid
                            AND d.adnum = a.attnum
                            AND a.atthasdef
                        ) FROM 'nextval[^\']*\'([^\']*)')
                        ) FROM 'nextval[^'']*''([^'']*)')
                        FROM pg_attribute a
                    LEFT JOIN pg_class c ON c.oid = a.attrelid
                    LEFT JOIN pg_attrdef d ON d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef
@@ -1017,9 +1057,11 @@
    {
        $sequence_name = $this->quoteIdentifier($this->getSequenceName($seq_name), true);
        $query = "SELECT NEXTVAL('$sequence_name')";
        $this->pushErrorHandling(PEAR_ERROR_RETURN);
        $this->expectError(MDB2_ERROR_NOSUCHTABLE);
        $result = $this->queryOne($query, 'integer');
        $this->popExpect();
        $this->popErrorHandling();
        if (PEAR::isError($result)) {
            if ($ondemand && $result->getCode() == MDB2_ERROR_NOSUCHTABLE) {
                $this->loadModule('Manager', null, true);
@@ -1052,7 +1094,7 @@
            return $this->queryOne('SELECT lastval()', 'integer');
        }
        $seq = $table.(empty($field) ? '' : '_'.$field);
        $sequence_name = $this->getSequenceName($seq);
        $sequence_name = $this->quoteIdentifier($this->getSequenceName($seq), true);
        return $this->queryOne("SELECT currval('$sequence_name')", 'integer');
    }