on-demand release 4.5dev+
[moodle.git] / lib / adodb / drivers / adodb-text.inc.php
blob36a1a0d4dc46409eb560459f70f2de866377af6f
1 <?php
2 /**
3 * ADOdb Plain Text driver
5 * @deprecated
7 * This file is part of ADOdb, a Database Abstraction Layer library for PHP.
9 * @package ADOdb
10 * @link https://adodb.org Project's web site and documentation
11 * @link https://github.com/ADOdb/ADOdb Source code and issue tracker
13 * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause
14 * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option,
15 * any later version. This means you can use it in proprietary products.
16 * See the LICENSE.md file distributed with this source code for details.
17 * @license BSD-3-Clause
18 * @license LGPL-2.1-or-later
20 * @copyright 2000-2013 John Lim
21 * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
24 // security - hide paths
25 if (!defined('ADODB_DIR')) die();
27 if (! defined("_ADODB_TEXT_LAYER")) {
28 define("_ADODB_TEXT_LAYER", 1 );
30 // for sorting in _query()
31 function adodb_cmp($a, $b) {
32 if ($a[0] == $b[0]) return 0;
33 return ($a[0] < $b[0]) ? -1 : 1;
35 // for sorting in _query()
36 function adodb_cmpr($a, $b) {
37 if ($a[0] == $b[0]) return 0;
38 return ($a[0] > $b[0]) ? -1 : 1;
40 class ADODB_text extends ADOConnection {
41 var $databaseType = 'text';
43 var $_origarray; // original data
44 var $_types;
45 var $_proberows = 8;
46 var $_colnames;
47 var $_skiprow1=false;
48 var $readOnly = true;
49 var $hasTransactions = false;
51 var $_rezarray;
52 var $_reznames;
53 var $_reztypes;
55 function RSRecordCount()
57 if (!empty($this->_rezarray)) return sizeof($this->_rezarray);
59 return sizeof($this->_origarray);
62 function _affectedrows()
64 return false;
67 // returns true or false
68 function PConnect(&$array, $types = false, $colnames = false)
70 return $this->Connect($array, $types, $colnames);
72 // returns true or false
73 function Connect(&$array, $types = false, $colnames = false)
75 if (is_string($array) and $array === 'iluvphplens') return 'me2';
77 if (!$array) {
78 $this->_origarray = false;
79 return true;
81 $row = $array[0];
82 $cols = sizeof($row);
85 if ($colnames) $this->_colnames = $colnames;
86 else {
87 $this->_colnames = $array[0];
88 $this->_skiprow1 = true;
90 if (!$types) {
91 // probe and guess the type
92 $types = array();
93 $firstrow = true;
94 if ($this->_proberows > sizeof($array)) $max = sizeof($array);
95 else $max = $this->_proberows;
96 for ($j=($this->_skiprow1)?1:0;$j < $max; $j++) {
97 $row = $array[$j];
98 if (!$row) break;
99 $i = -1;
100 foreach($row as $v) {
101 $i += 1;
102 //print " ($i ".$types[$i]. "$v) ";
103 $v = trim($v);
104 if (!preg_match('/^[+-]{0,1}[0-9\.]+$/',$v)) {
105 $types[$i] = 'C'; // once C, always C
106 continue;
108 if (isset($types[$i]) && $types[$i]=='C') continue;
109 if ($firstrow) {
110 // If empty string, we presume is character
111 // test for integer for 1st row only
112 // after that it is up to testing other rows to prove
113 // that it is not an integer
114 if (strlen($v) == 0) $types[0] = 'C';
115 if (strpos($v,'.') !== false) $types[0] = 'N';
116 else $types[$i] = 'I';
117 continue;
120 if (strpos($v,'.') !== false) $types[$i] = 'N';
123 $firstrow = false;
126 //print_r($types);
127 $this->_origarray = $array;
128 $this->_types = $types;
129 return true;
133 * Execute a query.
135 * We presume that the select statement is on the same table (what else?),
136 * with the only difference being the order by.
137 * You can filter by using $eval and each clause is stored in $arr e.g. $arr[1] == 'name'
138 * also supports SELECT [DISTINCT] COL FROM ... -- only 1 col supported
140 * @param string|array $sql Query to execute.
141 * @param array $inputarr An optional array of parameters.
142 * @param string $eval Optional eval string
144 * @return mixed|bool Query identifier or true if execution successful, false if failed.
146 function _query($sql, $inputarr=false, $eval=false)
148 if ($this->_origarray === false) return false;
150 $eval = $this->evalAll;
151 $usql = strtoupper(trim($sql));
152 $usql = preg_replace("/[\t\n\r]/",' ',$usql);
153 $usql = preg_replace('/ *BY/i',' BY',strtoupper($usql));
155 $eregword ='([A-Z_0-9]*)';
156 //print "<BR> $sql $eval ";
157 if ($eval) {
158 $i = 0;
159 foreach($this->_colnames as $n) {
160 $n = strtoupper(trim($n));
161 $eval = str_replace("\$$n","\$arr[$i]",$eval);
163 $i += 1;
166 $i = 0;
167 $eval = "\$rez=($eval);";
168 //print "<p>Eval string = $eval </p>";
169 $where_arr = array();
171 reset($this->_origarray);
172 foreach ($this->_origarray as $arr) {
174 if ($i == 0 && $this->_skiprow1)
175 $where_arr[] = $arr;
176 else {
177 eval($eval);
178 //print " $i: result=$rez arr[0]={$arr[0]} arr[1]={$arr[1]} <BR>\n ";
179 if ($rez) $where_arr[] = $arr;
181 $i += 1;
183 $this->_rezarray = $where_arr;
184 }else
185 $where_arr = $this->_origarray;
187 // THIS PROJECTION CODE ONLY WORKS FOR 1 COLUMN,
188 // OTHERWISE IT RETURNS ALL COLUMNS
189 if (substr($usql,0,7) == 'SELECT ') {
190 $at = strpos($usql,' FROM ');
191 $sel = trim(substr($usql,7,$at-7));
193 $distinct = false;
194 if (substr($sel,0,8) == 'DISTINCT') {
195 $distinct = true;
196 $sel = trim(substr($sel,8,$at));
199 // $sel holds the selection clause, comma delimited
200 // currently we only project if one column is involved
201 // this is to support popups in PHPLens
202 if (strpos(',',$sel)===false) {
203 $colarr = array();
205 preg_match("/$eregword/",$sel,$colarr);
206 $col = $colarr[1];
207 $i = 0;
208 $n = '';
209 reset($this->_colnames);
210 foreach ($this->_colnames as $n) {
212 if ($col == strtoupper(trim($n))) break;
213 $i += 1;
216 if ($n && $col) {
217 $distarr = array();
218 $projarray = array();
219 $projtypes = array($this->_types[$i]);
220 $projnames = array($n);
222 foreach ($where_arr as $a) {
223 if ($i == 0 && $this->_skiprow1) {
224 $projarray[] = array($n);
225 continue;
228 if ($distinct) {
229 $v = strtoupper($a[$i]);
230 if (! $distarr[$v]) {
231 $projarray[] = array($a[$i]);
232 $distarr[$v] = 1;
234 } else
235 $projarray[] = array($a[$i]);
237 } //foreach
238 //print_r($projarray);
240 } // check 1 column in projection
241 } // is SELECT
243 if (empty($projarray)) {
244 $projtypes = $this->_types;
245 $projarray = $where_arr;
246 $projnames = $this->_colnames;
248 $this->_rezarray = $projarray;
249 $this->_reztypes = $projtypes;
250 $this->_reznames = $projnames;
253 $pos = strpos($usql,' ORDER BY ');
254 if ($pos === false) return $this;
255 $orderby = trim(substr($usql,$pos+10));
257 preg_match("/$eregword/",$orderby,$arr);
258 if (sizeof($arr) < 2) return $this; // actually invalid sql
259 $col = $arr[1];
260 $at = (integer) $col;
261 if ($at == 0) {
262 $i = 0;
263 reset($projnames);
264 foreach ($projnames as $n) {
265 if (strtoupper(trim($n)) == $col) {
266 $at = $i+1;
267 break;
269 $i += 1;
273 if ($at <= 0 || $at > sizeof($projarray[0])) return $this; // cannot find sort column
274 $at -= 1;
276 // generate sort array consisting of (sortval1, row index1) (sortval2, row index2)...
277 $sorta = array();
278 $t = $projtypes[$at];
279 $num = ($t == 'I' || $t == 'N');
280 for ($i=($this->_skiprow1)?1:0, $max = sizeof($projarray); $i < $max; $i++) {
281 $row = $projarray[$i];
282 $val = ($num)?(float)$row[$at]:$row[$at];
283 $sorta[]=array($val,$i);
286 // check for desc sort
287 $orderby = substr($orderby,strlen($col)+1);
288 $arr = array();
289 preg_match('/([A-Z_0-9]*)/i',$orderby,$arr);
291 if (trim($arr[1]) == 'DESC') $sortf = 'adodb_cmpr';
292 else $sortf = 'adodb_cmp';
294 // hasta la sorta babe
295 usort($sorta, $sortf);
297 // rearrange original array
298 $arr2 = array();
299 if ($this->_skiprow1) $arr2[] = $projarray[0];
300 foreach($sorta as $v) {
301 $arr2[] = $projarray[$v[1]];
304 $this->_rezarray = $arr2;
305 return $this;
308 /* Returns: the last error message from previous database operation */
309 function ErrorMsg()
311 return '';
314 /* Returns: the last error number from previous database operation */
315 function ErrorNo()
317 return 0;
320 // returns true or false
321 function _close()
328 /*--------------------------------------------------------------------------------------
329 Class Name: Recordset
330 --------------------------------------------------------------------------------------*/
333 class ADORecordSet_text extends ADORecordSet_array
336 var $databaseType = "text";
338 function __construct( $conn,$mode=false)
340 parent::__construct();
341 $this->InitArray($conn->_rezarray,$conn->_reztypes,$conn->_reznames);
342 $conn->_rezarray = false;
345 } // class ADORecordSet_text
348 } // defined