Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
1 <?php 2 /* 3 @version v5.21.0 2021-02-27 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 https://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 Param($name,$type='C') 34 { 35 return '?'; 36 } 37 38 function Prepare($sql,$cursor=false) 39 { 40 $sqlarr = explode('?',$sql); 41 $sql = $sqlarr[0]; 42 for ($i = 1, $max = sizeof($sqlarr); $i < $max; $i++) { 43 $sql .= ':'.($i-1) . $sqlarr[$i]; 44 } 45 return ADODB_oci8::Prepare($sql,$cursor); 46 } 47 48 function Execute($sql,$inputarr=false) 49 { 50 return ADOConnection::Execute($sql,$inputarr); 51 } 52 53 /** 54 * The optimizations performed by ADODB_oci8::SelectLimit() are not 55 * compatible with the oci8po driver, so we rely on the slower method 56 * from the base class. 57 * We can't properly handle prepared statements either due to preprocessing 58 * of query parameters, so we treat them as regular SQL statements. 59 */ 60 function SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs2cache=0) 61 { 62 if(is_array($sql)) { 63 // $sql = $sql[0]; 64 } 65 return ADOConnection::SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache); 66 } 67 68 // emulate handling of parameters ? ?, replacing with :bind0 :bind1 69 function _query($sql,$inputarr=false) 70 { 71 if (is_array($inputarr)) { 72 $i = 0; 73 if (is_array($sql)) { 74 foreach($inputarr as $v) { 75 $arr['bind'.$i++] = $v; 76 } 77 } else { 78 $sql = $this->extractBinds($sql,$inputarr); 79 } 80 } 81 return ADODB_oci8::_query($sql,$inputarr); 82 } 83 84 /** 85 * Replaces compatibility bind markers with oracle ones and returns a 86 * valid sql statement 87 * 88 * This replaces a regexp based section of code that has been subject 89 * to numerous tweaks, as more extreme test cases have appeared. This 90 * is now done this like this to help maintainability and avoid the 91 * need to rely on regexp experienced maintainers 92 * 93 * @param string $sql The sql statement 94 * @param string[] $inputarr The bind array 95 * 96 * @return string The modified statement 97 */ 98 private function extractBinds($sql,$inputarr) 99 { 100 $inString = false; 101 $escaped = 0; 102 $sqlLength = strlen($sql) - 1; 103 $newSql = ''; 104 $bindCount = 0; 105 106 /* 107 * inputarr is the passed in bind list, which is associative, but 108 * we only want the keys here 109 */ 110 $inputKeys = array_keys($inputarr); 111 112 113 for ($i=0;$i<=$sqlLength;$i++) 114 { 115 /* 116 * find the next character of the string 117 */ 118 $c = $sql[$i]; 119 120 if ($c == "'" && !$inString && $escaped==0) 121 /* 122 * Found the start of a string inside the statement 123 */ 124 $inString = true; 125 elseif ($c == "\\" && $escaped==0) 126 /* 127 * The next character will be escaped 128 */ 129 $escaped = 1; 130 elseif ($c == "'" && $inString && $escaped==0) 131 /* 132 * We found the end of the string 133 */ 134 $inString = false; 135 136 if ($escaped == 2) 137 $escaped = 0; 138 139 if ($escaped==0 && !$inString && $c == '?') 140 /* 141 * We found a bind symbol, replace it with the oracle equivalent 142 */ 143 $newSql .= ':' . $inputKeys[$bindCount++]; 144 else 145 /* 146 * Add the current character the pile 147 */ 148 $newSql .= $c; 149 150 if ($escaped == 1) 151 /* 152 * We have just found an escape character, make sure we ignore the 153 * next one that comes along, it might be a ' character 154 */ 155 $escaped = 2; 156 } 157 158 return $newSql; 159 160 } 161 } 162 163 /*-------------------------------------------------------------------------------------- 164 Class Name: Recordset 165 --------------------------------------------------------------------------------------*/ 166 167 class ADORecordset_oci8po extends ADORecordset_oci8 { 168 169 var $databaseType = 'oci8po'; 170 171 function Fields($colname) 172 { 173 if ($this->fetchMode & OCI_ASSOC) return $this->fields[$colname]; 174 175 if (!$this->bind) { 176 $this->bind = array(); 177 for ($i=0; $i < $this->_numOfFields; $i++) { 178 $o = $this->FetchField($i); 179 $this->bind[strtoupper($o->name)] = $i; 180 } 181 } 182 return $this->fields[$this->bind[strtoupper($colname)]]; 183 } 184 185 // lowercase field names... 186 function _FetchField($fieldOffset = -1) 187 { 188 $fld = new ADOFieldObject; 189 $fieldOffset += 1; 190 $fld->name = OCIcolumnname($this->_queryID, $fieldOffset); 191 if (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_LOWER) { 192 $fld->name = strtolower($fld->name); 193 } 194 $fld->type = OCIcolumntype($this->_queryID, $fieldOffset); 195 $fld->max_length = OCIcolumnsize($this->_queryID, $fieldOffset); 196 if ($fld->type == 'NUMBER') { 197 $sc = OCIColumnScale($this->_queryID, $fieldOffset); 198 if ($sc == 0) { 199 $fld->type = 'INT'; 200 } 201 } 202 return $fld; 203 } 204 205 // 10% speedup to move MoveNext to child class 206 function MoveNext() 207 { 208 $ret = @oci_fetch_array($this->_queryID,$this->fetchMode); 209 if($ret !== false) { 210 global $ADODB_ANSI_PADDING_OFF; 211 $this->fields = $ret; 212 $this->_currentRow++; 213 $this->_updatefields(); 214 215 if (!empty($ADODB_ANSI_PADDING_OFF)) { 216 foreach($this->fields as $k => $v) { 217 if (is_string($v)) $this->fields[$k] = rtrim($v); 218 } 219 } 220 return true; 221 } 222 if (!$this->EOF) { 223 $this->EOF = true; 224 $this->_currentRow++; 225 } 226 return false; 227 } 228 229 /* Optimize SelectLimit() by using OCIFetch() instead of OCIFetchInto() */ 230 function GetArrayLimit($nrows,$offset=-1) 231 { 232 if ($offset <= 0) { 233 $arr = $this->GetArray($nrows); 234 return $arr; 235 } 236 for ($i=1; $i < $offset; $i++) 237 if (!@OCIFetch($this->_queryID)) { 238 $arr = array(); 239 return $arr; 240 } 241 $ret = @oci_fetch_array($this->_queryID,$this->fetchMode); 242 if ($ret === false) { 243 $arr = array(); 244 return $arr; 245 } 246 $this->fields = $ret; 247 $this->_updatefields(); 248 $results = array(); 249 $cnt = 0; 250 while (!$this->EOF && $nrows != $cnt) { 251 $results[$cnt++] = $this->fields; 252 $this->MoveNext(); 253 } 254 255 return $results; 256 } 257 258 function _fetch() 259 { 260 global $ADODB_ANSI_PADDING_OFF; 261 262 $ret = @oci_fetch_array($this->_queryID,$this->fetchMode); 263 if ($ret) { 264 $this->fields = $ret; 265 $this->_updatefields(); 266 267 if (!empty($ADODB_ANSI_PADDING_OFF)) { 268 foreach($this->fields as $k => $v) { 269 if (is_string($v)) $this->fields[$k] = rtrim($v); 270 } 271 } 272 } 273 return $ret !== false; 274 } 275 276 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body