Showing help when calling script/setup without parameters.
[akelos.git] / vendor / adodb / adodb-lib.inc.php
blob507e5be1de184cfac62b797d613ac69b4b5a6555
1 <?php
3 // security - hide paths
4 if (!defined('ADODB_DIR')) die();
6 global $ADODB_INCLUDED_LIB;
7 $ADODB_INCLUDED_LIB = 1;
9 /*
10 @version V4.64 20 June 2005 (c) 2000-2005 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.
17 */
20 // Force key to upper.
21 // See also http://www.php.net/manual/en/function.array-change-key-case.php
22 function _array_change_key_case($an_array)
24 if (is_array($an_array)) {
25 $new_array = array();
26 foreach($an_array as $key=>$value)
27 $new_array[strtoupper($key)] = $value;
29 return $new_array;
32 return $an_array;
35 function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc)
37 if (count($fieldArray) == 0) return 0;
38 $first = true;
39 $uSet = '';
41 if (!is_array($keyCol)) {
42 $keyCol = array($keyCol);
44 foreach($fieldArray as $k => $v) {
45 if ($autoQuote && !is_numeric($v) and strncmp($v,"'",1) !== 0 and strcasecmp($v,'null')!=0) {
46 $v = $zthis->qstr($v);
47 $fieldArray[$k] = $v;
49 if (in_array($k,$keyCol)) continue; // skip UPDATE if is key
51 if ($first) {
52 $first = false;
53 $uSet = "$k=$v";
54 } else
55 $uSet .= ",$k=$v";
58 $where = false;
59 foreach ($keyCol as $v) {
60 if ($where) $where .= " and $v=$fieldArray[$v]";
61 else $where = "$v=$fieldArray[$v]";
64 if ($uSet && $where) {
65 $update = "UPDATE $table SET $uSet WHERE $where";
67 $rs = $zthis->Execute($update);
70 if ($rs) {
71 if ($zthis->poorAffectedRows) {
73 The Select count(*) wipes out any errors that the update would have returned.
74 http://phplens.com/lens/lensforum/msgs.php?id=5696
76 if ($zthis->ErrorNo()<>0) return 0;
78 # affected_rows == 0 if update field values identical to old values
79 # for mysql - which is silly.
81 $cnt = $zthis->GetOne("select count(*) from $table where $where");
82 if ($cnt > 0) return 1; // record already exists
83 } else {
84 if (($zthis->Affected_Rows()>0)) return 1;
86 } else
87 return 0;
90 // print "<p>Error=".$this->ErrorNo().'<p>';
91 $first = true;
92 foreach($fieldArray as $k => $v) {
93 if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
95 if ($first) {
96 $first = false;
97 $iCols = "$k";
98 $iVals = "$v";
99 } else {
100 $iCols .= ",$k";
101 $iVals .= ",$v";
104 $insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
105 $rs = $zthis->Execute($insert);
106 return ($rs) ? 2 : 0;
109 // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
110 function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
111 $size=0, $selectAttr='',$compareFields0=true)
113 $hasvalue = false;
115 if ($multiple or is_array($defstr)) {
116 if ($size==0) $size=5;
117 $attr = ' multiple size="'.$size.'"';
118 if (!strpos($name,'[]')) $name .= '[]';
119 } else if ($size) $attr = ' size="'.$size.'"';
120 else $attr ='';
122 $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
123 if ($blank1stItem)
124 if (is_string($blank1stItem)) {
125 $barr = explode(':',$blank1stItem);
126 if (sizeof($barr) == 1) $barr[] = '';
127 $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
128 } else $s .= "\n<option></option>";
130 if ($zthis->FieldCount() > 1) $hasvalue=true;
131 else $compareFields0 = true;
133 $value = '';
134 $optgroup = null;
135 $firstgroup = true;
136 $fieldsize = sizeof($zthis->fields);
137 while(!$zthis->EOF) {
138 $zval = rtrim(reset($zthis->fields));
140 if ($blank1stItem && $zval=="") {
141 $zthis->MoveNext();
142 continue;
145 if ($fieldsize > 1) {
146 if (isset($zthis->fields[1]))
147 $zval2 = rtrim($zthis->fields[1]);
148 else
149 $zval2 = rtrim(next($zthis->fields));
151 $selected = ($compareFields0) ? $zval : $zval2;
153 $group = '';
154 if ($fieldsize > 2) {
155 $group = rtrim($zthis->fields[2]);
158 if ($optgroup != $group) {
159 $optgroup = $group;
160 if ($firstgroup) {
161 $firstgroup = false;
162 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
163 } else {
164 $s .="\n</optgroup>";
165 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
169 if ($hasvalue)
170 $value = " value='".htmlspecialchars($zval2)."'";
172 if (is_array($defstr)) {
174 if (in_array($selected,$defstr))
175 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
176 else
177 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
179 else {
180 if (strcasecmp($selected,$defstr)==0)
181 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
182 else
183 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
185 $zthis->MoveNext();
186 } // while
188 // closing last optgroup
189 if($optgroup != null) {
190 $s .= "\n</optgroup>";
192 return $s ."\n</select>\n";
195 // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
196 function _adodb_getmenu_gp(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
197 $size=0, $selectAttr='',$compareFields0=true)
199 $hasvalue = false;
201 if ($multiple or is_array($defstr)) {
202 if ($size==0) $size=5;
203 $attr = ' multiple size="'.$size.'"';
204 if (!strpos($name,'[]')) $name .= '[]';
205 } else if ($size) $attr = ' size="'.$size.'"';
206 else $attr ='';
208 $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
209 if ($blank1stItem)
210 if (is_string($blank1stItem)) {
211 $barr = explode(':',$blank1stItem);
212 if (sizeof($barr) == 1) $barr[] = '';
213 $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
214 } else $s .= "\n<option></option>";
216 if ($zthis->FieldCount() > 1) $hasvalue=true;
217 else $compareFields0 = true;
219 $value = '';
220 $optgroup = null;
221 $firstgroup = true;
222 $fieldsize = sizeof($zthis->fields);
223 while(!$zthis->EOF) {
224 $zval = rtrim(reset($zthis->fields));
226 if ($blank1stItem && $zval=="") {
227 $zthis->MoveNext();
228 continue;
231 if ($fieldsize > 1) {
232 if (isset($zthis->fields[1]))
233 $zval2 = rtrim($zthis->fields[1]);
234 else
235 $zval2 = rtrim(next($zthis->fields));
237 $selected = ($compareFields0) ? $zval : $zval2;
239 $group = '';
240 if (isset($zthis->fields[2])) {
241 $group = rtrim($zthis->fields[2]);
244 if ($optgroup != $group) {
245 $optgroup = $group;
246 if ($firstgroup) {
247 $firstgroup = false;
248 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
249 } else {
250 $s .="\n</optgroup>";
251 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
255 if ($hasvalue)
256 $value = " value='".htmlspecialchars($zval2)."'";
258 if (is_array($defstr)) {
260 if (in_array($selected,$defstr))
261 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
262 else
263 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
265 else {
266 if (strcasecmp($selected,$defstr)==0)
267 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
268 else
269 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
271 $zthis->MoveNext();
272 } // while
274 // closing last optgroup
275 if($optgroup != null) {
276 $s .= "\n</optgroup>";
278 return $s ."\n</select>\n";
283 Count the number of records this sql statement will return by using
284 query rewriting techniques...
286 Does not work with UNIONs, except with postgresql and oracle.
288 function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
290 $qryRecs = 0;
292 if (preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) ||
293 preg_match('/\s+GROUP\s+BY\s+/is',$sql) ||
294 preg_match('/\s+UNION\s+/is',$sql)) {
295 // ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias
296 // but this is only supported by oracle and postgresql...
297 if ($zthis->dataProvider == 'oci8') {
299 $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
301 // Allow Oracle hints to be used for query optimization, Chris Wrye
302 if (preg_match('#/\\*+.*?\\*\\/#', $sql, $hint)) {
303 $rewritesql = "SELECT ".$hint[0]." COUNT(*) FROM (".$rewritesql.")";
304 } else
305 $rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")";
307 } else if (strncmp($zthis->databaseType,'postgres',8) == 0) {
309 $info = $zthis->ServerInfo();
310 if (substr($info['version'],0,3) >= 7.1) { // good till version 999
311 $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$sql);
312 $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
315 } else {
316 // now replace SELECT ... FROM with SELECT COUNT(*) FROM
317 $rewritesql = preg_replace(
318 '/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql);
320 // fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails
321 // with mssql, access and postgresql. Also a good speedup optimization - skips sorting!
322 $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$rewritesql);
325 if (isset($rewritesql) && $rewritesql != $sql) {
326 if ($secs2cache) {
327 // we only use half the time of secs2cache because the count can quickly
328 // become inaccurate if new records are added
329 $qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr);
331 } else {
332 $qryRecs = $zthis->GetOne($rewritesql,$inputarr);
334 if ($qryRecs !== false) return $qryRecs;
336 //--------------------------------------------
337 // query rewrite failed - so try slower way...
340 // strip off unneeded ORDER BY if no UNION
341 if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql;
342 else $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
344 $rstest = &$zthis->Execute($rewritesql,$inputarr);
345 if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr);
347 if ($rstest) {
348 $qryRecs = $rstest->RecordCount();
349 if ($qryRecs == -1) {
350 global $ADODB_EXTENSION;
351 // some databases will return -1 on MoveLast() - change to MoveNext()
352 if ($ADODB_EXTENSION) {
353 while(!$rstest->EOF) {
354 adodb_movenext($rstest);
356 } else {
357 while(!$rstest->EOF) {
358 $rstest->MoveNext();
361 $qryRecs = $rstest->_currentRow;
363 $rstest->Close();
364 if ($qryRecs == -1) return 0;
367 return $qryRecs;
371 Code originally from "Cornel G" <conyg@fx.ro>
373 This code might not work with SQL that has UNION in it
375 Also if you are using CachePageExecute(), there is a strong possibility that
376 data will get out of synch. use CachePageExecute() only with tables that
377 rarely change.
379 function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
380 $inputarr=false, $secs2cache=0)
382 $atfirstpage = false;
383 $atlastpage = false;
384 $lastpageno=1;
386 // If an invalid nrows is supplied,
387 // we assume a default value of 10 rows per page
388 if (!isset($nrows) || $nrows <= 0) $nrows = 10;
390 $qryRecs = false; //count records for no offset
392 $qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache);
393 $lastpageno = (int) ceil($qryRecs / $nrows);
394 $zthis->_maxRecordCount = $qryRecs;
398 // ***** Here we check whether $page is the last page or
399 // whether we are trying to retrieve
400 // a page number greater than the last page number.
401 if ($page >= $lastpageno) {
402 $page = $lastpageno;
403 $atlastpage = true;
406 // If page number <= 1, then we are at the first page
407 if (empty($page) || $page <= 1) {
408 $page = 1;
409 $atfirstpage = true;
412 // We get the data we want
413 $offset = $nrows * ($page-1);
414 if ($secs2cache > 0)
415 $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
416 else
417 $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
420 // Before returning the RecordSet, we set the pagination properties we need
421 if ($rsreturn) {
422 $rsreturn->_maxRecordCount = $qryRecs;
423 $rsreturn->rowsPerPage = $nrows;
424 $rsreturn->AbsolutePage($page);
425 $rsreturn->AtFirstPage($atfirstpage);
426 $rsreturn->AtLastPage($atlastpage);
427 $rsreturn->LastPageNo($lastpageno);
429 return $rsreturn;
432 // Iván Oliva version
433 function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
436 $atfirstpage = false;
437 $atlastpage = false;
439 if (!isset($page) || $page <= 1) { // If page number <= 1, then we are at the first page
440 $page = 1;
441 $atfirstpage = true;
443 if ($nrows <= 0) $nrows = 10; // If an invalid nrows is supplied, we assume a default value of 10 rows per page
445 // ***** Here we check whether $page is the last page or whether we are trying to retrieve a page number greater than
446 // the last page number.
447 $pagecounter = $page + 1;
448 $pagecounteroffset = ($pagecounter * $nrows) - $nrows;
449 if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
450 else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
451 if ($rstest) {
452 while ($rstest && $rstest->EOF && $pagecounter>0) {
453 $atlastpage = true;
454 $pagecounter--;
455 $pagecounteroffset = $nrows * ($pagecounter - 1);
456 $rstest->Close();
457 if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
458 else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
460 if ($rstest) $rstest->Close();
462 if ($atlastpage) { // If we are at the last page or beyond it, we are going to retrieve it
463 $page = $pagecounter;
464 if ($page == 1) $atfirstpage = true; // We have to do this again in case the last page is the same as the first
465 //... page, that is, the recordset has only 1 page.
468 // We get the data we want
469 $offset = $nrows * ($page-1);
470 if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
471 else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
473 // Before returning the RecordSet, we set the pagination properties we need
474 if ($rsreturn) {
475 $rsreturn->rowsPerPage = $nrows;
476 $rsreturn->AbsolutePage($page);
477 $rsreturn->AtFirstPage($atfirstpage);
478 $rsreturn->AtLastPage($atlastpage);
480 return $rsreturn;
483 function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2)
485 if (!$rs) {
486 printf(ADODB_BAD_RS,'GetUpdateSQL');
487 return false;
490 $fieldUpdatedCount = 0;
491 $arrFields = _array_change_key_case($arrFields);
493 $hasnumeric = isset($rs->fields[0]);
494 $setFields = '';
496 // Loop through all of the fields in the recordset
497 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
498 // Get the field from the recordset
499 $field = $rs->FetchField($i);
501 // If the recordset field is one
502 // of the fields passed in then process.
503 $upperfname = strtoupper($field->name);
504 if (adodb_key_exists($upperfname,$arrFields,$force)) {
506 // If the existing field value in the recordset
507 // is different from the value passed in then
508 // go ahead and append the field name and new value to
509 // the update query.
511 if ($hasnumeric) $val = $rs->fields[$i];
512 else if (isset($rs->fields[$upperfname])) $val = $rs->fields[$upperfname];
513 else if (isset($rs->fields[$field->name])) $val = $rs->fields[$field->name];
514 else if (isset($rs->fields[strtolower($upperfname)])) $val = $rs->fields[strtolower($upperfname)];
515 else $val = '';
518 if ($forceUpdate || strcmp($val, $arrFields[$upperfname])) {
519 // Set the counter for the number of fields that will be updated.
520 $fieldUpdatedCount++;
522 // Based on the datatype of the field
523 // Format the value properly for the database
524 $type = $rs->MetaType($field->type);
527 if ($type == 'null') {
528 $type = 'C';
531 if (strpos($upperfname,' ') !== false)
532 $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
533 else
534 $fnameq = $upperfname;
537 // is_null requires php 4.0.4
538 //********************************************************//
539 if (is_null($arrFields[$upperfname])
540 || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
541 || $arrFields[$upperfname] === 'null'
544 switch ($force) {
546 //case 0:
547 // //Ignore empty values. This is allready handled in "adodb_key_exists" function.
548 //break;
550 case 1:
551 //Set null
552 $setFields .= $field->name . " = null, ";
553 break;
555 case 2:
556 //Set empty
557 $arrFields[$upperfname] = "";
558 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
559 break;
560 default:
561 case 3:
562 //Set the value that was given in array, so you can give both null and empty values
563 if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === 'null') {
564 $setFields .= $field->name . " = null, ";
565 } else {
566 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
568 break;
570 //********************************************************//
571 } else {
572 //we do this so each driver can customize the sql for
573 //DB specific column types.
574 //Oracle needs BLOB types to be handled with a returning clause
575 //postgres has special needs as well
576 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
577 $arrFields, $magicq);
583 // If there were any modified fields then build the rest of the update query.
584 if ($fieldUpdatedCount > 0 || $forceUpdate) {
585 // Get the table name from the existing query.
586 if (!empty($rs->tableName)) $tableName = $rs->tableName;
587 else preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
589 // Get the full where clause excluding the word "WHERE" from
590 // the existing query.
591 preg_match('/\sWHERE\s(.*)/is', $rs->sql, $whereClause);
593 $discard = false;
594 // not a good hack, improvements?
595 if ($whereClause) {
596 if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
597 else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard));
598 else preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard);
599 } else
600 $whereClause = array(false,false);
602 if ($discard)
603 $whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
605 $sql = 'UPDATE '.$tableName[1].' SET '.substr($setFields, 0, -2);
606 if (strlen($whereClause[1]) > 0)
607 $sql .= ' WHERE '.$whereClause[1];
609 return $sql;
611 } else {
612 return false;
616 function adodb_key_exists($key, &$arr,$force=2)
618 if ($force<=0) {
619 // the following is the old behaviour where null or empty fields are ignored
620 return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0);
623 if (isset($arr[$key])) return true;
624 ## null check below
625 if (ADODB_PHPVER >= 0x4010) return array_key_exists($key,$arr);
626 return false;
630 * There is a special case of this function for the oci8 driver.
631 * The proper way to handle an insert w/ a blob in oracle requires
632 * a returning clause with bind variables and a descriptor blob.
636 function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2)
638 static $cacheRS = false;
639 static $cacheSig = 0;
640 static $cacheCols;
642 $tableName = '';
643 $values = '';
644 $fields = '';
645 $recordSet = null;
646 $arrFields = _array_change_key_case($arrFields);
647 $fieldInsertedCount = 0;
649 if (is_string($rs)) {
650 //ok we have a table name
651 //try and get the column info ourself.
652 $tableName = $rs;
654 //we need an object for the recordSet
655 //because we have to call MetaType.
656 //php can't do a $rsclass::MetaType()
657 $rsclass = $zthis->rsPrefix.$zthis->databaseType;
658 $recordSet =& new $rsclass(-1,$zthis->fetchMode);
659 $recordSet->connection = &$zthis;
661 if (is_string($cacheRS) && $cacheRS == $rs) {
662 $columns =& $cacheCols;
663 } else {
664 $columns = $zthis->MetaColumns( $tableName );
665 $cacheRS = $tableName;
666 $cacheCols = $columns;
668 } else if (is_subclass_of($rs, 'adorecordset')) {
669 if (isset($rs->insertSig) && is_integer($cacheRS) && $cacheRS == $rs->insertSig) {
670 $columns =& $cacheCols;
671 } else {
672 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++)
673 $columns[] = $rs->FetchField($i);
674 $cacheRS = $cacheSig;
675 $cacheCols = $columns;
676 $rs->insertSig = $cacheSig++;
678 $recordSet =& $rs;
680 } else {
681 printf(ADODB_BAD_RS,'GetInsertSQL');
682 return false;
685 // Loop through all of the fields in the recordset
686 foreach( $columns as $field ) {
687 $upperfname = strtoupper($field->name);
688 if (adodb_key_exists($upperfname,$arrFields,$force)) {
689 $bad = false;
690 if (strpos($upperfname,' ') !== false)
691 $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
692 else
693 $fnameq = $upperfname;
695 $type = $recordSet->MetaType($field->type);
697 /********************************************************/
698 if (is_null($arrFields[$upperfname])
699 || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
700 || $arrFields[$upperfname] === 'null'
703 switch ($force) {
705 case 0: // we must always set null if missing
706 $bad = true;
707 break;
709 case 1:
710 $values .= "null, ";
711 break;
713 case 2:
714 //Set empty
715 $arrFields[$upperfname] = "";
716 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq);
717 break;
719 default:
720 case 3:
721 //Set the value that was given in array, so you can give both null and empty values
722 if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === 'null') {
723 $values .= "null, ";
724 } else {
725 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq);
727 break;
728 } // switch
730 /*********************************************************/
731 } else {
732 //we do this so each driver can customize the sql for
733 //DB specific column types.
734 //Oracle needs BLOB types to be handled with a returning clause
735 //postgres has special needs as well
736 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,
737 $arrFields, $magicq);
740 if ($bad) continue;
741 // Set the counter for the number of fields that will be inserted.
742 $fieldInsertedCount++;
745 // Get the name of the fields to insert
746 $fields .= $fnameq . ", ";
751 // If there were any inserted fields then build the rest of the insert query.
752 if ($fieldInsertedCount <= 0) return false;
754 // Get the table name from the existing query.
755 if (!$tableName) {
756 if (!empty($rs->tableName)) $tableName = $rs->tableName;
757 else if (preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName))
758 $tableName = $tableName[1];
759 else
760 return false;
763 // Strip off the comma and space on the end of both the fields
764 // and their values.
765 $fields = substr($fields, 0, -2);
766 $values = substr($values, 0, -2);
768 // Append the fields and their values to the insert query.
769 return 'INSERT INTO '.$tableName.' ( '.$fields.' ) VALUES ( '.$values.' )';
774 * This private method is used to help construct
775 * the update/sql which is generated by GetInsertSQL and GetUpdateSQL.
776 * It handles the string construction of 1 column -> sql string based on
777 * the column type. We want to do 'safe' handling of BLOBs
779 * @param string the type of sql we are trying to create
780 * 'I' or 'U'.
781 * @param string column data type from the db::MetaType() method
782 * @param string the column name
783 * @param array the column value
785 * @return string
788 function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq)
790 $sql = '';
792 // Based on the datatype of the field
793 // Format the value properly for the database
794 switch($type) {
795 case 'B':
796 //in order to handle Blobs correctly, we need
797 //to do some magic for Oracle
799 //we need to create a new descriptor to handle
800 //this properly
801 if (!empty($zthis->hasReturningInto)) {
802 if ($action == 'I') {
803 $sql = 'empty_blob(), ';
804 } else {
805 $sql = $fnameq. '=empty_blob(), ';
807 //add the variable to the returning clause array
808 //so the user can build this later in
809 //case they want to add more to it
810 $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
811 } else if (empty($arrFields[$fname])){
812 if ($action == 'I') {
813 $sql = 'empty_blob(), ';
814 } else {
815 $sql = $fnameq. '=empty_blob(), ';
817 } else {
818 //this is to maintain compatibility
819 //with older adodb versions.
820 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
822 break;
824 case "X":
825 //we need to do some more magic here for long variables
826 //to handle these correctly in oracle.
828 //create a safe bind var name
829 //to avoid conflicts w/ dupes.
830 if (!empty($zthis->hasReturningInto)) {
831 if ($action == 'I') {
832 $sql = ':xx'.$fname.'xx, ';
833 } else {
834 $sql = $fnameq.'=:xx'.$fname.'xx, ';
836 //add the variable to the returning clause array
837 //so the user can build this later in
838 //case they want to add more to it
839 $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
840 } else {
841 //this is to maintain compatibility
842 //with older adodb versions.
843 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
845 break;
847 default:
848 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
849 break;
852 return $sql;
855 function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true)
858 if ($recurse) {
859 switch($zthis->dataProvider) {
860 case 'postgres':
861 if ($type == 'L') $type = 'C';
862 break;
863 case 'oci8':
864 return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq);
869 switch($type) {
870 case "C":
871 case "X":
872 case 'B':
873 $val = $zthis->qstr($arrFields[$fname],$magicq);
874 break;
876 case "D":
877 $val = $zthis->DBDate($arrFields[$fname]);
878 break;
880 case "T":
881 $val = $zthis->DBTimeStamp($arrFields[$fname]);
882 break;
884 default:
885 $val = $arrFields[$fname];
886 if (empty($val)) $val = '0';
887 break;
890 if ($action == 'I') return $val . ", ";
893 return $fnameq . "=" . $val . ", ";
899 function _adodb_debug_execute(&$zthis, $sql, $inputarr)
901 $ss = '';
902 if ($inputarr) {
903 foreach($inputarr as $kk=>$vv) {
904 if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
905 $ss .= "($kk=>'$vv') ";
907 $ss = "[ $ss ]";
909 $sqlTxt = is_array($sql) ? $sql[0] : $sql;
910 /*str_replace(', ','##1#__^LF',is_array($sql) ? $sql[0] : $sql);
911 $sqlTxt = str_replace(',',', ',$sqlTxt);
912 $sqlTxt = str_replace('##1#__^LF', ', ' ,$sqlTxt);
914 // check if running from browser or command-line
915 $inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
917 $dbt = $zthis->databaseType;
918 if (isset($zthis->dsnType)) $dbt .= '-'.$zthis->dsnType;
919 if ($inBrowser) {
920 $ss = htmlspecialchars($ss);
921 if ($zthis->debug === -1)
922 ADOConnection::outp( "<br>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; <code>$ss</code>\n<br>\n",false);
923 else
924 ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; <code>$ss</code>\n<hr>\n",false);
925 } else {
926 ADOConnection::outp("-----\n($dbt): ".$sqlTxt."\n-----\n",false);
929 $qID = $zthis->_query($sql,$inputarr);
932 Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
933 because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
935 if ($zthis->databaseType == 'mssql') {
936 // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
937 if($emsg = $zthis->ErrorMsg()) {
938 if ($err = $zthis->ErrorNo()) ADOConnection::outp($err.': '.$emsg);
940 } else if (!$qID) {
941 ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
944 if ($zthis->debug === 99) _adodb_backtrace(true,9999,2);
945 return $qID;
949 function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0)
951 if (PHPVERSION() < 4.3) return '';
953 $html = (isset($_SERVER['HTTP_USER_AGENT']));
954 $fmt = ($html) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
956 $MAXSTRLEN = 128;
958 $s = ($html) ? '<pre align=left>' : '';
960 if (is_array($printOrArr)) $traceArr = $printOrArr;
961 else $traceArr = debug_backtrace();
962 array_shift($traceArr);
963 array_shift($traceArr);
964 $tabs = sizeof($traceArr)-2;
966 foreach ($traceArr as $arr) {
967 if ($skippy) {$skippy -= 1; continue;}
968 $levels -= 1;
969 if ($levels < 0) break;
971 $args = array();
972 for ($i=0; $i < $tabs; $i++) $s .= ($html) ? ' &nbsp; ' : "\t";
973 $tabs -= 1;
974 if ($html) $s .= '<font face="Courier New,Courier">';
975 if (isset($arr['class'])) $s .= $arr['class'].'.';
976 if (isset($arr['args']))
977 foreach($arr['args'] as $v) {
978 if (is_null($v)) $args[] = 'null';
979 else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
980 else if (is_object($v)) $args[] = 'Object:'.get_class($v);
981 else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
982 else {
983 $v = (string) @$v;
984 $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
985 if (strlen($v) > $MAXSTRLEN) $str .= '...';
986 $args[] = $str;
989 $s .= $arr['function'].'('.implode(', ',$args).')';
992 $s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
994 $s .= "\n";
996 if ($html) $s .= '</pre>';
997 if ($printOrArr) print $s;
999 return $s;