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