Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 and 403] [Versions 402 and 403]
1 <?php 2 /** 3 * ADOdb base PDO driver 4 * 5 * This file is part of ADOdb, a Database Abstraction Layer library for PHP. 6 * 7 * @package ADOdb 8 * @link https://adodb.org Project's web site and documentation 9 * @link https://github.com/ADOdb/ADOdb Source code and issue tracker 10 * 11 * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause 12 * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, 13 * any later version. This means you can use it in proprietary products. 14 * See the LICENSE.md file distributed with this source code for details. 15 * @license BSD-3-Clause 16 * @license LGPL-2.1-or-later 17 * 18 * @copyright 2000-2013 John Lim 19 * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community 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 $_lastAffectedRows = 0; 81 82 var $_errormsg = false; 83 var $_errorno = false; 84 85 var $_stmt = false; 86 87 /** @var ADODB_pdo_base */ 88 var $_driver; 89 90 /** @var PDO */ 91 var $_connectionID; 92 93 /** @var PDOStatement */ 94 var $_queryID; 95 96 /* 97 * Describe parameters passed directly to the PDO driver 98 * 99 * @example $db->pdoOptions = [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]; 100 */ 101 public $pdoParameters = array(); 102 103 function _UpdatePDO() 104 { 105 $d = $this->_driver; 106 $this->fmtDate = $d->fmtDate; 107 $this->fmtTimeStamp = $d->fmtTimeStamp; 108 $this->replaceQuote = $d->replaceQuote; 109 $this->sysDate = $d->sysDate; 110 $this->sysTimeStamp = $d->sysTimeStamp; 111 $this->random = $d->random; 112 $this->concat_operator = $d->concat_operator; 113 $this->nameQuote = $d->nameQuote; 114 $this->arrayClass = $d->arrayClass; 115 116 $this->hasGenID = $d->hasGenID; 117 $this->_genIDSQL = $d->_genIDSQL; 118 $this->_genSeqSQL = $d->_genSeqSQL; 119 $this->_dropSeqSQL = $d->_dropSeqSQL; 120 121 $d->_init($this); 122 } 123 124 function Time() 125 { 126 if (!empty($this->_driver->_hasdual)) { 127 $sql = "select $this->sysTimeStamp from dual"; 128 } 129 else { 130 $sql = "select $this->sysTimeStamp"; 131 } 132 133 $rs = $this->_Execute($sql); 134 if ($rs && !$rs->EOF) { 135 return $this->UnixTimeStamp(reset($rs->fields)); 136 } 137 138 return false; 139 } 140 141 // returns true or false 142 function _connect($argDSN, $argUsername, $argPassword, $argDatabasename, $persist=false) 143 { 144 $at = strpos($argDSN,':'); 145 $this->dsnType = substr($argDSN,0,$at); 146 147 if ($argDatabasename) { 148 switch($this->dsnType){ 149 case 'sqlsrv': 150 $argDSN .= ';database='.$argDatabasename; 151 break; 152 case 'mssql': 153 case 'mysql': 154 case 'oci': 155 case 'pgsql': 156 case 'sqlite': 157 case 'firebird': 158 default: 159 $argDSN .= ';dbname='.$argDatabasename; 160 } 161 } 162 /* 163 * Configure for persistent connection if required, 164 * by adding the the pdo parameter into any provided 165 * ones 166 */ 167 if ($persist) { 168 $this->pdoParameters[\PDO::ATTR_PERSISTENT] = true; 169 } 170 171 try { 172 $this->_connectionID = new \PDO($argDSN, $argUsername, $argPassword, $this->pdoParameters); 173 } catch (Exception $e) { 174 $this->_connectionID = false; 175 $this->_errorno = -1; 176 //var_dump($e); 177 $this->_errormsg = 'Connection attempt failed: '.$e->getMessage(); 178 return false; 179 } 180 181 if ($this->_connectionID) { 182 switch(ADODB_ASSOC_CASE){ 183 case ADODB_ASSOC_CASE_LOWER: 184 $m = PDO::CASE_LOWER; 185 break; 186 case ADODB_ASSOC_CASE_UPPER: 187 $m = PDO::CASE_UPPER; 188 break; 189 default: 190 case ADODB_ASSOC_CASE_NATIVE: 191 $m = PDO::CASE_NATURAL; 192 break; 193 } 194 195 //$this->_connectionID->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_SILENT ); 196 $this->_connectionID->setAttribute(PDO::ATTR_CASE,$m); 197 198 // Now merge in any provided attributes for PDO 199 foreach ($this->connectionParameters as $options) { 200 foreach($options as $k=>$v) { 201 if ($this->debug) { 202 ADOconnection::outp('Setting attribute: ' . $k . ' to ' . $v); 203 } 204 $this->_connectionID->setAttribute($k,$v); 205 } 206 } 207 208 $class = 'ADODB_pdo_'.$this->dsnType; 209 //$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true); 210 switch($this->dsnType) { 211 case 'mssql': 212 case 'mysql': 213 case 'oci': 214 case 'pgsql': 215 case 'sqlite': 216 case 'sqlsrv': 217 case 'firebird': 218 case 'dblib': 219 include_once(ADODB_DIR.'/drivers/adodb-pdo_'.$this->dsnType.'.inc.php'); 220 break; 221 } 222 if (class_exists($class)) { 223 $this->_driver = new $class(); 224 } 225 else { 226 $this->_driver = new ADODB_pdo_base(); 227 } 228 229 $this->_driver->_connectionID = $this->_connectionID; 230 $this->_UpdatePDO(); 231 $this->_driver->database = $this->database; 232 return true; 233 } 234 $this->_driver = new ADODB_pdo_base(); 235 return false; 236 } 237 238 function Concat() 239 { 240 $args = func_get_args(); 241 if($this->_driver instanceof ADODB_pdo && method_exists($this->_driver, 'Concat')) { 242 return call_user_func_array(array($this->_driver, 'Concat'), $args); 243 } 244 245 return call_user_func_array(parent::class . '::Concat', $args); 246 } 247 248 /** 249 * Triggers a driver-specific request for a bind parameter 250 * 251 * @param string $name 252 * @param string $type 253 * 254 * @return string 255 */ 256 public function param($name,$type='C') { 257 258 $args = func_get_args(); 259 if($this->_driver instanceof ADODB_pdo && method_exists($this->_driver, 'param')) { 260 // Return the driver specific entry, that mimics the native driver 261 return call_user_func_array(array($this->_driver, 'param'), $args); 262 } 263 264 // No driver specific method defined, use mysql format '?' 265 return call_user_func_array(parent::class . '::param', $args); 266 } 267 268 // returns true or false 269 function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename) 270 { 271 return $this->_connect($argDSN, $argUsername, $argPassword, $argDatabasename, true); 272 } 273 274 /*------------------------------------------------------------------------------*/ 275 276 277 function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 278 { 279 $save = $this->_driver->fetchMode; 280 $this->_driver->fetchMode = $this->fetchMode; 281 $this->_driver->debug = $this->debug; 282 $ret = $this->_driver->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache); 283 $this->_driver->fetchMode = $save; 284 return $ret; 285 } 286 287 288 function ServerInfo() 289 { 290 return $this->_driver->ServerInfo(); 291 } 292 293 function MetaTables($ttype=false,$showSchema=false,$mask=false) 294 { 295 return $this->_driver->MetaTables($ttype,$showSchema,$mask); 296 } 297 298 function MetaColumns($table,$normalize=true) 299 { 300 return $this->_driver->MetaColumns($table,$normalize); 301 } 302 303 public function metaIndexes($table,$normalize=true,$owner=false) 304 { 305 if (method_exists($this->_driver,'metaIndexes')) 306 return $this->_driver->metaIndexes($table,$normalize,$owner); 307 } 308 309 /** 310 * Return a list of Primary Keys for a specified table. 311 * 312 * @param string $table 313 * @param bool $owner (optional) not used in this driver 314 * 315 * @return string[] Array of indexes 316 */ 317 public function metaPrimaryKeys($table,$owner=false) 318 { 319 if (method_exists($this->_driver,'metaPrimaryKeys')) 320 return $this->_driver->metaPrimaryKeys($table,$owner); 321 } 322 323 /** 324 * Returns a list of Foreign Keys associated with a specific table. 325 * 326 * @param string $table 327 * @param string $owner (optional) not used in this driver 328 * @param bool $upper 329 * @param bool $associative 330 * 331 * @return string[]|false An array where keys are tables, and values are foreign keys; 332 * false if no foreign keys could be found. 333 */ 334 public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false) { 335 if (method_exists($this->_driver,'metaForeignKeys')) 336 return $this->_driver->metaForeignKeys($table, $owner, $upper, $associative); 337 } 338 339 /** 340 * List procedures or functions in an array. 341 * 342 * @param $procedureNamePattern A procedure name pattern; must match the procedure name as it is stored in the database. 343 * @param $catalog A catalog name; must match the catalog name as it is stored in the database. 344 * @param $schemaPattern A schema name pattern. 345 * 346 * @return false|array false if not supported, or array of procedures on current database with structure below 347 * Array( 348 * [name_of_procedure] => Array( 349 * [type] => PROCEDURE or FUNCTION 350 * [catalog] => Catalog_name 351 * [schema] => Schema_name 352 * [remarks] => explanatory comment on the procedure 353 * ) 354 * ) 355 */ 356 public function metaProcedures($procedureNamePattern = null, $catalog = null, $schemaPattern = null) { 357 if (method_exists($this->_driver,'metaProcedures')) 358 return $this->_driver->metaProcedures($procedureNamePattern,$catalog,$schemaPattern); 359 return false; 360 } 361 362 function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) 363 { 364 $obj = $stmt[1]; 365 if ($type) { 366 $obj->bindParam($name, $var, $type, $maxLen); 367 } 368 else { 369 $obj->bindParam($name, $var); 370 } 371 } 372 373 function OffsetDate($dayFraction,$date=false) 374 { 375 return $this->_driver->OffsetDate($dayFraction,$date); 376 } 377 378 function SelectDB($dbName) 379 { 380 return $this->_driver->SelectDB($dbName); 381 } 382 383 function SQLDate($fmt, $col=false) 384 { 385 return $this->_driver->SQLDate($fmt, $col); 386 } 387 388 function ErrorMsg() 389 { 390 if ($this->_errormsg !== false) { 391 return $this->_errormsg; 392 } 393 if (!empty($this->_stmt)) { 394 $arr = $this->_stmt->errorInfo(); 395 } 396 else if (!empty($this->_connectionID)) { 397 $arr = $this->_connectionID->errorInfo(); 398 } 399 else { 400 return 'No Connection Established'; 401 } 402 403 if ($arr) { 404 if (sizeof($arr)<2) { 405 return ''; 406 } 407 if ((integer)$arr[0]) { 408 return $arr[2]; 409 } 410 else { 411 return ''; 412 } 413 } 414 else { 415 return '-1'; 416 } 417 } 418 419 420 function ErrorNo() 421 { 422 if ($this->_errorno !== false) { 423 return $this->_errorno; 424 } 425 if (!empty($this->_stmt)) { 426 $err = $this->_stmt->errorCode(); 427 } 428 else if (!empty($this->_connectionID)) { 429 $arr = $this->_connectionID->errorInfo(); 430 if (isset($arr[0])) { 431 $err = $arr[0]; 432 } 433 else { 434 $err = -1; 435 } 436 } else { 437 return 0; 438 } 439 440 if ($err == '00000') { 441 return 0; // allows empty check 442 } 443 return $err; 444 } 445 446 /** 447 * @param bool $auto_commit 448 * @return void 449 */ 450 function SetAutoCommit($auto_commit) 451 { 452 if($this->_driver instanceof ADODB_pdo && method_exists($this->_driver, 'SetAutoCommit')) { 453 $this->_driver->SetAutoCommit($auto_commit); 454 } 455 } 456 457 function SetTransactionMode($transaction_mode) 458 { 459 if($this->_driver instanceof ADODB_pdo && method_exists($this->_driver, 'SetTransactionMode')) { 460 return $this->_driver->SetTransactionMode($transaction_mode); 461 } 462 463 return parent::SetTransactionMode($transaction_mode); 464 } 465 466 function beginTrans() 467 { 468 if($this->_driver instanceof ADODB_pdo && method_exists($this->_driver, 'beginTrans')) { 469 return $this->_driver->beginTrans(); 470 } 471 472 if (!$this->hasTransactions) { 473 return false; 474 } 475 if ($this->transOff) { 476 return true; 477 } 478 $this->transCnt += 1; 479 $this->_autocommit = false; 480 $this->SetAutoCommit(false); 481 482 return $this->_connectionID->beginTransaction(); 483 } 484 485 function commitTrans($ok=true) 486 { 487 488 if($this->_driver instanceof ADODB_pdo && method_exists($this->_driver, 'commitTrans')) { 489 return $this->_driver->commitTrans($ok); 490 } 491 492 if (!$this->hasTransactions) { 493 return false; 494 } 495 if ($this->transOff) { 496 return true; 497 } 498 if (!$ok) { 499 return $this->rollbackTrans(); 500 } 501 if ($this->transCnt) { 502 $this->transCnt -= 1; 503 } 504 $this->_autocommit = true; 505 506 $ret = $this->_connectionID->commit(); 507 $this->SetAutoCommit(true); 508 return $ret; 509 } 510 511 function RollbackTrans() 512 { 513 if($this->_driver instanceof ADODB_pdo && method_exists($this->_driver, 'RollbackTrans')) { 514 return $this->_driver->RollbackTrans(); 515 } 516 517 if (!$this->hasTransactions) { 518 return false; 519 } 520 if ($this->transOff) { 521 return true; 522 } 523 if ($this->transCnt) { 524 $this->transCnt -= 1; 525 } 526 $this->_autocommit = true; 527 528 $ret = $this->_connectionID->rollback(); 529 $this->SetAutoCommit(true); 530 return $ret; 531 } 532 533 function Prepare($sql) 534 { 535 $this->_stmt = $this->_connectionID->prepare($sql); 536 if ($this->_stmt) { 537 return array($sql,$this->_stmt); 538 } 539 540 return false; 541 } 542 543 function PrepareStmt($sql) 544 { 545 $stmt = $this->_connectionID->prepare($sql); 546 if (!$stmt) { 547 return false; 548 } 549 $obj = new ADOPDOStatement($stmt,$this); 550 return $obj; 551 } 552 553 public function createSequence($seqname='adodbseq',$startID=1) 554 { 555 if($this->_driver instanceof ADODB_pdo && method_exists($this->_driver, 'createSequence')) { 556 return $this->_driver->createSequence($seqname, $startID); 557 } 558 559 return parent::CreateSequence($seqname, $startID); 560 } 561 562 function DropSequence($seqname='adodbseq') 563 { 564 if($this->_driver instanceof ADODB_pdo && method_exists($this->_driver, 'DropSequence')) { 565 return $this->_driver->DropSequence($seqname); 566 } 567 568 return parent::DropSequence($seqname); 569 } 570 571 function GenID($seqname='adodbseq',$startID=1) 572 { 573 if($this->_driver instanceof ADODB_pdo && method_exists($this->_driver, 'GenID')) { 574 return $this->_driver->GenID($seqname, $startID); 575 } 576 577 return parent::GenID($seqname, $startID); 578 } 579 580 581 /* returns queryID or false */ 582 function _query($sql,$inputarr=false) 583 { 584 $ok = false; 585 if (is_array($sql)) { 586 $stmt = $sql[1]; 587 } else { 588 $stmt = $this->_connectionID->prepare($sql); 589 } 590 591 if ($stmt) { 592 if ($this->_driver instanceof ADODB_pdo) { 593 $this->_driver->debug = $this->debug; 594 } 595 if ($inputarr) { 596 597 /* 598 * inputarr must be numeric 599 */ 600 $inputarr = array_values($inputarr); 601 $ok = $stmt->execute($inputarr); 602 } 603 else { 604 $ok = $stmt->execute(); 605 } 606 } 607 608 609 $this->_errormsg = false; 610 $this->_errorno = false; 611 612 if ($ok) { 613 $this->_stmt = $stmt; 614 return $stmt; 615 } 616 617 if ($stmt) { 618 619 $arr = $stmt->errorinfo(); 620 if ((integer)$arr[1]) { 621 $this->_errormsg = $arr[2]; 622 $this->_errorno = $arr[1]; 623 } 624 625 } else { 626 $this->_errormsg = false; 627 $this->_errorno = false; 628 } 629 return false; 630 } 631 632 // returns true or false 633 function _close() 634 { 635 $this->_stmt = false; 636 return true; 637 } 638 639 function _affectedrows() 640 { 641 return ($this->_stmt) ? $this->_stmt->rowCount() : 0; 642 } 643 644 protected function _insertID($table = '', $column = '') 645 { 646 return ($this->_connectionID) ? $this->_connectionID->lastInsertId() : 0; 647 } 648 649 /** 650 * Quotes a string to be sent to the database. 651 * 652 * If we have an active connection, delegates quoting to the underlying 653 * PDO object PDO::quote(). Otherwise, replace "'" by the value of 654 * $replaceQuote (same behavior as mysqli driver). 655 * 656 * @param string $s The string to quote 657 * @param bool $magic_quotes This param is not used since 5.21.0. 658 * It remains for backwards compatibility. 659 * 660 * @return string Quoted string 661 */ 662 function qStr($s, $magic_quotes = false) 663 { 664 if ($this->_connectionID) { 665 return $this->_connectionID->quote($s); 666 } 667 return "'" . str_replace("'", $this->replaceQuote, $s) . "'"; 668 } 669 670 } 671 672 /** 673 * Base class for Database-specific PDO drivers. 674 */ 675 class ADODB_pdo_base extends ADODB_pdo { 676 677 var $sysDate = "'?'"; 678 var $sysTimeStamp = "'?'"; 679 680 681 function _init($parentDriver) 682 { 683 $parentDriver->_bindInputArray = true; 684 #$parentDriver->_connectionID->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,true); 685 } 686 687 function ServerInfo() 688 { 689 return ADOConnection::ServerInfo(); 690 } 691 692 function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 693 { 694 $ret = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache); 695 return $ret; 696 } 697 698 function MetaTables($ttype=false,$showSchema=false,$mask=false) 699 { 700 return false; 701 } 702 703 function MetaColumns($table,$normalize=true) 704 { 705 return false; 706 } 707 } 708 709 class ADOPDOStatement { 710 711 var $databaseType = "pdo"; 712 var $dataProvider = "pdo"; 713 var $_stmt; 714 var $_connectionID; 715 716 function __construct($stmt,$connection) 717 { 718 $this->_stmt = $stmt; 719 $this->_connectionID = $connection; 720 } 721 722 function Execute($inputArr=false) 723 { 724 $savestmt = $this->_connectionID->_stmt; 725 $rs = $this->_connectionID->Execute(array(false,$this->_stmt),$inputArr); 726 $this->_connectionID->_stmt = $savestmt; 727 return $rs; 728 } 729 730 function InParameter(&$var,$name,$maxLen=4000,$type=false) 731 { 732 733 if ($type) { 734 $this->_stmt->bindParam($name,$var,$type,$maxLen); 735 } 736 else { 737 $this->_stmt->bindParam($name, $var); 738 } 739 } 740 741 function Affected_Rows() 742 { 743 return ($this->_stmt) ? $this->_stmt->rowCount() : 0; 744 } 745 746 function ErrorMsg() 747 { 748 if ($this->_stmt) { 749 $arr = $this->_stmt->errorInfo(); 750 } 751 else { 752 $arr = $this->_connectionID->errorInfo(); 753 } 754 755 if (is_array($arr)) { 756 if ((integer) $arr[0] && isset($arr[2])) { 757 return $arr[2]; 758 } 759 else { 760 return ''; 761 } 762 } else { 763 return '-1'; 764 } 765 } 766 767 function NumCols() 768 { 769 return ($this->_stmt) ? $this->_stmt->columnCount() : 0; 770 } 771 772 function ErrorNo() 773 { 774 if ($this->_stmt) { 775 return $this->_stmt->errorCode(); 776 } 777 else { 778 return $this->_connectionID->errorInfo(); 779 } 780 } 781 } 782 783 /*-------------------------------------------------------------------------------------- 784 Class Name: Recordset 785 --------------------------------------------------------------------------------------*/ 786 787 class ADORecordSet_pdo extends ADORecordSet { 788 789 var $bind = false; 790 var $databaseType = "pdo"; 791 var $dataProvider = "pdo"; 792 793 /** @var PDOStatement */ 794 var $_queryID; 795 796 function __construct($id,$mode=false) 797 { 798 if ($mode === false) { 799 global $ADODB_FETCH_MODE; 800 $mode = $ADODB_FETCH_MODE; 801 } 802 $this->adodbFetchMode = $mode; 803 switch($mode) { 804 case ADODB_FETCH_NUM: $mode = PDO::FETCH_NUM; break; 805 case ADODB_FETCH_ASSOC: $mode = PDO::FETCH_ASSOC; break; 806 807 case ADODB_FETCH_BOTH: 808 default: $mode = PDO::FETCH_BOTH; break; 809 } 810 $this->fetchMode = $mode; 811 812 $this->_queryID = $id; 813 parent::__construct($id); 814 } 815 816 817 function Init() 818 { 819 if ($this->_inited) { 820 return; 821 } 822 $this->_inited = true; 823 if ($this->_queryID) { 824 @$this->_initrs(); 825 } 826 else { 827 $this->_numOfRows = 0; 828 $this->_numOfFields = 0; 829 } 830 if ($this->_numOfRows != 0 && $this->_currentRow == -1) { 831 $this->_currentRow = 0; 832 if ($this->EOF = ($this->_fetch() === false)) { 833 $this->_numOfRows = 0; // _numOfRows could be -1 834 } 835 } else { 836 $this->EOF = true; 837 } 838 } 839 840 function _initrs() 841 { 842 global $ADODB_COUNTRECS; 843 844 $this->_numOfRows = ($ADODB_COUNTRECS) ? @$this->_queryID->rowCount() : -1; 845 if (!$this->_numOfRows) { 846 $this->_numOfRows = -1; 847 } 848 $this->_numOfFields = $this->_queryID->columnCount(); 849 } 850 851 // returns the field object 852 function FetchField($fieldOffset = -1) 853 { 854 $off=$fieldOffset+1; // offsets begin at 1 855 856 $o= new ADOFieldObject(); 857 $arr = @$this->_queryID->getColumnMeta($fieldOffset); 858 if (!$arr) { 859 $o->name = 'bad getColumnMeta()'; 860 $o->max_length = -1; 861 $o->type = 'VARCHAR'; 862 $o->precision = 0; 863 # $false = false; 864 return $o; 865 } 866 //adodb_pr($arr); 867 $o->name = $arr['name']; 868 if (isset($arr['sqlsrv:decl_type']) && $arr['sqlsrv:decl_type'] <> "null") 869 { 870 /* 871 * If the database is SQL server, use the native built-ins 872 */ 873 $o->type = $arr['sqlsrv:decl_type']; 874 } 875 elseif (isset($arr['native_type']) && $arr['native_type'] <> "null") 876 { 877 $o->type = $arr['native_type']; 878 } 879 else 880 { 881 $o->type = adodb_pdo_type($arr['pdo_type']); 882 } 883 884 $o->max_length = $arr['len']; 885 $o->precision = $arr['precision']; 886 887 switch(ADODB_ASSOC_CASE) { 888 case ADODB_ASSOC_CASE_LOWER: 889 $o->name = strtolower($o->name); 890 break; 891 case ADODB_ASSOC_CASE_UPPER: 892 $o->name = strtoupper($o->name); 893 break; 894 } 895 return $o; 896 } 897 898 function _seek($row) 899 { 900 return false; 901 } 902 903 function _fetch() 904 { 905 if (!$this->_queryID) { 906 return false; 907 } 908 909 $this->fields = $this->_queryID->fetch($this->fetchMode); 910 return !empty($this->fields); 911 } 912 913 function _close() 914 { 915 $this->_queryID = false; 916 } 917 918 function Fields($colname) 919 { 920 if ($this->adodbFetchMode != ADODB_FETCH_NUM) { 921 return @$this->fields[$colname]; 922 } 923 924 if (!$this->bind) { 925 $this->bind = array(); 926 for ($i=0; $i < $this->_numOfFields; $i++) { 927 $o = $this->FetchField($i); 928 $this->bind[strtoupper($o->name)] = $i; 929 } 930 } 931 return $this->fields[$this->bind[strtoupper($colname)]]; 932 } 933 934 } 935 936 class ADORecordSet_array_pdo extends ADORecordSet_array { 937 /** @var PDOStatement */ 938 var $_queryID; 939 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body