📄 oci8.php
字号:
<?php/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */// +----------------------------------------------------------------------+// | PHP Version 4 |// +----------------------------------------------------------------------+// | Copyright (c) 1997-2004 The PHP Group |// +----------------------------------------------------------------------+// | This source file is subject to version 2.02 of the PHP license, |// | that is bundled with this package in the file LICENSE, and is |// | available at through the world-wide-web at |// | http://www.php.net/license/2_02.txt. |// | If you did not receive a copy of the PHP license and are unable to |// | obtain it through the world-wide-web, please send a note to |// | license@php.net so we can mail you a copy immediately. |// +----------------------------------------------------------------------+// | Author: James L. Pine <jlp@valinux.com> |// | Maintainer: Daniel Convissor <danielc@php.net> |// +----------------------------------------------------------------------+//// $Id: oci8.php,v 1.2 2005/07/22 05:10:14 max Exp $// be aware... OCIError() only appears to return anything when given a// statement, so functions return the generic DB_ERROR instead of more// useful errors that have to do with feedback from the database.require_once PEAR_DIR . 'DB/common.php';/** * Database independent query interface definition for PHP's Oracle 8 * call-interface extension. * * Definitely works with versions 8 and 9 of Oracle. * * @package DB * @version $Id: oci8.php,v 1.2 2005/07/22 05:10:14 max Exp $ * @category Database * @author James L. Pine <jlp@valinux.com> */class DB_oci8 extends DB_common{ // {{{ properties var $connection; var $phptype, $dbsyntax; var $manip_query = array(); var $prepare_types = array(); var $autoCommit = 1; var $last_stmt = false; /** * stores the $data passed to execute() in the oci8 driver * * Gets reset to array() when simpleQuery() is run. * * Needed in case user wants to call numRows() after prepare/execute * was used. * * @var array * @access private */ var $_data = array(); // }}} // {{{ constructor function DB_oci8() { $this->DB_common(); $this->phptype = 'oci8'; $this->dbsyntax = 'oci8'; $this->features = array( 'prepare' => false, 'pconnect' => true, 'transactions' => true, 'limit' => 'alter' ); $this->errorcode_map = array( 1 => DB_ERROR_CONSTRAINT, 900 => DB_ERROR_SYNTAX, 904 => DB_ERROR_NOSUCHFIELD, 921 => DB_ERROR_SYNTAX, 923 => DB_ERROR_SYNTAX, 942 => DB_ERROR_NOSUCHTABLE, 955 => DB_ERROR_ALREADY_EXISTS, 1400 => DB_ERROR_CONSTRAINT_NOT_NULL, 1407 => DB_ERROR_CONSTRAINT_NOT_NULL, 1476 => DB_ERROR_DIVZERO, 1722 => DB_ERROR_INVALID_NUMBER, 2289 => DB_ERROR_NOSUCHTABLE, 2291 => DB_ERROR_CONSTRAINT, 2449 => DB_ERROR_CONSTRAINT, ); } // }}} // {{{ connect() /** * Connect to a database and log in as the specified user. * * @param $dsn the data source name (see DB::parseDSN for syntax) * @param $persistent (optional) whether the connection should * be persistent * * @return int DB_OK on success, a DB error code on failure */ function connect($dsninfo, $persistent = false) { if (!DB::assertExtension('oci8')) { return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); } $this->dsn = $dsninfo; $connect_function = $persistent ? 'OCIPLogon' : 'OCILogon'; if ($dsninfo['hostspec']) { $conn = @$connect_function($dsninfo['username'], $dsninfo['password'], $dsninfo['hostspec']); } elseif ($dsninfo['username'] || $dsninfo['password']) { $conn = @$connect_function($dsninfo['username'], $dsninfo['password']); } else { $conn = false; } if ($conn == false) { $error = OCIError(); $error = (is_array($error)) ? $error['message'] : null; return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, null, $error); } $this->connection = $conn; return DB_OK; } // }}} // {{{ disconnect() /** * Log out and disconnect from the database. * * @return bool true on success, false if not connected. */ function disconnect() { $ret = @OCILogOff($this->connection); $this->connection = null; return $ret; } // }}} // {{{ simpleQuery() /** * Send a query to oracle and return the results as an oci8 resource * identifier. * * @param $query the SQL query * * @return int returns a valid oci8 result for successful SELECT * queries, DB_OK for other successful queries. A DB error code * is returned on failure. */ function simpleQuery($query) { $this->_data = array(); $this->last_query = $query; $query = $this->modifyQuery($query); $result = @OCIParse($this->connection, $query); if (!$result) { return $this->oci8RaiseError(); } if ($this->autoCommit) { $success = @OCIExecute($result,OCI_COMMIT_ON_SUCCESS); } else { $success = @OCIExecute($result,OCI_DEFAULT); } if (!$success) { return $this->oci8RaiseError($result); } $this->last_stmt=$result; // Determine which queries that should return data, and which // should return an error code only. return DB::isManip($query) ? DB_OK : $result; } // }}} // {{{ nextResult() /** * Move the internal oracle result pointer to the next available result * * @param a valid oci8 result resource * * @access public * * @return true if a result is available otherwise return false */ function nextResult($result) { return false; } // }}} // {{{ fetchInto() /** * Fetch a row and insert the data into an existing array. * * Formating of the array and the data therein are configurable. * See DB_result::fetchInto() for more information. * * @param resource $result query result identifier * @param array $arr (reference) array where data from the row * should be placed * @param int $fetchmode how the resulting array should be indexed * @param int $rownum the row number to fetch * * @return mixed DB_OK on success, null when end of result set is * reached or on failure * * @see DB_result::fetchInto() * @access private */ function fetchInto($result, &$arr, $fetchmode, $rownum=null) { if ($rownum !== null) { return $this->raiseError(DB_ERROR_NOT_CAPABLE); } if ($fetchmode & DB_FETCHMODE_ASSOC) { $moredata = @OCIFetchInto($result,$arr,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS); if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $moredata) { $arr = array_change_key_case($arr, CASE_LOWER); } } else { $moredata = OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS); } if (!$moredata) { return null; } if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { $this->_rtrimArrayValues($arr); } if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { $this->_convertNullArrayValuesToEmpty($arr); } return DB_OK; } // }}} // {{{ freeResult() /** * Free the internal resources associated with $result. * * @param $result oci8 result identifier * * @return bool true on success, false if $result is invalid */ function freeResult($result) { return @OCIFreeStatement($result); } /** * Free the internal resources associated with a prepared query. * * @param $stmt oci8 statement identifier * * @return bool true on success, false if $result is invalid */ function freePrepared($stmt) { if (isset($this->prepare_types[(int)$stmt])) { unset($this->prepare_types[(int)$stmt]); unset($this->manip_query[(int)$stmt]); } else { return false; } return true; } // }}} // {{{ numRows() function numRows($result) { // emulate numRows for Oracle. yuck. if ($this->options['portability'] & DB_PORTABILITY_NUMROWS && $result === $this->last_stmt) { $countquery = 'SELECT COUNT(*) FROM ('.$this->last_query.')'; $save_query = $this->last_query; $save_stmt = $this->last_stmt; if (count($this->_data)) { $smt = $this->prepare('SELECT COUNT(*) FROM ('.$this->last_query.')'); $count = $this->execute($smt, $this->_data); } else { $count =& $this->query($countquery); } if (DB::isError($count) || DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED))) { $this->last_query = $save_query; $this->last_stmt = $save_stmt; return $this->raiseError(DB_ERROR_NOT_CAPABLE); } return $row[0]; } return $this->raiseError(DB_ERROR_NOT_CAPABLE); } // }}} // {{{ numCols() /** * Get the number of columns in a result set. * * @param $result oci8 result identifier * * @return int the number of columns per row in $result */ function numCols($result) { $cols = @OCINumCols($result); if (!$cols) { return $this->oci8RaiseError($result); } return $cols; } // }}} // {{{ errorNative() /** * Get the native error code of the last error (if any) that occured * on the current connection. This does not work, as OCIError does * not work unless given a statement. If OCIError does return * something, so will this. * * @return int native oci8 error code */ function errorNative() { if (is_resource($this->last_stmt)) { $error = @OCIError($this->last_stmt); } else { $error = @OCIError($this->connection); } if (is_array($error)) { return $error['code']; } return false; } // }}} // {{{ prepare() /** * Prepares a query for multiple execution with execute(). * * With oci8, this is emulated. * * prepare() requires a generic query as string like <code> * INSERT INTO numbers VALUES (?, ?, ?) * </code>. The <kbd>?</kbd> characters are placeholders. * * Three types of placeholders can be used: * + <kbd>?</kbd> a quoted scalar value, i.e. strings, integers * + <kbd>!</kbd> value is inserted 'as is' * + <kbd>&</kbd> requires a file name. The file's contents get * inserted into the query (i.e. saving binary * data in a db) * * Use backslashes to escape placeholder characters if you don't want * them to be interpreted as placeholders. Example: <code> * "UPDATE foo SET col=? WHERE col='over \& under'" * </code> * * @param string $query query to be prepared * @return mixed DB statement resource on success. DB_Error on failure. */ function prepare($query) { $tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, PREG_SPLIT_DELIM_CAPTURE); $binds = count($tokens) - 1; $token = 0; $types = array(); $newquery = ''; foreach ($tokens as $key => $val) { switch ($val) { case '?': $types[$token++] = DB_PARAM_SCALAR; unset($tokens[$key]); break; case '&': $types[$token++] = DB_PARAM_OPAQUE; unset($tokens[$key]); break; case '!': $types[$token++] = DB_PARAM_MISC; unset($tokens[$key]); break; default: $tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val); if ($key != $binds) { $newquery .= $tokens[$key] . ':bind' . $token; } else { $newquery .= $tokens[$key]; } } } $this->last_query = $query; $newquery = $this->modifyQuery($newquery); if (!$stmt = @OCIParse($this->connection, $newquery)) { return $this->oci8RaiseError(); } $this->prepare_types[$stmt] = $types; $this->manip_query[(int)$stmt] = DB::isManip($query); return $stmt; } // }}} // {{{ execute() /** * Executes a DB statement prepared with prepare(). * * @param resource $stmt a DB statement resource returned from prepare() * @param mixed $data 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 for non-array items or the * quantity of elements in the array. * @return int returns an oci8 result resource for successful * SELECT queries, DB_OK for other successful queries. A DB error * code is returned on failure. * @see DB_oci::prepare() */ function &execute($stmt, $data = array()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -