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