[ Index ]
 

Code source de SPIP Agora 1.4

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/Pear/DB/ -> oci8.php (source)

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


Généré le : Sat Feb 24 14:40:03 2007 par Balluche grâce à PHPXref 0.7