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