You are here

class DB_pgsql in Flickr API 5

The methods PEAR DB uses to interact with PHP's pgsql extension for interacting with PostgreSQL databases

These methods overload the ones declared in DB_common.

@category Database @package DB @author Rui Hirokawa <hirokawa@php.net> @author Stig Bakken <ssb@php.net> @author Daniel Convissor <danielc@php.net> @copyright 1997-2005 The PHP Group @license http://www.php.net/license/3_0.txt PHP License 3.0 @version Release: @package_version@ @link http://pear.php.net/package/DB

Hierarchy

Expanded class hierarchy of DB_pgsql

File

phpFlickr/PEAR/DB/pgsql.php, line 48

View source
class DB_pgsql extends DB_common {

  // {{{ properties

  /**
   * The DB driver type (mysql, oci8, odbc, etc.)
   * @var string
   */
  var $phptype = 'pgsql';

  /**
   * The database syntax variant to be used (db2, access, etc.), if any
   * @var string
   */
  var $dbsyntax = 'pgsql';

  /**
   * The capabilities of this DB implementation
   *
   * The 'new_link' element contains the PHP version that first provided
   * new_link support for this DBMS.  Contains false if it's unsupported.
   *
   * Meaning of the 'limit' element:
   *   + 'emulate' = emulate with fetch row by number
   *   + 'alter'   = alter the query
   *   + false     = skip rows
   *
   * @var array
   */
  var $features = array(
    'limit' => 'alter',
    'new_link' => '4.3.0',
    'numrows' => true,
    'pconnect' => true,
    'prepare' => false,
    'ssl' => true,
    'transactions' => true,
  );

  /**
   * A mapping of native error codes to DB error codes
   * @var array
   */
  var $errorcode_map = array();

  /**
   * The raw database connection created by PHP
   * @var resource
   */
  var $connection;

  /**
   * The DSN information for connecting to a database
   * @var array
   */
  var $dsn = array();

  /**
   * Should data manipulation queries be committed automatically?
   * @var bool
   * @access private
   */
  var $autocommit = true;

  /**
   * The quantity of transactions begun
   *
   * {@internal  While this is private, it can't actually be designated
   * private in PHP 5 because it is directly accessed in the test suite.}}
   *
   * @var integer
   * @access private
   */
  var $transaction_opcount = 0;

  /**
   * The number of rows affected by a data manipulation query
   * @var integer
   */
  var $affected = 0;

  /**
   * The current row being looked at in fetchInto()
   * @var array
   * @access private
   */
  var $row = array();

  /**
   * The number of rows in a given result set
   * @var array
   * @access private
   */
  var $_num_rows = array();

  // }}}
  // {{{ constructor

  /**
   * This constructor calls <kbd>$this->DB_common()</kbd>
   *
   * @return void
   */
  function DB_pgsql() {
    $this
      ->DB_common();
  }

  // }}}
  // {{{ connect()

