58     var 
$string_quoting = array(
'start' => 
"'", 
'end' => 
"'", 
'escape' => 
"'", 
'escape_pattern' => 
'@');
 
   73         $this->phptype = 
'oci8';
 
   74         $this->dbsyntax = 
'oci8';
 
   76         $this->supported[
'sequences'] = 
true;
 
   77         $this->supported[
'indexes'] = 
true;
 
   78         $this->supported[
'summary_functions'] = 
true;
 
   79         $this->supported[
'order_by_text'] = 
true;
 
   80         $this->supported[
'current_id'] = 
true;
 
   81         $this->supported[
'affected_rows'] = 
true;
 
   82         $this->supported[
'transactions'] = 
true;
 
   83         $this->supported[
'savepoints'] = 
true;
 
   84         $this->supported[
'limit_queries'] = 
true;
 
   85         $this->supported[
'LOBs'] = 
true;
 
   86         $this->supported[
'replace'] = 
'emulated';
 
   87         $this->supported[
'sub_selects'] = 
true;
 
   88         $this->supported[
'auto_increment'] = 
false; 
 
   89         $this->supported[
'primary_key'] = 
true;
 
   90         $this->supported[
'result_introspection'] = 
true;
 
   91         $this->supported[
'prepared_statements'] = 
true;
 
   92         $this->supported[
'identifier_quoting'] = 
true;
 
   93         $this->supported[
'pattern_escaping'] = 
true;
 
   94         $this->supported[
'new_link'] = 
true;
 
   96         $this->options[
'DBA_username'] = 
false;
 
   97         $this->options[
'DBA_password'] = 
false;
 
   98         $this->options[
'database_name_prefix'] = 
false;
 
   99         $this->options[
'emulate_database'] = 
true;
 
  100         $this->options[
'default_tablespace'] = 
false;
 
  101         $this->options[
'default_text_field_length'] = 2000;
 
  102         $this->options[
'result_prefetching'] = 
false;
 
  117         if (is_resource($error)) {
 
  118             $error_data = @OCIError($error);
 
  120         } elseif ($this->connection) {
 
  121             $error_data = @OCIError($this->connection);
 
  123             $error_data = @OCIError();
 
  125         $native_code = $error_data[
'code'];
 
  126         $native_msg  = $error_data[
'message'];
 
  127         if (is_null($error)) {
 
  129             if (empty($ecode_map)) {
 
  153             if (isset($ecode_map[$native_code])) {
 
  154                 $error = $ecode_map[$native_code];
 
  157         return array($error, $native_code, $native_msg);
 
  173         $this->
debug(
'Starting transaction/savepoint', __FUNCTION__, array(
'is_manip' => 
true, 
'savepoint' => $savepoint));
 
  174         if (!is_null($savepoint)) {
 
  175             if (!$this->in_transaction) {
 
  177                     'savepoint cannot be released when changes are auto committed', __FUNCTION__);
 
  179             $query = 
'SAVEPOINT '.$savepoint;
 
  181         } elseif ($this->in_transaction) {
 
  184         if (!$this->destructor_registered && $this->opened_persistent) {
 
  185             $this->destructor_registered = 
true;
 
  186             register_shutdown_function(
'MDB2_closeOpenTransactions');
 
  188         $this->in_transaction = 
true;
 
  209         $this->
debug(
'Committing transaction/savepoint', __FUNCTION__, array(
'is_manip' => 
true, 
'savepoint' => $savepoint));
 
  210         if (!$this->in_transaction) {
 
  212                 'commit/release savepoint cannot be done changes are auto committed', __FUNCTION__);
 
  214         if (!is_null($savepoint)) {
 
  218         if ($this->uncommitedqueries) {
 
  225                 'Unable to commit transaction', __FUNCTION__);
 
  227             $this->uncommitedqueries = 0;
 
  229         $this->in_transaction = 
false;
 
  249         $this->
debug(
'Rolling back transaction/savepoint', __FUNCTION__, array(
'is_manip' => 
true, 
'savepoint' => $savepoint));
 
  250         if (!$this->in_transaction) {
 
  252                 'rollback cannot be done changes are auto committed', __FUNCTION__);
 
  254         if (!is_null($savepoint)) {
 
  255             $query = 
'ROLLBACK TO SAVEPOINT '.$savepoint;
 
  259         if ($this->uncommitedqueries) {
 
  266                 'Unable to rollback transaction', __FUNCTION__);
 
  268             $this->uncommitedqueries = 0;
 
  270         $this->in_transaction = 
false;
 
  292         $this->
debug(
'Setting transaction isolation level', __FUNCTION__, array(
'is_manip' => 
true));
 
  293         switch ($isolation) {
 
  294         case 'READ UNCOMMITTED':
 
  295             $isolation = 
'READ COMMITTED';
 
  296         case 'READ COMMITTED':
 
  297         case 'REPEATABLE READ':
 
  298             $isolation = 
'SERIALIZABLE';
 
  303                 'isolation level is not supported: '.$isolation, __FUNCTION__);
 
  306         $query = 
"ALTER SESSION ISOLATION LEVEL $isolation";
 
  319     function _doConnect($username, $password, $persistent = 
false)
 
  323                 'extension '.$this->phptype.
' is not compiled into PHP', __FUNCTION__);
 
  328         if (!empty($this->dsn[
'service']) && $this->dsn[
'hostspec']) {
 
  332             $port = $this->dsn[
'port'] ? $this->dsn[
'port'] : 1521;
 
  333             $sid = sprintf(
"(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP) 
  334                             (HOST=%s) (PORT=%s))) 
  335                             (CONNECT_DATA=(SERVICE_NAME=%s)))",
 
  336                 $this->dsn[
'hostspec'],
 
  338                 $this->dsn[
'service']
 
  340         } elseif ($this->dsn[
'hostspec']) {
 
  344             $sid = $this->dsn[
'hostspec'];
 
  349             if (!$this->options[
'emulate_database'] && $this->database_name) {
 
  351             } elseif (getenv(
'ORACLE_SID')) {
 
  352                 $sid = getenv(
'ORACLE_SID');
 
  353             } elseif ($sid = getenv(
'TWO_TASK')) {
 
  354                 $sid = getenv(
'TWO_TASK');
 
  357                     'not a valid connection string or environment variable [ORACLE_SID|TWO_TASK] not set',
 
  362         if (function_exists(
'oci_connect')) {
 
  363             if (isset($this->dsn[
'new_link'])
 
  364                 && ($this->dsn[
'new_link'] == 
'true' || $this->dsn[
'new_link'] === 
true)
 
  366                 $connect_function = 
'oci_new_connect';
 
  368                 $connect_function = $persistent ? 
'oci_pconnect' : 
'oci_connect';
 
  371             $charset = empty($this->dsn[
'charset']) ? null : $this->dsn[
'charset'];
 
  372             $connection = @$connect_function($username, $password, $sid, $charset);
 
  373             $error = @OCIError();
 
  374             if (isset($error[
'code']) && $error[
'code'] == 12541) {
 
  376                 $connection = @$connect_function($username, $password, null, $charset);
 
  379             $connect_function = $persistent ? 
'OCIPLogon' : 
'OCILogon';
 
  380             $connection = @$connect_function($username, $password, $sid);
 
  382             if (!empty($this->dsn[
'charset'])) {
 
  392                 'unable to establish a connection', __FUNCTION__);
 
  395        if (empty($this->dsn[
'disable_iso_date'])) {
 
  396             $query = 
"ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'";
 
  404         $query = 
"ALTER SESSION SET NLS_NUMERIC_CHARACTERS='. '";
 
  425         if ($this->database_name && $this->options[
'emulate_database']) {
 
  426              $this->dsn[
'username'] = $this->options[
'database_name_prefix'].$this->database_name;
 
  428         if (is_resource($this->connection)) {
 
  429             if (count(array_diff($this->connected_dsn, $this->dsn)) == 0
 
  430                 && $this->connected_database_name == $this->database_name
 
  431                 && $this->opened_persistent == $this->options[
'persistent']
 
  439             $this->dsn[
'username'],
 
  440             $this->dsn[
'password'],
 
  441             $this->options[
'persistent']
 
  449         $this->opened_persistent = $this->options[
'persistent'];
 
  450         $this->dbsyntax = $this->dsn[
'dbsyntax'] ? $this->dsn[
'dbsyntax'] : 
$this->phptype;
 
  452         $this->as_keyword = 
' ';
 
  454         if (is_array($server_info)) {
 
  455             if ($server_info[
'major'] >= 
'10') {
 
  456                 $this->as_keyword = 
' AS ';
 
  476         if (is_resource($this->connection)) {
 
  477             if ($this->in_transaction) {
 
  480                 $persistent = $this->options[
'persistent'];
 
  487                 $this->options[
'persistent'] = $persistent;
 
  490             if (!$this->opened_persistent || $force) {
 
  491                 if (function_exists(
'oci_close')) {
 
  492                     @oci_close($this->connection);
 
  494                     @OCILogOff($this->connection);
 
  497             $this->uncommitedqueries = 0;
 
  515             $this->options[
'DBA_username'],
 
  516             $this->options[
'DBA_password'],
 
  517             $this->options[
'persistent']
 
  525         $this->offset = $this->limit = 0;
 
  555             $this->options[
'DBA_username'],
 
  556             $this->options[
'DBA_password'],
 
  557             $this->options[
'persistent']
 
  565         $this->offset = $this->limit = 0;
 
  576             return $affected_rows;
 
  597         if (preg_match(
'/^\s*SELECT/i', 
$query)) {
 
  598             if (!preg_match(
'/\sFROM\s/i', 
$query)) {
 
  606                     $query = 
"SELECT * FROM (SELECT a.*, ROWNUM mdb2rn FROM ($query) a WHERE ROWNUM <= $max) WHERE mdb2rn >= $min";
 
  608                     $query = 
"SELECT a.* FROM ($query) a WHERE ROWNUM <= $max";
 
  629         $this->last_query = 
$query;
 
  630         $result = $this->
debug(
$query, 
'query', array(
'is_manip' => $is_manip, 
'when' => 
'pre'));
 
  654                 'Could not create statement', __FUNCTION__);
 
  658         $mode = $this->in_transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS;
 
  659         if (!@OCIExecute(
$result, $mode)) {
 
  661                 'Could not execute statement', __FUNCTION__);
 
  665         if (is_numeric($this->options[
'result_prefetching'])) {
 
  666             @ocisetprefetch(
$result, $this->options[
'result_prefetching']);
 
  669         $this->
debug(
$query, 
'query', array(
'is_manip' => $is_manip, 
'when' => 
'post', 
'result' => 
$result));
 
  711         if ($this->connected_server_info) {
 
  718                 'Could not get server information', __FUNCTION__);
 
  721         $this->connected_server_info = $server_info;
 
  723             if (!preg_match(
'/ (\d+)\.(\d+)\.(\d+)\.([\d\.]+) /', $server_info, $tmp)) {
 
  725                     'Could not parse version information:'.$server_info, __FUNCTION__);
 
  727             $server_info = array(
 
  732                 'native' => $server_info,
 
  761     function &
prepare(
$query, $types = null, $result_types = null, $lobs = array())
 
  763         if ($this->options[
'emulate_prepared']) {
 
  770         $this->offset = $this->limit = 0;
 
  771         $result = $this->
debug(
$query, __FUNCTION__, array(
'is_manip' => $is_manip, 
'when' => 
'pre'));
 
  779         $placeholder_type_guess = $placeholder_type = null;
 
  782         $positions = array();
 
  785         while ($position < strlen(
$query)) {
 
  786             $q_position = strpos(
$query, $question, $position);
 
  787             $c_position = strpos(
$query, $colon, $position);
 
  788             if ($q_position && $c_position) {
 
  789                 $p_position = min($q_position, $c_position);
 
  790             } elseif ($q_position) {
 
  791                 $p_position = $q_position;
 
  792             } elseif ($c_position) {
 
  793                 $p_position = $c_position;
 
  797             if (is_null($placeholder_type)) {
 
  798                 $placeholder_type_guess = 
$query[$p_position];
 
  805             if ($new_pos != $position) {
 
  806                 $position = $new_pos;
 
  810             if (
$query[$position] == $placeholder_type_guess) {
 
  811                 if (is_null($placeholder_type)) {
 
  812                     $placeholder_type = 
$query[$p_position];
 
  813                     $question = $colon = $placeholder_type;
 
  814                     if (!empty($types) && is_array($types)) {
 
  815                         if ($placeholder_type == 
':') {
 
  816                             if (is_int(key($types))) {
 
  822                             $types = array_values($types);
 
  826                 if ($placeholder_type == 
':') {
 
  827                     $parameter = preg_replace(
'/^.{'.($position+1).
'}([a-z0-9_]+).*$/si', 
'\\1', 
$query);
 
  828                     if ($parameter === 
'') {
 
  830                             'named parameter with an empty name', __FUNCTION__);
 
  834                     if (isset($count) && isset($types_tmp[++$count])) {
 
  835                         $types[$parameter] = $types_tmp[$count];
 
  837                     $length = strlen($parameter) + 1;
 
  840                     $length = strlen($parameter);
 
  842                 if (!in_array($parameter, $positions)) {
 
  843                     $positions[] = $parameter;
 
  845                 if (isset($types[$parameter])
 
  846                     && ($types[$parameter] == 
'clob' || $types[$parameter] == 
'blob')
 
  848                     if (!isset($lobs[$parameter])) {
 
  849                         $lobs[$parameter] = $parameter;
 
  851                     $value = $this->
quote(
true, $types[$parameter]);
 
  852                     $query = substr_replace(
$query, $value, $p_position, $length);
 
  853                     $position = $p_position + strlen($value) - 1;
 
  854                 } elseif ($placeholder_type == 
'?') {
 
  855                     $query = substr_replace(
$query, 
':'.$parameter, $p_position, 1);
 
  856                     $position = $p_position + $length;
 
  858                     $position = $p_position + 1;
 
  861                 $position = $p_position;
 
  864         if (is_array($lobs)) {
 
  866             foreach ($lobs as $parameter => $field) {
 
  868                 $variables.= ($variables ? 
', ' : 
' INTO ').
':'.$parameter;
 
  879                 'Could not create statement', __FUNCTION__);
 
  883         $class_name = 
'MDB2_Statement_'.$this->phptype;
 
  884         $obj =& 
new $class_name($this, $statement, $positions, 
$query, $types, $result_types, $is_manip, 
$limit, 
$offset);
 
  885         $this->
debug(
$query, __FUNCTION__, array(
'is_manip' => $is_manip, 
'when' => 
'post', 
'result' => $obj));
 
  902     function nextID($seq_name, $ondemand = 
true)
 
  905         $query = 
"SELECT $sequence_name.nextval FROM DUAL";
 
  912                 $result = $this->manager->createSequence($seq_name);
 
  916                 return $this->nextId($seq_name, 
false);
 
  936         $seq = $table.(empty($field) ? 
'' : 
'_'.$field);
 
  938         return $this->
queryOne(
"SELECT $sequence_name.currval", 
'integer');
 
  954         $query = 
'SELECT (last_number-1) FROM user_sequences';
 
  955         $query.= 
' WHERE sequence_name='.$this->quote($sequence_name, 
'text');
 
  956         $query.= 
' OR sequence_name='.$this->quote(strtoupper($sequence_name), 
'text');
 
  990             $fetchmode = $this->db->fetchmode;
 
  993             @OCIFetchInto($this->result, 
$row, OCI_ASSOC+OCI_RETURN_NULLS);
 
  997                 $row = array_change_key_case(
$row, $this->db->options[
'field_case']);
 
 1000             @OCIFetchInto($this->result, 
$row, OCI_RETURN_NULLS);
 
 1003             if ($this->result === 
false) {
 
 1005                     'resultset has already been freed', __FUNCTION__);
 
 1012         if ($this->offset > 0) {
 
 1018             if (empty($this->types)) {
 
 1025             $this->db->_fixResultArrayValues(
$row, $mode);
 
 1027         if (!empty($this->types)) {
 
 1028             $row = $this->db->datatype->convertResultRow($this->types, 
$row, $rtrim);
 
 1030         if (!empty($this->values)) {
 
 1034             $object_class = $this->db->options[
'fetch_class'];
 
 1035             if ($object_class == 
'stdClass') {
 
 1064         for ($column = 0; $column < $numcols; $column++) {
 
 1065             $column_name = @OCIColumnName($this->result, $column + 1);
 
 1069             $columns = array_change_key_case(
$columns, $this->db->options[
'field_case']);
 
 1086         $cols = @OCINumCols($this->result);
 
 1087         if (is_null($cols)) {
 
 1088             if ($this->result === 
false) {
 
 1090                     'resultset has already been freed', __FUNCTION__);
 
 1091             } elseif (is_null($this->result)) {
 
 1092                 return count($this->types);
 
 1094             return $this->db->raiseError(null, null, null,
 
 1095                 'Could not get column count', __FUNCTION__);
 
 1097         if ($this->offset > 0) {
 
 1114         if (is_resource($this->result) && $this->db->connection) {
 
 1115             $free = @OCIFreeCursor($this->result);
 
 1116             if ($free === 
false) {
 
 1117                 return $this->db->raiseError(null, null, null,
 
 1118                     'Could not free result', __FUNCTION__);
 
 1121         $this->result = 
false;
 
 1151         if (isset($this->buffer) && is_array($this->buffer)) {
 
 1153                 if (!end($this->buffer)) {
 
 1156             } elseif (isset($this->buffer[
$rownum])) {
 
 1157                 return (
bool)$this->buffer[
$rownum];
 
 1163             && (
$row = @OCIFetchInto($this->result, 
$buffer, OCI_RETURN_NULLS))
 
 1167             if ($this->offset > 0) {
 
 1170             if (empty($this->types)) {
 
 1171                 foreach (array_keys(
$buffer) as $key) {
 
 1172                     if (is_a(
$buffer[$key], 
'oci-lob')) {
 
 1201         if ($this->result === 
false) {
 
 1203                 'resultset has already been freed', __FUNCTION__);
 
 1205         } elseif (is_null($this->result)) {
 
 1214         $target_rownum = $this->rownum + 1;
 
 1216             $fetchmode = $this->db->fetchmode;
 
 1222         $row = $this->buffer[$target_rownum];
 
 1233             if (empty($this->types)) {
 
 1240             $this->db->_fixResultArrayValues(
$row, $mode);
 
 1242         if (!empty($this->types)) {
 
 1243             $row = $this->db->datatype->convertResultRow($this->types, 
$row, $rtrim);
 
 1245         if (!empty($this->values)) {
 
 1249             $object_class = $this->db->options[
'fetch_class'];
 
 1250             if ($object_class == 
'stdClass') {
 
 1272         if ($this->result === 
false) {
 
 1274                 'resultset has already been freed', __FUNCTION__);
 
 1291         if ($this->result === 
false) {
 
 1293                 'resultset has already been freed', __FUNCTION__);
 
 1294         } elseif (is_null($this->result)) {
 
 1314         if ($this->result === 
false) {
 
 1316                 'resultset has already been freed', __FUNCTION__);
 
 1317         } elseif (is_null($this->result)) {
 
 1335         $this->buffer = null;
 
 1336         $this->buffer_rownum = null;
 
 1361     function &
_execute($result_class = 
true, $result_wrap_class = 
false)
 
 1363         if (is_null($this->statement)) {
 
 1368         $this->db->debug($this->query, 
'execute', array(
'is_manip' => $this->is_manip, 
'when' => 
'pre', 
'parameters' => $this->values));
 
 1369         if ($this->db->getOption(
'disable_query')) {
 
 1370             $result = $this->is_manip ? 0 : null;
 
 1374         $connection = $this->db->getConnection();
 
 1380         $lobs = $quoted_values = array();
 
 1382         foreach ($this->positions as $parameter) {
 
 1383             if (!array_key_exists($parameter, $this->values)) {
 
 1385                     'Unable to bind to missing placeholder: '.$parameter, __FUNCTION__);
 
 1387             $value = $this->values[$parameter];
 
 1388             $type = array_key_exists($parameter, $this->types) ? $this->types[$parameter] : null;
 
 1389             if ($type == 
'clob' || $type == 
'blob') {
 
 1390                 $lobs[$i][
'file'] = 
false;
 
 1391                 if (is_resource($value)) {
 
 1394                     while (!feof($fp)) {
 
 1395                         $value.= fread($fp, 8192);
 
 1397                 } elseif (preg_match(
'/^(\w+:\/\/)(.*)$/', $value, $match)) {
 
 1405                 $lobs[$i][
'value'] = $value;
 
 1406                 $lobs[$i][
'descriptor'] = @OCINewDescriptor($connection, OCI_D_LOB);
 
 1407                 if (!is_object($lobs[$i][
'descriptor'])) {
 
 1408                     $result = $this->db->raiseError(null, null, null,
 
 1409                         'Unable to create descriptor for LOB in parameter: '.$parameter, __FUNCTION__);
 
 1412                 $lob_type = ($type == 
'blob' ? OCI_B_BLOB : OCI_B_CLOB);
 
 1413                 if (!@OCIBindByName($this->statement, 
':'.$parameter, $lobs[$i][
'descriptor'], -1, $lob_type)) {
 
 1414                     $result = $this->db->raiseError($this->statement, null, null,
 
 1415                         'could not bind LOB parameter', __FUNCTION__);
 
 1419                 $quoted_values[$i] = $this->db->quote($value, $type, 
false);
 
 1421                     return $quoted_values[$i];
 
 1423                 if (!@OCIBindByName($this->statement, 
':'.$parameter, $quoted_values[$i])) {
 
 1424                     $result = $this->db->raiseError($this->statement, null, null,
 
 1425                         'could not bind non LOB parameter', __FUNCTION__);
 
 1432         $lob_keys = array_keys($lobs);
 
 1434             $mode = (!empty($lobs) || $this->db->in_transaction) ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS;
 
 1435             if (!@OCIExecute($this->statement, $mode)) {
 
 1436                 $err =& $this->db->raiseError($this->statement, null, null,
 
 1437                     'could not execute statement', __FUNCTION__);
 
 1441             if (!empty($lobs)) {
 
 1442                 foreach ($lob_keys as $i) {
 
 1443                     if (!is_null($lobs[$i][
'value']) && $lobs[$i][
'value'] !== 
'') {
 
 1444                         if ($lobs[$i][
'file']) {
 
 1445                             $result = $lobs[$i][
'descriptor']->savefile($lobs[$i][
'value']);
 
 1447                             $result = $lobs[$i][
'descriptor']->save($lobs[$i][
'value']);
 
 1450                             $result = $this->db->raiseError(null, null, null,
 
 1451                                 'Unable to save descriptor contents', __FUNCTION__);
 
 1458                     if (!$this->db->in_transaction) {
 
 1459                         if (!@OCICommit($connection)) {
 
 1460                             $result = $this->db->raiseError(null, null, null,
 
 1461                                 'Unable to commit transaction', __FUNCTION__);
 
 1464                         ++$this->db->uncommitedqueries;
 
 1470         $lob_keys = array_keys($lobs);
 
 1471         foreach ($lob_keys as $i) {
 
 1472             $lobs[$i][
'descriptor']->free();
 
 1479         if ($this->is_manip) {
 
 1480             $affected_rows = $this->db->_affectedRows($connection, $this->statement);
 
 1481             return $affected_rows;
 
 1484         $result =& $this->db->_wrapResult($this->statement, $this->result_types,
 
 1485             $result_class, $result_wrap_class, $this->limit, $this->offset);
 
 1486         $this->db->debug($this->query, 
'execute', array(
'is_manip' => $this->is_manip, 
'when' => 
'post', 
'result' => 
$result));
 
 1501         if (is_null($this->positions)) {
 
 1502             return $this->db->raiseError(
MDB2_ERROR, null, null,
 
 1503                 'Prepared statement has already been freed', __FUNCTION__);
 
 1507         if (!is_null($this->statement) && !@OCIFreeStatement($this->statement)) {
 
 1508             $result = $this->db->raiseError(null, null, null,
 
 1509                 'Could not free statement', __FUNCTION__);