Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
1 <?php 2 /* 3 @version v5.21.0 2021-02-27 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 Released under both BSD license and Lesser GPL library license. 7 Whenever there is any discrepancy between the two licenses, 8 the BSD license will take precedence. 9 Set tabs to 4 for best viewing. 10 11 Latest version is available at https://adodb.org/ 12 13 Microsoft ADO data driver. Requires ADO. Works only on MS Windows. PHP5 compat version. 14 */ 15 16 // security - hide paths 17 if (!defined('ADODB_DIR')) die(); 18 19 define("_ADODB_ADO_LAYER", 1 ); 20 /*-------------------------------------------------------------------------------------- 21 --------------------------------------------------------------------------------------*/ 22 23 24 class ADODB_ado extends ADOConnection { 25 var $databaseType = "ado"; 26 var $_bindInputArray = false; 27 var $fmtDate = "'Y-m-d'"; 28 var $fmtTimeStamp = "'Y-m-d, h:i:sA'"; 29 var $replaceQuote = "''"; // string to use to replace quotes 30 var $dataProvider = "ado"; 31 var $hasAffectedRows = true; 32 var $adoParameterType = 201; // 201 = long varchar, 203=long wide varchar, 205 = long varbinary 33 var $_affectedRows = false; 34 var $_thisTransactions; 35 var $_cursor_type = 3; // 3=adOpenStatic,0=adOpenForwardOnly,1=adOpenKeyset,2=adOpenDynamic 36 var $_cursor_location = 3; // 2=adUseServer, 3 = adUseClient; 37 var $_lock_type = -1; 38 var $_execute_option = -1; 39 var $poorAffectedRows = true; 40 var $charPage; 41 42 function __construct() 43 { 44 $this->_affectedRows = new VARIANT; 45 } 46 47 function ServerInfo() 48 { 49 if (!empty($this->_connectionID)) $desc = $this->_connectionID->provider; 50 return array('description' => $desc, 'version' => ''); 51 } 52 53 function _affectedrows() 54 { 55 return $this->_affectedRows; 56 } 57 58 // you can also pass a connection string like this: 59 // 60 // $DB->Connect('USER ID=sa;PASSWORD=pwd;SERVER=mangrove;DATABASE=ai',false,false,'SQLOLEDB'); 61 function _connect($argHostname, $argUsername, $argPassword,$argDBorProvider, $argProvider= '') 62 { 63 // two modes 64 // - if $argProvider is empty, we assume that $argDBorProvider holds provider -- this is for backward compat 65 // - if $argProvider is not empty, then $argDBorProvider holds db 66 67 68 if ($argProvider) { 69 $argDatabasename = $argDBorProvider; 70 } else { 71 $argDatabasename = ''; 72 if ($argDBorProvider) $argProvider = $argDBorProvider; 73 else if (stripos($argHostname,'PROVIDER') === false) /* full conn string is not in $argHostname */ 74 $argProvider = 'MSDASQL'; 75 } 76 77 78 try { 79 $u = 'UID'; 80 $p = 'PWD'; 81 82 if (!empty($this->charPage)) 83 $dbc = new COM('ADODB.Connection',null,$this->charPage); 84 else 85 $dbc = new COM('ADODB.Connection'); 86 87 if (! $dbc) return false; 88 89 /* special support if provider is mssql or access */ 90 if ($argProvider=='mssql') { 91 $u = 'User Id'; //User parameter name for OLEDB 92 $p = 'Password'; 93 $argProvider = "SQLOLEDB"; // SQL Server Provider 94 95 // not yet 96 //if ($argDatabasename) $argHostname .= ";Initial Catalog=$argDatabasename"; 97 98 //use trusted connection for SQL if username not specified 99 if (!$argUsername) $argHostname .= ";Trusted_Connection=Yes"; 100 } else if ($argProvider=='access') 101 $argProvider = "Microsoft.Jet.OLEDB.4.0"; // Microsoft Jet Provider 102 103 if ($argProvider) $dbc->Provider = $argProvider; 104 105 if ($argProvider) $argHostname = "PROVIDER=$argProvider;DRIVER={SQL Server};SERVER=$argHostname"; 106 107 108 if ($argDatabasename) $argHostname .= ";DATABASE=$argDatabasename"; 109 if ($argUsername) $argHostname .= ";$u=$argUsername"; 110 if ($argPassword)$argHostname .= ";$p=$argPassword"; 111 112 if ($this->debug) ADOConnection::outp( "Host=".$argHostname."<BR>\n version=$dbc->version"); 113 // @ added below for php 4.0.1 and earlier 114 @$dbc->Open((string) $argHostname); 115 116 $this->_connectionID = $dbc; 117 118 $dbc->CursorLocation = $this->_cursor_location; 119 return $dbc->State > 0; 120 } catch (exception $e) { 121 if ($this->debug) echo "<pre>",$argHostname,"\n",$e,"</pre>\n"; 122 } 123 124 return false; 125 } 126 127 // returns true or false 128 function _pconnect($argHostname, $argUsername, $argPassword, $argProvider='MSDASQL') 129 { 130 return $this->_connect($argHostname,$argUsername,$argPassword,$argProvider); 131 } 132 133 /* 134 adSchemaCatalogs = 1, 135 adSchemaCharacterSets = 2, 136 adSchemaCollations = 3, 137 adSchemaColumns = 4, 138 adSchemaCheckConstraints = 5, 139 adSchemaConstraintColumnUsage = 6, 140 adSchemaConstraintTableUsage = 7, 141 adSchemaKeyColumnUsage = 8, 142 adSchemaReferentialContraints = 9, 143 adSchemaTableConstraints = 10, 144 adSchemaColumnsDomainUsage = 11, 145 adSchemaIndexes = 12, 146 adSchemaColumnPrivileges = 13, 147 adSchemaTablePrivileges = 14, 148 adSchemaUsagePrivileges = 15, 149 adSchemaProcedures = 16, 150 adSchemaSchemata = 17, 151 adSchemaSQLLanguages = 18, 152 adSchemaStatistics = 19, 153 adSchemaTables = 20, 154 adSchemaTranslations = 21, 155 adSchemaProviderTypes = 22, 156 adSchemaViews = 23, 157 adSchemaViewColumnUsage = 24, 158 adSchemaViewTableUsage = 25, 159 adSchemaProcedureParameters = 26, 160 adSchemaForeignKeys = 27, 161 adSchemaPrimaryKeys = 28, 162 adSchemaProcedureColumns = 29, 163 adSchemaDBInfoKeywords = 30, 164 adSchemaDBInfoLiterals = 31, 165 adSchemaCubes = 32, 166 adSchemaDimensions = 33, 167 adSchemaHierarchies = 34, 168 adSchemaLevels = 35, 169 adSchemaMeasures = 36, 170 adSchemaProperties = 37, 171 adSchemaMembers = 38 172 173 */ 174 175 function MetaTables($ttype = false, $showSchema = false, $mask = false) 176 { 177 $arr= array(); 178 $dbc = $this->_connectionID; 179 180 $adors=@$dbc->OpenSchema(20);//tables 181 if ($adors){ 182 $f = $adors->Fields(2);//table/view name 183 $t = $adors->Fields(3);//table type 184 while (!$adors->EOF){ 185 $tt=substr($t->value,0,6); 186 if ($tt!='SYSTEM' && $tt !='ACCESS') 187 $arr[]=$f->value; 188 //print $f->value . ' ' . $t->value.'<br>'; 189 $adors->MoveNext(); 190 } 191 $adors->Close(); 192 } 193 194 return $arr; 195 } 196 197 function MetaColumns($table, $normalize=true) 198 { 199 $table = strtoupper($table); 200 $arr= array(); 201 $dbc = $this->_connectionID; 202 203 $adors=@$dbc->OpenSchema(4);//tables 204 205 if ($adors){ 206 $t = $adors->Fields(2);//table/view name 207 while (!$adors->EOF){ 208 209 210 if (strtoupper($t->Value) == $table) { 211 212 $fld = new ADOFieldObject(); 213 $c = $adors->Fields(3); 214 $fld->name = $c->Value; 215 $fld->type = 'CHAR'; // cannot discover type in ADO! 216 $fld->max_length = -1; 217 $arr[strtoupper($fld->name)]=$fld; 218 } 219 220 $adors->MoveNext(); 221 } 222 $adors->Close(); 223 } 224 225 return $arr; 226 } 227 228 /* returns queryID or false */ 229 function _query($sql,$inputarr=false) 230 { 231 try { // In PHP5, all COM errors are exceptions, so to maintain old behaviour... 232 233 $dbc = $this->_connectionID; 234 235 // return rs 236 237 $false = false; 238 239 if ($inputarr) { 240 241 if (!empty($this->charPage)) 242 $oCmd = new COM('ADODB.Command',null,$this->charPage); 243 else 244 $oCmd = new COM('ADODB.Command'); 245 $oCmd->ActiveConnection = $dbc; 246 $oCmd->CommandText = $sql; 247 $oCmd->CommandType = 1; 248 249 foreach ($inputarr as $val) { 250 $type = gettype($val); 251 $len=strlen($val); 252 if ($type == 'boolean') 253 $this->adoParameterType = 11; 254 else if ($type == 'integer') 255 $this->adoParameterType = 3; 256 else if ($type == 'double') 257 $this->adoParameterType = 5; 258 elseif ($type == 'string') 259 $this->adoParameterType = 202; 260 else if (($val === null) || (!defined($val))) 261 $len=1; 262 else 263 $this->adoParameterType = 130; 264 265 // name, type, direction 1 = input, len, 266 $p = $oCmd->CreateParameter('name',$this->adoParameterType,1,$len,$val); 267 268 $oCmd->Parameters->Append($p); 269 } 270 271 $p = false; 272 $rs = $oCmd->Execute(); 273 $e = $dbc->Errors; 274 if ($dbc->Errors->Count > 0) return $false; 275 return $rs; 276 } 277 278 $rs = @$dbc->Execute($sql,$this->_affectedRows, $this->_execute_option); 279 280 if ($dbc->Errors->Count > 0) return $false; 281 if (! $rs) return $false; 282 283 if ($rs->State == 0) { 284 $true = true; 285 return $true; // 0 = adStateClosed means no records returned 286 } 287 return $rs; 288 289 } catch (exception $e) { 290 291 } 292 return $false; 293 } 294 295 296 function BeginTrans() 297 { 298 if ($this->transOff) return true; 299 300 if (isset($this->_thisTransactions)) 301 if (!$this->_thisTransactions) return false; 302 else { 303 $o = $this->_connectionID->Properties("Transaction DDL"); 304 $this->_thisTransactions = $o ? true : false; 305 if (!$o) return false; 306 } 307 @$this->_connectionID->BeginTrans(); 308 $this->transCnt += 1; 309 return true; 310 } 311 function CommitTrans($ok=true) 312 { 313 if (!$ok) return $this->RollbackTrans(); 314 if ($this->transOff) return true; 315 316 @$this->_connectionID->CommitTrans(); 317 if ($this->transCnt) @$this->transCnt -= 1; 318 return true; 319 } 320 function RollbackTrans() { 321 if ($this->transOff) return true; 322 @$this->_connectionID->RollbackTrans(); 323 if ($this->transCnt) @$this->transCnt -= 1; 324 return true; 325 } 326 327 /* Returns: the last error message from previous database operation */ 328 329 function ErrorMsg() 330 { 331 if (!$this->_connectionID) return "No connection established"; 332 $errmsg = ''; 333 334 try { 335 $errc = $this->_connectionID->Errors; 336 if (!$errc) return "No Errors object found"; 337 if ($errc->Count == 0) return ''; 338 $err = $errc->Item($errc->Count-1); 339 $errmsg = $err->Description; 340 }catch(exception $e) { 341 } 342 return $errmsg; 343 } 344 345 function ErrorNo() 346 { 347 $errc = $this->_connectionID->Errors; 348 if ($errc->Count == 0) return 0; 349 $err = $errc->Item($errc->Count-1); 350 return $err->NativeError; 351 } 352 353 // returns true or false 354 function _close() 355 { 356 if ($this->_connectionID) $this->_connectionID->Close(); 357 $this->_connectionID = false; 358 return true; 359 } 360 361 362 } 363 364 /*-------------------------------------------------------------------------------------- 365 Class Name: Recordset 366 --------------------------------------------------------------------------------------*/ 367 368 class ADORecordSet_ado extends ADORecordSet { 369 370 var $bind = false; 371 var $databaseType = "ado"; 372 var $dataProvider = "ado"; 373 var $_tarr = false; // caches the types 374 var $_flds; // and field objects 375 var $canSeek = true; 376 var $hideErrors = true; 377 378 function __construct($id,$mode=false) 379 { 380 if ($mode === false) { 381 global $ADODB_FETCH_MODE; 382 $mode = $ADODB_FETCH_MODE; 383 } 384 $this->fetchMode = $mode; 385 parent::__construct($id); 386 } 387 388 389 // returns the field object 390 function FetchField($fieldOffset = -1) { 391 $off=$fieldOffset+1; // offsets begin at 1 392 393 $o= new ADOFieldObject(); 394 $rs = $this->_queryID; 395 if (!$rs) return false; 396 397 $f = $rs->Fields($fieldOffset); 398 $o->name = $f->Name; 399 $t = $f->Type; 400 $o->type = $this->MetaType($t); 401 $o->max_length = $f->DefinedSize; 402 $o->ado_type = $t; 403 404 405 //print "off=$off name=$o->name type=$o->type len=$o->max_length<br>"; 406 return $o; 407 } 408 409 /* Use associative array to get fields array */ 410 function Fields($colname) 411 { 412 if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname]; 413 if (!$this->bind) { 414 $this->bind = array(); 415 for ($i=0; $i < $this->_numOfFields; $i++) { 416 $o = $this->FetchField($i); 417 $this->bind[strtoupper($o->name)] = $i; 418 } 419 } 420 421 return $this->fields[$this->bind[strtoupper($colname)]]; 422 } 423 424 425 function _initrs() 426 { 427 $rs = $this->_queryID; 428 429 try { 430 $this->_numOfRows = $rs->RecordCount; 431 } catch (Exception $e) { 432 $this->_numOfRows = -1; 433 } 434 $f = $rs->Fields; 435 $this->_numOfFields = $f->Count; 436 } 437 438 439 // should only be used to move forward as we normally use forward-only cursors 440 function _seek($row) 441 { 442 $rs = $this->_queryID; 443 // absoluteposition doesn't work -- my maths is wrong ? 444 // $rs->AbsolutePosition->$row-2; 445 // return true; 446 if ($this->_currentRow > $row) return false; 447 @$rs->Move((integer)$row - $this->_currentRow-1); //adBookmarkFirst 448 return true; 449 } 450 451 /* 452 OLEDB types 453 454 enum DBTYPEENUM 455 { DBTYPE_EMPTY = 0, 456 DBTYPE_NULL = 1, 457 DBTYPE_I2 = 2, 458 DBTYPE_I4 = 3, 459 DBTYPE_R4 = 4, 460 DBTYPE_R8 = 5, 461 DBTYPE_CY = 6, 462 DBTYPE_DATE = 7, 463 DBTYPE_BSTR = 8, 464 DBTYPE_IDISPATCH = 9, 465 DBTYPE_ERROR = 10, 466 DBTYPE_BOOL = 11, 467 DBTYPE_VARIANT = 12, 468 DBTYPE_IUNKNOWN = 13, 469 DBTYPE_DECIMAL = 14, 470 DBTYPE_UI1 = 17, 471 DBTYPE_ARRAY = 0x2000, 472 DBTYPE_BYREF = 0x4000, 473 DBTYPE_I1 = 16, 474 DBTYPE_UI2 = 18, 475 DBTYPE_UI4 = 19, 476 DBTYPE_I8 = 20, 477 DBTYPE_UI8 = 21, 478 DBTYPE_GUID = 72, 479 DBTYPE_VECTOR = 0x1000, 480 DBTYPE_RESERVED = 0x8000, 481 DBTYPE_BYTES = 128, 482 DBTYPE_STR = 129, 483 DBTYPE_WSTR = 130, 484 DBTYPE_NUMERIC = 131, 485 DBTYPE_UDT = 132, 486 DBTYPE_DBDATE = 133, 487 DBTYPE_DBTIME = 134, 488 DBTYPE_DBTIMESTAMP = 135 489 490 ADO Types 491 492 adEmpty = 0, 493 adTinyInt = 16, 494 adSmallInt = 2, 495 adInteger = 3, 496 adBigInt = 20, 497 adUnsignedTinyInt = 17, 498 adUnsignedSmallInt = 18, 499 adUnsignedInt = 19, 500 adUnsignedBigInt = 21, 501 adSingle = 4, 502 adDouble = 5, 503 adCurrency = 6, 504 adDecimal = 14, 505 adNumeric = 131, 506 adBoolean = 11, 507 adError = 10, 508 adUserDefined = 132, 509 adVariant = 12, 510 adIDispatch = 9, 511 adIUnknown = 13, 512 adGUID = 72, 513 adDate = 7, 514 adDBDate = 133, 515 adDBTime = 134, 516 adDBTimeStamp = 135, 517 adBSTR = 8, 518 adChar = 129, 519 adVarChar = 200, 520 adLongVarChar = 201, 521 adWChar = 130, 522 adVarWChar = 202, 523 adLongVarWChar = 203, 524 adBinary = 128, 525 adVarBinary = 204, 526 adLongVarBinary = 205, 527 adChapter = 136, 528 adFileTime = 64, 529 adDBFileTime = 137, 530 adPropVariant = 138, 531 adVarNumeric = 139 532 */ 533 function MetaType($t,$len=-1,$fieldobj=false) 534 { 535 if (is_object($t)) { 536 $fieldobj = $t; 537 $t = $fieldobj->type; 538 $len = $fieldobj->max_length; 539 } 540 541 if (!is_numeric($t)) return $t; 542 543 switch ($t) { 544 case 0: 545 case 12: // variant 546 case 8: // bstr 547 case 129: //char 548 case 130: //wc 549 case 200: // varc 550 case 202:// varWC 551 case 128: // bin 552 case 204: // varBin 553 case 72: // guid 554 if ($len <= $this->blobSize) return 'C'; 555 556 case 201: 557 case 203: 558 return 'X'; 559 case 128: 560 case 204: 561 case 205: 562 return 'B'; 563 case 7: 564 case 133: return 'D'; 565 566 case 134: 567 case 135: return 'T'; 568 569 case 11: return 'L'; 570 571 case 16:// adTinyInt = 16, 572 case 2://adSmallInt = 2, 573 case 3://adInteger = 3, 574 case 4://adBigInt = 20, 575 case 17://adUnsignedTinyInt = 17, 576 case 18://adUnsignedSmallInt = 18, 577 case 19://adUnsignedInt = 19, 578 case 20://adUnsignedBigInt = 21, 579 return 'I'; 580 default: return ADODB_DEFAULT_METATYPE; 581 } 582 } 583 584 // time stamp not supported yet 585 function _fetch() 586 { 587 $rs = $this->_queryID; 588 if (!$rs or $rs->EOF) { 589 $this->fields = false; 590 return false; 591 } 592 $this->fields = array(); 593 594 if (!$this->_tarr) { 595 $tarr = array(); 596 $flds = array(); 597 for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) { 598 $f = $rs->Fields($i); 599 $flds[] = $f; 600 $tarr[] = $f->Type; 601 } 602 // bind types and flds only once 603 $this->_tarr = $tarr; 604 $this->_flds = $flds; 605 } 606 $t = reset($this->_tarr); 607 $f = reset($this->_flds); 608 609 if ($this->hideErrors) $olde = error_reporting(E_ERROR|E_CORE_ERROR);// sometimes $f->value be null 610 for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) { 611 //echo "<p>",$t,' ';var_dump($f->value); echo '</p>'; 612 switch($t) { 613 case 135: // timestamp 614 if (!strlen((string)$f->value)) $this->fields[] = false; 615 else { 616 if (!is_numeric($f->value)) # $val = variant_date_to_timestamp($f->value); 617 // VT_DATE stores dates as (float) fractional days since 1899/12/30 00:00:00 618 $val= (float) variant_cast($f->value,VT_R8)*3600*24-2209161600; 619 else 620 $val = $f->value; 621 $this->fields[] = adodb_date('Y-m-d H:i:s',$val); 622 } 623 break; 624 case 133:// A date value (yyyymmdd) 625 if ($val = $f->value) { 626 $this->fields[] = substr($val,0,4).'-'.substr($val,4,2).'-'.substr($val,6,2); 627 } else 628 $this->fields[] = false; 629 break; 630 case 7: // adDate 631 if (!strlen((string)$f->value)) $this->fields[] = false; 632 else { 633 if (!is_numeric($f->value)) $val = variant_date_to_timestamp($f->value); 634 else $val = $f->value; 635 636 if (($val % 86400) == 0) $this->fields[] = adodb_date('Y-m-d',$val); 637 else $this->fields[] = adodb_date('Y-m-d H:i:s',$val); 638 } 639 break; 640 case 1: // null 641 $this->fields[] = false; 642 break; 643 case 20: 644 case 21: // bigint (64 bit) 645 $this->fields[] = (float) $f->value; // if 64 bit PHP, could use (int) 646 break; 647 case 6: // currency is not supported properly; 648 ADOConnection::outp( '<b>'.$f->Name.': currency type not supported by PHP</b>'); 649 $this->fields[] = (float) $f->value; 650 break; 651 case 11: //BIT; 652 $val = ""; 653 if(is_bool($f->value)) { 654 if($f->value==true) $val = 1; 655 else $val = 0; 656 } 657 if(is_null($f->value)) $val = null; 658 659 $this->fields[] = $val; 660 break; 661 default: 662 $this->fields[] = $f->value; 663 break; 664 } 665 //print " $f->value $t, "; 666 $f = next($this->_flds); 667 $t = next($this->_tarr); 668 } // for 669 if ($this->hideErrors) error_reporting($olde); 670 @$rs->MoveNext(); // @ needed for some versions of PHP! 671 672 if ($this->fetchMode & ADODB_FETCH_ASSOC) { 673 $this->fields = $this->GetRowAssoc(); 674 } 675 return true; 676 } 677 678 function NextRecordSet() 679 { 680 $rs = $this->_queryID; 681 $this->_queryID = $rs->NextRecordSet(); 682 //$this->_queryID = $this->_QueryId->NextRecordSet(); 683 if ($this->_queryID == null) return false; 684 685 $this->_currentRow = -1; 686 $this->_currentPage = -1; 687 $this->bind = false; 688 $this->fields = false; 689 $this->_flds = false; 690 $this->_tarr = false; 691 692 $this->_inited = false; 693 $this->Init(); 694 return true; 695 } 696 697 function _close() { 698 $this->_flds = false; 699 try { 700 @$this->_queryID->Close();// by Pete Dishman (peterd@telephonetics.co.uk) 701 } catch (Exception $e) { 702 } 703 $this->_queryID = false; 704 } 705 706 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body