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