Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]
1 <?php 2 /** 3 * Portable version of Oracle oci8 driver 4 * 5 * This file is part of ADOdb, a Database Abstraction Layer library for PHP. 6 * 7 * Portable version of oci8 driver, to make it more similar to other database 8 * drivers. The main differences are 9 * 1. that the OCI_ASSOC names are in lowercase instead of uppercase. 10 * 2. bind variables are mapped using ? instead of :<bindvar> 11 * 12 * @package ADOdb 13 * @link https://adodb.org Project's web site and documentation 14 * @link https://github.com/ADOdb/ADOdb Source code and issue tracker 15 * 16 * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause 17 * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, 18 * any later version. This means you can use it in proprietary products. 19 * See the LICENSE.md file distributed with this source code for details. 20 * @license BSD-3-Clause 21 * @license LGPL-2.1-or-later 22 * 23 * @copyright 2000-2013 John Lim 24 * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community 25 */ 26 27 // security - hide paths 28 if (!defined('ADODB_DIR')) die(); 29 30 include_once(ADODB_DIR.'/drivers/adodb-oci8.inc.php'); 31 32 class ADODB_oci8po extends ADODB_oci8 { 33 var $databaseType = 'oci8po'; 34 var $dataProvider = 'oci8'; 35 var $metaColumnsSQL = "select lower(cname),coltype,width, SCALE, PRECISION, NULLS, DEFAULTVAL from col where tname='%s' order by colno"; //changed by smondino@users.sourceforge. net 36 var $metaTablesSQL = "select lower(table_name),table_type from cat where table_type in ('TABLE','VIEW')"; 37 38 function Param($name,$type='C') 39 { 40 return '?'; 41 } 42 43 function Prepare($sql,$cursor=false) 44 { 45 $sqlarr = explode('?',$sql); 46 $sql = $sqlarr[0]; 47 for ($i = 1, $max = sizeof($sqlarr); $i < $max; $i++) { 48 $sql .= ':'.($i-1) . $sqlarr[$i]; 49 } 50 return ADODB_oci8::Prepare($sql,$cursor); 51 } 52 53 function Execute($sql,$inputarr=false) 54 { 55 return ADOConnection::Execute($sql,$inputarr); 56 } 57 58 /** 59 * The optimizations performed by ADODB_oci8::SelectLimit() are not 60 * compatible with the oci8po driver, so we rely on the slower method 61 * from the base class. 62 * We can't properly handle prepared statements either due to preprocessing 63 * of query parameters, so we treat them as regular SQL statements. 64 */ 65 function SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs2cache=0) 66 { 67 if(is_array($sql)) { 68 // $sql = $sql[0]; 69 } 70 return ADOConnection::SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache); 71 } 72 73 // emulate handling of parameters ? ?, replacing with :bind0 :bind1 74 function _query($sql,$inputarr=false) 75 { 76 if (is_array($inputarr)) { 77 $i = 0; 78 if (is_array($sql)) { 79 foreach($inputarr as $v) { 80 $arr['bind'.$i++] = $v; 81 } 82 } else { 83 $sql = $this->extractBinds($sql,$inputarr); 84 } 85 } 86 return ADODB_oci8::_query($sql,$inputarr); 87 } 88 89 /** 90 * Replaces compatibility bind markers with oracle ones and returns a 91 * valid sql statement 92 * 93 * This replaces a regexp based section of code that has been subject 94 * to numerous tweaks, as more extreme test cases have appeared. This 95 * is now done this like this to help maintainability and avoid the 96 * need to rely on regexp experienced maintainers 97 * 98 * @param string $sql The sql statement 99 * @param string[] $inputarr The bind array 100 * 101 * @return string The modified statement 102 */ 103 private function extractBinds($sql,$inputarr) 104 { 105 $inString = false; 106 $escaped = 0; 107 $sqlLength = strlen($sql) - 1; 108 $newSql = ''; 109 $bindCount = 0; 110 111 /* 112 * inputarr is the passed in bind list, which is associative, but 113 * we only want the keys here 114 */ 115 $inputKeys = array_keys($inputarr); 116 117 for ($i=0;$i<=$sqlLength;$i++) 118 { 119 /* 120 * find the next character of the string 121 */ 122 $c = $sql[$i]; 123 124 if ($c == "'" && !$inString && $escaped==0) 125 /* 126 * Found the start of a string inside the statement 127 */ 128 $inString = true; 129 elseif ($c == "\\" && $escaped==0) 130 /* 131 * The next character will be escaped 132 */ 133 $escaped = 1; 134 elseif ($c == "'" && $inString && $escaped==0) 135 /* 136 * We found the end of the string 137 */ 138 $inString = false; 139 140 if ($escaped == 2) 141 $escaped = 0; 142 143 if ($escaped==0 && !$inString && $c == '?') 144 /* 145 * We found a bind symbol, replace it with the oracle equivalent 146 */ 147 $newSql .= ':' . $inputKeys[$bindCount++]; 148 else 149 /* 150 * Add the current character the pile 151 */ 152 $newSql .= $c; 153 154 if ($escaped == 1) 155 /* 156 * We have just found an escape character, make sure we ignore the 157 * next one that comes along, it might be a ' character 158 */ 159 $escaped = 2; 160 } 161 162 return $newSql; 163 164 } 165 } 166 167 /*-------------------------------------------------------------------------------------- 168 Class Name: Recordset 169 --------------------------------------------------------------------------------------*/ 170 171 class ADORecordset_oci8po extends ADORecordset_oci8 { 172 173 var $databaseType = 'oci8po'; 174 175 function Fields($colname) 176 { 177 if ($this->fetchMode & OCI_ASSOC) return $this->fields[$colname]; 178 179 if (!$this->bind) { 180 $this->bind = array(); 181 for ($i=0; $i < $this->_numOfFields; $i++) { 182 $o = $this->FetchField($i); 183 $this->bind[strtoupper($o->name)] = $i; 184 } 185 } 186 return $this->fields[$this->bind[strtoupper($colname)]]; 187 } 188 189 // lowercase field names... 190 function _FetchField($fieldOffset = -1) 191 { 192 $fld = new ADOFieldObject; 193 $fieldOffset += 1; 194 $fld->name = oci_field_name($this->_queryID, $fieldOffset); 195 if (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_LOWER) { 196 $fld->name = strtolower($fld->name); 197 } 198 $fld->type = oci_field_type($this->_queryID, $fieldOffset); 199 $fld->max_length = oci_field_size($this->_queryID, $fieldOffset); 200 if ($fld->type == 'NUMBER') { 201 $sc = oci_field_scale($this->_queryID, $fieldOffset); 202 if ($sc == 0) { 203 $fld->type = 'INT'; 204 } 205 } 206 return $fld; 207 } 208 209 // 10% speedup to move MoveNext to child class 210 function MoveNext() 211 { 212 $ret = @oci_fetch_array($this->_queryID,$this->fetchMode); 213 if($ret !== false) { 214 global $ADODB_ANSI_PADDING_OFF; 215 $this->fields = $ret; 216 $this->_currentRow++; 217 $this->_updatefields(); 218 219 if (!empty($ADODB_ANSI_PADDING_OFF)) { 220 foreach($this->fields as $k => $v) { 221 if (is_string($v)) $this->fields[$k] = rtrim($v); 222 } 223 } 224 return true; 225 } 226 if (!$this->EOF) { 227 $this->EOF = true; 228 $this->_currentRow++; 229 } 230 return false; 231 } 232 233 function GetArrayLimit($nrows,$offset=-1) 234 { 235 if ($offset <= 0) { 236 $arr = $this->GetArray($nrows); 237 return $arr; 238 } 239 for ($i=1; $i < $offset; $i++) 240 if (!@oci_fetch($this->_queryID)) { 241 $arr = array(); 242 return $arr; 243 } 244 $ret = @oci_fetch_array($this->_queryID,$this->fetchMode); 245 if ($ret === false) { 246 $arr = array(); 247 return $arr; 248 } 249 $this->fields = $ret; 250 $this->_updatefields(); 251 $results = array(); 252 $cnt = 0; 253 while (!$this->EOF && $nrows != $cnt) { 254 $results[$cnt++] = $this->fields; 255 $this->MoveNext(); 256 } 257 258 return $results; 259 } 260 261 function _fetch() 262 { 263 global $ADODB_ANSI_PADDING_OFF; 264 265 $ret = @oci_fetch_array($this->_queryID,$this->fetchMode); 266 if ($ret) { 267 $this->fields = $ret; 268 $this->_updatefields(); 269 270 if (!empty($ADODB_ANSI_PADDING_OFF)) { 271 foreach($this->fields as $k => $v) { 272 if (is_string($v)) $this->fields[$k] = rtrim($v); 273 } 274 } 275 } 276 return $ret !== false; 277 } 278 279 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body