  /**
   * Connect to the database server, log in and open the database
   *
   * Don't call this method directly.  Use DB::connect() instead.
   *
   * PEAR DB's pgsql driver supports the following extra DSN options:
   *   + connect_timeout  How many seconds to wait for a connection to
   *                       be established.  Available since PEAR DB 1.7.0.
   *   + new_link         If set to true, causes subsequent calls to
   *                       connect() to return a new connection link
   *                       instead of the existing one.  WARNING: this is
   *                       not portable to other DBMS's.  Available only
   *                       if PHP is >= 4.3.0 and PEAR DB is >= 1.7.0.
   *   + options          Command line options to be sent to the server.
   *                       Available since PEAR DB 1.6.4.
   *   + service          Specifies a service name in pg_service.conf that
   *                       holds additional connection parameters.
   *                       Available since PEAR DB 1.7.0.
   *   + sslmode          How should SSL be used when connecting?  Values:
   *                       disable, allow, prefer or require.
   *                       Available since PEAR DB 1.7.0.
   *   + tty              This was used to specify where to send server
   *                       debug output.  Available since PEAR DB 1.6.4.
   *
   * Example of connecting to a new link via a socket:
   * <code>
   * require_once 'DB.php';
   *
   * $dsn = 'pgsql://user:pass@unix(/tmp)/dbname?new_link=true';
   * $options = array(
   *     'portability' => DB_PORTABILITY_ALL,
   * );
   *
   * $db =& DB::connect($dsn, $options);
   * if (PEAR::isError($db)) {
   *     die($db->getMessage());
   * }
   * </code>
   *
   * @param array $dsn         the data source name
   * @param bool  $persistent  should the connection be persistent?
   *
   * @return int  DB_OK on success. A DB_Error object on failure.
   *
   * @link http://www.postgresql.org/docs/current/static/libpq.html#LIBPQ-CONNECT
   */
  function connect($dsn, $persistent = false) {
    if (!PEAR::loadExtension('pgsql')) {
      return $this
        ->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
    }
    $this->dsn = $dsn;
    if ($dsn['dbsyntax']) {
      $this->dbsyntax = $dsn['dbsyntax'];
    }
    $protocol = $dsn['protocol'] ? $dsn['protocol'] : 'tcp';
    $params = array(
      '',
    );
    if ($protocol == 'tcp') {
      if ($dsn['hostspec']) {
        $params[0] .= 'host=' . $dsn['hostspec'];
      }
      if ($dsn['port']) {
        $params[0] .= ' port=' . $dsn['port'];
      }
    }
    elseif ($protocol == 'unix') {

      // Allow for pg socket in non-standard locations.
      if ($dsn['socket']) {
        $params[0] .= 'host=' . $dsn['socket'];
      }
      if ($dsn['port']) {
        $params[0] .= ' port=' . $dsn['port'];
      }
    }
    if ($dsn['database']) {
      $params[0] .= ' dbname=\'' . addslashes($dsn['database']) . '\'';
    }
    if ($dsn['username']) {
      $params[0] .= ' user=\'' . addslashes($dsn['username']) . '\'';
    }
    if ($dsn['password']) {
      $params[0] .= ' password=\'' . addslashes($dsn['password']) . '\'';
    }
    if (!empty($dsn['options'])) {
      $params[0] .= ' options=' . $dsn['options'];
    }
    if (!empty($dsn['tty'])) {
      $params[0] .= ' tty=' . $dsn['tty'];
    }
    if (!empty($dsn['connect_timeout'])) {
      $params[0] .= ' connect_timeout=' . $dsn['connect_timeout'];
    }
    if (!empty($dsn['sslmode'])) {
      $params[0] .= ' sslmode=' . $dsn['sslmode'];
    }
    if (!empty($dsn['service'])) {
      $params[0] .= ' service=' . $dsn['service'];
    }
    if (isset($dsn['new_link']) && ($dsn['new_link'] == 'true' || $dsn['new_link'] === true)) {
      if (version_compare(phpversion(), '4.3.0', '>=')) {
        $params[] = PGSQL_CONNECT_FORCE_NEW;
      }
    }
    $connect_function = $persistent ? 'pg_pconnect' : 'pg_connect';
    $ini = ini_get('track_errors');
    $php_errormsg = '';
    if ($ini) {
      $this->connection = @call_user_func_array($connect_function, $params);
    }
    else {
      ini_set('track_errors', 1);
      $this->connection = @call_user_func_array($connect_function, $params);
      ini_set('track_errors', $ini);
    }
    if (!$this->connection) {
      return $this
        ->raiseError(DB_ERROR_CONNECT_FAILED, null, null, null, $php_errormsg);
    }
    return DB_OK;
  }

  // }}}
  // {{{ disconnect()

  /**
   * Disconnects from the database server
   *
   * @return bool  TRUE on success, FALSE on failure
   */
  function disconnect() {
    $ret = @pg_close($this->connection);
    $this->connection = null;
    return $ret;
  }

  // }}}
  // {{{ simpleQuery()

  /**
   * Sends a query to the database server
   *
   * @param string  the SQL query string
   *
   * @return mixed  + a PHP result resrouce for successful SELECT queries
   *                + the DB_OK constant for other successful queries
   *                + a DB_Error object on failure
   */
  function simpleQuery($query) {
    $ismanip = DB::isManip($query);
    $this->last_query = $query;
    $query = $this
      ->modifyQuery($query);
    if (!$this->autocommit && $ismanip) {
      if ($this->transaction_opcount == 0) {
        $result = @pg_exec($this->connection, 'begin;');
        if (!$result) {
          return $this
            ->pgsqlRaiseError();
        }
      }
      $this->transaction_opcount++;
    }
    $result = @pg_exec($this->connection, $query);
    if (!$result) {
      return $this
        ->pgsqlRaiseError();
    }

    // Determine which queries that should return data, and which
    // should return an error code only.
    if ($ismanip) {
      $this->affected = @pg_affected_rows($result);
      return DB_OK;
    }
    elseif (preg_match('/^\\s*\\(*\\s*(SELECT|EXPLAIN|SHOW)\\s/si', $query)) {

      /* PostgreSQL commands:
            ABORT, ALTER, BEGIN, CLOSE, CLUSTER, COMMIT, COPY,
            CREATE, DECLARE, DELETE, DROP TABLE, EXPLAIN, FETCH,
            GRANT, INSERT, LISTEN, LOAD, LOCK, MOVE, NOTIFY, RESET,
            REVOKE, ROLLBACK, SELECT, SELECT INTO, SET, SHOW,
            UNLISTEN, UPDATE, VACUUM
         */
      $this->row[(int) $result] = 0;

      // reset the row counter.
      $numrows = $this
        ->numRows($result);
      if (is_object($numrows)) {
        return $numrows;
      }
      $this->_num_rows[(int) $result] = $numrows;
      $this->affected = 0;
      return $result;
    }
    else {
      $this->affected = 0;
      return DB_OK;
    }
  }

  // }}}
  // {{{ nextResult()

