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.80 8 Mar 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                 // fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails 
00329                 // with mssql, access and postgresql. Also a good speedup optimization - skips sorting!
00330                 // also see http://phplens.com/lens/lensforum/msgs.php?id=12752
00331                 if (preg_match('/\sORDER\s+BY\s*\(/i',$rewritesql))
00332                         $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$rewritesql);
00333                 else
00334                         $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$rewritesql);
00335                  
00336         }
00337         
00338         if (isset($rewritesql) && $rewritesql != $sql) {
00339                 if ($secs2cache) {
00340                         // we only use half the time of secs2cache because the count can quickly
00341                         // become inaccurate if new records are added
00342                         $qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr);
00343                         
00344                 } else {
00345                         $qryRecs = $zthis->GetOne($rewritesql,$inputarr);
00346                 }
00347                 if ($qryRecs !== false) return $qryRecs;
00348         }
00349         //--------------------------------------------
00350         // query rewrite failed - so try slower way...
00351         
00352         
00353         // strip off unneeded ORDER BY if no UNION
00354         if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql;
00355         else $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql); 
00356         
00357         $rstest = &$zthis->Execute($rewritesql,$inputarr);
00358         if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr);
00359         
00360         if ($rstest) {
00361                         $qryRecs = $rstest->RecordCount();
00362                 if ($qryRecs == -1) { 
00363                 global $ADODB_EXTENSION;
00364                 // some databases will return -1 on MoveLast() - change to MoveNext()
00365                         if ($ADODB_EXTENSION) {
00366                                 while(!$rstest->EOF) {
00367                                         adodb_movenext($rstest);
00368                                 }
00369                         } else {
00370                                 while(!$rstest->EOF) {
00371                                         $rstest->MoveNext();
00372                                 }
00373                         }
00374                         $qryRecs = $rstest->_currentRow;
00375                 }
00376                 $rstest->Close();
00377                 if ($qryRecs == -1) return 0;
00378         }
00379         
00380         return $qryRecs;
00381 }
00382 
00383 /*
00384         Code originally from "Cornel G" <conyg@fx.ro>
00385 
00386         This code might not work with SQL that has UNION in it  
00387         
00388         Also if you are using CachePageExecute(), there is a strong possibility that
00389         data will get out of synch. use CachePageExecute() only with tables that
00390         rarely change.
00391 */
00392 function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page, 
00393                                                 $inputarr=false, $secs2cache=0) 
00394 {
00395         $atfirstpage = false;
00396         $atlastpage = false;
00397         $lastpageno=1;
00398 
00399         // If an invalid nrows is supplied, 
00400         // we assume a default value of 10 rows per page
00401         if (!isset($nrows) || $nrows <= 0) $nrows = 10;
00402 
00403         $qryRecs = false; //count records for no offset
00404         
00405         $qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache);
00406         $lastpageno = (int) ceil($qryRecs / $nrows);
00407         $zthis->_maxRecordCount = $qryRecs;
00408         
00409 
00410 
00411         // ***** Here we check whether $page is the last page or 
00412         // whether we are trying to retrieve 
00413         // a page number greater than the last page number.
00414         if ($page >= $lastpageno) {
00415                 $page = $lastpageno;
00416                 $atlastpage = true;
00417         }
00418         
00419         // If page number <= 1, then we are at the first page
00420         if (empty($page) || $page <= 1) {       
00421                 $page = 1;
00422                 $atfirstpage = true;
00423         }
00424         
00425         // We get the data we want
00426         $offset = $nrows * ($page-1);
00427         if ($secs2cache > 0) 
00428                 $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
00429         else 
00430                 $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
00431 
00432         
00433         // Before returning the RecordSet, we set the pagination properties we need
00434         if ($rsreturn) {
00435                 $rsreturn->_maxRecordCount = $qryRecs;
00436                 $rsreturn->rowsPerPage = $nrows;
00437                 $rsreturn->AbsolutePage($page);
00438                 $rsreturn->AtFirstPage($atfirstpage);
00439                 $rsreturn->AtLastPage($atlastpage);
00440                 $rsreturn->LastPageNo($lastpageno);
00441         }
00442         return $rsreturn;
00443 }
00444 
00445 // Iván Oliva version
00446 function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0) 
00447 {
00448 
00449         $atfirstpage = false;
00450         $atlastpage = false;
00451         
00452         if (!isset($page) || $page <= 1) {      // If page number <= 1, then we are at the first page
00453                 $page = 1;
00454                 $atfirstpage = true;
00455         }
00456         if ($nrows <= 0) $nrows = 10;   // If an invalid nrows is supplied, we assume a default value of 10 rows per page
00457         
00458         // ***** Here we check whether $page is the last page or whether we are trying to retrieve a page number greater than 
00459         // the last page number.
00460         $pagecounter = $page + 1;
00461         $pagecounteroffset = ($pagecounter * $nrows) - $nrows;
00462         if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
00463         else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
00464         if ($rstest) {
00465                 while ($rstest && $rstest->EOF && $pagecounter>0) {
00466                         $atlastpage = true;
00467                         $pagecounter--;
00468                         $pagecounteroffset = $nrows * ($pagecounter - 1);
00469                         $rstest->Close();
00470                         if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
00471                         else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
00472                 }
00473                 if ($rstest) $rstest->Close();
00474         }
00475         if ($atlastpage) {      // If we are at the last page or beyond it, we are going to retrieve it
00476                 $page = $pagecounter;
00477                 if ($page == 1) $atfirstpage = true;    // We have to do this again in case the last page is the same as the first
00478                         //... page, that is, the recordset has only 1 page.
00479         }
00480         
00481         // We get the data we want
00482         $offset = $nrows * ($page-1);
00483         if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
00484         else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
00485         
00486         // Before returning the RecordSet, we set the pagination properties we need
00487         if ($rsreturn) {
00488                 $rsreturn->rowsPerPage = $nrows;
00489                 $rsreturn->AbsolutePage($page);
00490                 $rsreturn->AtFirstPage($atfirstpage);
00491                 $rsreturn->AtLastPage($atlastpage);
00492         }
00493         return $rsreturn;
00494 }
00495 
00496 function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2)
00497 {
00498                 if (!$rs) {
00499                         printf(ADODB_BAD_RS,'GetUpdateSQL');
00500                         return false;
00501                 }
00502         
00503                 $fieldUpdatedCount = 0;
00504                 $arrFields = _array_change_key_case($arrFields);
00505 
00506                 $hasnumeric = isset($rs->fields[0]);
00507                 $setFields = '';
00508                 
00509                 // Loop through all of the fields in the recordset
00510                 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
00511                         // Get the field from the recordset
00512                         $field = $rs->FetchField($i);
00513 
00514                         // If the recordset field is one
00515                         // of the fields passed in then process.
00516                         $upperfname = strtoupper($field->name);
00517                         if (adodb_key_exists($upperfname,$arrFields,$force)) {
00518                                 
00519                                 // If the existing field value in the recordset
00520                                 // is different from the value passed in then
00521                                 // go ahead and append the field name and new value to
00522                                 // the update query.
00523                                 
00524                                 if ($hasnumeric) $val = $rs->fields[$i];
00525                                 else if (isset($rs->fields[$upperfname])) $val = $rs->fields[$upperfname];
00526                                 else if (isset($rs->fields[$field->name])) $val =  $rs->fields[$field->name];
00527                                 else if (isset($rs->fields[strtolower($upperfname)])) $val =  $rs->fields[strtolower($upperfname)];
00528                                 else $val = '';
00529                                 
00530                         
00531                                 if ($forceUpdate || strcmp($val, $arrFields[$upperfname])) {
00532                                         // Set the counter for the number of fields that will be updated.
00533                                         $fieldUpdatedCount++;
00534 
00535                                         // Based on the datatype of the field
00536                                         // Format the value properly for the database
00537                                         $type = $rs->MetaType($field->type);
00538                                                 
00539 
00540                                         if ($type == 'null') {
00541                                                 $type = 'C';
00542                                         }
00543                                         
00544                                         if (strpos($upperfname,' ') !== false)
00545                                                 $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
00546                                         else
00547                                                 $fnameq = $upperfname;
00548                                         
00549                                         
00550                 // is_null requires php 4.0.4
00551                 //********************************************************//
00552                 if (is_null($arrFields[$upperfname])
00553                                         || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
00554                     || $arrFields[$upperfname] === 'null'
00555                     )
00556                 {
00557                     switch ($force) {
00558 
00559                         //case 0:
00560                         //    //Ignore empty values. This is allready handled in "adodb_key_exists" function.
00561                         //break;
00562 
00563                         case 1:
00564                             //Set null
00565                             $setFields .= $field->name . " = null, ";
00566                         break;
00567                                                         
00568                         case 2:
00569                             //Set empty
00570                             $arrFields[$upperfname] = "";
00571                             $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
00572                         break;
00573                                                 default:
00574                         case 3:
00575                             //Set the value that was given in array, so you can give both null and empty values
00576                             if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === 'null') {
00577                                 $setFields .= $field->name . " = null, ";
00578                             } else {
00579                                 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
00580                             }
00581                         break;
00582                     }
00583                 //********************************************************//
00584                 } else {
00585                                                 //we do this so each driver can customize the sql for
00586                                                 //DB specific column types. 
00587                                                 //Oracle needs BLOB types to be handled with a returning clause
00588                                                 //postgres has special needs as well
00589                                                 $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
00590                                                                                                                   $arrFields, $magicq);
00591                                         }
00592                                 }
00593                         }
00594                 }
00595 
00596                 // If there were any modified fields then build the rest of the update query.
00597                 if ($fieldUpdatedCount > 0 || $forceUpdate) {
00598                                         // Get the table name from the existing query.
00599                         if (!empty($rs->tableName)) $tableName = $rs->tableName;
00600                         else {
00601                                 preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
00602                                 $tableName = $tableName[1];
00603                         }
00604                         // Get the full where clause excluding the word "WHERE" from
00605                         // the existing query.
00606                         preg_match('/\sWHERE\s(.*)/is', $rs->sql, $whereClause);
00607                         
00608                         $discard = false;
00609                         // not a good hack, improvements?
00610                         if ($whereClause) {
00611                         #var_dump($whereClause);
00612                                 if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
00613                                 else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard));
00614                                 else if (preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard));
00615                                 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
00616                         } else
00617                                 $whereClause = array(false,false);
00618                                 
00619                         if ($discard)
00620                                 $whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
00621                         
00622                         $sql = 'UPDATE '.$tableName.' SET '.substr($setFields, 0, -2);
00623                         if (strlen($whereClause[1]) > 0) 
00624                                 $sql .= ' WHERE '.$whereClause[1];
00625 
00626                         return $sql;
00627 
00628                 } else {
00629                         return false;
00630         }
00631 }
00632 
00633 function adodb_key_exists($key, &$arr,$force=2)
00634 {
00635         if ($force<=0) {
00636                 // the following is the old behaviour where null or empty fields are ignored
00637                 return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0);
00638         }
00639 
00640         if (isset($arr[$key])) return true;
00641         ## null check below
00642         if (ADODB_PHPVER >= 0x4010) return array_key_exists($key,$arr);
00643         return false;
00644 }
00645 
00653 function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2)
00654 {
00655 static $cacheRS = false;
00656 static $cacheSig = 0;
00657 static $cacheCols;
00658 
00659         $tableName = '';
00660         $values = '';
00661         $fields = '';
00662         $recordSet = null;
00663         $arrFields = _array_change_key_case($arrFields);
00664         $fieldInsertedCount = 0;
00665         
00666         if (is_string($rs)) {
00667                 //ok we have a table name
00668                 //try and get the column info ourself.
00669                 $tableName = $rs;                       
00670         
00671                 //we need an object for the recordSet
00672                 //because we have to call MetaType.
00673                 //php can't do a $rsclass::MetaType()
00674                 $rsclass = $zthis->rsPrefix.$zthis->databaseType;
00675                 $recordSet = new $rsclass(-1,$zthis->fetchMode);
00676                 $recordSet->connection = &$zthis;
00677                 
00678                 if (is_string($cacheRS) && $cacheRS == $rs) {
00679                         $columns =& $cacheCols;
00680                 } else {
00681                         $columns = $zthis->MetaColumns( $tableName );
00682                         $cacheRS = $tableName;
00683                         $cacheCols = $columns;
00684                 }
00685         } else if (is_subclass_of($rs, 'adorecordset')) {
00686                 if (isset($rs->insertSig) && is_integer($cacheRS) && $cacheRS == $rs->insertSig) {
00687                         $columns =& $cacheCols;
00688                 } else {
00689                         for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) 
00690                                 $columns[] = $rs->FetchField($i);
00691                         $cacheRS = $cacheSig;
00692                         $cacheCols = $columns;
00693                         $rs->insertSig = $cacheSig++;
00694                 }
00695                 $recordSet =& $rs;
00696         
00697         } else {
00698                 printf(ADODB_BAD_RS,'GetInsertSQL');
00699                 return false;
00700         }
00701 
00702         // Loop through all of the fields in the recordset
00703         foreach( $columns as $field ) { 
00704                 $upperfname = strtoupper($field->name);
00705                 if (adodb_key_exists($upperfname,$arrFields,$force)) {
00706                         $bad = false;
00707                         if (strpos($upperfname,' ') !== false)
00708                                 $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
00709                         else
00710                                 $fnameq = $upperfname;
00711                         
00712                         $type = $recordSet->MetaType($field->type);
00713                         
00714             /********************************************************/
00715             if (is_null($arrFields[$upperfname])
00716                 || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
00717                 || $arrFields[$upperfname] === 'null'
00718                                 )
00719                {
00720                     switch ($force) {
00721 
00722                         case 0: // we must always set null if missing
00723                                                         $bad = true;
00724                                                         break;
00725                                                         
00726                         case 1:
00727                             $values  .= "null, ";
00728                         break;
00729                 
00730                         case 2:
00731                             //Set empty
00732                             $arrFields[$upperfname] = "";
00733                             $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq);
00734                         break;
00735 
00736                                                 default:
00737                         case 3:
00738                             //Set the value that was given in array, so you can give both null and empty values
00739                                                         if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === 'null') { 
00740                                                                 $values  .= "null, ";
00741                                                         } else {
00742                                         $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq);
00743                                         }
00744                                 break;
00745                         } // switch
00746 
00747             /*********************************************************/
00748                         } else {
00749                                 //we do this so each driver can customize the sql for
00750                                 //DB specific column types. 
00751                                 //Oracle needs BLOB types to be handled with a returning clause
00752                                 //postgres has special needs as well
00753                                 $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,
00754                                                                                            $arrFields, $magicq);
00755                         }
00756                         
00757                         if ($bad) continue;
00758                         // Set the counter for the number of fields that will be inserted.
00759                         $fieldInsertedCount++;
00760                         
00761                         
00762                         // Get the name of the fields to insert
00763                         $fields .= $fnameq . ", ";
00764                 }
00765         }
00766 
00767 
00768         // If there were any inserted fields then build the rest of the insert query.
00769         if ($fieldInsertedCount <= 0)  return false;
00770         
00771         // Get the table name from the existing query.
00772         if (!$tableName) {
00773                 if (!empty($rs->tableName)) $tableName = $rs->tableName;
00774                 else if (preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName))
00775                         $tableName = $tableName[1];
00776                 else 
00777                         return false;
00778         }               
00779 
00780         // Strip off the comma and space on the end of both the fields
00781         // and their values.
00782         $fields = substr($fields, 0, -2);
00783         $values = substr($values, 0, -2);
00784 
00785         // Append the fields and their values to the insert query.
00786         return 'INSERT INTO '.$zthis->nameQuote.$tableName.$zthis->nameQuote.' ( '.$fields.' ) VALUES ( '.$values.' )';
00787 }
00788 
00789 
00805 function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq) 
00806 {
00807     $sql = '';
00808     
00809     // Based on the datatype of the field
00810     // Format the value properly for the database
00811     switch($type) {
00812     case 'B':
00813         //in order to handle Blobs correctly, we need
00814         //to do some magic for Oracle
00815 
00816         //we need to create a new descriptor to handle 
00817         //this properly
00818         if (!empty($zthis->hasReturningInto)) {
00819             if ($action == 'I') {
00820                 $sql = 'empty_blob(), ';
00821             } else {
00822                 $sql = $fnameq. '=empty_blob(), ';
00823             }
00824             //add the variable to the returning clause array
00825             //so the user can build this later in
00826             //case they want to add more to it
00827             $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
00828         } else if (empty($arrFields[$fname])){
00829             if ($action == 'I') {
00830                 $sql = 'empty_blob(), ';
00831             } else {
00832                 $sql = $fnameq. '=empty_blob(), ';
00833             }            
00834         } else {
00835             //this is to maintain compatibility
00836             //with older adodb versions.
00837             $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
00838         }
00839         break;
00840 
00841     case "X":
00842         //we need to do some more magic here for long variables
00843         //to handle these correctly in oracle.
00844 
00845         //create a safe bind var name
00846         //to avoid conflicts w/ dupes.
00847        if (!empty($zthis->hasReturningInto)) {
00848             if ($action == 'I') {
00849                 $sql = ':xx'.$fname.'xx, ';                
00850             } else {
00851                 $sql = $fnameq.'=:xx'.$fname.'xx, ';
00852             }
00853             //add the variable to the returning clause array
00854             //so the user can build this later in
00855             //case they want to add more to it
00856             $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
00857         } else {
00858             //this is to maintain compatibility
00859             //with older adodb versions.
00860             $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
00861         }            
00862         break;
00863         
00864     default:
00865         $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq,  $arrFields, $magicq,false);
00866         break;
00867     }
00868     
00869     return $sql;
00870 }    
00871         
00872 function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true) 
00873 {
00874 
00875         if ($recurse) {
00876                 switch($zthis->dataProvider)  {
00877                 case 'postgres':
00878                         if ($type == 'L') $type = 'C';
00879                         break;
00880                 case 'oci8':
00881                         return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq);
00882                         
00883                 }
00884         }
00885                 
00886         switch($type) {
00887                 case "C":
00888                 case "X":
00889                 case 'B':
00890                         $val = $zthis->qstr($arrFields[$fname],$magicq);
00891                         break;
00892 
00893                 case "D":
00894                         $val = $zthis->DBDate($arrFields[$fname]);
00895                         break;
00896 
00897                 case "T":
00898                         $val = $zthis->DBTimeStamp($arrFields[$fname]);
00899                         break;
00900 
00901                 default:
00902                         $val = $arrFields[$fname];
00903                         if (empty($val)) $val = '0';
00904                         break;
00905         }
00906 
00907         if ($action == 'I') return $val . ", ";
00908         
00909         
00910         return $fnameq . "=" . $val  . ", ";
00911         
00912 }
00913 
00914 
00915 
00916 function _adodb_debug_execute(&$zthis, $sql, $inputarr)
00917 {
00918         $ss = '';
00919         if ($inputarr) {
00920                 foreach($inputarr as $kk=>$vv) {
00921                         if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
00922                         $ss .= "($kk=>'$vv') ";
00923                 }
00924                 $ss = "[ $ss ]";
00925         }
00926         $sqlTxt = is_array($sql) ? $sql[0] : $sql;
00927         /*str_replace(', ','##1#__^LF',is_array($sql) ? $sql[0] : $sql);
00928         $sqlTxt = str_replace(',',', ',$sqlTxt);
00929         $sqlTxt = str_replace('##1#__^LF', ', ' ,$sqlTxt);
00930         */
00931         // check if running from browser or command-line
00932         $inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
00933         
00934         $dbt = $zthis->databaseType;
00935         if (isset($zthis->dsnType)) $dbt .= '-'.$zthis->dsnType;
00936         if ($inBrowser) {
00937                 if ($ss) {
00938                         $ss = '<code>'.htmlspecialchars($ss).'</code>';
00939                 }
00940                 if ($zthis->debug === -1)
00941                         ADOConnection::outp( "<br />\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<br />\n",false);
00942                 else 
00943                         ADOConnection::outp( "<hr />\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr />\n",false);
00944         } else {
00945                 ADOConnection::outp("-----\n($dbt): ".$sqlTxt."\n-----\n",false);
00946         }
00947 
00948         $qID = $zthis->_query($sql,$inputarr);
00949         
00950         /* 
00951                 Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
00952                 because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
00953         */
00954         if ($zthis->databaseType == 'mssql') { 
00955         // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
00956                 if($emsg = $zthis->ErrorMsg()) {
00957                         if ($err = $zthis->ErrorNo()) ADOConnection::outp($err.': '.$emsg);
00958                 }
00959         } else if (!$qID) {
00960                 ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
00961         }
00962         
00963         if ($zthis->debug === 99) _adodb_backtrace(true,9999,2);
00964         return $qID;
00965 }
00966 
00967 # pretty print the debug_backtrace function
00968 function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0)
00969 {
00970         if (!function_exists('debug_backtrace')) return '';
00971          
00972         $html =  (isset($_SERVER['HTTP_USER_AGENT']));
00973         $fmt =  ($html) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
00974 
00975         $MAXSTRLEN = 128;
00976 
00977         $s = ($html) ? '<pre align=left>' : '';
00978         
00979         if (is_array($printOrArr)) $traceArr = $printOrArr;
00980         else $traceArr = debug_backtrace();
00981         array_shift($traceArr);
00982         array_shift($traceArr);
00983         $tabs = sizeof($traceArr)-2;
00984         
00985         foreach ($traceArr as $arr) {
00986                 if ($skippy) {$skippy -= 1; continue;}
00987                 $levels -= 1;
00988                 if ($levels < 0) break;
00989                 
00990                 $args = array();
00991                 for ($i=0; $i < $tabs; $i++) $s .=  ($html) ? ' &nbsp; ' : "\t";
00992                 $tabs -= 1;
00993                 if ($html) $s .= '<font face="Courier New,Courier">';
00994                 if (isset($arr['class'])) $s .= $arr['class'].'.';
00995                 if (isset($arr['args']))
00996                  foreach($arr['args'] as $v) {
00997                         if (is_null($v)) $args[] = 'null';
00998                         else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
00999                         else if (is_object($v)) $args[] = 'Object:'.get_class($v);
01000                         else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
01001                         else {
01002                                 $v = (string) @$v;
01003                                 $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
01004                                 if (strlen($v) > $MAXSTRLEN) $str .= '...';
01005                                 $args[] = $str;
01006                         }
01007                 }
01008                 $s .= $arr['function'].'('.implode(', ',$args).')';
01009                 
01010                 
01011                 $s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
01012                         
01013                 $s .= "\n";
01014         }       
01015         if ($html) $s .= '</pre>';
01016         if ($printOrArr) print $s;
01017         
01018         return $s;
01019 }
01020 
01021 ?>


Généré par L'expert TYPO3 avec  doxygen 1.4.6