"TYPO3 4.0.1: typo3_src-4.0.1/typo3/sysext/adodb/adodb/drivers/adodb-odbc.inc.php Source File", "datetime" => "Sat Dec 2 19:22:26 2006", "date" => "2 Dec 2006", "doxygenversion" => "1.4.6", "projectname" => "TYPO3 4.0.1", "projectnumber" => "4.0.1" ); get_header($doxygen_vars); ?>

adodb-odbc.inc.php

00001 <?php
00002 /* 
00003 V4.90 8 June 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 ?>