| [ Index ] |
|
Code source de vtiger CRM 5.0.2 |
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)." $ss\n<br />\n",false); 949 else 950 ADOConnection::outp( "<hr />\n($dbt): ".htmlspecialchars($sqlTxt)." $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) ? ' ' : "\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 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 10:22:19 2007 | par Balluche grâce à PHPXref 0.7 |