3 // security - hide paths
4 if (!defined('ADODB_DIR')) die();
6 global $ADODB_INCLUDED_LIB;
7 $ADODB_INCLUDED_LIB = 1;
10 @version V4.94 23 Jan 2007 (c) 2000-2007 John Lim (jlim\@natsoft.com.my). All rights reserved.
11 Released under both BSD license and Lesser GPL library license.
12 Whenever there is any discrepancy between the two licenses,
13 the BSD license will take precedence. See License.txt.
14 Set tabs to 4 for best viewing.
16 Less commonly used functions are placed here to reduce size of adodb.inc.php.
19 function adodb_probetypes(&$array,&$types,$probe=8)
21 // probe and guess the type
23 if ($probe > sizeof($array)) $max = sizeof($array);
27 for ($j=0;$j < $max; $j++
) {
34 if (isset($types[$i]) && $types[$i]=='C') continue;
36 //print " ($i ".$types[$i]. "$v) ";
39 if (!preg_match('/^[+-]{0,1}[0-9\.]+$/',$v)) {
40 $types[$i] = 'C'; // once C, always C
45 // If empty string, we presume is character
46 // test for integer for 1st row only
47 // after that it is up to testing other rows to prove
48 // that it is not an integer
49 if (strlen($v) == 0) $types[$i] = 'C';
50 if (strpos($v,'.') !== false) $types[$i] = 'N';
51 else $types[$i] = 'I';
55 if (strpos($v,'.') !== false) $types[$i] = 'N';
62 function adodb_transpose(&$arr, &$newarr, &$hdr, &$fobjs)
64 $oldX = sizeof(reset($arr));
69 $hdr = array('Fields');
70 for ($y = 0; $y < $oldY; $y++
) {
76 for ($x = $startx; $x < $oldX; $x++
) {
79 $newarr[] = array($o->name
);
83 for ($y = 0; $y < $oldY; $y++
) {
84 $newarr[$x-$startx][] = $arr[$y][$x];
89 // Force key to upper.
90 // See also http://www.php.net/manual/en/function.array-change-key-case.php
91 function _array_change_key_case($an_array)
93 if (is_array($an_array)) {
95 foreach($an_array as $key=>$value)
96 $new_array[strtoupper($key)] = $value;
104 function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc)
106 if (count($fieldArray) == 0) return 0;
110 if (!is_array($keyCol)) {
111 $keyCol = array($keyCol);
113 foreach($fieldArray as $k => $v) {
114 if ($autoQuote && !is_numeric($v) and strncmp($v,"'",1) !== 0 and strcasecmp($v,$zthis->null2null
)!=0) {
115 $v = $zthis->qstr($v);
116 $fieldArray[$k] = $v;
118 if (in_array($k,$keyCol)) continue; // skip UPDATE if is key
128 foreach ($keyCol as $v) {
129 if (isset($fieldArray[$v])) {
130 if ($where) $where .= ' and '.$v.'='.$fieldArray[$v];
131 else $where = $v.'='.$fieldArray[$v];
135 if ($uSet && $where) {
136 $update = "UPDATE $table SET $uSet WHERE $where";
138 $rs = $zthis->Execute($update);
142 if ($zthis->poorAffectedRows
) {
144 The Select count(*) wipes out any errors that the update would have returned.
145 http://phplens.com/lens/lensforum/msgs.php?id=5696
147 if ($zthis->ErrorNo()<>0) return 0;
149 # affected_rows == 0 if update field values identical to old values
150 # for mysql - which is silly.
152 $cnt = $zthis->GetOne("select count(*) from $table where $where");
153 if ($cnt > 0) return 1; // record already exists
155 if (($zthis->Affected_Rows()>0)) return 1;
161 // print "<p>Error=".$this->ErrorNo().'<p>';
163 foreach($fieldArray as $k => $v) {
164 if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
175 $insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
176 $rs = $zthis->Execute($insert);
177 return ($rs) ?
2 : 0;
180 // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
181 function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
182 $size=0, $selectAttr='',$compareFields0=true)
186 if ($multiple or is_array($defstr)) {
187 if ($size==0) $size=5;
188 $attr = ' multiple size="'.$size.'"';
189 if (!strpos($name,'[]')) $name .= '[]';
190 } else if ($size) $attr = ' size="'.$size.'"';
193 $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
195 if (is_string($blank1stItem)) {
196 $barr = explode(':',$blank1stItem);
197 if (sizeof($barr) == 1) $barr[] = '';
198 $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
199 } else $s .= "\n<option></option>";
201 if ($zthis->FieldCount() > 1) $hasvalue=true;
202 else $compareFields0 = true;
207 $fieldsize = $zthis->FieldCount();
208 while(!$zthis->EOF
) {
209 $zval = rtrim(reset($zthis->fields
));
211 if ($blank1stItem && $zval=="") {
216 if ($fieldsize > 1) {
217 if (isset($zthis->fields
[1]))
218 $zval2 = rtrim($zthis->fields
[1]);
220 $zval2 = rtrim(next($zthis->fields
));
222 $selected = ($compareFields0) ?
$zval : $zval2;
225 if ($fieldsize > 2) {
226 $group = rtrim($zthis->fields
[2]);
229 if ($optgroup != $group) {
233 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
235 $s .="\n</optgroup>";
236 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
241 $value = " value='".htmlspecialchars($zval2)."'";
243 if (is_array($defstr)) {
245 if (in_array($selected,$defstr))
246 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
248 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
251 if (strcasecmp($selected,$defstr)==0)
252 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
254 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
259 // closing last optgroup
260 if($optgroup != null) {
261 $s .= "\n</optgroup>";
263 return $s ."\n</select>\n";
266 // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
267 function _adodb_getmenu_gp(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
268 $size=0, $selectAttr='',$compareFields0=true)
272 if ($multiple or is_array($defstr)) {
273 if ($size==0) $size=5;
274 $attr = ' multiple size="'.$size.'"';
275 if (!strpos($name,'[]')) $name .= '[]';
276 } else if ($size) $attr = ' size="'.$size.'"';
279 $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
281 if (is_string($blank1stItem)) {
282 $barr = explode(':',$blank1stItem);
283 if (sizeof($barr) == 1) $barr[] = '';
284 $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
285 } else $s .= "\n<option></option>";
287 if ($zthis->FieldCount() > 1) $hasvalue=true;
288 else $compareFields0 = true;
293 $fieldsize = sizeof($zthis->fields
);
294 while(!$zthis->EOF
) {
295 $zval = rtrim(reset($zthis->fields
));
297 if ($blank1stItem && $zval=="") {
302 if ($fieldsize > 1) {
303 if (isset($zthis->fields
[1]))
304 $zval2 = rtrim($zthis->fields
[1]);
306 $zval2 = rtrim(next($zthis->fields
));
308 $selected = ($compareFields0) ?
$zval : $zval2;
311 if (isset($zthis->fields
[2])) {
312 $group = rtrim($zthis->fields
[2]);
315 if ($optgroup != $group) {
319 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
321 $s .="\n</optgroup>";
322 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
327 $value = " value='".htmlspecialchars($zval2)."'";
329 if (is_array($defstr)) {
331 if (in_array($selected,$defstr))
332 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
334 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
337 if (strcasecmp($selected,$defstr)==0)
338 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
340 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
345 // closing last optgroup
346 if($optgroup != null) {
347 $s .= "\n</optgroup>";
349 return $s ."\n</select>\n";
354 Count the number of records this sql statement will return by using
355 query rewriting heuristics...
357 Does not work with UNIONs, except with postgresql and oracle.
362 $cnt = _adodb_getcount($conn, $sql);
365 function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
369 if (!empty($zthis->_nestedSQL
) ||
preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) ||
370 preg_match('/\s+GROUP\s+BY\s+/is',$sql) ||
371 preg_match('/\s+UNION\s+/is',$sql)) {
372 // ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias
373 // but this is only supported by oracle and postgresql...
374 if ($zthis->dataProvider
== 'oci8') {
376 $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$sql);
378 // Allow Oracle hints to be used for query optimization, Chris Wrye
379 if (preg_match('#/\\*+.*?\\*\\/#', $sql, $hint)) {
380 $rewritesql = "SELECT ".$hint[0]." COUNT(*) FROM (".$rewritesql.")";
382 $rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")";
384 } else if (strncmp($zthis->databaseType
,'postgres',8) == 0) {
385 $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$sql);
386 $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
389 // now replace SELECT ... FROM with SELECT COUNT(*) FROM
390 $rewritesql = preg_replace(
391 '/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql);
395 // fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails
396 // with mssql, access and postgresql. Also a good speedup optimization - skips sorting!
397 // also see http://phplens.com/lens/lensforum/msgs.php?id=12752
398 if (preg_match('/\sORDER\s+BY\s*\(/i',$rewritesql))
399 $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$rewritesql);
401 $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$rewritesql);
406 if (isset($rewritesql) && $rewritesql != $sql) {
407 if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[1];
410 // we only use half the time of secs2cache because the count can quickly
411 // become inaccurate if new records are added
412 $qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr);
415 $qryRecs = $zthis->GetOne($rewritesql,$inputarr);
417 if ($qryRecs !== false) return $qryRecs;
419 //--------------------------------------------
420 // query rewrite failed - so try slower way...
423 // strip off unneeded ORDER BY if no UNION
424 if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql;
425 else $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
427 if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
429 $rstest = &$zthis->Execute($rewritesql,$inputarr);
430 if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr);
433 $qryRecs = $rstest->RecordCount();
434 if ($qryRecs == -1) {
435 global $ADODB_EXTENSION;
436 // some databases will return -1 on MoveLast() - change to MoveNext()
437 if ($ADODB_EXTENSION) {
438 while(!$rstest->EOF
) {
439 adodb_movenext($rstest);
442 while(!$rstest->EOF
) {
446 $qryRecs = $rstest->_currentRow
;
449 if ($qryRecs == -1) return 0;
455 Code originally from "Cornel G" <conyg@fx.ro>
457 This code might not work with SQL that has UNION in it
459 Also if you are using CachePageExecute(), there is a strong possibility that
460 data will get out of synch. use CachePageExecute() only with tables that
463 function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
464 $inputarr=false, $secs2cache=0)
466 $atfirstpage = false;
470 // If an invalid nrows is supplied,
471 // we assume a default value of 10 rows per page
472 if (!isset($nrows) ||
$nrows <= 0) $nrows = 10;
474 $qryRecs = false; //count records for no offset
476 $qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache);
477 $lastpageno = (int) ceil($qryRecs / $nrows);
478 $zthis->_maxRecordCount
= $qryRecs;
482 // ***** Here we check whether $page is the last page or
483 // whether we are trying to retrieve
484 // a page number greater than the last page number.
485 if ($page >= $lastpageno) {
490 // If page number <= 1, then we are at the first page
491 if (empty($page) ||
$page <= 1) {
496 // We get the data we want
497 $offset = $nrows * ($page-1);
499 $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
501 $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
504 // Before returning the RecordSet, we set the pagination properties we need
506 $rsreturn->_maxRecordCount
= $qryRecs;
507 $rsreturn->rowsPerPage
= $nrows;
508 $rsreturn->AbsolutePage($page);
509 $rsreturn->AtFirstPage($atfirstpage);
510 $rsreturn->AtLastPage($atlastpage);
511 $rsreturn->LastPageNo($lastpageno);
516 // Iv�n Oliva version
517 function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
520 $atfirstpage = false;
523 if (!isset($page) ||
$page <= 1) { // If page number <= 1, then we are at the first page
527 if ($nrows <= 0) $nrows = 10; // If an invalid nrows is supplied, we assume a default value of 10 rows per page
529 // ***** Here we check whether $page is the last page or whether we are trying to retrieve a page number greater than
530 // the last page number.
531 $pagecounter = $page +
1;
532 $pagecounteroffset = ($pagecounter * $nrows) - $nrows;
533 if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
534 else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
536 while ($rstest && $rstest->EOF
&& $pagecounter>0) {
539 $pagecounteroffset = $nrows * ($pagecounter - 1);
541 if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
542 else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
544 if ($rstest) $rstest->Close();
546 if ($atlastpage) { // If we are at the last page or beyond it, we are going to retrieve it
547 $page = $pagecounter;
548 if ($page == 1) $atfirstpage = true; // We have to do this again in case the last page is the same as the first
549 //... page, that is, the recordset has only 1 page.
552 // We get the data we want
553 $offset = $nrows * ($page-1);
554 if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
555 else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
557 // Before returning the RecordSet, we set the pagination properties we need
559 $rsreturn->rowsPerPage
= $nrows;
560 $rsreturn->AbsolutePage($page);
561 $rsreturn->AtFirstPage($atfirstpage);
562 $rsreturn->AtLastPage($atlastpage);
567 function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2)
569 global $ADODB_QUOTE_FIELDNAMES;
572 printf(ADODB_BAD_RS
,'GetUpdateSQL');
576 $fieldUpdatedCount = 0;
577 $arrFields = _array_change_key_case($arrFields);
579 $hasnumeric = isset($rs->fields
[0]);
582 // Loop through all of the fields in the recordset
583 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++
) {
584 // Get the field from the recordset
585 $field = $rs->FetchField($i);
587 // If the recordset field is one
588 // of the fields passed in then process.
589 $upperfname = strtoupper($field->name
);
590 if (adodb_key_exists($upperfname,$arrFields,$force)) {
592 // If the existing field value in the recordset
593 // is different from the value passed in then
594 // go ahead and append the field name and new value to
597 if ($hasnumeric) $val = $rs->fields
[$i];
598 else if (isset($rs->fields
[$upperfname])) $val = $rs->fields
[$upperfname];
599 else if (isset($rs->fields
[$field->name
])) $val = $rs->fields
[$field->name
];
600 else if (isset($rs->fields
[strtolower($upperfname)])) $val = $rs->fields
[strtolower($upperfname)];
604 if ($forceUpdate ||
strcmp($val, $arrFields[$upperfname])) {
605 // Set the counter for the number of fields that will be updated.
606 $fieldUpdatedCount++
;
608 // Based on the datatype of the field
609 // Format the value properly for the database
610 $type = $rs->MetaType($field->type
);
613 if ($type == 'null') {
617 if ((strpos($upperfname,' ') !== false) ||
($ADODB_QUOTE_FIELDNAMES))
618 $fnameq = $zthis->nameQuote
.$upperfname.$zthis->nameQuote
;
620 $fnameq = $upperfname;
623 // is_null requires php 4.0.4
624 //********************************************************//
625 if (is_null($arrFields[$upperfname])
626 ||
(empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
627 ||
$arrFields[$upperfname] === $zthis->null2null
633 // //Ignore empty values. This is allready handled in "adodb_key_exists" function.
638 $setFields .= $field->name
. " = null, ";
643 $arrFields[$upperfname] = "";
644 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
648 //Set the value that was given in array, so you can give both null and empty values
649 if (is_null($arrFields[$upperfname]) ||
$arrFields[$upperfname] === $zthis->null2null
) {
650 $setFields .= $field->name
. " = null, ";
652 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
656 //********************************************************//
658 //we do this so each driver can customize the sql for
659 //DB specific column types.
660 //Oracle needs BLOB types to be handled with a returning clause
661 //postgres has special needs as well
662 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
663 $arrFields, $magicq);
669 // If there were any modified fields then build the rest of the update query.
670 if ($fieldUpdatedCount > 0 ||
$forceUpdate) {
671 // Get the table name from the existing query.
672 if (!empty($rs->tableName
)) $tableName = $rs->tableName
;
674 preg_match("/FROM\s+".ADODB_TABLE_REGEX
."/is", $rs->sql
, $tableName);
675 $tableName = $tableName[1];
677 // Get the full where clause excluding the word "WHERE" from
678 // the existing query.
679 preg_match('/\sWHERE\s(.*)/is', $rs->sql
, $whereClause);
682 // not a good hack, improvements?
684 #var_dump($whereClause);
685 if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
686 else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard));
687 else if (preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard));
688 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
690 $whereClause = array(false,false);
693 $whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
695 $sql = 'UPDATE '.$tableName.' SET '.substr($setFields, 0, -2);
696 if (strlen($whereClause[1]) > 0)
697 $sql .= ' WHERE '.$whereClause[1];
706 function adodb_key_exists($key, &$arr,$force=2)
709 // the following is the old behaviour where null or empty fields are ignored
710 return (!empty($arr[$key])) ||
(isset($arr[$key]) && strlen($arr[$key])>0);
713 if (isset($arr[$key])) return true;
715 if (ADODB_PHPVER
>= 0x4010) return array_key_exists($key,$arr);
720 * There is a special case of this function for the oci8 driver.
721 * The proper way to handle an insert w/ a blob in oracle requires
722 * a returning clause with bind variables and a descriptor blob.
726 function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2)
728 static $cacheRS = false;
729 static $cacheSig = 0;
731 global $ADODB_QUOTE_FIELDNAMES;
737 $arrFields = _array_change_key_case($arrFields);
738 $fieldInsertedCount = 0;
740 if (is_string($rs)) {
741 //ok we have a table name
742 //try and get the column info ourself.
745 //we need an object for the recordSet
746 //because we have to call MetaType.
747 //php can't do a $rsclass::MetaType()
748 $rsclass = $zthis->rsPrefix
.$zthis->databaseType
;
749 $recordSet = new $rsclass(-1,$zthis->fetchMode
);
750 $recordSet->connection
= &$zthis;
752 if (is_string($cacheRS) && $cacheRS == $rs) {
753 $columns =& $cacheCols;
755 $columns = $zthis->MetaColumns( $tableName );
756 $cacheRS = $tableName;
757 $cacheCols = $columns;
759 } else if (is_subclass_of($rs, 'adorecordset')) {
760 if (isset($rs->insertSig
) && is_integer($cacheRS) && $cacheRS == $rs->insertSig
) {
761 $columns =& $cacheCols;
763 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++
)
764 $columns[] = $rs->FetchField($i);
765 $cacheRS = $cacheSig;
766 $cacheCols = $columns;
767 $rs->insertSig
= $cacheSig++
;
772 printf(ADODB_BAD_RS
,'GetInsertSQL');
776 // Loop through all of the fields in the recordset
777 foreach( $columns as $field ) {
778 $upperfname = strtoupper($field->name
);
779 if (adodb_key_exists($upperfname,$arrFields,$force)) {
781 if ((strpos($upperfname,' ') !== false) ||
($ADODB_QUOTE_FIELDNAMES))
782 $fnameq = $zthis->nameQuote
.$upperfname.$zthis->nameQuote
;
784 $fnameq = $upperfname;
786 $type = $recordSet->MetaType($field->type
);
788 /********************************************************/
789 if (is_null($arrFields[$upperfname])
790 ||
(empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
791 ||
$arrFields[$upperfname] === $zthis->null2null
796 case 0: // we must always set null if missing
806 $arrFields[$upperfname] = "";
807 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq);
812 //Set the value that was given in array, so you can give both null and empty values
813 if (is_null($arrFields[$upperfname]) ||
$arrFields[$upperfname] === $zthis->null2null
) {
816 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq);
821 /*********************************************************/
823 //we do this so each driver can customize the sql for
824 //DB specific column types.
825 //Oracle needs BLOB types to be handled with a returning clause
826 //postgres has special needs as well
827 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,
828 $arrFields, $magicq);
832 // Set the counter for the number of fields that will be inserted.
833 $fieldInsertedCount++
;
836 // Get the name of the fields to insert
837 $fields .= $fnameq . ", ";
842 // If there were any inserted fields then build the rest of the insert query.
843 if ($fieldInsertedCount <= 0) return false;
845 // Get the table name from the existing query.
847 if (!empty($rs->tableName
)) $tableName = $rs->tableName
;
848 else if (preg_match("/FROM\s+".ADODB_TABLE_REGEX
."/is", $rs->sql
, $tableName))
849 $tableName = $tableName[1];
854 // Strip off the comma and space on the end of both the fields
856 $fields = substr($fields, 0, -2);
857 $values = substr($values, 0, -2);
859 // Append the fields and their values to the insert query.
860 return 'INSERT INTO '.$tableName.' ( '.$fields.' ) VALUES ( '.$values.' )';
865 * This private method is used to help construct
866 * the update/sql which is generated by GetInsertSQL and GetUpdateSQL.
867 * It handles the string construction of 1 column -> sql string based on
868 * the column type. We want to do 'safe' handling of BLOBs
870 * @param string the type of sql we are trying to create
872 * @param string column data type from the db::MetaType() method
873 * @param string the column name
874 * @param array the column value
879 function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq)
883 // Based on the datatype of the field
884 // Format the value properly for the database
887 //in order to handle Blobs correctly, we need
888 //to do some magic for Oracle
890 //we need to create a new descriptor to handle
892 if (!empty($zthis->hasReturningInto
)) {
893 if ($action == 'I') {
894 $sql = 'empty_blob(), ';
896 $sql = $fnameq. '=empty_blob(), ';
898 //add the variable to the returning clause array
899 //so the user can build this later in
900 //case they want to add more to it
901 $zthis->_returningArray
[$fname] = ':xx'.$fname.'xx';
902 } else if (empty($arrFields[$fname])){
903 if ($action == 'I') {
904 $sql = 'empty_blob(), ';
906 $sql = $fnameq. '=empty_blob(), ';
909 //this is to maintain compatibility
910 //with older adodb versions.
911 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
916 //we need to do some more magic here for long variables
917 //to handle these correctly in oracle.
919 //create a safe bind var name
920 //to avoid conflicts w/ dupes.
921 if (!empty($zthis->hasReturningInto
)) {
922 if ($action == 'I') {
923 $sql = ':xx'.$fname.'xx, ';
925 $sql = $fnameq.'=:xx'.$fname.'xx, ';
927 //add the variable to the returning clause array
928 //so the user can build this later in
929 //case they want to add more to it
930 $zthis->_returningArray
[$fname] = ':xx'.$fname.'xx';
932 //this is to maintain compatibility
933 //with older adodb versions.
934 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
939 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
946 function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true)
950 switch($zthis->dataProvider
) {
952 if ($type == 'L') $type = 'C';
955 return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq);
964 $val = $zthis->qstr($arrFields[$fname],$magicq);
968 $val = $zthis->DBDate($arrFields[$fname]);
973 $val = $zthis->DBTimeStamp($arrFields[$fname]);
976 // moodle change start - see readme_moodle.txt
977 case "F": //Floating point number
978 case "N": //Numeric or decimal number
979 $val = (float)$arrFields[$fname];
982 case "L": //Integer field suitable for storing booleans (0 or 1)
986 $val = (int) $arrFields[$fname];
990 $val = str_replace(array("'"," ","("),"",$arrFields[$fname]); // basic sql injection defence
991 if (empty($val)) $val = '0';
995 if ($action == 'I') return $val . ", ";
998 return $fnameq . "=" . $val . ", ";
1004 function _adodb_debug_execute(&$zthis, $sql, $inputarr)
1008 foreach($inputarr as $kk=>$vv) {
1009 if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
1010 $ss .= "($kk=>'$vv') ";
1014 $sqlTxt = is_array($sql) ?
$sql[0] : $sql;
1015 /*str_replace(', ','##1#__^LF',is_array($sql) ? $sql[0] : $sql);
1016 $sqlTxt = str_replace(',',', ',$sqlTxt);
1017 $sqlTxt = str_replace('##1#__^LF', ', ' ,$sqlTxt);
1019 // check if running from browser or command-line
1020 $inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
1022 $dbt = $zthis->databaseType
;
1023 if (isset($zthis->dsnType
)) $dbt .= '-'.$zthis->dsnType
;
1026 $ss = '<code>'.htmlspecialchars($ss).'</code>';
1028 if ($zthis->debug
=== -1)
1029 ADOConnection
::outp( "<br />\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<br />\n",false);
1031 ADOConnection
::outp( "<hr />\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<hr />\n",false);
1033 ADOConnection
::outp("-----\n($dbt): ".$sqlTxt."\n-----\n",false);
1036 $qID = $zthis->_query($sql,$inputarr);
1039 Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
1040 because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
1042 if ($zthis->databaseType
== 'mssql') {
1043 // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
1044 if($emsg = $zthis->ErrorMsg()) {
1045 if ($err = $zthis->ErrorNo()) ADOConnection
::outp($err.': '.$emsg);
1048 ADOConnection
::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
1051 if ($zthis->debug
=== 99) _adodb_backtrace(true,9999,2);
1055 # pretty print the debug_backtrace function
1056 function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0)
1058 if (!function_exists('debug_backtrace')) return '';
1060 $html = (isset($_SERVER['HTTP_USER_AGENT']));
1061 $fmt = ($html) ?
"</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
1065 $s = ($html) ?
'<pre align=left>' : '';
1067 if (is_array($printOrArr)) $traceArr = $printOrArr;
1068 else $traceArr = debug_backtrace();
1069 array_shift($traceArr);
1070 array_shift($traceArr);
1071 $tabs = sizeof($traceArr)-2;
1073 foreach ($traceArr as $arr) {
1074 if ($skippy) {$skippy -= 1; continue;}
1076 if ($levels < 0) break;
1079 for ($i=0; $i < $tabs; $i++
) $s .= ($html) ?
' ' : "\t";
1081 if ($html) $s .= '<font face="Courier New,Courier">';
1082 if (isset($arr['class'])) $s .= $arr['class'].'.';
1083 if (isset($arr['args']))
1084 foreach($arr['args'] as $v) {
1085 if (is_null($v)) $args[] = 'null';
1086 else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
1087 else if (is_object($v)) $args[] = 'Object:'.get_class($v);
1088 else if (is_bool($v)) $args[] = $v ?
'true' : 'false';
1091 $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
1092 if (strlen($v) > $MAXSTRLEN) $str .= '...';
1096 $s .= $arr['function'].'('.implode(', ',$args).')';
1099 $s .= @sprintf
($fmt, $arr['line'],$arr['file'],basename($arr['file']));
1103 if ($html) $s .= '</pre>';
1104 if ($printOrArr) print $s;
1109 function _adodb_find_from($sql)
1112 $sql = str_replace(array("\n","\r"), ' ', $sql);
1113 $charCount = strlen($sql);
1117 $parentheseCount = 0;
1122 for($i = 0; $i < $charCount; $i++) {
1124 $char = substr($sql,$i,1);
1125 $prevChars = substr($sql,0,$i);
1126 $nextChars = substr($sql,$i+1);
1128 if((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === false) {
1133 elseif((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === true && $quote == $char) {
1138 elseif($char == "(" && $inString === false)
1141 elseif($char == ")" && $inString === false && $parentheseCount > 0)
1144 elseif($parentheseCount <= 0 && $inString === false && $char == " " && strtoupper(substr($prevChars,-5,5)) == " FROM")