DB
[ class tree: DB ] [ index: DB ] [ all elements ]

Source for file oci8.php

Documentation is available at oci8.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Author: James L. Pine <jlp@valinux.com>                              |
  17. // | Maintainer: Daniel Convissor <danielc@php.net>                       |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: oci8.php,v 1.64 2004/03/25 17:12:03 danielc Exp $
  21.  
  22.  
  23. // be aware...  OCIError() only appears to return anything when given a
  24. // statement, so functions return the generic DB_ERROR instead of more
  25. // useful errors that have to do with feedback from the database.
  26.  
  27.  
  28. require_once 'DB/common.php';
  29.  
  30. /**
  31.  * Database independent query interface definition for PHP's Oracle 8
  32.  * call-interface extension.
  33.  *
  34.  * Definitely works with versions 8 and 9 of Oracle.
  35.  *
  36.  * @package  DB
  37.  * @version  $Id: oci8.php,v 1.64 2004/03/25 17:12:03 danielc Exp $
  38.  * @category Database
  39.  * @author   James L. Pine <jlp@valinux.com>
  40.  */
  41. class DB_oci8 extends DB_common
  42. {
  43.     // {{{ properties
  44.  
  45.     var $connection;
  46.     var $phptype$dbsyntax;
  47.     var $manip_query = array();
  48.     var $prepare_types = array();
  49.     var $autoCommit = 1;
  50.     var $last_stmt = false;
  51.  
  52.     /**
  53.      * stores the $data passed to execute() in the oci8 driver
  54.      *
  55.      * Gets reset to array() when simpleQuery() is run.
  56.      *
  57.      * Needed in case user wants to call numRows() after prepare/execute
  58.      * was used.
  59.      *
  60.      * @var array 
  61.      * @access private
  62.      */
  63.     var $_data = array();
  64.  
  65.     // }}}
  66.     // {{{ constructor
  67.  
  68.     function DB_oci8()
  69.     {
  70.         $this->DB_common();
  71.         $this->phptype = 'oci8';
  72.         $this->dbsyntax = 'oci8';
  73.         $this->features = array(
  74.             'prepare' => false,
  75.             'pconnect' => true,
  76.             'transactions' => true,
  77.             'limit' => 'alter'
  78.         );
  79.         $this->errorcode_map = array(
  80.             1 => DB_ERROR_CONSTRAINT,
  81.             900 => DB_ERROR_SYNTAX,
  82.             904 => DB_ERROR_NOSUCHFIELD,
  83.             921 => DB_ERROR_SYNTAX,
  84.             923 => DB_ERROR_SYNTAX,
  85.             942 => DB_ERROR_NOSUCHTABLE,
  86.             955 => DB_ERROR_ALREADY_EXISTS,
  87.             1400 => DB_ERROR_CONSTRAINT_NOT_NULL,
  88.             1407 => DB_ERROR_CONSTRAINT_NOT_NULL,
  89.             1476 => DB_ERROR_DIVZERO,
  90.             1722 => DB_ERROR_INVALID_NUMBER,
  91.             2289 => DB_ERROR_NOSUCHTABLE,
  92.             2291 => DB_ERROR_CONSTRAINT,
  93.             2449 => DB_ERROR_CONSTRAINT,
  94.         );
  95.     }
  96.  
  97.     // }}}
  98.     // {{{ connect()
  99.  
  100.     /**
  101.      * Connect to a database and log in as the specified user.
  102.      *
  103.      * @param $dsn the data source name (see DB::parseDSN for syntax)
  104.      * @param $persistent (optional) whether the connection should
  105.      *         be persistent
  106.      *
  107.      * @return int DB_OK on success, a DB error code on failure
  108.      */
  109.     function connect($dsninfo$persistent = false)
  110.     {
  111.         if (!DB::assertExtension('oci8')) {
  112.             return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
  113.         }
  114.         $this->dsn $dsninfo;
  115.  
  116.         $connect_function $persistent 'OCIPLogon' 'OCILogon';
  117.  
  118.         if ($dsninfo['hostspec']{
  119.             $conn @$connect_function($dsninfo['username'],
  120.                                        $dsninfo['password'],
  121.                                        $dsninfo['hostspec']);
  122.         elseif ($dsninfo['username'|| $dsninfo['password']{
  123.             $conn @$connect_function($dsninfo['username'],
  124.                                        $dsninfo['password']);
  125.         else {
  126.             $conn = false;
  127.         }
  128.         if ($conn == false{
  129.             $error = OCIError();
  130.             $error (is_array($error)) $error['message': null;
  131.             return $this->raiseError(DB_ERROR_CONNECT_FAILEDnullnull,
  132.                                      null$error);
  133.         }
  134.         $this->connection = $conn;
  135.         return DB_OK;
  136.     }
  137.  
  138.     // }}}
  139.     // {{{ disconnect()
  140.  
  141.     /**
  142.      * Log out and disconnect from the database.
  143.      *
  144.      * @return bool true on success, false if not connected.
  145.      */
  146.     function disconnect()
  147.     {
  148.         $ret @OCILogOff($this->connection);
  149.         $this->connection = null;
  150.         return $ret;
  151.     }
  152.  
  153.     // }}}
  154.     // {{{ simpleQuery()
  155.  
  156.     /**
  157.      * Send a query to oracle and return the results as an oci8 resource
  158.      * identifier.
  159.      *
  160.      * @param $query the SQL query
  161.      *
  162.      * @return int returns a valid oci8 result for successful SELECT
  163.      *  queries, DB_OK for other successful queries.  A DB error code
  164.      *  is returned on failure.
  165.      */
  166.     function simpleQuery($query)
  167.     {
  168.         $this->_data = array();
  169.         $this->last_query = $query;
  170.         $query $this->modifyQuery($query);
  171.         $result @OCIParse($this->connection$query);
  172.         if (!$result{
  173.             return $this->oci8RaiseError();
  174.         }
  175.         if ($this->autoCommit{
  176.             $success @OCIExecute($result,OCI_COMMIT_ON_SUCCESS);
  177.         else {
  178.             $success @OCIExecute($result,OCI_DEFAULT);
  179.         }
  180.         if (!$success{
  181.             return $this->oci8RaiseError($result);
  182.         }
  183.         $this->last_stmt=$result;
  184.         // Determine which queries that should return data, and which
  185.         // should return an error code only.
  186.         return DB::isManip($queryDB_OK : $result;
  187.     }
  188.  
  189.     // }}}
  190.     // {{{ nextResult()
  191.  
  192.     /**
  193.      * Move the internal oracle result pointer to the next available result
  194.      *
  195.      * @param valid oci8 result resource
  196.      *
  197.      * @access public
  198.      *
  199.      * @return true if a result is available otherwise return false
  200.      */
  201.     function nextResult($result)
  202.     {
  203.         return false;
  204.     }
  205.  
  206.     // }}}
  207.     // {{{ fetchInto()
  208.  
  209.     /**
  210.      * Fetch a row and insert the data into an existing array.
  211.      *
  212.      * Formating of the array and the data therein are configurable.
  213.      * See DB_result::fetchInto() for more information.
  214.      *
  215.      * @param resource $result    query result identifier
  216.      * @param array    $arr       (reference) array where data from the row
  217.      *                             should be placed
  218.      * @param int      $fetchmode how the resulting array should be indexed
  219.      * @param int      $rownum    the row number to fetch
  220.      *
  221.      * @return mixed DB_OK on success, null when end of result set is
  222.      *                reached or on failure
  223.      *
  224.      * @see DB_result::fetchInto()
  225.      * @access private
  226.      */
  227.     function fetchInto($result&$arr$fetchmode$rownum=null)
  228.     {
  229.         if ($rownum !== null{
  230.             return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  231.         }
  232.         if ($fetchmode DB_FETCHMODE_ASSOC{
  233.             $moredata @OCIFetchInto($result,$arr,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS);
  234.             if ($this->options['portability'DB_PORTABILITY_LOWERCASE &&
  235.                 $moredata)
  236.             {
  237.                 $arr array_change_key_case($arrCASE_LOWER);
  238.             }
  239.         else {
  240.             $moredata = OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS);
  241.         }
  242.         if (!$moredata{
  243.             return null;
  244.         }
  245.         if ($this->options['portability'DB_PORTABILITY_RTRIM{
  246.             $this->_rtrimArrayValues($arr);
  247.         }
  248.         if ($this->options['portability'DB_PORTABILITY_NULL_TO_EMPTY{
  249.             $this->_convertNullArrayValuesToEmpty($arr);
  250.         }
  251.         return DB_OK;
  252.     }
  253.  
  254.     // }}}
  255.     // {{{ freeResult()
  256.  
  257.     /**
  258.      * Free the internal resources associated with $result.
  259.      *
  260.      * @param $result oci8 result identifier
  261.      *
  262.      * @return bool true on success, false if $result is invalid
  263.      */
  264.     function freeResult($result)
  265.     {
  266.         return @OCIFreeStatement($result);
  267.     }
  268.  
  269.     /**
  270.      * Free the internal resources associated with a prepared query.
  271.      *
  272.      * @param $stmt oci8 statement identifier
  273.      *
  274.      * @return bool true on success, false if $result is invalid
  275.      */
  276.     function freePrepared($stmt)
  277.     {
  278.         if (isset($this->prepare_types[(int)$stmt])) {
  279.             unset($this->prepare_types[(int)$stmt]);
  280.             unset($this->manip_query[(int)$stmt]);
  281.         else {
  282.             return false;
  283.         }
  284.         return true;
  285.     }
  286.  
  287.     // }}}
  288.     // {{{ numRows()
  289.  
  290.     function numRows($result)
  291.     {
  292.         // emulate numRows for Oracle.  yuck.
  293.         if ($this->options['portability'DB_PORTABILITY_NUMROWS &&
  294.             $result === $this->last_stmt)
  295.         {
  296.             $countquery 'SELECT COUNT(*) FROM ('.$this->last_query.')';
  297.             $save_query $this->last_query;
  298.             $save_stmt $this->last_stmt;
  299.  
  300.             if (count($this->_data)) {
  301.                 $smt $this->prepare('SELECT COUNT(*) FROM ('.$this->last_query.')');
  302.                 $count $this->execute($smt$this->_data);
  303.             else {
  304.                 $count =$this->query($countquery);
  305.             }
  306.  
  307.             if (DB::isError($count||
  308.                 DB::isError($row $count->fetchRow(DB_FETCHMODE_ORDERED)))
  309.             {
  310.                 $this->last_query = $save_query;
  311.                 $this->last_stmt = $save_stmt;
  312.                 return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  313.             }
  314.             return $row[0];
  315.         }
  316.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  317.     }
  318.  
  319.     // }}}
  320.     // {{{ numCols()
  321.  
  322.     /**
  323.      * Get the number of columns in a result set.
  324.      *
  325.      * @param $result oci8 result identifier
  326.      *
  327.      * @return int the number of columns per row in $result
  328.      */
  329.     function numCols($result)
  330.     {
  331.         $cols @OCINumCols($result);
  332.         if (!$cols{
  333.             return $this->oci8RaiseError($result);
  334.         }
  335.         return $cols;
  336.     }
  337.  
  338.     // }}}
  339.     // {{{ errorNative()
  340.  
  341.     /**
  342.      * Get the native error code of the last error (if any) that occured
  343.      * on the current connection.  This does not work, as OCIError does
  344.      * not work unless given a statement.  If OCIError does return
  345.      * something, so will this.
  346.      *
  347.      * @return int native oci8 error code
  348.      */
  349.     function errorNative()
  350.     {
  351.         if (is_resource($this->last_stmt)) {
  352.             $error @OCIError($this->last_stmt);
  353.         else {
  354.             $error @OCIError($this->connection);
  355.         }
  356.         if (is_array($error)) {
  357.             return $error['code'];
  358.         }
  359.         return false;
  360.     }
  361.  
  362.     // }}}
  363.     // {{{ prepare()
  364.  
  365.     /**
  366.      * Prepares a query for multiple execution with execute().
  367.      *
  368.      * With oci8, this is emulated.
  369.      *
  370.      * prepare() requires a generic query as string like <code>
  371.      *    INSERT INTO numbers VALUES (?, ?, ?)
  372.      * </code>.  The <kbd>?</kbd> characters are placeholders.
  373.      *
  374.      * Three types of placeholders can be used:
  375.      *   + <kbd>?</kbd>  a quoted scalar value, i.e. strings, integers
  376.      *   + <kbd>!</kbd>  value is inserted 'as is'
  377.      *   + <kbd>&</kbd>  requires a file name.  The file's contents get
  378.      *                     inserted into the query (i.e. saving binary
  379.      *                     data in a db)
  380.      *
  381.      * Use backslashes to escape placeholder characters if you don't want
  382.      * them to be interpreted as placeholders.  Example: <code>
  383.      *    "UPDATE foo SET col=? WHERE col='over \& under'"
  384.      * </code>
  385.      *
  386.      * @param string $query query to be prepared
  387.      * @return mixed DB statement resource on success. DB_Error on failure.
  388.      */
  389.     function prepare($query)
  390.     {
  391.         $tokens   preg_split('/((?<!\\\)[&?!])/'$query-1,
  392.                                PREG_SPLIT_DELIM_CAPTURE);
  393.         $binds    count($tokens- 1;
  394.         $token    = 0;
  395.         $types    = array();
  396.         $newquery '';
  397.  
  398.         foreach ($tokens as $key => $val{
  399.             switch ($val{
  400.                 case '?':
  401.                     $types[$token++DB_PARAM_SCALAR;
  402.                     unset($tokens[$key]);
  403.                     break;
  404.                 case '&':
  405.                     $types[$token++DB_PARAM_OPAQUE;
  406.                     unset($tokens[$key]);
  407.                     break;
  408.                 case '!':
  409.                     $types[$token++DB_PARAM_MISC;
  410.                     unset($tokens[$key]);
  411.                     break;
  412.                 default:
  413.                     $tokens[$keypreg_replace('/\\\([&?!])/'"\\1"$val);
  414.                     if ($key != $binds{
  415.                         $newquery .= $tokens[$key':bind' $token;
  416.                     else {
  417.                         $newquery .= $tokens[$key];
  418.                     }
  419.             }
  420.         }
  421.  
  422.         $this->last_query = $query;
  423.         $newquery $this->modifyQuery($newquery);
  424.         if (!$stmt @OCIParse($this->connection$newquery)) {
  425.             return $this->oci8RaiseError();
  426.         }
  427.         $this->prepare_types[$stmt$types;
  428.         $this->manip_query[(int)$stmtDB::isManip($query);
  429.         return $stmt;
  430.     }
  431.  
  432.     // }}}
  433.     // {{{ execute()
  434.  
  435.     /**
  436.      * Executes a DB statement prepared with prepare().
  437.      *
  438.      * @param resource  $stmt  a DB statement resource returned from prepare()
  439.      * @param mixed  $data  array, string or numeric data to be used in
  440.      *                       execution of the statement.  Quantity of items
  441.      *                       passed must match quantity of placeholders in
  442.      *                       query:  meaning 1 for non-array items or the
  443.      *                       quantity of elements in the array.
  444.      * @return int returns an oci8 result resource for successful
  445.      *  SELECT queries, DB_OK for other successful queries.  A DB error
  446.      *  code is returned on failure.
  447.      * @see DB_oci::prepare()
  448.      */
  449.     function &execute($stmt$data = array())
  450.     {
  451.         if (!is_array($data)) {
  452.             $data = array($data);
  453.         }
  454.  
  455.         $this->_data $data;
  456.  
  457.         $types =$this->prepare_types[$stmt];
  458.         if (count($types!= count($data)) {
  459.             $tmp =$this->raiseError(DB_ERROR_MISMATCH);
  460.             return $tmp;
  461.         }
  462.  
  463.         $i = 0;
  464.         foreach ($data as $key => $value{
  465.             if ($types[$i== DB_PARAM_MISC{
  466.                 /*
  467.                  * Oracle doesn't seem to have the ability to pass a
  468.                  * parameter along unchanged, so strip off quotes from start
  469.                  * and end, plus turn two single quotes to one single quote,
  470.                  * in order to avoid the quotes getting escaped by
  471.                  * Oracle and ending up in the database.
  472.                  */
  473.                 $data[$keypreg_replace("/^'(.*)'$/""\\1"$data[$key]);
  474.                 $data[$keystr_replace("''""'"$data[$key]);
  475.             elseif ($types[$i== DB_PARAM_OPAQUE{
  476.                 $fp @fopen($data[$key]'rb');
  477.                 if (!$fp{
  478.                     $tmp =$this->raiseError(DB_ERROR_ACCESS_VIOLATION);
  479.                     return $tmp;
  480.                 }
  481.                 $data[$keyfread($fpfilesize($data[$key]));
  482.                 fclose($fp);
  483.             }
  484.             if (!@OCIBindByName($stmt':bind' $i$data[$key]-1)) {
  485.                 $tmp $this->oci8RaiseError($stmt);
  486.                 return $tmp;
  487.             }
  488.             $i++;
  489.         }
  490.         if ($this->autoCommit{
  491.             $success @OCIExecute($stmtOCI_COMMIT_ON_SUCCESS);
  492.         else {
  493.             $success @OCIExecute($stmtOCI_DEFAULT);
  494.         }
  495.         if (!$success{
  496.             $tmp $this->oci8RaiseError($stmt);
  497.             return $tmp;
  498.         }
  499.         $this->last_stmt = $stmt;
  500.         if ($this->manip_query[(int)$stmt]{
  501.             $tmp DB_OK;
  502.         else {
  503.             $tmp =new DB_result($this$stmt);
  504.         }
  505.         return $tmp;
  506.     }
  507.  
  508.     // }}}
  509.     // {{{ autoCommit()
  510.  
  511.     /**
  512.      * Enable/disable automatic commits
  513.      *
  514.      * @param $onoff true/false whether to autocommit
  515.      */
  516.     function autoCommit($onoff = false)
  517.     {
  518.         $this->autoCommit = (bool)$onoff;;
  519.         return DB_OK;
  520.     }
  521.  
  522.     // }}}
  523.     // {{{ commit()
  524.  
  525.     /**
  526.      * Commit transactions on the current connection
  527.      *
  528.      * @return DB_ERROR or DB_OK
  529.      */
  530.     function commit()
  531.     {
  532.         $result @OCICommit($this->connection);
  533.         if (!$result{
  534.             return $this->oci8RaiseError();
  535.         }
  536.         return DB_OK;
  537.     }
  538.  
  539.     // }}}
  540.     // {{{ rollback()
  541.  
  542.     /**
  543.      * Roll back all uncommitted transactions on the current connection.
  544.      *
  545.      * @return DB_ERROR or DB_OK
  546.      */
  547.     function rollback()
  548.     {
  549.         $result @OCIRollback($this->connection);
  550.         if (!$result{
  551.             return $this->oci8RaiseError();
  552.         }
  553.         return DB_OK;
  554.     }
  555.  
  556.     // }}}
  557.     // {{{ affectedRows()
  558.  
  559.     /**
  560.      * Gets the number of rows affected by the last query.
  561.      * if the last query was a select, returns 0.
  562.      *
  563.      * @return number of rows affected by the last query or DB_ERROR
  564.      */
  565.     function affectedRows()
  566.     {
  567.         if ($this->last_stmt === false{
  568.             return $this->oci8RaiseError();
  569.         }
  570.         $result @OCIRowCount($this->last_stmt);
  571.         if ($result === false{
  572.             return $this->oci8RaiseError($this->last_stmt);
  573.         }
  574.         return $result;
  575.     }
  576.  
  577.     // }}}
  578.     // {{{ modifyQuery()
  579.  
  580.     function modifyQuery($query)
  581.     {
  582.         // "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle
  583.         if (preg_match('/^\s*SELECT/i'$query&&
  584.             !preg_match('/\sFROM\s/i'$query)) {
  585.             $query .= ' FROM dual';
  586.         }
  587.         return $query;
  588.     }
  589.  
  590.     // }}}
  591.     // {{{ modifyLimitQuery()
  592.  
  593.     /**
  594.      * Emulate the row limit support altering the query
  595.      *
  596.      * @param string $query The query to treat
  597.      * @param int    $from  The row to start to fetch from
  598.      * @param int    $count The offset
  599.      * @return string The modified query
  600.      *
  601.      * @author Tomas V.V.Cox <cox@idecnet.com>
  602.      */
  603.     function modifyLimitQuery($query$from$count$params = array())
  604.     {
  605.         // Let Oracle return the name of the columns instead of
  606.         // coding a "home" SQL parser
  607.  
  608.         if (count($params)) {
  609.             $result $this->prepare("SELECT * FROM ($query"
  610.                                      . 'WHERE NULL = NULL');
  611.             $tmp =$this->execute($result$params);
  612.         else {
  613.             $q_fields = "SELECT * FROM ($query) WHERE NULL = NULL";
  614.  
  615.             if (!$result @OCIParse($this->connection$q_fields)) {
  616.                 $this->last_query = $q_fields;
  617.                 return $this->oci8RaiseError();
  618.             }
  619.             if (!@OCIExecute($resultOCI_DEFAULT)) {
  620.                 $this->last_query = $q_fields;
  621.                 return $this->oci8RaiseError($result);
  622.             }
  623.         }
  624.  
  625.         $ncols = OCINumCols($result);
  626.         $cols  = array();
  627.         for $i = 1; $i <= $ncols$i++ {
  628.             $cols['"' . OCIColumnName($result$i'"';
  629.         }
  630.         $fields implode(', '$cols);
  631.         // XXX Test that (tip by John Lim)
  632.         //if (preg_match('/^\s*SELECT\s+/is', $query, $match)) {
  633.         //    // Introduce the FIRST_ROWS Oracle query optimizer
  634.         //    $query = substr($query, strlen($match[0]), strlen($query));
  635.         //    $query = "SELECT /* +FIRST_ROWS */ " . $query;
  636.         //}
  637.  
  638.         // Construct the query
  639.         // more at: http://marc.theaimsgroup.com/?l=php-db&m=99831958101212&w=2
  640.         // Perhaps this could be optimized with the use of Unions
  641.         $query = "SELECT $fields FROM".
  642.                  "  (SELECT rownum as linenum, $fields FROM".
  643.                  "      ($query)".
  644.                  '  WHERE rownum <= '($from $count.
  645.                  ') WHERE linenum >= ' . ++$from;
  646.         return $query;
  647.     }
  648.  
  649.     // }}}
  650.     // {{{ nextId()
  651.  
  652.     /**
  653.      * Returns the next free id in a sequence
  654.      *
  655.      * @param string  $seq_name  name of the sequence
  656.      * @param boolean $ondemand  when true, the seqence is automatically
  657.      *                            created if it does not exist
  658.      *
  659.      * @return int  the next id number in the sequence.  DB_Error if problem.
  660.      *
  661.      * @internal
  662.      * @see DB_common::nextID()
  663.      * @access public
  664.      */
  665.     function nextId($seq_name$ondemand = true)
  666.     {
  667.         $seqname $this->getSequenceName($seq_name);
  668.         $repeat = 0;
  669.         do {
  670.             $this->expectError(DB_ERROR_NOSUCHTABLE);
  671.             $result =$this->query("SELECT ${seqname}.nextval FROM dual");
  672.             $this->popExpect();
  673.             if ($ondemand && DB::isError($result&&
  674.                 $result->getCode(== DB_ERROR_NOSUCHTABLE{
  675.                 $repeat = 1;
  676.                 $result $this->createSequence($seq_name);
  677.                 if (DB::isError($result)) {
  678.                     return $this->raiseError($result);
  679.                 }
  680.             else {
  681.                 $repeat = 0;
  682.             }
  683.         while ($repeat);
  684.         if (DB::isError($result)) {
  685.             return $this->raiseError($result);
  686.         }
  687.         $arr $result->fetchRow(DB_FETCHMODE_ORDERED);
  688.         return $arr[0];
  689.     }
  690.  
  691.     /**
  692.      * Creates a new sequence
  693.      *
  694.      * @param string $seq_name  name of the new sequence
  695.      *
  696.      * @return int  DB_OK on success.  A DB_Error object is returned if
  697.      *               problems arise.
  698.      *
  699.      * @internal
  700.      * @see DB_common::createSequence()
  701.      * @access public
  702.      */
  703.     function createSequence($seq_name)
  704.     {
  705.         $seqname $this->getSequenceName($seq_name);
  706.         return $this->query("CREATE SEQUENCE ${seqname}");
  707.     }
  708.  
  709.     // }}}
  710.     // {{{ dropSequence()
  711.  
  712.     /**
  713.      * Deletes a sequence
  714.      *
  715.      * @param string $seq_name  name of the sequence to be deleted
  716.      *
  717.      * @return int  DB_OK on success.  DB_Error if problems.
  718.      *
  719.      * @internal
  720.      * @see DB_common::dropSequence()
  721.      * @access public
  722.      */
  723.     function dropSequence($seq_name)
  724.     {
  725.         $seqname $this->getSequenceName($seq_name);
  726.         return $this->query("DROP SEQUENCE ${seqname}");
  727.     }
  728.  
  729.     // }}}
  730.     // {{{ oci8RaiseError()
  731.  
  732.     /**
  733.      * Gather information about an error, then use that info to create a
  734.      * DB error object and finally return that object.
  735.      *
  736.      * @param  integer  $errno  PEAR error number (usually a DB constant) if
  737.      *                           manually raising an error
  738.      * @return object  DB error object
  739.      * @see DB_common::errorCode()
  740.      * @see DB_common::raiseError()
  741.      */
  742.     function oci8RaiseError($errno = null)
  743.     {
  744.         if ($errno === null{
  745.             $error @OCIError($this->connection);
  746.             return $this->raiseError($this->errorCode($error['code']),
  747.                                      nullnullnull$error['message']);
  748.         elseif (is_resource($errno)) {
  749.             $error @OCIError($errno);
  750.             return $this->raiseError($this->errorCode($error['code']),
  751.                                      nullnullnull$error['message']);
  752.         }
  753.         return $this->raiseError($this->errorCode($errno));
  754.     }
  755.  
  756.     // }}}
  757.     // {{{ getSpecialQuery()
  758.  
  759.     /**
  760.      * Returns the query needed to get some backend info
  761.      * @param string $type What kind of info you want to retrieve
  762.      * @return string The SQL query string
  763.      */
  764.     function getSpecialQuery($type)
  765.     {
  766.         switch ($type{
  767.             case 'tables':
  768.                 return 'SELECT table_name FROM user_tables';
  769.             default:
  770.                 return null;
  771.         }
  772.     }
  773.  
  774.     // }}}
  775.     // {{{ tableInfo()
  776.  
  777.     /**
  778.      * Returns information about a table or a result set.
  779.      *
  780.      * NOTE: only supports 'table' and 'flags' if <var>$result</var>
  781.      * is a table name.
  782.      *
  783.      * NOTE: flags won't contain index information.
  784.      *
  785.      * @param object|string $result  DB_result object from a query or a
  786.      *                                 string containing the name of a table
  787.      * @param int            $mode    a valid tableInfo mode
  788.      * @return array  an associative array with the information requested
  789.      *                 or an error object if something is wrong
  790.      * @access public
  791.      * @internal
  792.      * @see DB_common::tableInfo()
  793.      */
  794.     function tableInfo($result$mode = null)
  795.     {
  796.         if ($this->options['portability'DB_PORTABILITY_LOWERCASE{
  797.             $case_func 'strtolower';
  798.         else {
  799.             $case_func 'strval';
  800.         }
  801.  
  802.         if (is_string($result)) {
  803.             /*
  804.              * Probably received a table name.
  805.              * Create a result resource identifier.
  806.              */
  807.             $result strtoupper($result);
  808.             $q_fields 'SELECT column_name, data_type, data_length, '
  809.                         . 'nullable '
  810.                         . 'FROM user_tab_columns '
  811.                         . "WHERE table_name='$result' ORDER BY column_id";
  812.  
  813.             $this->last_query = $q_fields;
  814.  
  815.             if (!$stmt @OCIParse($this->connection$q_fields)) {
  816.                 return $this->oci8RaiseError(DB_ERROR_NEED_MORE_DATA);
  817.             }
  818.             if (!@OCIExecute($stmtOCI_DEFAULT)) {
  819.                 return $this->oci8RaiseError($stmt);
  820.             }
  821.  
  822.             $i = 0;
  823.             while (@OCIFetch($stmt)) {
  824.                 $res[$i]['table'$case_func($result);
  825.                 $res[$i]['name']  $case_func(@OCIResult($stmt1));
  826.                 $res[$i]['type']  @OCIResult($stmt2);
  827.                 $res[$i]['len']   @OCIResult($stmt3);
  828.                 $res[$i]['flags'(@OCIResult($stmt4== 'N''not_null' '';
  829.  
  830.                 if ($mode DB_TABLEINFO_ORDER{
  831.                     $res['order'][$res[$i]['name']] $i;
  832.                 }
  833.                 if ($mode DB_TABLEINFO_ORDERTABLE{
  834.                     $res['ordertable'][$res[$i]['table']][$res[$i]['name']] $i;
  835.                 }
  836.                 $i++;
  837.             }
  838.  
  839.             if ($mode{
  840.                 $res['num_fields'$i;
  841.             }
  842.             @OCIFreeStatement($stmt);
  843.  
  844.         else {
  845.             if (isset($result->result)) {
  846.                 /*
  847.                  * Probably received a result object.
  848.                  * Extract the result resource identifier.
  849.                  */
  850.                 $result $result->result;
  851.             else {
  852.                 /*
  853.                  * ELSE, probably received a result resource identifier.
  854.                  * Depricated.  Here for compatibility only.
  855.                  */
  856.             }
  857.  
  858.             if ($result === $this->last_stmt{
  859.                 $count @OCINumCols($result);
  860.  
  861.                 for ($i=0; $i<$count$i++{
  862.                     $res[$i]['table''';
  863.                     $res[$i]['name']  $case_func(@OCIColumnName($result$i+1));
  864.                     $res[$i]['type']  @OCIColumnType($result$i+1);
  865.                     $res[$i]['len']   @OCIColumnSize($result$i+1);
  866.                     $res[$i]['flags''';
  867.  
  868.                     if ($mode DB_TABLEINFO_ORDER{
  869.                         $res['order'][$res[$i]['name']] $i;
  870.                     }
  871.                     if ($mode DB_TABLEINFO_ORDERTABLE{
  872.                         $res['ordertable'][$res[$i]['table']][$res[$i]['name']] $i;
  873.                     }
  874.                 }
  875.  
  876.                 if ($mode{
  877.                     $res['num_fields'$count;
  878.                 }
  879.  
  880.             else {
  881.                 return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  882.             }
  883.         }
  884.         return $res;
  885.     }
  886.  
  887.     // }}}
  888.  
  889. }
  890.  
  891. /*
  892.  * Local variables:
  893.  * tab-width: 4
  894.  * c-basic-offset: 4
  895.  * End:
  896.  */
  897.  
  898. ?>

Documentation generated on Mon, 11 Mar 2019 10:14:54 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.