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