new approach to logging database access and upgraded adodb
[openemr.git] / library / adodb / drivers / adodb-db2.inc.php
blob745035a422329303d7f2b388dd3ab039b8d53edf
1 <?php
2 /*
3 V5.14 8 Sept 2011 (c) 2000-2011 (jlim#natsoft.com). All rights reserved.
5 This is a version of the ADODB driver for DB2. It uses the 'ibm_db2' PECL extension
6 for PHP (http://pecl.php.net/package/ibm_db2), which in turn requires DB2 V8.2.2 or
7 higher.
9 Originally tested with PHP 5.1.1 and Apache 2.0.55 on Windows XP SP2.
10 More recently tested with PHP 5.1.2 and Apache 2.0.55 on Windows XP SP2.
12 This file was ported from "adodb-odbc.inc.php" by Larry Menard, "larry.menard#rogers.com".
13 I ripped out what I believed to be a lot of redundant or obsolete code, but there are
14 probably still some remnants of the ODBC support in this file; I'm relying on reviewers
15 of this code to point out any other things that can be removed.
18 // security - hide paths
19 if (!defined('ADODB_DIR')) die();
21 define("_ADODB_DB2_LAYER", 2 );
23 /*--------------------------------------------------------------------------------------
24 --------------------------------------------------------------------------------------*/
30 class ADODB_db2 extends ADOConnection {
31 var $databaseType = "db2";
32 var $fmtDate = "'Y-m-d'";
33 var $concat_operator = '||';
35 var $sysTime = 'CURRENT TIME';
36 var $sysDate = 'CURRENT DATE';
37 var $sysTimeStamp = 'CURRENT TIMESTAMP';
39 var $fmtTimeStamp = "'Y-m-d H:i:s'";
40 var $replaceQuote = "''"; // string to use to replace quotes
41 var $dataProvider = "db2";
42 var $hasAffectedRows = true;
44 var $binmode = DB2_BINARY;
46 var $useFetchArray = false; // setting this to true will make array elements in FETCH_ASSOC mode case-sensitive
47 // breaking backward-compat
48 var $_bindInputArray = false;
49 var $_genIDSQL = "VALUES NEXTVAL FOR %s";
50 var $_genSeqSQL = "CREATE SEQUENCE %s START WITH %s NO MAXVALUE NO CYCLE";
51 var $_dropSeqSQL = "DROP SEQUENCE %s";
52 var $_autocommit = true;
53 var $_haserrorfunctions = true;
54 var $_lastAffectedRows = 0;
55 var $uCaseTables = true; // for meta* functions, uppercase table names
56 var $hasInsertID = true;
59 function _insertid()
61 return ADOConnection::GetOne('VALUES IDENTITY_VAL_LOCAL()');
64 function ADODB_db2()
66 $this->_haserrorfunctions = ADODB_PHPVER >= 0x4050;
69 // returns true or false
70 function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
72 global $php_errormsg;
74 if (!function_exists('db2_connect')) {
75 ADOConnection::outp("Warning: The old ODBC based DB2 driver has been renamed 'odbc_db2'. This ADOdb driver calls PHP's native db2 extension which is not installed.");
76 return null;
78 // This needs to be set before the connect().
79 // Replaces the odbc_binmode() call that was in Execute()
80 ini_set('ibm_db2.binmode', $this->binmode);
82 if ($argDatabasename && empty($argDSN)) {
84 if (stripos($argDatabasename,'UID=') && stripos($argDatabasename,'PWD=')) $this->_connectionID = db2_connect($argDatabasename,null,null);
85 else $this->_connectionID = db2_connect($argDatabasename,$argUsername,$argPassword);
86 } else {
87 if ($argDatabasename) $schema = $argDatabasename;
88 if (stripos($argDSN,'UID=') && stripos($argDSN,'PWD=')) $this->_connectionID = db2_connect($argDSN,null,null);
89 else $this->_connectionID = db2_connect($argDSN,$argUsername,$argPassword);
91 if (isset($php_errormsg)) $php_errormsg = '';
93 // For db2_connect(), there is an optional 4th arg. If present, it must be
94 // an array of valid options. So far, we don't use them.
96 $this->_errorMsg = @db2_conn_errormsg();
97 if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
99 if ($this->_connectionID && isset($schema)) $this->Execute("SET SCHEMA=$schema");
100 return $this->_connectionID != false;
103 // returns true or false
104 function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
106 global $php_errormsg;
108 if (!function_exists('db2_connect')) return null;
110 // This needs to be set before the connect().
111 // Replaces the odbc_binmode() call that was in Execute()
112 ini_set('ibm_db2.binmode', $this->binmode);
114 if (isset($php_errormsg)) $php_errormsg = '';
115 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
117 if ($argDatabasename && empty($argDSN)) {
119 if (stripos($argDatabasename,'UID=') && stripos($argDatabasename,'PWD=')) $this->_connectionID = db2_pconnect($argDatabasename,null,null);
120 else $this->_connectionID = db2_pconnect($argDatabasename,$argUsername,$argPassword);
121 } else {
122 if ($argDatabasename) $schema = $argDatabasename;
123 if (stripos($argDSN,'UID=') && stripos($argDSN,'PWD=')) $this->_connectionID = db2_pconnect($argDSN,null,null);
124 else $this->_connectionID = db2_pconnect($argDSN,$argUsername,$argPassword);
126 if (isset($php_errormsg)) $php_errormsg = '';
128 $this->_errorMsg = @db2_conn_errormsg();
129 if ($this->_connectionID && $this->autoRollback) @db2_rollback($this->_connectionID);
130 if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
132 if ($this->_connectionID && isset($schema)) $this->Execute("SET SCHEMA=$schema");
133 return $this->_connectionID != false;
136 // format and return date string in database timestamp format
137 function DBTimeStamp($ts)
139 if (empty($ts) && $ts !== 0) return 'null';
140 if (is_string($ts)) $ts = ADORecordSet::UnixTimeStamp($ts);
141 return 'TO_DATE('.adodb_date($this->fmtTimeStamp,$ts).",'YYYY-MM-DD HH24:MI:SS')";
144 // Format date column in sql string given an input format that understands Y M D
145 function SQLDate($fmt, $col=false)
147 // use right() and replace() ?
148 if (!$col) $col = $this->sysDate;
150 /* use TO_CHAR() if $fmt is TO_CHAR() allowed fmt */
151 if ($fmt== 'Y-m-d H:i:s')
152 return 'TO_CHAR('.$col.", 'YYYY-MM-DD HH24:MI:SS')";
154 $s = '';
156 $len = strlen($fmt);
157 for ($i=0; $i < $len; $i++) {
158 if ($s) $s .= $this->concat_operator;
159 $ch = $fmt[$i];
160 switch($ch) {
161 case 'Y':
162 case 'y':
163 if ($len==1) return "year($col)";
164 $s .= "char(year($col))";
165 break;
166 case 'M':
167 if ($len==1) return "monthname($col)";
168 $s .= "substr(monthname($col),1,3)";
169 break;
170 case 'm':
171 if ($len==1) return "month($col)";
172 $s .= "right(digits(month($col)),2)";
173 break;
174 case 'D':
175 case 'd':
176 if ($len==1) return "day($col)";
177 $s .= "right(digits(day($col)),2)";
178 break;
179 case 'H':
180 case 'h':
181 if ($len==1) return "hour($col)";
182 if ($col != $this->sysDate) $s .= "right(digits(hour($col)),2)";
183 else $s .= "''";
184 break;
185 case 'i':
186 case 'I':
187 if ($len==1) return "minute($col)";
188 if ($col != $this->sysDate)
189 $s .= "right(digits(minute($col)),2)";
190 else $s .= "''";
191 break;
192 case 'S':
193 case 's':
194 if ($len==1) return "second($col)";
195 if ($col != $this->sysDate)
196 $s .= "right(digits(second($col)),2)";
197 else $s .= "''";
198 break;
199 default:
200 if ($ch == '\\') {
201 $i++;
202 $ch = substr($fmt,$i,1);
204 $s .= $this->qstr($ch);
207 return $s;
211 function ServerInfo()
213 $row = $this->GetRow("SELECT service_level, fixpack_num FROM TABLE(sysproc.env_get_inst_info())
214 as INSTANCEINFO");
217 if ($row) {
218 $info['version'] = $row[0].':'.$row[1];
219 $info['fixpack'] = $row[1];
220 $info['description'] = '';
221 } else {
222 return ADOConnection::ServerInfo();
225 return $info;
228 function CreateSequence($seqname='adodbseq',$start=1)
230 if (empty($this->_genSeqSQL)) return false;
231 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$start));
232 if (!$ok) return false;
233 return true;
236 function DropSequence($seqname)
238 if (empty($this->_dropSeqSQL)) return false;
239 return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
242 function SelectLimit($sql,$nrows=-1,$offset=-1,$inputArr=false)
244 $nrows = (integer) $nrows;
245 if ($offset <= 0) {
246 // could also use " OPTIMIZE FOR $nrows ROWS "
247 if ($nrows >= 0) $sql .= " FETCH FIRST $nrows ROWS ONLY ";
248 $rs = $this->Execute($sql,$inputArr);
249 } else {
250 if ($offset > 0 && $nrows < 0);
251 else {
252 $nrows += $offset;
253 $sql .= " FETCH FIRST $nrows ROWS ONLY ";
255 $rs = ADOConnection::SelectLimit($sql,-1,$offset,$inputArr);
258 return $rs;
262 This algorithm is not very efficient, but works even if table locking
263 is not available.
265 Will return false if unable to generate an ID after $MAXLOOPS attempts.
267 function GenID($seq='adodbseq',$start=1)
269 // if you have to modify the parameter below, your database is overloaded,
270 // or you need to implement generation of id's yourself!
271 $num = $this->GetOne("VALUES NEXTVAL FOR $seq");
272 return $num;
276 function ErrorMsg()
278 if ($this->_haserrorfunctions) {
279 if ($this->_errorMsg !== false) return $this->_errorMsg;
280 if (empty($this->_connectionID)) return @db2_conn_errormsg();
281 return @db2_conn_errormsg($this->_connectionID);
282 } else return ADOConnection::ErrorMsg();
285 function ErrorNo()
288 if ($this->_haserrorfunctions) {
289 if ($this->_errorCode !== false) {
290 // bug in 4.0.6, error number can be corrupted string (should be 6 digits)
291 return (strlen($this->_errorCode)<=2) ? 0 : $this->_errorCode;
294 if (empty($this->_connectionID)) $e = @db2_conn_error();
295 else $e = @db2_conn_error($this->_connectionID);
297 // bug in 4.0.6, error number can be corrupted string (should be 6 digits)
298 // so we check and patch
299 if (strlen($e)<=2) return 0;
300 return $e;
301 } else return ADOConnection::ErrorNo();
306 function BeginTrans()
308 if (!$this->hasTransactions) return false;
309 if ($this->transOff) return true;
310 $this->transCnt += 1;
311 $this->_autocommit = false;
312 return db2_autocommit($this->_connectionID,false);
315 function CommitTrans($ok=true)
317 if ($this->transOff) return true;
318 if (!$ok) return $this->RollbackTrans();
319 if ($this->transCnt) $this->transCnt -= 1;
320 $this->_autocommit = true;
321 $ret = db2_commit($this->_connectionID);
322 db2_autocommit($this->_connectionID,true);
323 return $ret;
326 function RollbackTrans()
328 if ($this->transOff) return true;
329 if ($this->transCnt) $this->transCnt -= 1;
330 $this->_autocommit = true;
331 $ret = db2_rollback($this->_connectionID);
332 db2_autocommit($this->_connectionID,true);
333 return $ret;
336 function MetaPrimaryKeys($table)
338 global $ADODB_FETCH_MODE;
340 if ($this->uCaseTables) $table = strtoupper($table);
341 $schema = '';
342 $this->_findschema($table,$schema);
344 $savem = $ADODB_FETCH_MODE;
345 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
346 $qid = @db2_primarykeys($this->_connectionID,'',$schema,$table);
348 if (!$qid) {
349 $ADODB_FETCH_MODE = $savem;
350 return false;
352 $rs = new ADORecordSet_db2($qid);
353 $ADODB_FETCH_MODE = $savem;
355 if (!$rs) return false;
357 $arr = $rs->GetArray();
358 $rs->Close();
359 $arr2 = array();
360 for ($i=0; $i < sizeof($arr); $i++) {
361 if ($arr[$i][3]) $arr2[] = $arr[$i][3];
363 return $arr2;
366 function MetaForeignKeys($table, $owner = FALSE, $upper = FALSE, $asociative = FALSE )
368 global $ADODB_FETCH_MODE;
370 if ($this->uCaseTables) $table = strtoupper($table);
371 $schema = '';
372 $this->_findschema($table,$schema);
374 $savem = $ADODB_FETCH_MODE;
375 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
376 $qid = @db2_foreign_keys($this->_connectionID,'',$schema,$table);
377 if (!$qid) {
378 $ADODB_FETCH_MODE = $savem;
379 return false;
381 $rs = new ADORecordSet_db2($qid);
383 $ADODB_FETCH_MODE = $savem;
385 $rs->fields indices
386 0 PKTABLE_CAT
387 1 PKTABLE_SCHEM
388 2 PKTABLE_NAME
389 3 PKCOLUMN_NAME
390 4 FKTABLE_CAT
391 5 FKTABLE_SCHEM
392 6 FKTABLE_NAME
393 7 FKCOLUMN_NAME
395 if (!$rs) return false;
397 $foreign_keys = array();
398 while (!$rs->EOF) {
399 if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
400 if (!is_array($foreign_keys[$rs->fields[5].'.'.$rs->fields[6]]))
401 $foreign_keys[$rs->fields[5].'.'.$rs->fields[6]] = array();
402 $foreign_keys[$rs->fields[5].'.'.$rs->fields[6]][$rs->fields[7]] = $rs->fields[3];
404 $rs->MoveNext();
407 $rs->Close();
408 return $foreign_key;
412 function MetaTables($ttype=false,$schema=false)
414 global $ADODB_FETCH_MODE;
416 $savem = $ADODB_FETCH_MODE;
417 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
418 $qid = db2_tables($this->_connectionID);
420 $rs = new ADORecordSet_db2($qid);
422 $ADODB_FETCH_MODE = $savem;
423 if (!$rs) {
424 $false = false;
425 return $false;
428 $arr = $rs->GetArray();
429 $rs->Close();
430 $arr2 = array();
432 if ($ttype) {
433 $isview = strncmp($ttype,'V',1) === 0;
435 for ($i=0; $i < sizeof($arr); $i++) {
436 if (!$arr[$i][2]) continue;
437 $type = $arr[$i][3];
438 $owner = $arr[$i][1];
439 $schemaval = ($schema) ? $arr[$i][1].'.' : '';
440 if ($ttype) {
441 if ($isview) {
442 if (strncmp($type,'V',1) === 0) $arr2[] = $schemaval.$arr[$i][2];
443 } else if (strncmp($owner,'SYS',3) !== 0) $arr2[] = $schemaval.$arr[$i][2];
444 } else if (strncmp($owner,'SYS',3) !== 0) $arr2[] = $schemaval.$arr[$i][2];
446 return $arr2;
450 See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2datetime_data_type_changes.asp
451 / SQL data type codes /
452 #define SQL_UNKNOWN_TYPE 0
453 #define SQL_CHAR 1
454 #define SQL_NUMERIC 2
455 #define SQL_DECIMAL 3
456 #define SQL_INTEGER 4
457 #define SQL_SMALLINT 5
458 #define SQL_FLOAT 6
459 #define SQL_REAL 7
460 #define SQL_DOUBLE 8
461 #if (DB2VER >= 0x0300)
462 #define SQL_DATETIME 9
463 #endif
464 #define SQL_VARCHAR 12
467 / One-parameter shortcuts for date/time data types /
468 #if (DB2VER >= 0x0300)
469 #define SQL_TYPE_DATE 91
470 #define SQL_TYPE_TIME 92
471 #define SQL_TYPE_TIMESTAMP 93
473 #define SQL_UNICODE (-95)
474 #define SQL_UNICODE_VARCHAR (-96)
475 #define SQL_UNICODE_LONGVARCHAR (-97)
477 function DB2Types($t)
479 switch ((integer)$t) {
480 case 1:
481 case 12:
482 case 0:
483 case -95:
484 case -96:
485 return 'C';
486 case -97:
487 case -1: //text
488 return 'X';
489 case -4: //image
490 return 'B';
492 case 9:
493 case 91:
494 return 'D';
496 case 10:
497 case 11:
498 case 92:
499 case 93:
500 return 'T';
502 case 4:
503 case 5:
504 case -6:
505 return 'I';
507 case -11: // uniqidentifier
508 return 'R';
509 case -7: //bit
510 return 'L';
512 default:
513 return 'N';
517 function MetaColumns($table, $normalize=true)
519 global $ADODB_FETCH_MODE;
521 $false = false;
522 if ($this->uCaseTables) $table = strtoupper($table);
523 $schema = '';
524 $this->_findschema($table,$schema);
526 $savem = $ADODB_FETCH_MODE;
527 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
529 $colname = "%";
530 $qid = db2_columns($this->_connectionID, "", $schema, $table, $colname);
531 if (empty($qid)) return $false;
533 $rs = new ADORecordSet_db2($qid);
534 $ADODB_FETCH_MODE = $savem;
536 if (!$rs) return $false;
537 $rs->_fetch();
539 $retarr = array();
542 $rs->fields indices
543 0 TABLE_QUALIFIER
544 1 TABLE_SCHEM
545 2 TABLE_NAME
546 3 COLUMN_NAME
547 4 DATA_TYPE
548 5 TYPE_NAME
549 6 PRECISION
550 7 LENGTH
551 8 SCALE
552 9 RADIX
553 10 NULLABLE
554 11 REMARKS
556 while (!$rs->EOF) {
557 if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
558 $fld = new ADOFieldObject();
559 $fld->name = $rs->fields[3];
560 $fld->type = $this->DB2Types($rs->fields[4]);
562 // ref: http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp
563 // access uses precision to store length for char/varchar
564 if ($fld->type == 'C' or $fld->type == 'X') {
565 if ($rs->fields[4] <= -95) // UNICODE
566 $fld->max_length = $rs->fields[7]/2;
567 else
568 $fld->max_length = $rs->fields[7];
569 } else
570 $fld->max_length = $rs->fields[7];
571 $fld->not_null = !empty($rs->fields[10]);
572 $fld->scale = $rs->fields[8];
573 $fld->primary_key = false;
574 $retarr[strtoupper($fld->name)] = $fld;
575 } else if (sizeof($retarr)>0)
576 break;
577 $rs->MoveNext();
579 $rs->Close();
580 if (empty($retarr)) $retarr = false;
582 $qid = db2_primary_keys($this->_connectionID, "", $schema, $table);
583 if (empty($qid)) return $false;
585 $rs = new ADORecordSet_db2($qid);
586 $ADODB_FETCH_MODE = $savem;
588 if (!$rs) return $retarr;
589 $rs->_fetch();
592 $rs->fields indices
593 0 TABLE_CAT
594 1 TABLE_SCHEM
595 2 TABLE_NAME
596 3 COLUMN_NAME
597 4 KEY_SEQ
598 5 PK_NAME
600 while (!$rs->EOF) {
601 if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
602 $retarr[strtoupper($rs->fields[3])]->primary_key = true;
603 } else if (sizeof($retarr)>0)
604 break;
605 $rs->MoveNext();
607 $rs->Close();
609 if (empty($retarr)) $retarr = false;
610 return $retarr;
614 function Prepare($sql)
616 if (! $this->_bindInputArray) return $sql; // no binding
617 $stmt = db2_prepare($this->_connectionID,$sql);
618 if (!$stmt) {
619 // we don't know whether db2 driver is parsing prepared stmts, so just return sql
620 return $sql;
622 return array($sql,$stmt,false);
625 /* returns queryID or false */
626 function _query($sql,$inputarr=false)
628 GLOBAL $php_errormsg;
629 if (isset($php_errormsg)) $php_errormsg = '';
630 $this->_error = '';
632 if ($inputarr) {
633 if (is_array($sql)) {
634 $stmtid = $sql[1];
635 } else {
636 $stmtid = db2_prepare($this->_connectionID,$sql);
638 if ($stmtid == false) {
639 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
640 return false;
644 if (! db2_execute($stmtid,$inputarr)) {
645 if ($this->_haserrorfunctions) {
646 $this->_errorMsg = db2_stmt_errormsg();
647 $this->_errorCode = db2_stmt_error();
649 return false;
652 } else if (is_array($sql)) {
653 $stmtid = $sql[1];
654 if (!db2_execute($stmtid)) {
655 if ($this->_haserrorfunctions) {
656 $this->_errorMsg = db2_stmt_errormsg();
657 $this->_errorCode = db2_stmt_error();
659 return false;
661 } else
662 $stmtid = @db2_exec($this->_connectionID,$sql);
664 $this->_lastAffectedRows = 0;
665 if ($stmtid) {
666 if (@db2_num_fields($stmtid) == 0) {
667 $this->_lastAffectedRows = db2_num_rows($stmtid);
668 $stmtid = true;
669 } else {
670 $this->_lastAffectedRows = 0;
673 if ($this->_haserrorfunctions) {
674 $this->_errorMsg = '';
675 $this->_errorCode = 0;
676 } else
677 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
678 } else {
679 if ($this->_haserrorfunctions) {
680 $this->_errorMsg = db2_stmt_errormsg();
681 $this->_errorCode = db2_stmt_error();
682 } else
683 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
686 return $stmtid;
690 Insert a null into the blob field of the table first.
691 Then use UpdateBlob to store the blob.
693 Usage:
695 $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
696 $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
698 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
700 return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false;
703 // returns true or false
704 function _close()
706 $ret = @db2_close($this->_connectionID);
707 $this->_connectionID = false;
708 return $ret;
711 function _affectedrows()
713 return $this->_lastAffectedRows;
718 /*--------------------------------------------------------------------------------------
719 Class Name: Recordset
720 --------------------------------------------------------------------------------------*/
722 class ADORecordSet_db2 extends ADORecordSet {
724 var $bind = false;
725 var $databaseType = "db2";
726 var $dataProvider = "db2";
727 var $useFetchArray;
729 function ADORecordSet_db2($id,$mode=false)
731 if ($mode === false) {
732 global $ADODB_FETCH_MODE;
733 $mode = $ADODB_FETCH_MODE;
735 $this->fetchMode = $mode;
737 $this->_queryID = $id;
741 // returns the field object
742 function FetchField($offset = -1)
744 $o= new ADOFieldObject();
745 $o->name = @db2_field_name($this->_queryID,$offset);
746 $o->type = @db2_field_type($this->_queryID,$offset);
747 $o->max_length = db2_field_width($this->_queryID,$offset);
748 if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
749 else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
750 return $o;
753 /* Use associative array to get fields array */
754 function Fields($colname)
756 if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
757 if (!$this->bind) {
758 $this->bind = array();
759 for ($i=0; $i < $this->_numOfFields; $i++) {
760 $o = $this->FetchField($i);
761 $this->bind[strtoupper($o->name)] = $i;
765 return $this->fields[$this->bind[strtoupper($colname)]];
769 function _initrs()
771 global $ADODB_COUNTRECS;
772 $this->_numOfRows = ($ADODB_COUNTRECS) ? @db2_num_rows($this->_queryID) : -1;
773 $this->_numOfFields = @db2_num_fields($this->_queryID);
774 // some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0
775 if ($this->_numOfRows == 0) $this->_numOfRows = -1;
778 function _seek($row)
780 return false;
783 // speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
784 function GetArrayLimit($nrows,$offset=-1)
786 if ($offset <= 0) {
787 $rs = $this->GetArray($nrows);
788 return $rs;
790 $savem = $this->fetchMode;
791 $this->fetchMode = ADODB_FETCH_NUM;
792 $this->Move($offset);
793 $this->fetchMode = $savem;
795 if ($this->fetchMode & ADODB_FETCH_ASSOC) {
796 $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
799 $results = array();
800 $cnt = 0;
801 while (!$this->EOF && $nrows != $cnt) {
802 $results[$cnt++] = $this->fields;
803 $this->MoveNext();
806 return $results;
810 function MoveNext()
812 if ($this->_numOfRows != 0 && !$this->EOF) {
813 $this->_currentRow++;
815 $this->fields = @db2_fetch_array($this->_queryID);
816 if ($this->fields) {
817 if ($this->fetchMode & ADODB_FETCH_ASSOC) {
818 $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
820 return true;
823 $this->fields = false;
824 $this->EOF = true;
825 return false;
828 function _fetch()
831 $this->fields = db2_fetch_array($this->_queryID);
832 if ($this->fields) {
833 if ($this->fetchMode & ADODB_FETCH_ASSOC) {
834 $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
836 return true;
838 $this->fields = false;
839 return false;
842 function _close()
844 return @db2_free_result($this->_queryID);