7c6049bea03c8dd8da4dad5bdb44f7ffa1fc4f9d
[moodle.git] / lib / adodb / drivers / adodb-oci8po.inc.php
1 <?php
2 /*
3 @version   v5.20.3  01-Jan-2016
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.
10   Latest version is available at http://adodb.sourceforge.net
12   Portable version of oci8 driver, to make it more similar to other database drivers.
13   The main differences are
15    1. that the OCI_ASSOC names are in lowercase instead of uppercase.
16    2. bind variables are mapped using ? instead of :<bindvar>
18    Should some emulation of RecordCount() be implemented?
20 */
22 // security - hide paths
23 if (!defined('ADODB_DIR')) die();
25 include_once(ADODB_DIR.'/drivers/adodb-oci8.inc.php');
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')";
33         function __construct()
34         {
35                 $this->_hasOCIFetchStatement = ADODB_PHPVER >= 0x4200;
36                 # oci8po does not support adodb extension: adodb_movenext()
37         }
39         function Param($name,$type='C')
40         {
41                 return '?';
42         }
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         }
54         function Execute($sql,$inputarr=false)
55         {
56                 return ADOConnection::Execute($sql,$inputarr);
57         }
59         // emulate handling of parameters ? ?, replacing with :bind0 :bind1
60         function _query($sql,$inputarr=false)
61         {
62                 if (is_array($inputarr)) {
63                         $i = 0;
64                         if (is_array($sql)) {
65                                 foreach($inputarr as $v) {
66                                         $arr['bind'.$i++] = $v;
67                                 }
68                         } else {
69                                 // Need to identify if the ? is inside a quoted string, and if
70                                 // so not use it as a bind variable
71                                 preg_match_all('/".*\??"|\'.*\?.*?\'/', $sql, $matches);
72                                 foreach($matches[0] as $qmMatch){
73                                         $qmReplace = str_replace('?', '-QUESTIONMARK-', $qmMatch);
74                                         $sql = str_replace($qmMatch, $qmReplace, $sql);
75                                 }
77                                 $sqlarr = explode('?',$sql);
78                                 $sql = $sqlarr[0];
80                                 foreach($inputarr as $k => $v) {
81                                         $sql .=  ":$k" . $sqlarr[++$i];
82                                 }
84                                 $sql = str_replace('-QUESTIONMARK-', '?', $sql);
85                         }
86                 }
87                 return ADODB_oci8::_query($sql,$inputarr);
88         }
89 }
91 /*--------------------------------------------------------------------------------------
92                  Class Name: Recordset
93 --------------------------------------------------------------------------------------*/
95 class ADORecordset_oci8po extends ADORecordset_oci8 {
97         var $databaseType = 'oci8po';
99         function __construct($queryID,$mode=false)
100         {
101                 parent::__construct($queryID,$mode);
102         }
104         function Fields($colname)
105         {
106                 if ($this->fetchMode & OCI_ASSOC) return $this->fields[$colname];
108                 if (!$this->bind) {
109                         $this->bind = array();
110                         for ($i=0; $i < $this->_numOfFields; $i++) {
111                                 $o = $this->FetchField($i);
112                                 $this->bind[strtoupper($o->name)] = $i;
113                         }
114                 }
115                  return $this->fields[$this->bind[strtoupper($colname)]];
116         }
118         // lowercase field names...
119         function _FetchField($fieldOffset = -1)
120         {
121                 $fld = new ADOFieldObject;
122                 $fieldOffset += 1;
123                 $fld->name = OCIcolumnname($this->_queryID, $fieldOffset);
124                 if (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_LOWER) {
125                         $fld->name = strtolower($fld->name);
126                 }
127                 $fld->type = OCIcolumntype($this->_queryID, $fieldOffset);
128                 $fld->max_length = OCIcolumnsize($this->_queryID, $fieldOffset);
129                 if ($fld->type == 'NUMBER') {
130                         $sc = OCIColumnScale($this->_queryID, $fieldOffset);
131                         if ($sc == 0) {
132                                 $fld->type = 'INT';
133                         }
134                 }
135                 return $fld;
136         }
138         // 10% speedup to move MoveNext to child class
139         function MoveNext()
140         {
141                 if(@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode)) {
142                 global $ADODB_ANSI_PADDING_OFF;
143                         $this->_currentRow++;
144                         $this->_updatefields();
146                         if (!empty($ADODB_ANSI_PADDING_OFF)) {
147                                 foreach($this->fields as $k => $v) {
148                                         if (is_string($v)) $this->fields[$k] = rtrim($v);
149                                 }
150                         }
151                         return true;
152                 }
153                 if (!$this->EOF) {
154                         $this->EOF = true;
155                         $this->_currentRow++;
156                 }
157                 return false;
158         }
160         /* Optimize SelectLimit() by using OCIFetch() instead of OCIFetchInto() */
161         function GetArrayLimit($nrows,$offset=-1)
162         {
163                 if ($offset <= 0) {
164                         $arr = $this->GetArray($nrows);
165                         return $arr;
166                 }
167                 for ($i=1; $i < $offset; $i++)
168                         if (!@OCIFetch($this->_queryID)) {
169                                 $arr = array();
170                                 return $arr;
171                         }
172                 if (!@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode)) {
173                         $arr = array();
174                         return $arr;
175                 }
176                 $this->_updatefields();
177                 $results = array();
178                 $cnt = 0;
179                 while (!$this->EOF && $nrows != $cnt) {
180                         $results[$cnt++] = $this->fields;
181                         $this->MoveNext();
182                 }
184                 return $results;
185         }
187         function _fetch()
188         {
189                 global $ADODB_ANSI_PADDING_OFF;
191                 $ret = @OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode);
192                 if ($ret) {
193                         $this->_updatefields();
195                         if (!empty($ADODB_ANSI_PADDING_OFF)) {
196                                 foreach($this->fields as $k => $v) {
197                                         if (is_string($v)) $this->fields[$k] = rtrim($v);
198                                 }
199                         }
200                 }
201                 return $ret;
202         }