C:/lib/adodb/adodb-lib.inc.php Quellcode

adodb-lib.inc.php
gehe zur Dokumentation dieser Datei
1 <?php
2 // security - hide paths
3 if (!defined('ADODB_DIR')) die();
4 
6 $ADODB_INCLUDED_LIB = 1;
7 
8 /*
9  @version V5.19dev ??-???-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 
18 function adodb_strip_order_by($sql)
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)';
46  die(adodb_strip_order_by($sql));
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 // Ivn 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  // is_null requires php 4.0.4
662  //********************************************************//
663  if (is_null($arrFields[$upperfname])
664  || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
665  || $arrFields[$upperfname] === $zthis->null2null
666  )
667  {
668  switch ($force) {
669 
670  //case 0:
671  // //Ignore empty values. This is allready handled in "adodb_key_exists" function.
672  //break;
673 
674  case 1:
675  //Set null
676  $setFields .= $field->name . " = null, ";
677  break;
678 
679  case 2:
680  //Set empty
681  $arrFields[$upperfname] = "";
682  $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
683  break;
684  default:
685  case 3:
686  //Set the value that was given in array, so you can give both null and empty values
687  if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) {
688  $setFields .= $field->name . " = null, ";
689  } else {
690  $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
691  }
692  break;
693  }
694  //********************************************************//
695  } else {
696  //we do this so each driver can customize the sql for
697  //DB specific column types.
698  //Oracle needs BLOB types to be handled with a returning clause
699  //postgres has special needs as well
700  $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
701  $arrFields, $magicq);
702  }
703  }
704  }
705  }
706 
707  // If there were any modified fields then build the rest of the update query.
708  if ($fieldUpdatedCount > 0 || $forceUpdate) {
709  // Get the table name from the existing query.
710  if (!empty($rs->tableName)) $tableName = $rs->tableName;
711  else {
712  preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
713  $tableName = $tableName[1];
714  }
715  // Get the full where clause excluding the word "WHERE" from
716  // the existing query.
717  preg_match('/\sWHERE\s(.*)/is', $rs->sql, $whereClause);
718 
719  $discard = false;
720  // not a good hack, improvements?
721  if ($whereClause) {
722  #var_dump($whereClause);
723  if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
724  else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard));
725  else if (preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard));
726  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
727  } else
728  $whereClause = array(false,false);
729 
730  if ($discard)
731  $whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
732 
733  $sql = 'UPDATE '.$tableName.' SET '.substr($setFields, 0, -2);
734  if (strlen($whereClause[1]) > 0)
735  $sql .= ' WHERE '.$whereClause[1];
736 
737  return $sql;
738 
739  } else {
740  return false;
741  }
742 }
743 
744 function adodb_key_exists($key, &$arr,$force=2)
745 {
746  if ($force<=0) {
747  // the following is the old behaviour where null or empty fields are ignored
748  return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0);
749  }
750 
751  if (isset($arr[$key])) return true;
752  ## null check below
753  if (ADODB_PHPVER >= 0x4010) return array_key_exists($key,$arr);
754  return false;
755 }
756 
764 function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2)
765 {
766 static $cacheRS = false;
767 static $cacheSig = 0;
768 static $cacheCols;
769  global $ADODB_QUOTE_FIELDNAMES;
770 
771  $tableName = '';
772  $values = '';
773  $fields = '';
774  $recordSet = null;
775  $arrFields = _array_change_key_case($arrFields);
776  $fieldInsertedCount = 0;
777 
778  if (is_string($rs)) {
779  //ok we have a table name
780  //try and get the column info ourself.
781  $tableName = $rs;
782 
783  //we need an object for the recordSet
784  //because we have to call MetaType.
785  //php can't do a $rsclass::MetaType()
786  $rsclass = $zthis->rsPrefix.$zthis->databaseType;
787  $recordSet = new $rsclass(-1,$zthis->fetchMode);
788  $recordSet->connection = $zthis;
789 
790  if (is_string($cacheRS) && $cacheRS == $rs) {
791  $columns = $cacheCols;
792  } else {
793  $columns = $zthis->MetaColumns( $tableName );
794  $cacheRS = $tableName;
795  $cacheCols = $columns;
796  }
797  } else if (is_subclass_of($rs, 'adorecordset')) {
798  if (isset($rs->insertSig) && is_integer($cacheRS) && $cacheRS == $rs->insertSig) {
799  $columns = $cacheCols;
800  } else {
801  for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++)
802  $columns[] = $rs->FetchField($i);
803  $cacheRS = $cacheSig;
804  $cacheCols = $columns;
805  $rs->insertSig = $cacheSig++;
806  }
807  $recordSet = $rs;
808 
809  } else {
810  printf(ADODB_BAD_RS,'GetInsertSQL');
811  return false;
812  }
813 
814  // Loop through all of the fields in the recordset
815  foreach( $columns as $field ) {
816  $upperfname = strtoupper($field->name);
817  if (adodb_key_exists($upperfname,$arrFields,$force)) {
818  $bad = false;
819  if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) {
820  switch (ADODB_QUOTE_FIELDNAMES) {
821  case 'LOWER':
822  $fnameq = $zthis->nameQuote.strtolower($field->name).$zthis->nameQuote;break;
823  case 'NATIVE':
824  $fnameq = $zthis->nameQuote.$field->name.$zthis->nameQuote;break;
825  case 'UPPER':
826  default:
827  $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;break;
828  }
829  } else
830  $fnameq = $upperfname;
831 
832  $type = $recordSet->MetaType($field->type);
833 
834  /********************************************************/
835  if (is_null($arrFields[$upperfname])
836  || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
837  || $arrFields[$upperfname] === $zthis->null2null
838  )
839  {
840  switch ($force) {
841 
842  case 0: // we must always set null if missing
843  $bad = true;
844  break;
845 
846  case 1:
847  $values .= "null, ";
848  break;
849 
850  case 2:
851  //Set empty
852  $arrFields[$upperfname] = "";
853  $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq);
854  break;
855 
856  default:
857  case 3:
858  //Set the value that was given in array, so you can give both null and empty values
859  if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) {
860  $values .= "null, ";
861  } else {
862  $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq);
863  }
864  break;
865  } // switch
866 
867  /*********************************************************/
868  } else {
869  //we do this so each driver can customize the sql for
870  //DB specific column types.
871  //Oracle needs BLOB types to be handled with a returning clause
872  //postgres has special needs as well
873  $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,
874  $arrFields, $magicq);
875  }
876 
877  if ($bad) continue;
878  // Set the counter for the number of fields that will be inserted.
879  $fieldInsertedCount++;
880 
881 
882  // Get the name of the fields to insert
883  $fields .= $fnameq . ", ";
884  }
885  }
886 
887 
888  // If there were any inserted fields then build the rest of the insert query.
889  if ($fieldInsertedCount <= 0) return false;
890 
891  // Get the table name from the existing query.
892  if (!$tableName) {
893  if (!empty($rs->tableName)) $tableName = $rs->tableName;
894  else if (preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName))
895  $tableName = $tableName[1];
896  else
897  return false;
898  }
899 
900  // Strip off the comma and space on the end of both the fields
901  // and their values.
902  $fields = substr($fields, 0, -2);
903  $values = substr($values, 0, -2);
904 
905  // Append the fields and their values to the insert query.
906  return 'INSERT INTO '.$tableName.' ( '.$fields.' ) VALUES ( '.$values.' )';
907 }
908 
909 
925 function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq)
926 {
927  $sql = '';
928 
929  // Based on the datatype of the field
930  // Format the value properly for the database
931  switch($type) {
932  case 'B':
933  //in order to handle Blobs correctly, we need
934  //to do some magic for Oracle
935 
936  //we need to create a new descriptor to handle
937  //this properly
938  if (!empty($zthis->hasReturningInto)) {
939  if ($action == 'I') {
940  $sql = 'empty_blob(), ';
941  } else {
942  $sql = $fnameq. '=empty_blob(), ';
943  }
944  //add the variable to the returning clause array
945  //so the user can build this later in
946  //case they want to add more to it
947  $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
948  } else if (empty($arrFields[$fname])){
949  if ($action == 'I') {
950  $sql = 'empty_blob(), ';
951  } else {
952  $sql = $fnameq. '=empty_blob(), ';
953  }
954  } else {
955  //this is to maintain compatibility
956  //with older adodb versions.
957  $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
958  }
959  break;
960 
961  case "X":
962  //we need to do some more magic here for long variables
963  //to handle these correctly in oracle.
964 
965  //create a safe bind var name
966  //to avoid conflicts w/ dupes.
967  if (!empty($zthis->hasReturningInto)) {
968  if ($action == 'I') {
969  $sql = ':xx'.$fname.'xx, ';
970  } else {
971  $sql = $fnameq.'=:xx'.$fname.'xx, ';
972  }
973  //add the variable to the returning clause array
974  //so the user can build this later in
975  //case they want to add more to it
976  $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
977  } else {
978  //this is to maintain compatibility
979  //with older adodb versions.
980  $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
981  }
982  break;
983 
984  default:
985  $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
986  break;
987  }
988 
989  return $sql;
990 }
991 
992 function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true)
993 {
994 
995  if ($recurse) {
996  switch($zthis->dataProvider) {
997  case 'postgres':
998  if ($type == 'L') $type = 'C';
999  break;
1000  case 'oci8':
1001  return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq);
1002 
1003  }
1004  }
1005 
1006  switch($type) {
1007  case "C":
1008  case "X":
1009  case 'B':
1010  $val = $zthis->qstr($arrFields[$fname],$magicq);
1011  break;
1012 
1013  case "D":
1014  $val = $zthis->DBDate($arrFields[$fname]);
1015  break;
1016 
1017  case "T":
1018  $val = $zthis->DBTimeStamp($arrFields[$fname]);
1019  break;
1020 
1021  case "N":
1022  $val = $arrFields[$fname];
1023  if (!is_numeric($val)) $val = str_replace(',', '.', (float)$val);
1024  break;
1025 
1026  case "I":
1027  case "R":
1028  $val = $arrFields[$fname];
1029  if (!is_numeric($val)) $val = (integer) $val;
1030  break;
1031 
1032  default:
1033  $val = str_replace(array("'"," ","("),"",$arrFields[$fname]); // basic sql injection defence
1034  if (empty($val)) $val = '0';
1035  break;
1036  }
1037 
1038  if ($action == 'I') return $val . ", ";
1039 
1040 
1041  return $fnameq . "=" . $val . ", ";
1042 
1043 }
1044 
1045 
1046 
1047 function _adodb_debug_execute(&$zthis, $sql, $inputarr)
1048 {
1049  $ss = '';
1050  if ($inputarr) {
1051  foreach($inputarr as $kk=>$vv) {
1052  if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
1053  if (is_null($vv)) $ss .= "($kk=>null) ";
1054  else $ss .= "($kk=>'$vv') ";
1055  }
1056  $ss = "[ $ss ]";
1057  }
1058  $sqlTxt = is_array($sql) ? $sql[0] : $sql;
1059  /*str_replace(', ','##1#__^LF',is_array($sql) ? $sql[0] : $sql);
1060  $sqlTxt = str_replace(',',', ',$sqlTxt);
1061  $sqlTxt = str_replace('##1#__^LF', ', ' ,$sqlTxt);
1062  */
1063  // check if running from browser or command-line
1064  $inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
1065 
1066  $dbt = $zthis->databaseType;
1067  if (isset($zthis->dsnType)) $dbt .= '-'.$zthis->dsnType;
1068  if ($inBrowser) {
1069  if ($ss) {
1070  $ss = '<code>'.htmlspecialchars($ss).'</code>';
1071  }
1072  if ($zthis->debug === -1)
1073  ADOConnection::outp( "<br>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<br>\n",false);
1074  else if ($zthis->debug !== -99)
1075  ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr>\n",false);
1076  } else {
1077  $ss = "\n ".$ss;
1078  if ($zthis->debug !== -99)
1079  ADOConnection::outp("-----<hr>\n($dbt): ".$sqlTxt." $ss\n-----<hr>\n",false);
1080  }
1081 
1082  $qID = $zthis->_query($sql,$inputarr);
1083 
1084  /*
1085  Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
1086  because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
1087  */
1088  if ($zthis->databaseType == 'mssql') {
1089  // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
1090 
1091  if($emsg = $zthis->ErrorMsg()) {
1092  if ($err = $zthis->ErrorNo()) {
1093  if ($zthis->debug === -99)
1094  ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr>\n",false);
1095 
1096  ADOConnection::outp($err.': '.$emsg);
1097  }
1098  }
1099  } else if (!$qID) {
1100 
1101  if ($zthis->debug === -99)
1102  if ($inBrowser) ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr>\n",false);
1103  else ADOConnection::outp("-----<hr>\n($dbt): ".$sqlTxt."$ss\n-----<hr>\n",false);
1104 
1105  ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
1106  }
1107 
1108  if ($zthis->debug === 99) _adodb_backtrace(true,9999,2);
1109  return $qID;
1110 }
1111 
1112 # pretty print the debug_backtrace function
1113 function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0,$ishtml=null)
1114 {
1115  if (!function_exists('debug_backtrace')) return '';
1116 
1117  if ($ishtml === null) $html = (isset($_SERVER['HTTP_USER_AGENT']));
1118  else $html = $ishtml;
1119 
1120  $fmt = ($html) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
1121 
1122  $MAXSTRLEN = 128;
1123 
1124  $s = ($html) ? '<pre align=left>' : '';
1125 
1126  if (is_array($printOrArr)) $traceArr = $printOrArr;
1127  else $traceArr = debug_backtrace();
1128  array_shift($traceArr);
1129  array_shift($traceArr);
1130  $tabs = sizeof($traceArr)-2;
1131 
1132  foreach ($traceArr as $arr) {
1133  if ($skippy) {$skippy -= 1; continue;}
1134  $levels -= 1;
1135  if ($levels < 0) break;
1136 
1137  $args = array();
1138  for ($i=0; $i < $tabs; $i++) $s .= ($html) ? ' &nbsp; ' : "\t";
1139  $tabs -= 1;
1140  if ($html) $s .= '<font face="Courier New,Courier">';
1141  if (isset($arr['class'])) $s .= $arr['class'].'.';
1142  if (isset($arr['args']))
1143  foreach($arr['args'] as $v) {
1144  if (is_null($v)) $args[] = 'null';
1145  else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
1146  else if (is_object($v)) $args[] = 'Object:'.get_class($v);
1147  else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
1148  else {
1149  $v = (string) @$v;
1150  $str = htmlspecialchars(str_replace(array("\r","\n"),' ',substr($v,0,$MAXSTRLEN)));
1151  if (strlen($v) > $MAXSTRLEN) $str .= '...';
1152  $args[] = $str;
1153  }
1154  }
1155  $s .= $arr['function'].'('.implode(', ',$args).')';
1156 
1157 
1158  $s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
1159 
1160  $s .= "\n";
1161  }
1162  if ($html) $s .= '</pre>';
1163  if ($printOrArr) print $s;
1164 
1165  return $s;
1166 }
1167 /*
1168 function _adodb_find_from($sql)
1169 {
1170 
1171  $sql = str_replace(array("\n","\r"), ' ', $sql);
1172  $charCount = strlen($sql);
1173 
1174  $inString = false;
1175  $quote = '';
1176  $parentheseCount = 0;
1177  $prevChars = '';
1178  $nextChars = '';
1179 
1180 
1181  for($i = 0; $i < $charCount; $i++) {
1182 
1183  $char = substr($sql,$i,1);
1184  $prevChars = substr($sql,0,$i);
1185  $nextChars = substr($sql,$i+1);
1186 
1187  if((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === false) {
1188  $quote = $char;
1189  $inString = true;
1190  }
1191 
1192  elseif((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === true && $quote == $char) {
1193  $quote = "";
1194  $inString = false;
1195  }
1196 
1197  elseif($char == "(" && $inString === false)
1198  $parentheseCount++;
1199 
1200  elseif($char == ")" && $inString === false && $parentheseCount > 0)
1201  $parentheseCount--;
1202 
1203  elseif($parentheseCount <= 0 && $inString === false && $char == " " && strtoupper(substr($prevChars,-5,5)) == " FROM")
1204  return $i;
1205 
1206  }
1207 }
1208 */
1209 
1210 ?>




Korrekturen, Hinweise und Ergänzungen

Bitte scheuen Sie sich nicht und melden Sie, was auf dieser Seite sachlich falsch oder irreführend ist, was ergänzt werden sollte, was fehlt usw. Dazu bitte oben aus dem Menü Seite den Eintrag Support Forum wählen. Es ist eine kostenlose Anmeldung erforderlich, um Anmerkungen zu posten. Unpassende Postings, Spam usw. werden kommentarlos entfernt.