Documentation TYPO3 par Ameos

adodb-lib.inc.php

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)." &nbsp; $ss\n<br />\n",false);
01007                 else 
01008                         ADOConnection::outp( "<hr />\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $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) ? ' &nbsp; ' : "\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 ?>


Généré par Les spécialistes TYPO3 avec  doxygen 1.4.6