|
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 Requires ODBC. Works on Windows and Unix. 00012 */ 00013 // security - hide paths 00014 if (!defined('ADODB_DIR')) die(); 00015 00016 define("_ADODB_ODBC_LAYER", 2 ); 00017 00018 /*-------------------------------------------------------------------------------------- 00019 --------------------------------------------------------------------------------------*/ 00020 00021 00022 class ADODB_odbc extends ADOConnection { 00023 var $databaseType = "odbc"; 00024 var $fmtDate = "'Y-m-d'"; 00025 var $fmtTimeStamp = "'Y-m-d, h:i:sA'"; 00026 var $replaceQuote = "''"; // string to use to replace quotes 00027 var $dataProvider = "odbc"; 00028 var $hasAffectedRows = true; 00029 var $binmode = ODBC_BINMODE_RETURN; 00030 var $useFetchArray = false; // setting this to true will make array elements in FETCH_ASSOC mode case-sensitive 00031 // breaking backward-compat 00032 //var $longreadlen = 8000; // default number of chars to return for a Blob/Long field 00033 var $_bindInputArray = false; 00034 var $curmode = SQL_CUR_USE_DRIVER; // See sqlext.h, SQL_CUR_DEFAULT == SQL_CUR_USE_DRIVER == 2L 00035 var $_genSeqSQL = "create table %s (id integer)"; 00036 var $_autocommit = true; 00037 var $_haserrorfunctions = true; 00038 var $_has_stupid_odbc_fetch_api_change = true; 00039 var $_lastAffectedRows = 0; 00040 var $uCaseTables = true; // for meta* functions, uppercase table names 00041 00042 function ADODB_odbc() 00043 { 00044 $this->_haserrorfunctions = ADODB_PHPVER >= 0x4050; 00045 $this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200; 00046 } 00047 00048 // returns true or false 00049 function _connect($argDSN, $argUsername, $argPassword, $argDatabasename) 00050 { 00051 global $php_errormsg; 00052 00053 if (!function_exists('odbc_connect')) return null; 00054 00055 if ($this->debug && $argDatabasename && $this->databaseType != 'vfp') { 00056 ADOConnection::outp("For odbc Connect(), $argDatabasename is not used. Place dsn in 1st parameter."); 00057 } 00058 if (isset($php_errormsg)) $php_errormsg = ''; 00059 if ($this->curmode === false) $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword); 00060 else $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword,$this->curmode); 00061 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 00062 if (isset($this->connectStmt)) $this->Execute($this->connectStmt); 00063 00064 return $this->_connectionID != false; 00065 } 00066 00067 // returns true or false 00068 function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename) 00069 { 00070 global $php_errormsg; 00071 00072 if (!function_exists('odbc_connect')) return null; 00073 00074 if (isset($php_errormsg)) $php_errormsg = ''; 00075 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 00076 if ($this->debug && $argDatabasename) { 00077 ADOConnection::outp("For odbc PConnect(), $argDatabasename is not used. Place dsn in 1st parameter."); 00078 } 00079 // print "dsn=$argDSN u=$argUsername p=$argPassword<br>"; flush(); 00080 if ($this->curmode === false) $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword); 00081 else $this->_connectionID = odbc_pconnect($argDSN,$argUsername,$argPassword,$this->curmode); 00082 00083 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 00084 if ($this->_connectionID && $this->autoRollback) @odbc_rollback($this->_connectionID); 00085 if (isset($this->connectStmt)) $this->Execute($this->connectStmt); 00086 00087 return $this->_connectionID != false; 00088 } 00089 00090 00091 function ServerInfo() 00092 { 00093 00094 if (!empty($this->host) && ADODB_PHPVER >= 0x4300) { 00095 $dsn = strtoupper($this->host); 00096 $first = true; 00097 $found = false; 00098 00099 if (!function_exists('odbc_data_source')) return false; 00100 00101 while(true) { 00102 00103 $rez = @odbc_data_source($this->_connectionID, 00104 $first ? SQL_FETCH_FIRST : SQL_FETCH_NEXT); 00105 $first = false; 00106 if (!is_array($rez)) break; 00107 if (strtoupper($rez['server']) == $dsn) { 00108 $found = true; 00109 break; 00110 } 00111 } 00112 if (!$found) return ADOConnection::ServerInfo(); 00113 if (!isset($rez['version'])) $rez['version'] = ''; 00114 return $rez; 00115 } else { 00116 return ADOConnection::ServerInfo(); 00117 } 00118 } 00119 00120 00121 function CreateSequence($seqname='adodbseq',$start=1) 00122 { 00123 if (empty($this->_genSeqSQL)) return false; 00124 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname)); 00125 if (!$ok) return false; 00126 $start -= 1; 00127 return $this->Execute("insert into $seqname values($start)"); 00128 } 00129 00130 var $_dropSeqSQL = 'drop table %s'; 00131 function DropSequence($seqname) 00132 { 00133 if (empty($this->_dropSeqSQL)) return false; 00134 return $this->Execute(sprintf($this->_dropSeqSQL,$seqname)); 00135 } 00136 00137 /* 00138 This algorithm is not very efficient, but works even if table locking 00139 is not available. 00140 00141 Will return false if unable to generate an ID after $MAXLOOPS attempts. 00142 */ 00143 function GenID($seq='adodbseq',$start=1) 00144 { 00145 // if you have to modify the parameter below, your database is overloaded, 00146 // or you need to implement generation of id's yourself! 00147 $MAXLOOPS = 100; 00148 //$this->debug=1; 00149 while (--$MAXLOOPS>=0) { 00150 $num = $this->GetOne("select id from $seq"); 00151 if ($num === false) { 00152 $this->Execute(sprintf($this->_genSeqSQL ,$seq)); 00153 $start -= 1; 00154 $num = '0'; 00155 $ok = $this->Execute("insert into $seq values($start)"); 00156 if (!$ok) return false; 00157 } 00158 $this->Execute("update $seq set id=id+1 where id=$num"); 00159 00160 if ($this->affected_rows() > 0) { 00161 $num += 1; 00162 $this->genID = $num; 00163 return $num; 00164 } elseif ($this->affected_rows() == 0) { 00165 // some drivers do not return a valid value => try with another method 00166 $value = $this->GetOne("select id from $seq"); 00167 if ($value == $num + 1) { 00168 return $value; 00169 } 00170 } 00171 } 00172 if ($fn = $this->raiseErrorFn) { 00173 $fn($this->databaseType,'GENID',-32000,"Unable to generate unique id after $MAXLOOPS attempts",$seq,$num); 00174 } 00175 return false; 00176 } 00177 00178 00179 function ErrorMsg() 00180 { 00181 if ($this->_haserrorfunctions) { 00182 if ($this->_errorMsg !== false) return $this->_errorMsg; 00183 if (empty($this->_connectionID)) return @odbc_errormsg(); 00184 return @odbc_errormsg($this->_connectionID); 00185 } else return ADOConnection::ErrorMsg(); 00186 } 00187 00188 function ErrorNo() 00189 { 00190 00191 if ($this->_haserrorfunctions) { 00192 if ($this->_errorCode !== false) { 00193 // bug in 4.0.6, error number can be corrupted string (should be 6 digits) 00194 return (strlen($this->_errorCode)<=2) ? 0 : $this->_errorCode; 00195 } 00196 00197 if (empty($this->_connectionID)) $e = @odbc_error(); 00198 else $e = @odbc_error($this->_connectionID); 00199 00200 // bug in 4.0.6, error number can be corrupted string (should be 6 digits) 00201 // so we check and patch 00202 if (strlen($e)<=2) return 0; 00203 return $e; 00204 } else return ADOConnection::ErrorNo(); 00205 } 00206 00207 00208 00209 function BeginTrans() 00210 { 00211 if (!$this->hasTransactions) return false; 00212 if ($this->transOff) return true; 00213 $this->transCnt += 1; 00214 $this->_autocommit = false; 00215 return odbc_autocommit($this->_connectionID,false); 00216 } 00217 00218 function CommitTrans($ok=true) 00219 { 00220 if ($this->transOff) return true; 00221 if (!$ok) return $this->RollbackTrans(); 00222 if ($this->transCnt) $this->transCnt -= 1; 00223 $this->_autocommit = true; 00224 $ret = odbc_commit($this->_connectionID); 00225 odbc_autocommit($this->_connectionID,true); 00226 return $ret; 00227 } 00228 00229 function RollbackTrans() 00230 { 00231 if ($this->transOff) return true; 00232 if ($this->transCnt) $this->transCnt -= 1; 00233 $this->_autocommit = true; 00234 $ret = odbc_rollback($this->_connectionID); 00235 odbc_autocommit($this->_connectionID,true); 00236 return $ret; 00237 } 00238 00239 function MetaPrimaryKeys($table) 00240 { 00241 global $ADODB_FETCH_MODE; 00242 00243 if ($this->uCaseTables) $table = strtoupper($table); 00244 $schema = ''; 00245 $this->_findschema($table,$schema); 00246 00247 $savem = $ADODB_FETCH_MODE; 00248 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00249 $qid = @odbc_primarykeys($this->_connectionID,'',$schema,$table); 00250 00251 if (!$qid) { 00252 $ADODB_FETCH_MODE = $savem; 00253 return false; 00254 } 00255 $rs = new ADORecordSet_odbc($qid); 00256 $ADODB_FETCH_MODE = $savem; 00257 00258 if (!$rs) return false; 00259 $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change; 00260 00261 $arr = $rs->GetArray(); 00262 $rs->Close(); 00263 //print_r($arr); 00264 $arr2 = array(); 00265 for ($i=0; $i < sizeof($arr); $i++) { 00266 if ($arr[$i][3]) $arr2[] = $arr[$i][3]; 00267 } 00268 return $arr2; 00269 } 00270 00271 00272 00273 function MetaTables($ttype=false) 00274 { 00275 global $ADODB_FETCH_MODE; 00276 00277 $savem = $ADODB_FETCH_MODE; 00278 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00279 $qid = odbc_tables($this->_connectionID); 00280 00281 $rs = new ADORecordSet_odbc($qid); 00282 00283 $ADODB_FETCH_MODE = $savem; 00284 if (!$rs) { 00285 $false = false; 00286 return $false; 00287 } 00288 $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change; 00289 00290 $arr = $rs->GetArray(); 00291 //print_r($arr); 00292 00293 $rs->Close(); 00294 $arr2 = array(); 00295 00296 if ($ttype) { 00297 $isview = strncmp($ttype,'V',1) === 0; 00298 } 00299 for ($i=0; $i < sizeof($arr); $i++) { 00300 if (!$arr[$i][2]) continue; 00301 $type = $arr[$i][3]; 00302 if ($ttype) { 00303 if ($isview) { 00304 if (strncmp($type,'V',1) === 0) $arr2[] = $arr[$i][2]; 00305 } else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2]; 00306 } else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2]; 00307 } 00308 return $arr2; 00309 } 00310 00311 /* 00312 See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcdatetime_data_type_changes.asp 00313 / SQL data type codes / 00314 #define SQL_UNKNOWN_TYPE 0 00315 #define SQL_CHAR 1 00316 #define SQL_NUMERIC 2 00317 #define SQL_DECIMAL 3 00318 #define SQL_INTEGER 4 00319 #define SQL_SMALLINT 5 00320 #define SQL_FLOAT 6 00321 #define SQL_REAL 7 00322 #define SQL_DOUBLE 8 00323 #if (ODBCVER >= 0x0300) 00324 #define SQL_DATETIME 9 00325 #endif 00326 #define SQL_VARCHAR 12 00327 00328 00329 / One-parameter shortcuts for date/time data types / 00330 #if (ODBCVER >= 0x0300) 00331 #define SQL_TYPE_DATE 91 00332 #define SQL_TYPE_TIME 92 00333 #define SQL_TYPE_TIMESTAMP 93 00334 00335 #define SQL_UNICODE (-95) 00336 #define SQL_UNICODE_VARCHAR (-96) 00337 #define SQL_UNICODE_LONGVARCHAR (-97) 00338 */ 00339 function ODBCTypes($t) 00340 { 00341 switch ((integer)$t) { 00342 case 1: 00343 case 12: 00344 case 0: 00345 case -95: 00346 case -96: 00347 return 'C'; 00348 case -97: 00349 case -1: //text 00350 return 'X'; 00351 case -4: //image 00352 return 'B'; 00353 00354 case 9: 00355 case 91: 00356 return 'D'; 00357 00358 case 10: 00359 case 11: 00360 case 92: 00361 case 93: 00362 return 'T'; 00363 00364 case 4: 00365 case 5: 00366 case -6: 00367 return 'I'; 00368 00369 case -11: // uniqidentifier 00370 return 'R'; 00371 case -7: //bit 00372 return 'L'; 00373 00374 default: 00375 return 'N'; 00376 } 00377 } 00378 00379 function MetaColumns($table, $normalize=true) 00380 { 00381 global $ADODB_FETCH_MODE; 00382 00383 $false = false; 00384 if ($this->uCaseTables) $table = strtoupper($table); 00385 $schema = ''; 00386 $this->_findschema($table,$schema); 00387 00388 $savem = $ADODB_FETCH_MODE; 00389 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00390 00391 /*if (false) { // after testing, confirmed that the following does not work becoz of a bug 00392 $qid2 = odbc_tables($this->_connectionID); 00393 $rs = new ADORecordSet_odbc($qid2); 00394 $ADODB_FETCH_MODE = $savem; 00395 if (!$rs) return false; 00396 $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change; 00397 $rs->_fetch(); 00398 00399 while (!$rs->EOF) { 00400 if ($table == strtoupper($rs->fields[2])) { 00401 $q = $rs->fields[0]; 00402 $o = $rs->fields[1]; 00403 break; 00404 } 00405 $rs->MoveNext(); 00406 } 00407 $rs->Close(); 00408 00409 $qid = odbc_columns($this->_connectionID,$q,$o,strtoupper($table),'%'); 00410 } */ 00411 00412 switch ($this->databaseType) { 00413 case 'access': 00414 case 'vfp': 00415 $qid = odbc_columns($this->_connectionID);#,'%','',strtoupper($table),'%'); 00416 break; 00417 00418 00419 case 'db2': 00420 $colname = "%"; 00421 $qid = odbc_columns($this->_connectionID, "", $schema, $table, $colname); 00422 break; 00423 00424 default: 00425 $qid = @odbc_columns($this->_connectionID,'%','%',strtoupper($table),'%'); 00426 if (empty($qid)) $qid = odbc_columns($this->_connectionID); 00427 break; 00428 } 00429 if (empty($qid)) return $false; 00430 00431 $rs = new ADORecordSet_odbc($qid); 00432 $ADODB_FETCH_MODE = $savem; 00433 00434 if (!$rs) return $false; 00435 $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change; 00436 $rs->_fetch(); 00437 00438 $retarr = array(); 00439 00440 /* 00441 $rs->fields indices 00442 0 TABLE_QUALIFIER 00443 1 TABLE_SCHEM 00444 2 TABLE_NAME 00445 3 COLUMN_NAME 00446 4 DATA_TYPE 00447 5 TYPE_NAME 00448 6 PRECISION 00449 7 LENGTH 00450 8 SCALE 00451 9 RADIX 00452 10 NULLABLE 00453 11 REMARKS 00454 */ 00455 while (!$rs->EOF) { 00456 // adodb_pr($rs->fields); 00457 if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) { 00458 $fld = new ADOFieldObject(); 00459 $fld->name = $rs->fields[3]; 00460 $fld->type = $this->ODBCTypes($rs->fields[4]); 00461 00462 // ref: http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp 00463 // access uses precision to store length for char/varchar 00464 if ($fld->type == 'C' or $fld->type == 'X') { 00465 if ($this->databaseType == 'access') 00466 $fld->max_length = $rs->fields[6]; 00467 else if ($rs->fields[4] <= -95) // UNICODE 00468 $fld->max_length = $rs->fields[7]/2; 00469 else 00470 $fld->max_length = $rs->fields[7]; 00471 } else 00472 $fld->max_length = $rs->fields[7]; 00473 $fld->not_null = !empty($rs->fields[10]); 00474 $fld->scale = $rs->fields[8]; 00475 $retarr[strtoupper($fld->name)] = $fld; 00476 } else if (sizeof($retarr)>0) 00477 break; 00478 $rs->MoveNext(); 00479 } 00480 $rs->Close(); //-- crashes 4.03pl1 -- why? 00481 00482 if (empty($retarr)) $retarr = false; 00483 return $retarr; 00484 } 00485 00486 function Prepare($sql) 00487 { 00488 if (! $this->_bindInputArray) return $sql; // no binding 00489 $stmt = odbc_prepare($this->_connectionID,$sql); 00490 if (!$stmt) { 00491 // we don't know whether odbc driver is parsing prepared stmts, so just return sql 00492 return $sql; 00493 } 00494 return array($sql,$stmt,false); 00495 } 00496 00497 /* returns queryID or false */ 00498 function _query($sql,$inputarr=false) 00499 { 00500 GLOBAL $php_errormsg; 00501 if (isset($php_errormsg)) $php_errormsg = ''; 00502 $this->_error = ''; 00503 00504 if ($inputarr) { 00505 if (is_array($sql)) { 00506 $stmtid = $sql[1]; 00507 } else { 00508 $stmtid = odbc_prepare($this->_connectionID,$sql); 00509 00510 if ($stmtid == false) { 00511 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 00512 return false; 00513 } 00514 } 00515 00516 if (! odbc_execute($stmtid,$inputarr)) { 00517 //@odbc_free_result($stmtid); 00518 if ($this->_haserrorfunctions) { 00519 $this->_errorMsg = odbc_errormsg(); 00520 $this->_errorCode = odbc_error(); 00521 } 00522 return false; 00523 } 00524 00525 } else if (is_array($sql)) { 00526 $stmtid = $sql[1]; 00527 if (!odbc_execute($stmtid)) { 00528 //@odbc_free_result($stmtid); 00529 if ($this->_haserrorfunctions) { 00530 $this->_errorMsg = odbc_errormsg(); 00531 $this->_errorCode = odbc_error(); 00532 } 00533 return false; 00534 } 00535 } else 00536 $stmtid = odbc_exec($this->_connectionID,$sql); 00537 00538 $this->_lastAffectedRows = 0; 00539 if ($stmtid) { 00540 if (@odbc_num_fields($stmtid) == 0) { 00541 $this->_lastAffectedRows = odbc_num_rows($stmtid); 00542 $stmtid = true; 00543 } else { 00544 $this->_lastAffectedRows = 0; 00545 odbc_binmode($stmtid,$this->binmode); 00546 odbc_longreadlen($stmtid,$this->maxblobsize); 00547 } 00548 00549 if ($this->_haserrorfunctions) { 00550 $this->_errorMsg = ''; 00551 $this->_errorCode = 0; 00552 } else 00553 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 00554 } else { 00555 if ($this->_haserrorfunctions) { 00556 $this->_errorMsg = odbc_errormsg(); 00557 $this->_errorCode = odbc_error(); 00558 } else 00559 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 00560 } 00561 return $stmtid; 00562 } 00563 00564 /* 00565 Insert a null into the blob field of the table first. 00566 Then use UpdateBlob to store the blob. 00567 00568 Usage: 00569 00570 $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)'); 00571 $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1'); 00572 */ 00573 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB') 00574 { 00575 return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false; 00576 } 00577 00578 // returns true or false 00579 function _close() 00580 { 00581 $ret = @odbc_close($this->_connectionID); 00582 $this->_connectionID = false; 00583 return $ret; 00584 } 00585 00586 function _affectedrows() 00587 { 00588 return $this->_lastAffectedRows; 00589 } 00590 00591 } 00592 00593 /*-------------------------------------------------------------------------------------- 00594 Class Name: Recordset 00595 --------------------------------------------------------------------------------------*/ 00596 00597 class ADORecordSet_odbc extends ADORecordSet { 00598 00599 var $bind = false; 00600 var $databaseType = "odbc"; 00601 var $dataProvider = "odbc"; 00602 var $useFetchArray; 00603 var $_has_stupid_odbc_fetch_api_change; 00604 00605 function ADORecordSet_odbc($id,$mode=false) 00606 { 00607 if ($mode === false) { 00608 global $ADODB_FETCH_MODE; 00609 $mode = $ADODB_FETCH_MODE; 00610 } 00611 $this->fetchMode = $mode; 00612 00613 $this->_queryID = $id; 00614 00615 // the following is required for mysql odbc driver in 4.3.1 -- why? 00616 $this->EOF = false; 00617 $this->_currentRow = -1; 00618 //$this->ADORecordSet($id); 00619 } 00620 00621 00622 // returns the field object 00623 function FetchField($fieldOffset = -1) 00624 { 00625 00626 $off=$fieldOffset+1; // offsets begin at 1 00627 00628 $o= new ADOFieldObject(); 00629 $o->name = @odbc_field_name($this->_queryID,$off); 00630 $o->type = @odbc_field_type($this->_queryID,$off); 00631 $o->max_length = @odbc_field_len($this->_queryID,$off); 00632 if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name); 00633 else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name); 00634 return $o; 00635 } 00636 00637 /* Use associative array to get fields array */ 00638 function Fields($colname) 00639 { 00640 if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname]; 00641 if (!$this->bind) { 00642 $this->bind = array(); 00643 for ($i=0; $i < $this->_numOfFields; $i++) { 00644 $o = $this->FetchField($i); 00645 $this->bind[strtoupper($o->name)] = $i; 00646 } 00647 } 00648 00649 return $this->fields[$this->bind[strtoupper($colname)]]; 00650 } 00651 00652 00653 function _initrs() 00654 { 00655 global $ADODB_COUNTRECS; 00656 $this->_numOfRows = ($ADODB_COUNTRECS) ? @odbc_num_rows($this->_queryID) : -1; 00657 $this->_numOfFields = @odbc_num_fields($this->_queryID); 00658 // some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0 00659 if ($this->_numOfRows == 0) $this->_numOfRows = -1; 00660 //$this->useFetchArray = $this->connection->useFetchArray; 00661 $this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200; 00662 } 00663 00664 function _seek($row) 00665 { 00666 return false; 00667 } 00668 00669 // speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated 00670 function GetArrayLimit($nrows,$offset=-1) 00671 { 00672 if ($offset <= 0) { 00673 $rs = $this->GetArray($nrows); 00674 return $rs; 00675 } 00676 $savem = $this->fetchMode; 00677 $this->fetchMode = ADODB_FETCH_NUM; 00678 $this->Move($offset); 00679 $this->fetchMode = $savem; 00680 00681 if ($this->fetchMode & ADODB_FETCH_ASSOC) { 00682 $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE); 00683 } 00684 00685 $results = array(); 00686 $cnt = 0; 00687 while (!$this->EOF && $nrows != $cnt) { 00688 $results[$cnt++] = $this->fields; 00689 $this->MoveNext(); 00690 } 00691 00692 return $results; 00693 } 00694 00695 00696 function MoveNext() 00697 { 00698 if ($this->_numOfRows != 0 && !$this->EOF) { 00699 $this->_currentRow++; 00700 00701 if ($this->_has_stupid_odbc_fetch_api_change) 00702 $rez = @odbc_fetch_into($this->_queryID,$this->fields); 00703 else { 00704 $row = 0; 00705 $rez = @odbc_fetch_into($this->_queryID,$row,$this->fields); 00706 } 00707 if ($rez) { 00708 if ($this->fetchMode & ADODB_FETCH_ASSOC) { 00709 $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE); 00710 } 00711 return true; 00712 } 00713 } 00714 $this->fields = false; 00715 $this->EOF = true; 00716 return false; 00717 } 00718 00719 function _fetch() 00720 { 00721 00722 if ($this->_has_stupid_odbc_fetch_api_change) 00723 $rez = @odbc_fetch_into($this->_queryID,$this->fields); 00724 else { 00725 $row = 0; 00726 $rez = @odbc_fetch_into($this->_queryID,$row,$this->fields); 00727 } 00728 if ($rez) { 00729 if ($this->fetchMode & ADODB_FETCH_ASSOC) { 00730 $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE); 00731 } 00732 return true; 00733 } 00734 $this->fields = false; 00735 return false; 00736 } 00737 00738 function _close() 00739 { 00740 return @odbc_free_result($this->_queryID); 00741 } 00742 00743 } 00744 ?>