2 // security - hide paths
3 if (!defined('ADODB_DIR')) die();
5 global $ADODB_INCLUDED_LIB;
6 $ADODB_INCLUDED_LIB = 1;
9 @version V5.14 8 Sept 2011 (c) 2000-2011 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.
15 Less commonly used functions are placed here to reduce size of adodb.inc.php.
18 function adodb_strip_order_by($sql)
20 $rez = preg_match('/(\sORDER\s+BY\s[^)]*)/is',$sql,$arr);
22 if (strpos($arr[0],'(') !== false) {
23 $at = strpos($sql,$arr[0]);
25 for ($i=$at, $max=strlen($sql); $i < $max; $i++
) {
29 } elseif($ch == ')') {
36 $sql = substr($sql,0,$at).substr($sql,$i);
38 $sql = str_replace($arr[0], '', $sql);
43 $sql = 'select * from (select a from b order by a(b),b(c) desc)';
44 $sql = '(select * from abc order by 1)';
45 die(adodb_strip_order_by($sql));
48 function adodb_probetypes(&$array,&$types,$probe=8)
50 // probe and guess the type
52 if ($probe > sizeof($array)) $max = sizeof($array);
56 for ($j=0;$j < $max; $j++
) {
63 if (isset($types[$i]) && $types[$i]=='C') continue;
65 //print " ($i ".$types[$i]. "$v) ";
68 if (!preg_match('/^[+-]{0,1}[0-9\.]+$/',$v)) {
69 $types[$i] = 'C'; // once C, always C
74 // If empty string, we presume is character
75 // test for integer for 1st row only
76 // after that it is up to testing other rows to prove
77 // that it is not an integer
78 if (strlen($v) == 0) $types[$i] = 'C';
79 if (strpos($v,'.') !== false) $types[$i] = 'N';
80 else $types[$i] = 'I';
84 if (strpos($v,'.') !== false) $types[$i] = 'N';
91 function adodb_transpose(&$arr, &$newarr, &$hdr, &$fobjs)
93 $oldX = sizeof(reset($arr));
98 $hdr = array('Fields');
99 for ($y = 0; $y < $oldY; $y++
) {
100 $hdr[] = $arr[$y][0];
105 for ($x = $startx; $x < $oldX; $x++
) {
108 $newarr[] = array($o->name
);
112 for ($y = 0; $y < $oldY; $y++
) {
113 $newarr[$x-$startx][] = $arr[$y][$x];
118 // Force key to upper.
119 // See also http://www.php.net/manual/en/function.array-change-key-case.php
120 function _array_change_key_case($an_array)
122 if (is_array($an_array)) {
123 $new_array = array();
124 foreach($an_array as $key=>$value)
125 $new_array[strtoupper($key)] = $value;
133 function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc)
135 if (count($fieldArray) == 0) return 0;
139 if (!is_array($keyCol)) {
140 $keyCol = array($keyCol);
142 foreach($fieldArray as $k => $v) {
145 $fieldArray[$k] = $v;
146 } else if ($autoQuote && /*!is_numeric($v) /*and strncmp($v,"'",1) !== 0 -- sql injection risk*/ strcasecmp($v,$zthis->null2null
)!=0) {
147 $v = $zthis->qstr($v);
148 $fieldArray[$k] = $v;
150 if (in_array($k,$keyCol)) continue; // skip UPDATE if is key
160 foreach ($keyCol as $v) {
161 if (isset($fieldArray[$v])) {
162 if ($where) $where .= ' and '.$v.'='.$fieldArray[$v];
163 else $where = $v.'='.$fieldArray[$v];
167 if ($uSet && $where) {
168 $update = "UPDATE $table SET $uSet WHERE $where";
170 $rs = $zthis->Execute($update);
174 if ($zthis->poorAffectedRows
) {
176 The Select count(*) wipes out any errors that the update would have returned.
177 http://phplens.com/lens/lensforum/msgs.php?id=5696
179 if ($zthis->ErrorNo()<>0) return 0;
181 # affected_rows == 0 if update field values identical to old values
182 # for mysql - which is silly.
184 $cnt = $zthis->GetOne("select count(*) from $table where $where");
185 if ($cnt > 0) return 1; // record already exists
187 if (($zthis->Affected_Rows()>0)) return 1;
193 // print "<p>Error=".$this->ErrorNo().'<p>';
195 foreach($fieldArray as $k => $v) {
196 if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
207 $insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
208 $rs = $zthis->Execute($insert);
209 return ($rs) ?
2 : 0;
212 // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
213 function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
214 $size=0, $selectAttr='',$compareFields0=true)
218 if ($multiple or is_array($defstr)) {
219 if ($size==0) $size=5;
220 $attr = ' multiple size="'.$size.'"';
221 if (!strpos($name,'[]')) $name .= '[]';
222 } else if ($size) $attr = ' size="'.$size.'"';
225 $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
227 if (is_string($blank1stItem)) {
228 $barr = explode(':',$blank1stItem);
229 if (sizeof($barr) == 1) $barr[] = '';
230 $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
231 } else $s .= "\n<option></option>";
233 if ($zthis->FieldCount() > 1) $hasvalue=true;
234 else $compareFields0 = true;
239 $fieldsize = $zthis->FieldCount();
240 while(!$zthis->EOF
) {
241 $zval = rtrim(reset($zthis->fields
));
243 if ($blank1stItem && $zval=="") {
248 if ($fieldsize > 1) {
249 if (isset($zthis->fields
[1]))
250 $zval2 = rtrim($zthis->fields
[1]);
252 $zval2 = rtrim(next($zthis->fields
));
254 $selected = ($compareFields0) ?
$zval : $zval2;
257 if ($fieldsize > 2) {
258 $group = rtrim($zthis->fields
[2]);
261 if ($optgroup != $group) {
265 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
267 $s .="\n</optgroup>";
268 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
273 $value = " value='".htmlspecialchars($zval2)."'";
275 if (is_array($defstr)) {
277 if (in_array($selected,$defstr))
278 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
280 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
283 if (strcasecmp($selected,$defstr)==0)
284 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
286 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
291 // closing last optgroup
292 if($optgroup != null) {
293 $s .= "\n</optgroup>";
295 return $s ."\n</select>\n";
298 // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
299 function _adodb_getmenu_gp(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
300 $size=0, $selectAttr='',$compareFields0=true)
304 if ($multiple or is_array($defstr)) {
305 if ($size==0) $size=5;
306 $attr = ' multiple size="'.$size.'"';
307 if (!strpos($name,'[]')) $name .= '[]';
308 } else if ($size) $attr = ' size="'.$size.'"';
311 $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
313 if (is_string($blank1stItem)) {
314 $barr = explode(':',$blank1stItem);
315 if (sizeof($barr) == 1) $barr[] = '';
316 $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
317 } else $s .= "\n<option></option>";
319 if ($zthis->FieldCount() > 1) $hasvalue=true;
320 else $compareFields0 = true;
325 $fieldsize = sizeof($zthis->fields
);
326 while(!$zthis->EOF
) {
327 $zval = rtrim(reset($zthis->fields
));
329 if ($blank1stItem && $zval=="") {
334 if ($fieldsize > 1) {
335 if (isset($zthis->fields
[1]))
336 $zval2 = rtrim($zthis->fields
[1]);
338 $zval2 = rtrim(next($zthis->fields
));
340 $selected = ($compareFields0) ?
$zval : $zval2;
343 if (isset($zthis->fields
[2])) {
344 $group = rtrim($zthis->fields
[2]);
347 if ($optgroup != $group) {
351 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
353 $s .="\n</optgroup>";
354 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
359 $value = " value='".htmlspecialchars($zval2)."'";
361 if (is_array($defstr)) {
363 if (in_array($selected,$defstr))
364 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
366 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
369 if (strcasecmp($selected,$defstr)==0)
370 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
372 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
377 // closing last optgroup
378 if($optgroup != null) {
379 $s .= "\n</optgroup>";
381 return $s ."\n</select>\n";
386 Count the number of records this sql statement will return by using
387 query rewriting heuristics...
389 Does not work with UNIONs, except with postgresql and oracle.
394 $cnt = _adodb_getcount($conn, $sql);
397 function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
401 if (!empty($zthis->_nestedSQL
) ||
preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) ||
402 preg_match('/\s+GROUP\s+BY\s+/is',$sql) ||
403 preg_match('/\s+UNION\s+/is',$sql)) {
405 $rewritesql = adodb_strip_order_by($sql);
407 // ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias
408 // but this is only supported by oracle and postgresql...
409 if ($zthis->dataProvider
== 'oci8') {
410 // Allow Oracle hints to be used for query optimization, Chris Wrye
411 if (preg_match('#/\\*+.*?\\*\\/#', $sql, $hint)) {
412 $rewritesql = "SELECT ".$hint[0]." COUNT(*) FROM (".$rewritesql.")";
414 $rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")";
416 } else if (strncmp($zthis->databaseType
,'postgres',8) == 0 ||
strncmp($zthis->databaseType
,'mysql',5) == 0) {
417 $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
419 $rewritesql = "SELECT COUNT(*) FROM ($rewritesql)";
422 // now replace SELECT ... FROM with SELECT COUNT(*) FROM
423 $rewritesql = preg_replace(
424 '/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql);
425 // fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails
426 // with mssql, access and postgresql. Also a good speedup optimization - skips sorting!
427 // also see http://phplens.com/lens/lensforum/msgs.php?id=12752
428 $rewritesql = adodb_strip_order_by($rewritesql);
431 if (isset($rewritesql) && $rewritesql != $sql) {
432 if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
435 // we only use half the time of secs2cache because the count can quickly
436 // become inaccurate if new records are added
437 $qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr);
440 $qryRecs = $zthis->GetOne($rewritesql,$inputarr);
442 if ($qryRecs !== false) return $qryRecs;
444 //--------------------------------------------
445 // query rewrite failed - so try slower way...
448 // strip off unneeded ORDER BY if no UNION
449 if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql;
450 else $rewritesql = $rewritesql = adodb_strip_order_by($sql);
452 if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
455 $rstest = $zthis->CacheExecute($secs2cache,$rewritesql,$inputarr);
456 if (!$rstest) $rstest = $zthis->CacheExecute($secs2cache,$sql,$inputarr);
458 $rstest = $zthis->Execute($rewritesql,$inputarr);
459 if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr);
462 $qryRecs = $rstest->RecordCount();
463 if ($qryRecs == -1) {
464 global $ADODB_EXTENSION;
465 // some databases will return -1 on MoveLast() - change to MoveNext()
466 if ($ADODB_EXTENSION) {
467 while(!$rstest->EOF
) {
468 adodb_movenext($rstest);
471 while(!$rstest->EOF
) {
475 $qryRecs = $rstest->_currentRow
;
478 if ($qryRecs == -1) return 0;
484 Code originally from "Cornel G" <conyg@fx.ro>
486 This code might not work with SQL that has UNION in it
488 Also if you are using CachePageExecute(), there is a strong possibility that
489 data will get out of synch. use CachePageExecute() only with tables that
492 function _adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
493 $inputarr=false, $secs2cache=0)
495 $atfirstpage = false;
499 // If an invalid nrows is supplied,
500 // we assume a default value of 10 rows per page
501 if (!isset($nrows) ||
$nrows <= 0) $nrows = 10;
503 $qryRecs = false; //count records for no offset
505 $qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache);
506 $lastpageno = (int) ceil($qryRecs / $nrows);
507 $zthis->_maxRecordCount
= $qryRecs;
511 // ***** Here we check whether $page is the last page or
512 // whether we are trying to retrieve
513 // a page number greater than the last page number.
514 if ($page >= $lastpageno) {
519 // If page number <= 1, then we are at the first page
520 if (empty($page) ||
$page <= 1) {
525 // We get the data we want
526 $offset = $nrows * ($page-1);
528 $rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
530 $rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
533 // Before returning the RecordSet, we set the pagination properties we need
535 $rsreturn->_maxRecordCount
= $qryRecs;
536 $rsreturn->rowsPerPage
= $nrows;
537 $rsreturn->AbsolutePage($page);
538 $rsreturn->AtFirstPage($atfirstpage);
539 $rsreturn->AtLastPage($atlastpage);
540 $rsreturn->LastPageNo($lastpageno);
545 // Iván Oliva version
546 function _adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
549 $atfirstpage = false;
552 if (!isset($page) ||
$page <= 1) { // If page number <= 1, then we are at the first page
556 if ($nrows <= 0) $nrows = 10; // If an invalid nrows is supplied, we assume a default value of 10 rows per page
558 // ***** Here we check whether $page is the last page or whether we are trying to retrieve a page number greater than
559 // the last page number.
560 $pagecounter = $page +
1;
561 $pagecounteroffset = ($pagecounter * $nrows) - $nrows;
562 if ($secs2cache>0) $rstest = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
563 else $rstest = $zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
565 while ($rstest && $rstest->EOF
&& $pagecounter>0) {
568 $pagecounteroffset = $nrows * ($pagecounter - 1);
570 if ($secs2cache>0) $rstest = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
571 else $rstest = $zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
573 if ($rstest) $rstest->Close();
575 if ($atlastpage) { // If we are at the last page or beyond it, we are going to retrieve it
576 $page = $pagecounter;
577 if ($page == 1) $atfirstpage = true; // We have to do this again in case the last page is the same as the first
578 //... page, that is, the recordset has only 1 page.
581 // We get the data we want
582 $offset = $nrows * ($page-1);
583 if ($secs2cache > 0) $rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
584 else $rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
586 // Before returning the RecordSet, we set the pagination properties we need
588 $rsreturn->rowsPerPage
= $nrows;
589 $rsreturn->AbsolutePage($page);
590 $rsreturn->AtFirstPage($atfirstpage);
591 $rsreturn->AtLastPage($atlastpage);
596 function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2)
598 global $ADODB_QUOTE_FIELDNAMES;
601 printf(ADODB_BAD_RS
,'GetUpdateSQL');
605 $fieldUpdatedCount = 0;
606 $arrFields = _array_change_key_case($arrFields);
608 $hasnumeric = isset($rs->fields
[0]);
611 // Loop through all of the fields in the recordset
612 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++
) {
613 // Get the field from the recordset
614 $field = $rs->FetchField($i);
616 // If the recordset field is one
617 // of the fields passed in then process.
618 $upperfname = strtoupper($field->name
);
619 if (adodb_key_exists($upperfname,$arrFields,$force)) {
621 // If the existing field value in the recordset
622 // is different from the value passed in then
623 // go ahead and append the field name and new value to
626 if ($hasnumeric) $val = $rs->fields
[$i];
627 else if (isset($rs->fields
[$upperfname])) $val = $rs->fields
[$upperfname];
628 else if (isset($rs->fields
[$field->name
])) $val = $rs->fields
[$field->name
];
629 else if (isset($rs->fields
[strtolower($upperfname)])) $val = $rs->fields
[strtolower($upperfname)];
633 if ($forceUpdate ||
strcmp($val, $arrFields[$upperfname])) {
634 // Set the counter for the number of fields that will be updated.
635 $fieldUpdatedCount++
;
637 // Based on the datatype of the field
638 // Format the value properly for the database
639 $type = $rs->MetaType($field->type
);
642 if ($type == 'null') {
646 if ((strpos($upperfname,' ') !== false) ||
($ADODB_QUOTE_FIELDNAMES)) {
647 switch (ADODB_QUOTE_FIELDNAMES
) {
649 $fnameq = $zthis->nameQuote
.strtolower($field->name
).$zthis->nameQuote
;break;
651 $fnameq = $zthis->nameQuote
.$field->name
.$zthis->nameQuote
;break;
654 $fnameq = $zthis->nameQuote
.$upperfname.$zthis->nameQuote
;break;
657 $fnameq = $upperfname;
660 // is_null requires php 4.0.4
661 //********************************************************//
662 if (is_null($arrFields[$upperfname])
663 ||
(empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
664 ||
$arrFields[$upperfname] === $zthis->null2null
670 // //Ignore empty values. This is allready handled in "adodb_key_exists" function.
675 $setFields .= $field->name
. " = null, ";
680 $arrFields[$upperfname] = "";
681 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
685 //Set the value that was given in array, so you can give both null and empty values
686 if (is_null($arrFields[$upperfname]) ||
$arrFields[$upperfname] === $zthis->null2null
) {
687 $setFields .= $field->name
. " = null, ";
689 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
693 //********************************************************//
695 //we do this so each driver can customize the sql for
696 //DB specific column types.
697 //Oracle needs BLOB types to be handled with a returning clause
698 //postgres has special needs as well
699 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
700 $arrFields, $magicq);
706 // If there were any modified fields then build the rest of the update query.
707 if ($fieldUpdatedCount > 0 ||
$forceUpdate) {
708 // Get the table name from the existing query.
709 if (!empty($rs->tableName
)) $tableName = $rs->tableName
;
711 preg_match("/FROM\s+".ADODB_TABLE_REGEX
."/is", $rs->sql
, $tableName);
712 $tableName = $tableName[1];
714 // Get the full where clause excluding the word "WHERE" from
715 // the existing query.
716 preg_match('/\sWHERE\s(.*)/is', $rs->sql
, $whereClause);
719 // not a good hack, improvements?
721 #var_dump($whereClause);
722 if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
723 else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard));
724 else if (preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard));
725 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 $whereClause = array(false,false);
730 $whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
732 $sql = 'UPDATE '.$tableName.' SET '.substr($setFields, 0, -2);
733 if (strlen($whereClause[1]) > 0)
734 $sql .= ' WHERE '.$whereClause[1];
743 function adodb_key_exists($key, &$arr,$force=2)
746 // the following is the old behaviour where null or empty fields are ignored
747 return (!empty($arr[$key])) ||
(isset($arr[$key]) && strlen($arr[$key])>0);
750 if (isset($arr[$key])) return true;
752 if (ADODB_PHPVER
>= 0x4010) return array_key_exists($key,$arr);
757 * There is a special case of this function for the oci8 driver.
758 * The proper way to handle an insert w/ a blob in oracle requires
759 * a returning clause with bind variables and a descriptor blob.
763 function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2)
765 static $cacheRS = false;
766 static $cacheSig = 0;
768 global $ADODB_QUOTE_FIELDNAMES;
774 $arrFields = _array_change_key_case($arrFields);
775 $fieldInsertedCount = 0;
777 if (is_string($rs)) {
778 //ok we have a table name
779 //try and get the column info ourself.
782 //we need an object for the recordSet
783 //because we have to call MetaType.
784 //php can't do a $rsclass::MetaType()
785 $rsclass = $zthis->rsPrefix
.$zthis->databaseType
;
786 $recordSet = new $rsclass(-1,$zthis->fetchMode
);
787 $recordSet->connection
= $zthis;
789 if (is_string($cacheRS) && $cacheRS == $rs) {
790 $columns = $cacheCols;
792 $columns = $zthis->MetaColumns( $tableName );
793 $cacheRS = $tableName;
794 $cacheCols = $columns;
796 } else if (is_subclass_of($rs, 'adorecordset')) {
797 if (isset($rs->insertSig
) && is_integer($cacheRS) && $cacheRS == $rs->insertSig
) {
798 $columns = $cacheCols;
800 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++
)
801 $columns[] = $rs->FetchField($i);
802 $cacheRS = $cacheSig;
803 $cacheCols = $columns;
804 $rs->insertSig
= $cacheSig++
;
809 printf(ADODB_BAD_RS
,'GetInsertSQL');
813 // Loop through all of the fields in the recordset
814 foreach( $columns as $field ) {
815 $upperfname = strtoupper($field->name
);
816 if (adodb_key_exists($upperfname,$arrFields,$force)) {
818 if ((strpos($upperfname,' ') !== false) ||
($ADODB_QUOTE_FIELDNAMES)) {
819 switch (ADODB_QUOTE_FIELDNAMES
) {
821 $fnameq = $zthis->nameQuote
.strtolower($field->name
).$zthis->nameQuote
;break;
823 $fnameq = $zthis->nameQuote
.$field->name
.$zthis->nameQuote
;break;
826 $fnameq = $zthis->nameQuote
.$upperfname.$zthis->nameQuote
;break;
829 $fnameq = $upperfname;
831 $type = $recordSet->MetaType($field->type
);
833 /********************************************************/
834 if (is_null($arrFields[$upperfname])
835 ||
(empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
836 ||
$arrFields[$upperfname] === $zthis->null2null
841 case 0: // we must always set null if missing
851 $arrFields[$upperfname] = "";
852 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq);
857 //Set the value that was given in array, so you can give both null and empty values
858 if (is_null($arrFields[$upperfname]) ||
$arrFields[$upperfname] === $zthis->null2null
) {
861 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq);
866 /*********************************************************/
868 //we do this so each driver can customize the sql for
869 //DB specific column types.
870 //Oracle needs BLOB types to be handled with a returning clause
871 //postgres has special needs as well
872 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,
873 $arrFields, $magicq);
877 // Set the counter for the number of fields that will be inserted.
878 $fieldInsertedCount++
;
881 // Get the name of the fields to insert
882 $fields .= $fnameq . ", ";
887 // If there were any inserted fields then build the rest of the insert query.
888 if ($fieldInsertedCount <= 0) return false;
890 // Get the table name from the existing query.
892 if (!empty($rs->tableName
)) $tableName = $rs->tableName
;
893 else if (preg_match("/FROM\s+".ADODB_TABLE_REGEX
."/is", $rs->sql
, $tableName))
894 $tableName = $tableName[1];
899 // Strip off the comma and space on the end of both the fields
901 $fields = substr($fields, 0, -2);
902 $values = substr($values, 0, -2);
904 // Append the fields and their values to the insert query.
905 return 'INSERT INTO '.$tableName.' ( '.$fields.' ) VALUES ( '.$values.' )';
910 * This private method is used to help construct
911 * the update/sql which is generated by GetInsertSQL and GetUpdateSQL.
912 * It handles the string construction of 1 column -> sql string based on
913 * the column type. We want to do 'safe' handling of BLOBs
915 * @param string the type of sql we are trying to create
917 * @param string column data type from the db::MetaType() method
918 * @param string the column name
919 * @param array the column value
924 function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq)
928 // Based on the datatype of the field
929 // Format the value properly for the database
932 //in order to handle Blobs correctly, we need
933 //to do some magic for Oracle
935 //we need to create a new descriptor to handle
937 if (!empty($zthis->hasReturningInto
)) {
938 if ($action == 'I') {
939 $sql = 'empty_blob(), ';
941 $sql = $fnameq. '=empty_blob(), ';
943 //add the variable to the returning clause array
944 //so the user can build this later in
945 //case they want to add more to it
946 $zthis->_returningArray
[$fname] = ':xx'.$fname.'xx';
947 } else if (empty($arrFields[$fname])){
948 if ($action == 'I') {
949 $sql = 'empty_blob(), ';
951 $sql = $fnameq. '=empty_blob(), ';
954 //this is to maintain compatibility
955 //with older adodb versions.
956 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
961 //we need to do some more magic here for long variables
962 //to handle these correctly in oracle.
964 //create a safe bind var name
965 //to avoid conflicts w/ dupes.
966 if (!empty($zthis->hasReturningInto
)) {
967 if ($action == 'I') {
968 $sql = ':xx'.$fname.'xx, ';
970 $sql = $fnameq.'=:xx'.$fname.'xx, ';
972 //add the variable to the returning clause array
973 //so the user can build this later in
974 //case they want to add more to it
975 $zthis->_returningArray
[$fname] = ':xx'.$fname.'xx';
977 //this is to maintain compatibility
978 //with older adodb versions.
979 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
984 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
991 function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true)
995 switch($zthis->dataProvider
) {
997 if ($type == 'L') $type = 'C';
1000 return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq);
1009 $val = $zthis->qstr($arrFields[$fname],$magicq);
1013 $val = $zthis->DBDate($arrFields[$fname]);
1017 $val = $zthis->DBTimeStamp($arrFields[$fname]);
1021 $val = $arrFields[$fname];
1022 if (!is_numeric($val)) $val = str_replace(',', '.', (float)$val);
1027 $val = $arrFields[$fname];
1028 if (!is_numeric($val)) $val = (integer) $val;
1032 $val = str_replace(array("'"," ","("),"",$arrFields[$fname]); // basic sql injection defence
1033 if (empty($val)) $val = '0';
1037 if ($action == 'I') return $val . ", ";
1040 return $fnameq . "=" . $val . ", ";
1046 function _adodb_debug_execute(&$zthis, $sql, $inputarr)
1050 foreach($inputarr as $kk=>$vv) {
1051 if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
1052 if (is_null($vv)) $ss .= "($kk=>null) ";
1053 else $ss .= "($kk=>'$vv') ";
1057 $sqlTxt = is_array($sql) ?
$sql[0] : $sql;
1058 /*str_replace(', ','##1#__^LF',is_array($sql) ? $sql[0] : $sql);
1059 $sqlTxt = str_replace(',',', ',$sqlTxt);
1060 $sqlTxt = str_replace('##1#__^LF', ', ' ,$sqlTxt);
1062 // check if running from browser or command-line
1063 $inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
1065 $dbt = $zthis->databaseType
;
1066 if (isset($zthis->dsnType
)) $dbt .= '-'.$zthis->dsnType
;
1069 $ss = '<code>'.htmlspecialchars($ss).'</code>';
1071 if ($zthis->debug
=== -1)
1072 ADOConnection
::outp( "<br>\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<br>\n",false);
1073 else if ($zthis->debug
!== -99)
1074 ADOConnection
::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<hr>\n",false);
1077 if ($zthis->debug
!== -99)
1078 ADOConnection
::outp("-----<hr>\n($dbt): ".$sqlTxt." $ss\n-----<hr>\n",false);
1081 $qID = $zthis->_query($sql,$inputarr);
1084 Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
1085 because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
1087 if ($zthis->databaseType
== 'mssql') {
1088 // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
1090 if($emsg = $zthis->ErrorMsg()) {
1091 if ($err = $zthis->ErrorNo()) {
1092 if ($zthis->debug
=== -99)
1093 ADOConnection
::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<hr>\n",false);
1095 ADOConnection
::outp($err.': '.$emsg);
1100 if ($zthis->debug
=== -99)
1101 if ($inBrowser) ADOConnection
::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<hr>\n",false);
1102 else ADOConnection
::outp("-----<hr>\n($dbt): ".$sqlTxt."$ss\n-----<hr>\n",false);
1104 ADOConnection
::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
1107 if ($zthis->debug
=== 99) _adodb_backtrace(true,9999,2);
1111 # pretty print the debug_backtrace function
1112 function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0,$ishtml=null)
1114 if (!function_exists('debug_backtrace')) return '';
1116 if ($ishtml === null) $html = (isset($_SERVER['HTTP_USER_AGENT']));
1117 else $html = $ishtml;
1119 $fmt = ($html) ?
"</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
1123 $s = ($html) ?
'<pre align=left>' : '';
1125 if (is_array($printOrArr)) $traceArr = $printOrArr;
1126 else $traceArr = debug_backtrace();
1127 array_shift($traceArr);
1128 array_shift($traceArr);
1129 $tabs = sizeof($traceArr)-2;
1131 foreach ($traceArr as $arr) {
1132 if ($skippy) {$skippy -= 1; continue;}
1134 if ($levels < 0) break;
1137 for ($i=0; $i < $tabs; $i++
) $s .= ($html) ?
' ' : "\t";
1139 if ($html) $s .= '<font face="Courier New,Courier">';
1140 if (isset($arr['class'])) $s .= $arr['class'].'.';
1141 if (isset($arr['args']))
1142 foreach($arr['args'] as $v) {
1143 if (is_null($v)) $args[] = 'null';
1144 else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
1145 else if (is_object($v)) $args[] = 'Object:'.get_class($v);
1146 else if (is_bool($v)) $args[] = $v ?
'true' : 'false';
1149 $str = htmlspecialchars(str_replace(array("\r","\n"),' ',substr($v,0,$MAXSTRLEN)));
1150 if (strlen($v) > $MAXSTRLEN) $str .= '...';
1154 $s .= $arr['function'].'('.implode(', ',$args).')';
1157 $s .= @sprintf
($fmt, $arr['line'],$arr['file'],basename($arr['file']));
1161 if ($html) $s .= '</pre>';
1162 if ($printOrArr) print $s;
1167 function _adodb_find_from($sql)
1170 $sql = str_replace(array("\n","\r"), ' ', $sql);
1171 $charCount = strlen($sql);
1175 $parentheseCount = 0;
1180 for($i = 0; $i < $charCount; $i++) {
1182 $char = substr($sql,$i,1);
1183 $prevChars = substr($sql,0,$i);
1184 $nextChars = substr($sql,$i+1);
1186 if((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === false) {
1191 elseif((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === true && $quote == $char) {
1196 elseif($char == "(" && $inString === false)
1199 elseif($char == ")" && $inString === false && $parentheseCount > 0)
1202 elseif($parentheseCount <= 0 && $inString === false && $char == " " && strtoupper(substr($prevChars,-5,5)) == " FROM")