00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 if (!defined('ADODB_DIR')) die();
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 # define the LOB descriptor type for the given type
00042 # returns false if no LOB descriptor
00043 function oci_lob_desc($type) {
00044 switch ($type) {
00045 case OCI_B_BFILE: $result = OCI_D_FILE; break;
00046 case OCI_B_CFILEE: $result = OCI_D_FILE; break;
00047 case OCI_B_CLOB: $result = OCI_D_LOB; break;
00048 case OCI_B_BLOB: $result = OCI_D_LOB; break;
00049 case OCI_B_ROWID: $result = OCI_D_ROWID; break;
00050 default: $result = false; break;
00051 }
00052 return $result;
00053 }
00054
00055 class ADODB_oci8 extends ADOConnection {
00056 var $databaseType = 'oci8';
00057 var $dataProvider = 'oci8';
00058 var $replaceQuote = "''";
00059 var $concat_operator='||';
00060 var $sysDate = "TRUNC(SYSDATE)";
00061 var $sysTimeStamp = 'SYSDATE';
00062 var $metaDatabasesSQL = "SELECT USERNAME FROM ALL_USERS WHERE USERNAME NOT IN ('SYS','SYSTEM','DBSNMP','OUTLN') ORDER BY 1";
00063 var $_stmt;
00064 var $_commit = OCI_COMMIT_ON_SUCCESS;
00065 var $_initdate = true;
00066 var $metaTablesSQL = "select table_name,table_type from cat where table_type in ('TABLE','VIEW') and table_name not like 'BIN\$%'";
00067 var $metaColumnsSQL = "select cname,coltype,width, SCALE, PRECISION, NULLS, DEFAULTVAL from col where tname='%s' order by colno";
00068 var $_bindInputArray = true;
00069 var $hasGenID = true;
00070 var $_genIDSQL = "SELECT (%s.nextval) FROM DUAL";
00071 var $_genSeqSQL = "CREATE SEQUENCE %s START WITH %s";
00072 var $_dropSeqSQL = "DROP SEQUENCE %s";
00073 var $hasAffectedRows = true;
00074 var $random = "abs(mod(DBMS_RANDOM.RANDOM,10000001)/10000000)";
00075 var $noNullStrings = false;
00076 var $connectSID = false;
00077 var $_bind = false;
00078 var $_nestedSQL = true;
00079 var $_hasOCIFetchStatement = false;
00080 var $_getarray = false;
00081 var $leftOuter = '';
00082 var $session_sharing_force_blob = false;
00083 var $firstrows = true;
00084 var $selectOffsetAlg1 = 100;
00085 var $NLS_DATE_FORMAT = 'YYYY-MM-DD';
00086 var $useDBDateFormatForTextInput=false;
00087 var $datetime = false;
00088 var $_refLOBs = array();
00089
00090
00091
00092 function ADODB_oci8()
00093 {
00094 $this->_hasOCIFetchStatement = ADODB_PHPVER >= 0x4200;
00095 if (defined('ADODB_EXTENSION')) $this->rsPrefix .= 'ext_';
00096 }
00097
00098
00099 function &MetaColumns($table)
00100 {
00101 global $ADODB_FETCH_MODE;
00102
00103 $false = false;
00104 $save = $ADODB_FETCH_MODE;
00105 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00106 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
00107
00108 $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
00109
00110 if (isset($savem)) $this->SetFetchMode($savem);
00111 $ADODB_FETCH_MODE = $save;
00112 if (!$rs) {
00113 return $false;
00114 }
00115 $retarr = array();
00116 while (!$rs->EOF) {
00117 $fld = new ADOFieldObject();
00118 $fld->name = $rs->fields[0];
00119 $fld->type = $rs->fields[1];
00120 $fld->max_length = $rs->fields[2];
00121 $fld->scale = $rs->fields[3];
00122 if ($rs->fields[1] == 'NUMBER') {
00123 if ($rs->fields[3] == 0) $fld->type = 'INT';
00124 $fld->max_length = $rs->fields[4];
00125 }
00126 $fld->not_null = (strncmp($rs->fields[5], 'NOT',3) === 0);
00127 $fld->binary = (strpos($fld->type,'BLOB') !== false);
00128 $fld->default_value = $rs->fields[6];
00129
00130 if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
00131 else $retarr[strtoupper($fld->name)] = $fld;
00132 $rs->MoveNext();
00133 }
00134 $rs->Close();
00135 if (empty($retarr))
00136 return $false;
00137 else
00138 return $retarr;
00139 }
00140
00141 function Time()
00142 {
00143 $rs =& $this->Execute("select TO_CHAR($this->sysTimeStamp,'YYYY-MM-DD HH24:MI:SS') from dual");
00144 if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
00145
00146 return false;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$mode=0)
00184 {
00185 if (!function_exists('OCIPLogon')) return null;
00186
00187
00188 $this->_errorMsg = false;
00189 $this->_errorCode = false;
00190
00191 if($argHostname) {
00192 if (empty($argDatabasename)) $argDatabasename = $argHostname;
00193 else {
00194 if(strpos($argHostname,":")) {
00195 $argHostinfo=explode(":",$argHostname);
00196 $argHostname=$argHostinfo[0];
00197 $argHostport=$argHostinfo[1];
00198 } else {
00199 $argHostport = empty($this->port)? "1521" : $this->port;
00200 }
00201
00202 if ($this->connectSID) {
00203 $argDatabasename="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=".$argHostname
00204 .")(PORT=$argHostport))(CONNECT_DATA=(SID=$argDatabasename)))";
00205 } else
00206 $argDatabasename="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=".$argHostname
00207 .")(PORT=$argHostport))(CONNECT_DATA=(SERVICE_NAME=$argDatabasename)))";
00208 }
00209 }
00210
00211
00212 if ($mode==1) {
00213 $this->_connectionID = ($this->charSet) ?
00214 OCIPLogon($argUsername,$argPassword, $argDatabasename,$this->charSet)
00215 :
00216 OCIPLogon($argUsername,$argPassword, $argDatabasename)
00217 ;
00218 if ($this->_connectionID && $this->autoRollback) OCIrollback($this->_connectionID);
00219 } else if ($mode==2) {
00220 $this->_connectionID = ($this->charSet) ?
00221 OCINLogon($argUsername,$argPassword, $argDatabasename,$this->charSet)
00222 :
00223 OCINLogon($argUsername,$argPassword, $argDatabasename);
00224
00225 } else {
00226 $this->_connectionID = ($this->charSet) ?
00227 OCILogon($argUsername,$argPassword, $argDatabasename,$this->charSet)
00228 :
00229 OCILogon($argUsername,$argPassword, $argDatabasename);
00230 }
00231 if (!$this->_connectionID) return false;
00232 if ($this->_initdate) {
00233 $this->Execute("ALTER SESSION SET NLS_DATE_FORMAT='".$this->NLS_DATE_FORMAT."'");
00234 }
00235
00236
00237
00238
00239
00240 return true;
00241 }
00242
00243 function ServerInfo()
00244 {
00245 $arr['compat'] = $this->GetOne('select value from sys.database_compatible_level');
00246 $arr['description'] = @OCIServerVersion($this->_connectionID);
00247 $arr['version'] = ADOConnection::_findvers($arr['description']);
00248 return $arr;
00249 }
00250
00251 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
00252 {
00253 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,1);
00254 }
00255
00256
00257 function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
00258 {
00259 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,2);
00260 }
00261
00262 function _affectedrows()
00263 {
00264 if (is_resource($this->_stmt)) return @OCIRowCount($this->_stmt);
00265 return 0;
00266 }
00267
00268 function IfNull( $field, $ifNull )
00269 {
00270 return " NVL($field, $ifNull) ";
00271 }
00272
00273
00274 function DBDate($d)
00275 {
00276 if (empty($d) && $d !== 0) return 'null';
00277
00278 if (is_string($d)) $d = ADORecordSet::UnixDate($d);
00279 return "TO_DATE(".adodb_date($this->fmtDate,$d).",'".$this->NLS_DATE_FORMAT."')";
00280 }
00281
00282 function BindDate($d)
00283 {
00284 $d = ADOConnection::DBDate($d);
00285 if (strncmp($d,"'",1)) return $d;
00286
00287 return substr($d,1,strlen($d)-2);
00288 }
00289
00290 function BindTimeStamp($d)
00291 {
00292 $d = ADOConnection::DBTimeStamp($d);
00293 if (strncmp($d,"'",1)) return $d;
00294
00295 return substr($d,1,strlen($d)-2);
00296 }
00297
00298
00299 function DBTimeStamp($ts)
00300 {
00301 if (empty($ts) && $ts !== 0) return 'null';
00302 if (is_string($ts)) $ts = ADORecordSet::UnixTimeStamp($ts);
00303 return 'TO_DATE('.adodb_date($this->fmtTimeStamp,$ts).",'RRRR-MM-DD, HH:MI:SS AM')";
00304 }
00305
00306 function RowLock($tables,$where,$flds='1 as ignore')
00307 {
00308 if ($this->autoCommit) $this->BeginTrans();
00309 return $this->GetOne("select $flds from $tables where $where for update");
00310 }
00311
00312 function &MetaTables($ttype=false,$showSchema=false,$mask=false)
00313 {
00314 if ($mask) {
00315 $save = $this->metaTablesSQL;
00316 $mask = $this->qstr(strtoupper($mask));
00317 $this->metaTablesSQL .= " AND upper(table_name) like $mask";
00318 }
00319 $ret =& ADOConnection::MetaTables($ttype,$showSchema);
00320
00321 if ($mask) {
00322 $this->metaTablesSQL = $save;
00323 }
00324 return $ret;
00325 }
00326
00327
00328 function &MetaIndexes ($table, $primary = FALSE, $owner=false)
00329 {
00330
00331 global $ADODB_FETCH_MODE;
00332
00333 $save = $ADODB_FETCH_MODE;
00334 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00335
00336 if ($this->fetchMode !== FALSE) {
00337 $savem = $this->SetFetchMode(FALSE);
00338 }
00339
00340
00341 $table = strtoupper($table);
00342
00343
00344 $primary_key = '';
00345
00346 $false = false;
00347 $rs = $this->Execute(sprintf("SELECT * FROM ALL_CONSTRAINTS WHERE UPPER(TABLE_NAME)='%s' AND CONSTRAINT_TYPE='P'",$table));
00348 if ($row = $rs->FetchRow())
00349 $primary_key = $row[1];
00350
00351 if ($primary==TRUE && $primary_key=='') {
00352 if (isset($savem))
00353 $this->SetFetchMode($savem);
00354 $ADODB_FETCH_MODE = $save;
00355 return $false;
00356 }
00357
00358 $rs = $this->Execute(sprintf("SELECT ALL_INDEXES.INDEX_NAME, ALL_INDEXES.UNIQUENESS, ALL_IND_COLUMNS.COLUMN_POSITION, ALL_IND_COLUMNS.COLUMN_NAME FROM ALL_INDEXES,ALL_IND_COLUMNS WHERE UPPER(ALL_INDEXES.TABLE_NAME)='%s' AND ALL_IND_COLUMNS.INDEX_NAME=ALL_INDEXES.INDEX_NAME",$table));
00359
00360
00361 if (!is_object($rs)) {
00362 if (isset($savem))
00363 $this->SetFetchMode($savem);
00364 $ADODB_FETCH_MODE = $save;
00365 return $false;
00366 }
00367
00368 $indexes = array ();
00369
00370
00371 while ($row = $rs->FetchRow()) {
00372 if ($primary && $row[0] != $primary_key) continue;
00373 if (!isset($indexes[$row[0]])) {
00374 $indexes[$row[0]] = array(
00375 'unique' => ($row[1] == 'UNIQUE'),
00376 'columns' => array()
00377 );
00378 }
00379 $indexes[$row[0]]['columns'][$row[2] - 1] = $row[3];
00380 }
00381
00382
00383 foreach ( array_keys ($indexes) as $index ) {
00384 ksort ($indexes[$index]['columns']);
00385 }
00386
00387 if (isset($savem)) {
00388 $this->SetFetchMode($savem);
00389 $ADODB_FETCH_MODE = $save;
00390 }
00391 return $indexes;
00392 }
00393
00394 function BeginTrans()
00395 {
00396 if ($this->transOff) return true;
00397 $this->transCnt += 1;
00398 $this->autoCommit = false;
00399 $this->_commit = OCI_DEFAULT;
00400
00401 if ($this->_transmode) $this->Execute("SET TRANSACTION ".$this->_transmode);
00402 return true;
00403 }
00404
00405 function CommitTrans($ok=true)
00406 {
00407 if ($this->transOff) return true;
00408 if (!$ok) return $this->RollbackTrans();
00409
00410 if ($this->transCnt) $this->transCnt -= 1;
00411 $ret = OCIcommit($this->_connectionID);
00412 $this->_commit = OCI_COMMIT_ON_SUCCESS;
00413 $this->autoCommit = true;
00414 return $ret;
00415 }
00416
00417 function RollbackTrans()
00418 {
00419 if ($this->transOff) return true;
00420 if ($this->transCnt) $this->transCnt -= 1;
00421 $ret = OCIrollback($this->_connectionID);
00422 $this->_commit = OCI_COMMIT_ON_SUCCESS;
00423 $this->autoCommit = true;
00424 return $ret;
00425 }
00426
00427
00428 function SelectDB($dbName)
00429 {
00430 return false;
00431 }
00432
00433 function ErrorMsg()
00434 {
00435 if ($this->_errorMsg !== false) return $this->_errorMsg;
00436
00437 if (is_resource($this->_stmt)) $arr = @OCIError($this->_stmt);
00438 if (empty($arr)) {
00439 if (is_resource($this->_connectionID)) $arr = @OCIError($this->_connectionID);
00440 else $arr = @OCIError();
00441 if ($arr === false) return '';
00442 }
00443 $this->_errorMsg = $arr['message'];
00444 $this->_errorCode = $arr['code'];
00445 return $this->_errorMsg;
00446 }
00447
00448 function ErrorNo()
00449 {
00450 if ($this->_errorCode !== false) return $this->_errorCode;
00451
00452 if (is_resource($this->_stmt)) $arr = @OCIError($this->_stmt);
00453 if (empty($arr)) {
00454 $arr = @OCIError($this->_connectionID);
00455 if ($arr == false) $arr = @OCIError();
00456 if ($arr == false) return '';
00457 }
00458
00459 $this->_errorMsg = $arr['message'];
00460 $this->_errorCode = $arr['code'];
00461
00462 return $arr['code'];
00463 }
00464
00465
00466 function SQLDate($fmt, $col=false)
00467 {
00468 if (!$col) $col = $this->sysTimeStamp;
00469 $s = 'TO_CHAR('.$col.",'";
00470
00471 $len = strlen($fmt);
00472 for ($i=0; $i < $len; $i++) {
00473 $ch = $fmt[$i];
00474 switch($ch) {
00475 case 'Y':
00476 case 'y':
00477 $s .= 'YYYY';
00478 break;
00479 case 'Q':
00480 case 'q':
00481 $s .= 'Q';
00482 break;
00483
00484 case 'M':
00485 $s .= 'Mon';
00486 break;
00487
00488 case 'm':
00489 $s .= 'MM';
00490 break;
00491 case 'D':
00492 case 'd':
00493 $s .= 'DD';
00494 break;
00495
00496 case 'H':
00497 $s.= 'HH24';
00498 break;
00499
00500 case 'h':
00501 $s .= 'HH';
00502 break;
00503
00504 case 'i':
00505 $s .= 'MI';
00506 break;
00507
00508 case 's':
00509 $s .= 'SS';
00510 break;
00511
00512 case 'a':
00513 case 'A':
00514 $s .= 'AM';
00515 break;
00516
00517 case 'w':
00518 $s .= 'D';
00519 break;
00520
00521 case 'l':
00522 $s .= 'DAY';
00523 break;
00524
00525 case 'W':
00526 $s .= 'WW';
00527 break;
00528
00529 default:
00530
00531 if ($ch == '\\') {
00532 $i++;
00533 $ch = substr($fmt,$i,1);
00534 }
00535 if (strpos('-/.:;, ',$ch) !== false) $s .= $ch;
00536 else $s .= '"'.$ch.'"';
00537
00538 }
00539 }
00540 return $s. "')";
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
00560 {
00561
00562 if ($this->firstrows) {
00563 if (strpos($sql,'
00564
00565
00566 ',$sql);
00567 }
00568
00569 if ($offset < $this->selectOffsetAlg1) {
00570 if ($nrows > 0) {
00571 if ($offset > 0) $nrows += $offset;
00572
00573 if ($this->databaseType == 'oci8po') {
00574 $sql = "select * from (".$sql.") where rownum <= ?";
00575 } else {
00576 $sql = "select * from (".$sql.") where rownum <= :adodb_offset";
00577 }
00578 $inputarr['adodb_offset'] = $nrows;
00579 $nrows = -1;
00580 }
00581
00582
00583 $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
00584 return $rs;
00585
00586 } else {
00587
00588
00589
00590 $q_fields = "SELECT * FROM (".$sql.") WHERE NULL = NULL";
00591
00592 $false = false;
00593 if (! $stmt_arr = $this->Prepare($q_fields)) {
00594 return $false;
00595 }
00596 $stmt = $stmt_arr[1];
00597
00598 if (is_array($inputarr)) {
00599 foreach($inputarr as $k => $v) {
00600 if (is_array($v)) {
00601 if (sizeof($v) == 2)
00602 OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1]);
00603 else
00604 OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
00605 } else {
00606 $len = -1;
00607 if ($v === ' ') $len = 1;
00608 if (isset($bindarr)) {
00609 $bindarr[$k] = $v;
00610 } else {
00611 OCIBindByName($stmt,":$k",$inputarr[$k],$len);
00612 }
00613 }
00614 }
00615 }
00616
00617 if (!OCIExecute($stmt, OCI_DEFAULT)) {
00618 OCIFreeStatement($stmt);
00619 return $false;
00620 }
00621
00622 $ncols = OCINumCols($stmt);
00623 for ( $i = 1; $i <= $ncols; $i++ ) {
00624 $cols[] = '"'.OCIColumnName($stmt, $i).'"';
00625 }
00626 $result = false;
00627
00628 OCIFreeStatement($stmt);
00629 $fields = implode(',', $cols);
00630 $nrows += $offset;
00631 $offset += 1;
00632
00633 if ($this->databaseType == 'oci8po') {
00634 $sql = "SELECT $fields FROM".
00635 "(SELECT rownum as adodb_rownum, $fields FROM".
00636 " ($sql) WHERE rownum <= ?".
00637 ") WHERE adodb_rownum >= ?";
00638 } else {
00639 $sql = "SELECT $fields FROM".
00640 "(SELECT rownum as adodb_rownum, $fields FROM".
00641 " ($sql) WHERE rownum <= :adodb_nrows".
00642 ") WHERE adodb_rownum >= :adodb_offset";
00643 }
00644 $inputarr['adodb_nrows'] = $nrows;
00645 $inputarr['adodb_offset'] = $offset;
00646
00647 if ($secs2cache>0) $rs =& $this->CacheExecute($secs2cache, $sql,$inputarr);
00648 else $rs =& $this->Execute($sql,$inputarr);
00649 return $rs;
00650 }
00651
00652 }
00653
00674 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
00675 {
00676
00677
00678
00679 switch(strtoupper($blobtype)) {
00680 default: ADOConnection::outp("<b>UpdateBlob</b>: Unknown blobtype=$blobtype"); return false;
00681 case 'BLOB': $type = OCI_B_BLOB; break;
00682 case 'CLOB': $type = OCI_B_CLOB; break;
00683 }
00684
00685 if ($this->databaseType == 'oci8po')
00686 $sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO ?";
00687 else
00688 $sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO :blob";
00689
00690 $desc = OCINewDescriptor($this->_connectionID, OCI_D_LOB);
00691 $arr['blob'] = array($desc,-1,$type);
00692 if ($this->session_sharing_force_blob) $this->Execute('ALTER SESSION SET CURSOR_SHARING=EXACT');
00693 $commit = $this->autoCommit;
00694 if ($commit) $this->BeginTrans();
00695 $rs = $this->_Execute($sql,$arr);
00696 if ($rez = !empty($rs)) $desc->save($val);
00697 $desc->free();
00698 if ($commit) $this->CommitTrans();
00699 if ($this->session_sharing_force_blob) $this->Execute('ALTER SESSION SET CURSOR_SHARING=FORCE');
00700
00701 if ($rez) $rs->Close();
00702 return $rez;
00703 }
00704
00708 function UpdateBlobFile($table,$column,$val,$where,$blobtype='BLOB')
00709 {
00710 switch(strtoupper($blobtype)) {
00711 default: ADOConnection::outp( "<b>UpdateBlob</b>: Unknown blobtype=$blobtype"); return false;
00712 case 'BLOB': $type = OCI_B_BLOB; break;
00713 case 'CLOB': $type = OCI_B_CLOB; break;
00714 }
00715
00716 if ($this->databaseType == 'oci8po')
00717 $sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO ?";
00718 else
00719 $sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO :blob";
00720
00721 $desc = OCINewDescriptor($this->_connectionID, OCI_D_LOB);
00722 $arr['blob'] = array($desc,-1,$type);
00723
00724 $this->BeginTrans();
00725 $rs = ADODB_oci8::Execute($sql,$arr);
00726 if ($rez = !empty($rs)) $desc->savefile($val);
00727 $desc->free();
00728 $this->CommitTrans();
00729
00730 if ($rez) $rs->Close();
00731 return $rez;
00732 }
00733
00741 function &Execute($sql,$inputarr=false)
00742 {
00743 if ($this->fnExecute) {
00744 $fn = $this->fnExecute;
00745 $ret =& $fn($this,$sql,$inputarr);
00746 if (isset($ret)) return $ret;
00747 }
00748 if ($inputarr) {
00749 #if (!is_array($inputarr)) $inputarr = array($inputarr);
00750
00751 $element0 = reset($inputarr);
00752
00753 # is_object check because oci8 descriptors can be passed in
00754 if (is_array($element0) && !is_object(reset($element0))) {
00755 if (is_string($sql))
00756 $stmt = $this->Prepare($sql);
00757 else
00758 $stmt = $sql;
00759
00760 foreach($inputarr as $arr) {
00761 $ret =& $this->_Execute($stmt,$arr);
00762 if (!$ret) return $ret;
00763 }
00764 } else {
00765 $ret =& $this->_Execute($sql,$inputarr);
00766 }
00767
00768 } else {
00769 $ret =& $this->_Execute($sql,false);
00770 }
00771
00772 return $ret;
00773 }
00774
00775
00776
00777
00778
00779
00780 function Prepare($sql,$cursor=false)
00781 {
00782 static $BINDNUM = 0;
00783
00784 $stmt = OCIParse($this->_connectionID,$sql);
00785
00786 if (!$stmt) {
00787 $this->_errorMsg = false;
00788 $this->_errorCode = false;
00789 $arr = @OCIError($this->_connectionID);
00790 if ($arr === false) return false;
00791
00792 $this->_errorMsg = $arr['message'];
00793 $this->_errorCode = $arr['code'];
00794 return false;
00795 }
00796
00797 $BINDNUM += 1;
00798
00799 $sttype = @OCIStatementType($stmt);
00800 if ($sttype == 'BEGIN' || $sttype == 'DECLARE') {
00801 return array($sql,$stmt,0,$BINDNUM, ($cursor) ? OCINewCursor($this->_connectionID) : false);
00802 }
00803 return array($sql,$stmt,0,$BINDNUM);
00804 }
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820 function &ExecuteCursor($sql,$cursorName='rs',$params=false)
00821 {
00822 if (is_array($sql)) $stmt = $sql;
00823 else $stmt = ADODB_oci8::Prepare($sql,true); # true to allocate OCINewCursor
00824
00825 if (is_array($stmt) && sizeof($stmt) >= 5) {
00826 $hasref = true;
00827 $ignoreCur = false;
00828 $this->Parameter($stmt, $ignoreCur, $cursorName, false, -1, OCI_B_CURSOR);
00829 if ($params) {
00830 foreach($params as $k => $v) {
00831 $this->Parameter($stmt,$params[$k], $k);
00832 }
00833 }
00834 } else
00835 $hasref = false;
00836
00837 $rs =& $this->Execute($stmt);
00838 if ($rs) {
00839 if ($rs->databaseType == 'array') OCIFreeCursor($stmt[4]);
00840 else if ($hasref) $rs->_refcursor = $stmt[4];
00841 }
00842 return $rs;
00843 }
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 function Bind(&$stmt,&$var,$size=4000,$type=false,$name=false,$isOutput=false)
00876 {
00877
00878 if (!is_array($stmt)) return false;
00879
00880 if (($type == OCI_B_CURSOR) && sizeof($stmt) >= 5) {
00881 return OCIBindByName($stmt[1],":".$name,$stmt[4],$size,$type);
00882 }
00883
00884 if ($name == false) {
00885 if ($type !== false) $rez = OCIBindByName($stmt[1],":".$stmt[2],$var,$size,$type);
00886 else $rez = OCIBindByName($stmt[1],":".$stmt[2],$var,$size);
00887 $stmt[2] += 1;
00888 } else if (oci_lob_desc($type)) {
00889 if ($this->debug) {
00890 ADOConnection::outp("<b>Bind</b>: name = $name");
00891 }
00892
00893 $numlob = count($this->_refLOBs);
00894 $this->_refLOBs[$numlob]['LOB'] = OCINewDescriptor($this->_connectionID, oci_lob_desc($type));
00895 $this->_refLOBs[$numlob]['TYPE'] = $isOutput;
00896
00897 $tmp = &$this->_refLOBs[$numlob]['LOB'];
00898 $rez = OCIBindByName($stmt[1], ":".$name, $tmp, -1, $type);
00899 if ($this->debug) {
00900 ADOConnection::outp("<b>Bind</b>: descriptor has been allocated, var (".$name.") binded");
00901 }
00902
00903
00904 if ($isOutput == false) {
00905 $var = $this->BlobEncode($var);
00906 $tmp->WriteTemporary($var);
00907 $this->_refLOBs[$numlob]['VAR'] = &$var;
00908 if ($this->debug) {
00909 ADOConnection::outp("<b>Bind</b>: LOB has been written to temp");
00910 }
00911 } else {
00912 $this->_refLOBs[$numlob]['VAR'] = &$var;
00913 }
00914 $rez = $tmp;
00915 } else {
00916 if ($this->debug)
00917 ADOConnection::outp("<b>Bind</b>: name = $name");
00918
00919 if ($type !== false) $rez = OCIBindByName($stmt[1],":".$name,$var,$size,$type);
00920 else $rez = OCIBindByName($stmt[1],":".$name,$var,$size);
00921 }
00922
00923 return $rez;
00924 }
00925
00926 function Param($name,$type=false)
00927 {
00928 return ':'.$name;
00929 }
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false)
00948 {
00949 if ($this->debug) {
00950 $prefix = ($isOutput) ? 'Out' : 'In';
00951 $ztype = (empty($type)) ? 'false' : $type;
00952 ADOConnection::outp( "{$prefix}Parameter(\$stmt, \$php_var='$var', \$name='$name', \$maxLen=$maxLen, \$type=$ztype);");
00953 }
00954 return $this->Bind($stmt,$var,$maxLen,$type,$name,$isOutput);
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972 function _query($sql,$inputarr)
00973 {
00974 if (is_array($sql)) {
00975 $stmt = $sql[1];
00976
00977
00978
00979 if (is_array($inputarr)) {
00980 $bindpos = $sql[3];
00981 if (isset($this->_bind[$bindpos])) {
00982
00983 $bindarr = &$this->_bind[$bindpos];
00984 } else {
00985
00986 $bindarr = array();
00987 foreach($inputarr as $k => $v) {
00988 $bindarr[$k] = $v;
00989 OCIBindByName($stmt,":$k",$bindarr[$k],is_string($v) && strlen($v)>4000 ? -1 : 4000);
00990 }
00991 $this->_bind[$bindpos] = &$bindarr;
00992 }
00993 }
00994 } else {
00995 $stmt=OCIParse($this->_connectionID,$sql);
00996 }
00997
00998 $this->_stmt = $stmt;
00999 if (!$stmt) return false;
01000
01001 if (defined('ADODB_PREFETCH_ROWS')) @OCISetPrefetch($stmt,ADODB_PREFETCH_ROWS);
01002
01003 if (is_array($inputarr)) {
01004 foreach($inputarr as $k => $v) {
01005 if (is_array($v)) {
01006 if (sizeof($v) == 2)
01007 OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1]);
01008 else
01009 OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
01010
01011 if ($this->debug==99) echo "name=:$k",' var='.$inputarr[$k][0],' len='.$v[1],' type='.$v[2],'<br>';
01012 } else {
01013 $len = -1;
01014 if ($v === ' ') $len = 1;
01015 if (isset($bindarr)) {
01016 $bindarr[$k] = $v;
01017 } else {
01018 OCIBindByName($stmt,":$k",$inputarr[$k],$len);
01019 }
01020 }
01021 }
01022 }
01023
01024 $this->_errorMsg = false;
01025 $this->_errorCode = false;
01026 if (OCIExecute($stmt,$this->_commit)) {
01027
01028 if (count($this -> _refLOBs) > 0) {
01029
01030 foreach ($this -> _refLOBs as $key => $value) {
01031 if ($this -> _refLOBs[$key]['TYPE'] == true) {
01032 $tmp = $this -> _refLOBs[$key]['LOB'] -> load();
01033 if ($this -> debug) {
01034 ADOConnection::outp("<b>OUT LOB</b>: LOB has been loaded. <br>");
01035 }
01036
01037 $this -> _refLOBs[$key]['VAR'] = $tmp;
01038 } else {
01039 $this->_refLOBs[$key]['LOB']->save($this->_refLOBs[$key]['VAR']);
01040 $this -> _refLOBs[$key]['LOB']->free();
01041 unset($this -> _refLOBs[$key]);
01042 if ($this->debug) {
01043 ADOConnection::outp("<b>IN LOB</b>: LOB has been saved. <br>");
01044 }
01045 }
01046 }
01047 }
01048
01049 switch (@OCIStatementType($stmt)) {
01050 case "SELECT":
01051 return $stmt;
01052
01053 case 'DECLARE':
01054 case "BEGIN":
01055 if (is_array($sql) && !empty($sql[4])) {
01056 $cursor = $sql[4];
01057 if (is_resource($cursor)) {
01058 $ok = OCIExecute($cursor);
01059 return $cursor;
01060 }
01061 return $stmt;
01062 } else {
01063 if (is_resource($stmt)) {
01064 OCIFreeStatement($stmt);
01065 return true;
01066 }
01067 return $stmt;
01068 }
01069 break;
01070 default :
01071
01072 return true;
01073 }
01074 }
01075 return false;
01076 }
01077
01078
01079 function _close()
01080 {
01081 if (!$this->_connectionID) return;
01082
01083 if (!$this->autoCommit) OCIRollback($this->_connectionID);
01084 if (count($this->_refLOBs) > 0) {
01085 foreach ($this ->_refLOBs as $key => $value) {
01086 $this->_refLOBs[$key]['LOB']->free();
01087 unset($this->_refLOBs[$key]);
01088 }
01089 }
01090 OCILogoff($this->_connectionID);
01091
01092 $this->_stmt = false;
01093 $this->_connectionID = false;
01094 }
01095
01096 function MetaPrimaryKeys($table, $owner=false,$internalKey=false)
01097 {
01098 if ($internalKey) return array('ROWID');
01099
01100
01101 $table = strtoupper($table);
01102 if ($owner) {
01103 $owner_clause = "AND ((a.OWNER = b.OWNER) AND (a.OWNER = UPPER('$owner')))";
01104 $ptab = 'ALL_';
01105 } else {
01106 $owner_clause = '';
01107 $ptab = 'USER_';
01108 }
01109 $sql = "
01110 SELECT /*+ RULE */ distinct b.column_name
01111 FROM {$ptab}CONSTRAINTS a
01112 , {$ptab}CONS_COLUMNS b
01113 WHERE ( UPPER(b.table_name) = ('$table'))
01114 AND (UPPER(a.table_name) = ('$table') and a.constraint_type = 'P')
01115 $owner_clause
01116 AND (a.constraint_name = b.constraint_name)";
01117
01118 $rs = $this->Execute($sql);
01119 if ($rs && !$rs->EOF) {
01120 $arr =& $rs->GetArray();
01121 $a = array();
01122 foreach($arr as $v) {
01123 $a[] = reset($v);
01124 }
01125 return $a;
01126 }
01127 else return false;
01128 }
01129
01130
01131 function MetaForeignKeys($table, $owner=false)
01132 {
01133 global $ADODB_FETCH_MODE;
01134
01135 $save = $ADODB_FETCH_MODE;
01136 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
01137 $table = $this->qstr(strtoupper($table));
01138 if (!$owner) {
01139 $owner = $this->user;
01140 $tabp = 'user_';
01141 } else
01142 $tabp = 'all_';
01143
01144 $owner = ' and owner='.$this->qstr(strtoupper($owner));
01145
01146 $sql =
01147 "select constraint_name,r_owner,r_constraint_name
01148 from {$tabp}constraints
01149 where constraint_type = 'R' and table_name = $table $owner";
01150
01151 $constraints =& $this->GetArray($sql);
01152 $arr = false;
01153 foreach($constraints as $constr) {
01154 $cons = $this->qstr($constr[0]);
01155 $rowner = $this->qstr($constr[1]);
01156 $rcons = $this->qstr($constr[2]);
01157 $cols = $this->GetArray("select column_name from {$tabp}cons_columns where constraint_name=$cons $owner order by position");
01158 $tabcol = $this->GetArray("select table_name,column_name from {$tabp}cons_columns where owner=$rowner and constraint_name=$rcons order by position");
01159
01160 if ($cols && $tabcol)
01161 for ($i=0, $max=sizeof($co