[ Index ]
 

Code source de eGroupWare 1.2.106-2

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/phpgwapi/inc/adodb/ -> adodb-lib.inc.php (source)

   1  <?php
   2  
   3  // security - hide paths
   4  if (!defined('ADODB_DIR')) die();
   5  
   6  global $ADODB_INCLUDED_LIB;
   7  $ADODB_INCLUDED_LIB = 1;
   8  
   9  /* 
  10   @version V4.65 22 July 2005 (c) 2000-2005 John Lim (jlim\@natsoft.com.my). All rights reserved.
  11    Released under both BSD license and Lesser GPL library license. 
  12    Whenever there is any discrepancy between the two licenses, 
  13    the BSD license will take precedence. See License.txt. 
  14    Set tabs to 4 for best viewing.
  15    
  16    Less commonly used functions are placed here to reduce size of adodb.inc.php. 
  17  */ 
  18  
  19  
  20  // Force key to upper. 
  21  // See also http://www.php.net/manual/en/function.array-change-key-case.php
  22  function _array_change_key_case($an_array)
  23  {
  24      if (is_array($an_array)) {
  25          $new_array = array();
  26          foreach($an_array as $key=>$value)
  27              $new_array[strtoupper($key)] = $value;
  28  
  29             return $new_array;
  30     }
  31  
  32      return $an_array;
  33  }
  34  
  35  function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc)
  36  {
  37          if (count($fieldArray) == 0) return 0;
  38          $first = true;
  39          $uSet = '';
  40          
  41          if (!is_array($keyCol)) {
  42              $keyCol = array($keyCol);
  43          }
  44          foreach($fieldArray as $k => $v) {
  45              if ($autoQuote && !is_numeric($v) and strncmp($v,"'",1) !== 0 and strcasecmp($v,'null')!=0) {
  46                  $v = $zthis->qstr($v);
  47                  $fieldArray[$k] = $v;
  48              }
  49              if (in_array($k,$keyCol)) continue; // skip UPDATE if is key
  50              
  51              if ($first) {
  52                  $first = false;            
  53                  $uSet = "$k=$v";
  54              } else
  55                  $uSet .= ",$k=$v";
  56          }
  57           
  58          $where = false;
  59          foreach ($keyCol as $v) {
  60              if ($where) $where .= " and $v=$fieldArray[$v]";
  61              else $where = "$v=$fieldArray[$v]";
  62          }
  63          
  64          if ($uSet && $where) {
  65              $update = "UPDATE $table SET $uSet WHERE $where";
  66  
  67              $rs = $zthis->Execute($update);
  68              
  69              
  70              if ($rs) {
  71                  if ($zthis->poorAffectedRows) {
  72                  /*
  73                   The Select count(*) wipes out any errors that the update would have returned. 
  74                  http://phplens.com/lens/lensforum/msgs.php?id=5696
  75                  */
  76                      if ($zthis->ErrorNo()<>0) return 0;
  77                      
  78                  # affected_rows == 0 if update field values identical to old values
  79                  # for mysql - which is silly. 
  80              
  81                      $cnt = $zthis->GetOne("select count(*) from $table where $where");
  82                      if ($cnt > 0) return 1; // record already exists
  83                  } else {
  84                      if (($zthis->Affected_Rows()>0)) return 1;
  85                  }
  86              } else
  87                  return 0;
  88          }
  89          
  90      //    print "<p>Error=".$this->ErrorNo().'<p>';
  91          $first = true;
  92          foreach($fieldArray as $k => $v) {
  93              if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
  94              
  95              if ($first) {
  96                  $first = false;            
  97                  $iCols = "$k";
  98                  $iVals = "$v";
  99              } else {
 100                  $iCols .= ",$k";
 101                  $iVals .= ",$v";
 102              }                
 103          }
 104          $insert = "INSERT INTO $table ($iCols) VALUES ($iVals)"; 
 105          $rs = $zthis->Execute($insert);
 106          return ($rs) ? 2 : 0;
 107  }
 108  
 109  // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
 110  function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
 111              $size=0, $selectAttr='',$compareFields0=true)
 112  {
 113      $hasvalue = false;
 114  
 115      if ($multiple or is_array($defstr)) {
 116          if ($size==0) $size=5;
 117          $attr = ' multiple size="'.$size.'"';
 118          if (!strpos($name,'[]')) $name .= '[]';
 119      } else if ($size) $attr = ' size="'.$size.'"';
 120      else $attr ='';
 121      
 122      $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
 123      if ($blank1stItem) 
 124          if (is_string($blank1stItem))  {
 125              $barr = explode(':',$blank1stItem);
 126              if (sizeof($barr) == 1) $barr[] = '';
 127              $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
 128          } else $s .= "\n<option></option>";
 129  
 130      if ($zthis->FieldCount() > 1) $hasvalue=true;
 131      else $compareFields0 = true;
 132      
 133      $value = '';
 134      $optgroup = null;
 135      $firstgroup = true;
 136      $fieldsize = $zthis->FieldCount();
 137      while(!$zthis->EOF) {
 138          $zval = rtrim(reset($zthis->fields));
 139  
 140          if ($blank1stItem && $zval=="") {
 141              $zthis->MoveNext();
 142              continue;
 143          }
 144  
 145          if ($fieldsize > 1) {
 146              if (isset($zthis->fields[1]))
 147                  $zval2 = rtrim($zthis->fields[1]);
 148              else
 149                  $zval2 = rtrim(next($zthis->fields));
 150          }
 151          $selected = ($compareFields0) ? $zval : $zval2;
 152          
 153          $group = '';
 154          if ($fieldsize > 2) {
 155              $group = rtrim($zthis->fields[2]);
 156          }
 157   
 158          if ($optgroup != $group) {
 159              $optgroup = $group;
 160              if ($firstgroup) {
 161                  $firstgroup = false;
 162                  $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
 163              } else {
 164                  $s .="\n</optgroup>";
 165                  $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
 166              }
 167          }
 168      
 169          if ($hasvalue) 
 170              $value = " value='".htmlspecialchars($zval2)."'";
 171          
 172          if (is_array($defstr))  {
 173              
 174              if (in_array($selected,$defstr)) 
 175                  $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
 176              else 
 177                  $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
 178          }
 179          else {
 180              if (strcasecmp($selected,$defstr)==0) 
 181                  $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
 182              else
 183                  $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
 184          }
 185          $zthis->MoveNext();
 186      } // while
 187      
 188      // closing last optgroup
 189      if($optgroup != null) {
 190          $s .= "\n</optgroup>";
 191      }
 192      return $s ."\n</select>\n";
 193  }
 194  
 195  // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
 196  function _adodb_getmenu_gp(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
 197              $size=0, $selectAttr='',$compareFields0=true)
 198  {
 199      $hasvalue = false;
 200  
 201      if ($multiple or is_array($defstr)) {
 202          if ($size==0) $size=5;
 203          $attr = ' multiple size="'.$size.'"';
 204          if (!strpos($name,'[]')) $name .= '[]';
 205      } else if ($size) $attr = ' size="'.$size.'"';
 206      else $attr ='';
 207      
 208      $s = '<select name="'.$name.'"'.$attr.' '.$selectAttr.'>';
 209      if ($blank1stItem) 
 210          if (is_string($blank1stItem))  {
 211              $barr = explode(':',$blank1stItem);
 212              if (sizeof($barr) == 1) $barr[] = '';
 213              $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
 214          } else $s .= "\n<option></option>";
 215  
 216      if ($zthis->FieldCount() > 1) $hasvalue=true;
 217      else $compareFields0 = true;
 218      
 219      $value = '';
 220      $optgroup = null;
 221      $firstgroup = true;
 222      $fieldsize = sizeof($zthis->fields);
 223      while(!$zthis->EOF) {
 224          $zval = rtrim(reset($zthis->fields));
 225  
 226          if ($blank1stItem && $zval=="") {
 227              $zthis->MoveNext();
 228              continue;
 229          }
 230  
 231          if ($fieldsize > 1) {
 232              if (isset($zthis->fields[1]))
 233                  $zval2 = rtrim($zthis->fields[1]);
 234              else
 235                  $zval2 = rtrim(next($zthis->fields));
 236          }
 237          $selected = ($compareFields0) ? $zval : $zval2;
 238          
 239          $group = '';
 240          if (isset($zthis->fields[2])) {
 241              $group = rtrim($zthis->fields[2]);
 242          }
 243   
 244          if ($optgroup != $group) {
 245              $optgroup = $group;
 246              if ($firstgroup) {
 247                  $firstgroup = false;
 248                  $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
 249              } else {
 250                  $s .="\n</optgroup>";
 251                  $s .="\n<optgroup label='". htmlspecialchars($group) ."'>";
 252              }
 253          }
 254      
 255          if ($hasvalue) 
 256              $value = " value='".htmlspecialchars($zval2)."'";
 257          
 258          if (is_array($defstr))  {
 259              
 260              if (in_array($selected,$defstr)) 
 261                  $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
 262              else 
 263                  $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
 264          }
 265          else {
 266              if (strcasecmp($selected,$defstr)==0) 
 267                  $s .= "\n<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
 268              else
 269                  $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
 270          }
 271          $zthis->MoveNext();
 272      } // while
 273      
 274      // closing last optgroup
 275      if($optgroup != null) {
 276          $s .= "\n</optgroup>";
 277      }
 278      return $s ."\n</select>\n";
 279  }
 280  
 281  
 282  /*
 283      Count the number of records this sql statement will return by using
 284      query rewriting techniques...
 285      
 286      Does not work with UNIONs, except with postgresql and oracle.
 287  */
 288  function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0) 
 289  {
 290      $qryRecs = 0;
 291      
 292       if (preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) || 
 293           preg_match('/\s+GROUP\s+BY\s+/is',$sql) || 
 294          preg_match('/\s+UNION\s+/is',$sql)) {
 295          // ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias
 296          // but this is only supported by oracle and postgresql...
 297          if ($zthis->dataProvider == 'oci8') {
 298              
 299              $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
 300              
 301              // Allow Oracle hints to be used for query optimization, Chris Wrye
 302              if (preg_match('#/\\*+.*?\\*\\/#', $sql, $hint)) {
 303                  $rewritesql = "SELECT ".$hint[0]." COUNT(*) FROM (".$rewritesql.")"; 
 304              } else
 305                  $rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")"; 
 306              
 307          } else if (strncmp($zthis->databaseType,'postgres',8) == 0)  {
 308              
 309              $info = $zthis->ServerInfo();
 310              if (substr($info['version'],0,3) >= 7.1) { // good till version 999
 311                  $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$sql);
 312                  $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
 313              }
 314          }
 315      } else {
 316          // now replace SELECT ... FROM with SELECT COUNT(*) FROM
 317          $rewritesql = preg_replace(
 318                      '/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql);
 319  
 320          // fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails 
 321          // with mssql, access and postgresql. Also a good speedup optimization - skips sorting!
 322          $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$rewritesql);
 323      }
 324      
 325      if (isset($rewritesql) && $rewritesql != $sql) {
 326          if ($secs2cache) {
 327              // we only use half the time of secs2cache because the count can quickly
 328              // become inaccurate if new records are added
 329              $qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr);
 330              
 331          } else {
 332              $qryRecs = $zthis->GetOne($rewritesql,$inputarr);
 333            }
 334          if ($qryRecs !== false) return $qryRecs;
 335      }
 336      //--------------------------------------------
 337      // query rewrite failed - so try slower way...
 338      
 339      
 340      // strip off unneeded ORDER BY if no UNION
 341      if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql;
 342      else $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql); 
 343      
 344      $rstest = &$zthis->Execute($rewritesql,$inputarr);
 345      if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr);
 346      
 347      if ($rstest) {
 348                $qryRecs = $rstest->RecordCount();
 349          if ($qryRecs == -1) { 
 350          global $ADODB_EXTENSION;
 351          // some databases will return -1 on MoveLast() - change to MoveNext()
 352              if ($ADODB_EXTENSION) {
 353                  while(!$rstest->EOF) {
 354                      adodb_movenext($rstest);
 355                  }
 356              } else {
 357                  while(!$rstest->EOF) {
 358                      $rstest->MoveNext();
 359                  }
 360              }
 361              $qryRecs = $rstest->_currentRow;
 362          }
 363          $rstest->Close();
 364          if ($qryRecs == -1) return 0;
 365      }
 366      
 367      return $qryRecs;
 368  }
 369  
 370  /*
 371       Code originally from "Cornel G" <conyg@fx.ro>
 372  
 373      This code might not work with SQL that has UNION in it    
 374      
 375      Also if you are using CachePageExecute(), there is a strong possibility that
 376      data will get out of synch. use CachePageExecute() only with tables that
 377      rarely change.
 378  */
 379  function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page, 
 380                          $inputarr=false, $secs2cache=0) 
 381  {
 382      $atfirstpage = false;
 383      $atlastpage = false;
 384      $lastpageno=1;
 385  
 386      // If an invalid nrows is supplied, 
 387      // we assume a default value of 10 rows per page
 388      if (!isset($nrows) || $nrows <= 0) $nrows = 10;
 389  
 390      $qryRecs = false; //count records for no offset
 391      
 392      $qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache);
 393      $lastpageno = (int) ceil($qryRecs / $nrows);
 394      $zthis->_maxRecordCount = $qryRecs;
 395      
 396  
 397  
 398      // ***** Here we check whether $page is the last page or 
 399      // whether we are trying to retrieve 
 400      // a page number greater than the last page number.
 401      if ($page >= $lastpageno) {
 402          $page = $lastpageno;
 403          $atlastpage = true;
 404      }
 405      
 406      // If page number <= 1, then we are at the first page
 407      if (empty($page) || $page <= 1) {    
 408          $page = 1;
 409          $atfirstpage = true;
 410      }
 411      
 412      // We get the data we want
 413      $offset = $nrows * ($page-1);
 414      if ($secs2cache > 0) 
 415          $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
 416      else 
 417          $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
 418  
 419      
 420      // Before returning the RecordSet, we set the pagination properties we need
 421      if ($rsreturn) {
 422          $rsreturn->_maxRecordCount = $qryRecs;
 423          $rsreturn->rowsPerPage = $nrows;
 424          $rsreturn->AbsolutePage($page);
 425          $rsreturn->AtFirstPage($atfirstpage);
 426          $rsreturn->AtLastPage($atlastpage);
 427          $rsreturn->LastPageNo($lastpageno);
 428      }
 429      return $rsreturn;
 430  }
 431  
 432  // Iván Oliva version
 433  function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0) 
 434  {
 435  
 436      $atfirstpage = false;
 437      $atlastpage = false;
 438      
 439      if (!isset($page) || $page <= 1) {    // If page number <= 1, then we are at the first page
 440          $page = 1;
 441          $atfirstpage = true;
 442      }
 443      if ($nrows <= 0) $nrows = 10;    // If an invalid nrows is supplied, we assume a default value of 10 rows per page
 444      
 445      // ***** Here we check whether $page is the last page or whether we are trying to retrieve a page number greater than 
 446      // the last page number.
 447      $pagecounter = $page + 1;
 448      $pagecounteroffset = ($pagecounter * $nrows) - $nrows;
 449      if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
 450      else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
 451      if ($rstest) {
 452          while ($rstest && $rstest->EOF && $pagecounter>0) {
 453              $atlastpage = true;
 454              $pagecounter--;
 455              $pagecounteroffset = $nrows * ($pagecounter - 1);
 456              $rstest->Close();
 457              if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
 458              else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
 459          }
 460          if ($rstest) $rstest->Close();
 461      }
 462      if ($atlastpage) {    // If we are at the last page or beyond it, we are going to retrieve it
 463          $page = $pagecounter;
 464          if ($page == 1) $atfirstpage = true;    // We have to do this again in case the last page is the same as the first
 465              //... page, that is, the recordset has only 1 page.
 466      }
 467      
 468      // We get the data we want
 469      $offset = $nrows * ($page-1);
 470      if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
 471      else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
 472      
 473      // Before returning the RecordSet, we set the pagination properties we need
 474      if ($rsreturn) {
 475          $rsreturn->rowsPerPage = $nrows;
 476          $rsreturn->AbsolutePage($page);
 477          $rsreturn->AtFirstPage($atfirstpage);
 478          $rsreturn->AtLastPage($atlastpage);
 479      }
 480      return $rsreturn;
 481  }
 482  
 483  function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2)
 484  {
 485          if (!$rs) {
 486              printf(ADODB_BAD_RS,'GetUpdateSQL');
 487              return false;
 488          }
 489      
 490          $fieldUpdatedCount = 0;
 491          $arrFields = _array_change_key_case($arrFields);
 492  
 493          $hasnumeric = isset($rs->fields[0]);
 494          $setFields = '';
 495          
 496          // Loop through all of the fields in the recordset
 497          for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
 498              // Get the field from the recordset
 499              $field = $rs->FetchField($i);
 500  
 501              // If the recordset field is one
 502              // of the fields passed in then process.
 503              $upperfname = strtoupper($field->name);
 504              if (adodb_key_exists($upperfname,$arrFields,$force)) {
 505                  
 506                  // If the existing field value in the recordset
 507                  // is different from the value passed in then
 508                  // go ahead and append the field name and new value to
 509                  // the update query.
 510                  
 511                  if ($hasnumeric) $val = $rs->fields[$i];
 512                  else if (isset($rs->fields[$upperfname])) $val = $rs->fields[$upperfname];
 513                  else if (isset($rs->fields[$field->name])) $val =  $rs->fields[$field->name];
 514                  else if (isset($rs->fields[strtolower($upperfname)])) $val =  $rs->fields[strtolower($upperfname)];
 515                  else $val = '';
 516                  
 517              
 518                  if ($forceUpdate || strcmp($val, $arrFields[$upperfname])) {
 519                      // Set the counter for the number of fields that will be updated.
 520                      $fieldUpdatedCount++;
 521  
 522                      // Based on the datatype of the field
 523                      // Format the value properly for the database
 524                      $type = $rs->MetaType($field->type);
 525                          
 526  
 527                      if ($type == 'null') {
 528                          $type = 'C';
 529                      }
 530                      
 531                      if (strpos($upperfname,' ') !== false)
 532                          $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
 533                      else
 534                          $fnameq = $upperfname;
 535                      
 536                      
 537                  // is_null requires php 4.0.4
 538                  //********************************************************//
 539                  if (is_null($arrFields[$upperfname])
 540                      || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
 541                      || $arrFields[$upperfname] === 'null'
 542                      )
 543                  {
 544                      switch ($force) {
 545  
 546                          //case 0:
 547                          //    //Ignore empty values. This is allready handled in "adodb_key_exists" function.
 548                          //break;
 549  
 550                          case 1:
 551                              //Set null
 552                              $setFields .= $field->name . " = null, ";
 553                          break;
 554                              
 555                          case 2:
 556                              //Set empty
 557                              $arrFields[$upperfname] = "";
 558                              $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
 559                          break;
 560                          default:
 561                          case 3:
 562                              //Set the value that was given in array, so you can give both null and empty values
 563                              if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === 'null') {
 564                                  $setFields .= $field->name . " = null, ";
 565                              } else {
 566                                  $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
 567                              }
 568                          break;
 569                      }
 570                  //********************************************************//
 571                  } else {
 572                          //we do this so each driver can customize the sql for
 573                          //DB specific column types. 
 574                          //Oracle needs BLOB types to be handled with a returning clause
 575                          //postgres has special needs as well
 576                          $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
 577                                                            $arrFields, $magicq);
 578                      }
 579                  }
 580              }
 581          }
 582  
 583          // If there were any modified fields then build the rest of the update query.
 584          if ($fieldUpdatedCount > 0 || $forceUpdate) {
 585                      // Get the table name from the existing query.
 586              if (!empty($rs->tableName)) $tableName = $rs->tableName;
 587              else {
 588                  preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
 589                  $tableName = $tableName[1];
 590              }
 591              // Get the full where clause excluding the word "WHERE" from
 592              // the existing query.
 593              preg_match('/\sWHERE\s(.*)/is', $rs->sql, $whereClause);
 594              
 595              $discard = false;
 596              // not a good hack, improvements?
 597              if ($whereClause) {
 598                  if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
 599                  else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard));
 600                  else preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard);
 601              } else
 602                  $whereClause = array(false,false);
 603                  
 604              if ($discard)
 605                  $whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
 606              
 607              $sql = 'UPDATE '.$tableName.' SET '.substr($setFields, 0, -2);
 608              if (strlen($whereClause[1]) > 0) 
 609                  $sql .= ' WHERE '.$whereClause[1];
 610  
 611              return $sql;
 612  
 613          } else {
 614              return false;
 615      }
 616  }
 617  
 618  function adodb_key_exists($key, &$arr,$force=2)
 619  {
 620      if ($force<=0) {
 621          // the following is the old behaviour where null or empty fields are ignored
 622          return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0);
 623      }
 624  
 625      if (isset($arr[$key])) return true;
 626      ## null check below
 627      if (ADODB_PHPVER >= 0x4010) return array_key_exists($key,$arr);
 628      return false;
 629  }
 630  
 631  /**
 632   * There is a special case of this function for the oci8 driver.
 633   * The proper way to handle an insert w/ a blob in oracle requires
 634   * a returning clause with bind variables and a descriptor blob.
 635   * 
 636   * 
 637   */
 638  function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2)
 639  {
 640  static $cacheRS = false;
 641  static $cacheSig = 0;
 642  static $cacheCols;
 643  
 644      $tableName = '';
 645      $values = '';
 646      $fields = '';
 647      $recordSet = null;
 648      $arrFields = _array_change_key_case($arrFields);
 649      $fieldInsertedCount = 0;
 650      
 651      if (is_string($rs)) {
 652          //ok we have a table name
 653          //try and get the column info ourself.
 654          $tableName = $rs;            
 655      
 656          //we need an object for the recordSet
 657          //because we have to call MetaType.
 658          //php can't do a $rsclass::MetaType()
 659          $rsclass = $zthis->rsPrefix.$zthis->databaseType;
 660          $recordSet = new $rsclass(-1,$zthis->fetchMode);
 661          $recordSet->connection = &$zthis;
 662          
 663          if (is_string($cacheRS) && $cacheRS == $rs) {
 664              $columns =& $cacheCols;
 665          } else {
 666              $columns = $zthis->MetaColumns( $tableName );
 667              $cacheRS = $tableName;
 668              $cacheCols = $columns;
 669          }
 670      } else if (is_subclass_of($rs, 'adorecordset')) {
 671          if (isset($rs->insertSig) && is_integer($cacheRS) && $cacheRS == $rs->insertSig) {
 672              $columns =& $cacheCols;
 673          } else {
 674              for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) 
 675                  $columns[] = $rs->FetchField($i);
 676              $cacheRS = $cacheSig;
 677              $cacheCols = $columns;
 678              $rs->insertSig = $cacheSig++;
 679          }
 680          $recordSet =& $rs;
 681      
 682      } else {
 683          printf(ADODB_BAD_RS,'GetInsertSQL');
 684          return false;
 685      }
 686  
 687      // Loop through all of the fields in the recordset
 688      foreach( $columns as $field ) { 
 689          $upperfname = strtoupper($field->name);
 690          if (adodb_key_exists($upperfname,$arrFields,$force)) {
 691              $bad = false;
 692              if (strpos($upperfname,' ') !== false)
 693                  $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
 694              else
 695                  $fnameq = $upperfname;
 696              
 697              $type = $recordSet->MetaType($field->type);
 698              
 699              /********************************************************/
 700              if (is_null($arrFields[$upperfname])
 701                  || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
 702                  || $arrFields[$upperfname] === 'null'
 703                  )
 704                 {
 705                      switch ($force) {
 706  
 707                          case 0: // we must always set null if missing
 708                              $bad = true;
 709                              break;
 710                              
 711                          case 1:
 712                              $values  .= "null, ";
 713                          break;
 714          
 715                          case 2:
 716                              //Set empty
 717                              $arrFields[$upperfname] = "";
 718                              $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq);
 719                          break;
 720  
 721                          default:
 722                          case 3:
 723                              //Set the value that was given in array, so you can give both null and empty values
 724                              if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === 'null') { 
 725                                  $values  .= "null, ";
 726                              } else {
 727                                  $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq);
 728                               }
 729                            break;
 730                       } // switch
 731  
 732              /*********************************************************/
 733              } else {
 734                  //we do this so each driver can customize the sql for
 735                  //DB specific column types. 
 736                  //Oracle needs BLOB types to be handled with a returning clause
 737                  //postgres has special needs as well
 738                  $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,
 739                                                 $arrFields, $magicq);
 740              }
 741              
 742              if ($bad) continue;
 743              // Set the counter for the number of fields that will be inserted.
 744              $fieldInsertedCount++;
 745              
 746              
 747              // Get the name of the fields to insert
 748              $fields .= $fnameq . ", ";
 749          }
 750      }
 751  
 752  
 753      // If there were any inserted fields then build the rest of the insert query.
 754      if ($fieldInsertedCount <= 0)  return false;
 755      
 756      // Get the table name from the existing query.
 757      if (!$tableName) {
 758          if (!empty($rs->tableName)) $tableName = $rs->tableName;
 759          else if (preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName))
 760              $tableName = $tableName[1];
 761          else 
 762              return false;
 763      }        
 764  
 765      // Strip off the comma and space on the end of both the fields
 766      // and their values.
 767      $fields = substr($fields, 0, -2);
 768      $values = substr($values, 0, -2);
 769  
 770      // Append the fields and their values to the insert query.
 771      return 'INSERT INTO '.$tableName.' ( '.$fields.' ) VALUES ( '.$values.' )';
 772  }
 773  
 774  
 775  /**
 776   * This private method is used to help construct
 777   * the update/sql which is generated by GetInsertSQL and GetUpdateSQL.
 778   * It handles the string construction of 1 column -> sql string based on
 779   * the column type.  We want to do 'safe' handling of BLOBs
 780   * 
 781   * @param string the type of sql we are trying to create
 782   *                'I' or 'U'. 
 783   * @param string column data type from the db::MetaType() method  
 784   * @param string the column name
 785   * @param array the column value
 786   * 
 787   * @return string
 788   * 
 789   */
 790  function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq) 
 791  {
 792      $sql = '';
 793      
 794      // Based on the datatype of the field
 795      // Format the value properly for the database
 796      switch($type) {
 797      case 'B':
 798          //in order to handle Blobs correctly, we need
 799          //to do some magic for Oracle
 800  
 801          //we need to create a new descriptor to handle 
 802          //this properly
 803          if (!empty($zthis->hasReturningInto)) {
 804              if ($action == 'I') {
 805                  $sql = 'empty_blob(), ';
 806              } else {
 807                  $sql = $fnameq. '=empty_blob(), ';
 808              }
 809              //add the variable to the returning clause array
 810              //so the user can build this later in
 811              //case they want to add more to it
 812              $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
 813          } else if (empty($arrFields[$fname])){
 814              if ($action == 'I') {
 815                  $sql = 'empty_blob(), ';
 816              } else {
 817                  $sql = $fnameq. '=empty_blob(), ';
 818              }            
 819          } else {
 820              //this is to maintain compatibility
 821              //with older adodb versions.
 822              $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
 823          }
 824          break;
 825  
 826      case "X":
 827          //we need to do some more magic here for long variables
 828          //to handle these correctly in oracle.
 829  
 830          //create a safe bind var name
 831          //to avoid conflicts w/ dupes.
 832         if (!empty($zthis->hasReturningInto)) {
 833              if ($action == 'I') {
 834                  $sql = ':xx'.$fname.'xx, ';                
 835              } else {
 836                  $sql = $fnameq.'=:xx'.$fname.'xx, ';
 837              }
 838              //add the variable to the returning clause array
 839              //so the user can build this later in
 840              //case they want to add more to it
 841              $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
 842          } else {
 843              //this is to maintain compatibility
 844              //with older adodb versions.
 845              $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
 846          }            
 847          break;
 848          
 849      default:
 850          $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq,  $arrFields, $magicq,false);
 851          break;
 852      }
 853      
 854      return $sql;
 855  }    
 856      
 857  function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true) 
 858  {
 859  
 860      if ($recurse) {
 861          switch($zthis->dataProvider)  {
 862          case 'postgres':
 863              if ($type == 'L') $type = 'C';
 864              break;
 865          case 'oci8':
 866              return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq);
 867              
 868          }
 869      }
 870          
 871      switch($type) {
 872          case "C":
 873          case "X":
 874          case 'B':
 875              $val = $zthis->qstr($arrFields[$fname],$magicq);
 876              break;
 877  
 878          case "D":
 879              $val = $zthis->DBDate($arrFields[$fname]);
 880              break;
 881  
 882          case "T":
 883              $val = $zthis->DBTimeStamp($arrFields[$fname]);
 884              break;
 885  
 886          default:
 887              $val = $arrFields[$fname];
 888              if (empty($val)) $val = '0';
 889              break;
 890      }
 891  
 892      if ($action == 'I') return $val . ", ";
 893      
 894      
 895      return $fnameq . "=" . $val  . ", ";
 896      
 897  }
 898  
 899  
 900  
 901  function _adodb_debug_execute(&$zthis, $sql, $inputarr)
 902  {
 903      $ss = '';
 904      if ($inputarr) {
 905          foreach($inputarr as $kk=>$vv) {
 906              if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
 907              $ss .= "($kk=>'$vv') ";
 908          }
 909          $ss = "[ $ss ]";
 910      }
 911      $sqlTxt = is_array($sql) ? $sql[0] : $sql;
 912      /*str_replace(', ','##1#__^LF',is_array($sql) ? $sql[0] : $sql);
 913      $sqlTxt = str_replace(',',', ',$sqlTxt);
 914      $sqlTxt = str_replace('##1#__^LF', ', ' ,$sqlTxt);
 915      */
 916      // check if running from browser or command-line
 917      $inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
 918      
 919      $dbt = $zthis->databaseType;
 920      if (isset($zthis->dsnType)) $dbt .= '-'.$zthis->dsnType;
 921      if ($inBrowser) {
 922          $ss = htmlspecialchars($ss);
 923          if ($zthis->debug === -1)
 924              ADOConnection::outp( "<br>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; <code>$ss</code>\n<br>\n",false);
 925          else 
 926              ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; <code>$ss</code>\n<hr>\n",false);
 927      } else {
 928          ADOConnection::outp("-----\n($dbt): ".$sqlTxt."\n-----\n",false);
 929      }
 930  
 931      $qID = $zthis->_query($sql,$inputarr);
 932      
 933      /* 
 934          Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
 935          because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
 936      */
 937      if ($zthis->databaseType == 'mssql') { 
 938      // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
 939          if($emsg = $zthis->ErrorMsg()) {
 940              if ($err = $zthis->ErrorNo()) ADOConnection::outp($err.': '.$emsg);
 941          }
 942      } else if (!$qID) {
 943          ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
 944      }
 945      
 946      if ($zthis->debug === 99) _adodb_backtrace(true,9999,2);
 947      return $qID;
 948  }
 949  
 950  
 951  function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0)
 952  {
 953      if ((float) PHPVERSION() < 4.3) return '';
 954       
 955      $html =  (isset($_SERVER['HTTP_USER_AGENT']));
 956      $fmt =  ($html) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
 957  
 958      $MAXSTRLEN = 128;
 959  
 960      $s = ($html) ? '<pre align=left>' : '';
 961      
 962      if (is_array($printOrArr)) $traceArr = $printOrArr;
 963      else $traceArr = debug_backtrace();
 964      array_shift($traceArr);
 965      array_shift($traceArr);
 966      $tabs = sizeof($traceArr)-2;
 967      
 968      foreach ($traceArr as $arr) {
 969          if ($skippy) {$skippy -= 1; continue;}
 970          $levels -= 1;
 971          if ($levels < 0) break;
 972          
 973          $args = array();
 974          for ($i=0; $i < $tabs; $i++) $s .=  ($html) ? ' &nbsp; ' : "\t";
 975          $tabs -= 1;
 976          if ($html) $s .= '<font face="Courier New,Courier">';
 977          if (isset($arr['class'])) $s .= $arr['class'].'.';
 978          if (isset($arr['args']))
 979           foreach($arr['args'] as $v) {
 980              if (is_null($v)) $args[] = 'null';
 981              else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
 982              else if (is_object($v)) $args[] = 'Object:'.get_class($v);
 983              else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
 984              else {
 985                  $v = (string) @$v;
 986                  $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
 987                  if (strlen($v) > $MAXSTRLEN) $str .= '...';
 988                  $args[] = $str;
 989              }
 990          }
 991          $s .= $arr['function'].'('.implode(', ',$args).')';
 992          
 993          
 994          $s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
 995              
 996          $s .= "\n";
 997      }    
 998      if ($html) $s .= '</pre>';
 999      if ($printOrArr) print $s;
1000      
1001      return $s;
1002  }
1003  
1004  ?>


Généré le : Sun Feb 25 17:20:01 2007 par Balluche grâce à PHPXref 0.7