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')";
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 $_hasOCIFetchStatement = false;
00079 var $_getarray = false;
00080 var $leftOuter = '';
00081 var $session_sharing_force_blob = false;
00082 var $firstrows = true;
00083 var $selectOffsetAlg1 = 100;
00084 var $NLS_DATE_FORMAT = 'YYYY-MM-DD';
00085 var $useDBDateFormatForTextInput=false;
00086 var $datetime = false;
00087 var $_refLOBs = array();
00088
00089
00090
00091 function ADODB_oci8()
00092 {
00093 $this->_hasOCIFetchStatement = ADODB_PHPVER >= 0x4200;
00094 if (defined('ADODB_EXTENSION')) $this->rsPrefix .= 'ext_';
00095 }
00096
00097
00098 function &MetaColumns($table)
00099 {
00100 global $ADODB_FETCH_MODE;
00101
00102 $false = false;
00103 $save = $ADODB_FETCH_MODE;
00104 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00105 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
00106
00107 $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
00108
00109 if (isset($savem)) $this->SetFetchMode($savem);
00110 $ADODB_FETCH_MODE = $save;
00111 if (!$rs) {
00112 return $false;
00113 }
00114 $retarr = array();
00115 while (!$rs->EOF) {
00116 $fld = new ADOFieldObject();
00117 $fld->name = $rs->fields[0];
00118 $fld->type = $rs->fields[1];
00119 $fld->max_length = $rs->fields[2];
00120 $fld->scale = $rs->fields[3];
00121 if ($rs->fields[1] == 'NUMBER' && $rs->fields[3] == 0) {
00122 $fld->type ='INT';
00123 $fld->max_length = $rs->fields[4];
00124 }
00125 $fld->not_null = (strncmp($rs->fields[5], 'NOT',3) === 0);
00126 $fld->binary = (strpos($fld->type,'BLOB') !== false);
00127 $fld->default_value = $rs->fields[6];
00128
00129 if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
00130 else $retarr[strtoupper($fld->name)] = $fld;
00131 $rs->MoveNext();
00132 }
00133 $rs->Close();
00134 if (empty($retarr))
00135 return $false;
00136 else
00137 return $retarr;
00138 }
00139
00140 function Time()
00141 {
00142 $rs =& $this->Execute("select TO_CHAR($this->sysTimeStamp,'YYYY-MM-DD HH24:MI:SS') from dual");
00143 if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
00144
00145 return false;
00146 }
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 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$mode=0)
00183 {
00184 if (!function_exists('OCIPLogon')) return null;
00185
00186
00187 $this->_errorMsg = false;
00188 $this->_errorCode = false;
00189
00190 if($argHostname) {
00191 if (empty($argDatabasename)) $argDatabasename = $argHostname;
00192 else {
00193 if(strpos($argHostname,":")) {
00194 $argHostinfo=explode(":",$argHostname);
00195 $argHostname=$argHostinfo[0];
00196 $argHostport=$argHostinfo[1];
00197 } else {
00198 $argHostport = empty($this->port)? "1521" : $this->port;
00199 }
00200
00201 if ($this->connectSID) {
00202 $argDatabasename="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=".$argHostname
00203 .")(PORT=$argHostport))(CONNECT_DATA=(SID=$argDatabasename)))";
00204 } else
00205 $argDatabasename="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=".$argHostname
00206 .")(PORT=$argHostport))(CONNECT_DATA=(SERVICE_NAME=$argDatabasename)))";
00207 }
00208 }
00209
00210
00211 if ($mode==1) {
00212 $this->_connectionID = ($this->charSet) ?
00213 OCIPLogon($argUsername,$argPassword, $argDatabasename)
00214 :
00215 OCIPLogon($argUsername,$argPassword, $argDatabasename, $this->charSet)
00216 ;
00217 if ($this->_connectionID && $this->autoRollback) OCIrollback($this->_connectionID);
00218 } else if ($mode==2) {
00219 $this->_connectionID = ($this->charSet) ?
00220 OCINLogon($argUsername,$argPassword, $argDatabasename)
00221 :
00222 OCINLogon($argUsername,$argPassword, $argDatabasename, $this->charSet);
00223
00224 } else {
00225 $this->_connectionID = ($this->charSet) ?
00226 OCILogon($argUsername,$argPassword, $argDatabasename)
00227 :
00228 OCILogon($argUsername,$argPassword, $argDatabasename,$this->charSet);
00229 }
00230 if (!$this->_connectionID) return false;
00231 if ($this->_initdate) {
00232 $this->Execute("ALTER SESSION SET NLS_DATE_FORMAT='".$this->NLS_DATE_FORMAT."'");
00233 }
00234
00235
00236
00237
00238
00239 return true;
00240 }
00241
00242 function ServerInfo()
00243 {
00244 $arr['compat'] = $this->GetOne('select value from sys.database_compatible_level');
00245 $arr['description'] = @OCIServerVersion($this->_connectionID);
00246 $arr['version'] = ADOConnection::_findvers($arr['description']);
00247 return $arr;
00248 }
00249
00250 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
00251 {
00252 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,1);
00253 }
00254
00255
00256 function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
00257 {
00258 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,2);
00259 }
00260
00261 function _affectedrows()
00262 {
00263 if (is_resource($this->_stmt)) return @OCIRowCount($this->_stmt);
00264 return 0;
00265 }
00266
00267 function IfNull( $field, $ifNull )
00268 {
00269 return " NVL($field, $ifNull) ";
00270 }
00271
00272
00273 function DBDate($d)
00274 {
00275 if (empty($d) && $d !== 0) return 'null';
00276
00277 if (is_string($d)) $d = ADORecordSet::UnixDate($d);
00278 return "TO_DATE(".adodb_date($this->fmtDate,$d).",'".$this->NLS_DATE_FORMAT."')";
00279 }
00280
00281
00282
00283 function DBTimeStamp($ts)
00284 {
00285 if (empty($ts) && $ts !== 0) return 'null';
00286 if (is_string($ts)) $ts = ADORecordSet::UnixTimeStamp($ts);
00287 return 'TO_DATE('.adodb_date($this->fmtTimeStamp,$ts).",'RRRR-MM-DD, HH:MI:SS AM')";
00288 }
00289
00290 function RowLock($tables,$where,$flds='1 as ignore')
00291 {
00292 if ($this->autoCommit) $this->BeginTrans();
00293 return $this->GetOne("select $flds from $tables where $where for update");
00294 }
00295
00296 function &MetaTables($ttype=false,$showSchema=false,$mask=false)
00297 {
00298 if ($mask) {
00299 $save = $this->metaTablesSQL;
00300 $mask = $this->qstr(strtoupper($mask));
00301 $this->metaTablesSQL .= " AND upper(table_name) like $mask";
00302 }
00303 $ret =& ADOConnection::MetaTables($ttype,$showSchema);
00304
00305 if ($mask) {
00306 $this->metaTablesSQL = $save;
00307 }
00308 return $ret;
00309 }
00310
00311
00312 function &MetaIndexes ($table, $primary = FALSE, $owner=false)
00313 {
00314
00315 global $ADODB_FETCH_MODE;
00316
00317 $save = $ADODB_FETCH_MODE;
00318 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00319
00320 if ($this->fetchMode !== FALSE) {
00321 $savem = $this->SetFetchMode(FALSE);
00322 }
00323
00324
00325 $table = strtoupper($table);
00326
00327
00328 $primary_key = '';
00329
00330 $false = false;
00331 $rs = $this->Execute(sprintf("SELECT * FROM ALL_CONSTRAINTS WHERE UPPER(TABLE_NAME)='%s' AND CONSTRAINT_TYPE='P'",$table));
00332 if ($row = $rs->FetchRow())
00333 $primary_key = $row[1];
00334
00335 if ($primary==TRUE && $primary_key=='') {
00336 if (isset($savem))
00337 $this->SetFetchMode($savem);
00338 $ADODB_FETCH_MODE = $save;
00339 return $false;
00340 }
00341
00342 $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));
00343
00344
00345 if (!is_object($rs)) {
00346 if (isset($savem))
00347 $this->SetFetchMode($savem);
00348 $ADODB_FETCH_MODE = $save;
00349 return $false;
00350 }
00351
00352 $indexes = array ();
00353
00354
00355 while ($row = $rs->FetchRow()) {
00356 if ($primary && $row[0] != $primary_key) continue;
00357 if (!isset($indexes[$row[0]])) {
00358 $indexes[$row[0]] = array(
00359 'unique' => ($row[1] == 'UNIQUE'),
00360 'columns' => array()
00361 );
00362 }
00363 $indexes[$row[0]]['columns'][$row[2] - 1] = $row[3];
00364 }
00365
00366
00367 foreach ( array_keys ($indexes) as $index ) {
00368 ksort ($indexes[$index]['columns']);
00369 }
00370
00371 if (isset($savem)) {
00372 $this->SetFetchMode($savem);
00373 $ADODB_FETCH_MODE = $save;
00374 }
00375 return $indexes;
00376 }
00377
00378 function BeginTrans()
00379 {
00380 if ($this->transOff) return true;
00381 $this->transCnt += 1;
00382 $this->autoCommit = false;
00383 $this->_commit = OCI_DEFAULT;
00384 return true;
00385 }
00386
00387 function CommitTrans($ok=true)
00388 {
00389 if ($this->transOff) return true;
00390 if (!$ok) return $this->RollbackTrans();
00391
00392 if ($this->transCnt) $this->transCnt -= 1;
00393 $ret = OCIcommit($this->_connectionID);
00394 $this->_commit = OCI_COMMIT_ON_SUCCESS;
00395 $this->autoCommit = true;
00396 return $ret;
00397 }
00398
00399 function RollbackTrans()
00400 {
00401 if ($this->transOff) return true;
00402 if ($this->transCnt) $this->transCnt -= 1;
00403 $ret = OCIrollback($this->_connectionID);
00404 $this->_commit = OCI_COMMIT_ON_SUCCESS;
00405 $this->autoCommit = true;
00406 return $ret;
00407 }
00408
00409
00410 function SelectDB($dbName)
00411 {
00412 return false;
00413 }
00414
00415 function ErrorMsg()
00416 {
00417 if ($this->_errorMsg !== false) return $this->_errorMsg;
00418
00419 if (is_resource($this->_stmt)) $arr = @OCIerror($this->_stmt);
00420 if (empty($arr)) {
00421 $arr = @OCIerror($this->_connectionID);
00422 if ($arr === false) $arr = @OCIError();
00423 if ($arr === false) return '';
00424 }
00425 $this->_errorMsg = $arr['message'];
00426 $this->_errorCode = $arr['code'];
00427 return $this->_errorMsg;
00428 }
00429
00430 function ErrorNo()
00431 {
00432 if ($this->_errorCode !== false) return $this->_errorCode;
00433
00434 if (is_resource($this->_stmt)) $arr = @OCIError($this->_stmt);
00435 if (empty($arr)) {
00436 $arr = @OCIError($this->_connectionID);
00437 if ($arr == false) $arr = @OCIError();
00438 if ($arr == false) return '';
00439 }
00440
00441 $this->_errorMsg = $arr['message'];
00442 $this->_errorCode = $arr['code'];
00443
00444 return $arr['code'];
00445 }
00446
00447
00448 function SQLDate($fmt, $col=false)
00449 {
00450 if (!$col) $col = $this->sysTimeStamp;
00451 $s = 'TO_CHAR('.$col.",'";
00452
00453 $len = strlen($fmt);
00454 for ($i=0; $i < $len; $i++) {
00455 $ch = $fmt[$i];
00456 switch($ch) {
00457 case 'Y':
00458 case 'y':
00459 $s .= 'YYYY';
00460 break;
00461 case 'Q':
00462 case 'q':
00463 $s .= 'Q';
00464 break;
00465
00466 case 'M':
00467 $s .= 'Mon';
00468 break;
00469
00470 case 'm':
00471 $s .= 'MM';
00472 break;
00473 case 'D':
00474 case 'd':
00475 $s .= 'DD';
00476 break;
00477
00478 case 'H':
00479 $s.= 'HH24';
00480 break;
00481
00482 case 'h':
00483 $s .= 'HH';
00484 break;
00485
00486 case 'i':
00487 $s .= 'MI';
00488 break;
00489
00490 case 's':
00491 $s .= 'SS';
00492 break;
00493
00494 case 'a':
00495 case 'A':
00496 $s .= 'AM';
00497 break;
00498
00499 case 'w':
00500 $s .= 'D';
00501 break;
00502
00503 case 'l':
00504 $s .= 'DAY';
00505 break;
00506
00507 case 'W':
00508 $s .= 'WW';
00509 break;
00510
00511 default:
00512
00513 if ($ch == '\\') {
00514 $i++;
00515 $ch = substr($fmt,$i,1);
00516 }
00517 if (strpos('-/.:;, ',$ch) !== false) $s .= $ch;
00518 else $s .= '"'.$ch.'"';
00519
00520 }
00521 }
00522 return $s. "')";
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
00542 {
00543
00544 if ($this->firstrows) {
00545 if (strpos($sql,'
00546
00547
00548 ',$sql);
00549 }
00550
00551 if ($offset < $this->selectOffsetAlg1) {
00552 if ($nrows > 0) {
00553 if ($offset > 0) $nrows += $offset;
00554
00555 if ($this->databaseType == 'oci8po') {
00556 $sql = "select * from (".$sql.") where rownum <= ?";
00557 } else {
00558 $sql = "select * from (".$sql.") where rownum <= :adodb_offset";
00559 }
00560 $inputarr['adodb_offset'] = $nrows;
00561 $nrows = -1;
00562 }
00563
00564
00565 $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
00566 return $rs;
00567
00568 } else {
00569
00570
00571
00572 $q_fields = "SELECT * FROM (".$sql.") WHERE NULL = NULL";
00573
00574 $false = false;
00575 if (! $stmt_arr = $this->Prepare($q_fields)) {
00576 return $false;
00577 }
00578 $stmt = $stmt_arr[1];
00579
00580 if (is_array($inputarr)) {
00581 foreach($inputarr as $k => $v) {
00582 if (is_array($v)) {
00583 if (sizeof($v) == 2)
00584 OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1]);
00585 else
00586 OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
00587 } else {
00588 $len = -1;
00589 if ($v === ' ') $len = 1;
00590 if (isset($bindarr)) {
00591 $bindarr[$k] = $v;
00592 } else {
00593 OCIBindByName($stmt,":$k",$inputarr[$k],$len);
00594 }
00595 }
00596 }
00597 }
00598
00599 if (!OCIExecute($stmt, OCI_DEFAULT)) {
00600 OCIFreeStatement($stmt);
00601 return $false;
00602 }
00603
00604 $ncols = OCINumCols($stmt);
00605 for ( $i = 1; $i <= $ncols; $i++ ) {
00606 $cols[] = '"'.OCIColumnName($stmt, $i).'"';
00607 }
00608 $result = false;
00609
00610 OCIFreeStatement($stmt);
00611 $fields = implode(',', $cols);
00612 $nrows += $offset;
00613 $offset += 1;
00614
00615 if ($this->databaseType == 'oci8po') {
00616 $sql = "SELECT $fields FROM".
00617 "(SELECT rownum as adodb_rownum, $fields FROM".
00618 " ($sql) WHERE rownum <= ?".
00619 ") WHERE adodb_rownum >= ?";
00620 } else {
00621 $sql = "SELECT $fields FROM".
00622 "(SELECT rownum as adodb_rownum, $fields FROM".
00623 " ($sql) WHERE rownum <= :adodb_nrows".
00624 ") WHERE adodb_rownum >= :adodb_offset";
00625 }
00626 $inputarr['adodb_nrows'] = $nrows;
00627 $inputarr['adodb_offset'] = $offset;
00628
00629 if ($secs2cache>0) $rs =& $this->CacheExecute($secs2cache, $sql,$inputarr);
00630 else $rs =& $this->Execute($sql,$inputarr);
00631 return $rs;
00632 }
00633
00634 }
00635
00656 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
00657 {
00658
00659
00660
00661 switch(strtoupper($blobtype)) {
00662 default: ADOConnection::outp("<b>UpdateBlob</b>: Unknown blobtype=$blobtype"); return false;
00663 case 'BLOB': $type = OCI_B_BLOB; break;
00664 case 'CLOB': $type = OCI_B_CLOB; break;
00665 }
00666
00667 if ($this->databaseType == 'oci8po')
00668 $sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO ?";
00669 else
00670 $sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO :blob";
00671
00672 $desc = OCINewDescriptor($this->_connectionID, OCI_D_LOB);
00673 $arr['blob'] = array($desc,-1,$type);
00674 if ($this->session_sharing_force_blob) $this->Execute('ALTER SESSION SET CURSOR_SHARING=EXACT');
00675 $commit = $this->autoCommit;
00676 if ($commit) $this->BeginTrans();
00677 $rs = $this->_Execute($sql,$arr);
00678 if ($rez = !empty($rs)) $desc->save($val);
00679 $desc->free();
00680 if ($commit) $this->CommitTrans();
00681 if ($this->session_sharing_force_blob) $this->Execute('ALTER SESSION SET CURSOR_SHARING=FORCE');
00682
00683 if ($rez) $rs->Close();
00684 return $rez;
00685 }
00686
00690 function UpdateBlobFile($table,$column,$val,$where,$blobtype='BLOB')
00691 {
00692 switch(strtoupper($blobtype)) {
00693 default: ADOConnection::outp( "<b>UpdateBlob</b>: Unknown blobtype=$blobtype"); return false;
00694 case 'BLOB': $type = OCI_B_BLOB; break;
00695 case 'CLOB': $type = OCI_B_CLOB; break;
00696 }
00697
00698 if ($this->databaseType == 'oci8po')
00699 $sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO ?";
00700 else
00701 $sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO :blob";
00702
00703 $desc = OCINewDescriptor($this->_connectionID, OCI_D_LOB);
00704 $arr['blob'] = array($desc,-1,$type);
00705
00706 $this->BeginTrans();
00707 $rs = ADODB_oci8::Execute($sql,$arr);
00708 if ($rez = !empty($rs)) $desc->savefile($val);
00709 $desc->free();
00710 $this->CommitTrans();
00711
00712 if ($rez) $rs->Close();
00713 return $rez;
00714 }
00715
00723 function &Execute($sql,$inputarr=false)
00724 {
00725 if ($this->fnExecute) {
00726 $fn = $this->fnExecute;
00727 $ret =& $fn($this,$sql,$inputarr);
00728 if (isset($ret)) return $ret;
00729 }
00730 if ($inputarr) {
00731 #if (!is_array($inputarr)) $inputarr = array($inputarr);
00732
00733 $element0 = reset($inputarr);
00734
00735 # is_object check because oci8 descriptors can be passed in
00736 if (is_array($element0) && !is_object(reset($element0))) {
00737 if (is_string($sql))
00738 $stmt = $this->Prepare($sql);
00739 else
00740 $stmt = $sql;
00741
00742 foreach($inputarr as $arr) {
00743 $ret =& $this->_Execute($stmt,$arr);
00744 if (!$ret) return $ret;
00745 }
00746 } else {
00747 $ret =& $this->_Execute($sql,$inputarr);
00748 }
00749
00750 } else {
00751 $ret =& $this->_Execute($sql,false);
00752 }
00753
00754 return $ret;
00755 }
00756
00757
00758
00759
00760
00761
00762 function Prepare($sql,$cursor=false)
00763 {
00764 static $BINDNUM = 0;
00765
00766 $stmt = OCIParse($this->_connectionID,$sql);
00767
00768 if (!$stmt) return false;
00769
00770 $BINDNUM += 1;
00771
00772 $sttype = @OCIStatementType($stmt);
00773 if ($sttype == 'BEGIN' || $sttype == 'DECLARE') {
00774 return array($sql,$stmt,0,$BINDNUM, ($cursor) ? OCINewCursor($this->_connectionID) : false);
00775 }
00776 return array($sql,$stmt,0,$BINDNUM);
00777 }
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 function &ExecuteCursor($sql,$cursorName='rs',$params=false)
00794 {
00795 if (is_array($sql)) $stmt = $sql;
00796 else $stmt = ADODB_oci8::Prepare($sql,true); # true to allocate OCINewCursor
00797
00798 if (is_array($stmt) && sizeof($stmt) >= 5) {
00799 $hasref = true;
00800 $ignoreCur = false;
00801 $this->Parameter($stmt, $ignoreCur, $cursorName, false, -1, OCI_B_CURSOR);
00802 if ($params) {
00803 foreach($params as $k => $v) {
00804 $this->Parameter($stmt,$params[$k], $k);
00805 }
00806 }
00807 } else
00808 $hasref = false;
00809
00810 $rs =& $this->Execute($stmt);
00811 if ($rs) {
00812 if ($rs->databaseType == 'array') OCIFreeCursor($stmt[4]);
00813 else if ($hasref) $rs->_refcursor = $stmt[4];
00814 }
00815 return $rs;
00816 }
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 function Bind(&$stmt,&$var,$size=4000,$type=false,$name=false,$isOutput=false)
00849 {
00850
00851 if (!is_array($stmt)) return false;
00852
00853 if (($type == OCI_B_CURSOR) && sizeof($stmt) >= 5) {
00854 return OCIBindByName($stmt[1],":".$name,$stmt[4],$size,$type);
00855 }
00856
00857 if ($name == false) {
00858 if ($type !== false) $rez = OCIBindByName($stmt[1],":".$stmt[2],$var,$size,$type);
00859 else $rez = OCIBindByName($stmt[1],":".$stmt[2],$var,$size);
00860 $stmt[2] += 1;
00861 } else if (oci_lob_desc($type)) {
00862 if ($this->debug) {
00863 ADOConnection::outp("<b>Bind</b>: name = $name");
00864 }
00865
00866 $numlob = count($this->_refLOBs);
00867 $this->_refLOBs[$numlob]['LOB'] = OCINewDescriptor($this->_connectionID, oci_lob_desc($type));
00868 $this->_refLOBs[$numlob]['TYPE'] = $isOutput;
00869
00870 $tmp = &$this->_refLOBs[$numlob]['LOB'];
00871 $rez = OCIBindByName($stmt[1], ":".$name, $tmp, -1, $type);
00872 if ($this->debug) {
00873 ADOConnection::outp("<b>Bind</b>: descriptor has been allocated, var (".$name.") binded");
00874 }
00875
00876
00877 if ($isOutput == false) {
00878 $var = $this->BlobEncode($var);
00879 $tmp->WriteTemporary($var);
00880 $this->_refLOBs[$numlob]['VAR'] = &$var;
00881 if ($this->debug) {
00882 ADOConnection::outp("<b>Bind</b>: LOB has been written to temp");
00883 }
00884 } else {
00885 $this->_refLOBs[$numlob]['VAR'] = &$var;
00886 }
00887 $rez = $tmp;
00888 } else {
00889 if ($this->debug)
00890 ADOConnection::outp("<b>Bind</b>: name = $name");
00891
00892 if ($type !== false) $rez = OCIBindByName($stmt[1],":".$name,$var,$size,$type);
00893 else $rez = OCIBindByName($stmt[1],":".$name,$var,$size);
00894 }
00895
00896 return $rez;
00897 }
00898
00899 function Param($name,$type=false)
00900 {
00901 return ':'.$name;
00902 }
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920 function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false)
00921 {
00922 if ($this->debug) {
00923 $prefix = ($isOutput) ? 'Out' : 'In';
00924 $ztype = (empty($type)) ? 'false' : $type;
00925 ADOConnection::outp( "{$prefix}Parameter(\$stmt, \$php_var='$var', \$name='$name', \$maxLen=$maxLen, \$type=$ztype);");
00926 }
00927 return $this->Bind($stmt,$var,$maxLen,$type,$name,$isOutput);
00928 }
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945 function _query($sql,$inputarr)
00946 {
00947 if (is_array($sql)) {
00948 $stmt = $sql[1];
00949
00950
00951
00952 if (is_array($inputarr)) {
00953 $bindpos = $sql[3];
00954 if (isset($this->_bind[$bindpos])) {
00955
00956 $bindarr = &$this->_bind[$bindpos];
00957 } else {
00958
00959 $bindarr = array();
00960 foreach($inputarr as $k => $v) {
00961 $bindarr[$k] = $v;
00962 OCIBindByName($stmt,":$k",$bindarr[$k],is_string($v) && strlen($v)>4000 ? -1 : 4000);
00963 }
00964 $this->_bind[$bindpos] = &$bindarr;
00965 }
00966 }
00967 } else {
00968 $stmt=OCIParse($this->_connectionID,$sql);
00969 }
00970
00971 $this->_stmt = $stmt;
00972 if (!$stmt) return false;
00973
00974 if (defined('ADODB_PREFETCH_ROWS')) @OCISetPrefetch($stmt,ADODB_PREFETCH_ROWS);
00975
00976 if (is_array($inputarr)) {
00977 foreach($inputarr as $k => $v) {
00978 if (is_array($v)) {
00979 if (sizeof($v) == 2)
00980 OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1]);
00981 else
00982 OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
00983
00984 if ($this->debug==99) echo "name=:$k",' var='.$inputarr[$k][0],' len='.$v[1],' type='.$v[2],'<br>';
00985 } else {
00986 $len = -1;
00987 if ($v === ' ') $len = 1;
00988 if (isset($bindarr)) {
00989 $bindarr[$k] = $v;
00990 } else {
00991 OCIBindByName($stmt,":$k",$inputarr[$k],$len);
00992 }
00993 }
00994 }
00995 }
00996
00997 $this->_errorMsg = false;
00998 $this->_errorCode = false;
00999 if (OCIExecute($stmt,$this->_commit)) {
01000
01001 if (count($this -> _refLOBs) > 0) {
01002
01003 foreach ($this -> _refLOBs as $key => $value) {
01004 if ($this -> _refLOBs[$key]['TYPE'] == true) {
01005 $tmp = $this -> _refLOBs[$key]['LOB'] -> load();
01006 if ($this -> debug) {
01007 ADOConnection::outp("<b>OUT LOB</b>: LOB has been loaded. <br>");
01008 }
01009
01010 $this -> _refLOBs[$key]['VAR'] = $tmp;
01011 } else {
01012 $this->_refLOBs[$key]['LOB']->save($this->_refLOBs[$key]['VAR']);
01013 $this -> _refLOBs[$key]['LOB']->free();
01014 unset($this -> _refLOBs[$key]);
01015 if ($this->debug) {
01016 ADOConnection::outp("<b>IN LOB</b>: LOB has been saved. <br>");
01017 }
01018 }
01019 }
01020 }
01021
01022 switch (@OCIStatementType($stmt)) {
01023 case "SELECT":
01024 return $stmt;
01025
01026 case 'DECLARE':
01027 case "BEGIN":
01028 if (is_array($sql) && !empty($sql[4])) {
01029 $cursor = $sql[4];
01030 if (is_resource($cursor)) {
01031 $ok = OCIExecute($cursor);
01032 return $cursor;
01033 }
01034 return $stmt;
01035 } else {
01036 if (is_resource($stmt)) {
01037 OCIFreeStatement($stmt);
01038 return true;
01039 }
01040 return $stmt;
01041 }
01042 break;
01043 default :
01044
01045 return true;
01046 }
01047 }
01048 return false;
01049 }
01050
01051
01052 function _close()
01053 {
01054 if (!$this->_connectionID) return;
01055
01056 if (!$this->autoCommit) OCIRollback($this->_connectionID);
01057 if (count($this->_refLOBs) > 0) {
01058 foreach ($this ->_refLOBs as $key => $value) {
01059 $this->_refLOBs[$key]['LOB']->free();
01060 unset($this->_refLOBs[$key]);
01061 }
01062 }
01063 OCILogoff($this->_connectionID);
01064
01065 $this->_stmt = false;
01066 $this->_connectionID = false;
01067 }
01068
01069 function MetaPrimaryKeys($table, $owner=false,$internalKey=false)
01070 {
01071 if ($internalKey) return array('ROWID');
01072
01073
01074 $table = strtoupper($table);
01075 if ($owner) {
01076 $owner_clause = "AND ((a.OWNER = b.OWNER) AND (a.OWNER = UPPER('$owner')))";
01077 $ptab = 'ALL_';
01078 } else {
01079 $owner_clause = '';
01080 $ptab = 'USER_';
01081 }
01082 $sql = "
01083 SELECT /*+ RULE */ distinct b.column_name
01084 FROM {$ptab}CONSTRAINTS a
01085 , {$ptab}CONS_COLUMNS b
01086 WHERE ( UPPER(b.table_name) = ('$table'))
01087 AND (UPPER(a.table_name) = ('$table') and a.constraint_type = 'P')
01088 $owner_clause
01089 AND (a.constraint_name = b.constraint_name)";
01090
01091 $rs = $this->Execute($sql);
01092 if ($rs && !$rs->EOF) {
01093 $arr =& $rs->GetArray();
01094 $a = array();
01095 foreach($arr as $v) {
01096 $a[] = reset($v);
01097 }
01098 return $a;
01099 }
01100 else return false;
01101 }
01102
01103
01104 function MetaForeignKeys($table, $owner=false)
01105 {
01106 global $ADODB_FETCH_MODE;
01107
01108 $save = $ADODB_FETCH_MODE;
01109 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
01110 $table = $this->qstr(strtoupper($table));
01111 if (!$owner) {
01112 $owner = $this->user;
01113 $tabp = 'user_';
01114 } else
01115 $tabp = 'all_';
01116
01117 $owner = ' and owner='.$this->qstr(strtoupper($owner));
01118
01119 $sql =
01120 "select constraint_name,r_owner,r_constraint_name
01121 from {$tabp}constraints
01122 where constraint_type = 'R' and table_name = $table $owner";
01123
01124 $constraints =& $this->GetArray($sql);
01125 $arr = false;
01126 foreach($constraints as $constr) {
01127 $cons = $this->qstr($constr[0]);
01128 $rowner = $this->qstr($constr[1]);
01129 $rcons = $this->qstr($constr[2]);
01130 $cols = $this->GetArray("select column_name from {$tabp}cons_columns where constraint_name=$cons $owner order by position");
01131 $tabcol = $this->GetArray("select table_name,column_name from {$tabp}cons_columns where owner=$rowner and constraint_name=$rcons order by position");
01132
01133 if ($cols && $tabcol)
01134 for ($i=0, $max=sizeof($cols); $i < $max; $i++) {
01135 $arr[$tabcol[$i][0]] = $cols[$i][0].'='.$tabcol[$i][1];
01136 }
01137 }
01138 $ADODB_FETCH_MODE = $save;
01139
01140 return $arr;
01141 }
01142
01143
01144 function CharMax()
01145 {
01146 return 4000;
01147 }
01148
01149 function TextMax()
01150 {
01151 return 4000;
01152 }
01153
01164 function qstr($s,$magic_quotes=false)
01165 {
01166
01167
01168 if ($this->noNullStrings && strlen($s)==0)$s = ' ';
01169 if (!$magic_quotes) {
01170 if ($this->replaceQuote[0] == '\\'){
01171 $s = str_replace('\\','\\\\',$s);
01172 }
01173 return "'".str_replace("'",$this->replaceQuote,$s)."'";
01174 }
01175
01176
01177 $s = str_replace('\\"','"',$s);
01178
01179 $s = str_replace('\\\\','\\',$s);
01180 return "'".str_replace("\\'",$this->replaceQuote,$s)."'";
01181
01182 }
01183
01184 }
01185
01186
01187
01188
01189
01190 class ADORecordset_oci8 extends ADORecordSet {
01191
01192 var $databaseType = 'oci8';
01193 var $bind=false;
01194 var $_fieldobjs;
01195
01196
01197
01198 function ADORecordset_oci8($queryID,$mode=false)
01199 {
01200 if ($mode === false) {
01201 global $ADODB_FETCH_MODE;
01202 $mode = $ADODB_FETCH_MODE;
01203 }
01204 switch ($mode)
01205 {
01206 case ADODB_FETCH_ASSOC:$this->fetchMode = OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS; break;
01207 case ADODB_FETCH_DEFAULT:
01208 case ADODB_FETCH_BOTH:$this->fetchMode = OCI_NUM+OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS; break;
01209 case ADODB_FETCH_NUM:
01210 default:
01211 $this->fetchMode = OCI_NUM+OCI_RETURN_NULLS+OCI_RETURN_LOBS; break;
01212 }
01213
01214 $this->adodbFetchMode = $mode;
01215 $this->_queryID = $queryID;
01216 }
01217
01218
01219 function Init()
01220 {
01221 if ($this->_inited) return;
01222
01223 $this->_inited = true;
01224 if ($this->_queryID) {
01225
01226 $this->_currentRow = 0;
01227 @$this->_initrs();
01228 $this->EOF = !$this->_fetch();
01229
01230
01231
01232
01233
01234
01235
01236
01237 if (!is_array($this->fields)) {
01238 $this->_numOfRows = 0;
01239 $this->fields = array();
01240 }
01241 } else {
01242 $this->fields = array();
01243 $this->_numOfRows = 0;
01244 $this->_numOfFields = 0;
01245 $this->EOF = true;
01246 }
01247 }
01248
01249 function _initrs()
01250 {
01251 $this->_numOfRows = -1;
01252 $this->_numOfFields = OCInumcols($this->_queryID);
01253 if ($this->_numOfFields>0) {
01254 $this->_fieldobjs = array();
01255 $max = $this->_numOfFields;
01256 for ($i=0;$i<$max; $i++) $this->_fieldobjs[] = $this->_FetchField($i);
01257 }
01258 }
01259
01260
01261
01262
01263
01264
01265 function &_FetchField($fieldOffset = -1)
01266 {
01267 $fld = new ADOFieldObject;
01268 $fieldOffset += 1;
01269 $fld->name =OCIcolumnname($this->_queryID, $fieldOffset);
01270 $fld->type = OCIcolumntype($this->_queryID, $fieldOffset);
01271 $fld->max_length = OCIcolumnsize($this->_queryID, $fieldOffset);
01272 if ($fld->type == 'NUMBER') {
01273 $p = OCIColumnPrecision($this->_queryID, $fieldOffset);
01274 $sc = OCIColumnScale($this->_queryID, $fieldOffset);
01275 if ($p != 0 && $sc == 0) $fld->type = 'INT';
01276
01277 }
01278 return $fld;
01279 }
01280
01281
01282 function &FetchField($fieldOffset = -1)
01283 {
01284 return $this->_fieldobjs[$fieldOffset];
01285 }
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305 function MoveNext()
01306 {
01307 if (@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode)) {
01308 $this->_currentRow += 1;
01309 return true;
01310 }
01311 if (!$this->EOF) {
01312 $this->_currentRow += 1;
01313 $this->EOF = true;
01314 }
01315 return false;
01316 }
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353 function &GetArrayLimit($nrows,$offset=-1)
01354 {
01355 if ($offset <= 0) {
01356 $arr =& $this->GetArray($nrows);
01357 return $arr;
01358 }
01359 for ($i=1; $i < $offset; $i++)
01360 if (!@OCIFetch($this->_queryID)) return array();
01361
01362 if (!@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode)) return array();
01363 $results = array();
01364 $cnt = 0;
01365 while (!$this->EOF && $nrows != $cnt) {
01366 $results[$cnt++] = $this->fields;
01367 $this->MoveNext();
01368 }
01369
01370 return $results;
01371 }
01372
01373
01374
01375 function Fields($colname)
01376 {
01377 if (!$this->bind) {
01378 $this->bind = array();
01379 for ($i=0; $i < $this->_numOfFields; $i++) {
01380 $o = $this->FetchField($i);
01381 $this->bind[strtoupper($o->name)] = $i;
01382 }
01383 }
01384
01385 return $this->fields[$this->bind[strtoupper($colname)]];
01386 }
01387
01388
01389
01390 function _seek($row)
01391 {
01392 return false;
01393 }
01394
01395 function _fetch()
01396 {
01397 return @OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode);
01398 }
01399
01400
01401
01402
01403 function _close()
01404 {
01405 if ($this->connection->_stmt === $this->_queryID) $this->connection->_stmt = false;
01406 if (!empty($this->_refcursor)) {
01407 OCIFreeCursor($this->_refcursor);
01408 $this->_refcursor = false;
01409 }
01410 @OCIFreeStatement($this->_queryID);
01411 $this->_queryID = false;
01412
01413 }
01414
01415 function MetaType($t,$len=-1)
01416 {
01417 if (is_object($t)) {
01418 $fieldobj = $t;
01419 $t = $fieldobj->type;
01420 $len = $fieldobj->max_length;
01421 }
01422 switch (strtoupper($t)) {
01423 case 'VARCHAR':
01424 case 'VARCHAR2':
01425 case 'CHAR':
01426 case 'VARBINARY':
01427 case 'BINARY':
01428 case 'NCHAR':
01429 case 'NVARCHAR':
01430 case 'NVARCHAR2':
01431 if (isset($this) && $len <= $this->blobSize) return 'C';
01432
01433 case 'NCLOB':
01434 case 'LONG':
01435 case 'LONG VARCHAR':
01436 case 'CLOB':
01437 return 'X';
01438
01439 case 'LONG RAW':
01440 case 'LONG VARBINARY':
01441 case 'BLOB':
01442 return 'B';
01443
01444 case 'DATE':
01445 return ($this->connection->datetime) ? 'T' : 'D';
01446
01447
01448 case 'TIMESTAMP': return 'T';
01449
01450 case 'INT':
01451 case 'SMALLINT':
01452 case 'INTEGER':
01453 return 'I';
01454
01455 default: return 'N';
01456 }
01457 }
01458 }
01459
01460 class ADORecordSet_ext_oci8 extends ADORecordSet_oci8 {
01461 function ADORecordSet_ext_oci8($queryID,$mode=false)
01462 {
01463 if ($mode === false) {
01464 global $ADODB_FETCH_MODE;
01465 $mode = $ADODB_FETCH_MODE;
01466 }
01467 switch ($mode)
01468 {
01469 case ADODB_FETCH_ASSOC:$this->fetchMode = OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS; break;
01470 case ADODB_FETCH_DEFAULT:
01471 case ADODB_FETCH_BOTH:$this->fetchMode = OCI_NUM+OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS; break;
01472 case ADODB_FETCH_NUM:
01473 default: $this->fetchMode = OCI_NUM+OCI_RETURN_NULLS+OCI_RETURN_LOBS; break;
01474 }
01475 $this->adodbFetchMode = $mode;
01476 $this->_queryID = $queryID;
01477 }
01478
01479 function MoveNext()
01480 {
01481 return adodb_movenext($this);
01482 }
01483 }
01484 ?>