Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
	/**
74
	 * Execute a query.
75
	 *
76
	 * Emulate handling of parameters ? ?, replacing with :bind0 :bind1
77
	 *
78
	 * @param string|array $sql        Query to execute.
79
	 * @param array        $inputarr   An optional array of parameters.
80
	 *
81
	 * @return mixed|bool Query identifier or true if execution successful, false if failed.
82
	 */
83
	function _query($sql,$inputarr=false)
84
	{
85
		if (is_array($inputarr)) {
86
			$i = 0;
87
			if (is_array($sql)) {
88
				foreach($inputarr as $v) {
89
					$arr['bind'.$i++] = $v;
90
				}
91
			} else {
92
				$sql = $this->extractBinds($sql,$inputarr);
93
			}
94
		}
95
		return ADODB_oci8::_query($sql,$inputarr);
96
	}
97
 
98
	/**
99
	* Replaces compatibility bind markers with oracle ones and returns a
100
	* valid sql statement
101
	*
102
	* This replaces a regexp based section of code that has been subject
103
	* to numerous tweaks, as more extreme test cases have appeared. This
104
	* is now done this like this to help maintainability and avoid the
105
	* need to rely on regexp experienced maintainers
106
	*
107
	* @param	string		$sql		The sql statement
108
	* @param	string[]	$inputarr	The bind array
109
	*
110
	* @return	string	The modified statement
111
	*/
112
	private function extractBinds($sql,$inputarr)
113
	{
114
		$inString  = false;
115
		$escaped   = 0;
116
		$sqlLength = strlen($sql) - 1;
117
		$newSql    = '';
118
		$bindCount = 0;
119
 
120
		/*
121
		* inputarr is the passed in bind list, which is associative, but
122
		* we only want the keys here
123
		*/
124
		$inputKeys = array_keys($inputarr);
125
 
126
		for ($i=0;$i<=$sqlLength;$i++)
127
		{
128
			/*
129
			* find the next character of the string
130
			*/
131
			$c = $sql[$i];
132
 
133
			if ($c == "'" && !$inString && $escaped==0)
134
				/*
135
				* Found the start of a string inside the statement
136
				*/
137
				$inString = true;
138
			elseif ($c == "\\" && $escaped==0)
139
				/*
140
				* The next character will be escaped
141
				*/
142
				$escaped = 1;
143
			elseif ($c == "'" && $inString && $escaped==0)
144
				/*
145
				* We found the end of the string
146
				*/
147
				$inString = false;
148
 
149
			if ($escaped == 2)
150
				$escaped = 0;
151
 
152
			if ($escaped==0 && !$inString && $c == '?')
153
				/*
154
				* We found a bind symbol, replace it with the oracle equivalent
155
				*/
156
				$newSql .= ':' . $inputKeys[$bindCount++];
157
			else
158
				/*
159
				* Add the current character the pile
160
				*/
161
				$newSql .= $c;
162
 
163
			if ($escaped == 1)
164
				/*
165
				* We have just found an escape character, make sure we ignore the
166
				* next one that comes along, it might be a ' character
167
				*/
168
				$escaped = 2;
169
		}
170
 
171
		return $newSql;
172
 
173
	}
174
}
175
 
176
/*--------------------------------------------------------------------------------------
177
		 Class Name: Recordset
178
--------------------------------------------------------------------------------------*/
179
 
180
class ADORecordset_oci8po extends ADORecordset_oci8 {
181
 
182
	var $databaseType = 'oci8po';
183
 
184
	function Fields($colname)
185
	{
186
		if ($this->fetchMode & OCI_ASSOC) return $this->fields[$colname];
187
 
188
		if (!$this->bind) {
189
			$this->bind = array();
190
			for ($i=0; $i < $this->_numOfFields; $i++) {
191
				$o = $this->FetchField($i);
192
				$this->bind[strtoupper($o->name)] = $i;
193
			}
194
		}
195
		 return $this->fields[$this->bind[strtoupper($colname)]];
196
	}
197
 
198
	// lowercase field names...
199
	function _FetchField($fieldOffset = -1)
200
	{
201
		$fld = new ADOFieldObject;
202
		$fieldOffset += 1;
203
		$fld->name = oci_field_name($this->_queryID, $fieldOffset);
204
		if (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_LOWER) {
205
			$fld->name = strtolower($fld->name);
206
		}
207
		$fld->type = oci_field_type($this->_queryID, $fieldOffset);
208
		$fld->max_length = oci_field_size($this->_queryID, $fieldOffset);
209
		if ($fld->type == 'NUMBER') {
210
			$sc = oci_field_scale($this->_queryID, $fieldOffset);
211
			if ($sc == 0) {
212
				$fld->type = 'INT';
213
			}
214
		}
215
		return $fld;
216
	}
217
 
218
	// 10% speedup to move MoveNext to child class
219
	function MoveNext()
220
	{
221
		$ret = @oci_fetch_array($this->_queryID,$this->fetchMode);
222
		if($ret !== false) {
223
		global $ADODB_ANSI_PADDING_OFF;
224
			$this->fields = $ret;
225
			$this->_currentRow++;
226
			$this->_updatefields();
227
 
228
			if (!empty($ADODB_ANSI_PADDING_OFF)) {
229
				foreach($this->fields as $k => $v) {
230
					if (is_string($v)) $this->fields[$k] = rtrim($v);
231
				}
232
			}
233
			return true;
234
		}
235
		if (!$this->EOF) {
236
			$this->EOF = true;
237
			$this->_currentRow++;
238
		}
239
		return false;
240
	}
241
 
242
	function GetArrayLimit($nrows,$offset=-1)
243
	{
244
		if ($offset <= 0) {
245
			$arr = $this->GetArray($nrows);
246
			return $arr;
247
		}
248
		for ($i=1; $i < $offset; $i++)
249
			if (!@oci_fetch($this->_queryID)) {
250
				$arr = array();
251
				return $arr;
252
			}
253
		$ret = @oci_fetch_array($this->_queryID,$this->fetchMode);
254
		if ($ret === false) {
255
			$arr = array();
256
			return $arr;
257
		}
258
		$this->fields = $ret;
259
		$this->_updatefields();
260
		$results = array();
261
		$cnt = 0;
262
		while (!$this->EOF && $nrows != $cnt) {
263
			$results[$cnt++] = $this->fields;
264
			$this->MoveNext();
265
		}
266
 
267
		return $results;
268
	}
269
 
270
	function _fetch()
271
	{
272
		global $ADODB_ANSI_PADDING_OFF;
273
 
274
		$ret = @oci_fetch_array($this->_queryID,$this->fetchMode);
275
		if ($ret) {
276
			$this->fields = $ret;
277
			$this->_updatefields();
278
 
279
			if (!empty($ADODB_ANSI_PADDING_OFF)) {
280
				foreach($this->fields as $k => $v) {
281
					if (is_string($v)) $this->fields[$k] = rtrim($v);
282
				}
283
			}
284
		}
285
		return $ret !== false;
286
	}
287
 
288
}