Documentation TYPO3 par Ameos |
00001 <?php 00002 /* 00003 V4.93 10 Oct 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 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 } 00165 } 00166 if ($fn = $this->raiseErrorFn) { 00167 $fn($this->databaseType,'GENID',-32000,"Unable to generate unique id after $MAXLOOPS attempts",$seq,$num); 00168 } 00169 return false; 00170 } 00171 00172 00173 function ErrorMsg() 00174 { 00175 if ($this->_haserrorfunctions) { 00176 if ($this->_errorMsg !== false) return $this->_errorMsg; 00177 if (empty($this->_connectionID)) return @odbc_errormsg(); 00178 return @odbc_errormsg($this->_connectionID); 00179 } else return ADOConnection::ErrorMsg(); 00180 } 00181 00182 function ErrorNo() 00183 { 00184 00185 if ($this->_haserrorfunctions) { 00186 if ($this->_errorCode !== false) { 00187 // bug in 4.0.6, error number can be corrupted string (should be 6 digits) 00188 return (strlen($this->_errorCode)<=2) ? 0 : $this->_errorCode; 00189 } 00190 00191 if (empty($this->_connectionID)) $e = @odbc_error(); 00192 else $e = @odbc_error($this->_connectionID); 00193 00194 // bug in 4.0.6, error number can be corrupted string (should be 6 digits) 00195 // so we check and patch 00196 if (strlen($e)<=2) return 0; 00197 return $e; 00198 } else return ADOConnection::ErrorNo(); 00199 } 00200 00201 00202 00203 function BeginTrans() 00204 { 00205 if (!$this->hasTransactions) return false; 00206 if ($this->transOff) return true; 00207 $this->transCnt += 1; 00208 $this->_autocommit = false; 00209 return odbc_autocommit($this->_connectionID,false); 00210 } 00211 00212 function CommitTrans($ok=true) 00213 { 00214 if ($this->transOff) return true; 00215 if (!$ok) return $this->RollbackTrans(); 00216 if ($this->transCnt) $this->transCnt -= 1; 00217 $this->_autocommit = true; 00218 $ret = odbc_commit($this->_connectionID); 00219 odbc_autocommit($this->_connectionID,true); 00220 return $ret; 00221 } 00222 00223 function RollbackTrans() 00224 { 00225 if ($this->transOff) return true; 00226 if ($this->transCnt) $this->transCnt -= 1; 00227 $this->_autocommit = true; 00228 $ret = odbc_rollback($this->_connectionID); 00229 odbc_autocommit($this->_connectionID,true); 00230 return $ret; 00231 } 00232 00233 function MetaPrimaryKeys($table) 00234 { 00235 global $ADODB_FETCH_MODE; 00236 00237 if ($this->uCaseTables) $table = strtoupper($table); 00238 $schema = ''; 00239 $this->_findschema($table,$schema); 00240 00241 $savem = $ADODB_FETCH_MODE; 00242 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00243 $qid = @odbc_primarykeys($this->_connectionID,'',$schema,$table); 00244 00245 if (!$qid) { 00246 $ADODB_FETCH_MODE = $savem; 00247 return false; 00248 } 00249 $rs = new ADORecordSet_odbc($qid); 00250 $ADODB_FETCH_MODE = $savem; 00251 00252 if (!$rs) return false; 00253 $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change; 00254 00255 $arr =& $rs->GetArray(); 00256 $rs->Close(); 00257 //print_r($arr); 00258 $arr2 = array(); 00259 for ($i=0; $i < sizeof($arr); $i++) { 00260 if ($arr[$i][3]) $arr2[] = $arr[$i][3]; 00261 } 00262 return $arr2; 00263 } 00264 00265 00266 00267 function &MetaTables($ttype=false) 00268 { 00269 global $ADODB_FETCH_MODE; 00270 00271 $savem = $ADODB_FETCH_MODE; 00272 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00273 $qid = odbc_tables($this->_connectionID); 00274 00275 $rs = new ADORecordSet_odbc($qid); 00276 00277 $ADODB_FETCH_MODE = $savem; 00278 if (!$rs) { 00279 $false = false; 00280 return $false; 00281 } 00282 $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change; 00283 00284 $arr =& $rs->GetArray(); 00285 //print_r($arr); 00286 00287 $rs->Close(); 00288 $arr2 = array(); 00289 00290 if ($ttype) { 00291 $isview = strncmp($ttype,'V',1) === 0; 00292 } 00293 for ($i=0; $i < sizeof($arr); $i++) { 00294 if (!$arr[$i][2]) continue; 00295 $type = $arr[$i][3]; 00296 if ($ttype) { 00297 if ($isview) { 00298 if (strncmp($type,'V',1) === 0) $arr2[] = $arr[$i][2]; 00299 } else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2]; 00300 } else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2]; 00301 } 00302 return $arr2; 00303 } 00304 00305 /* 00306 See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcdatetime_data_type_changes.asp 00307 / SQL data type codes / 00308 #define SQL_UNKNOWN_TYPE 0 00309 #define SQL_CHAR 1 00310 #define SQL_NUMERIC 2 00311 #define SQL_DECIMAL 3 00312 #define SQL_INTEGER 4 00313 #define SQL_SMALLINT 5 00314 #define SQL_FLOAT 6 00315 #define SQL_REAL 7 00316 #define SQL_DOUBLE 8 00317 #if (ODBCVER >= 0x0300) 00318 #define SQL_DATETIME 9 00319 #endif 00320 #define SQL_VARCHAR 12 00321 00322 00323 / One-parameter shortcuts for date/time data types / 00324 #if (ODBCVER >= 0x0300) 00325 #define SQL_TYPE_DATE 91 00326 #define SQL_TYPE_TIME 92 00327 #define SQL_TYPE_TIMESTAMP 93 00328 00329 #define SQL_UNICODE (-95) 00330 #define SQL_UNICODE_VARCHAR (-96) 00331 #define SQL_UNICODE_LONGVARCHAR (-97) 00332 */ 00333 function ODBCTypes($t) 00334 { 00335 switch ((integer)$t) { 00336 case 1: 00337 case 12: 00338 case 0: 00339 case -95: 00340 case -96: 00341 return 'C'; 00342 case -97: 00343 case -1: //text 00344 return 'X'; 00345 case -4: //image 00346 return 'B'; 00347 00348 case 9: 00349 case 91: 00350 return 'D'; 00351 00352 case 10: 00353 case 11: 00354 case 92: 00355 case 93: 00356 return 'T'; 00357 00358 case 4: 00359 case 5: 00360 case -6: 00361 return 'I'; 00362 00363 case -11: // uniqidentifier 00364 return 'R'; 00365 case -7: //bit 00366 return 'L'; 00367 00368 default: 00369 return 'N'; 00370 } 00371 } 00372 00373 function &MetaColumns($table) 00374 { 00375 global $ADODB_FETCH_MODE; 00376 00377 $false = false; 00378 if ($this->uCaseTables) $table = strtoupper($table); 00379 $schema = ''; 00380 $this->_findschema($table,$schema); 00381 00382 $savem = $ADODB_FETCH_MODE; 00383 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00384 00385 /*if (false) { // after testing, confirmed that the following does not work becoz of a bug 00386 $qid2 = odbc_tables($this->_connectionID); 00387 $rs = new ADORecordSet_odbc($qid2); 00388 $ADODB_FETCH_MODE = $savem; 00389 if (!$rs) return false; 00390 $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change; 00391 $rs->_fetch(); 00392 00393 while (!$rs->EOF) { 00394 if ($table == strtoupper($rs->fields[2])) { 00395 $q = $rs->fields[0]; 00396 $o = $rs->fields[1]; 00397 break; 00398 } 00399 $rs->MoveNext(); 00400 } 00401 $rs->Close(); 00402 00403 $qid = odbc_columns($this->_connectionID,$q,$o,strtoupper($table),'%'); 00404 } */ 00405 00406 switch ($this->databaseType) { 00407 case 'access': 00408 case 'vfp': 00409 $qid = odbc_columns($this->_connectionID);#,'%','',strtoupper($table),'%'); 00410 break; 00411 00412 00413 case 'db2': 00414 $colname = "%"; 00415 $qid = odbc_columns($this->_connectionID, "", $schema, $table, $colname); 00416 break; 00417 00418 default: 00419 $qid = @odbc_columns($this->_connectionID,'%','%',strtoupper($table),'%'); 00420 if (empty($qid)) $qid = odbc_columns($this->_connectionID); 00421 break; 00422 } 00423 if (empty($qid)) return $false; 00424 00425 $rs =& new ADORecordSet_odbc($qid); 00426 $ADODB_FETCH_MODE = $savem; 00427 00428 if (!$rs) return $false; 00429 $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change; 00430 $rs->_fetch(); 00431 00432 $retarr = array(); 00433 00434 /* 00435 $rs->fields indices 00436 0 TABLE_QUALIFIER 00437 1 TABLE_SCHEM 00438 2 TABLE_NAME 00439 3 COLUMN_NAME 00440 4 DATA_TYPE 00441 5 TYPE_NAME 00442 6 PRECISION 00443 7 LENGTH 00444 8 SCALE 00445 9 RADIX 00446 10 NULLABLE 00447 11 REMARKS 00448 */ 00449 while (!$rs->EOF) { 00450 // adodb_pr($rs->fields); 00451 if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) { 00452 $fld = new ADOFieldObject(); 00453 $fld->name = $rs->fields[3]; 00454 $fld->type = $this->ODBCTypes($rs->fields[4]); 00455 00456 // ref: http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp 00457 // access uses precision to store length for char/varchar 00458 if ($fld->type == 'C' or $fld->type == 'X') { 00459 if ($this->databaseType == 'access') 00460 $fld->max_length = $rs->fields[6]; 00461 else if ($rs->fields[4] <= -95) // UNICODE 00462 $fld->max_length = $rs->fields[7]/2; 00463 else 00464 $fld->max_length = $rs->fields[7]; 00465 } else 00466 $fld->max_length = $rs->fields[7]; 00467 $fld->not_null = !empty($rs->fields[10]); 00468 $fld->scale = $rs->fields[8]; 00469 $retarr[strtoupper($fld->name)] = $fld; 00470 } else if (sizeof($retarr)>0) 00471 break; 00472 $rs->MoveNext(); 00473 } 00474 $rs->Close(); //-- crashes 4.03pl1 -- why? 00475 00476 if (empty($retarr)) $retarr = false; 00477 return $retarr; 00478 } 00479 00480 function Prepare($sql) 00481 { 00482 if (! $this->_bindInputArray) return $sql; // no binding 00483 $stmt = odbc_prepare($this->_connectionID,$sql); 00484 if (!$stmt) { 00485 // we don't know whether odbc driver is parsing prepared stmts, so just return sql 00486 return $sql; 00487 } 00488 return array($sql,$stmt,false); 00489 } 00490 00491 /* returns queryID or false */ 00492 function _query($sql,$inputarr=false) 00493 { 00494 GLOBAL $php_errormsg; 00495 if (isset($php_errormsg)) $php_errormsg = ''; 00496 $this->_error = ''; 00497 00498 if ($inputarr) { 00499 if (is_array($sql)) { 00500 $stmtid = $sql[1]; 00501 } else { 00502 $stmtid = odbc_prepare($this->_connectionID,$sql); 00503 00504 if ($stmtid == false) { 00505 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 00506 return false; 00507 } 00508 } 00509 00510 if (! odbc_execute($stmtid,$inputarr)) { 00511 //@odbc_free_result($stmtid); 00512 if ($this->_haserrorfunctions) { 00513 $this->_errorMsg = odbc_errormsg(); 00514 $this->_errorCode = odbc_error(); 00515 } 00516 if($this->_errorCode == '00000') { // MS SQL Server sometimes returns this in combination with the FreeTDS 00517 $this->_errorMsg = ''; // driver and UnixODBC under Linux. This fixes the bogus "error" 00518 $this->_errorCode = 0; // <karsten@typo3.org> 00519 return true; 00520 } 00521 return false; 00522 } 00523 00524 } else if (is_array($sql)) { 00525 $stmtid = $sql[1]; 00526 if (!odbc_execute($stmtid)) { 00527 //@odbc_free_result($stmtid); 00528 if ($this->_haserrorfunctions) { 00529 $this->_errorMsg = odbc_errormsg(); 00530 $this->_errorCode = odbc_error(); 00531 } 00532 if($this->_errorCode == '00000') { // MS SQL Server sometimes returns this in combination with the FreeTDS 00533 $this->_errorMsg = ''; // driver and UnixODBC under Linux. This fixes the bogus "error" 00534 $this->_errorCode = 0; // <karsten@typo3.org> 00535 return true; 00536 } 00537 return false; 00538 } 00539 } else 00540 $stmtid = odbc_exec($this->_connectionID,$sql); 00541 00542 $this->_lastAffectedRows = 0; 00543 if ($stmtid) { 00544 if (@odbc_num_fields($stmtid) == 0) { 00545 $this->_lastAffectedRows = odbc_num_rows($stmtid); 00546 $stmtid = true; 00547 } else { 00548 $this->_lastAffectedRows = 0; 00549 odbc_binmode($stmtid,$this->binmode); 00550 odbc_longreadlen($stmtid,$this->maxblobsize); 00551 } 00552 00553 if ($this->_haserrorfunctions) { 00554 $this->_errorMsg = ''; 00555 $this->_errorCode = 0; 00556 } else 00557 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 00558 } else { 00559 if ($this->_haserrorfunctions) { 00560 $this->_errorMsg = odbc_errormsg(); 00561 $this->_errorCode = odbc_error(); 00562 } else 00563 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 00564 } 00565 return $stmtid; 00566 } 00567 00568 /* 00569 Insert a null into the blob field of the table first. 00570 Then use UpdateBlob to store the blob. 00571 00572 Usage: 00573 00574 $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)'); 00575 $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1'); 00576 */ 00577 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB') 00578 { 00579 return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false; 00580 } 00581 00582 // returns true or false 00583 function _close() 00584 { 00585 $ret = @odbc_close($this->_connectionID); 00586 $this->_connectionID = false; 00587 return $ret; 00588 } 00589 00590 function _affectedrows() 00591 { 00592 return $this->_lastAffectedRows; 00593 } 00594 00595 } 00596 00597 /*-------------------------------------------------------------------------------------- 00598 Class Name: Recordset 00599 --------------------------------------------------------------------------------------*/ 00600 00601 class ADORecordSet_odbc extends ADORecordSet { 00602 00603 var $bind = false; 00604 var $databaseType = "odbc"; 00605 var $dataProvider = "odbc"; 00606 var $useFetchArray; 00607 var $_has_stupid_odbc_fetch_api_change; 00608 00609 function ADORecordSet_odbc($id,$mode=false) 00610 { 00611 if ($mode === false) { 00612 global $ADODB_FETCH_MODE; 00613 $mode = $ADODB_FETCH_MODE; 00614 } 00615 $this->fetchMode = $mode; 00616 00617 $this->_queryID = $id; 00618 00619 // the following is required for mysql odbc driver in 4.3.1 -- why? 00620 $this->EOF = false; 00621 $this->_currentRow = -1; 00622 //$this->ADORecordSet($id); 00623 } 00624 00625 00626 // returns the field object 00627 function &FetchField($fieldOffset = -1) 00628 { 00629 00630 $off=$fieldOffset+1; // offsets begin at 1 00631 00632 $o= new ADOFieldObject(); 00633 $o->name = @odbc_field_name($this->_queryID,$off); 00634 $o->type = @odbc_field_type($this->_queryID,$off); 00635 $o->max_length = @odbc_field_len($this->_queryID,$off); 00636 if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name); 00637 else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name); 00638 return $o; 00639 } 00640 00641 /* Use associative array to get fields array */ 00642 function Fields($colname) 00643 { 00644 if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname]; 00645 if (!$this->bind) { 00646 $this->bind = array(); 00647 for ($i=0; $i < $this->_numOfFields; $i++) { 00648 $o = $this->FetchField($i); 00649 $this->bind[strtoupper($o->name)] = $i; 00650 } 00651 } 00652 00653 return $this->fields[$this->bind[strtoupper($colname)]]; 00654 } 00655 00656 00657 function _initrs() 00658 { 00659 global $ADODB_COUNTRECS; 00660 $this->_numOfRows = ($ADODB_COUNTRECS) ? @odbc_num_rows($this->_queryID) : -1; 00661 $this->_numOfFields = @odbc_num_fields($this->_queryID); 00662 // some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0 00663 if ($this->_numOfRows == 0) $this->_numOfRows = -1; 00664 //$this->useFetchArray = $this->connection->useFetchArray; 00665 $this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200; 00666 } 00667 00668 function _seek($row) 00669 { 00670 return false; 00671 } 00672 00673 // speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated 00674 function &GetArrayLimit($nrows,$offset=-1) 00675 { 00676 if ($offset <= 0) { 00677 $rs =& $this->GetArray($nrows); 00678 return $rs; 00679 } 00680 $savem = $this->fetchMode; 00681 $this->fetchMode = ADODB_FETCH_NUM; 00682 $this->Move($offset); 00683 $this->fetchMode = $savem; 00684 00685 if ($this->fetchMode & ADODB_FETCH_ASSOC) { 00686 $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE); 00687 } 00688 00689 $results = array(); 00690 $cnt = 0; 00691 while (!$this->EOF && $nrows != $cnt) { 00692 $results[$cnt++] = $this->fields; 00693 $this->MoveNext(); 00694 } 00695 00696 return $results; 00697 } 00698 00699 00700 function MoveNext() 00701 { 00702 if ($this->_numOfRows != 0 && !$this->EOF) { 00703 $this->_currentRow++; 00704 00705 if ($this->_has_stupid_odbc_fetch_api_change) 00706 $rez = @odbc_fetch_into($this->_queryID,$this->fields); 00707 else { 00708 $row = 0; 00709 $rez = @odbc_fetch_into($this->_queryID,$row,$this->fields); 00710 } 00711 if ($rez) { 00712 if ($this->fetchMode & ADODB_FETCH_ASSOC) { 00713 $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE); 00714 } 00715 return true; 00716 } 00717 } 00718 $this->fields = false; 00719 $this->EOF = true; 00720 return false; 00721 } 00722 00723 function _fetch() 00724 { 00725 00726 if ($this->_has_stupid_odbc_fetch_api_change) 00727 $rez = @odbc_fetch_into($this->_queryID,$this->fields); 00728 else { 00729 $row = 0; 00730 $rez = @odbc_fetch_into($this->_queryID,$row,$this->fields); 00731 } 00732 if ($rez) { 00733 if ($this->fetchMode & ADODB_FETCH_ASSOC) { 00734 $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE); 00735 } 00736 return true; 00737 } 00738 $this->fields = false; 00739 return false; 00740 } 00741 00742 function _close() 00743 { 00744 return @odbc_free_result($this->_queryID); 00745 } 00746 00747 } 00748 ?>