TYPO3 CMS  TYPO3_6-2
adodb-text.inc.php
Go to the documentation of this file.
1 <?php
2 /*
3 V5.19 23-Apr-2014 (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
4  Set tabs to 4.
5 */
6 
7 /*
8 Setup:
9 
10  $db = NewADOConnection('text');
11  $db->Connect($array,[$types],[$colnames]);
12 
13  Parameter $array is the 2 dimensional array of data. The first row can contain the
14  column names. If column names is not defined in first row, you MUST define $colnames,
15  the 3rd parameter.
16 
17  Parameter $types is optional. If defined, it should contain an array matching
18  the number of columns in $array, with each element matching the correct type defined
19  by MetaType: (B,C,I,L,N). If undefined, we will probe for $this->_proberows rows
20  to guess the type. Only C,I and N are recognised.
21 
22  Parameter $colnames is optional. If defined, it is an array that contains the
23  column names of $array. If undefined, we assume the first row of $array holds the
24  column names.
25 
26  The Execute() function will return a recordset. The recordset works like a normal recordset.
27  We have partial support for SQL parsing. We process the SQL using the following rules:
28 
29  1. SQL order by's always work for the first column ordered. Subsequent cols are ignored
30 
31  2. All operations take place on the same table. No joins possible. In fact the FROM clause
32  is ignored! You can use any name for the table.
33 
34  3. To simplify code, all columns are returned, except when selecting 1 column
35 
36  $rs = $db->Execute('select col1,col2 from table'); // sql ignored, will generate all cols
37 
38  We special case handling of 1 column because it is used in filter popups
39 
40  $rs = $db->Execute('select col1 from table');
41  // sql accepted and processed -- any table name is accepted
42 
43  $rs = $db->Execute('select distinct col1 from table');
44  // sql accepted and processed
45 
46 4. Where clauses are ignored, but searching with the 3rd parameter of Execute is permitted.
47  This has to use PHP syntax and we will eval() it. You can even use PHP functions.
48 
49  $rs = $db->Execute('select * from table',false,"\$COL1='abc' and $\COL2=3")
50  // the 3rd param is searched -- make sure that $COL1 is a legal column name
51  // and all column names must be in upper case.
52 
53 4. Group by, having, other clauses are ignored
54 
55 5. Expression columns, min(), max() are ignored
56 
57 6. All data is readonly. Only SELECTs permitted.
58 */
59 
60 // security - hide paths
61 if (!defined('ADODB_DIR')) die();
62 
63 if (! defined("_ADODB_TEXT_LAYER")) {
64  define("_ADODB_TEXT_LAYER", 1 );
65 
66 // for sorting in _query()
67 function adodb_cmp($a, $b) {
68  if ($a[0] == $b[0]) return 0;
69  return ($a[0] < $b[0]) ? -1 : 1;
70 }
71 // for sorting in _query()
72 function adodb_cmpr($a, $b) {
73  if ($a[0] == $b[0]) return 0;
74  return ($a[0] > $b[0]) ? -1 : 1;
75 }
76 class ADODB_text extends ADOConnection {
77  var $databaseType = 'text';
78 
79  var $_origarray; // original data
80  var $_types;
81  var $_proberows = 8;
82  var $_colnames;
83  var $_skiprow1=false;
84  var $readOnly = true;
85  var $hasTransactions = false;
86 
87  var $_rezarray;
88  var $_reznames;
89  var $_reztypes;
90 
91  function ADODB_text()
92  {
93  }
94 
95  function RSRecordCount()
96  {
97  if (!empty($this->_rezarray)) return sizeof($this->_rezarray);
98 
99  return sizeof($this->_origarray);
100  }
101 
102  function _insertid()
103  {
104  return false;
105  }
106 
107  function _affectedrows()
108  {
109  return false;
110  }
111 
112  // returns true or false
113  function PConnect(&$array, $types = false, $colnames = false)
114  {
115  return $this->Connect($array, $types, $colnames);
116  }
117  // returns true or false
118  function Connect(&$array, $types = false, $colnames = false)
119  {
120  if (is_string($array) and $array === 'iluvphplens') return 'me2';
121 
122  if (!$array) {
123  $this->_origarray = false;
124  return true;
125  }
126  $row = $array[0];
127  $cols = sizeof($row);
128 
129 
130  if ($colnames) $this->_colnames = $colnames;
131  else {
132  $this->_colnames = $array[0];
133  $this->_skiprow1 = true;
134  }
135  if (!$types) {
136  // probe and guess the type
137  $types = array();
138  $firstrow = true;
139  if ($this->_proberows > sizeof($array)) $max = sizeof($array);
140  else $max = $this->_proberows;
141  for ($j=($this->_skiprow1)?1:0;$j < $max; $j++) {
142  $row = $array[$j];
143  if (!$row) break;
144  $i = -1;
145  foreach($row as $v) {
146  $i += 1;
147  //print " ($i ".$types[$i]. "$v) ";
148  $v = trim($v);
149  if (!preg_match('/^[+-]{0,1}[0-9\.]+$/',$v)) {
150  $types[$i] = 'C'; // once C, always C
151  continue;
152  }
153  if (isset($types[$i]) && $types[$i]=='C') continue;
154  if ($firstrow) {
155  // If empty string, we presume is character
156  // test for integer for 1st row only
157  // after that it is up to testing other rows to prove
158  // that it is not an integer
159  if (strlen($v) == 0) $types[0] = 'C';
160  if (strpos($v,'.') !== false) $types[0] = 'N';
161  else $types[$i] = 'I';
162  continue;
163  }
164 
165  if (strpos($v,'.') !== false) $types[$i] = 'N';
166 
167  }
168  $firstrow = false;
169  }
170  }
171  //print_r($types);
172  $this->_origarray = $array;
173  $this->_types = $types;
174  return true;
175  }
176 
177 
178 
179  // returns queryID or false
180  // We presume that the select statement is on the same table (what else?),
181  // with the only difference being the order by.
182  //You can filter by using $eval and each clause is stored in $arr .eg. $arr[1] == 'name'
183  // also supports SELECT [DISTINCT] COL FROM ... -- only 1 col supported
184  function _query($sql,$input_arr,$eval=false)
185  {
186  if ($this->_origarray === false) return false;
187 
188  $eval = $this->evalAll;
189  $usql = strtoupper(trim($sql));
190  $usql = preg_replace("/[\t\n\r]/",' ',$usql);
191  $usql = preg_replace('/ *BY/i',' BY',strtoupper($usql));
192 
193  $eregword ='([A-Z_0-9]*)';
194  //print "<BR> $sql $eval ";
195  if ($eval) {
196  $i = 0;
197  foreach($this->_colnames as $n) {
198  $n = strtoupper(trim($n));
199  $eval = str_replace("\$$n","\$arr[$i]",$eval);
200 
201  $i += 1;
202  }
203 
204  $i = 0;
205  $eval = "\$rez=($eval);";
206  //print "<p>Eval string = $eval </p>";
207  $where_arr = array();
208 
209  reset($this->_origarray);
210  while (list($k_arr,$arr) = each($this->_origarray)) {
211 
212  if ($i == 0 && $this->_skiprow1)
213  $where_arr[] = $arr;
214  else {
215  eval($eval);
216  //print " $i: result=$rez arr[0]={$arr[0]} arr[1]={$arr[1]} <BR>\n ";
217  if ($rez) $where_arr[] = $arr;
218  }
219  $i += 1;
220  }
221  $this->_rezarray = $where_arr;
222  }else
223  $where_arr = $this->_origarray;
224 
225  // THIS PROJECTION CODE ONLY WORKS FOR 1 COLUMN,
226  // OTHERWISE IT RETURNS ALL COLUMNS
227  if (substr($usql,0,7) == 'SELECT ') {
228  $at = strpos($usql,' FROM ');
229  $sel = trim(substr($usql,7,$at-7));
230 
231  $distinct = false;
232  if (substr($sel,0,8) == 'DISTINCT') {
233  $distinct = true;
234  $sel = trim(substr($sel,8,$at));
235  }
236 
237  // $sel holds the selection clause, comma delimited
238  // currently we only project if one column is involved
239  // this is to support popups in PHPLens
240  if (strpos(',',$sel)===false) {
241  $colarr = array();
242 
243  preg_match("/$eregword/",$sel,$colarr);
244  $col = $colarr[1];
245  $i = 0;
246  $n = '';
247  reset($this->_colnames);
248  while (list($k_n,$n) = each($this->_colnames)) {
249 
250  if ($col == strtoupper(trim($n))) break;
251  $i += 1;
252  }
253 
254  if ($n && $col) {
255  $distarr = array();
256  $projarray = array();
257  $projtypes = array($this->_types[$i]);
258  $projnames = array($n);
259 
260  reset($where_arr);
261  while (list($k_a,$a) = each($where_arr)) {
262  if ($i == 0 && $this->_skiprow1) {
263  $projarray[] = array($n);
264  continue;
265  }
266 
267  if ($distinct) {
268  $v = strtoupper($a[$i]);
269  if (! $distarr[$v]) {
270  $projarray[] = array($a[$i]);
271  $distarr[$v] = 1;
272  }
273  } else
274  $projarray[] = array($a[$i]);
275 
276  } //foreach
277  //print_r($projarray);
278  }
279  } // check 1 column in projection
280  } // is SELECT
281 
282  if (empty($projarray)) {
283  $projtypes = $this->_types;
284  $projarray = $where_arr;
285  $projnames = $this->_colnames;
286  }
287  $this->_rezarray = $projarray;
288  $this->_reztypes = $projtypes;
289  $this->_reznames = $projnames;
290 
291 
292  $pos = strpos($usql,' ORDER BY ');
293  if ($pos === false) return $this;
294  $orderby = trim(substr($usql,$pos+10));
295 
296  preg_match("/$eregword/",$orderby,$arr);
297  if (sizeof($arr) < 2) return $this; // actually invalid sql
298  $col = $arr[1];
299  $at = (integer) $col;
300  if ($at == 0) {
301  $i = 0;
302  reset($projnames);
303  while (list($k_n,$n) = each($projnames)) {
304  if (strtoupper(trim($n)) == $col) {
305  $at = $i+1;
306  break;
307  }
308  $i += 1;
309  }
310  }
311 
312  if ($at <= 0 || $at > sizeof($projarray[0])) return $this; // cannot find sort column
313  $at -= 1;
314 
315  // generate sort array consisting of (sortval1, row index1) (sortval2, row index2)...
316  $sorta = array();
317  $t = $projtypes[$at];
318  $num = ($t == 'I' || $t == 'N');
319  for ($i=($this->_skiprow1)?1:0, $max = sizeof($projarray); $i < $max; $i++) {
320  $row = $projarray[$i];
321  $val = ($num)?(float)$row[$at]:$row[$at];
322  $sorta[]=array($val,$i);
323  }
324 
325  // check for desc sort
326  $orderby = substr($orderby,strlen($col)+1);
327  $arr == array();
328  preg_match('/([A-Z_0-9]*)/i',$orderby,$arr);
329 
330  if (trim($arr[1]) == 'DESC') $sortf = 'adodb_cmpr';
331  else $sortf = 'adodb_cmp';
332 
333  // hasta la sorta babe
334  usort($sorta, $sortf);
335 
336  // rearrange original array
337  $arr2 = array();
338  if ($this->_skiprow1) $arr2[] = $projarray[0];
339  foreach($sorta as $v) {
340  $arr2[] = $projarray[$v[1]];
341  }
342 
343  $this->_rezarray = $arr2;
344  return $this;
345  }
346 
347  /* Returns: the last error message from previous database operation */
348  function ErrorMsg()
349  {
350  return '';
351  }
352 
353  /* Returns: the last error number from previous database operation */
354  function ErrorNo()
355  {
356  return 0;
357  }
358 
359  // returns true or false
360  function _close()
361  {
362  }
363 
364 
365 }
366 
367 /*--------------------------------------------------------------------------------------
368  Class Name: Recordset
369 --------------------------------------------------------------------------------------*/
370 
371 
372 class ADORecordSet_text extends ADORecordSet_array
373 {
374 
375  var $databaseType = "text";
376 
377  function ADORecordSet_text(&$conn,$mode=false)
378  {
379  $this->ADORecordSet_array();
380  $this->InitArray($conn->_rezarray,$conn->_reztypes,$conn->_reznames);
381  $conn->_rezarray = false;
382  }
383 
384 } // class ADORecordSet_text
385 
386 
387 } // defined
$sql
Definition: server.php:82
$conn
Definition: server.php:79
die
Definition: index.php:6