pgsql.php
来自「视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.」· PHP 代码 · 共 1,474 行 · 第 1/4 页
PHP
1,474 行
<?php// +----------------------------------------------------------------------+// | PHP Version 4 |// +----------------------------------------------------------------------+// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |// | Stig. S. Bakken, Lukas Smith |// | All rights reserved. |// +----------------------------------------------------------------------+// | MDB is a merge of PEAR DB and Metabases that provides a unified DB |// | API as well as database abstraction for PHP applications. |// | This LICENSE is in the BSD license style. |// | |// | Redistribution and use in source and binary forms, with or without |// | modification, are permitted provided that the following conditions |// | are met: |// | |// | Redistributions of source code must retain the above copyright |// | notice, this list of conditions and the following disclaimer. |// | |// | Redistributions in binary form must reproduce the above copyright |// | notice, this list of conditions and the following disclaimer in the |// | documentation and/or other materials provided with the distribution. |// | |// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |// | Lukas Smith nor the names of his contributors may be used to endorse |// | or promote products derived from this software without specific prior|// | written permission. |// | |// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |// | POSSIBILITY OF SUCH DAMAGE. |// +----------------------------------------------------------------------+// | Author: Paul Cooper <pgc@ucecom.com> |// +----------------------------------------------------------------------+//// $Id: pgsql.php,v 1.62.4.20 2004/03/12 16:19:30 lsmith Exp $require_once('MDB/Common.php');/** * MDB PostGreSQL driver * * Notes: * - Creation of new databases is based on database template1. * * - The decimal type fields are emulated with integer fields. * * - PostgreSQL stores large objects in files managed by the server. * Tables with large object fields only store identifiers pointing to those * files. If you delete or update rows of those tables, the actual large * object files are not deleted from the server file system. Therefore you may * need to reclaim large object field space by deleting those files manually. * * @package MDB * @category Database * @author Paul Cooper <pgc@ucecom.com> */class MDB_pgsql extends MDB_Common{ var $connection = 0; var $connected_host; var $connected_port; var $selected_database = ''; var $opened_persistent = ''; var $escape_quotes = "\\"; var $decimal_factor = 1.0; var $highest_fetched_row = array(); var $columns = array(); // }}} // {{{ constructor /** * Constructor */ function MDB_pgsql() { $this->MDB_Common(); $this->phptype = 'pgsql'; $this->dbsyntax = 'pgsql'; $this->supported['Sequences'] = 1; $this->supported['Indexes'] = 1; $this->supported['SummaryFunctions'] = 1; $this->supported['OrderByText'] = 1; $this->supported['Transactions'] = 1; $this->supported['CurrId'] = 1; $this->supported['SelectRowRanges'] = 1; $this->supported['LOBs'] = 1; $this->supported['Replace'] = 1; $this->supported['SubSelects'] = 1; $this->decimal_factor = pow(10.0, $this->decimal_places); } // }}} // {{{ errorCode() /** * Map native error codes to DB's portable ones. Requires that * the DB implementation's constructor fills in the $errorcode_map * property. * * @param $nativecode the native error code, as returned by the backend * database extension (string or integer) * @return int a portable MDB error code, or FALSE if this DB * implementation has no mapping for the given error code. */ function errorCode($errormsg) { static $error_regexps; if (empty($error_regexps)) { $error_regexps = array( '/([Tt]able does not exist\.|[Rr]elation [\"\'].*[\"\'] does not exist|[Ss]equence does not exist|[Cc]lass ".+" not found)$/' => MDB_ERROR_NOSUCHTABLE, '/[Tt]able [\"\'].*[\"\'] does not exist/' => MDB_ERROR_NOSUCHTABLE, '/[Rr]elation [\"\'].*[\"\'] already exists|[Cc]annot insert a duplicate key into (a )?unique index.*/' => MDB_ERROR_ALREADY_EXISTS, '/divide by zero$/' => MDB_ERROR_DIVZERO, '/pg_atoi: error in .*: can\'t parse /' => MDB_ERROR_INVALID_NUMBER, '/ttribute [\"\'].*[\"\'] not found$|[Rr]elation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => MDB_ERROR_NOSUCHFIELD, '/parser: parse error at or near \"/' => MDB_ERROR_SYNTAX, '/syntax error at/' => MDB_ERROR_SYNTAX, '/violates not-null constraint/' => MDB_ERROR_CONSTRAINT_NOT_NULL, '/violates [\w ]+ constraint/' => MDB_ERROR_CONSTRAINT, '/referential integrity violation/' => MDB_ERROR_CONSTRAINT, '/deadlock detected/' => MDB_ERROR_DEADLOCK ); } foreach ($error_regexps as $regexp => $code) { if (preg_match($regexp, $errormsg)) { return($code); } } // Fall back to MDB_ERROR if there was no mapping. return(MDB_ERROR); } // }}} // {{{ pgsqlRaiseError() /** * This method is used to communicate an error and invoke error * callbacks etc. Basically a wrapper for MDB::raiseError * that checks for native error msgs. * * @param integer $errno error code * @param string $message userinfo message * @return object a PEAR error object * @access public * @see PEAR_Error */ function pgsqlRaiseError($errno = NULL, $message = NULL) { if ($this->connection) { $error = @pg_errormessage($this->connection); } else { $error = @pg_errormessage(); } return($this->raiseError($this->errorCode($error), NULL, NULL, $message, $error)); } // }}} // {{{ errorNative() /** * Get the native error code of the last error (if any) that * occured on the current connection. * * @access public * * @return int native pgsql error code */ function errorNative() { return @pg_errormessage($this->connection); } // }}} // {{{ autoCommit() /** * Define whether database changes done on the database be automatically * committed. This function may also implicitly start or end a transaction. * * @param boolean $auto_commit flag that indicates whether the database * changes should be committed right after executing every query * statement. If this argument is 0 a transaction implicitly started. * Otherwise, if a transaction is in progress it is ended by committing * any database changes that were pending. * @return mixed MDB_OK on success, a MDB error on failure * @access public */ function autoCommit($auto_commit) { $this->debug('AutoCommit: '.($auto_commit ? 'On' : 'Off')); if ($this->auto_commit == $auto_commit) { return(MDB_OK); } if ($this->connection) { if (MDB::isError($result = $this->_doQuery($auto_commit ? 'END' : 'BEGIN'))) return($result); } $this->auto_commit = $auto_commit; $this->in_transaction = !$auto_commit; return(MDB_OK); } // }}} // {{{ commit() /** * Commit the database changes done during a transaction that is in * progress. This function may only be called when auto-committing is * disabled, otherwise it will fail. Therefore, a new transaction is * implicitly started after committing the pending changes. * * @return mixed MDB_OK on success, a MDB error on failure * @access public */ function commit() { $this->debug('Commit Transaction'); if ($this->auto_commit) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'Commit: transaction changes are being auto commited')); } return($this->_doQuery('COMMIT') && $this->_doQuery('BEGIN')); } // }}} // {{{ rollback() /** * Cancel any database changes done during a transaction that is in * progress. This function may only be called when auto-committing is * disabled, otherwise it will fail. Therefore, a new transaction is * implicitly started after canceling the pending changes. * * @return mixed MDB_OK on success, a MDB error on failure * @access public */ function rollback() { $this->debug('Rollback Transaction'); if ($this->auto_commit) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'Rollback: transactions can not be rolled back when changes are auto commited')); } return($this->_doQuery('ROLLBACK') && $this->_doQuery('BEGIN')); } // }}} // {{{ _doConnect() /** * Does the grunt work of connecting to the database * * @return mixed connection resource on success, MDB_Error on failure * @access private **/ function _doConnect($database_name, $persistent) { $function = ($persistent ? 'pg_pconnect' : 'pg_connect'); if (!function_exists($function)) { return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'doConnect: PostgreSQL support is not available in this PHP configuration')); } $port = (isset($this->port) ? $this->port : ''); if ($database_name == '') { $database_name = 'template1'; } $connect_string = 'dbname='.$database_name; if ($this->host != '') { $connect_string .= ' host='.$this->host; } if ($port != '') { $connect_string .= ' port='.strval($port); } if ($this->user != '') { $connect_string .= ' user='.$this->user; } if ($this->password != '') { $connect_string .= ' password='.$this->password; } putenv('PGDATESTYLE=ISO'); if (($connection = @$function($connect_string)) > 0) { return($connection); } if (isset($php_errormsg)) { $error_msg = $php_errormsg; } else { $error_msg = 'Could not connect to PostgreSQL server'; } return($this->raiseError(MDB_ERROR_CONNECT_FAILED, NULL, NULL, 'doConnect: '.$error_msg)); } // }}} // {{{ connect() /** * Connect to the database * * @return TRUE on success, MDB_Error on failure * @access public **/ function connect() { $port = (isset($this->options['port']) ? $this->options['port'] : ''); if($this->connection != 0) { if (!strcmp($this->connected_host, $this->host) && !strcmp($this->connected_port, $port) && !strcmp($this->selected_database, $this->database_name) && ($this->opened_persistent == $this->options['persistent'])) { return(MDB_OK); } @pg_close($this->connection); $this->affected_rows = -1; $this->connection = 0; } if(!PEAR::loadExtension($this->phptype)) { return(PEAR::raiseError(NULL, MDB_ERROR_NOT_FOUND, NULL, NULL, 'extension '.$this->phptype.' is not compiled into PHP', 'MDB_Error', TRUE)); } if(function_exists('pg_cmdTuples')) { $connection = $this->_doConnect('template1', 0); if (!MDB::isError($connection)) { if (($result = @pg_exec($connection, 'BEGIN'))) { $error_reporting = error_reporting(63); @pg_cmdtuples($result); if (!isset($php_errormsg) || strcmp($php_errormsg, 'This compilation does not support pg_cmdtuples()')) { $this->supported['AffectedRows'] = 1; } error_reporting($error_reporting); } else { $err = $this->raiseError(MDB_ERROR, NULL, NULL, 'Setup: '.@pg_errormessage($connection)); } @pg_close($connection); } else { $err = $this->raiseError(MDB_ERROR, NULL, NULL, 'Setup: could not execute BEGIN'); } if (isset($err) && MDB::isError($err)) { return($err); } } $connection = $this->_doConnect($this->database_name, $this->options['persistent']); if (MDB::isError($connection)) { return($connection); } $this->connection = $connection; if (!$this->auto_commit && MDB::isError($trans_result = $this->_doQuery('BEGIN'))) { pg_Close($this->connection); $this->connection = 0; $this->affected_rows = -1; return($trans_result); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?