See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
1 <?php 2 /** 3 @version v5.20.16 12-Jan-2020 4 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved. 5 @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community 6 7 Released under both BSD license and Lesser GPL library license. 8 Whenever there is any discrepancy between the two licenses, 9 the BSD license will take precedence. 10 11 Set tabs to 4 for best viewing. 12 13 Latest version is available at http://adodb.org/ 14 15 Requires ODBC. Works on Windows and Unix. 16 17 Problems: 18 Where is float/decimal type in pdo_param_type 19 LOB handling for CLOB/BLOB differs significantly 20 */ 21 22 // security - hide paths 23 if (!defined('ADODB_DIR')) die(); 24 25 26 /* 27 enum pdo_param_type { 28 PDO::PARAM_NULL, 0 29 30 /* int as in long (the php native int type). 31 * If you mark a column as an int, PDO expects get_col to return 32 * a pointer to a long 33 PDO::PARAM_INT, 1 34 35 /* get_col ptr should point to start of the string buffer 36 PDO::PARAM_STR, 2 37 38 /* get_col: when len is 0 ptr should point to a php_stream *, 39 * otherwise it should behave like a string. Indicate a NULL field 40 * value by setting the ptr to NULL 41 PDO::PARAM_LOB, 3 42 43 /* get_col: will expect the ptr to point to a new PDOStatement object handle, 44 * but this isn't wired up yet 45 PDO::PARAM_STMT, 4 /* hierarchical result set 46 47 /* get_col ptr should point to a zend_bool 48 PDO::PARAM_BOOL, 5 49 50 51 /* magic flag to denote a parameter as being input/output 52 PDO::PARAM_INPUT_OUTPUT = 0x80000000 53 }; 54 */ 55 56 function adodb_pdo_type($t) 57 { 58 switch($t) { 59 case 2: return 'VARCHAR'; 60 case 3: return 'BLOB'; 61 default: return 'NUMERIC'; 62 } 63 } 64 65 /*----------------------------------------------------------------------------*/ 66 67 68 class ADODB_pdo extends ADOConnection { 69 var $databaseType = "pdo"; 70 var $dataProvider = "pdo"; 71 var $fmtDate = "'Y-m-d'"; 72 var $fmtTimeStamp = "'Y-m-d, h:i:sA'"; 73 var $replaceQuote = "''"; // string to use to replace quotes 74 var $hasAffectedRows = true; 75 var $_bindInputArray = true; 76 var $_genIDSQL; 77 var $_genSeqSQL = "create table %s (id integer)"; 78 var $_dropSeqSQL; 79 var $_autocommit = true; 80 var $_haserrorfunctions = true; 81 var $_lastAffectedRows = 0; 82 83 var $_errormsg = false; 84 var $_errorno = false; 85 86 var $dsnType = ''; 87 var $stmt = false; 88 var $_driver; 89 90 function __construct() 91 { 92 } 93 94 function _UpdatePDO() 95 { 96 $d = $this->_driver; 97 $this->fmtDate = $d->fmtDate; 98 $this->fmtTimeStamp = $d->fmtTimeStamp; 99 $this->replaceQuote = $d->replaceQuote; 100 $this->sysDate = $d->sysDate; 101 $this->sysTimeStamp = $d->sysTimeStamp; 102 $this->random = $d->random; 103 $this->concat_operator = $d->concat_operator; 104 $this->nameQuote = $d->nameQuote; 105 106 $this->hasGenID = $d->hasGenID; 107 $this->_genIDSQL = $d->_genIDSQL; 108 $this->_genSeqSQL = $d->_genSeqSQL; 109 $this->_dropSeqSQL = $d->_dropSeqSQL; 110 111 $d->_init($this); 112 } 113 114 function Time() 115 { 116 if (!empty($this->_driver->_hasdual)) { 117 $sql = "select $this->sysTimeStamp from dual"; 118 } 119 else { 120 $sql = "select $this->sysTimeStamp"; 121 } 122 123 $rs = $this->_Execute($sql); 124 if ($rs && !$rs->EOF) { 125 return $this->UnixTimeStamp(reset($rs->fields)); 126 } 127 128 return false; 129 } 130 131 // returns true or false 132 function _connect($argDSN, $argUsername, $argPassword, $argDatabasename, $persist=false) 133 { 134 $at = strpos($argDSN,':'); 135 $this->dsnType = substr($argDSN,0,$at); 136 137 if ($argDatabasename) { 138 switch($this->dsnType){ 139 case 'sqlsrv': 140 $argDSN .= ';database='.$argDatabasename; 141 break; 142 case 'mssql': 143 case 'mysql': 144 case 'oci': 145 case 'pgsql': 146 case 'sqlite': 147 default: 148 $argDSN .= ';dbname='.$argDatabasename; 149 } 150 } 151 try { 152 $this->_connectionID = new PDO($argDSN, $argUsername, $argPassword); 153 } catch (Exception $e) { 154 $this->_connectionID = false; 155 $this->_errorno = -1; 156 //var_dump($e); 157 $this->_errormsg = 'Connection attempt failed: '.$e->getMessage(); 158 return false; 159 } 160 161 if ($this->_connectionID) { 162 switch(ADODB_ASSOC_CASE){ 163 case ADODB_ASSOC_CASE_LOWER: 164 $m = PDO::CASE_LOWER; 165 break; 166 case ADODB_ASSOC_CASE_UPPER: 167 $m = PDO::CASE_UPPER; 168 break; 169 default: 170 case ADODB_ASSOC_CASE_NATIVE: 171 $m = PDO::CASE_NATURAL; 172 break; 173 } 174 175 //$this->_connectionID->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_SILENT ); 176 $this->_connectionID->setAttribute(PDO::ATTR_CASE,$m); 177 178 $class = 'ADODB_pdo_'.$this->dsnType; 179 //$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true); 180 switch($this->dsnType) { 181 case 'mssql': 182 case 'mysql': 183 case 'oci': 184 case 'pgsql': 185 case 'sqlite': 186 case 'sqlsrv': 187 include_once(ADODB_DIR.'/drivers/adodb-pdo_'.$this->dsnType.'.inc.php'); 188 break; 189 } 190 if (class_exists($class)) { 191 $this->_driver = new $class(); 192 } 193 else { 194 $this->_driver = new ADODB_pdo_base(); 195 } 196 197 $this->_driver->_connectionID = $this->_connectionID; 198 $this->_UpdatePDO(); 199 $this->_driver->database = $this->database; 200 return true; 201 } 202 $this->_driver = new ADODB_pdo_base(); 203 return false; 204 } 205 206 function Concat() 207 { 208 $args = func_get_args(); 209 if(method_exists($this->_driver, 'Concat')) { 210 return call_user_func_array(array($this->_driver, 'Concat'), $args); 211 } 212 213 if (PHP_VERSION >= 5.3) { 214 return call_user_func_array('parent::Concat', $args); 215 } 216 return call_user_func_array(array($this,'parent::Concat'), $args); 217 } 218 219 // returns true or false 220 function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename) 221 { 222 return $this->_connect($argDSN, $argUsername, $argPassword, $argDatabasename, true); 223 } 224 225 /*------------------------------------------------------------------------------*/ 226 227 228 function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 229 { 230 $save = $this->_driver->fetchMode; 231 $this->_driver->fetchMode = $this->fetchMode; 232 $this->_driver->debug = $this->debug; 233 $ret = $this->_driver->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache); 234 $this->_driver->fetchMode = $save; 235 return $ret; 236 } 237 238 239 function ServerInfo() 240 { 241 return $this->_driver->ServerInfo(); 242 } 243 244 function MetaTables($ttype=false,$showSchema=false,$mask=false) 245 { 246 return $this->_driver->MetaTables($ttype,$showSchema,$mask); 247 } 248 249 function MetaColumns($table,$normalize=true) 250 { 251 return $this->_driver->MetaColumns($table,$normalize); 252 } 253 254 function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) 255 { 256 $obj = $stmt[1]; 257 if ($type) { 258 $obj->bindParam($name, $var, $type, $maxLen); 259 } 260 else { 261 $obj->bindParam($name, $var); 262 } 263 } 264 265 function OffsetDate($dayFraction,$date=false) 266 { 267 return $this->_driver->OffsetDate($dayFraction,$date); 268 } 269 270 function SelectDB($dbName) 271 { 272 return $this->_driver->SelectDB($dbName); 273 } 274 275 function SQLDate($fmt, $col=false) 276 { 277 return $this->_driver->SQLDate($fmt, $col); 278 } 279 280 function ErrorMsg() 281 { 282 if ($this->_errormsg !== false) { 283 return $this->_errormsg; 284 } 285 if (!empty($this->_stmt)) { 286 $arr = $this->_stmt->errorInfo(); 287 } 288 else if (!empty($this->_connectionID)) { 289 $arr = $this->_connectionID->errorInfo(); 290 } 291 else { 292 return 'No Connection Established'; 293 } 294 295 if ($arr) { 296 if (sizeof($arr)<2) { 297 return ''; 298 } 299 if ((integer)$arr[0]) { 300 return $arr[2]; 301 } 302 else { 303 return ''; 304 } 305 } 306 else { 307 return '-1'; 308 } 309 } 310 311 312 function ErrorNo() 313 { 314 if ($this->_errorno !== false) { 315 return $this->_errorno; 316 } 317 if (!empty($this->_stmt)) { 318 $err = $this->_stmt->errorCode(); 319 } 320 else if (!empty($this->_connectionID)) { 321 $arr = $this->_connectionID->errorInfo(); 322 if (isset($arr[0])) { 323 $err = $arr[0]; 324 } 325 else { 326 $err = -1; 327 } 328 } else { 329 return 0; 330 } 331 332 if ($err == '00000') { 333 return 0; // allows empty check 334 } 335 return $err; 336 } 337 338 /** 339 * @param bool $auto_commit 340 * @return void 341 */ 342 function SetAutoCommit($auto_commit) 343 { 344 if(method_exists($this->_driver, 'SetAutoCommit')) { 345 $this->_driver->SetAutoCommit($auto_commit); 346 } 347 } 348 349 function SetTransactionMode($transaction_mode) 350 { 351 if(method_exists($this->_driver, 'SetTransactionMode')) { 352 return $this->_driver->SetTransactionMode($transaction_mode); 353 } 354 355 return parent::SetTransactionMode($seqname); 356 } 357 358 function BeginTrans() 359 { 360 if(method_exists($this->_driver, 'BeginTrans')) { 361 return $this->_driver->BeginTrans(); 362 } 363 364 if (!$this->hasTransactions) { 365 return false; 366 } 367 if ($this->transOff) { 368 return true; 369 } 370 $this->transCnt += 1; 371 $this->_autocommit = false; 372 $this->SetAutoCommit(false); 373 374 return $this->_connectionID->beginTransaction(); 375 } 376 377 function CommitTrans($ok=true) 378 { 379 if(method_exists($this->_driver, 'CommitTrans')) { 380 return $this->_driver->CommitTrans($ok); 381 } 382 383 if (!$this->hasTransactions) { 384 return false; 385 } 386 if ($this->transOff) { 387 return true; 388 } 389 if (!$ok) { 390 return $this->RollbackTrans(); 391 } 392 if ($this->transCnt) { 393 $this->transCnt -= 1; 394 } 395 $this->_autocommit = true; 396 397 $ret = $this->_connectionID->commit(); 398 $this->SetAutoCommit(true); 399 return $ret; 400 } 401 402 function RollbackTrans() 403 { 404 if(method_exists($this->_driver, 'RollbackTrans')) { 405 return $this->_driver->RollbackTrans(); 406 } 407 408 if (!$this->hasTransactions) { 409 return false; 410 } 411 if ($this->transOff) { 412 return true; 413 } 414 if ($this->transCnt) { 415 $this->transCnt -= 1; 416 } 417 $this->_autocommit = true; 418 419 $ret = $this->_connectionID->rollback(); 420 $this->SetAutoCommit(true); 421 return $ret; 422 } 423 424 function Prepare($sql) 425 { 426 $this->_stmt = $this->_connectionID->prepare($sql); 427 if ($this->_stmt) { 428 return array($sql,$this->_stmt); 429 } 430 431 return false; 432 } 433 434 function PrepareStmt($sql) 435 { 436 $stmt = $this->_connectionID->prepare($sql); 437 if (!$stmt) { 438 return false; 439 } 440 $obj = new ADOPDOStatement($stmt,$this); 441 return $obj; 442 } 443 444 function CreateSequence($seqname='adodbseq',$startID=1) 445 { 446 if(method_exists($this->_driver, 'CreateSequence')) { 447 return $this->_driver->CreateSequence($seqname, $startID); 448 } 449 450 return parent::CreateSequence($seqname, $startID); 451 } 452 453 function DropSequence($seqname='adodbseq') 454 { 455 if(method_exists($this->_driver, 'DropSequence')) { 456 return $this->_driver->DropSequence($seqname); 457 } 458 459 return parent::DropSequence($seqname); 460 } 461 462 function GenID($seqname='adodbseq',$startID=1) 463 { 464 if(method_exists($this->_driver, 'GenID')) { 465 return $this->_driver->GenID($seqname, $startID); 466 } 467 468 return parent::GenID($seqname, $startID); 469 } 470 471 472 /* returns queryID or false */ 473 function _query($sql,$inputarr=false) 474 { 475 $ok = false; 476 if (is_array($sql)) { 477 $stmt = $sql[1]; 478 } else { 479 $stmt = $this->_connectionID->prepare($sql); 480 } 481 #adodb_backtrace(); 482 #var_dump($this->_bindInputArray); 483 if ($stmt) { 484 $this->_driver->debug = $this->debug; 485 if ($inputarr) { 486 $ok = $stmt->execute($inputarr); 487 } 488 else { 489 $ok = $stmt->execute(); 490 } 491 } 492 493 494 $this->_errormsg = false; 495 $this->_errorno = false; 496 497 if ($ok) { 498 $this->_stmt = $stmt; 499 return $stmt; 500 } 501 502 if ($stmt) { 503 504 $arr = $stmt->errorinfo(); 505 if ((integer)$arr[1]) { 506 $this->_errormsg = $arr[2]; 507 $this->_errorno = $arr[1]; 508 } 509 510 } else { 511 $this->_errormsg = false; 512 $this->_errorno = false; 513 } 514 return false; 515 } 516 517 // returns true or false 518 function _close() 519 { 520 $this->_stmt = false; 521 return true; 522 } 523 524 function _affectedrows() 525 { 526 return ($this->_stmt) ? $this->_stmt->rowCount() : 0; 527 } 528 529 function _insertid() 530 { 531 return ($this->_connectionID) ? $this->_connectionID->lastInsertId() : 0; 532 } 533 534 /** 535 * Quotes a string to be sent to the database. 536 * If we have an active connection, delegates quoting to the underlying 537 * PDO object. Otherwise, replace "'" by the value of $replaceQuote (same 538 * behavior as mysqli driver) 539 * @param string $s The string to quote 540 * @param boolean $magic_quotes If false, use PDO::quote(). 541 * @return string Quoted string 542 */ 543 function qstr($s, $magic_quotes = false) 544 { 545 if (!$magic_quotes) { 546 if ($this->_connectionID) { 547 return $this->_connectionID->quote($s); 548 } 549 return "'" . str_replace("'", $this->replaceQuote, $s) . "'"; 550 } 551 552 // undo magic quotes for " 553 $s = str_replace('\\"', '"', $s); 554 return "'$s'"; 555 } 556 557 } 558 559 class ADODB_pdo_base extends ADODB_pdo { 560 561 var $sysDate = "'?'"; 562 var $sysTimeStamp = "'?'"; 563 564 565 function _init($parentDriver) 566 { 567 $parentDriver->_bindInputArray = true; 568 #$parentDriver->_connectionID->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,true); 569 } 570 571 function ServerInfo() 572 { 573 return ADOConnection::ServerInfo(); 574 } 575 576 function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 577 { 578 $ret = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache); 579 return $ret; 580 } 581 582 function MetaTables($ttype=false,$showSchema=false,$mask=false) 583 { 584 return false; 585 } 586 587 function MetaColumns($table,$normalize=true) 588 { 589 return false; 590 } 591 } 592 593 class ADOPDOStatement { 594 595 var $databaseType = "pdo"; 596 var $dataProvider = "pdo"; 597 var $_stmt; 598 var $_connectionID; 599 600 function __construct($stmt,$connection) 601 { 602 $this->_stmt = $stmt; 603 $this->_connectionID = $connection; 604 } 605 606 function Execute($inputArr=false) 607 { 608 $savestmt = $this->_connectionID->_stmt; 609 $rs = $this->_connectionID->Execute(array(false,$this->_stmt),$inputArr); 610 $this->_connectionID->_stmt = $savestmt; 611 return $rs; 612 } 613 614 function InParameter(&$var,$name,$maxLen=4000,$type=false) 615 { 616 617 if ($type) { 618 $this->_stmt->bindParam($name,$var,$type,$maxLen); 619 } 620 else { 621 $this->_stmt->bindParam($name, $var); 622 } 623 } 624 625 function Affected_Rows() 626 { 627 return ($this->_stmt) ? $this->_stmt->rowCount() : 0; 628 } 629 630 function ErrorMsg() 631 { 632 if ($this->_stmt) { 633 $arr = $this->_stmt->errorInfo(); 634 } 635 else { 636 $arr = $this->_connectionID->errorInfo(); 637 } 638 639 if (is_array($arr)) { 640 if ((integer) $arr[0] && isset($arr[2])) { 641 return $arr[2]; 642 } 643 else { 644 return ''; 645 } 646 } else { 647 return '-1'; 648 } 649 } 650 651 function NumCols() 652 { 653 return ($this->_stmt) ? $this->_stmt->columnCount() : 0; 654 } 655 656 function ErrorNo() 657 { 658 if ($this->_stmt) { 659 return $this->_stmt->errorCode(); 660 } 661 else { 662 return $this->_connectionID->errorInfo(); 663 } 664 } 665 } 666 667 /*-------------------------------------------------------------------------------------- 668 Class Name: Recordset 669 --------------------------------------------------------------------------------------*/ 670 671 class ADORecordSet_pdo extends ADORecordSet { 672 673 var $bind = false; 674 var $databaseType = "pdo"; 675 var $dataProvider = "pdo"; 676 677 function __construct($id,$mode=false) 678 { 679 if ($mode === false) { 680 global $ADODB_FETCH_MODE; 681 $mode = $ADODB_FETCH_MODE; 682 } 683 $this->adodbFetchMode = $mode; 684 switch($mode) { 685 case ADODB_FETCH_NUM: $mode = PDO::FETCH_NUM; break; 686 case ADODB_FETCH_ASSOC: $mode = PDO::FETCH_ASSOC; break; 687 688 case ADODB_FETCH_BOTH: 689 default: $mode = PDO::FETCH_BOTH; break; 690 } 691 $this->fetchMode = $mode; 692 693 $this->_queryID = $id; 694 parent::__construct($id); 695 } 696 697 698 function Init() 699 { 700 if ($this->_inited) { 701 return; 702 } 703 $this->_inited = true; 704 if ($this->_queryID) { 705 @$this->_initrs(); 706 } 707 else { 708 $this->_numOfRows = 0; 709 $this->_numOfFields = 0; 710 } 711 if ($this->_numOfRows != 0 && $this->_currentRow == -1) { 712 $this->_currentRow = 0; 713 if ($this->EOF = ($this->_fetch() === false)) { 714 $this->_numOfRows = 0; // _numOfRows could be -1 715 } 716 } else { 717 $this->EOF = true; 718 } 719 } 720 721 function _initrs() 722 { 723 global $ADODB_COUNTRECS; 724 725 $this->_numOfRows = ($ADODB_COUNTRECS) ? @$this->_queryID->rowCount() : -1; 726 if (!$this->_numOfRows) { 727 $this->_numOfRows = -1; 728 } 729 $this->_numOfFields = $this->_queryID->columnCount(); 730 } 731 732 // returns the field object 733 function FetchField($fieldOffset = -1) 734 { 735 $off=$fieldOffset+1; // offsets begin at 1 736 737 $o= new ADOFieldObject(); 738 $arr = @$this->_queryID->getColumnMeta($fieldOffset); 739 if (!$arr) { 740 $o->name = 'bad getColumnMeta()'; 741 $o->max_length = -1; 742 $o->type = 'VARCHAR'; 743 $o->precision = 0; 744 # $false = false; 745 return $o; 746 } 747 //adodb_pr($arr); 748 $o->name = $arr['name']; 749 if (isset($arr['sqlsrv:decl_type']) && $arr['sqlsrv:decl_type'] <> "null") 750 { 751 /* 752 * If the database is SQL server, use the native built-ins 753 */ 754 $o->type = $arr['sqlsrv:decl_type']; 755 } 756 elseif (isset($arr['native_type']) && $arr['native_type'] <> "null") 757 { 758 $o->type = $arr['native_type']; 759 } 760 else 761 { 762 $o->type = adodb_pdo_type($arr['pdo_type']); 763 } 764 765 $o->max_length = $arr['len']; 766 $o->precision = $arr['precision']; 767 768 switch(ADODB_ASSOC_CASE) { 769 case ADODB_ASSOC_CASE_LOWER: 770 $o->name = strtolower($o->name); 771 break; 772 case ADODB_ASSOC_CASE_UPPER: 773 $o->name = strtoupper($o->name); 774 break; 775 } 776 return $o; 777 } 778 779 function _seek($row) 780 { 781 return false; 782 } 783 784 function _fetch() 785 { 786 if (!$this->_queryID) { 787 return false; 788 } 789 790 $this->fields = $this->_queryID->fetch($this->fetchMode); 791 return !empty($this->fields); 792 } 793 794 function _close() 795 { 796 $this->_queryID = false; 797 } 798 799 function Fields($colname) 800 { 801 if ($this->adodbFetchMode != ADODB_FETCH_NUM) { 802 return @$this->fields[$colname]; 803 } 804 805 if (!$this->bind) { 806 $this->bind = array(); 807 for ($i=0; $i < $this->_numOfFields; $i++) { 808 $o = $this->FetchField($i); 809 $this->bind[strtoupper($o->name)] = $i; 810 } 811 } 812 return $this->fields[$this->bind[strtoupper($colname)]]; 813 } 814 815 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body