3 // security - hide paths
4 if (!defined('ADODB_DIR')) die();
6 global $ADODB_INCLUDED_LIB;
7 $ADODB_INCLUDED_LIB = 1;
10 @version V4.92a 29 Aug 2006 (c) 2000-2006 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';
61 function &adodb_transpose(&$arr, &$newarr, &$hdr)
63 $oldX = sizeof(reset($arr));
69 for ($y = 0; $y < $oldY; $y++
) {
75 for ($x = $startx; $x < $oldX; $x++
) {
77 for ($y = 0; $y < $oldY; $y++
) {
78 $newarr[$x-$startx][] = $arr[$y][$x];
83 // Force key to upper.
84 // See also http://www.php.net/manual/en/function.array-change-key-case.php
85 function _array_change_key_case($an_array)
87 if (is_array($an_array)) {
89 foreach($an_array as $key=>$value)
90 $new_array[strtoupper($key)] = $value;
98 function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc)
100 if (count($fieldArray) == 0) return 0;
104 if (!is_array($keyCol)) {
105 $keyCol = array($keyCol);
107 foreach($fieldArray as $k => $v) {
108 if ($autoQuote && !is_numeric($v) and strncmp($v,"'",1) !== 0 and strcasecmp($v,'null')!=0) {
109 $v = $zthis->qstr($v);
110 $fieldArray[$k] = $v;
112 if (in_array($k,$keyCol)) continue; // skip UPDATE if is key
122 foreach ($keyCol as $v) {
123 if (isset($fieldArray[$v])) {
124 if ($where) $where .= ' and '.$v.'='.$fieldArray[$v];
125 else $where = $v.'='.$fieldArray[$v];
129 if ($uSet && $where) {
130 $update = "UPDATE $table SET $uSet WHERE $where";
132 $rs = $zthis->Execute($update);
136 if ($zthis->poorAffectedRows
) {
138 The Select count(*) wipes out any errors that the update would have returned.
139 http://phplens.com/lens/lensforum/msgs.php?id=5696
141 if ($zthis->ErrorNo()<>0) return 0;
143 # affected_rows == 0 if update field values identical to old values
144 # for mysql - which is silly.
146 $cnt = $zthis->GetOne("select count(*) from $table where $where");
147 if ($cnt > 0) return 1; // record already exists
149 if (($zthis->Affected_Rows()>0)) return 1;
155 // print "<p>Error=".$this->ErrorNo().'<p>';
157 foreach($fieldArray as $k => $v) {
158 if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
169 $insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
170 $rs = $zthis->Execute($insert);
171 return ($rs) ?
2 : 0;
174 // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
175 function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
176 $size=0, $selectAttr='',$compareFields0=true)
180 if ($multiple or is_array($defstr)) {
181 if ($size==0) $size=5;
182 $attr = ' multiple size="'.$size.'"';
183 if (!strpos($name,'[]')) $name .= '[]';
184 } else if ($size) $attr = ' size="'.$size.'"';
187 $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
189 if (is_string($blank1stItem)) {
190 $barr = explode(':',$blank1stItem);
191 if (sizeof($barr) == 1) $barr[] = '';
192 $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
193 } else $s .= "\n<option></option>";
195 if ($zthis->FieldCount() > 1) $hasvalue=true;
196 else $compareFields0 = true;
201 $fieldsize = $zthis->FieldCount();
202 while(!$zthis->EOF
) {
203 $zval = rtrim(reset($zthis->fields
));
205 if ($blank1stItem && $zval=="") {
210 if ($fieldsize > 1) {
211 if (isset($zthis->fields
[1]))
212 $zval2 = rtrim($zthis->fields
[1]);
214 $zval2 = rtrim(next($zthis->fields
));
216 $selected = ($compareFields0) ?
$zval : $zval2;
219 if ($fieldsize > 2) {
220 $group = rtrim($zthis->fields
[2]);
223 if ($optgroup != $group) {
227 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
229 $s .="\n</optgroup>";
230 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
235 $value = " value='".htmlspecialchars($zval2)."'";
237 if (is_array($defstr)) {
239 if (in_array($selected,$defstr))
240 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
242 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
245 if (strcasecmp($selected,$defstr)==0)
246 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
248 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
253 // closing last optgroup
254 if($optgroup != null) {
255 $s .= "\n</optgroup>";
257 return $s ."\n</select>\n";
260 // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
261 function _adodb_getmenu_gp(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
262 $size=0, $selectAttr='',$compareFields0=true)
266 if ($multiple or is_array($defstr)) {
267 if ($size==0) $size=5;
268 $attr = ' multiple size="'.$size.'"';
269 if (!strpos($name,'[]')) $name .= '[]';
270 } else if ($size) $attr = ' size="'.$size.'"';
273 $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
275 if (is_string($blank1stItem)) {
276 $barr = explode(':',$blank1stItem);
277 if (sizeof($barr) == 1) $barr[] = '';
278 $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
279 } else $s .= "\n<option></option>";
281 if ($zthis->FieldCount() > 1) $hasvalue=true;
282 else $compareFields0 = true;
287 $fieldsize = sizeof($zthis->fields
);
288 while(!$zthis->EOF
) {
289 $zval = rtrim(reset($zthis->fields
));
291 if ($blank1stItem && $zval=="") {
296 if ($fieldsize > 1) {
297 if (isset($zthis->fields
[1]))
298 $zval2 = rtrim($zthis->fields
[1]);
300 $zval2 = rtrim(next($zthis->fields
));
302 $selected = ($compareFields0) ?
$zval : $zval2;
305 if (isset($zthis->fields
[2])) {
306 $group = rtrim($zthis->fields
[2]);
309 if ($optgroup != $group) {
313 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
315 $s .="\n</optgroup>";
316 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
321 $value = " value='".htmlspecialchars($zval2)."'";
323 if (is_array($defstr)) {
325 if (in_array($selected,$defstr))
326 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
328 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
331 if (strcasecmp($selected,$defstr)==0)
332 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
334 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
339 // closing last optgroup
340 if($optgroup != null) {
341 $s .= "\n</optgroup>";
343 return $s ."\n</select>\n";
348 Count the number of records this sql statement will return by using
349 query rewriting heuristics...
351 Does not work with UNIONs, except with postgresql and oracle.
356 $cnt = _adodb_getcount($conn, $sql);
359 function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
363 if (!empty($zthis->_nestedSQL
) ||
preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) ||
364 preg_match('/\s+GROUP\s+BY\s+/is',$sql) ||
365 preg_match('/\s+UNION\s+/is',$sql)) {
366 // ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias
367 // but this is only supported by oracle and postgresql...
368 if ($zthis->dataProvider
== 'oci8') {
370 $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$sql);
372 // Allow Oracle hints to be used for query optimization, Chris Wrye
373 if (preg_match('#/\\*+.*?\\*\\/#', $sql, $hint)) {
374 $rewritesql = "SELECT ".$hint[0]." COUNT(*) FROM (".$rewritesql.")";
376 $rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")";
378 } else if (strncmp($zthis->databaseType
,'postgres',8) == 0) {
379 $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$sql);
380 $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
383 // now replace SELECT ... FROM with SELECT COUNT(*) FROM
384 $rewritesql = preg_replace(
385 '/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql);
389 // fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails
390 // with mssql, access and postgresql. Also a good speedup optimization - skips sorting!
391 // also see http://phplens.com/lens/lensforum/msgs.php?id=12752
392 if (preg_match('/\sORDER\s+BY\s*\(/i',$rewritesql))
393 $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$rewritesql);
395 $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$rewritesql);
400 if (isset($rewritesql) && $rewritesql != $sql) {
401 if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[1];
404 // we only use half the time of secs2cache because the count can quickly
405 // become inaccurate if new records are added
406 $qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr);
409 $qryRecs = $zthis->GetOne($rewritesql,$inputarr);
411 if ($qryRecs !== false) return $qryRecs;
413 //--------------------------------------------
414 // query rewrite failed - so try slower way...
417 // strip off unneeded ORDER BY if no UNION
418 if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql;
419 else $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
421 if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
423 $rstest = &$zthis->Execute($rewritesql,$inputarr);
424 if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr);
427 $qryRecs = $rstest->RecordCount();
428 if ($qryRecs == -1) {
429 global $ADODB_EXTENSION;
430 // some databases will return -1 on MoveLast() - change to MoveNext()
431 if ($ADODB_EXTENSION) {
432 while(!$rstest->EOF
) {
433 adodb_movenext($rstest);
436 while(!$rstest->EOF
) {
440 $qryRecs = $rstest->_currentRow
;
443 if ($qryRecs == -1) return 0;
449 Code originally from "Cornel G" <conyg@fx.ro>
451 This code might not work with SQL that has UNION in it
453 Also if you are using CachePageExecute(), there is a strong possibility that
454 data will get out of synch. use CachePageExecute() only with tables that
457 function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
458 $inputarr=false, $secs2cache=0)
460 $atfirstpage = false;
464 // If an invalid nrows is supplied,
465 // we assume a default value of 10 rows per page
466 if (!isset($nrows) ||
$nrows <= 0) $nrows = 10;
468 $qryRecs = false; //count records for no offset
470 $qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache);
471 $lastpageno = (int) ceil($qryRecs / $nrows);
472 $zthis->_maxRecordCount
= $qryRecs;
476 // ***** Here we check whether $page is the last page or
477 // whether we are trying to retrieve
478 // a page number greater than the last page number.
479 if ($page >= $lastpageno) {
484 // If page number <= 1, then we are at the first page
485 if (empty($page) ||
$page <= 1) {
490 // We get the data we want
491 $offset = $nrows * ($page-1);
493 $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
495 $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
498 // Before returning the RecordSet, we set the pagination properties we need
500 $rsreturn->_maxRecordCount
= $qryRecs;
501 $rsreturn->rowsPerPage
= $nrows;
502 $rsreturn->AbsolutePage($page);
503 $rsreturn->AtFirstPage($atfirstpage);
504 $rsreturn->AtLastPage($atlastpage);
505 $rsreturn->LastPageNo($lastpageno);
510 // Iván Oliva version
511 function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
514 $atfirstpage = false;
517 if (!isset($page) ||
$page <= 1) { // If page number <= 1, then we are at the first page
521 if ($nrows <= 0) $nrows = 10; // If an invalid nrows is supplied, we assume a default value of 10 rows per page
523 // ***** Here we check whether $page is the last page or whether we are trying to retrieve a page number greater than
524 // the last page number.
525 $pagecounter = $page +
1;
526 $pagecounteroffset = ($pagecounter * $nrows) - $nrows;
527 if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
528 else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
530 while ($rstest && $rstest->EOF
&& $pagecounter>0) {
533 $pagecounteroffset = $nrows * ($pagecounter - 1);
535 if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
536 else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
538 if ($rstest) $rstest->Close();
540 if ($atlastpage) { // If we are at the last page or beyond it, we are going to retrieve it
541 $page = $pagecounter;
542 if ($page == 1) $atfirstpage = true; // We have to do this again in case the last page is the same as the first
543 //... page, that is, the recordset has only 1 page.
546 // We get the data we want
547 $offset = $nrows * ($page-1);
548 if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
549 else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
551 // Before returning the RecordSet, we set the pagination properties we need
553 $rsreturn->rowsPerPage
= $nrows;
554 $rsreturn->AbsolutePage($page);
555 $rsreturn->AtFirstPage($atfirstpage);
556 $rsreturn->AtLastPage($atlastpage);
561 function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2)
564 printf(ADODB_BAD_RS
,'GetUpdateSQL');
568 $fieldUpdatedCount = 0;
569 $arrFields = _array_change_key_case($arrFields);
571 $hasnumeric = isset($rs->fields
[0]);
574 // Loop through all of the fields in the recordset
575 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++
) {
576 // Get the field from the recordset
577 $field = $rs->FetchField($i);
579 // If the recordset field is one
580 // of the fields passed in then process.
581 $upperfname = strtoupper($field->name
);
582 if (adodb_key_exists($upperfname,$arrFields,$force)) {
584 // If the existing field value in the recordset
585 // is different from the value passed in then
586 // go ahead and append the field name and new value to
589 if ($hasnumeric) $val = $rs->fields
[$i];
590 else if (isset($rs->fields
[$upperfname])) $val = $rs->fields
[$upperfname];
591 else if (isset($rs->fields
[$field->name
])) $val = $rs->fields
[$field->name
];
592 else if (isset($rs->fields
[strtolower($upperfname)])) $val = $rs->fields
[strtolower($upperfname)];
596 if ($forceUpdate ||
strcmp($val, $arrFields[$upperfname])) {
597 // Set the counter for the number of fields that will be updated.
598 $fieldUpdatedCount++
;
600 // Based on the datatype of the field
601 // Format the value properly for the database
602 $type = $rs->MetaType($field->type
);
605 if ($type == 'null') {
609 if (strpos($upperfname,' ') !== false)
610 $fnameq = $zthis->nameQuote
.$upperfname.$zthis->nameQuote
;
612 $fnameq = $upperfname;
615 // is_null requires php 4.0.4
616 //********************************************************//
617 if (is_null($arrFields[$upperfname])
618 ||
(empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
619 ||
$arrFields[$upperfname] === 'null'
625 // //Ignore empty values. This is allready handled in "adodb_key_exists" function.
630 $setFields .= $field->name
. " = null, ";
635 $arrFields[$upperfname] = "";
636 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
640 //Set the value that was given in array, so you can give both null and empty values
641 if (is_null($arrFields[$upperfname]) ||
$arrFields[$upperfname] === 'null') {
642 $setFields .= $field->name
. " = null, ";
644 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
648 //********************************************************//
650 //we do this so each driver can customize the sql for
651 //DB specific column types.
652 //Oracle needs BLOB types to be handled with a returning clause
653 //postgres has special needs as well
654 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
655 $arrFields, $magicq);
661 // If there were any modified fields then build the rest of the update query.
662 if ($fieldUpdatedCount > 0 ||
$forceUpdate) {
663 // Get the table name from the existing query.
664 if (!empty($rs->tableName
)) $tableName = $rs->tableName
;
666 preg_match("/FROM\s+".ADODB_TABLE_REGEX
."/is", $rs->sql
, $tableName);
667 $tableName = $tableName[1];
669 // Get the full where clause excluding the word "WHERE" from
670 // the existing query.
671 preg_match('/\sWHERE\s(.*)/is', $rs->sql
, $whereClause);
674 // not a good hack, improvements?
676 #var_dump($whereClause);
677 if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
678 else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard));
679 else if (preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard));
680 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
682 $whereClause = array(false,false);
685 $whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
687 $sql = 'UPDATE '.$tableName.' SET '.substr($setFields, 0, -2);
688 if (strlen($whereClause[1]) > 0)
689 $sql .= ' WHERE '.$whereClause[1];
698 function adodb_key_exists($key, &$arr,$force=2)
701 // the following is the old behaviour where null or empty fields are ignored
702 return (!empty($arr[$key])) ||
(isset($arr[$key]) && strlen($arr[$key])>0);
705 if (isset($arr[$key])) return true;
707 if (ADODB_PHPVER
>= 0x4010) return array_key_exists($key,$arr);
712 * There is a special case of this function for the oci8 driver.
713 * The proper way to handle an insert w/ a blob in oracle requires
714 * a returning clause with bind variables and a descriptor blob.
718 function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2)
720 static $cacheRS = false;
721 static $cacheSig = 0;
728 $arrFields = _array_change_key_case($arrFields);
729 $fieldInsertedCount = 0;
731 if (is_string($rs)) {
732 //ok we have a table name
733 //try and get the column info ourself.
736 //we need an object for the recordSet
737 //because we have to call MetaType.
738 //php can't do a $rsclass::MetaType()
739 $rsclass = $zthis->rsPrefix
.$zthis->databaseType
;
740 $recordSet = new $rsclass(-1,$zthis->fetchMode
);
741 $recordSet->connection
= &$zthis;
743 if (is_string($cacheRS) && $cacheRS == $rs) {
744 $columns =& $cacheCols;
746 $columns = $zthis->MetaColumns( $tableName );
747 $cacheRS = $tableName;
748 $cacheCols = $columns;
750 } else if (is_subclass_of($rs, 'adorecordset')) {
751 if (isset($rs->insertSig
) && is_integer($cacheRS) && $cacheRS == $rs->insertSig
) {
752 $columns =& $cacheCols;
754 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++
)
755 $columns[] = $rs->FetchField($i);
756 $cacheRS = $cacheSig;
757 $cacheCols = $columns;
758 $rs->insertSig
= $cacheSig++
;
763 printf(ADODB_BAD_RS
,'GetInsertSQL');
767 // Loop through all of the fields in the recordset
768 foreach( $columns as $field ) {
769 $upperfname = strtoupper($field->name
);
770 if (adodb_key_exists($upperfname,$arrFields,$force)) {
772 if (strpos($upperfname,' ') !== false)
773 $fnameq = $zthis->nameQuote
.$upperfname.$zthis->nameQuote
;
775 $fnameq = $upperfname;
777 $type = $recordSet->MetaType($field->type
);
779 /********************************************************/
780 if (is_null($arrFields[$upperfname])
781 ||
(empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
782 ||
$arrFields[$upperfname] === 'null'
787 case 0: // we must always set null if missing
797 $arrFields[$upperfname] = "";
798 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq);
803 //Set the value that was given in array, so you can give both null and empty values
804 if (is_null($arrFields[$upperfname]) ||
$arrFields[$upperfname] === 'null') {
807 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq);
812 /*********************************************************/
814 //we do this so each driver can customize the sql for
815 //DB specific column types.
816 //Oracle needs BLOB types to be handled with a returning clause
817 //postgres has special needs as well
818 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,
819 $arrFields, $magicq);
823 // Set the counter for the number of fields that will be inserted.
824 $fieldInsertedCount++
;
827 // Get the name of the fields to insert
828 $fields .= $fnameq . ", ";
833 // If there were any inserted fields then build the rest of the insert query.
834 if ($fieldInsertedCount <= 0) return false;
836 // Get the table name from the existing query.
838 if (!empty($rs->tableName
)) $tableName = $rs->tableName
;
839 else if (preg_match("/FROM\s+".ADODB_TABLE_REGEX
."/is", $rs->sql
, $tableName))
840 $tableName = $tableName[1];
845 // Strip off the comma and space on the end of both the fields
847 $fields = substr($fields, 0, -2);
848 $values = substr($values, 0, -2);
850 // Append the fields and their values to the insert query.
851 return 'INSERT INTO '.$tableName.' ( '.$fields.' ) VALUES ( '.$values.' )';
856 * This private method is used to help construct
857 * the update/sql which is generated by GetInsertSQL and GetUpdateSQL.
858 * It handles the string construction of 1 column -> sql string based on
859 * the column type. We want to do 'safe' handling of BLOBs
861 * @param string the type of sql we are trying to create
863 * @param string column data type from the db::MetaType() method
864 * @param string the column name
865 * @param array the column value
870 function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq)
874 // Based on the datatype of the field
875 // Format the value properly for the database
878 //in order to handle Blobs correctly, we need
879 //to do some magic for Oracle
881 //we need to create a new descriptor to handle
883 if (!empty($zthis->hasReturningInto
)) {
884 if ($action == 'I') {
885 $sql = 'empty_blob(), ';
887 $sql = $fnameq. '=empty_blob(), ';
889 //add the variable to the returning clause array
890 //so the user can build this later in
891 //case they want to add more to it
892 $zthis->_returningArray
[$fname] = ':xx'.$fname.'xx';
893 } else if (empty($arrFields[$fname])){
894 if ($action == 'I') {
895 $sql = 'empty_blob(), ';
897 $sql = $fnameq. '=empty_blob(), ';
900 //this is to maintain compatibility
901 //with older adodb versions.
902 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
907 //we need to do some more magic here for long variables
908 //to handle these correctly in oracle.
910 //create a safe bind var name
911 //to avoid conflicts w/ dupes.
912 if (!empty($zthis->hasReturningInto
)) {
913 if ($action == 'I') {
914 $sql = ':xx'.$fname.'xx, ';
916 $sql = $fnameq.'=:xx'.$fname.'xx, ';
918 //add the variable to the returning clause array
919 //so the user can build this later in
920 //case they want to add more to it
921 $zthis->_returningArray
[$fname] = ':xx'.$fname.'xx';
923 //this is to maintain compatibility
924 //with older adodb versions.
925 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
930 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
937 function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true)
941 switch($zthis->dataProvider
) {
943 if ($type == 'L') $type = 'C';
946 return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq);
955 $val = $zthis->qstr($arrFields[$fname],$magicq);
959 $val = $zthis->DBDate($arrFields[$fname]);
963 $val = $zthis->DBTimeStamp($arrFields[$fname]);
967 $val = $arrFields[$fname];
968 if (empty($val)) $val = '0';
972 if ($action == 'I') return $val . ", ";
975 return $fnameq . "=" . $val . ", ";
981 function _adodb_debug_execute(&$zthis, $sql, $inputarr)
985 foreach($inputarr as $kk=>$vv) {
986 if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
987 $ss .= "($kk=>'$vv') ";
991 $sqlTxt = is_array($sql) ?
$sql[0] : $sql;
992 /*str_replace(', ','##1#__^LF',is_array($sql) ? $sql[0] : $sql);
993 $sqlTxt = str_replace(',',', ',$sqlTxt);
994 $sqlTxt = str_replace('##1#__^LF', ', ' ,$sqlTxt);
996 // check if running from browser or command-line
997 $inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
999 $dbt = $zthis->databaseType
;
1000 if (isset($zthis->dsnType
)) $dbt .= '-'.$zthis->dsnType
;
1003 $ss = '<code>'.htmlspecialchars($ss).'</code>';
1005 if ($zthis->debug
=== -1)
1006 ADOConnection
::outp( "<br />\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<br />\n",false);
1008 ADOConnection
::outp( "<hr />\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<hr />\n",false);
1010 ADOConnection
::outp("-----\n($dbt): ".$sqlTxt."\n-----\n",false);
1013 $qID = $zthis->_query($sql,$inputarr);
1016 Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
1017 because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
1019 if ($zthis->databaseType
== 'mssql') {
1020 // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
1021 if($emsg = $zthis->ErrorMsg()) {
1022 if ($err = $zthis->ErrorNo()) ADOConnection
::outp($err.': '.$emsg);
1025 ADOConnection
::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
1028 if ($zthis->debug
=== 99) _adodb_backtrace(true,9999,2);
1032 # pretty print the debug_backtrace function
1033 function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0)
1035 if (!function_exists('debug_backtrace')) return '';
1037 $html = (isset($_SERVER['HTTP_USER_AGENT']));
1038 $fmt = ($html) ?
"</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
1042 $s = ($html) ?
'<pre align=left>' : '';
1044 if (is_array($printOrArr)) $traceArr = $printOrArr;
1045 else $traceArr = debug_backtrace();
1046 array_shift($traceArr);
1047 array_shift($traceArr);
1048 $tabs = sizeof($traceArr)-2;
1050 foreach ($traceArr as $arr) {
1051 if ($skippy) {$skippy -= 1; continue;}
1053 if ($levels < 0) break;
1056 for ($i=0; $i < $tabs; $i++
) $s .= ($html) ?
' ' : "\t";
1058 if ($html) $s .= '<font face="Courier New,Courier">';
1059 if (isset($arr['class'])) $s .= $arr['class'].'.';
1060 if (isset($arr['args']))
1061 foreach($arr['args'] as $v) {
1062 if (is_null($v)) $args[] = 'null';
1063 else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
1064 else if (is_object($v)) $args[] = 'Object:'.get_class($v);
1065 else if (is_bool($v)) $args[] = $v ?
'true' : 'false';
1068 $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
1069 if (strlen($v) > $MAXSTRLEN) $str .= '...';
1073 $s .= $arr['function'].'('.implode(', ',$args).')';
1076 $s .= @sprintf
($fmt, $arr['line'],$arr['file'],basename($arr['file']));
1080 if ($html) $s .= '</pre>';
1081 if ($printOrArr) print $s;
1086 function _adodb_find_from($sql)
1089 $sql = str_replace(array("\n","\r"), ' ', $sql);
1090 $charCount = strlen($sql);
1094 $parentheseCount = 0;
1099 for($i = 0; $i < $charCount; $i++) {
1101 $char = substr($sql,$i,1);
1102 $prevChars = substr($sql,0,$i);
1103 $nextChars = substr($sql,$i+1);
1105 if((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === false) {
1110 elseif((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === true && $quote == $char) {
1115 elseif($char == "(" && $inString === false)
1118 elseif($char == ")" && $inString === false && $parentheseCount > 0)
1121 elseif($parentheseCount <= 0 && $inString === false && $char == " " && strtoupper(substr($prevChars,-5,5)) == " FROM")