00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 if (!defined('ADODB_DIR')) die();
00018
00019 define("_ADODB_DB2_LAYER", 2 );
00020
00021
00022
00023
00024
00025 class ADODB_db2 extends ADOConnection {
00026 var $databaseType = "db2";
00027 var $fmtDate = "'Y-m-d'";
00028 var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
00029 var $replaceQuote = "''";
00030 var $dataProvider = "db2";
00031 var $hasAffectedRows = true;
00032
00033 var $binmode = DB2_BINARY;
00034
00035 var $useFetchArray = false;
00036
00037 var $_bindInputArray = false;
00038 var $_genSeqSQL = "create table %s (id integer)";
00039 var $_autocommit = true;
00040 var $_haserrorfunctions = true;
00041 var $_lastAffectedRows = 0;
00042 var $uCaseTables = true;
00043
00044 function ADODB_db2()
00045 {
00046 $this->_haserrorfunctions = ADODB_PHPVER >= 0x4050;
00047 }
00048
00049
00050 function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
00051 {
00052 global $php_errormsg;
00053
00054 if (!function_exists('db2_connect')) {
00055 ADOConnection::outp("Warning: The old ODBC based DB2 driver has been renamed 'odbc_db2'. This ADOdb driver calls PHP's native db2 extension.");
00056 return null;
00057 }
00058
00059
00060 ini_set('ibm_db2.binmode', $this->binmode);
00061
00062 if ($argDatabasename) {
00063 $this->_connectionID = db2_connect($argDatabasename,$argUsername,$argPassword);
00064 } else {
00065 $this->_connectionID = db2_connect($argDSN,$argUsername,$argPassword);
00066 }
00067 if (isset($php_errormsg)) $php_errormsg = '';
00068
00069
00070
00071
00072 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
00073 if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
00074
00075 return $this->_connectionID != false;
00076 }
00077
00078
00079 function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
00080 {
00081 global $php_errormsg;
00082
00083 if (!function_exists('db2_connect')) return null;
00084
00085
00086
00087 ini_set('ibm_db2.binmode', $this->binmode);
00088
00089 if (isset($php_errormsg)) $php_errormsg = '';
00090 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
00091
00092 if ($argDatabasename) {
00093 $this->_connectionID = db2_pconnect($argDatabasename,$argUsername,$argPassword);
00094 } else {
00095 $this->_connectionID = db2_pconnect($argDSN,$argUsername,$argPassword);
00096 }
00097 if (isset($php_errormsg)) $php_errormsg = '';
00098
00099 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
00100 if ($this->_connectionID && $this->autoRollback) @db2_rollback($this->_connectionID);
00101 if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
00102
00103 return $this->_connectionID != false;
00104 }
00105
00106
00107 function ServerInfo()
00108 {
00109
00110 if (!empty($this->host) && ADODB_PHPVER >= 0x4300) {
00111 $dsn = strtoupper($this->host);
00112 $first = true;
00113 $found = false;
00114
00115 if (!function_exists('db2_data_source')) return false;
00116
00117 while(true) {
00118
00119 $rez = @db2_data_source($this->_connectionID,
00120 $first ? SQL_FETCH_FIRST : SQL_FETCH_NEXT);
00121 $first = false;
00122 if (!is_array($rez)) break;
00123 if (strtoupper($rez['server']) == $dsn) {
00124 $found = true;
00125 break;
00126 }
00127 }
00128 if (!$found) return ADOConnection::ServerInfo();
00129 if (!isset($rez['version'])) $rez['version'] = '';
00130 return $rez;
00131 } else {
00132 return ADOConnection::ServerInfo();
00133 }
00134 }
00135
00136
00137 function CreateSequence($seqname='adodbseq',$start=1)
00138 {
00139 if (empty($this->_genSeqSQL)) return false;
00140 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
00141 if (!$ok) return false;
00142 $start -= 1;
00143 return $this->Execute("insert into $seqname values($start)");
00144 }
00145
00146 var $_dropSeqSQL = 'drop table %s';
00147 function DropSequence($seqname)
00148 {
00149 if (empty($this->_dropSeqSQL)) return false;
00150 return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
00151 }
00152
00153
00154
00155
00156
00157
00158
00159 function GenID($seq='adodbseq',$start=1)
00160 {
00161
00162
00163 $MAXLOOPS = 100;
00164 while (--$MAXLOOPS>=0) {
00165 $num = $this->GetOne("select id from $seq");
00166 if ($num === false) {
00167 $this->Execute(sprintf($this->_genSeqSQL ,$seq));
00168 $start -= 1;
00169 $num = '0';
00170 $ok = $this->Execute("insert into $seq values($start)");
00171 if (!$ok) return false;
00172 }
00173 $this->Execute("update $seq set id=id+1 where id=$num");
00174
00175 if ($this->affected_rows() > 0) {
00176 $num += 1;
00177 $this->genID = $num;
00178 return $num;
00179 }
00180 }
00181 if ($fn = $this->raiseErrorFn) {
00182 $fn($this->databaseType,'GENID',-32000,"Unable to generate unique id after $MAXLOOPS attempts",$seq,$num);
00183 }
00184 return false;
00185 }
00186
00187
00188 function ErrorMsg()
00189 {
00190 if ($this->_haserrorfunctions) {
00191 if ($this->_errorMsg !== false) return $this->_errorMsg;
00192 if (empty($this->_connectionID)) return @db2_errormsg();
00193 return @db2_errormsg($this->_connectionID);
00194 } else return ADOConnection::ErrorMsg();
00195 }
00196
00197 function ErrorNo()
00198 {
00199
00200 if ($this->_haserrorfunctions) {
00201 if ($this->_errorCode !== false) {
00202
00203 return (strlen($this->_errorCode)<=2) ? 0 : $this->_errorCode;
00204 }
00205
00206 if (empty($this->_connectionID)) $e = @db2_error();
00207 else $e = @db2_error($this->_connectionID);
00208
00209
00210
00211 if (strlen($e)<=2) return 0;
00212 return $e;
00213 } else return ADOConnection::ErrorNo();
00214 }
00215
00216
00217
00218 function BeginTrans()
00219 {
00220 if (!$this->hasTransactions) return false;
00221 if ($this->transOff) return true;
00222 $this->transCnt += 1;
00223 $this->_autocommit = false;
00224 return db2_autocommit($this->_connectionID,false);
00225 }
00226
00227 function CommitTrans($ok=true)
00228 {
00229 if ($this->transOff) return true;
00230 if (!$ok) return $this->RollbackTrans();
00231 if ($this->transCnt) $this->transCnt -= 1;
00232 $this->_autocommit = true;
00233 $ret = db2_commit($this->_connectionID);
00234 db2_autocommit($this->_connectionID,true);
00235 return $ret;
00236 }
00237
00238 function RollbackTrans()
00239 {
00240 if ($this->transOff) return true;
00241 if ($this->transCnt) $this->transCnt -= 1;
00242 $this->_autocommit = true;
00243 $ret = db2_rollback($this->_connectionID);
00244 db2_autocommit($this->_connectionID,true);
00245 return $ret;
00246 }
00247
00248 function MetaPrimaryKeys($table)
00249 {
00250 global $ADODB_FETCH_MODE;
00251
00252 if ($this->uCaseTables) $table = strtoupper($table);
00253 $schema = '';
00254 $this->_findschema($table,$schema);
00255
00256 $savem = $ADODB_FETCH_MODE;
00257 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00258 $qid = @db2_primarykeys($this->_connectionID,'',$schema,$table);
00259
00260 if (!$qid) {
00261 $ADODB_FETCH_MODE = $savem;
00262 return false;
00263 }
00264 $rs = new ADORecordSet_db2($qid);
00265 $ADODB_FETCH_MODE = $savem;
00266
00267 if (!$rs) return false;
00268
00269 $arr =& $rs->GetArray();
00270 $rs->Close();
00271 $arr2 = array();
00272 for ($i=0; $i < sizeof($arr); $i++) {
00273 if ($arr[$i][3]) $arr2[] = $arr[$i][3];
00274 }
00275 return $arr2;
00276 }
00277
00278
00279
00280 function &MetaTables($ttype=false)
00281 {
00282 global $ADODB_FETCH_MODE;
00283
00284 $savem = $ADODB_FETCH_MODE;
00285 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00286 $qid = db2_tables($this->_connectionID);
00287
00288 $rs = new ADORecordSet_db2($qid);
00289
00290 $ADODB_FETCH_MODE = $savem;
00291 if (!$rs) {
00292 $false = false;
00293 return $false;
00294 }
00295
00296 $arr =& $rs->GetArray();
00297
00298 $rs->Close();
00299 $arr2 = array();
00300
00301 if ($ttype) {
00302 $isview = strncmp($ttype,'V',1) === 0;
00303 }
00304 for ($i=0; $i < sizeof($arr); $i++) {
00305 if (!$arr[$i][2]) continue;
00306 $type = $arr[$i][3];
00307 if ($ttype) {
00308 if ($isview) {
00309 if (strncmp($type,'V',1) === 0) $arr2[] = $arr[$i][2];
00310 } else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2];
00311 } else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2];
00312 }
00313 return $arr2;
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 function DB2Types($t)
00345 {
00346 switch ((integer)$t) {
00347 case 1:
00348 case 12:
00349 case 0:
00350 case -95:
00351 case -96:
00352 return 'C';
00353 case -97:
00354 case -1:
00355 return 'X';
00356 case -4:
00357 return 'B';
00358
00359 case 9:
00360 case 91:
00361 return 'D';
00362
00363 case 10:
00364 case 11:
00365 case 92:
00366 case 93:
00367 return 'T';
00368
00369 case 4:
00370 case 5:
00371 case -6:
00372 return 'I';
00373
00374 case -11:
00375 return 'R';
00376 case -7:
00377 return 'L';
00378
00379 default:
00380 return 'N';
00381 }
00382 }
00383
00384 function &MetaColumns($table)
00385 {
00386 global $ADODB_FETCH_MODE;
00387
00388 $false = false;
00389 if ($this->uCaseTables) $table = strtoupper($table);
00390 $schema = '';
00391 $this->_findschema($table,$schema);
00392
00393 $savem = $ADODB_FETCH_MODE;
00394 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00395
00396 $colname = "%";
00397 $qid = db2_columns($this->_connectionID, "", $schema, $table, $colname);
00398 if (empty($qid)) return $false;
00399
00400 $rs =& new ADORecordSet_db2($qid);
00401 $ADODB_FETCH_MODE = $savem;
00402
00403 if (!$rs) return $false;
00404 $rs->_fetch();
00405
00406 $retarr = array();
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 while (!$rs->EOF) {
00424 if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
00425 $fld = new ADOFieldObject();
00426 $fld->name = $rs->fields[3];
00427 $fld->type = $this->DB2Types($rs->fields[4]);
00428
00429
00430
00431 if ($fld->type == 'C' or $fld->type == 'X') {
00432 if ($rs->fields[4] <= -95)
00433 $fld->max_length = $rs->fields[7]/2;
00434 else
00435 $fld->max_length = $rs->fields[7];
00436 } else
00437 $fld->max_length = $rs->fields[7];
00438 $fld->not_null = !empty($rs->fields[10]);
00439 $fld->scale = $rs->fields[8];
00440 $retarr[strtoupper($fld->name)] = $fld;
00441 } else if (sizeof($retarr)>0)
00442 break;
00443 $rs->MoveNext();
00444 }
00445 $rs->Close();
00446
00447 if (empty($retarr)) $retarr = false;
00448 return $retarr;
00449 }
00450
00451 function Prepare($sql)
00452 {
00453 if (! $this->_bindInputArray) return $sql;
00454 $stmt = db2_prepare($this->_connectionID,$sql);
00455 if (!$stmt) {
00456
00457 return $sql;
00458 }
00459 return array($sql,$stmt,false);
00460 }
00461
00462
00463 function _query($sql,$inputarr=false)
00464 {
00465 GLOBAL $php_errormsg;
00466 if (isset($php_errormsg)) $php_errormsg = '';
00467 $this->_error = '';
00468
00469 if ($inputarr) {
00470 if (is_array($sql)) {
00471 $stmtid = $sql[1];
00472 } else {
00473 $stmtid = db2_prepare($this->_connectionID,$sql);
00474
00475 if ($stmtid == false) {
00476 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
00477 return false;
00478 }
00479 }
00480
00481 if (! db2_execute($stmtid,$inputarr)) {
00482 if ($this->_haserrorfunctions) {
00483 $this->_errorMsg = db2_errormsg();
00484 $this->_errorCode = db2_error();
00485 }
00486 return false;
00487 }
00488
00489 } else if (is_array($sql)) {
00490 $stmtid = $sql[1];
00491 if (!db2_execute($stmtid)) {
00492 if ($this->_haserrorfunctions) {
00493 $this->_errorMsg = db2_errormsg();
00494 $this->_errorCode = db2_error();
00495 }
00496 return false;
00497 }
00498 } else
00499 $stmtid = db2_exec($this->_connectionID,$sql);
00500
00501 $this->_lastAffectedRows = 0;
00502 if ($stmtid) {
00503 if (@db2_num_fields($stmtid) == 0) {
00504 $this->_lastAffectedRows = db2_num_rows($stmtid);
00505 $stmtid = true;
00506 } else {
00507 $this->_lastAffectedRows = 0;
00508 }
00509
00510 if ($this->_haserrorfunctions) {
00511 $this->_errorMsg = '';
00512 $this->_errorCode = 0;
00513 } else
00514 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
00515 } else {
00516 if ($this->_haserrorfunctions) {
00517 $this->_errorMsg = db2_stmt_errormsg();
00518 $this->_errorCode = db2_stmt_error();
00519 } else
00520 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
00521 }
00522 return $stmtid;
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
00535 {
00536 return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false;
00537 }
00538
00539
00540 function _close()
00541 {
00542 $ret = @db2_close($this->_connectionID);
00543 $this->_connectionID = false;
00544 return $ret;
00545 }
00546
00547 function _affectedrows()
00548 {
00549 return $this->_lastAffectedRows;
00550 }
00551
00552 }
00553
00554
00555
00556
00557
00558 class ADORecordSet_db2 extends ADORecordSet {
00559
00560 var $bind = false;
00561 var $databaseType = "db2";
00562 var $dataProvider = "db2";
00563 var $useFetchArray;
00564
00565 function ADORecordSet_db2($id,$mode=false)
00566 {
00567 if ($mode === false) {
00568 global $ADODB_FETCH_MODE;
00569 $mode = $ADODB_FETCH_MODE;
00570 }
00571 $this->fetchMode = $mode;
00572
00573 $this->_queryID = $id;
00574 }
00575
00576
00577
00578 function &FetchField($fieldOffset = -1)
00579 {
00580
00581 $off=$fieldOffset+1;
00582
00583 $o= new ADOFieldObject();
00584 $o->name = @db2_field_name($this->_queryID,$off);
00585 $o->type = @db2_field_type($this->_queryID,$off);
00586 $o->max_length = db2_field_width($this->_queryID,$off);
00587 if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
00588 else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
00589 return $o;
00590 }
00591
00592
00593 function Fields($colname)
00594 {
00595 if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
00596 if (!$this->bind) {
00597 $this->bind = array();
00598 for ($i=0; $i < $this->_numOfFields; $i++) {
00599 $o = $this->FetchField($i);
00600 $this->bind[strtoupper($o->name)] = $i;
00601 }
00602 }
00603
00604 return $this->fields[$this->bind[strtoupper($colname)]];
00605 }
00606
00607
00608 function _initrs()
00609 {
00610 global $ADODB_COUNTRECS;
00611 $this->_numOfRows = ($ADODB_COUNTRECS) ? @db2_num_rows($this->_queryID) : -1;
00612 $this->_numOfFields = @db2_num_fields($this->_queryID);
00613
00614 if ($this->_numOfRows == 0) $this->_numOfRows = -1;
00615 }
00616
00617 function _seek($row)
00618 {
00619 return false;
00620 }
00621
00622
00623 function &GetArrayLimit($nrows,$offset=-1)
00624 {
00625 if ($offset <= 0) {
00626 $rs =& $this->GetArray($nrows);
00627 return $rs;
00628 }
00629 $savem = $this->fetchMode;
00630 $this->fetchMode = ADODB_FETCH_NUM;
00631 $this->Move($offset);
00632 $this->fetchMode = $savem;
00633
00634 if ($this->fetchMode & ADODB_FETCH_ASSOC) {
00635 $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
00636 }
00637
00638 $results = array();
00639 $cnt = 0;
00640 while (!$this->EOF && $nrows != $cnt) {
00641 $results[$cnt++] = $this->fields;
00642 $this->MoveNext();
00643 }
00644
00645 return $results;
00646 }
00647
00648
00649 function MoveNext()
00650 {
00651 if ($this->_numOfRows != 0 && !$this->EOF) {
00652 $this->_currentRow++;
00653
00654 $this->fields = @db2_fetch_array($this->_queryID);
00655 if ($this->fields) {
00656 if ($this->fetchMode & ADODB_FETCH_ASSOC) {
00657 $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
00658 }
00659 return true;
00660 }
00661 }
00662 $this->fields = false;
00663 $this->EOF = true;
00664 return false;
00665 }
00666
00667 function _fetch()
00668 {
00669
00670 $this->fields = db2_fetch_array($this->_queryID);
00671 if ($this->fields) {
00672 if ($this->fetchMode & ADODB_FETCH_ASSOC) {
00673 $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
00674 }
00675 return true;
00676 }
00677 $this->fields = false;
00678 return false;
00679 }
00680
00681 function _close()
00682 {
00683 return @db2_free_result($this->_queryID);
00684 }
00685
00686 }
00687 ?>