Documentation TYPO3 par Ameos |
00001 <?php 00002 00003 // security - hide paths 00004 if (!defined('ADODB_DIR')) die(); 00005 00006 global $ADODB_INCLUDED_LIB; 00007 $ADODB_INCLUDED_LIB = 1; 00008 00009 /* 00010 @version V4.93 10 Oct 2006 (c) 2000-2006 John Lim (jlim\@natsoft.com.my). All rights reserved. 00011 Released under both BSD license and Lesser GPL library license. 00012 Whenever there is any discrepancy between the two licenses, 00013 the BSD license will take precedence. See License.txt. 00014 Set tabs to 4 for best viewing. 00015 00016 Less commonly used functions are placed here to reduce size of adodb.inc.php. 00017 */ 00018 00019 function adodb_probetypes(&$array,&$types,$probe=8) 00020 { 00021 // probe and guess the type 00022 $types = array(); 00023 if ($probe > sizeof($array)) $max = sizeof($array); 00024 else $max = $probe; 00025 00026 00027 for ($j=0;$j < $max; $j++) { 00028 $row =& $array[$j]; 00029 if (!$row) break; 00030 $i = -1; 00031 foreach($row as $v) { 00032 $i += 1; 00033 00034 if (isset($types[$i]) && $types[$i]=='C') continue; 00035 00036 //print " ($i ".$types[$i]. "$v) "; 00037 $v = trim($v); 00038 00039 if (!preg_match('/^[+-]{0,1}[0-9\.]+$/',$v)) { 00040 $types[$i] = 'C'; // once C, always C 00041 00042 continue; 00043 } 00044 if ($j == 0) { 00045 // If empty string, we presume is character 00046 // test for integer for 1st row only 00047 // after that it is up to testing other rows to prove 00048 // that it is not an integer 00049 if (strlen($v) == 0) $types[$i] = 'C'; 00050 if (strpos($v,'.') !== false) $types[$i] = 'N'; 00051 else $types[$i] = 'I'; 00052 continue; 00053 } 00054 00055 if (strpos($v,'.') !== false) $types[$i] = 'N'; 00056 00057 } 00058 } 00059 } 00060 00061 function &adodb_transpose(&$arr, &$newarr, &$hdr) 00062 { 00063 $oldX = sizeof(reset($arr)); 00064 $oldY = sizeof($arr); 00065 00066 if ($hdr) { 00067 $startx = 1; 00068 $hdr = array(); 00069 for ($y = 0; $y < $oldY; $y++) { 00070 $hdr[] = $arr[$y][0]; 00071 } 00072 } else 00073 $startx = 0; 00074 00075 for ($x = $startx; $x < $oldX; $x++) { 00076 $newarr[] = array(); 00077 for ($y = 0; $y < $oldY; $y++) { 00078 $newarr[$x-$startx][] = $arr[$y][$x]; 00079 } 00080 } 00081 } 00082 00083 // Force key to upper. 00084 // See also http://www.php.net/manual/en/function.array-change-key-case.php 00085 function _array_change_key_case($an_array) 00086 { 00087 if (is_array($an_array)) { 00088 $new_array = array(); 00089 foreach($an_array as $key=>$value) 00090 $new_array[strtoupper($key)] = $value; 00091 00092 return $new_array; 00093 } 00094 00095 return $an_array; 00096 } 00097 00098 function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc) 00099 { 00100 if (count($fieldArray) == 0) return 0; 00101 $first = true; 00102 $uSet = ''; 00103 00104 if (!is_array($keyCol)) { 00105 $keyCol = array($keyCol); 00106 } 00107 foreach($fieldArray as $k => $v) { 00108 if ($autoQuote && !is_numeric($v) and strncmp($v,"'",1) !== 0 and strcasecmp($v,$zthis->null2null)!=0) { 00109 $v = $zthis->qstr($v); 00110 $fieldArray[$k] = $v; 00111 } 00112 if (in_array($k,$keyCol)) continue; // skip UPDATE if is key 00113 00114 if ($first) { 00115 $first = false; 00116 $uSet = "$k=$v"; 00117 } else 00118 $uSet .= ",$k=$v"; 00119 } 00120 00121 $where = false; 00122 foreach ($keyCol as $v) { 00123 if (isset($fieldArray[$v])) { 00124 if ($where) $where .= ' and '.$v.'='.$fieldArray[$v]; 00125 else $where = $v.'='.$fieldArray[$v]; 00126 } 00127 } 00128 00129 if ($uSet && $where) { 00130 $update = "UPDATE $table SET $uSet WHERE $where"; 00131 00132 $rs = $zthis->Execute($update); 00133 00134 00135 if ($rs) { 00136 if ($zthis->poorAffectedRows) { 00137 /* 00138 The Select count(*) wipes out any errors that the update would have returned. 00139 http://phplens.com/lens/lensforum/msgs.php?id=5696 00140 */ 00141 if ($zthis->ErrorNo()<>0) return 0; 00142 00143 # affected_rows == 0 if update field values identical to old values 00144 # for mysql - which is silly. 00145 00146 $cnt = $zthis->GetOne("select count(*) from $table where $where"); 00147 if ($cnt > 0) return 1; // record already exists 00148 } else { 00149 if (($zthis->Affected_Rows()>0)) return 1; 00150 } 00151 } else 00152 return 0; 00153 } 00154 00155 // print "<p>Error=".$this->ErrorNo().'<p>'; 00156 $first = true; 00157 foreach($fieldArray as $k => $v) { 00158 if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col 00159 00160 if ($first) { 00161 $first = false; 00162 $iCols = "$k"; 00163 $iVals = "$v"; 00164 } else { 00165 $iCols .= ",$k"; 00166 $iVals .= ",$v"; 00167 } 00168 } 00169 $insert = "INSERT INTO $table ($iCols) VALUES ($iVals)"; 00170 $rs = $zthis->Execute($insert); 00171 return ($rs) ? 2 : 0; 00172 } 00173 00174 // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM 00175 function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false, 00176 $size=0, $selectAttr='',$compareFields0=true) 00177 { 00178 $hasvalue = false; 00179 00180 if ($multiple or is_array($defstr)) { 00181 if ($size==0) $size=5; 00182 $attr = ' multiple size="'.$size.'"'; 00183 if (!strpos($name,'[]')) $name .= '[]'; 00184 } else if ($size) $attr = ' size="'.$size.'"'; 00185 else $attr =''; 00186 00187 $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>'; 00188 if ($blank1stItem) 00189 if (is_string($blank1stItem)) { 00190 $barr = explode(':',$blank1stItem); 00191 if (sizeof($barr) == 1) $barr[] = ''; 00192 $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>"; 00193 } else $s .= "\n<option></option>"; 00194 00195 if ($zthis->FieldCount() > 1) $hasvalue=true; 00196 else $compareFields0 = true; 00197 00198 $value = ''; 00199 $optgroup = null; 00200 $firstgroup = true; 00201 $fieldsize = $zthis->FieldCount(); 00202 while(!$zthis->EOF) { 00203 $zval = rtrim(reset($zthis->fields)); 00204 00205 if ($blank1stItem && $zval=="") { 00206 $zthis->MoveNext(); 00207 continue; 00208 } 00209 00210 if ($fieldsize > 1) { 00211 if (isset($zthis->fields[1])) 00212 $zval2 = rtrim($zthis->fields[1]); 00213 else 00214 $zval2 = rtrim(next($zthis->fields)); 00215 } 00216 $selected = ($compareFields0) ? $zval : $zval2; 00217 00218 $group = ''; 00219 if ($fieldsize > 2) { 00220 $group = rtrim($zthis->fields[2]); 00221 } 00222 /* 00223 if ($optgroup != $group) { 00224 $optgroup = $group; 00225 if ($firstgroup) { 00226 $firstgroup = false; 00227 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>"; 00228 } else { 00229 $s .="\n</optgroup>"; 00230 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>"; 00231 } 00232 } 00233 */ 00234 if ($hasvalue) 00235 $value = " value='".htmlspecialchars($zval2)."'"; 00236 00237 if (is_array($defstr)) { 00238 00239 if (in_array($selected,$defstr)) 00240 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>'; 00241 else 00242 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>'; 00243 } 00244 else { 00245 if (strcasecmp($selected,$defstr)==0) 00246 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>'; 00247 else 00248 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>'; 00249 } 00250 $zthis->MoveNext(); 00251 } // while 00252 00253 // closing last optgroup 00254 if($optgroup != null) { 00255 $s .= "\n</optgroup>"; 00256 } 00257 return $s ."\n</select>\n"; 00258 } 00259 00260 // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM 00261 function _adodb_getmenu_gp(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false, 00262 $size=0, $selectAttr='',$compareFields0=true) 00263 { 00264 $hasvalue = false; 00265 00266 if ($multiple or is_array($defstr)) { 00267 if ($size==0) $size=5; 00268 $attr = ' multiple size="'.$size.'"'; 00269 if (!strpos($name,'[]')) $name .= '[]'; 00270 } else if ($size) $attr = ' size="'.$size.'"'; 00271 else $attr =''; 00272 00273 $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>'; 00274 if ($blank1stItem) 00275 if (is_string($blank1stItem)) { 00276 $barr = explode(':',$blank1stItem); 00277 if (sizeof($barr) == 1) $barr[] = ''; 00278 $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>"; 00279 } else $s .= "\n<option></option>"; 00280 00281 if ($zthis->FieldCount() > 1) $hasvalue=true; 00282 else $compareFields0 = true; 00283 00284 $value = ''; 00285 $optgroup = null; 00286 $firstgroup = true; 00287 $fieldsize = sizeof($zthis->fields); 00288 while(!$zthis->EOF) { 00289 $zval = rtrim(reset($zthis->fields)); 00290 00291 if ($blank1stItem && $zval=="") { 00292 $zthis->MoveNext(); 00293 continue; 00294 } 00295 00296 if ($fieldsize > 1) { 00297 if (isset($zthis->fields[1])) 00298 $zval2 = rtrim($zthis->fields[1]); 00299 else 00300 $zval2 = rtrim(next($zthis->fields)); 00301 } 00302 $selected = ($compareFields0) ? $zval : $zval2; 00303 00304 $group = ''; 00305 if (isset($zthis->fields[2])) { 00306 $group = rtrim($zthis->fields[2]); 00307 } 00308 00309 if ($optgroup != $group) { 00310 $optgroup = $group; 00311 if ($firstgroup) { 00312 $firstgroup = false; 00313 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>"; 00314 } else { 00315 $s .="\n</optgroup>"; 00316 $s .="\n<optgroup label='". htmlspecialchars($group) ."'>"; 00317 } 00318 } 00319 00320 if ($hasvalue) 00321 $value = " value='".htmlspecialchars($zval2)."'"; 00322 00323 if (is_array($defstr)) { 00324 00325 if (in_array($selected,$defstr)) 00326 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>'; 00327 else 00328 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>'; 00329 } 00330 else { 00331 if (strcasecmp($selected,$defstr)==0) 00332 $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>'; 00333 else 00334 $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>'; 00335 } 00336 $zthis->MoveNext(); 00337 } // while 00338 00339 // closing last optgroup 00340 if($optgroup != null) { 00341 $s .= "\n</optgroup>"; 00342 } 00343 return $s ."\n</select>\n"; 00344 } 00345 00346 00347 /* 00348 Count the number of records this sql statement will return by using 00349 query rewriting heuristics... 00350 00351 Does not work with UNIONs, except with postgresql and oracle. 00352 00353 Usage: 00354 00355 $conn->Connect(...); 00356 $cnt = _adodb_getcount($conn, $sql); 00357 00358 */ 00359 function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0) 00360 { 00361 $qryRecs = 0; 00362 00363 if (!empty($zthis->_nestedSQL) || preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) || 00364 preg_match('/\s+GROUP\s+BY\s+/is',$sql) || 00365 preg_match('/\s+UNION\s+/is',$sql)) { 00366 // ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias 00367 // but this is only supported by oracle and postgresql... 00368 if ($zthis->dataProvider == 'oci8') { 00369 00370 $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$sql); 00371 00372 // Allow Oracle hints to be used for query optimization, Chris Wrye 00373 if (preg_match('#/\\*+.*?\\*\\/#', $sql, $hint)) { 00374 $rewritesql = "SELECT ".$hint[0]." COUNT(*) FROM (".$rewritesql.")"; 00375 } else 00376 $rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")"; 00377 00378 } else if (strncmp($zthis->databaseType,'postgres',8) == 0) { 00379 $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$sql); 00380 $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_"; 00381 } 00382 } else { 00383 // now replace SELECT ... FROM with SELECT COUNT(*) FROM 00384 $rewritesql = preg_replace( 00385 '/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql); 00386 00387 00388 00389 // fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails 00390 // with mssql, access and postgresql. Also a good speedup optimization - skips sorting! 00391 // also see http://phplens.com/lens/lensforum/msgs.php?id=12752 00392 if (preg_match('/\sORDER\s+BY\s*\(/i',$rewritesql)) 00393 $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$rewritesql); 00394 else 00395 $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$rewritesql); 00396 } 00397 00398 00399 00400 if (isset($rewritesql) && $rewritesql != $sql) { 00401 if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[1]; 00402 00403 if ($secs2cache) { 00404 // we only use half the time of secs2cache because the count can quickly 00405 // become inaccurate if new records are added 00406 $qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr); 00407 00408 } else { 00409 $qryRecs = $zthis->GetOne($rewritesql,$inputarr); 00410 } 00411 if ($qryRecs !== false) return $qryRecs; 00412 } 00413 //-------------------------------------------- 00414 // query rewrite failed - so try slower way... 00415 00416 00417 // strip off unneeded ORDER BY if no UNION 00418 if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql; 00419 else $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql); 00420 00421 if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0]; 00422 00423 $rstest = &$zthis->Execute($rewritesql,$inputarr); 00424 if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr); 00425 00426 if ($rstest) { 00427 $qryRecs = $rstest->RecordCount(); 00428 if ($qryRecs == -1) { 00429 global $ADODB_EXTENSION; 00430 // some databases will return -1 on MoveLast() - change to MoveNext() 00431 if ($ADODB_EXTENSION) { 00432 while(!$rstest->EOF) { 00433 adodb_movenext($rstest); 00434 } 00435 } else { 00436 while(!$rstest->EOF) { 00437 $rstest->MoveNext(); 00438 } 00439 } 00440 $qryRecs = $rstest->_currentRow; 00441 } 00442 $rstest->Close(); 00443 if ($qryRecs == -1) return 0; 00444 } 00445 return $qryRecs; 00446 } 00447 00448 /* 00449 Code originally from "Cornel G" <conyg@fx.ro> 00450 00451 This code might not work with SQL that has UNION in it 00452 00453 Also if you are using CachePageExecute(), there is a strong possibility that 00454 data will get out of synch. use CachePageExecute() only with tables that 00455 rarely change. 00456 */ 00457 function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page, 00458 $inputarr=false, $secs2cache=0) 00459 { 00460 $atfirstpage = false; 00461 $atlastpage = false; 00462 $lastpageno=1; 00463 00464 // If an invalid nrows is supplied, 00465 // we assume a default value of 10 rows per page 00466 if (!isset($nrows) || $nrows <= 0) $nrows = 10; 00467 00468 $qryRecs = false; //count records for no offset 00469 00470 $qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache); 00471 $lastpageno = (int) ceil($qryRecs / $nrows); 00472 $zthis->_maxRecordCount = $qryRecs; 00473 00474 00475 00476 // ***** Here we check whether $page is the last page or 00477 // whether we are trying to retrieve 00478 // a page number greater than the last page number. 00479 if ($page >= $lastpageno) { 00480 $page = $lastpageno; 00481 $atlastpage = true; 00482 } 00483 00484 // If page number <= 1, then we are at the first page 00485 if (empty($page) || $page <= 1) { 00486 $page = 1; 00487 $atfirstpage = true; 00488 } 00489 00490 // We get the data we want 00491 $offset = $nrows * ($page-1); 00492 if ($secs2cache > 0) 00493 $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr); 00494 else 00495 $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache); 00496 00497 00498 // Before returning the RecordSet, we set the pagination properties we need 00499 if ($rsreturn) { 00500 $rsreturn->_maxRecordCount = $qryRecs; 00501 $rsreturn->rowsPerPage = $nrows; 00502 $rsreturn->AbsolutePage($page); 00503 $rsreturn->AtFirstPage($atfirstpage); 00504 $rsreturn->AtLastPage($atlastpage); 00505 $rsreturn->LastPageNo($lastpageno); 00506 } 00507 return $rsreturn; 00508 } 00509 00510 // Iván Oliva version 00511 function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0) 00512 { 00513 00514 $atfirstpage = false; 00515 $atlastpage = false; 00516 00517 if (!isset($page) || $page <= 1) { // If page number <= 1, then we are at the first page 00518 $page = 1; 00519 $atfirstpage = true; 00520 } 00521 if ($nrows <= 0) $nrows = 10; // If an invalid nrows is supplied, we assume a default value of 10 rows per page 00522 00523 // ***** Here we check whether $page is the last page or whether we are trying to retrieve a page number greater than 00524 // the last page number. 00525 $pagecounter = $page + 1; 00526 $pagecounteroffset = ($pagecounter * $nrows) - $nrows; 00527 if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr); 00528 else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache); 00529 if ($rstest) { 00530 while ($rstest && $rstest->EOF && $pagecounter>0) { 00531 $atlastpage = true; 00532 $pagecounter--; 00533 $pagecounteroffset = $nrows * ($pagecounter - 1); 00534 $rstest->Close(); 00535 if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr); 00536 else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache); 00537 } 00538 if ($rstest) $rstest->Close(); 00539 } 00540 if ($atlastpage) { // If we are at the last page or beyond it, we are going to retrieve it 00541 $page = $pagecounter; 00542 if ($page == 1) $atfirstpage = true; // We have to do this again in case the last page is the same as the first 00543 //... page, that is, the recordset has only 1 page. 00544 } 00545 00546 // We get the data we want 00547 $offset = $nrows * ($page-1); 00548 if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr); 00549 else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache); 00550 00551 // Before returning the RecordSet, we set the pagination properties we need 00552 if ($rsreturn) { 00553 $rsreturn->rowsPerPage = $nrows; 00554 $rsreturn->AbsolutePage($page); 00555 $rsreturn->AtFirstPage($atfirstpage); 00556 $rsreturn->AtLastPage($atlastpage); 00557 } 00558 return $rsreturn; 00559 } 00560 00561 function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2) 00562 { 00563 if (!$rs) { 00564 printf(ADODB_BAD_RS,'GetUpdateSQL'); 00565 return false; 00566 } 00567 00568 $fieldUpdatedCount = 0; 00569 $arrFields = _array_change_key_case($arrFields); 00570 00571 $hasnumeric = isset($rs->fields[0]); 00572 $setFields = ''; 00573 00574 // Loop through all of the fields in the recordset 00575 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) { 00576 // Get the field from the recordset 00577 $field = $rs->FetchField($i); 00578 00579 // If the recordset field is one 00580 // of the fields passed in then process. 00581 $upperfname = strtoupper($field->name); 00582 if (adodb_key_exists($upperfname,$arrFields,$force)) { 00583 00584 // If the existing field value in the recordset 00585 // is different from the value passed in then 00586 // go ahead and append the field name and new value to 00587 // the update query. 00588 00589 if ($hasnumeric) $val = $rs->fields[$i]; 00590 else if (isset($rs->fields[$upperfname])) $val = $rs->fields[$upperfname]; 00591 else if (isset($rs->fields[$field->name])) $val = $rs->fields[$field->name]; 00592 else if (isset($rs->fields[strtolower($upperfname)])) $val = $rs->fields[strtolower($upperfname)]; 00593 else $val = ''; 00594 00595 00596 if ($forceUpdate || strcmp($val, $arrFields[$upperfname])) { 00597 // Set the counter for the number of fields that will be updated. 00598 $fieldUpdatedCount++; 00599 00600 // Based on the datatype of the field 00601 // Format the value properly for the database 00602 $type = $rs->MetaType($field->type); 00603 00604 00605 if ($type == 'null') { 00606 $type = 'C'; 00607 } 00608 00609 if (strpos($upperfname,' ') !== false) 00610 $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote; 00611 else 00612 $fnameq = $upperfname; 00613 00614 00615 // is_null requires php 4.0.4 00616 //********************************************************// 00617 if (is_null($arrFields[$upperfname]) 00618 || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0) 00619 || $arrFields[$upperfname] === $zthis->null2null 00620 ) 00621 { 00622 switch ($force) { 00623 00624 //case 0: 00625 // //Ignore empty values. This is allready handled in "adodb_key_exists" function. 00626 //break; 00627 00628 case 1: 00629 //Set null 00630 $setFields .= $field->name . " = null, "; 00631 break; 00632 00633 case 2: 00634 //Set empty 00635 $arrFields[$upperfname] = ""; 00636 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq); 00637 break; 00638 default: 00639 case 3: 00640 //Set the value that was given in array, so you can give both null and empty values 00641 if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) { 00642 $setFields .= $field->name . " = null, "; 00643 } else { 00644 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq); 00645 } 00646 break; 00647 } 00648 //********************************************************// 00649 } else { 00650 //we do this so each driver can customize the sql for 00651 //DB specific column types. 00652 //Oracle needs BLOB types to be handled with a returning clause 00653 //postgres has special needs as well 00654 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq, 00655 $arrFields, $magicq); 00656 } 00657 } 00658 } 00659 } 00660 00661 // If there were any modified fields then build the rest of the update query. 00662 if ($fieldUpdatedCount > 0 || $forceUpdate) { 00663 // Get the table name from the existing query. 00664 if (!empty($rs->tableName)) $tableName = $rs->tableName; 00665 else { 00666 preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName); 00667 $tableName = $tableName[1]; 00668 } 00669 // Get the full where clause excluding the word "WHERE" from 00670 // the existing query. 00671 preg_match('/\sWHERE\s(.*)/is', $rs->sql, $whereClause); 00672 00673 $discard = false; 00674 // not a good hack, improvements? 00675 if ($whereClause) { 00676 #var_dump($whereClause); 00677 if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard)); 00678 else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard)); 00679 else if (preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard)); 00680 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 00681 } else 00682 $whereClause = array(false,false); 00683 00684 if ($discard) 00685 $whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1])); 00686 00687 $sql = 'UPDATE '.$tableName.' SET '.substr($setFields, 0, -2); 00688 if (strlen($whereClause[1]) > 0) 00689 $sql .= ' WHERE '.$whereClause[1]; 00690 00691 return $sql; 00692 00693 } else { 00694 return false; 00695 } 00696 } 00697 00698 function adodb_key_exists($key, &$arr,$force=2) 00699 { 00700 if ($force<=0) { 00701 // the following is the old behaviour where null or empty fields are ignored 00702 return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0); 00703 } 00704 00705 if (isset($arr[$key])) return true; 00706 ## null check below 00707 if (ADODB_PHPVER >= 0x4010) return array_key_exists($key,$arr); 00708 return false; 00709 } 00710 00718 function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2) 00719 { 00720 static $cacheRS = false; 00721 static $cacheSig = 0; 00722 static $cacheCols; 00723 00724 $tableName = ''; 00725 $values = ''; 00726 $fields = ''; 00727 $recordSet = null; 00728 $arrFields = _array_change_key_case($arrFields); 00729 $fieldInsertedCount = 0; 00730 00731 if (is_string($rs)) { 00732 //ok we have a table name 00733 //try and get the column info ourself. 00734 $tableName = $rs; 00735 00736 //we need an object for the recordSet 00737 //because we have to call MetaType. 00738 //php can't do a $rsclass::MetaType() 00739 $rsclass = $zthis->rsPrefix.$zthis->databaseType; 00740 $recordSet = new $rsclass(-1,$zthis->fetchMode); 00741 $recordSet->connection = &$zthis; 00742 00743 if (is_string($cacheRS) && $cacheRS == $rs) { 00744 $columns =& $cacheCols; 00745 } else { 00746 $columns = $zthis->MetaColumns( $tableName ); 00747 $cacheRS = $tableName; 00748 $cacheCols = $columns; 00749 } 00750 } else if (is_subclass_of($rs, 'adorecordset')) { 00751 if (isset($rs->insertSig) && is_integer($cacheRS) && $cacheRS == $rs->insertSig) { 00752 $columns =& $cacheCols; 00753 } else { 00754 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) 00755 $columns[] = $rs->FetchField($i); 00756 $cacheRS = $cacheSig; 00757 $cacheCols = $columns; 00758 $rs->insertSig = $cacheSig++; 00759 } 00760 $recordSet =& $rs; 00761 00762 } else { 00763 printf(ADODB_BAD_RS,'GetInsertSQL'); 00764 return false; 00765 } 00766 00767 // Loop through all of the fields in the recordset 00768 foreach( $columns as $field ) { 00769 $upperfname = strtoupper($field->name); 00770 if (adodb_key_exists($upperfname,$arrFields,$force)) { 00771 $bad = false; 00772 if (strpos($upperfname,' ') !== false) 00773 $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote; 00774 else 00775 $fnameq = $upperfname; 00776 00777 $type = $recordSet->MetaType($field->type); 00778 00779 /********************************************************/ 00780 if (is_null($arrFields[$upperfname]) 00781 || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0) 00782 || $arrFields[$upperfname] === $zthis->null2null 00783 ) 00784 { 00785 switch ($force) { 00786 00787 case 0: // we must always set null if missing 00788 $bad = true; 00789 break; 00790 00791 case 1: 00792 $values .= "null, "; 00793 break; 00794 00795 case 2: 00796 //Set empty 00797 $arrFields[$upperfname] = ""; 00798 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq); 00799 break; 00800 00801 default: 00802 case 3: 00803 //Set the value that was given in array, so you can give both null and empty values 00804 if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) { 00805 $values .= "null, "; 00806 } else { 00807 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq); 00808 } 00809 break; 00810 } // switch 00811 00812 /*********************************************************/ 00813 } else { 00814 //we do this so each driver can customize the sql for 00815 //DB specific column types. 00816 //Oracle needs BLOB types to be handled with a returning clause 00817 //postgres has special needs as well 00818 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, 00819 $arrFields, $magicq); 00820 } 00821 00822 if ($bad) continue; 00823 // Set the counter for the number of fields that will be inserted. 00824 $fieldInsertedCount++; 00825 00826 00827 // Get the name of the fields to insert 00828 $fields .= $fnameq . ", "; 00829 } 00830 } 00831 00832 00833 // If there were any inserted fields then build the rest of the insert query. 00834 if ($fieldInsertedCount <= 0) return false; 00835 00836 // Get the table name from the existing query. 00837 if (!$tableName) { 00838 if (!empty($rs->tableName)) $tableName = $rs->tableName; 00839 else if (preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName)) 00840 $tableName = $tableName[1]; 00841 else 00842 return false; 00843 } 00844 00845 // Strip off the comma and space on the end of both the fields 00846 // and their values. 00847 $fields = substr($fields, 0, -2); 00848 $values = substr($values, 0, -2); 00849 00850 // Append the fields and their values to the insert query. 00851 return 'INSERT INTO '.$zthis->nameQuote.$tableName.$zthis->nameQuote.' ( '.$fields.' ) VALUES ( '.$values.' )'; 00852 } 00853 00854 00870 function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq) 00871 { 00872 $sql = ''; 00873 00874 // Based on the datatype of the field 00875 // Format the value properly for the database 00876 switch($type) { 00877 case 'B': 00878 //in order to handle Blobs correctly, we need 00879 //to do some magic for Oracle 00880 00881 //we need to create a new descriptor to handle 00882 //this properly 00883 if (!empty($zthis->hasReturningInto)) { 00884 if ($action == 'I') { 00885 $sql = 'empty_blob(), '; 00886 } else { 00887 $sql = $fnameq. '=empty_blob(), '; 00888 } 00889 //add the variable to the returning clause array 00890 //so the user can build this later in 00891 //case they want to add more to it 00892 $zthis->_returningArray[$fname] = ':xx'.$fname.'xx'; 00893 } else if (empty($arrFields[$fname])){ 00894 if ($action == 'I') { 00895 $sql = 'empty_blob(), '; 00896 } else { 00897 $sql = $fnameq. '=empty_blob(), '; 00898 } 00899 } else { 00900 //this is to maintain compatibility 00901 //with older adodb versions. 00902 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false); 00903 } 00904 break; 00905 00906 case "X": 00907 //we need to do some more magic here for long variables 00908 //to handle these correctly in oracle. 00909 00910 //create a safe bind var name 00911 //to avoid conflicts w/ dupes. 00912 if (!empty($zthis->hasReturningInto)) { 00913 if ($action == 'I') { 00914 $sql = ':xx'.$fname.'xx, '; 00915 } else { 00916 $sql = $fnameq.'=:xx'.$fname.'xx, '; 00917 } 00918 //add the variable to the returning clause array 00919 //so the user can build this later in 00920 //case they want to add more to it 00921 $zthis->_returningArray[$fname] = ':xx'.$fname.'xx'; 00922 } else { 00923 //this is to maintain compatibility 00924 //with older adodb versions. 00925 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false); 00926 } 00927 break; 00928 00929 default: 00930 $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false); 00931 break; 00932 } 00933 00934 return $sql; 00935 } 00936 00937 function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true) 00938 { 00939 00940 if ($recurse) { 00941 switch($zthis->dataProvider) { 00942 case 'postgres': 00943 if ($type == 'L') $type = 'C'; 00944 break; 00945 case 'oci8': 00946 return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq); 00947 00948 } 00949 } 00950 00951 switch($type) { 00952 case "C": 00953 case "X": 00954 case 'B': 00955 $val = $zthis->qstr($arrFields[$fname],$magicq); 00956 break; 00957 00958 case "D": 00959 $val = $zthis->DBDate($arrFields[$fname]); 00960 break; 00961 00962 case "T": 00963 $val = $zthis->DBTimeStamp($arrFields[$fname]); 00964 break; 00965 00966 default: 00967 $val = $arrFields[$fname]; 00968 if (empty($val)) $val = '0'; 00969 break; 00970 } 00971 00972 if ($action == 'I') return $val . ", "; 00973 00974 00975 return $fnameq . "=" . $val . ", "; 00976 00977 } 00978 00979 00980 00981 function _adodb_debug_execute(&$zthis, $sql, $inputarr) 00982 { 00983 $ss = ''; 00984 if ($inputarr) { 00985 foreach($inputarr as $kk=>$vv) { 00986 if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...'; 00987 $ss .= "($kk=>'$vv') "; 00988 } 00989 $ss = "[ $ss ]"; 00990 } 00991 $sqlTxt = is_array($sql) ? $sql[0] : $sql; 00992 /*str_replace(', ','##1#__^LF',is_array($sql) ? $sql[0] : $sql); 00993 $sqlTxt = str_replace(',',', ',$sqlTxt); 00994 $sqlTxt = str_replace('##1#__^LF', ', ' ,$sqlTxt); 00995 */ 00996 // check if running from browser or command-line 00997 $inBrowser = isset($_SERVER['HTTP_USER_AGENT']); 00998 00999 $dbt = $zthis->databaseType; 01000 if (isset($zthis->dsnType)) $dbt .= '-'.$zthis->dsnType; 01001 if ($inBrowser) { 01002 if ($ss) { 01003 $ss = '<code>'.htmlspecialchars($ss).'</code>'; 01004 } 01005 if ($zthis->debug === -1) 01006 ADOConnection::outp( "<br />\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<br />\n",false); 01007 else 01008 ADOConnection::outp( "<hr />\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<hr />\n",false); 01009 } else { 01010 ADOConnection::outp("-----\n($dbt): ".$sqlTxt."\n-----\n",false); 01011 } 01012 01013 $qID = $zthis->_query($sql,$inputarr); 01014 01015 /* 01016 Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql 01017 because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion 01018 */ 01019 if ($zthis->databaseType == 'mssql') { 01020 // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6 01021 if($emsg = $zthis->ErrorMsg()) { 01022 if ($err = $zthis->ErrorNo()) ADOConnection::outp($err.': '.$emsg); 01023 } 01024 } else if (!$qID) { 01025 ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg()); 01026 } 01027 01028 if ($zthis->debug === 99) _adodb_backtrace(true,9999,2); 01029 return $qID; 01030 } 01031 01032 # pretty print the debug_backtrace function 01033 function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0) 01034 { 01035 if (!function_exists('debug_backtrace')) return ''; 01036 01037 $html = (isset($_SERVER['HTTP_USER_AGENT'])); 01038 $fmt = ($html) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s"; 01039 01040 $MAXSTRLEN = 128; 01041 01042 $s = ($html) ? '<pre align=left>' : ''; 01043 01044 if (is_array($printOrArr)) $traceArr = $printOrArr; 01045 else $traceArr = debug_backtrace(); 01046 array_shift($traceArr); 01047 array_shift($traceArr); 01048 $tabs = sizeof($traceArr)-2; 01049 01050 foreach ($traceArr as $arr) { 01051 if ($skippy) {$skippy -= 1; continue;} 01052 $levels -= 1; 01053 if ($levels < 0) break; 01054 01055 $args = array(); 01056 for ($i=0; $i < $tabs; $i++) $s .= ($html) ? ' ' : "\t"; 01057 $tabs -= 1; 01058 if ($html) $s .= '<font face="Courier New,Courier">'; 01059 if (isset($arr['class'])) $s .= $arr['class'].'.'; 01060 if (isset($arr['args'])) 01061 foreach($arr['args'] as $v) { 01062 if (is_null($v)) $args[] = 'null'; 01063 else if (is_array($v)) $args[] = 'Array['.sizeof($v).']'; 01064 else if (is_object($v)) $args[] = 'Object:'.get_class($v); 01065 else if (is_bool($v)) $args[] = $v ? 'true' : 'false'; 01066 else { 01067 $v = (string) @$v; 01068 $str = htmlspecialchars(substr($v,0,$MAXSTRLEN)); 01069 if (strlen($v) > $MAXSTRLEN) $str .= '...'; 01070 $args[] = $str; 01071 } 01072 } 01073 $s .= $arr['function'].'('.implode(', ',$args).')'; 01074 01075 01076 $s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file'])); 01077 01078 $s .= "\n"; 01079 } 01080 if ($html) $s .= '</pre>'; 01081 if ($printOrArr) print $s; 01082 01083 return $s; 01084 } 01085 /* 01086 function _adodb_find_from($sql) 01087 { 01088 01089 $sql = str_replace(array("\n","\r"), ' ', $sql); 01090 $charCount = strlen($sql); 01091 01092 $inString = false; 01093 $quote = ''; 01094 $parentheseCount = 0; 01095 $prevChars = ''; 01096 $nextChars = ''; 01097 01098 01099 for($i = 0; $i < $charCount; $i++) { 01100 01101 $char = substr($sql,$i,1); 01102 $prevChars = substr($sql,0,$i); 01103 $nextChars = substr($sql,$i+1); 01104 01105 if((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === false) { 01106 $quote = $char; 01107 $inString = true; 01108 } 01109 01110 elseif((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === true && $quote == $char) { 01111 $quote = ""; 01112 $inString = false; 01113 } 01114 01115 elseif($char == "(" && $inString === false) 01116 $parentheseCount++; 01117 01118 elseif($char == ")" && $inString === false && $parentheseCount > 0) 01119 $parentheseCount--; 01120 01121 elseif($parentheseCount <= 0 && $inString === false && $char == " " && strtoupper(substr($prevChars,-5,5)) == " FROM") 01122 return $i; 01123 01124 } 01125 } 01126 */ 01127 01128 ?>