See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
1 <?php 2 /* 3 @version v5.20.16 12-Jan-2020 4 @copyright (c) 2000-2013 John Lim. All rights reserved. 5 @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community 6 Released under both BSD license and Lesser GPL library license. 7 Whenever there is any discrepancy between the two licenses, 8 the BSD license will take precedence. 9 10 Latest version is available at http://adodb.org/ 11 12 Portable version of oci8 driver, to make it more similar to other database drivers. 13 The main differences are 14 15 1. that the OCI_ASSOC names are in lowercase instead of uppercase. 16 2. bind variables are mapped using ? instead of :<bindvar> 17 18 Should some emulation of RecordCount() be implemented? 19 20 */ 21 22 // security - hide paths 23 if (!defined('ADODB_DIR')) die(); 24 25 include_once(ADODB_DIR.'/drivers/adodb-oci8.inc.php'); 26 27 class ADODB_oci8po extends ADODB_oci8 { 28 var $databaseType = 'oci8po'; 29 var $dataProvider = 'oci8'; 30 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 31 var $metaTablesSQL = "select lower(table_name),table_type from cat where table_type in ('TABLE','VIEW')"; 32 33 function __construct() 34 { 35 $this->_hasOCIFetchStatement = ADODB_PHPVER >= 0x4200; 36 # oci8po does not support adodb extension: adodb_movenext() 37 } 38 39 function Param($name,$type='C') 40 { 41 return '?'; 42 } 43 44 function Prepare($sql,$cursor=false) 45 { 46 $sqlarr = explode('?',$sql); 47 $sql = $sqlarr[0]; 48 for ($i = 1, $max = sizeof($sqlarr); $i < $max; $i++) { 49 $sql .= ':'.($i-1) . $sqlarr[$i]; 50 } 51 return ADODB_oci8::Prepare($sql,$cursor); 52 } 53 54 function Execute($sql,$inputarr=false) 55 { 56 return ADOConnection::Execute($sql,$inputarr); 57 } 58 59 /** 60 * The optimizations performed by ADODB_oci8::SelectLimit() are not 61 * compatible with the oci8po driver, so we rely on the slower method 62 * from the base class. 63 * We can't properly handle prepared statements either due to preprocessing 64 * of query parameters, so we treat them as regular SQL statements. 65 */ 66 function SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs2cache=0) 67 { 68 if(is_array($sql)) { 69 // $sql = $sql[0]; 70 } 71 return ADOConnection::SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache); 72 } 73 74 // emulate handling of parameters ? ?, replacing with :bind0 :bind1 75 function _query($sql,$inputarr=false) 76 { 77 if (is_array($inputarr)) { 78 $i = 0; 79 if (is_array($sql)) { 80 foreach($inputarr as $v) { 81 $arr['bind'.$i++] = $v; 82 } 83 } else { 84 $sql = $this->extractBinds($sql,$inputarr); 85 } 86 } 87 return ADODB_oci8::_query($sql,$inputarr); 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 final 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 118 for ($i=0;$i<=$sqlLength;$i++) 119 { 120 /* 121 * find the next character of the string 122 */ 123 $c = $sql[$i]; 124 125 if ($c == "'" && !$inString && $escaped==0) 126 /* 127 * Found the start of a string inside the statement 128 */ 129 $inString = true; 130 elseif ($c == "\\" && $escaped==0) 131 /* 132 * The next character will be escaped 133 */ 134 $escaped = 1; 135 elseif ($c == "'" && $inString && $escaped==0) 136 /* 137 * We found the end of the string 138 */ 139 $inString = false; 140 141 if ($escaped == 2) 142 $escaped = 0; 143 144 if ($escaped==0 && !$inString && $c == '?') 145 /* 146 * We found a bind symbol, replace it with the oracle equivalent 147 */ 148 $newSql .= ':' . $inputKeys[$bindCount++]; 149 else 150 /* 151 * Add the current character the pile 152 */ 153 $newSql .= $c; 154 155 if ($escaped == 1) 156 /* 157 * We have just found an escape character, make sure we ignore the 158 * next one that comes along, it might be a ' character 159 */ 160 $escaped = 2; 161 } 162 163 return $newSql; 164 165 } 166 } 167 168 /*-------------------------------------------------------------------------------------- 169 Class Name: Recordset 170 --------------------------------------------------------------------------------------*/ 171 172 class ADORecordset_oci8po extends ADORecordset_oci8 { 173 174 var $databaseType = 'oci8po'; 175 176 function __construct($queryID,$mode=false) 177 { 178 parent::__construct($queryID,$mode); 179 } 180 181 function Fields($colname) 182 { 183 if ($this->fetchMode & OCI_ASSOC) return $this->fields[$colname]; 184 185 if (!$this->bind) { 186 $this->bind = array(); 187 for ($i=0; $i < $this->_numOfFields; $i++) { 188 $o = $this->FetchField($i); 189 $this->bind[strtoupper($o->name)] = $i; 190 } 191 } 192 return $this->fields[$this->bind[strtoupper($colname)]]; 193 } 194 195 // lowercase field names... 196 function _FetchField($fieldOffset = -1) 197 { 198 $fld = new ADOFieldObject; 199 $fieldOffset += 1; 200 $fld->name = OCIcolumnname($this->_queryID, $fieldOffset); 201 if (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_LOWER) { 202 $fld->name = strtolower($fld->name); 203 } 204 $fld->type = OCIcolumntype($this->_queryID, $fieldOffset); 205 $fld->max_length = OCIcolumnsize($this->_queryID, $fieldOffset); 206 if ($fld->type == 'NUMBER') { 207 $sc = OCIColumnScale($this->_queryID, $fieldOffset); 208 if ($sc == 0) { 209 $fld->type = 'INT'; 210 } 211 } 212 return $fld; 213 } 214 215 // 10% speedup to move MoveNext to child class 216 function MoveNext() 217 { 218 $ret = @oci_fetch_array($this->_queryID,$this->fetchMode); 219 if($ret !== false) { 220 global $ADODB_ANSI_PADDING_OFF; 221 $this->fields = $ret; 222 $this->_currentRow++; 223 $this->_updatefields(); 224 225 if (!empty($ADODB_ANSI_PADDING_OFF)) { 226 foreach($this->fields as $k => $v) { 227 if (is_string($v)) $this->fields[$k] = rtrim($v); 228 } 229 } 230 return true; 231 } 232 if (!$this->EOF) { 233 $this->EOF = true; 234 $this->_currentRow++; 235 } 236 return false; 237 } 238 239 /* Optimize SelectLimit() by using OCIFetch() instead of OCIFetchInto() */ 240 function GetArrayLimit($nrows,$offset=-1) 241 { 242 if ($offset <= 0) { 243 $arr = $this->GetArray($nrows); 244 return $arr; 245 } 246 for ($i=1; $i < $offset; $i++) 247 if (!@OCIFetch($this->_queryID)) { 248 $arr = array(); 249 return $arr; 250 } 251 $ret = @oci_fetch_array($this->_queryID,$this->fetchMode); 252 if ($ret === false) { 253 $arr = array(); 254 return $arr; 255 } 256 $this->fields = $ret; 257 $this->_updatefields(); 258 $results = array(); 259 $cnt = 0; 260 while (!$this->EOF && $nrows != $cnt) { 261 $results[$cnt++] = $this->fields; 262 $this->MoveNext(); 263 } 264 265 return $results; 266 } 267 268 function _fetch() 269 { 270 global $ADODB_ANSI_PADDING_OFF; 271 272 $ret = @oci_fetch_array($this->_queryID,$this->fetchMode); 273 if ($ret) { 274 $this->fields = $ret; 275 $this->_updatefields(); 276 277 if (!empty($ADODB_ANSI_PADDING_OFF)) { 278 foreach($this->fields as $k => $v) { 279 if (is_string($v)) $this->fields[$k] = rtrim($v); 280 } 281 } 282 } 283 return $ret !== false; 284 } 285 286 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body