| verzia 1.2, 2005/11/07 20:37:25 |
verzia 1.3, 2011/06/17 13:56:39 |
|
|
| * @author Rui Hirokawa <hirokawa@php.net> |
* @author Rui Hirokawa <hirokawa@php.net> |
| * @author Stig Bakken <ssb@php.net> |
* @author Stig Bakken <ssb@php.net> |
| * @author Daniel Convissor <danielc@php.net> |
* @author Daniel Convissor <danielc@php.net> |
| * @copyright 1997-2005 The PHP Group |
* @copyright 1997-2007 The PHP Group |
| * @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
| * @version CVS: $Id$ |
* @version CVS: $Id$ |
| * @link http://pear.php.net/package/DB |
* @link http://pear.php.net/package/DB |
| Riadok 41 require_once 'DB/common.php'; |
|
| Riadok 41 require_once 'DB/common.php'; |
|
| * @author Rui Hirokawa <hirokawa@php.net> |
* @author Rui Hirokawa <hirokawa@php.net> |
| * @author Stig Bakken <ssb@php.net> |
* @author Stig Bakken <ssb@php.net> |
| * @author Daniel Convissor <danielc@php.net> |
* @author Daniel Convissor <danielc@php.net> |
| * @copyright 1997-2005 The PHP Group |
* @copyright 1997-2007 The PHP Group |
| * @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
| * @version Release: 1.7.6 |
* @version Release: 1.7.14RC2 |
| * @link http://pear.php.net/package/DB |
* @link http://pear.php.net/package/DB |
| */ |
*/ |
| class DB_pgsql extends DB_common |
class DB_pgsql extends DB_common |
| Riadok 193 class DB_pgsql extends DB_common |
|
| Riadok 193 class DB_pgsql extends DB_common |
|
| * 'portability' => DB_PORTABILITY_ALL, |
* 'portability' => DB_PORTABILITY_ALL, |
| * ); |
* ); |
| * |
* |
| * $db =& DB::connect($dsn, $options); |
* $db = DB::connect($dsn, $options); |
| * if (PEAR::isError($db)) { |
* if (PEAR::isError($db)) { |
| * die($db->getMessage()); |
* die($db->getMessage()); |
| * } |
* } |
| Riadok 277 class DB_pgsql extends DB_common |
|
| Riadok 277 class DB_pgsql extends DB_common |
|
| $this->connection = @call_user_func_array($connect_function, |
$this->connection = @call_user_func_array($connect_function, |
| $params); |
$params); |
| } else { |
} else { |
| ini_set('track_errors', 1); |
@ini_set('track_errors', 1); |
| $this->connection = @call_user_func_array($connect_function, |
$this->connection = @call_user_func_array($connect_function, |
| $params); |
$params); |
| ini_set('track_errors', $ini); |
@ini_set('track_errors', $ini); |
| } |
} |
| |
|
| if (!$this->connection) { |
if (!$this->connection) { |
| Riadok 320 class DB_pgsql extends DB_common |
|
| Riadok 320 class DB_pgsql extends DB_common |
|
| */ |
*/ |
| function simpleQuery($query) |
function simpleQuery($query) |
| { |
{ |
| $ismanip = DB::isManip($query); |
$ismanip = $this->_checkManip($query); |
| $this->last_query = $query; |
$this->last_query = $query; |
| $query = $this->modifyQuery($query); |
$query = $this->modifyQuery($query); |
| if (!$this->autocommit && $ismanip) { |
if (!$this->autocommit && $ismanip) { |
| Riadok 336 class DB_pgsql extends DB_common |
|
| Riadok 336 class DB_pgsql extends DB_common |
|
| if (!$result) { |
if (!$result) { |
| return $this->pgsqlRaiseError(); |
return $this->pgsqlRaiseError(); |
| } |
} |
| // Determine which queries that should return data, and which |
|
| // should return an error code only. |
/* |
| |
* Determine whether queries produce affected rows, result or nothing. |
| |
* |
| |
* This logic was introduced in version 1.1 of the file by ssb, |
| |
* though the regex has been modified slightly since then. |
| |
* |
| |
* 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, WITH |
| |
*/ |
| if ($ismanip) { |
if ($ismanip) { |
| $this->affected = @pg_affected_rows($result); |
$this->affected = @pg_affected_rows($result); |
| return DB_OK; |
return DB_OK; |
| } elseif (preg_match('/^\s*\(*\s*(SELECT|EXPLAIN|SHOW)\s/si', $query)) { |
} elseif (preg_match('/^\s*\(*\s*(SELECT|EXPLAIN|FETCH|SHOW|WITH)\s/si', |
| /* PostgreSQL commands: |
$query)) |
| 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. |
$this->row[(int)$result] = 0; // reset the row counter. |
| $numrows = $this->numRows($result); |
$numrows = $this->numRows($result); |
| if (is_object($numrows)) { |
if (is_object($numrows)) { |
| Riadok 471 class DB_pgsql extends DB_common |
|
| Riadok 478 class DB_pgsql extends DB_common |
|
| } |
} |
| |
|
| // }}} |
// }}} |
| // {{{ quoteSmart() |
// {{{ quoteBoolean() |
| |
|
| /** |
/** |
| * Formats input so it can be safely used in a query |
* Formats a boolean value for use within a query in a locale-independent |
| * |
* manner. |
| * @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 |
|
| * |
* |
| |
* @param boolean the boolean value to be quoted. |
| |
* @return string the quoted string. |
| * @see DB_common::quoteSmart() |
* @see DB_common::quoteSmart() |
| * @since Method available since Release 1.6.0 |
* @since Method available since release 1.7.8. |
| */ |
*/ |
| function quoteSmart($in) |
function quoteBoolean($boolean) { |
| { |
return $boolean ? 'TRUE' : 'FALSE'; |
| 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() |
// {{{ escapeSimple() |
| |
|
| Riadok 512 class DB_pgsql extends DB_common |
|
| Riadok 502 class DB_pgsql extends DB_common |
|
| * {@internal PostgreSQL treats a backslash as an escape character, |
* {@internal PostgreSQL treats a backslash as an escape character, |
| * so they are escaped as well. |
* 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 |
* @param string $str the string to be escaped |
| * |
* |
| * @return string the escaped string |
* @return string the escaped string |
| Riadok 524 class DB_pgsql extends DB_common |
|
| Riadok 511 class DB_pgsql extends DB_common |
|
| */ |
*/ |
| function escapeSimple($str) |
function escapeSimple($str) |
| { |
{ |
| return str_replace("'", "''", str_replace('\\', '\\\\', $str)); |
if (function_exists('pg_escape_string')) { |
| |
/* This fixes an undocumented BC break in PHP 5.2.0 which changed |
| |
* the prototype of pg_escape_string. I'm not thrilled about having |
| |
* to sniff the PHP version, quite frankly, but it's the only way |
| |
* to deal with the problem. Revision 1.331.2.13.2.10 on |
| |
* php-src/ext/pgsql/pgsql.c (PHP_5_2 branch) is to blame, for the |
| |
* record. */ |
| |
if (version_compare(PHP_VERSION, '5.2.0', '>=')) { |
| |
return pg_escape_string($this->connection, $str); |
| |
} else { |
| |
return pg_escape_string($str); |
| |
} |
| |
} else { |
| |
return str_replace("'", "''", str_replace('\\', '\\\\', $str)); |
| |
} |
| } |
} |
| |
|
| // }}} |
// }}} |
| Riadok 675 class DB_pgsql extends DB_common |
|
| Riadok 676 class DB_pgsql extends DB_common |
|
| $repeat = false; |
$repeat = false; |
| do { |
do { |
| $this->pushErrorHandling(PEAR_ERROR_RETURN); |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
| $result =& $this->query("SELECT NEXTVAL('${seqname}')"); |
$result = $this->query("SELECT NEXTVAL('${seqname}')"); |
| $this->popErrorHandling(); |
$this->popErrorHandling(); |
| if ($ondemand && DB::isError($result) && |
if ($ondemand && DB::isError($result) && |
| $result->getCode() == DB_ERROR_NOSUCHTABLE) { |
$result->getCode() == DB_ERROR_NOSUCHTABLE) { |
| Riadok 779 class DB_pgsql extends DB_common |
|
| Riadok 780 class DB_pgsql extends DB_common |
|
| function pgsqlRaiseError($errno = null) |
function pgsqlRaiseError($errno = null) |
| { |
{ |
| $native = $this->errorNative(); |
$native = $this->errorNative(); |
| |
if (!$native) { |
| |
$native = 'Database connection has been lost.'; |
| |
$errno = DB_ERROR_CONNECT_FAILED; |
| |
} |
| if ($errno === null) { |
if ($errno === null) { |
| $errno = $this->errorCode($native); |
$errno = $this->errorCode($native); |
| } |
} |
| Riadok 815 class DB_pgsql extends DB_common |
|
| Riadok 820 class DB_pgsql extends DB_common |
|
| static $error_regexps; |
static $error_regexps; |
| if (!isset($error_regexps)) { |
if (!isset($error_regexps)) { |
| $error_regexps = array( |
$error_regexps = array( |
| |
'/column .* (of relation .*)?does not exist/i' |
| |
=> DB_ERROR_NOSUCHFIELD, |
| '/(relation|sequence|table).*does not exist|class .* not found/i' |
'/(relation|sequence|table).*does not exist|class .* not found/i' |
| => DB_ERROR_NOSUCHTABLE, |
=> DB_ERROR_NOSUCHTABLE, |
| '/index .* does not exist/' |
'/index .* does not exist/' |
| => DB_ERROR_NOT_FOUND, |
=> DB_ERROR_NOT_FOUND, |
| '/column .* does not exist/i' |
|
| => DB_ERROR_NOSUCHFIELD, |
|
| '/relation .* already exists/i' |
'/relation .* already exists/i' |
| => DB_ERROR_ALREADY_EXISTS, |
=> DB_ERROR_ALREADY_EXISTS, |
| '/(divide|division) by zero$/i' |
'/(divide|division) by zero$/i' |
| Riadok 976 class DB_pgsql extends DB_common |
|
| Riadok 981 class DB_pgsql extends DB_common |
|
| { |
{ |
| $field_name = @pg_fieldname($resource, $num_field); |
$field_name = @pg_fieldname($resource, $num_field); |
| |
|
| |
// Check if there's a schema in $table_name and update things |
| |
// accordingly. |
| |
$from = 'pg_attribute f, pg_class tab, pg_type typ'; |
| |
if (strpos($table_name, '.') !== false) { |
| |
$from .= ', pg_namespace nsp'; |
| |
list($schema, $table) = explode('.', $table_name); |
| |
$tableWhere = "tab.relname = '$table' AND tab.relnamespace = nsp.oid AND nsp.nspname = '$schema'"; |
| |
} else { |
| |
$tableWhere = "tab.relname = '$table_name'"; |
| |
} |
| |
|
| $result = @pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef |
$result = @pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef |
| FROM pg_attribute f, pg_class tab, pg_type typ |
FROM $from |
| WHERE tab.relname = typ.typname |
WHERE tab.relname = typ.typname |
| AND typ.typrelid = f.attrelid |
AND typ.typrelid = f.attrelid |
| AND f.attname = '$field_name' |
AND f.attname = '$field_name' |
| AND tab.relname = '$table_name'"); |
AND $tableWhere"); |
| if (@pg_numrows($result) > 0) { |
if (@pg_numrows($result) > 0) { |
| $row = @pg_fetch_row($result, 0); |
$row = @pg_fetch_row($result, 0); |
| $flags = ($row[0] == 't') ? 'not_null ' : ''; |
$flags = ($row[0] == 't') ? 'not_null ' : ''; |
| |
|
| if ($row[1] == 't') { |
if ($row[1] == 't') { |
| $result = @pg_exec($this->connection, "SELECT a.adsrc |
$result = @pg_exec($this->connection, "SELECT a.adsrc |
| FROM pg_attribute f, pg_class tab, pg_type typ, pg_attrdef a |
FROM $from, pg_attrdef a |
| WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid |
WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid |
| AND f.attrelid = a.adrelid AND f.attname = '$field_name' |
AND f.attrelid = a.adrelid AND f.attname = '$field_name' |
| AND tab.relname = '$table_name' AND f.attnum = a.adnum"); |
AND $tableWhere AND f.attnum = a.adnum"); |
| $row = @pg_fetch_row($result, 0); |
$row = @pg_fetch_row($result, 0); |
| $num = preg_replace("/'(.*)'::\w+/", "\\1", $row[0]); |
$num = preg_replace("/'(.*)'::\w+/", "\\1", $row[0]); |
| $flags .= 'default_' . rawurlencode($num) . ' '; |
$flags .= 'default_' . rawurlencode($num) . ' '; |
| Riadok 1000 class DB_pgsql extends DB_common |
|
| Riadok 1016 class DB_pgsql extends DB_common |
|
| $flags = ''; |
$flags = ''; |
| } |
} |
| $result = @pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey |
$result = @pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey |
| FROM pg_attribute f, pg_class tab, pg_type typ, pg_index i |
FROM $from, pg_index i |
| WHERE tab.relname = typ.typname |
WHERE tab.relname = typ.typname |
| AND typ.typrelid = f.attrelid |
AND typ.typrelid = f.attrelid |
| AND f.attrelid = i.indrelid |
AND f.attrelid = i.indrelid |
| AND f.attname = '$field_name' |
AND f.attname = '$field_name' |
| AND tab.relname = '$table_name'"); |
AND $tableWhere"); |
| $count = @pg_numrows($result); |
$count = @pg_numrows($result); |
| |
|
| for ($i = 0; $i < $count ; $i++) { |
for ($i = 0; $i < $count ; $i++) { |
| Riadok 1066 class DB_pgsql extends DB_common |
|
| Riadok 1082 class DB_pgsql extends DB_common |
|
| . ' FROM pg_catalog.pg_tables' |
. ' FROM pg_catalog.pg_tables' |
| . ' WHERE schemaname NOT IN' |
. ' WHERE schemaname NOT IN' |
| . " ('pg_catalog', 'information_schema', 'pg_toast')"; |
. " ('pg_catalog', 'information_schema', 'pg_toast')"; |
| |
case 'schema.views': |
| |
return "SELECT schemaname || '.' || viewname from pg_views WHERE schemaname" |
| |
. " NOT IN ('information_schema', 'pg_catalog')"; |
| case 'views': |
case 'views': |
| // Table cols: viewname | viewowner | definition |
// Table cols: viewname | viewowner | definition |
| return 'SELECT viewname from pg_views WHERE schemaname' |
return 'SELECT viewname from pg_views WHERE schemaname' |
| Riadok 1084 class DB_pgsql extends DB_common |
|
| Riadok 1103 class DB_pgsql extends DB_common |
|
| } |
} |
| |
|
| // }}} |
// }}} |
| |
// {{{ _checkManip() |
| |
|
| |
/** |
| |
* Checks if the given query is a manipulation query. This also takes into |
| |
* account the _next_query_manip flag and sets the _last_query_manip flag |
| |
* (and resets _next_query_manip) according to the result. |
| |
* |
| |
* @param string The query to check. |
| |
* |
| |
* @return boolean true if the query is a manipulation query, false |
| |
* otherwise |
| |
* |
| |
* @access protected |
| |
*/ |
| |
function _checkManip($query) |
| |
{ |
| |
return (preg_match('/^\s*(SAVEPOINT|RELEASE)\s+/i', $query) |
| |
|| parent::_checkManip($query)); |
| |
} |
| |
|
| } |
} |
| |
|