Documentation TYPO3 par Ameos |
00001 <?php 00002 /* 00003 V4.80 8 Mar 2006 (c) 2000-2006 John Lim (jlim@natsoft.com.my). All rights reserved. 00004 Released under both BSD license and Lesser GPL library license. 00005 Whenever there is any discrepancy between the two licenses, 00006 the BSD license will take precedence. 00007 Set tabs to 4 for best viewing. 00008 00009 Latest version is available at http://adodb.sourceforge.net 00010 00011 Microsoft ADO data driver. Requires ADO. Works only on MS Windows. PHP5 compat version. 00012 */ 00013 00014 // security - hide paths 00015 if (!defined('ADODB_DIR')) die(); 00016 00017 define("_ADODB_ADO_LAYER", 1 ); 00018 /*-------------------------------------------------------------------------------------- 00019 --------------------------------------------------------------------------------------*/ 00020 00021 00022 class ADODB_ado extends ADOConnection { 00023 var $databaseType = "ado"; 00024 var $_bindInputArray = false; 00025 var $fmtDate = "'Y-m-d'"; 00026 var $fmtTimeStamp = "'Y-m-d, h:i:sA'"; 00027 var $replaceQuote = "''"; // string to use to replace quotes 00028 var $dataProvider = "ado"; 00029 var $hasAffectedRows = true; 00030 var $adoParameterType = 201; // 201 = long varchar, 203=long wide varchar, 205 = long varbinary 00031 var $_affectedRows = false; 00032 var $_thisTransactions; 00033 var $_cursor_type = 3; // 3=adOpenStatic,0=adOpenForwardOnly,1=adOpenKeyset,2=adOpenDynamic 00034 var $_cursor_location = 3; // 2=adUseServer, 3 = adUseClient; 00035 var $_lock_type = -1; 00036 var $_execute_option = -1; 00037 var $poorAffectedRows = true; 00038 var $charPage; 00039 00040 function ADODB_ado() 00041 { 00042 $this->_affectedRows = new VARIANT; 00043 } 00044 00045 function ServerInfo() 00046 { 00047 if (!empty($this->_connectionID)) $desc = $this->_connectionID->provider; 00048 return array('description' => $desc, 'version' => ''); 00049 } 00050 00051 function _affectedrows() 00052 { 00053 if (PHP_VERSION >= 5) return $this->_affectedRows; 00054 00055 return $this->_affectedRows->value; 00056 } 00057 00058 // you can also pass a connection string like this: 00059 // 00060 // $DB->Connect('USER ID=sa;PASSWORD=pwd;SERVER=mangrove;DATABASE=ai',false,false,'SQLOLEDB'); 00061 function _connect($argHostname, $argUsername, $argPassword, $argProvider= 'MSDASQL') 00062 { 00063 try { 00064 $u = 'UID'; 00065 $p = 'PWD'; 00066 00067 if (!empty($this->charPage)) 00068 $dbc = new COM('ADODB.Connection',null,$this->charPage); 00069 else 00070 $dbc = new COM('ADODB.Connection'); 00071 00072 if (! $dbc) return false; 00073 00074 /* special support if provider is mssql or access */ 00075 if ($argProvider=='mssql') { 00076 $u = 'User Id'; //User parameter name for OLEDB 00077 $p = 'Password'; 00078 $argProvider = "SQLOLEDB"; // SQL Server Provider 00079 00080 // not yet 00081 //if ($argDatabasename) $argHostname .= ";Initial Catalog=$argDatabasename"; 00082 00083 //use trusted conection for SQL if username not specified 00084 if (!$argUsername) $argHostname .= ";Trusted_Connection=Yes"; 00085 } else if ($argProvider=='access') 00086 $argProvider = "Microsoft.Jet.OLEDB.4.0"; // Microsoft Jet Provider 00087 00088 if ($argProvider) $dbc->Provider = $argProvider; 00089 00090 if ($argUsername) $argHostname .= ";$u=$argUsername"; 00091 if ($argPassword)$argHostname .= ";$p=$argPassword"; 00092 00093 if ($this->debug) ADOConnection::outp( "Host=".$argHostname."<BR>\n version=$dbc->version"); 00094 // @ added below for php 4.0.1 and earlier 00095 @$dbc->Open((string) $argHostname); 00096 00097 $this->_connectionID = $dbc; 00098 00099 $dbc->CursorLocation = $this->_cursor_location; 00100 return $dbc->State > 0; 00101 } catch (exception $e) { 00102 } 00103 00104 return false; 00105 } 00106 00107 // returns true or false 00108 function _pconnect($argHostname, $argUsername, $argPassword, $argProvider='MSDASQL') 00109 { 00110 return $this->_connect($argHostname,$argUsername,$argPassword,$argProvider); 00111 } 00112 00113 /* 00114 adSchemaCatalogs = 1, 00115 adSchemaCharacterSets = 2, 00116 adSchemaCollations = 3, 00117 adSchemaColumns = 4, 00118 adSchemaCheckConstraints = 5, 00119 adSchemaConstraintColumnUsage = 6, 00120 adSchemaConstraintTableUsage = 7, 00121 adSchemaKeyColumnUsage = 8, 00122 adSchemaReferentialContraints = 9, 00123 adSchemaTableConstraints = 10, 00124 adSchemaColumnsDomainUsage = 11, 00125 adSchemaIndexes = 12, 00126 adSchemaColumnPrivileges = 13, 00127 adSchemaTablePrivileges = 14, 00128 adSchemaUsagePrivileges = 15, 00129 adSchemaProcedures = 16, 00130 adSchemaSchemata = 17, 00131 adSchemaSQLLanguages = 18, 00132 adSchemaStatistics = 19, 00133 adSchemaTables = 20, 00134 adSchemaTranslations = 21, 00135 adSchemaProviderTypes = 22, 00136 adSchemaViews = 23, 00137 adSchemaViewColumnUsage = 24, 00138 adSchemaViewTableUsage = 25, 00139 adSchemaProcedureParameters = 26, 00140 adSchemaForeignKeys = 27, 00141 adSchemaPrimaryKeys = 28, 00142 adSchemaProcedureColumns = 29, 00143 adSchemaDBInfoKeywords = 30, 00144 adSchemaDBInfoLiterals = 31, 00145 adSchemaCubes = 32, 00146 adSchemaDimensions = 33, 00147 adSchemaHierarchies = 34, 00148 adSchemaLevels = 35, 00149 adSchemaMeasures = 36, 00150 adSchemaProperties = 37, 00151 adSchemaMembers = 38 00152 00153 */ 00154 00155 function &MetaTables() 00156 { 00157 $arr= array(); 00158 $dbc = $this->_connectionID; 00159 00160 $adors=@$dbc->OpenSchema(20);//tables 00161 if ($adors){ 00162 $f = $adors->Fields(2);//table/view name 00163 $t = $adors->Fields(3);//table type 00164 while (!$adors->EOF){ 00165 $tt=substr($t->value,0,6); 00166 if ($tt!='SYSTEM' && $tt !='ACCESS') 00167 $arr[]=$f->value; 00168 //print $f->value . ' ' . $t->value.'<br>'; 00169 $adors->MoveNext(); 00170 } 00171 $adors->Close(); 00172 } 00173 00174 return $arr; 00175 } 00176 00177 function &MetaColumns($table) 00178 { 00179 $table = strtoupper($table); 00180 $arr= array(); 00181 $dbc = $this->_connectionID; 00182 00183 $adors=@$dbc->OpenSchema(4);//tables 00184 00185 if ($adors){ 00186 $t = $adors->Fields(2);//table/view name 00187 while (!$adors->EOF){ 00188 00189 00190 if (strtoupper($t->Value) == $table) { 00191 00192 $fld = new ADOFieldObject(); 00193 $c = $adors->Fields(3); 00194 $fld->name = $c->Value; 00195 $fld->type = 'CHAR'; // cannot discover type in ADO! 00196 $fld->max_length = -1; 00197 $arr[strtoupper($fld->name)]=$fld; 00198 } 00199 00200 $adors->MoveNext(); 00201 } 00202 $adors->Close(); 00203 } 00204 00205 return $arr; 00206 } 00207 00208 00209 00210 00211 /* returns queryID or false */ 00212 function &_query($sql,$inputarr=false) 00213 { 00214 try { // In PHP5, all COM errors are exceptions, so to maintain old behaviour... 00215 00216 $dbc = $this->_connectionID; 00217 00218 // return rs 00219 if ($inputarr) { 00220 00221 if (!empty($this->charPage)) 00222 $oCmd = new COM('ADODB.Command',null,$this->charPage); 00223 else 00224 $oCmd = new COM('ADODB.Command'); 00225 $oCmd->ActiveConnection = $dbc; 00226 $oCmd->CommandText = $sql; 00227 $oCmd->CommandType = 1; 00228 00229 foreach($inputarr as $val) { 00230 // name, type, direction 1 = input, len, 00231 $this->adoParameterType = 130; 00232 $p = $oCmd->CreateParameter('name',$this->adoParameterType,1,strlen($val),$val); 00233 //print $p->Type.' '.$p->value; 00234 $oCmd->Parameters->Append($p); 00235 } 00236 $p = false; 00237 $rs = $oCmd->Execute(); 00238 $e = $dbc->Errors; 00239 if ($dbc->Errors->Count > 0) return false; 00240 return $rs; 00241 } 00242 00243 $rs = @$dbc->Execute($sql,$this->_affectedRows, $this->_execute_option); 00244 00245 if ($dbc->Errors->Count > 0) return false; 00246 if (! $rs) return false; 00247 00248 if ($rs->State == 0) return true; // 0 = adStateClosed means no records returned 00249 return $rs; 00250 00251 } catch (exception $e) { 00252 00253 } 00254 return false; 00255 } 00256 00257 00258 function BeginTrans() 00259 { 00260 if ($this->transOff) return true; 00261 00262 if (isset($this->_thisTransactions)) 00263 if (!$this->_thisTransactions) return false; 00264 else { 00265 $o = $this->_connectionID->Properties("Transaction DDL"); 00266 $this->_thisTransactions = $o ? true : false; 00267 if (!$o) return false; 00268 } 00269 @$this->_connectionID->BeginTrans(); 00270 $this->transCnt += 1; 00271 return true; 00272 } 00273 function CommitTrans($ok=true) 00274 { 00275 if (!$ok) return $this->RollbackTrans(); 00276 if ($this->transOff) return true; 00277 00278 @$this->_connectionID->CommitTrans(); 00279 if ($this->transCnt) @$this->transCnt -= 1; 00280 return true; 00281 } 00282 function RollbackTrans() { 00283 if ($this->transOff) return true; 00284 @$this->_connectionID->RollbackTrans(); 00285 if ($this->transCnt) @$this->transCnt -= 1; 00286 return true; 00287 } 00288 00289 /* Returns: the last error message from previous database operation */ 00290 00291 function ErrorMsg() 00292 { 00293 $errc = $this->_connectionID->Errors; 00294 if ($errc->Count == 0) return ''; 00295 $err = $errc->Item($errc->Count-1); 00296 return $err->Description; 00297 } 00298 00299 function ErrorNo() 00300 { 00301 $errc = $this->_connectionID->Errors; 00302 if ($errc->Count == 0) return 0; 00303 $err = $errc->Item($errc->Count-1); 00304 return $err->NativeError; 00305 } 00306 00307 // returns true or false 00308 function _close() 00309 { 00310 if ($this->_connectionID) $this->_connectionID->Close(); 00311 $this->_connectionID = false; 00312 return true; 00313 } 00314 00315 00316 } 00317 00318 /*-------------------------------------------------------------------------------------- 00319 Class Name: Recordset 00320 --------------------------------------------------------------------------------------*/ 00321 00322 class ADORecordSet_ado extends ADORecordSet { 00323 00324 var $bind = false; 00325 var $databaseType = "ado"; 00326 var $dataProvider = "ado"; 00327 var $_tarr = false; // caches the types 00328 var $_flds; // and field objects 00329 var $canSeek = true; 00330 var $hideErrors = true; 00331 00332 function ADORecordSet_ado($id,$mode=false) 00333 { 00334 if ($mode === false) { 00335 global $ADODB_FETCH_MODE; 00336 $mode = $ADODB_FETCH_MODE; 00337 } 00338 $this->fetchMode = $mode; 00339 return $this->ADORecordSet($id,$mode); 00340 } 00341 00342 00343 // returns the field object 00344 function &FetchField($fieldOffset = -1) { 00345 $off=$fieldOffset+1; // offsets begin at 1 00346 00347 $o= new ADOFieldObject(); 00348 $rs = $this->_queryID; 00349 $f = $rs->Fields($fieldOffset); 00350 $o->name = $f->Name; 00351 $t = $f->Type; 00352 $o->type = $this->MetaType($t); 00353 $o->max_length = $f->DefinedSize; 00354 $o->ado_type = $t; 00355 00356 00357 //print "off=$off name=$o->name type=$o->type len=$o->max_length<br>"; 00358 return $o; 00359 } 00360 00361 /* Use associative array to get fields array */ 00362 function Fields($colname) 00363 { 00364 if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname]; 00365 if (!$this->bind) { 00366 $this->bind = array(); 00367 for ($i=0; $i < $this->_numOfFields; $i++) { 00368 $o = $this->FetchField($i); 00369 $this->bind[strtoupper($o->name)] = $i; 00370 } 00371 } 00372 00373 return $this->fields[$this->bind[strtoupper($colname)]]; 00374 } 00375 00376 00377 function _initrs() 00378 { 00379 $rs = $this->_queryID; 00380 $this->_numOfRows = $rs->RecordCount; 00381 00382 $f = $rs->Fields; 00383 $this->_numOfFields = $f->Count; 00384 } 00385 00386 00387 // should only be used to move forward as we normally use forward-only cursors 00388 function _seek($row) 00389 { 00390 $rs = $this->_queryID; 00391 // absoluteposition doesn't work -- my maths is wrong ? 00392 // $rs->AbsolutePosition->$row-2; 00393 // return true; 00394 if ($this->_currentRow > $row) return false; 00395 @$rs->Move((integer)$row - $this->_currentRow-1); //adBookmarkFirst 00396 return true; 00397 } 00398 00399 /* 00400 OLEDB types 00401 00402 enum DBTYPEENUM 00403 { DBTYPE_EMPTY = 0, 00404 DBTYPE_NULL = 1, 00405 DBTYPE_I2 = 2, 00406 DBTYPE_I4 = 3, 00407 DBTYPE_R4 = 4, 00408 DBTYPE_R8 = 5, 00409 DBTYPE_CY = 6, 00410 DBTYPE_DATE = 7, 00411 DBTYPE_BSTR = 8, 00412 DBTYPE_IDISPATCH = 9, 00413 DBTYPE_ERROR = 10, 00414 DBTYPE_BOOL = 11, 00415 DBTYPE_VARIANT = 12, 00416 DBTYPE_IUNKNOWN = 13, 00417 DBTYPE_DECIMAL = 14, 00418 DBTYPE_UI1 = 17, 00419 DBTYPE_ARRAY = 0x2000, 00420 DBTYPE_BYREF = 0x4000, 00421 DBTYPE_I1 = 16, 00422 DBTYPE_UI2 = 18, 00423 DBTYPE_UI4 = 19, 00424 DBTYPE_I8 = 20, 00425 DBTYPE_UI8 = 21, 00426 DBTYPE_GUID = 72, 00427 DBTYPE_VECTOR = 0x1000, 00428 DBTYPE_RESERVED = 0x8000, 00429 DBTYPE_BYTES = 128, 00430 DBTYPE_STR = 129, 00431 DBTYPE_WSTR = 130, 00432 DBTYPE_NUMERIC = 131, 00433 DBTYPE_UDT = 132, 00434 DBTYPE_DBDATE = 133, 00435 DBTYPE_DBTIME = 134, 00436 DBTYPE_DBTIMESTAMP = 135 00437 00438 ADO Types 00439 00440 adEmpty = 0, 00441 adTinyInt = 16, 00442 adSmallInt = 2, 00443 adInteger = 3, 00444 adBigInt = 20, 00445 adUnsignedTinyInt = 17, 00446 adUnsignedSmallInt = 18, 00447 adUnsignedInt = 19, 00448 adUnsignedBigInt = 21, 00449 adSingle = 4, 00450 adDouble = 5, 00451 adCurrency = 6, 00452 adDecimal = 14, 00453 adNumeric = 131, 00454 adBoolean = 11, 00455 adError = 10, 00456 adUserDefined = 132, 00457 adVariant = 12, 00458 adIDispatch = 9, 00459 adIUnknown = 13, 00460 adGUID = 72, 00461 adDate = 7, 00462 adDBDate = 133, 00463 adDBTime = 134, 00464 adDBTimeStamp = 135, 00465 adBSTR = 8, 00466 adChar = 129, 00467 adVarChar = 200, 00468 adLongVarChar = 201, 00469 adWChar = 130, 00470 adVarWChar = 202, 00471 adLongVarWChar = 203, 00472 adBinary = 128, 00473 adVarBinary = 204, 00474 adLongVarBinary = 205, 00475 adChapter = 136, 00476 adFileTime = 64, 00477 adDBFileTime = 137, 00478 adPropVariant = 138, 00479 adVarNumeric = 139 00480 */ 00481 function MetaType($t,$len=-1,$fieldobj=false) 00482 { 00483 if (is_object($t)) { 00484 $fieldobj = $t; 00485 $t = $fieldobj->type; 00486 $len = $fieldobj->max_length; 00487 } 00488 00489 if (!is_numeric($t)) return $t; 00490 00491 switch ($t) { 00492 case 0: 00493 case 12: // variant 00494 case 8: // bstr 00495 case 129: //char 00496 case 130: //wc 00497 case 200: // varc 00498 case 202:// varWC 00499 case 128: // bin 00500 case 204: // varBin 00501 case 72: // guid 00502 if ($len <= $this->blobSize) return 'C'; 00503 00504 case 201: 00505 case 203: 00506 return 'X'; 00507 case 128: 00508 case 204: 00509 case 205: 00510 return 'B'; 00511 case 7: 00512 case 133: return 'D'; 00513 00514 case 134: 00515 case 135: return 'T'; 00516 00517 case 11: return 'L'; 00518 00519 case 16:// adTinyInt = 16, 00520 case 2://adSmallInt = 2, 00521 case 3://adInteger = 3, 00522 case 4://adBigInt = 20, 00523 case 17://adUnsignedTinyInt = 17, 00524 case 18://adUnsignedSmallInt = 18, 00525 case 19://adUnsignedInt = 19, 00526 case 20://adUnsignedBigInt = 21, 00527 return 'I'; 00528 default: return 'N'; 00529 } 00530 } 00531 00532 // time stamp not supported yet 00533 function _fetch() 00534 { 00535 $rs = $this->_queryID; 00536 if (!$rs or $rs->EOF) { 00537 $this->fields = false; 00538 return false; 00539 } 00540 $this->fields = array(); 00541 00542 if (!$this->_tarr) { 00543 $tarr = array(); 00544 $flds = array(); 00545 for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) { 00546 $f = $rs->Fields($i); 00547 $flds[] = $f; 00548 $tarr[] = $f->Type; 00549 } 00550 // bind types and flds only once 00551 $this->_tarr = $tarr; 00552 $this->_flds = $flds; 00553 } 00554 $t = reset($this->_tarr); 00555 $f = reset($this->_flds); 00556 00557 if ($this->hideErrors) $olde = error_reporting(E_ERROR|E_CORE_ERROR);// sometimes $f->value be null 00558 for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) { 00559 //echo "<p>",$t,' ';var_dump($f->value); echo '</p>'; 00560 switch($t) { 00561 case 135: // timestamp 00562 if (!strlen((string)$f->value)) $this->fields[] = false; 00563 else { 00564 if (!is_numeric($f->value)) # $val = variant_date_to_timestamp($f->value); 00565 // VT_DATE stores dates as (float) fractional days since 1899/12/30 00:00:00 00566 $val= (float) variant_cast($f->value,VT_R8)*3600*24-2209161600; 00567 else 00568 $val = $f->value; 00569 $this->fields[] = adodb_date('Y-m-d H:i:s',$val); 00570 } 00571 break; 00572 case 133:// A date value (yyyymmdd) 00573 if ($val = $f->value) { 00574 $this->fields[] = substr($val,0,4).'-'.substr($val,4,2).'-'.substr($val,6,2); 00575 } else 00576 $this->fields[] = false; 00577 break; 00578 case 7: // adDate 00579 if (!strlen((string)$f->value)) $this->fields[] = false; 00580 else { 00581 if (!is_numeric($f->value)) $val = variant_date_to_timestamp($f->value); 00582 else $val = $f->value; 00583 00584 if (($val % 86400) == 0) $this->fields[] = adodb_date('Y-m-d',$val); 00585 else $this->fields[] = adodb_date('Y-m-d H:i:s',$val); 00586 } 00587 break; 00588 case 1: // null 00589 $this->fields[] = false; 00590 break; 00591 case 6: // currency is not supported properly; 00592 ADOConnection::outp( '<b>'.$f->Name.': currency type not supported by PHP</b>'); 00593 $this->fields[] = (float) $f->value; 00594 break; 00595 default: 00596 $this->fields[] = $f->value; 00597 break; 00598 } 00599 //print " $f->value $t, "; 00600 $f = next($this->_flds); 00601 $t = next($this->_tarr); 00602 } // for 00603 if ($this->hideErrors) error_reporting($olde); 00604 @$rs->MoveNext(); // @ needed for some versions of PHP! 00605 00606 if ($this->fetchMode & ADODB_FETCH_ASSOC) { 00607 $this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE); 00608 } 00609 return true; 00610 } 00611 00612 function NextRecordSet() 00613 { 00614 $rs = $this->_queryID; 00615 $this->_queryID = $rs->NextRecordSet(); 00616 //$this->_queryID = $this->_QueryId->NextRecordSet(); 00617 if ($this->_queryID == null) return false; 00618 00619 $this->_currentRow = -1; 00620 $this->_currentPage = -1; 00621 $this->bind = false; 00622 $this->fields = false; 00623 $this->_flds = false; 00624 $this->_tarr = false; 00625 00626 $this->_inited = false; 00627 $this->Init(); 00628 return true; 00629 } 00630 00631 function _close() { 00632 $this->_flds = false; 00633 @$this->_queryID->Close();// by Pete Dishman (peterd@telephonetics.co.uk) 00634 $this->_queryID = false; 00635 } 00636 00637 } 00638 00639 ?>