[ Index ]
 

Code source de vtiger CRM 5.0.2

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

title

Body

[fermer]

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


Généré le : Sun Feb 25 10:22:19 2007 par Balluche grâce à PHPXref 0.7