AutorÃa | Ultima modificación | Ver Log |
<?php/*** Portable version of Oracle oci8 driver** This file is part of ADOdb, a Database Abstraction Layer library for PHP.** Portable version of oci8 driver, to make it more similar to other database* drivers. The main differences are* 1. that the OCI_ASSOC names are in lowercase instead of uppercase.* 2. bind variables are mapped using ? instead of :<bindvar>** @package ADOdb* @link https://adodb.org Project's web site and documentation* @link https://github.com/ADOdb/ADOdb Source code and issue tracker** The ADOdb Library is dual-licensed, released under both the BSD 3-Clause* and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option,* any later version. This means you can use it in proprietary products.* See the LICENSE.md file distributed with this source code for details.* @license BSD-3-Clause* @license LGPL-2.1-or-later** @copyright 2000-2013 John Lim* @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community*/// security - hide pathsif (!defined('ADODB_DIR')) die();include_once(ADODB_DIR.'/drivers/adodb-oci8.inc.php');class ADODB_oci8po extends ADODB_oci8 {var $databaseType = 'oci8po';var $dataProvider = 'oci8';var $metaColumnsSQL = "select lower(cname),coltype,width, SCALE, PRECISION, NULLS, DEFAULTVAL from col where tname='%s' order by colno"; //changed by smondino@users.sourceforge. netvar $metaTablesSQL = "select lower(table_name),table_type from cat where table_type in ('TABLE','VIEW')";function Param($name,$type='C'){return '?';}function Prepare($sql,$cursor=false){$sqlarr = explode('?',$sql);$sql = $sqlarr[0];for ($i = 1, $max = sizeof($sqlarr); $i < $max; $i++) {$sql .= ':'.($i-1) . $sqlarr[$i];}return ADODB_oci8::Prepare($sql,$cursor);}function Execute($sql,$inputarr=false){return ADOConnection::Execute($sql,$inputarr);}/*** The optimizations performed by ADODB_oci8::SelectLimit() are not* compatible with the oci8po driver, so we rely on the slower method* from the base class.* We can't properly handle prepared statements either due to preprocessing* of query parameters, so we treat them as regular SQL statements.*/function SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs2cache=0){if(is_array($sql)) {// $sql = $sql[0];}return ADOConnection::SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);}/*** Execute a query.** Emulate handling of parameters ? ?, replacing with :bind0 :bind1** @param string|array $sql Query to execute.* @param array $inputarr An optional array of parameters.** @return mixed|bool Query identifier or true if execution successful, false if failed.*/function _query($sql,$inputarr=false){if (is_array($inputarr)) {$i = 0;if (is_array($sql)) {foreach($inputarr as $v) {$arr['bind'.$i++] = $v;}} else {$sql = $this->extractBinds($sql,$inputarr);}}return ADODB_oci8::_query($sql,$inputarr);}/*** Replaces compatibility bind markers with oracle ones and returns a* valid sql statement** This replaces a regexp based section of code that has been subject* to numerous tweaks, as more extreme test cases have appeared. This* is now done this like this to help maintainability and avoid the* need to rely on regexp experienced maintainers** @param string $sql The sql statement* @param string[] $inputarr The bind array** @return string The modified statement*/private function extractBinds($sql,$inputarr){$inString = false;$escaped = 0;$sqlLength = strlen($sql) - 1;$newSql = '';$bindCount = 0;/** inputarr is the passed in bind list, which is associative, but* we only want the keys here*/$inputKeys = array_keys($inputarr);for ($i=0;$i<=$sqlLength;$i++){/** find the next character of the string*/$c = $sql[$i];if ($c == "'" && !$inString && $escaped==0)/** Found the start of a string inside the statement*/$inString = true;elseif ($c == "\\" && $escaped==0)/** The next character will be escaped*/$escaped = 1;elseif ($c == "'" && $inString && $escaped==0)/** We found the end of the string*/$inString = false;if ($escaped == 2)$escaped = 0;if ($escaped==0 && !$inString && $c == '?')/** We found a bind symbol, replace it with the oracle equivalent*/$newSql .= ':' . $inputKeys[$bindCount++];else/** Add the current character the pile*/$newSql .= $c;if ($escaped == 1)/** We have just found an escape character, make sure we ignore the* next one that comes along, it might be a ' character*/$escaped = 2;}return $newSql;}}/*--------------------------------------------------------------------------------------Class Name: Recordset--------------------------------------------------------------------------------------*/class ADORecordset_oci8po extends ADORecordset_oci8 {var $databaseType = 'oci8po';function Fields($colname){if ($this->fetchMode & OCI_ASSOC) return $this->fields[$colname];if (!$this->bind) {$this->bind = array();for ($i=0; $i < $this->_numOfFields; $i++) {$o = $this->FetchField($i);$this->bind[strtoupper($o->name)] = $i;}}return $this->fields[$this->bind[strtoupper($colname)]];}// lowercase field names...function _FetchField($fieldOffset = -1){$fld = new ADOFieldObject;$fieldOffset += 1;$fld->name = oci_field_name($this->_queryID, $fieldOffset);if (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_LOWER) {$fld->name = strtolower($fld->name);}$fld->type = oci_field_type($this->_queryID, $fieldOffset);$fld->max_length = oci_field_size($this->_queryID, $fieldOffset);if ($fld->type == 'NUMBER') {$sc = oci_field_scale($this->_queryID, $fieldOffset);if ($sc == 0) {$fld->type = 'INT';}}return $fld;}// 10% speedup to move MoveNext to child classfunction MoveNext(){$ret = @oci_fetch_array($this->_queryID,$this->fetchMode);if($ret !== false) {global $ADODB_ANSI_PADDING_OFF;$this->fields = $ret;$this->_currentRow++;$this->_updatefields();if (!empty($ADODB_ANSI_PADDING_OFF)) {foreach($this->fields as $k => $v) {if (is_string($v)) $this->fields[$k] = rtrim($v);}}return true;}if (!$this->EOF) {$this->EOF = true;$this->_currentRow++;}return false;}function GetArrayLimit($nrows,$offset=-1){if ($offset <= 0) {$arr = $this->GetArray($nrows);return $arr;}for ($i=1; $i < $offset; $i++)if (!@oci_fetch($this->_queryID)) {$arr = array();return $arr;}$ret = @oci_fetch_array($this->_queryID,$this->fetchMode);if ($ret === false) {$arr = array();return $arr;}$this->fields = $ret;$this->_updatefields();$results = array();$cnt = 0;while (!$this->EOF && $nrows != $cnt) {$results[$cnt++] = $this->fields;$this->MoveNext();}return $results;}function _fetch(){global $ADODB_ANSI_PADDING_OFF;$ret = @oci_fetch_array($this->_queryID,$this->fetchMode);if ($ret) {$this->fields = $ret;$this->_updatefields();if (!empty($ADODB_ANSI_PADDING_OFF)) {foreach($this->fields as $k => $v) {if (is_string($v)) $this->fields[$k] = rtrim($v);}}}return $ret !== false;}}