  /**
   * Move the internal pgsql result pointer to the next available result
   *
   * @param a valid fbsql result resource
   *
   * @access public
   *
   * @return true if a result is available otherwise return false
   */
  function nextResult($result) {
    return false;
  }

  // }}}
  // {{{ fetchInto()

  /**
   * Places a row from the result set into the given array
   *
   * Formating of the array and the data therein are configurable.
   * See DB_result::fetchInto() for more information.
   *
   * This method is not meant to be called directly.  Use
   * DB_result::fetchInto() instead.  It can't be declared "protected"
   * because DB_result is a separate object.
   *
   * @param resource $result    the query result resource
   * @param array    $arr       the referenced array to put the data in
   * @param int      $fetchmode how the resulting array should be indexed
   * @param int      $rownum    the row number to fetch (0 = first row)
   *
   * @return mixed  DB_OK on success, NULL when the end of a result set is
   *                 reached or on failure
   *
   * @see DB_result::fetchInto()
   */
  function fetchInto($result, &$arr, $fetchmode, $rownum = null) {
    $result_int = (int) $result;
    $rownum = $rownum !== null ? $rownum : $this->row[$result_int];
    if ($rownum >= $this->_num_rows[$result_int]) {
      return null;
    }
    if ($fetchmode & DB_FETCHMODE_ASSOC) {
      $arr = @pg_fetch_array($result, $rownum, PGSQL_ASSOC);
      if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
        $arr = array_change_key_case($arr, CASE_LOWER);
      }
    }
    else {
      $arr = @pg_fetch_row($result, $rownum);
    }
    if (!$arr) {
      return null;
    }
    if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
      $this
        ->_rtrimArrayValues($arr);
    }
    if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
      $this
        ->_convertNullArrayValuesToEmpty($arr);
    }
    $this->row[$result_int] = ++$rownum;
    return DB_OK;
  }

  // }}}
  // {{{ freeResult()

  /**
   * Deletes the result set and frees the memory occupied by the result set
   *
   * This method is not meant to be called directly.  Use
   * DB_result::free() instead.  It can't be declared "protected"
   * because DB_result is a separate object.
   *
   * @param resource $result  PHP's query result resource
   *
   * @return bool  TRUE on success, FALSE if $result is invalid
   *
   * @see DB_result::free()
   */
  function freeResult($result) {
    if (is_resource($result)) {
      unset($this->row[(int) $result]);
      unset($this->_num_rows[(int) $result]);
      $this->affected = 0;
      return @pg_freeresult($result);
    }
    return false;
  }

  // }}}
  // {{{ quote()

  /**
   * @deprecated  Deprecated in release 1.6.0
   * @internal
   */
  function quote($str) {
    return $this
      ->quoteSmart($str);
  }

  // }}}
  // {{{ quoteSmart()

  /**
   * Formats input so it can be safely used in a query
   *
   * @param mixed $in  the data to be formatted
   *
   * @return mixed  the formatted data.  The format depends on the input's
   *                 PHP type:
   *                 + null = the string <samp>NULL</samp>
   *                 + boolean = string <samp>TRUE</samp> or <samp>FALSE</samp>
   *                 + integer or double = the unquoted number
   *                 + other (including strings and numeric strings) =
   *                   the data escaped according to MySQL's settings
   *                   then encapsulated between single quotes
   *
   * @see DB_common::quoteSmart()
   * @since Method available since Release 1.6.0
   */
  function quoteSmart($in) {
    if (is_int($in) || is_double($in)) {
      return $in;
    }
    elseif (is_bool($in)) {
      return $in ? 'TRUE' : 'FALSE';
    }
    elseif (is_null($in)) {
      return 'NULL';
    }
    else {
      return "'" . $this
        ->escapeSimple($in) . "'";
    }
  }

  // }}}
  // {{{ escapeSimple()

  /**
   * Escapes a string according to the current DBMS's standards
   *
   * {@internal PostgreSQL treats a backslash as an escape character,
   * so they are escaped as well.
   *
   * Not using pg_escape_string() yet because it requires PostgreSQL
   * to be at version 7.2 or greater.}}
   *
   * @param string $str  the string to be escaped
   *
   * @return string  the escaped string
   *
   * @see DB_common::quoteSmart()
   * @since Method available since Release 1.6.0
   */
  function escapeSimple($str) {
    return str_replace("'", "''", str_replace('\\', '\\\\', $str));
  }

  // }}}
  // {{{ numCols()

  /**
   * Gets the number of columns in a result set
   *
   * This method is not meant to be called directly.  Use
   * DB_result::numCols() instead.  It can't be declared "protected"
   * because DB_result is a separate object.
   *
   * @param resource $result  PHP's query result resource
   *
   * @return int  the number of columns.  A DB_Error object on failure.
   *
   * @see DB_result::numCols()
   */
  function numCols($result) {
    $cols = @pg_numfields($result);
    if (!$cols) {
      return $this
        ->pgsqlRaiseError();
    }
    return $cols;
  }

  // }}}
  // {{{ numRows()

  /**
   * Gets the number of rows in a result set
   *
   * This method is not meant to be called directly.  Use
   * DB_result::numRows() instead.  It can't be declared "protected"
   * because DB_result is a separate object.
   *
   * @param resource $result  PHP's query result resource
   *
   * @return int  the number of rows.  A DB_Error object on failure.
   *
   * @see DB_result::numRows()
   */
  function numRows($result) {
    $rows = @pg_numrows($result);
    if ($rows === null) {
      return $this
        ->pgsqlRaiseError();
    }
    return $rows;
  }

  // }}}
  // {{{ autoCommit()

  /**
   * Enables or disables automatic commits
   *
   * @param bool $onoff  true turns it on, false turns it off
   *
   * @return int  DB_OK on success.  A DB_Error object if the driver
   *               doesn't support auto-committing transactions.
   */
  function autoCommit($onoff = false) {

    // XXX if $this->transaction_opcount > 0, we should probably
    // issue a warning here.
    $this->autocommit = $onoff ? true : false;
    return DB_OK;
  }

  // }}}
  // {{{ commit()

  /**
   * Commits the current transaction
   *
   * @return int  DB_OK on success.  A DB_Error object on failure.
   */
  function commit() {
    if ($this->transaction_opcount > 0) {

      // (disabled) hack to shut up error messages from libpq.a

      //@fclose(@fopen("php://stderr", "w"));
      $result = @pg_exec($this->connection, 'end;');
      $this->transaction_opcount = 0;
      if (!$result) {
        return $this
          ->pgsqlRaiseError();
      }
    }
    return DB_OK;
  }

  // }}}
  // {{{ rollback()

  /**
   * Reverts the current transaction
   *
   * @return int  DB_OK on success.  A DB_Error object on failure.
   */
  function rollback() {
    if ($this->transaction_opcount > 0) {
      $result = @pg_exec($this->connection, 'abort;');
      $this->transaction_opcount = 0;
      if (!$result) {
        return $this
          ->pgsqlRaiseError();
      }
    }
    return DB_OK;
  }

  // }}}
  // {{{ affectedRows()

  /**
   * Determines the number of rows affected by a data maniuplation query
   *
   * 0 is returned for queries that don't manipulate data.
   *
   * @return int  the number of rows.  A DB_Error object on failure.
   */
  function affectedRows() {
    return $this->affected;
  }

  // }}}
  // {{{ nextId()

  /**
   * Returns the next free id in a sequence
   *
   * @param string  $seq_name  name of the sequence
   * @param boolean $ondemand  when true, the seqence is automatically
   *                            created if it does not exist
   *
   * @return int  the next id number in the sequence.
   *               A DB_Error object on failure.
   *
   * @see DB_common::nextID(), DB_common::getSequenceName(),
   *      DB_pgsql::createSequence(), DB_pgsql::dropSequence()
   */
  function nextId($seq_name, $ondemand = true) {
    $seqname = $this
      ->getSequenceName($seq_name);
    $repeat = false;
    do {
      $this
        ->pushErrorHandling(PEAR_ERROR_RETURN);
      $result =& $this
        ->query("SELECT NEXTVAL('{$seqname}')");
      $this
        ->popErrorHandling();
      if ($ondemand && DB::isError($result) && $result
        ->getCode() == DB_ERROR_NOSUCHTABLE) {
        $repeat = true;
        $this
          ->pushErrorHandling(PEAR_ERROR_RETURN);
        $result = $this
          ->createSequence($seq_name);
        $this
          ->popErrorHandling();
        if (DB::isError($result)) {
          return $this
            ->raiseError($result);
        }
      }
      else {
        $repeat = false;
      }
    } while ($repeat);
    if (DB::isError($result)) {
      return $this
        ->raiseError($result);
    }
    $arr = $result
      ->fetchRow(DB_FETCHMODE_ORDERED);
    $result
      ->free();
    return $arr[0];
  }

  // }}}
  // {{{ createSequence()

  /**
   * Creates a new sequence
   *
   * @param string $seq_name  name of the new sequence
   *
   * @return int  DB_OK on success.  A DB_Error object on failure.
   *
   * @see DB_common::createSequence(), DB_common::getSequenceName(),
   *      DB_pgsql::nextID(), DB_pgsql::dropSequence()
   */
  function createSequence($seq_name) {
    $seqname = $this
      ->getSequenceName($seq_name);
    $result = $this
      ->query("CREATE SEQUENCE {$seqname}");
    return $result;
  }

  // }}}
  // {{{ dropSequence()

  /**
   * Deletes a sequence
   *
   * @param string $seq_name  name of the sequence to be deleted
   *
   * @return int  DB_OK on success.  A DB_Error object on failure.
   *
   * @see DB_common::dropSequence(), DB_common::getSequenceName(),
   *      DB_pgsql::nextID(), DB_pgsql::createSequence()
   */
  function dropSequence($seq_name) {
    return $this
      ->query('DROP SEQUENCE ' . $this
      ->getSequenceName($seq_name));
  }

  // }}}
  // {{{ modifyLimitQuery()

  /**
   * Adds LIMIT clauses to a query string according to current DBMS standards
   *
   * @param string $query   the query to modify
   * @param int    $from    the row to start to fetching (0 = the first row)
   * @param int    $count   the numbers of rows to fetch
   * @param mixed  $params  array, string or numeric data to be used in
   *                         execution of the statement.  Quantity of items
   *                         passed must match quantity of placeholders in
   *                         query:  meaning 1 placeholder for non-array
   *                         parameters or 1 placeholder per array element.
   *
   * @return string  the query string with LIMIT clauses added
   *
   * @access protected
   */
  function modifyLimitQuery($query, $from, $count, $params = array()) {
    return "{$query} LIMIT {$count} OFFSET {$from}";
  }

  // }}}
  // {{{ pgsqlRaiseError()

  /**
   * Produces a DB_Error object regarding the current problem
   *
   * @param int $errno  if the error is being manually raised pass a
   *                     DB_ERROR* constant here.  If this isn't passed
   *                     the error information gathered from the DBMS.
   *
   * @return object  the DB_Error object
   *
   * @see DB_common::raiseError(),
   *      DB_pgsql::errorNative(), DB_pgsql::errorCode()
   */
  function pgsqlRaiseError($errno = null) {
    $native = $this
      ->errorNative();
    if ($errno === null) {
      $errno = $this
        ->errorCode($native);
    }
    return $this
      ->raiseError($errno, null, null, null, $native);
  }

  // }}}
  // {{{ errorNative()

  /**
   * Gets the DBMS' native error message produced by the last query
   *
   * {@internal Error messages are used instead of error codes
   * in order to support older versions of PostgreSQL.}}
   *
   * @return string  the DBMS' error message
   */
  function errorNative() {
    return @pg_errormessage($this->connection);
  }

  // }}}
  // {{{ errorCode()

  /**
   * Determines PEAR::DB error code from the database's text error message.
   *
   * @param  string  $errormsg  error message returned from the database
   * @return integer  an error number from a DB error constant
   */
  function errorCode($errormsg) {
    static $error_regexps;
    if (!isset($error_regexps)) {
      $error_regexps = array(
        '/(relation|sequence|table).*does not exist|class .* not found/i' => DB_ERROR_NOSUCHTABLE,
        '/index .* does not exist/' => DB_ERROR_NOT_FOUND,
        '/column .* does not exist/i' => DB_ERROR_NOSUCHFIELD,
        '/relation .* already exists/i' => DB_ERROR_ALREADY_EXISTS,
        '/(divide|division) by zero$/i' => DB_ERROR_DIVZERO,
        '/pg_atoi: error in .*: can\'t parse /i' => DB_ERROR_INVALID_NUMBER,
        '/invalid input syntax for( type)? (integer|numeric)/i' => DB_ERROR_INVALID_NUMBER,
        '/value .* is out of range for type \\w*int/i' => DB_ERROR_INVALID_NUMBER,
        '/integer out of range/i' => DB_ERROR_INVALID_NUMBER,
        '/value too long for type character/i' => DB_ERROR_INVALID,
        '/attribute .* not found|relation .* does not have attribute/i' => DB_ERROR_NOSUCHFIELD,
        '/column .* specified in USING clause does not exist in (left|right) table/i' => DB_ERROR_NOSUCHFIELD,
        '/parser: parse error at or near/i' => DB_ERROR_SYNTAX,
        '/syntax error at/' => DB_ERROR_SYNTAX,
        '/column reference .* is ambiguous/i' => DB_ERROR_SYNTAX,
        '/permission denied/' => DB_ERROR_ACCESS_VIOLATION,
        '/violates not-null constraint/' => DB_ERROR_CONSTRAINT_NOT_NULL,
        '/violates [\\w ]+ constraint/' => DB_ERROR_CONSTRAINT,
        '/referential integrity violation/' => DB_ERROR_CONSTRAINT,
        '/more expressions than target columns/i' => DB_ERROR_VALUE_COUNT_ON_ROW,
      );
    }
    foreach ($error_regexps as $regexp => $code) {
      if (preg_match($regexp, $errormsg)) {
        return $code;
      }
    }

    // Fall back to DB_ERROR if there was no mapping.
    return DB_ERROR;
  }

  // }}}
  // {{{ tableInfo()

  /**
   * Returns information about a table or a result set
   *
   * NOTE: only supports 'table' and 'flags' if <var>$result</var>
   * is a table name.
   *
   * @param object|string  $result  DB_result object from a query or a
   *                                 string containing the name of a table.
   *                                 While this also accepts a query result
   *                                 resource identifier, this behavior is
   *                                 deprecated.
   * @param int            $mode    a valid tableInfo mode
   *
   * @return array  an associative array with the information requested.
   *                 A DB_Error object on failure.
   *
   * @see DB_common::tableInfo()
   */
  function tableInfo($result, $mode = null) {
    if (is_string($result)) {

      /*
       * Probably received a table name.
       * Create a result resource identifier.
       */
      $id = @pg_exec($this->connection, "SELECT * FROM {$result} LIMIT 0");
      $got_string = true;
    }
    elseif (isset($result->result)) {

      /*
       * Probably received a result object.
       * Extract the result resource identifier.
       */
      $id = $result->result;
      $got_string = false;
    }
    else {

      /*
       * Probably received a result resource identifier.
       * Copy it.
       * Deprecated.  Here for compatibility only.
       */
      $id = $result;
      $got_string = false;
    }
    if (!is_resource($id)) {
      return $this
        ->pgsqlRaiseError(DB_ERROR_NEED_MORE_DATA);
    }
    if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
      $case_func = 'strtolower';
    }
    else {
      $case_func = 'strval';
    }
    $count = @pg_numfields($id);
    $res = array();
    if ($mode) {
      $res['num_fields'] = $count;
    }
    for ($i = 0; $i < $count; $i++) {
      $res[$i] = array(
        'table' => $got_string ? $case_func($result) : '',
        'name' => $case_func(@pg_fieldname($id, $i)),
        'type' => @pg_fieldtype($id, $i),
        'len' => @pg_fieldsize($id, $i),
        'flags' => $got_string ? $this
          ->_pgFieldFlags($id, $i, $result) : '',
      );
      if ($mode & DB_TABLEINFO_ORDER) {
        $res['order'][$res[$i]['name']] = $i;
      }
      if ($mode & DB_TABLEINFO_ORDERTABLE) {
        $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
      }
    }

    // free the result only if we were called on a table
    if ($got_string) {
      @pg_freeresult($id);
    }
    return $res;
  }

  // }}}
  // {{{ _pgFieldFlags()

  /**
   * Get a column's flags
   *
   * Supports "not_null", "default_value", "primary_key", "unique_key"
   * and "multiple_key".  The default value is passed through
   * rawurlencode() in case there are spaces in it.
   *
   * @param int $resource   the PostgreSQL result identifier
   * @param int $num_field  the field number
   *
   * @return string  the flags
   *
   * @access private
   */
  function _pgFieldFlags($resource, $num_field, $table_name) {
    $field_name = @pg_fieldname($resource, $num_field);
    $result = @pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef\n                                FROM pg_attribute f, pg_class tab, pg_type typ\n                                WHERE tab.relname = typ.typname\n                                AND typ.typrelid = f.attrelid\n                                AND f.attname = '{$field_name}'\n                                AND tab.relname = '{$table_name}'");
    if (@pg_numrows($result) > 0) {
      $row = @pg_fetch_row($result, 0);
      $flags = $row[0] == 't' ? 'not_null ' : '';
      if ($row[1] == 't') {
        $result = @pg_exec($this->connection, "SELECT a.adsrc\n                                    FROM pg_attribute f, pg_class tab, pg_type typ, pg_attrdef a\n                                    WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid\n                                    AND f.attrelid = a.adrelid AND f.attname = '{$field_name}'\n                                    AND tab.relname = '{$table_name}' AND f.attnum = a.adnum");
        $row = @pg_fetch_row($result, 0);
        $num = preg_replace("/'(.*)'::\\w+/", "\\1", $row[0]);
        $flags .= 'default_' . rawurlencode($num) . ' ';
      }
    }
    else {
      $flags = '';
    }
    $result = @pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey\n                                FROM pg_attribute f, pg_class tab, pg_type typ, pg_index i\n                                WHERE tab.relname = typ.typname\n                                AND typ.typrelid = f.attrelid\n                                AND f.attrelid = i.indrelid\n                                AND f.attname = '{$field_name}'\n                                AND tab.relname = '{$table_name}'");
    $count = @pg_numrows($result);
    for ($i = 0; $i < $count; $i++) {
      $row = @pg_fetch_row($result, $i);
      $keys = explode(' ', $row[2]);
      if (in_array($num_field + 1, $keys)) {
        $flags .= $row[0] == 't' && $row[1] == 'f' ? 'unique_key ' : '';
        $flags .= $row[1] == 't' ? 'primary_key ' : '';
        if (count($keys) > 1) {
          $flags .= 'multiple_key ';
        }
      }
    }
    return trim($flags);
  }

  // }}}
  // {{{ getSpecialQuery()

  /**
   * Obtains the query string needed for listing a given type of objects
   *
   * @param string $type  the kind of objects you want to retrieve
   *
   * @return string  the SQL query string or null if the driver doesn't
   *                  support the object type requested
   *
   * @access protected
   * @see DB_common::getListOf()
   */
  function getSpecialQuery($type) {
    switch ($type) {
      case 'tables':
        return 'SELECT c.relname AS "Name"' . ' FROM pg_class c, pg_user u' . ' WHERE c.relowner = u.usesysid' . " AND c.relkind = 'r'" . ' AND NOT EXISTS' . ' (SELECT 1 FROM pg_views' . '  WHERE viewname = c.relname)' . " AND c.relname !~ '^(pg_|sql_)'" . ' UNION' . ' SELECT c.relname AS "Name"' . ' FROM pg_class c' . " WHERE c.relkind = 'r'" . ' AND NOT EXISTS' . ' (SELECT 1 FROM pg_views' . '  WHERE viewname = c.relname)' . ' AND NOT EXISTS' . ' (SELECT 1 FROM pg_user' . '  WHERE usesysid = c.relowner)' . " AND c.relname !~ '^pg_'";
      case 'schema.tables':
        return "SELECT schemaname || '.' || tablename" . ' AS "Name"' . ' FROM pg_catalog.pg_tables' . ' WHERE schemaname NOT IN' . " ('pg_catalog', 'information_schema', 'pg_toast')";
      case 'views':

        // Table cols: viewname | viewowner | definition
        return 'SELECT viewname from pg_views WHERE schemaname' . " NOT IN ('information_schema', 'pg_catalog')";
      case 'users':

        // cols: usename |usesysid|usecreatedb|usetrace|usesuper|usecatupd|passwd  |valuntil
        return 'SELECT usename FROM pg_user';
      case 'databases':
        return 'SELECT datname FROM pg_database';
      case 'functions':
      case 'procedures':
        return 'SELECT proname FROM pg_proc WHERE proowner <> 1';
      default:
        return null;
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DB_common::$fetchmode property The current default fetch mode
DB_common::$fetchmode_object_class property The name of the class into which results should be fetched when DB_FETCHMODE_OBJECT is in effect
DB_common::$last_parameters property The parameters from the most recently executed query @since Property available since Release 1.7.0
DB_common::$last_query property The most recently executed query
DB_common::$options property Run-time configuration options
DB_common::$prepared_queries property The prepared queries
DB_common::$prepare_tokens property The elements from each prepared statement
DB_common::$prepare_types property The data types of the various elements in each prepared statement
DB_common::$was_connected property Was a connection present when the object was serialized()?
DB_common::autoExecute function Automaticaly generates an insert or update query and call prepare() and execute() with it
DB_common::autoPrepare function Automaticaly generates an insert or update query and pass it to prepare()
DB_common::buildManipSQL function Produces an SQL query string for autoPrepare()
DB_common::DB_common function This constructor calls <kbd>$this->PEAR('DB_Error')</kbd>
DB_common::errorMessage function Maps a DB error code to a textual message
DB_common::execute function Executes a DB statement prepared with prepare()
DB_common::executeEmulateQuery function Emulates executing prepared statements if the DBMS not support them
DB_common::executeMultiple function Performs several execute() calls on the same statement handle
DB_common::freePrepared function Frees the internal resources associated with a prepared query
DB_common::getAll function Fetches all of the rows from a query result
DB_common::getAssoc function Fetches an entire query result and returns it as an associative array using the first column as the key
DB_common::getCol function Fetches a single column from a query result and returns it as an indexed array
DB_common::getListOf function Lists internal database information
DB_common::getOne function Fetches the first column of the first row from a query result
DB_common::getOption function Returns the value of an option
DB_common::getRow function Fetches the first row of data returned from a query result
DB_common::getSequenceName function Generates the name used inside the database for a sequence
DB_common::getTables Deprecated function Lists the tables in the current database
DB_common::limitQuery function Generates and executes a LIMIT query
DB_common::modifyQuery function Changes a query string for various DBMS specific reasons 1
DB_common::prepare function Prepares a query for multiple execution with execute()
DB_common::provides function Tells whether the present driver supports a given feature
DB_common::query function Sends a query to the database server
DB_common::quoteIdentifier function Quotes a string so it can be safely used as a table or column name 1
DB_common::quoteString Deprecated function DEPRECATED: Quotes a string so it can be safely used within string delimiters in a query
DB_common::raiseError function Communicates an error and invoke error callbacks, etc Overrides PEAR::raiseError
DB_common::setFetchMode function Sets the fetch mode that should be used by default for query results
DB_common::setOption function Sets run-time configuration options for PEAR DB
DB_common::toString Deprecated function DEPRECATED: String conversion method
DB_common::_convertNullArrayValuesToEmpty function Converts all null values in an array to empty strings
DB_common::_rtrimArrayValues function Right-trims all strings in an array
DB_common::__sleep function Automatically indicates which properties should be saved when PHP's serialize() function is called
DB_common::__toString function Automatic string conversion for PHP 5
DB_common::__wakeup function Automatically reconnects to the database when PHP's unserialize() function is called
DB_pgsql::$affected property The number of rows affected by a data manipulation query
DB_pgsql::$autocommit property Should data manipulation queries be committed automatically? @access private
DB_pgsql::$connection property The raw database connection created by PHP
DB_pgsql::$dbsyntax property The database syntax variant to be used (db2, access, etc.), if any
DB_pgsql::$dsn property The DSN information for connecting to a database
DB_pgsql::$errorcode_map property A mapping of native error codes to DB error codes
DB_pgsql::$features property The capabilities of this DB implementation
DB_pgsql::$phptype property The DB driver type (mysql, oci8, odbc, etc.)
DB_pgsql::$row property The current row being looked at in fetchInto() @access private
DB_pgsql::$transaction_opcount property The quantity of transactions begun
DB_pgsql::$_num_rows property The number of rows in a given result set @access private
DB_pgsql::affectedRows function Determines the number of rows affected by a data maniuplation query Overrides DB_common::affectedRows
DB_pgsql::autoCommit function Enables or disables automatic commits Overrides DB_common::autoCommit
DB_pgsql::commit function Commits the current transaction Overrides DB_common::commit
DB_pgsql::connect function Connect to the database server, log in and open the database
DB_pgsql::createSequence function Creates a new sequence Overrides DB_common::createSequence
DB_pgsql::DB_pgsql function This constructor calls <kbd>$this->DB_common()</kbd>
DB_pgsql::disconnect function Disconnects from the database server
DB_pgsql::dropSequence function Deletes a sequence Overrides DB_common::dropSequence
DB_pgsql::errorCode function Determines PEAR::DB error code from the database's text error message. Overrides DB_common::errorCode
DB_pgsql::errorNative function Gets the DBMS' native error message produced by the last query Overrides DB_common::errorNative
DB_pgsql::escapeSimple function Escapes a string according to the current DBMS's standards Overrides DB_common::escapeSimple
DB_pgsql::fetchInto function Places a row from the result set into the given array
DB_pgsql::freeResult function Deletes the result set and frees the memory occupied by the result set
DB_pgsql::getSpecialQuery function Obtains the query string needed for listing a given type of objects Overrides DB_common::getSpecialQuery
DB_pgsql::modifyLimitQuery function Adds LIMIT clauses to a query string according to current DBMS standards Overrides DB_common::modifyLimitQuery
DB_pgsql::nextId function Returns the next free id in a sequence Overrides DB_common::nextId
DB_pgsql::nextResult function Move the internal pgsql result pointer to the next available result
DB_pgsql::numCols function Gets the number of columns in a result set
DB_pgsql::numRows function Gets the number of rows in a result set Overrides DB_common::numRows
DB_pgsql::pgsqlRaiseError function Produces a DB_Error object regarding the current problem
DB_pgsql::quote Deprecated function @internal Overrides DB_common::quote
DB_pgsql::quoteSmart function Formats input so it can be safely used in a query Overrides DB_common::quoteSmart
DB_pgsql::rollback function Reverts the current transaction Overrides DB_common::rollback
DB_pgsql::simpleQuery function Sends a query to the database server
DB_pgsql::tableInfo function Returns information about a table or a result set Overrides DB_common::tableInfo
DB_pgsql::_pgFieldFlags function Get a column's flags
PEAR::$_debug property Whether to enable internal debug messages.
PEAR::$_default_error_handler property Default error handler (callback) for this object, if error mode is PEAR_ERROR_CALLBACK.
PEAR::$_default_error_mode property Default error mode for this object.
PEAR::$_default_error_options property Default error options used for this object when error mode is PEAR_ERROR_TRIGGER.
PEAR::$_error_class property Which class to use for error objects.
PEAR::$_expected_errors property An array of expected errors.
PEAR::delExpect function This method deletes all occurences of the specified element from the expected error codes stack.
PEAR::expectError function This method is used to tell which errors you expect to get. Expected errors are always returned with error mode PEAR_ERROR_RETURN. Expected error codes are stored in a stack, and this method pushes a new element onto it. The list of expected errors…
PEAR::getStaticProperty function If you have a class that's mostly/entirely static, and you need static properties, you can use this method to simulate them. Eg. in your method(s) do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); You MUST…
PEAR::isError function Tell whether a value is a PEAR error.
PEAR::loadExtension function OS independant PHP extension load. Remember to take care on the correct extension name for case sensitive OSes.
PEAR::PEAR function Constructor. Registers this object in $_PEAR_destructor_object_list for destructor emulation if a destructor object exists.
PEAR::popErrorHandling function Pop the last error handler used
PEAR::popExpect function This method pops one element off the expected error codes stack.
PEAR::pushErrorHandling function Push a new error handler on top of the error handler options stack. With this you can easily override the actual error handler for some code and restore it later with popErrorHandling.
PEAR::registerShutdownFunc function Use this function to register a shutdown method for static classes.
PEAR::setErrorHandling function Sets how errors generated by this object should be handled. Can be invoked both in objects and statically. If called statically, setErrorHandling sets the default behaviour for all PEAR objects. If called in an object, setErrorHandling sets the…
PEAR::staticPopErrorHandling function
PEAR::staticPushErrorHandling function
PEAR::throwError function Simpler form of raiseError with fewer options. In most cases message, code and userinfo are enough.
PEAR::_checkDelExpect function This method checks unsets an error code if available
PEAR::_PEAR function Destructor (the emulated type of...). Does nothing right now, but is included for forward compatibility, so subclass destructors should always call it.