TYPO3 CMS  TYPO3_6-2
adodb-lib.inc.php
Go to the documentation of this file.
1 <?php
2 // security - hide paths
3 if (!defined('ADODB_DIR')) die();
4 
6 $ADODB_INCLUDED_LIB = 1;
7 
8 /*
9  @version V5.19 23-Apr-2014 (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
10  Released under both BSD license and Lesser GPL library license.
11  Whenever there is any discrepancy between the two licenses,
12  the BSD license will take precedence. See License.txt.
13  Set tabs to 4 for best viewing.
14 
15  Less commonly used functions are placed here to reduce size of adodb.inc.php.
16 */
17 
19 {
20  $rez = preg_match('/(\sORDER\s+BY\s(?:[^)](?!limit))*)(?:\sLIMIT\s+[0-9]+)?/is', $sql, $arr);
21  if ($arr)
22  if (strpos($arr[1], '(') !== false) {
23  $at = strpos($sql, $arr[1]);
24  $cntin = 0;
25  for ($i=$at, $max=strlen($sql); $i < $max; $i++) {
26  $ch = $sql[$i];
27  if ($ch == '(') {
28  $cntin += 1;
29  } elseif($ch == ')') {
30  $cntin -= 1;
31  if ($cntin < 0) {
32  break;
33  }
34  }
35  }
36  $sql = substr($sql,0,$at).substr($sql,$i);
37  } else {
38  $sql = str_replace($arr[1], '', $sql);
39  }
40  return $sql;
41  }
42 
43 if (false) {
44  $sql = 'select * from (select a from b order by a(b),b(c) desc)';
45  $sql = '(select * from abc order by 1)';
47 }
48 
49 function adodb_probetypes(&$array,&$types,$probe=8)
50 {
51 // probe and guess the type
52  $types = array();
53  if ($probe > sizeof($array)) $max = sizeof($array);
54  else $max = $probe;
55 
56 
57  for ($j=0;$j < $max; $j++) {
58  $row = $array[$j];
59  if (!$row) break;
60  $i = -1;
61  foreach($row as $v) {
62  $i += 1;
63 
64  if (isset($types[$i]) && $types[$i]=='C') continue;
65 
66  //print " ($i ".$types[$i]. "$v) ";
67  $v = trim($v);
68 
69  if (!preg_match('/^[+-]{0,1}[0-9\.]+$/',$v)) {
70  $types[$i] = 'C'; // once C, always C
71 
72  continue;
73  }
74  if ($j == 0) {
75  // If empty string, we presume is character
76  // test for integer for 1st row only
77  // after that it is up to testing other rows to prove
78  // that it is not an integer
79  if (strlen($v) == 0) $types[$i] = 'C';
80  if (strpos($v,'.') !== false) $types[$i] = 'N';
81  else $types[$i] = 'I';
82  continue;
83  }
84 
85  if (strpos($v,'.') !== false) $types[$i] = 'N';
86 
87  }
88  }
89 
90 }
91 
92 function adodb_transpose(&$arr, &$newarr, &$hdr, &$fobjs)
93 {
94  $oldX = sizeof(reset($arr));
95  $oldY = sizeof($arr);
96 
97  if ($hdr) {
98  $startx = 1;
99  $hdr = array('Fields');
100  for ($y = 0; $y < $oldY; $y++) {
101  $hdr[] = $arr[$y][0];
102  }
103  } else
104  $startx = 0;
105 
106  for ($x = $startx; $x < $oldX; $x++) {
107  if ($fobjs) {
108  $o = $fobjs[$x];
109  $newarr[] = array($o->name);
110  } else
111  $newarr[] = array();
112 
113  for ($y = 0; $y < $oldY; $y++) {
114  $newarr[$x-$startx][] = $arr[$y][$x];
115  }
116  }
117 }
118 
119 // Force key to upper.
120 // See also http://www.php.net/manual/en/function.array-change-key-case.php
121 function _array_change_key_case($an_array)
122 {
123  if (is_array($an_array)) {
124  $new_array = array();
125  foreach($an_array as $key=>$value)
126  $new_array[strtoupper($key)] = $value;
127 
128  return $new_array;
129  }
130 
131  return $an_array;
132 }
133 
134 function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc)
135 {
136  if (count($fieldArray) == 0) return 0;
137  $first = true;
138  $uSet = '';
139 
140  if (!is_array($keyCol)) {
141  $keyCol = array($keyCol);
142  }
143  foreach($fieldArray as $k => $v) {
144  if ($v === null) {
145  $v = 'NULL';
146  $fieldArray[$k] = $v;
147  } else if ($autoQuote && strcasecmp($v,$zthis->null2null)!=0) {
148  $v = $zthis->qstr($v);
149  $fieldArray[$k] = $v;
150  }
151  if (in_array($k,$keyCol)) continue; // skip UPDATE if is key
152 
153  if ($first) {
154  $first = false;
155  $uSet = "$k=$v";
156  } else
157  $uSet .= ",$k=$v";
158  }
159 
160  $where = false;
161  foreach ($keyCol as $v) {
162  if (isset($fieldArray[$v])) {
163  if ($where) $where .= ' and '.$v.'='.$fieldArray[$v];
164  else $where = $v.'='.$fieldArray[$v];
165  }
166  }
167 
168  if ($uSet && $where) {
169  $update = "UPDATE $table SET $uSet WHERE $where";
170 
171  $rs = $zthis->Execute($update);
172 
173 
174  if ($rs) {
175  if ($zthis->poorAffectedRows) {
176  /*
177  The Select count(*) wipes out any errors that the update would have returned.
178  http://phplens.com/lens/lensforum/msgs.php?id=5696
179  */
180  if ($zthis->ErrorNo()<>0) return 0;
181 
182  # affected_rows == 0 if update field values identical to old values
183  # for mysql - which is silly.
184 
185  $cnt = $zthis->GetOne("select count(*) from $table where $where");
186  if ($cnt > 0) return 1; // record already exists
187  } else {
188  if (($zthis->Affected_Rows()>0)) return 1;
189  }
190  } else
191  return 0;
192  }
193 
194  // print "<p>Error=".$this->ErrorNo().'<p>';
195  $first = true;
196  foreach($fieldArray as $k => $v) {
197  if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
198 
199  if ($first) {
200  $first = false;
201  $iCols = "$k";
202  $iVals = "$v";
203  } else {
204  $iCols .= ",$k";
205  $iVals .= ",$v";
206  }
207  }
208  $insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
209  $rs = $zthis->Execute($insert);
210  return ($rs) ? 2 : 0;
211 }
212 
213 // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
214 function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
215  $size=0, $selectAttr='',$compareFields0=true)
216 {
217  $hasvalue = false;
218 
219  if ($multiple or is_array($defstr)) {
220  if ($size==0) $size=5;
221  $attr = ' multiple size="'.$size.'"';
222  if (!strpos($name,'[]')) $name .= '[]';
223  } else if ($size) $attr = ' size="'.$size.'"';
224  else $attr ='';
225 
226  $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
227  if ($blank1stItem)
228  if (is_string($blank1stItem)) {
229  $barr = explode(':',$blank1stItem);
230  if (sizeof($barr) == 1) $barr[] = '';
231  $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
232  } else $s .= "\n<option></option>";
233 
234  if ($zthis->FieldCount() > 1) $hasvalue=true;
235  else $compareFields0 = true;
236 
237  $value = '';
238  $optgroup = null;
239  $firstgroup = true;
240  $fieldsize = $zthis->FieldCount();
241  while(!$zthis->EOF) {
242  $zval = rtrim(reset($zthis->fields));
243 
244  if ($blank1stItem && $zval=="") {
245  $zthis->MoveNext();
246  continue;
247  }
248 
249  if ($fieldsize > 1) {
250  if (isset($zthis->fields[1]))
251  $zval2 = rtrim($zthis->fields[1]);
252  else
253  $zval2 = rtrim(next($zthis->fields));
254  }
255  $selected = ($compareFields0) ? $zval : $zval2;
256 
257  $group = '';
258  if ($fieldsize > 2) {
259  $group = rtrim($zthis->fields[2]);
260  }
261 /*
262  if ($optgroup != $group) {
263  $optgroup = $group;
264  if ($firstgroup) {
265  $firstgroup = false;
266  $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
267  } else {
268  $s .="\n</optgroup>";
269  $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
270  }
271  }
272 */
273  if ($hasvalue)
274  $value = " value='".htmlspecialchars($zval2)."'";
275 
276  if (is_array($defstr)) {
277 
278  if (in_array($selected,$defstr))
279  $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
280  else
281  $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
282  }
283  else {
284  if (strcasecmp($selected,$defstr)==0)
285  $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
286  else
287  $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
288  }
289  $zthis->MoveNext();
290  } // while
291 
292  // closing last optgroup
293  if($optgroup != null) {
294  $s .= "\n</optgroup>";
295  }
296  return $s ."\n</select>\n";
297 }
298 
299 // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
300 function _adodb_getmenu_gp(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
301  $size=0, $selectAttr='',$compareFields0=true)
302 {
303  $hasvalue = false;
304 
305  if ($multiple or is_array($defstr)) {
306  if ($size==0) $size=5;
307  $attr = ' multiple size="'.$size.'"';
308  if (!strpos($name,'[]')) $name .= '[]';
309  } else if ($size) $attr = ' size="'.$size.'"';
310  else $attr ='';
311 
312  $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
313  if ($blank1stItem)
314  if (is_string($blank1stItem)) {
315  $barr = explode(':',$blank1stItem);
316  if (sizeof($barr) == 1) $barr[] = '';
317  $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
318  } else $s .= "\n<option></option>";
319 
320  if ($zthis->FieldCount() > 1) $hasvalue=true;
321  else $compareFields0 = true;
322 
323  $value = '';
324  $optgroup = null;
325  $firstgroup = true;
326  $fieldsize = sizeof($zthis->fields);
327  while(!$zthis->EOF) {
328  $zval = rtrim(reset($zthis->fields));
329 
330  if ($blank1stItem && $zval=="") {
331  $zthis->MoveNext();
332  continue;
333  }
334 
335  if ($fieldsize > 1) {
336  if (isset($zthis->fields[1]))
337  $zval2 = rtrim($zthis->fields[1]);
338  else
339  $zval2 = rtrim(next($zthis->fields));
340  }
341  $selected = ($compareFields0) ? $zval : $zval2;
342 
343  $group = '';
344  if (isset($zthis->fields[2])) {
345  $group = rtrim($zthis->fields[2]);
346  }
347 
348  if ($optgroup != $group) {
349  $optgroup = $group;
350  if ($firstgroup) {
351  $firstgroup = false;
352  $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
353  } else {
354  $s .="\n</optgroup>";
355  $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
356  }
357  }
358 
359  if ($hasvalue)
360  $value = " value='".htmlspecialchars($zval2)."'";
361 
362  if (is_array($defstr)) {
363 
364  if (in_array($selected,$defstr))
365  $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
366  else
367  $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
368  }
369  else {
370  if (strcasecmp($selected,$defstr)==0)
371  $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
372  else
373  $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
374  }
375  $zthis->MoveNext();
376  } // while
377 
378  // closing last optgroup
379  if($optgroup != null) {
380  $s .= "\n</optgroup>";
381  }
382  return $s ."\n</select>\n";
383 }
384 
385 
386 /*
387  Count the number of records this sql statement will return by using
388  query rewriting heuristics...
389 
390  Does not work with UNIONs, except with postgresql and oracle.
391 
392  Usage:
393 
394  $conn->Connect(...);
395  $cnt = _adodb_getcount($conn, $sql);
396 
397 */
398 function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
399 {
400  $qryRecs = 0;
401 
402  if (!empty($zthis->_nestedSQL) || preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) ||
403  preg_match('/\s+GROUP\s+BY\s+/is',$sql) ||
404  preg_match('/\s+UNION\s+/is',$sql)) {
405 
406  $rewritesql = adodb_strip_order_by($sql);
407 
408  // ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias
409  // but this is only supported by oracle and postgresql...
410  if ($zthis->dataProvider == 'oci8') {
411  // Allow Oracle hints to be used for query optimization, Chris Wrye
412  if (preg_match('#/\\*+.*?\\*\\/#', $sql, $hint)) {
413  $rewritesql = "SELECT ".$hint[0]." COUNT(*) FROM (".$rewritesql.")";
414  } else
415  $rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")";
416 
417  } else if (strncmp($zthis->databaseType,'postgres',8) == 0 || strncmp($zthis->databaseType,'mysql',5) == 0) {
418  $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
419  } else {
420  $rewritesql = "SELECT COUNT(*) FROM ($rewritesql)";
421  }
422  } else {
423  // now replace SELECT ... FROM with SELECT COUNT(*) FROM
424  $rewritesql = preg_replace(
425  '/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql);
426  // fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails
427  // with mssql, access and postgresql. Also a good speedup optimization - skips sorting!
428  // also see http://phplens.com/lens/lensforum/msgs.php?id=12752
429  $rewritesql = adodb_strip_order_by($rewritesql);
430  }
431 
432  if (isset($rewritesql) && $rewritesql != $sql) {
433  if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
434 
435  if ($secs2cache) {
436  // we only use half the time of secs2cache because the count can quickly
437  // become inaccurate if new records are added
438  $qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr);
439 
440  } else {
441  $qryRecs = $zthis->GetOne($rewritesql,$inputarr);
442  }
443  if ($qryRecs !== false) return $qryRecs;
444  }
445  //--------------------------------------------
446  // query rewrite failed - so try slower way...
447 
448 
449  // strip off unneeded ORDER BY if no UNION
450  if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql;
451  else $rewritesql = $rewritesql = adodb_strip_order_by($sql);
452 
453  if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
454 
455  if ($secs2cache) {
456  $rstest = $zthis->CacheExecute($secs2cache,$rewritesql,$inputarr);
457  if (!$rstest) $rstest = $zthis->CacheExecute($secs2cache,$sql,$inputarr);
458  } else {
459  $rstest = $zthis->Execute($rewritesql,$inputarr);
460  if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr);
461  }
462  if ($rstest) {
463  $qryRecs = $rstest->RecordCount();
464  if ($qryRecs == -1) {
465  global $ADODB_EXTENSION;
466  // some databases will return -1 on MoveLast() - change to MoveNext()
467  if ($ADODB_EXTENSION) {
468  while(!$rstest->EOF) {
469  adodb_movenext($rstest);
470  }
471  } else {
472  while(!$rstest->EOF) {
473  $rstest->MoveNext();
474  }
475  }
476  $qryRecs = $rstest->_currentRow;
477  }
478  $rstest->Close();
479  if ($qryRecs == -1) return 0;
480  }
481  return $qryRecs;
482 }
483 
484 /*
485  Code originally from "Cornel G" <conyg@fx.ro>
486 
487  This code might not work with SQL that has UNION in it
488 
489  Also if you are using CachePageExecute(), there is a strong possibility that
490  data will get out of synch. use CachePageExecute() only with tables that
491  rarely change.
492 */
493 function _adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
494  $inputarr=false, $secs2cache=0)
495 {
496  $atfirstpage = false;
497  $atlastpage = false;
498  $lastpageno=1;
499 
500  // If an invalid nrows is supplied,
501  // we assume a default value of 10 rows per page
502  if (!isset($nrows) || $nrows <= 0) $nrows = 10;
503 
504  $qryRecs = false; //count records for no offset
505 
506  $qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache);
507  $lastpageno = (int) ceil($qryRecs / $nrows);
508  $zthis->_maxRecordCount = $qryRecs;
509 
510 
511 
512  // ***** Here we check whether $page is the last page or
513  // whether we are trying to retrieve
514  // a page number greater than the last page number.
515  if ($page >= $lastpageno) {
516  $page = $lastpageno;
517  $atlastpage = true;
518  }
519 
520  // If page number <= 1, then we are at the first page
521  if (empty($page) || $page <= 1) {
522  $page = 1;
523  $atfirstpage = true;
524  }
525 
526  // We get the data we want
527  $offset = $nrows * ($page-1);
528  if ($secs2cache > 0)
529  $rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
530  else
531  $rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
532 
533 
534  // Before returning the RecordSet, we set the pagination properties we need
535  if ($rsreturn) {
536  $rsreturn->_maxRecordCount = $qryRecs;
537  $rsreturn->rowsPerPage = $nrows;
538  $rsreturn->AbsolutePage($page);
539  $rsreturn->AtFirstPage($atfirstpage);
540  $rsreturn->AtLastPage($atlastpage);
541  $rsreturn->LastPageNo($lastpageno);
542  }
543  return $rsreturn;
544 }
545 
546 // Iván Oliva version
547 function _adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
548 {
549 
550  $atfirstpage = false;
551  $atlastpage = false;
552 
553  if (!isset($page) || $page <= 1) { // If page number <= 1, then we are at the first page
554  $page = 1;
555  $atfirstpage = true;
556  }
557  if ($nrows <= 0) $nrows = 10; // If an invalid nrows is supplied, we assume a default value of 10 rows per page
558 
559  // ***** Here we check whether $page is the last page or whether we are trying to retrieve a page number greater than
560  // the last page number.
561  $pagecounter = $page + 1;
562  $pagecounteroffset = ($pagecounter * $nrows) - $nrows;
563  if ($secs2cache>0) $rstest = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
564  else $rstest = $zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
565  if ($rstest) {
566  while ($rstest && $rstest->EOF && $pagecounter>0) {
567  $atlastpage = true;
568  $pagecounter--;
569  $pagecounteroffset = $nrows * ($pagecounter - 1);
570  $rstest->Close();
571  if ($secs2cache>0) $rstest = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
572  else $rstest = $zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
573  }
574  if ($rstest) $rstest->Close();
575  }
576  if ($atlastpage) { // If we are at the last page or beyond it, we are going to retrieve it
577  $page = $pagecounter;
578  if ($page == 1) $atfirstpage = true; // We have to do this again in case the last page is the same as the first
579  //... page, that is, the recordset has only 1 page.
580  }
581 
582  // We get the data we want
583  $offset = $nrows * ($page-1);
584  if ($secs2cache > 0) $rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
585  else $rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
586 
587  // Before returning the RecordSet, we set the pagination properties we need
588  if ($rsreturn) {
589  $rsreturn->rowsPerPage = $nrows;
590  $rsreturn->AbsolutePage($page);
591  $rsreturn->AtFirstPage($atfirstpage);
592  $rsreturn->AtLastPage($atlastpage);
593  }
594  return $rsreturn;
595 }
596 
597 function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2)
598 {
599  global $ADODB_QUOTE_FIELDNAMES;
600 
601  if (!$rs) {
602  printf(ADODB_BAD_RS,'GetUpdateSQL');
603  return false;
604  }
605 
606  $fieldUpdatedCount = 0;
607  $arrFields = _array_change_key_case($arrFields);
608 
609  $hasnumeric = isset($rs->fields[0]);
610  $setFields = '';
611 
612  // Loop through all of the fields in the recordset
613  for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
614  // Get the field from the recordset
615  $field = $rs->FetchField($i);
616 
617  // If the recordset field is one
618  // of the fields passed in then process.
619  $upperfname = strtoupper($field->name);
620  if (adodb_key_exists($upperfname,$arrFields,$force)) {
621 
622  // If the existing field value in the recordset
623  // is different from the value passed in then
624  // go ahead and append the field name and new value to
625  // the update query.
626 
627  if ($hasnumeric) $val = $rs->fields[$i];
628  else if (isset($rs->fields[$upperfname])) $val = $rs->fields[$upperfname];
629  else if (isset($rs->fields[$field->name])) $val = $rs->fields[$field->name];
630  else if (isset($rs->fields[strtolower($upperfname)])) $val = $rs->fields[strtolower($upperfname)];
631  else $val = '';
632 
633 
634  if ($forceUpdate || strcmp($val, $arrFields[$upperfname])) {
635  // Set the counter for the number of fields that will be updated.
636  $fieldUpdatedCount++;
637 
638  // Based on the datatype of the field
639  // Format the value properly for the database
640  $type = $rs->MetaType($field->type);
641 
642 
643  if ($type == 'null') {
644  $type = 'C';
645  }
646 
647  if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) {
648  switch ($ADODB_QUOTE_FIELDNAMES) {
649  case 'LOWER':
650  $fnameq = $zthis->nameQuote.strtolower($field->name).$zthis->nameQuote;break;
651  case 'NATIVE':
652  $fnameq = $zthis->nameQuote.$field->name.$zthis->nameQuote;break;
653  case 'UPPER':
654  default:
655  $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;break;
656  }
657  } else
658  $fnameq = $upperfname;
659 
660  //********************************************************//
661  if (is_null($arrFields[$upperfname])
662  || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
663  || $arrFields[$upperfname] === $zthis->null2null
664  )
665  {
666  switch ($force) {
667 
668  //case 0:
669  // //Ignore empty values. This is allready handled in "adodb_key_exists" function.
670  //break;
671 
672  case 1:
673  //Set null
674  $setFields .= $field->name . " = null, ";
675  break;
676 
677  case 2:
678  //Set empty
679  $arrFields[$upperfname] = "";
680  $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
681  break;
682  default:
683  case 3:
684  //Set the value that was given in array, so you can give both null and empty values
685  if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) {
686  $setFields .= $field->name . " = null, ";
687  } else {
688  $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
689  }
690  break;
691  }
692  //********************************************************//
693  } else {
694  //we do this so each driver can customize the sql for
695  //DB specific column types.
696  //Oracle needs BLOB types to be handled with a returning clause
697  //postgres has special needs as well
698  $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
699  $arrFields, $magicq);
700  }
701  }
702  }
703  }
704 
705  // If there were any modified fields then build the rest of the update query.
706  if ($fieldUpdatedCount > 0 || $forceUpdate) {
707  // Get the table name from the existing query.
708  if (!empty($rs->tableName)) $tableName = $rs->tableName;
709  else {
710  preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
711  $tableName = $tableName[1];
712  }
713  // Get the full where clause excluding the word "WHERE" from
714  // the existing query.
715  preg_match('/\sWHERE\s(.*)/is', $rs->sql, $whereClause);
716 
717  $discard = false;
718  // not a good hack, improvements?
719  if ($whereClause) {
720  #var_dump($whereClause);
721  if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
722  else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard));
723  else if (preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard));
724  else preg_match('/\s.*(\) WHERE .*)/is', $whereClause[1], $discard); # see http://sourceforge.net/tracker/index.php?func=detail&aid=1379638&group_id=42718&atid=433976
725  } else
726  $whereClause = array(false,false);
727 
728  if ($discard)
729  $whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
730 
731  $sql = 'UPDATE '.$tableName.' SET '.substr($setFields, 0, -2);
732  if (strlen($whereClause[1]) > 0)
733  $sql .= ' WHERE '.$whereClause[1];
734 
735  return $sql;
736 
737  } else {
738  return false;
739  }
740 }
741 
742 function adodb_key_exists($key, &$arr,$force=2)
743 {
744  if ($force<=0) {
745  // the following is the old behaviour where null or empty fields are ignored
746  return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0);
747  }
748 
749  if (isset($arr[$key])) return true;
750  ## null check below
751  if (ADODB_PHPVER >= 0x4010) return array_key_exists($key,$arr);
752  return false;
753 }
754 
762 function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2)
763 {
764 static $cacheRS = false;
765 static $cacheSig = 0;
766 static $cacheCols;
767  global $ADODB_QUOTE_FIELDNAMES;
768 
769  $tableName = '';
770  $values = '';
771  $fields = '';
772  $recordSet = null;
773  $arrFields = _array_change_key_case($arrFields);
774  $fieldInsertedCount = 0;
775 
776  if (is_string($rs)) {
777  //ok we have a table name
778  //try and get the column info ourself.
779  $tableName = $rs;
780 
781  //we need an object for the recordSet
782  //because we have to call MetaType.
783  //php can't do a $rsclass::MetaType()
784  $rsclass = $zthis->rsPrefix.$zthis->databaseType;
785  $recordSet = new $rsclass(-1,$zthis->fetchMode);
786  $recordSet->connection = $zthis;
787 
788  if (is_string($cacheRS) && $cacheRS == $rs) {
789  $columns = $cacheCols;
790  } else {
791  $columns = $zthis->MetaColumns( $tableName );
792  $cacheRS = $tableName;
793  $cacheCols = $columns;
794  }
795  } else if (is_subclass_of($rs, 'adorecordset')) {
796  if (isset($rs->insertSig) && is_integer($cacheRS) && $cacheRS == $rs->insertSig) {
797  $columns = $cacheCols;
798  } else {
799  for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++)
800  $columns[] = $rs->FetchField($i);
801  $cacheRS = $cacheSig;
802  $cacheCols = $columns;
803  $rs->insertSig = $cacheSig++;
804  }
805  $recordSet = $rs;
806 
807  } else {
808  printf(ADODB_BAD_RS,'GetInsertSQL');
809  return false;
810  }
811 
812  // Loop through all of the fields in the recordset
813  foreach( $columns as $field ) {
814  $upperfname = strtoupper($field->name);
815  if (adodb_key_exists($upperfname,$arrFields,$force)) {
816  $bad = false;
817  if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) {
818  switch ($ADODB_QUOTE_FIELDNAMES) {
819  case 'LOWER':
820  $fnameq = $zthis->nameQuote.strtolower($field->name).$zthis->nameQuote;break;
821  case 'NATIVE':
822  $fnameq = $zthis->nameQuote.$field->name.$zthis->nameQuote;break;
823  case 'UPPER':
824  default:
825  $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;break;
826  }
827  } else
828  $fnameq = $upperfname;
829 
830  $type = $recordSet->MetaType($field->type);
831 
832  /********************************************************/
833  if (is_null($arrFields[$upperfname])
834  || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
835  || $arrFields[$upperfname] === $zthis->null2null
836  )
837  {
838  switch ($force) {
839 
840  case 0: // we must always set null if missing
841  $bad = true;
842  break;
843 
844  case 1:
845  $values .= "null, ";
846  break;
847 
848  case 2:
849  //Set empty
850  $arrFields[$upperfname] = "";
851  $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq);
852  break;
853 
854  default:
855  case 3:
856  //Set the value that was given in array, so you can give both null and empty values
857  if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) {
858  $values .= "null, ";
859  } else {
860  $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq);
861  }
862  break;
863  } // switch
864 
865  /*********************************************************/
866  } else {
867  //we do this so each driver can customize the sql for
868  //DB specific column types.
869  //Oracle needs BLOB types to be handled with a returning clause
870  //postgres has special needs as well
871  $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,
872  $arrFields, $magicq);
873  }
874 
875  if ($bad) continue;
876  // Set the counter for the number of fields that will be inserted.
877  $fieldInsertedCount++;
878 
879 
880  // Get the name of the fields to insert
881  $fields .= $fnameq . ", ";
882  }
883  }
884 
885 
886  // If there were any inserted fields then build the rest of the insert query.
887  if ($fieldInsertedCount <= 0) return false;
888 
889  // Get the table name from the existing query.
890  if (!$tableName) {
891  if (!empty($rs->tableName)) $tableName = $rs->tableName;
892  else if (preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName))
893  $tableName = $tableName[1];
894  else
895  return false;
896  }
897 
898  // Strip off the comma and space on the end of both the fields
899  // and their values.
900  $fields = substr($fields, 0, -2);
901  $values = substr($values, 0, -2);
902 
903  // Append the fields and their values to the insert query.
904  return 'INSERT INTO '.$tableName.' ( '.$fields.' ) VALUES ( '.$values.' )';
905 }
906 
907 
923 function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq)
924 {
925  $sql = '';
926 
927  // Based on the datatype of the field
928  // Format the value properly for the database
929  switch($type) {
930  case 'B':
931  //in order to handle Blobs correctly, we need
932  //to do some magic for Oracle
933 
934  //we need to create a new descriptor to handle
935  //this properly
936  if (!empty($zthis->hasReturningInto)) {
937  if ($action == 'I') {
938  $sql = 'empty_blob(), ';
939  } else {
940  $sql = $fnameq. '=empty_blob(), ';
941  }
942  //add the variable to the returning clause array
943  //so the user can build this later in
944  //case they want to add more to it
945  $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
946  } else if (empty($arrFields[$fname])){
947  if ($action == 'I') {
948  $sql = 'empty_blob(), ';
949  } else {
950  $sql = $fnameq. '=empty_blob(), ';
951  }
952  } else {
953  //this is to maintain compatibility
954  //with older adodb versions.
955  $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
956  }
957  break;
958 
959  case "X":
960  //we need to do some more magic here for long variables
961  //to handle these correctly in oracle.
962 
963  //create a safe bind var name
964  //to avoid conflicts w/ dupes.
965  if (!empty($zthis->hasReturningInto)) {
966  if ($action == 'I') {
967  $sql = ':xx'.$fname.'xx, ';
968  } else {
969  $sql = $fnameq.'=:xx'.$fname.'xx, ';
970  }
971  //add the variable to the returning clause array
972  //so the user can build this later in
973  //case they want to add more to it
974  $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
975  } else {
976  //this is to maintain compatibility
977  //with older adodb versions.
978  $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
979  }
980  break;
981 
982  default:
983  $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
984  break;
985  }
986 
987  return $sql;
988 }
989 
990 function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true)
991 {
992 
993  if ($recurse) {
994  switch($zthis->dataProvider) {
995  case 'postgres':
996  if ($type == 'L') $type = 'C';
997  break;
998  case 'oci8':
999  return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq);
1000 
1001  }
1002  }
1003 
1004  switch($type) {
1005  case "C":
1006  case "X":
1007  case 'B':
1008  $val = $zthis->qstr($arrFields[$fname],$magicq);
1009  break;
1010 
1011  case "D":
1012  $val = $zthis->DBDate($arrFields[$fname]);
1013  break;
1014 
1015  case "T":
1016  $val = $zthis->DBTimeStamp($arrFields[$fname]);
1017  break;
1018 
1019  case "N":
1020  $val = $arrFields[$fname];
1021  if (!is_numeric($val)) $val = str_replace(',', '.', (float)$val);
1022  break;
1023 
1024  case "I":
1025  case "R":
1026  $val = $arrFields[$fname];
1027  if (!is_numeric($val)) $val = (integer) $val;
1028  break;
1029 
1030  default:
1031  $val = str_replace(array("'"," ","("),"",$arrFields[$fname]); // basic sql injection defence
1032  if (empty($val)) $val = '0';
1033  break;
1034  }
1035 
1036  if ($action == 'I') return $val . ", ";
1037 
1038 
1039  return $fnameq . "=" . $val . ", ";
1040 
1041 }
1042 
1043 
1044 
1045 function _adodb_debug_execute(&$zthis, $sql, $inputarr)
1046 {
1047  $ss = '';
1048  if ($inputarr) {
1049  foreach($inputarr as $kk=>$vv) {
1050  if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
1051  if (is_null($vv)) $ss .= "($kk=>null) ";
1052  else $ss .= "($kk=>'$vv') ";
1053  }
1054  $ss = "[ $ss ]";
1055  }
1056  $sqlTxt = is_array($sql) ? $sql[0] : $sql;
1057  /*str_replace(', ','##1#__^LF',is_array($sql) ? $sql[0] : $sql);
1058  $sqlTxt = str_replace(',',', ',$sqlTxt);
1059  $sqlTxt = str_replace('##1#__^LF', ', ' ,$sqlTxt);
1060  */
1061  // check if running from browser or command-line
1062  $inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
1063 
1064  $dbt = $zthis->databaseType;
1065  if (isset($zthis->dsnType)) $dbt .= '-'.$zthis->dsnType;
1066  if ($inBrowser) {
1067  if ($ss) {
1068  $ss = '<code>'.htmlspecialchars($ss).'</code>';
1069  }
1070  if ($zthis->debug === -1)
1071  ADOConnection::outp( "<br>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<br>\n",false);
1072  else if ($zthis->debug !== -99)
1073  ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr>\n",false);
1074  } else {
1075  $ss = "\n ".$ss;
1076  if ($zthis->debug !== -99)
1077  ADOConnection::outp("-----<hr>\n($dbt): ".$sqlTxt." $ss\n-----<hr>\n",false);
1078  }
1079 
1080  $qID = $zthis->_query($sql,$inputarr);
1081 
1082  /*
1083  Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
1084  because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
1085  */
1086  if ($zthis->databaseType == 'mssql') {
1087  // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
1088 
1089  if($emsg = $zthis->ErrorMsg()) {
1090  if ($err = $zthis->ErrorNo()) {
1091  if ($zthis->debug === -99)
1092  ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr>\n",false);
1093 
1094  ADOConnection::outp($err.': '.$emsg);
1095  }
1096  }
1097  } else if (!$qID) {
1098 
1099  if ($zthis->debug === -99)
1100  if ($inBrowser) ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr>\n",false);
1101  else ADOConnection::outp("-----<hr>\n($dbt): ".$sqlTxt."$ss\n-----<hr>\n",false);
1102 
1103  ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
1104  }
1105 
1106  if ($zthis->debug === 99) _adodb_backtrace(true,9999,2);
1107  return $qID;
1108 }
1109 
1110 # pretty print the debug_backtrace function
1111 function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0,$ishtml=null)
1112 {
1113  if (!function_exists('debug_backtrace')) return '';
1114 
1115  if ($ishtml === null) $html = (isset($_SERVER['HTTP_USER_AGENT']));
1116  else $html = $ishtml;
1117 
1118  $fmt = ($html) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
1119 
1120  $MAXSTRLEN = 128;
1121 
1122  $s = ($html) ? '<pre align=left>' : '';
1123 
1124  if (is_array($printOrArr)) $traceArr = $printOrArr;
1125  else $traceArr = debug_backtrace();
1126  array_shift($traceArr);
1127  array_shift($traceArr);
1128  $tabs = sizeof($traceArr)-2;
1129 
1130  foreach ($traceArr as $arr) {
1131  if ($skippy) {$skippy -= 1; continue;}
1132  $levels -= 1;
1133  if ($levels < 0) break;
1134 
1135  $args = array();
1136  for ($i=0; $i < $tabs; $i++) $s .= ($html) ? ' &nbsp; ' : "\t";
1137  $tabs -= 1;
1138  if ($html) $s .= '<font face="Courier New,Courier">';
1139  if (isset($arr['class'])) $s .= $arr['class'].'.';
1140  if (isset($arr['args']))
1141  foreach($arr['args'] as $v) {
1142  if (is_null($v)) $args[] = 'null';
1143  else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
1144  else if (is_object($v)) $args[] = 'Object:'.get_class($v);
1145  else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
1146  else {
1147  $v = (string) @$v;
1148  $str = htmlspecialchars(str_replace(array("\r","\n"),' ',substr($v,0,$MAXSTRLEN)));
1149  if (strlen($v) > $MAXSTRLEN) $str .= '...';
1150  $args[] = $str;
1151  }
1152  }
1153  $s .= $arr['function'].'('.implode(', ',$args).')';
1154 
1155 
1156  $s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
1157 
1158  $s .= "\n";
1159  }
1160  if ($html) $s .= '</pre>';
1161  if ($printOrArr) print $s;
1162 
1163  return $s;
1164 }
1165 /*
1166 function _adodb_find_from($sql)
1167 {
1168 
1169  $sql = str_replace(array("\n","\r"), ' ', $sql);
1170  $charCount = strlen($sql);
1171 
1172  $inString = false;
1173  $quote = '';
1174  $parentheseCount = 0;
1175  $prevChars = '';
1176  $nextChars = '';
1177 
1178 
1179  for($i = 0; $i < $charCount; $i++) {
1180 
1181  $char = substr($sql,$i,1);
1182  $prevChars = substr($sql,0,$i);
1183  $nextChars = substr($sql,$i+1);
1184 
1185  if((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === false) {
1186  $quote = $char;
1187  $inString = true;
1188  }
1189 
1190  elseif((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === true && $quote == $char) {
1191  $quote = "";
1192  $inString = false;
1193  }
1194 
1195  elseif($char == "(" && $inString === false)
1196  $parentheseCount++;
1197 
1198  elseif($char == ")" && $inString === false && $parentheseCount > 0)
1199  $parentheseCount--;
1200 
1201  elseif($parentheseCount <= 0 && $inString === false && $char == " " && strtoupper(substr($prevChars,-5,5)) == " FROM")
1202  return $i;
1203 
1204  }
1205 }
1206 */
_adodb_getupdatesql(&$zthis, &$rs, $arrFields, $forceUpdate=false, $magicq=false, $force=2)
_adodb_column_sql_oci8(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq)
_adodb_backtrace($printOrArr=true, $levels=9999, $skippy=0, $ishtml=null)
_adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true)
$sql
Definition: server.php:82
if(false) adodb_probetypes(&$array, &$types, $probe=8)
if(isset($_REQUEST['nrows'])) else $rs
Definition: server.php:92
global $ADODB_INCLUDED_LIB
_adodb_getinsertsql(&$zthis, &$rs, $arrFields, $magicq=false, $force=2)
_adodb_getmenu_gp(&$zthis, $name, $defstr='', $blank1stItem=true, $multiple=false, $size=0, $selectAttr='', $compareFields0=true)
_adodb_debug_execute(&$zthis, $sql, $inputarr)
die
Definition: index.php:6
_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
_array_change_key_case($an_array)
_adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc)
_adodb_getmenu(&$zthis, $name, $defstr='', $blank1stItem=true, $multiple=false, $size=0, $selectAttr='', $compareFields0=true)
adodb_transpose(&$arr, &$newarr, &$hdr, &$fobjs)
adodb_key_exists($key, &$arr, $force=2)
adodb_strip_order_by($sql)
_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
_adodb_getcount(&$zthis, $sql, $inputarr=false, $secs2cache=0)