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