|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 /* 00003 V5.14 8 Sept 2011 (c) 2000-2011 (jlim#natsoft.com). All rights reserved. 00004 00005 This is a version of the ADODB driver for DB2. It uses the 'ibm_db2' PECL extension 00006 for PHP (http://pecl.php.net/package/ibm_db2), which in turn requires DB2 V8.2.2 or 00007 higher. 00008 00009 Originally tested with PHP 5.1.1 and Apache 2.0.55 on Windows XP SP2. 00010 More recently tested with PHP 5.1.2 and Apache 2.0.55 on Windows XP SP2. 00011 00012 This file was ported from "adodb-odbc.inc.php" by Larry Menard, "larry.menard#rogers.com". 00013 I ripped out what I believed to be a lot of redundant or obsolete code, but there are 00014 probably still some remnants of the ODBC support in this file; I'm relying on reviewers 00015 of this code to point out any other things that can be removed. 00016 */ 00017 00018 // security - hide paths 00019 if (!defined('ADODB_DIR')) die(); 00020 00021 define("_ADODB_DB2_LAYER", 2 ); 00022 00023 /*-------------------------------------------------------------------------------------- 00024 --------------------------------------------------------------------------------------*/ 00025 00026 00027 00028 00029 00030 class ADODB_db2 extends ADOConnection { 00031 var $databaseType = "db2"; 00032 var $fmtDate = "'Y-m-d'"; 00033 var $concat_operator = '||'; 00034 00035 var $sysTime = 'CURRENT TIME'; 00036 var $sysDate = 'CURRENT DATE'; 00037 var $sysTimeStamp = 'CURRENT TIMESTAMP'; 00038 00039 var $fmtTimeStamp = "'Y-m-d H:i:s'"; 00040 var $replaceQuote = "''"; // string to use to replace quotes 00041 var $dataProvider = "db2"; 00042 var $hasAffectedRows = true; 00043 00044 var $binmode = DB2_BINARY; 00045 00046 var $useFetchArray = false; // setting this to true will make array elements in FETCH_ASSOC mode case-sensitive 00047 // breaking backward-compat 00048 var $_bindInputArray = false; 00049 var $_genIDSQL = "VALUES NEXTVAL FOR %s"; 00050 var $_genSeqSQL = "CREATE SEQUENCE %s START WITH %s NO MAXVALUE NO CYCLE"; 00051 var $_dropSeqSQL = "DROP SEQUENCE %s"; 00052 var $_autocommit = true; 00053 var $_haserrorfunctions = true; 00054 var $_lastAffectedRows = 0; 00055 var $uCaseTables = true; // for meta* functions, uppercase table names 00056 var $hasInsertID = true; 00057 00058 00059 function _insertid() 00060 { 00061 return ADOConnection::GetOne('VALUES IDENTITY_VAL_LOCAL()'); 00062 } 00063 00064 function ADODB_db2() 00065 { 00066 $this->_haserrorfunctions = ADODB_PHPVER >= 0x4050; 00067 } 00068 00069 // returns true or false 00070 function _connect($argDSN, $argUsername, $argPassword, $argDatabasename) 00071 { 00072 global $php_errormsg; 00073 00074 if (!function_exists('db2_connect')) { 00075 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."); 00076 return null; 00077 } 00078 // This needs to be set before the connect(). 00079 // Replaces the odbc_binmode() call that was in Execute() 00080 ini_set('ibm_db2.binmode', $this->binmode); 00081 00082 if ($argDatabasename && empty($argDSN)) { 00083 00084 if (stripos($argDatabasename,'UID=') && stripos($argDatabasename,'PWD=')) $this->_connectionID = db2_connect($argDatabasename,null,null); 00085 else $this->_connectionID = db2_connect($argDatabasename,$argUsername,$argPassword); 00086 } else { 00087 if ($argDatabasename) $schema = $argDatabasename; 00088 if (stripos($argDSN,'UID=') && stripos($argDSN,'PWD=')) $this->_connectionID = db2_connect($argDSN,null,null); 00089 else $this->_connectionID = db2_connect($argDSN,$argUsername,$argPassword); 00090 } 00091 if (isset($php_errormsg)) $php_errormsg = ''; 00092 00093 // For db2_connect(), there is an optional 4th arg. If present, it must be 00094 // an array of valid options. So far, we don't use them. 00095 00096 $this->_errorMsg = @db2_conn_errormsg(); 00097 if (isset($this->connectStmt)) $this->Execute($this->connectStmt); 00098 00099 if ($this->_connectionID && isset($schema)) $this->Execute("SET SCHEMA=$schema"); 00100 return $this->_connectionID != false; 00101 } 00102 00103 // returns true or false 00104 function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename) 00105 { 00106 global $php_errormsg; 00107 00108 if (!function_exists('db2_connect')) return null; 00109 00110 // This needs to be set before the connect(). 00111 // Replaces the odbc_binmode() call that was in Execute() 00112 ini_set('ibm_db2.binmode', $this->binmode); 00113 00114 if (isset($php_errormsg)) $php_errormsg = ''; 00115 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 00116 00117 if ($argDatabasename && empty($argDSN)) { 00118 00119 if (stripos($argDatabasename,'UID=') && stripos($argDatabasename,'PWD=')) $this->_connectionID = db2_pconnect($argDatabasename,null,null); 00120 else $this->_connectionID = db2_pconnect($argDatabasename,$argUsername,$argPassword); 00121 } else { 00122 if ($argDatabasename) $schema = $argDatabasename; 00123 if (stripos($argDSN,'UID=') && stripos($argDSN,'PWD=')) $this->_connectionID = db2_pconnect($argDSN,null,null); 00124 else $this->_connectionID = db2_pconnect($argDSN,$argUsername,$argPassword); 00125 } 00126 if (isset($php_errormsg)) $php_errormsg = ''; 00127 00128 $this->_errorMsg = @db2_conn_errormsg(); 00129 if ($this->_connectionID && $this->autoRollback) @db2_rollback($this->_connectionID); 00130 if (isset($this->connectStmt)) $this->Execute($this->connectStmt); 00131 00132 if ($this->_connectionID && isset($schema)) $this->Execute("SET SCHEMA=$schema"); 00133 return $this->_connectionID != false; 00134 } 00135 00136 // format and return date string in database timestamp format 00137 function DBTimeStamp($ts) 00138 { 00139 if (empty($ts) && $ts !== 0) return 'null'; 00140 if (is_string($ts)) $ts = ADORecordSet::UnixTimeStamp($ts); 00141 return 'TO_DATE('.adodb_date($this->fmtTimeStamp,$ts).",'YYYY-MM-DD HH24:MI:SS')"; 00142 } 00143 00144 // Format date column in sql string given an input format that understands Y M D 00145 function SQLDate($fmt, $col=false) 00146 { 00147 // use right() and replace() ? 00148 if (!$col) $col = $this->sysDate; 00149 00150 /* use TO_CHAR() if $fmt is TO_CHAR() allowed fmt */ 00151 if ($fmt== 'Y-m-d H:i:s') 00152 return 'TO_CHAR('.$col.", 'YYYY-MM-DD HH24:MI:SS')"; 00153 00154 $s = ''; 00155 00156 $len = strlen($fmt); 00157 for ($i=0; $i < $len; $i++) { 00158 if ($s) $s .= $this->concat_operator; 00159 $ch = $fmt[$i]; 00160 switch($ch) { 00161 case 'Y': 00162 case 'y': 00163 if ($len==1) return "year($col)"; 00164 $s .= "char(year($col))"; 00165 break; 00166 case 'M': 00167 if ($len==1) return "monthname($col)"; 00168 $s .= "substr(monthname($col),1,3)"; 00169 break; 00170 case 'm': 00171 if ($len==1) return "month($col)"; 00172 $s .= "right(digits(month($col)),2)"; 00173 break; 00174 case 'D': 00175 case 'd': 00176 if ($len==1) return "day($col)"; 00177 $s .= "right(digits(day($col)),2)"; 00178 break; 00179 case 'H': 00180 case 'h': 00181 if ($len==1) return "hour($col)"; 00182 if ($col != $this->sysDate) $s .= "right(digits(hour($col)),2)"; 00183 else $s .= "''"; 00184 break; 00185 case 'i': 00186 case 'I': 00187 if ($len==1) return "minute($col)"; 00188 if ($col != $this->sysDate) 00189 $s .= "right(digits(minute($col)),2)"; 00190 else $s .= "''"; 00191 break; 00192 case 'S': 00193 case 's': 00194 if ($len==1) return "second($col)"; 00195 if ($col != $this->sysDate) 00196 $s .= "right(digits(second($col)),2)"; 00197 else $s .= "''"; 00198 break; 00199 default: 00200 if ($ch == '\\') { 00201 $i++; 00202 $ch = substr($fmt,$i,1); 00203 } 00204 $s .= $this->qstr($ch); 00205 } 00206 } 00207 return $s; 00208 } 00209 00210 00211 function ServerInfo() 00212 { 00213 $row = $this->GetRow("SELECT service_level, fixpack_num FROM TABLE(sysproc.env_get_inst_info()) 00214 as INSTANCEINFO"); 00215 00216 00217 if ($row) { 00218 $info['version'] = $row[0].':'.$row[1]; 00219 $info['fixpack'] = $row[1]; 00220 $info['description'] = ''; 00221 } else { 00222 return ADOConnection::ServerInfo(); 00223 } 00224 00225 return $info; 00226 } 00227 00228 function CreateSequence($seqname='adodbseq',$start=1) 00229 { 00230 if (empty($this->_genSeqSQL)) return false; 00231 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$start)); 00232 if (!$ok) return false; 00233 return true; 00234 } 00235 00236 function DropSequence($seqname) 00237 { 00238 if (empty($this->_dropSeqSQL)) return false; 00239 return $this->Execute(sprintf($this->_dropSeqSQL,$seqname)); 00240 } 00241 00242 function SelectLimit($sql,$nrows=-1,$offset=-1,$inputArr=false) 00243 { 00244 $nrows = (integer) $nrows; 00245 if ($offset <= 0) { 00246 // could also use " OPTIMIZE FOR $nrows ROWS " 00247 if ($nrows >= 0) $sql .= " FETCH FIRST $nrows ROWS ONLY "; 00248 $rs = $this->Execute($sql,$inputArr); 00249 } else { 00250 if ($offset > 0 && $nrows < 0); 00251 else { 00252 $nrows += $offset; 00253 $sql .= " FETCH FIRST $nrows ROWS ONLY "; 00254 } 00255 $rs = ADOConnection::SelectLimit($sql,-1,$offset,$inputArr); 00256 } 00257 00258 return $rs; 00259 } 00260 00261 /* 00262 This algorithm is not very efficient, but works even if table locking 00263 is not available. 00264 00265 Will return false if unable to generate an ID after $MAXLOOPS attempts. 00266 */ 00267 function GenID($seq='adodbseq',$start=1) 00268 { 00269 // if you have to modify the parameter below, your database is overloaded, 00270 // or you need to implement generation of id's yourself! 00271 $num = $this->GetOne("VALUES NEXTVAL FOR $seq"); 00272 return $num; 00273 } 00274 00275 00276 function ErrorMsg() 00277 { 00278 if ($this->_haserrorfunctions) { 00279 if ($this->_errorMsg !== false) return $this->_errorMsg; 00280 if (empty($this->_connectionID)) return @db2_conn_errormsg(); 00281 return @db2_conn_errormsg($this->_connectionID); 00282 } else return ADOConnection::ErrorMsg(); 00283 } 00284 00285 function ErrorNo() 00286 { 00287 00288 if ($this->_haserrorfunctions) { 00289 if ($this->_errorCode !== false) { 00290 // bug in 4.0.6, error number can be corrupted string (should be 6 digits) 00291 return (strlen($this->_errorCode)<=2) ? 0 : $this->_errorCode; 00292 } 00293 00294 if (empty($this->_connectionID)) $e = @db2_conn_error(); 00295 else $e = @db2_conn_error($this->_connectionID); 00296 00297 // bug in 4.0.6, error number can be corrupted string (should be 6 digits) 00298 // so we check and patch 00299 if (strlen($e)<=2) return 0; 00300 return $e; 00301 } else return ADOConnection::ErrorNo(); 00302 } 00303 00304 00305 00306 function BeginTrans() 00307 { 00308 if (!$this->hasTransactions) return false; 00309 if ($this->transOff) return true; 00310 $this->transCnt += 1; 00311 $this->_autocommit = false; 00312 return db2_autocommit($this->_connectionID,false); 00313 } 00314 00315 function CommitTrans($ok=true) 00316 { 00317 if ($this->transOff) return true; 00318 if (!$ok) return $this->RollbackTrans(); 00319 if ($this->transCnt) $this->transCnt -= 1; 00320 $this->_autocommit = true; 00321 $ret = db2_commit($this->_connectionID); 00322 db2_autocommit($this->_connectionID,true); 00323 return $ret; 00324 } 00325 00326 function RollbackTrans() 00327 { 00328 if ($this->transOff) return true; 00329 if ($this->transCnt) $this->transCnt -= 1; 00330 $this->_autocommit = true; 00331 $ret = db2_rollback($this->_connectionID); 00332 db2_autocommit($this->_connectionID,true); 00333 return $ret; 00334 } 00335 00336 function MetaPrimaryKeys($table) 00337 { 00338 global $ADODB_FETCH_MODE; 00339 00340 if ($this->uCaseTables) $table = strtoupper($table); 00341 $schema = ''; 00342 $this->_findschema($table,$schema); 00343 00344 $savem = $ADODB_FETCH_MODE; 00345 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00346 $qid = @db2_primarykeys($this->_connectionID,'',$schema,$table); 00347 00348 if (!$qid) { 00349 $ADODB_FETCH_MODE = $savem; 00350 return false; 00351 } 00352 $rs = new ADORecordSet_db2($qid); 00353 $ADODB_FETCH_MODE = $savem; 00354 00355 if (!$rs) return false; 00356 00357 $arr = $rs->GetArray(); 00358 $rs->Close(); 00359 $arr2 = array(); 00360 for ($i=0; $i < sizeof($arr); $i++) { 00361 if ($arr[$i][3]) $arr2[] = $arr[$i][3]; 00362 } 00363 return $arr2; 00364 } 00365 00366 function MetaForeignKeys($table, $owner = FALSE, $upper = FALSE, $asociative = FALSE ) 00367 { 00368 global $ADODB_FETCH_MODE; 00369 00370 if ($this->uCaseTables) $table = strtoupper($table); 00371 $schema = ''; 00372 $this->_findschema($table,$schema); 00373 00374 $savem = $ADODB_FETCH_MODE; 00375 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00376 $qid = @db2_foreign_keys($this->_connectionID,'',$schema,$table); 00377 if (!$qid) { 00378 $ADODB_FETCH_MODE = $savem; 00379 return false; 00380 } 00381 $rs = new ADORecordSet_db2($qid); 00382 00383 $ADODB_FETCH_MODE = $savem; 00384 /* 00385 $rs->fields indices 00386 0 PKTABLE_CAT 00387 1 PKTABLE_SCHEM 00388 2 PKTABLE_NAME 00389 3 PKCOLUMN_NAME 00390 4 FKTABLE_CAT 00391 5 FKTABLE_SCHEM 00392 6 FKTABLE_NAME 00393 7 FKCOLUMN_NAME 00394 */ 00395 if (!$rs) return false; 00396 00397 $foreign_keys = array(); 00398 while (!$rs->EOF) { 00399 if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) { 00400 if (!is_array($foreign_keys[$rs->fields[5].'.'.$rs->fields[6]])) 00401 $foreign_keys[$rs->fields[5].'.'.$rs->fields[6]] = array(); 00402 $foreign_keys[$rs->fields[5].'.'.$rs->fields[6]][$rs->fields[7]] = $rs->fields[3]; 00403 } 00404 $rs->MoveNext(); 00405 } 00406 00407 $rs->Close(); 00408 return $foreign_key; 00409 } 00410 00411 00412 function MetaTables($ttype=false,$schema=false) 00413 { 00414 global $ADODB_FETCH_MODE; 00415 00416 $savem = $ADODB_FETCH_MODE; 00417 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00418 $qid = db2_tables($this->_connectionID); 00419 00420 $rs = new ADORecordSet_db2($qid); 00421 00422 $ADODB_FETCH_MODE = $savem; 00423 if (!$rs) { 00424 $false = false; 00425 return $false; 00426 } 00427 00428 $arr = $rs->GetArray(); 00429 $rs->Close(); 00430 $arr2 = array(); 00431 00432 if ($ttype) { 00433 $isview = strncmp($ttype,'V',1) === 0; 00434 } 00435 for ($i=0; $i < sizeof($arr); $i++) { 00436 if (!$arr[$i][2]) continue; 00437 $type = $arr[$i][3]; 00438 $owner = $arr[$i][1]; 00439 $schemaval = ($schema) ? $arr[$i][1].'.' : ''; 00440 if ($ttype) { 00441 if ($isview) { 00442 if (strncmp($type,'V',1) === 0) $arr2[] = $schemaval.$arr[$i][2]; 00443 } else if (strncmp($owner,'SYS',3) !== 0) $arr2[] = $schemaval.$arr[$i][2]; 00444 } else if (strncmp($owner,'SYS',3) !== 0) $arr2[] = $schemaval.$arr[$i][2]; 00445 } 00446 return $arr2; 00447 } 00448 00449 /* 00450 See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2datetime_data_type_changes.asp 00451 / SQL data type codes / 00452 #define SQL_UNKNOWN_TYPE 0 00453 #define SQL_CHAR 1 00454 #define SQL_NUMERIC 2 00455 #define SQL_DECIMAL 3 00456 #define SQL_INTEGER 4 00457 #define SQL_SMALLINT 5 00458 #define SQL_FLOAT 6 00459 #define SQL_REAL 7 00460 #define SQL_DOUBLE 8 00461 #if (DB2VER >= 0x0300) 00462 #define SQL_DATETIME 9 00463 #endif 00464 #define SQL_VARCHAR 12 00465 00466 00467 / One-parameter shortcuts for date/time data types / 00468 #if (DB2VER >= 0x0300) 00469 #define SQL_TYPE_DATE 91 00470 #define SQL_TYPE_TIME 92 00471 #define SQL_TYPE_TIMESTAMP 93 00472 00473 #define SQL_UNICODE (-95) 00474 #define SQL_UNICODE_VARCHAR (-96) 00475 #define SQL_UNICODE_LONGVARCHAR (-97) 00476 */ 00477 function DB2Types($t) 00478 { 00479 switch ((integer)$t) { 00480 case 1: 00481 case 12: 00482 case 0: 00483 case -95: 00484 case -96: 00485 return 'C'; 00486 case -97: 00487 case -1: //text 00488 return 'X'; 00489 case -4: //image 00490 return 'B'; 00491 00492 case 9: 00493 case 91: 00494 return 'D'; 00495 00496 case 10: 00497 case 11: 00498 case 92: 00499 case 93: 00500 return 'T'; 00501 00502 case 4: 00503 case 5: 00504 case -6: 00505 return 'I'; 00506 00507 case -11: // uniqidentifier 00508 return 'R'; 00509 case -7: //bit 00510 return 'L'; 00511 00512 default: 00513 return 'N'; 00514 } 00515 } 00516 00517 function MetaColumns($table, $normalize=true) 00518 { 00519 global $ADODB_FETCH_MODE; 00520 00521 $false = false; 00522 if ($this->uCaseTables) $table = strtoupper($table); 00523 $schema = ''; 00524 $this->_findschema($table,$schema); 00525 00526 $savem = $ADODB_FETCH_MODE; 00527 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00528 00529 $colname = "%"; 00530 $qid = db2_columns($this->_connectionID, "", $schema, $table, $colname); 00531 if (empty($qid)) return $false; 00532 00533 $rs = new ADORecordSet_db2($qid); 00534 $ADODB_FETCH_MODE = $savem; 00535 00536 if (!$rs) return $false; 00537 $rs->_fetch(); 00538 00539 $retarr = array(); 00540 00541 /* 00542 $rs->fields indices 00543 0 TABLE_QUALIFIER 00544 1 TABLE_SCHEM 00545 2 TABLE_NAME 00546 3 COLUMN_NAME 00547 4 DATA_TYPE 00548 5 TYPE_NAME 00549 6 PRECISION 00550 7 LENGTH 00551 8 SCALE 00552 9 RADIX 00553 10 NULLABLE 00554 11 REMARKS 00555 */ 00556 while (!$rs->EOF) { 00557 if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) { 00558 $fld = new ADOFieldObject(); 00559 $fld->name = $rs->fields[3]; 00560 $fld->type = $this->DB2Types($rs->fields[4]); 00561 00562 // ref: http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp 00563 // access uses precision to store length for char/varchar 00564 if ($fld->type == 'C' or $fld->type == 'X') { 00565 if ($rs->fields[4] <= -95) // UNICODE 00566 $fld->max_length = $rs->fields[7]/2; 00567 else 00568 $fld->max_length = $rs->fields[7]; 00569 } else 00570 $fld->max_length = $rs->fields[7]; 00571 $fld->not_null = !empty($rs->fields[10]); 00572 $fld->scale = $rs->fields[8]; 00573 $fld->primary_key = false; 00574 $retarr[strtoupper($fld->name)] = $fld; 00575 } else if (sizeof($retarr)>0) 00576 break; 00577 $rs->MoveNext(); 00578 } 00579 $rs->Close(); 00580 if (empty($retarr)) $retarr = false; 00581 00582 $qid = db2_primary_keys($this->_connectionID, "", $schema, $table); 00583 if (empty($qid)) return $false; 00584 00585 $rs = new ADORecordSet_db2($qid); 00586 $ADODB_FETCH_MODE = $savem; 00587 00588 if (!$rs) return $retarr; 00589 $rs->_fetch(); 00590 00591 /* 00592 $rs->fields indices 00593 0 TABLE_CAT 00594 1 TABLE_SCHEM 00595 2 TABLE_NAME 00596 3 COLUMN_NAME 00597 4 KEY_SEQ 00598 5 PK_NAME 00599 */ 00600 while (!$rs->EOF) { 00601 if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) { 00602 $retarr[strtoupper($rs->fields[3])]->primary_key = true; 00603 } else if (sizeof($retarr)>0) 00604 break; 00605 $rs->MoveNext(); 00606 } 00607 $rs->Close(); 00608 00609 if (empty($retarr)) $retarr = false; 00610 return $retarr; 00611 } 00612 00613 00614 function Prepare($sql) 00615 { 00616 if (! $this->_bindInputArray) return $sql; // no binding 00617 $stmt = db2_prepare($this->_connectionID,$sql); 00618 if (!$stmt) { 00619 // we don't know whether db2 driver is parsing prepared stmts, so just return sql 00620 return $sql; 00621 } 00622 return array($sql,$stmt,false); 00623 } 00624 00625 /* returns queryID or false */ 00626 function _query($sql,$inputarr=false) 00627 { 00628 GLOBAL $php_errormsg; 00629 if (isset($php_errormsg)) $php_errormsg = ''; 00630 $this->_error = ''; 00631 00632 if ($inputarr) { 00633 if (is_array($sql)) { 00634 $stmtid = $sql[1]; 00635 } else { 00636 $stmtid = db2_prepare($this->_connectionID,$sql); 00637 00638 if ($stmtid == false) { 00639 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 00640 return false; 00641 } 00642 } 00643 00644 if (! db2_execute($stmtid,$inputarr)) { 00645 if ($this->_haserrorfunctions) { 00646 $this->_errorMsg = db2_stmt_errormsg(); 00647 $this->_errorCode = db2_stmt_error(); 00648 } 00649 return false; 00650 } 00651 00652 } else if (is_array($sql)) { 00653 $stmtid = $sql[1]; 00654 if (!db2_execute($stmtid)) { 00655 if ($this->_haserrorfunctions) { 00656 $this->_errorMsg = db2_stmt_errormsg(); 00657 $this->_errorCode = db2_stmt_error(); 00658 } 00659 return false; 00660 } 00661 } else 00662 $stmtid = @db2_exec($this->_connectionID,$sql); 00663 00664 $this->_lastAffectedRows = 0; 00665 if ($stmtid) { 00666 if (@db2_num_fields($stmtid) == 0) { 00667 $this->_lastAffectedRows = db2_num_rows($stmtid); 00668 $stmtid = true; 00669 } else { 00670 $this->_lastAffectedRows = 0; 00671 } 00672 00673 if ($this->_haserrorfunctions) { 00674 $this->_errorMsg = ''; 00675 $this->_errorCode = 0; 00676 } else 00677 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 00678 } else { 00679 if ($this->_haserrorfunctions) { 00680 $this->_errorMsg = db2_stmt_errormsg(); 00681 $this->_errorCode = db2_stmt_error(); 00682 } else 00683 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 00684 00685 } 00686 return $stmtid; 00687 } 00688 00689 /* 00690 Insert a null into the blob field of the table first. 00691 Then use UpdateBlob to store the blob. 00692 00693 Usage: 00694 00695 $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)'); 00696 $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1'); 00697 */ 00698 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB') 00699 { 00700 return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false; 00701 } 00702 00703 // returns true or false 00704 function _close() 00705 { 00706 $ret = @db2_close($this->_connectionID); 00707 $this->_connectionID = false; 00708 return $ret; 00709 } 00710 00711 function _affectedrows() 00712 { 00713 return $this->_lastAffectedRows; 00714 } 00715 00716 } 00717 00718 /*-------------------------------------------------------------------------------------- 00719 Class Name: Recordset 00720 --------------------------------------------------------------------------------------*/ 00721 00722 class ADORecordSet_db2 extends ADORecordSet { 00723 00724 var $bind = false; 00725 var $databaseType = "db2"; 00726 var $dataProvider = "db2"; 00727 var $useFetchArray; 00728 00729 function ADORecordSet_db2($id,$mode=false) 00730 { 00731 if ($mode === false) { 00732 global $ADODB_FETCH_MODE; 00733 $mode = $ADODB_FETCH_MODE; 00734 } 00735 $this->fetchMode = $mode; 00736 00737 $this->_queryID = $id; 00738 } 00739 00740 00741 // returns the field object 00742 function FetchField($offset = -1) 00743 { 00744 $o= new ADOFieldObject(); 00745 $o->name = @db2_field_name($this->_queryID,$offset); 00746 $o->type = @db2_field_type($this->_queryID,$offset); 00747 $o->max_length = db2_field_width($this->_queryID,$offset); 00748 if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name); 00749 else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name); 00750 return $o; 00751 } 00752 00753 /* Use associative array to get fields array */ 00754 function Fields($colname) 00755 { 00756 if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname]; 00757 if (!$this->bind) { 00758 $this->bind = array(); 00759 for ($i=0; $i < $this->_numOfFields; $i++) { 00760 $o = $this->FetchField($i); 00761 $this->bind[strtoupper($o->name)] = $i; 00762 } 00763 } 00764 00765 return $this->fields[$this->bind[strtoupper($colname)]]; 00766 } 00767 00768 00769 function _initrs() 00770 { 00771 global $ADODB_COUNTRECS; 00772 $this->_numOfRows = ($ADODB_COUNTRECS) ? @db2_num_rows($this->_queryID) : -1; 00773 $this->_numOfFields = @db2_num_fields($this->_queryID); 00774 // some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0 00775 if ($this->_numOfRows == 0) $this->_numOfRows = -1; 00776 } 00777 00778 function _seek($row) 00779 { 00780 return false; 00781 } 00782 00783 // speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated 00784 function GetArrayLimit($nrows,$offset=-1) 00785 { 00786 if ($offset <= 0) { 00787 $rs = $this->GetArray($nrows); 00788 return $rs; 00789 } 00790 $savem = $this->fetchMode; 00791 $this->fetchMode = ADODB_FETCH_NUM; 00792 $this->Move($offset); 00793 $this->fetchMode = $savem; 00794 00795 if ($this->fetchMode & ADODB_FETCH_ASSOC) { 00796 $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE); 00797 } 00798 00799 $results = array(); 00800 $cnt = 0; 00801 while (!$this->EOF && $nrows != $cnt) { 00802 $results[$cnt++] = $this->fields; 00803 $this->MoveNext(); 00804 } 00805 00806 return $results; 00807 } 00808 00809 00810 function MoveNext() 00811 { 00812 if ($this->_numOfRows != 0 && !$this->EOF) { 00813 $this->_currentRow++; 00814 00815 $this->fields = @db2_fetch_array($this->_queryID); 00816 if ($this->fields) { 00817 if ($this->fetchMode & ADODB_FETCH_ASSOC) { 00818 $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE); 00819 } 00820 return true; 00821 } 00822 } 00823 $this->fields = false; 00824 $this->EOF = true; 00825 return false; 00826 } 00827 00828 function _fetch() 00829 { 00830 00831 $this->fields = db2_fetch_array($this->_queryID); 00832 if ($this->fields) { 00833 if ($this->fetchMode & ADODB_FETCH_ASSOC) { 00834 $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE); 00835 } 00836 return true; 00837 } 00838 $this->fields = false; 00839 return false; 00840 } 00841 00842 function _close() 00843 { 00844 return @db2_free_result($this->_queryID); 00845 } 00846 00847 } 00848 ?>