[ Index ]
 

Code source de SPIP Agora 1.4

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

title

Body

[fermer]

/Pear/DB/ -> ibase.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: Sterling Hughes <sterling@php.net>                           |
  17  // | Maintainer: Daniel Convissor <danielc@php.net>                       |
  18  // +----------------------------------------------------------------------+
  19  //
  20  // $Id: ibase.php,v 1.69 2004/06/24 15:24:56 danielc Exp $
  21  
  22  
  23  // Bugs:
  24  //  - If dbsyntax is not firebird, the limitQuery may fail
  25  
  26  
  27  require_once 'DB/common.php';
  28  
  29  /**
  30   * Database independent query interface definition for PHP's Interbase
  31   * extension.
  32   *
  33   * @package  DB
  34   * @version  $Id: ibase.php,v 1.69 2004/06/24 15:24:56 danielc Exp $
  35   * @category Database
  36   * @author   Sterling Hughes <sterling@php.net>
  37   */
  38  class DB_ibase extends DB_common
  39  {
  40  
  41      // {{{ properties
  42  
  43      var $connection;
  44      var $phptype, $dbsyntax;
  45      var $autocommit = 1;
  46      var $manip_query = array();
  47  
  48      // }}}
  49      // {{{ constructor
  50  
  51      function DB_ibase()
  52      {
  53          $this->DB_common();
  54          $this->phptype = 'ibase';
  55          $this->dbsyntax = 'ibase';
  56          $this->features = array(
  57              'prepare' => true,
  58              'pconnect' => true,
  59              'transactions' => true,
  60              'limit' => false
  61          );
  62          // just a few of the tons of Interbase error codes listed in the
  63          // Language Reference section of the Interbase manual
  64          $this->errorcode_map = array(
  65              -104 => DB_ERROR_SYNTAX,
  66              -150 => DB_ERROR_ACCESS_VIOLATION,
  67              -151 => DB_ERROR_ACCESS_VIOLATION,
  68              -155 => DB_ERROR_NOSUCHTABLE,
  69              88   => DB_ERROR_NOSUCHTABLE,
  70              -157 => DB_ERROR_NOSUCHFIELD,
  71              -158 => DB_ERROR_VALUE_COUNT_ON_ROW,
  72              -170 => DB_ERROR_MISMATCH,
  73              -171 => DB_ERROR_MISMATCH,
  74              -172 => DB_ERROR_INVALID,
  75              -204 => DB_ERROR_INVALID,
  76              -205 => DB_ERROR_NOSUCHFIELD,
  77              -206 => DB_ERROR_NOSUCHFIELD,
  78              -208 => DB_ERROR_INVALID,
  79              -219 => DB_ERROR_NOSUCHTABLE,
  80              -297 => DB_ERROR_CONSTRAINT,
  81              -530 => DB_ERROR_CONSTRAINT,
  82              -607 => DB_ERROR_NOSUCHTABLE,
  83              -803 => DB_ERROR_CONSTRAINT,
  84              -551 => DB_ERROR_ACCESS_VIOLATION,
  85              -552 => DB_ERROR_ACCESS_VIOLATION,
  86              -922 => DB_ERROR_NOSUCHDB,
  87              -923 => DB_ERROR_CONNECT_FAILED,
  88              -924 => DB_ERROR_CONNECT_FAILED
  89          );
  90      }
  91  
  92      // }}}
  93      // {{{ connect()
  94  
  95      function connect($dsninfo, $persistent = false)
  96      {
  97          if (!DB::assertExtension('interbase')) {
  98              return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
  99          }
 100          $this->dsn = $dsninfo;
 101          $dbhost = $dsninfo['hostspec'] ?
 102                    ($dsninfo['hostspec'] . ':' . $dsninfo['database']) :
 103                    $dsninfo['database'];
 104  
 105          $connect_function = $persistent ? 'ibase_pconnect' : 'ibase_connect';
 106  
 107          $params = array();
 108          $params[] = $dbhost;
 109          $params[] = $dsninfo['username'] ? $dsninfo['username'] : null;
 110          $params[] = $dsninfo['password'] ? $dsninfo['password'] : null;
 111          $params[] = isset($dsninfo['charset']) ? $dsninfo['charset'] : null;
 112          $params[] = isset($dsninfo['buffers']) ? $dsninfo['buffers'] : null;
 113          $params[] = isset($dsninfo['dialect']) ? $dsninfo['dialect'] : null;
 114          $params[] = isset($dsninfo['role'])    ? $dsninfo['role'] : null;
 115  
 116          $conn = @call_user_func_array($connect_function, $params);
 117          if (!$conn) {
 118              return $this->ibaseRaiseError(DB_ERROR_CONNECT_FAILED);
 119          }
 120          $this->connection = $conn;
 121          if ($this->dsn['dbsyntax'] == 'firebird') {
 122              $this->features['limit'] = 'alter';
 123          }
 124          return DB_OK;
 125      }
 126  
 127      // }}}
 128      // {{{ disconnect()
 129  
 130      function disconnect()
 131      {
 132          $ret = @ibase_close($this->connection);
 133          $this->connection = null;
 134          return $ret;
 135      }
 136  
 137      // }}}
 138      // {{{ simpleQuery()
 139  
 140      function simpleQuery($query)
 141      {
 142          $ismanip = DB::isManip($query);
 143          $this->last_query = $query;
 144          $query = $this->modifyQuery($query);
 145          $result = @ibase_query($this->connection, $query);
 146          if (!$result) {
 147              return $this->ibaseRaiseError();
 148          }
 149          if ($this->autocommit && $ismanip) {
 150              @ibase_commit($this->connection);
 151          }
 152          // Determine which queries that should return data, and which
 153          // should return an error code only.
 154          return $ismanip ? DB_OK : $result;
 155      }
 156  
 157      // }}}
 158      // {{{ modifyLimitQuery()
 159  
 160      /**
 161       * This method is used by backends to alter limited queries
 162       * Uses the new FIRST n SKIP n Firebird 1.0 syntax, so it is
 163       * only compatible with Firebird 1.x
 164       *
 165       * @param string  $query query to modify
 166       * @param integer $from  the row to start to fetching
 167       * @param integer $count the numbers of rows to fetch
 168       *
 169       * @return the new (modified) query
 170       * @author Ludovico Magnocavallo <ludo@sumatrasolutions.com>
 171       * @access private
 172       */
 173      function modifyLimitQuery($query, $from, $count, $params = array())
 174      {
 175          if ($this->dsn['dbsyntax'] == 'firebird') {
 176              //$from++; // SKIP starts from 1, ie SKIP 1 starts from the first record
 177                             // (cox) Seems that SKIP starts in 0
 178              $query = preg_replace('/^\s*select\s(.*)$/is',
 179                                    "SELECT FIRST $count SKIP $from $1", $query);
 180          }
 181          return $query;
 182      }
 183  
 184      // }}}
 185      // {{{ nextResult()
 186  
 187      /**
 188       * Move the internal ibase result pointer to the next available result
 189       *
 190       * @param a valid fbsql result resource
 191       *
 192       * @access public
 193       *
 194       * @return true if a result is available otherwise return false
 195       */
 196      function nextResult($result)
 197      {
 198          return false;
 199      }
 200  
 201      // }}}
 202      // {{{ fetchInto()
 203  
 204      /**
 205       * Fetch a row and insert the data into an existing array.
 206       *
 207       * Formating of the array and the data therein are configurable.
 208       * See DB_result::fetchInto() for more information.
 209       *
 210       * @param resource $result    query result identifier
 211       * @param array    $arr       (reference) array where data from the row
 212       *                            should be placed
 213       * @param int      $fetchmode how the resulting array should be indexed
 214       * @param int      $rownum    the row number to fetch
 215       *
 216       * @return mixed DB_OK on success, null when end of result set is
 217       *               reached or on failure
 218       *
 219       * @see DB_result::fetchInto()
 220       * @access private
 221       */
 222      function fetchInto($result, &$arr, $fetchmode, $rownum=null)
 223      {
 224          if ($rownum !== null) {
 225              return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE);
 226          }
 227          if ($fetchmode & DB_FETCHMODE_ASSOC) {
 228              if (function_exists('ibase_fetch_assoc')) {
 229                  $arr = @ibase_fetch_assoc($result);
 230              } else {
 231                  $arr = get_object_vars(ibase_fetch_object($result));
 232              }
 233              if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
 234                  $arr = array_change_key_case($arr, CASE_LOWER);
 235              }
 236          } else {
 237              $arr = @ibase_fetch_row($result);
 238          }
 239          if (!$arr) {
 240              if ($errmsg = @ibase_errmsg()) {
 241                  return $this->ibaseRaiseError(null, $errmsg);
 242              } else {
 243                  return null;
 244              }
 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      function freeResult($result)
 259      {
 260          return @ibase_free_result($result);
 261      }
 262  
 263      // }}}
 264      // {{{ freeQuery()
 265  
 266      function freeQuery($query)
 267      {
 268          @ibase_free_query($query);
 269          return true;
 270      }
 271  
 272      // }}}
 273      // {{{ numCols()
 274  
 275      function numCols($result)
 276      {
 277          $cols = @ibase_num_fields($result);
 278          if (!$cols) {
 279              return $this->ibaseRaiseError();
 280          }
 281          return $cols;
 282      }
 283  
 284      // }}}
 285      // {{{ prepare()
 286  
 287      /**
 288       * Prepares a query for multiple execution with execute().
 289       *
 290       * prepare() requires a generic query as string like <code>
 291       *    INSERT INTO numbers VALUES (?, ?, ?)
 292       * </code>.  The <kbd>?</kbd> characters are placeholders.
 293       *
 294       * Three types of placeholders can be used:
 295       *   + <kbd>?</kbd>  a quoted scalar value, i.e. strings, integers
 296       *   + <kbd>!</kbd>  value is inserted 'as is'
 297       *   + <kbd>&</kbd>  requires a file name.  The file's contents get
 298       *                     inserted into the query (i.e. saving binary
 299       *                     data in a db)
 300       *
 301       * Use backslashes to escape placeholder characters if you don't want
 302       * them to be interpreted as placeholders.  Example: <code>
 303       *    "UPDATE foo SET col=? WHERE col='over \& under'"
 304       * </code>
 305       *
 306       * @param string $query query to be prepared
 307       * @return mixed DB statement resource on success. DB_Error on failure.
 308       */
 309      function prepare($query)
 310      {
 311          $tokens   = preg_split('/((?<!\\\)[&?!])/', $query, -1,
 312                                 PREG_SPLIT_DELIM_CAPTURE);
 313          $token    = 0;
 314          $types    = array();
 315          $newquery = '';
 316  
 317          foreach ($tokens as $key => $val) {
 318              switch ($val) {
 319                  case '?':
 320                      $types[$token++] = DB_PARAM_SCALAR;
 321                      break;
 322                  case '&':
 323                      $types[$token++] = DB_PARAM_OPAQUE;
 324                      break;
 325                  case '!':
 326                      $types[$token++] = DB_PARAM_MISC;
 327                      break;
 328                  default:
 329                      $tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val);
 330                      $newquery .= $tokens[$key] . '?';
 331              }
 332          }
 333  
 334          $newquery = substr($newquery, 0, -1);
 335          $this->last_query = $query;
 336          $newquery = $this->modifyQuery($newquery);
 337          $stmt = @ibase_prepare($this->connection, $newquery);
 338          $this->prepare_types[(int)$stmt] = $types;
 339          $this->manip_query[(int)$stmt]   = DB::isManip($query);
 340          return $stmt;
 341      }
 342  
 343      // }}}
 344      // {{{ execute()
 345  
 346      /**
 347       * Executes a DB statement prepared with prepare().
 348       *
 349       * @param resource  $stmt  a DB statement resource returned from prepare()
 350       * @param mixed  $data  array, string or numeric data to be used in
 351       *                      execution of the statement.  Quantity of items
 352       *                      passed must match quantity of placeholders in
 353       *                      query:  meaning 1 for non-array items or the
 354       *                      quantity of elements in the array.
 355       * @return object  a new DB_Result or a DB_Error when fail
 356       * @see DB_ibase::prepare()
 357       * @access public
 358       */
 359      function &execute($stmt, $data = array())
 360      {
 361          if (!is_array($data)) {
 362              $data = array($data);
 363          }
 364  
 365          $types =& $this->prepare_types[(int)$stmt];
 366          if (count($types) != count($data)) {
 367              $tmp =& $this->raiseError(DB_ERROR_MISMATCH);
 368              return $tmp;
 369          }
 370  
 371          $i = 0;
 372          foreach ($data as $key => $value) {
 373              if ($types[$i] == DB_PARAM_MISC) {
 374                  /*
 375                   * ibase doesn't seem to have the ability to pass a
 376                   * parameter along unchanged, so strip off quotes from start
 377                   * and end, plus turn two single quotes to one single quote,
 378                   * in order to avoid the quotes getting escaped by
 379                   * ibase and ending up in the database.
 380                   */
 381                  $data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]);
 382                  $data[$key] = str_replace("''", "'", $data[$key]);
 383              } elseif ($types[$i] == DB_PARAM_OPAQUE) {
 384                  $fp = @fopen($data[$key], 'rb');
 385                  if (!$fp) {
 386                      $tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
 387                      return $tmp;
 388                  }
 389                  $data[$key] = fread($fp, filesize($data[$key]));
 390                  fclose($fp);
 391              }
 392              $i++;
 393          }
 394  
 395          array_unshift($data, $stmt);
 396  
 397          $res = call_user_func_array('ibase_execute', $data);
 398          if (!$res) {
 399              $tmp =& $this->ibaseRaiseError();
 400              return $tmp;
 401          }
 402          /* XXX need this?
 403          if ($this->autocommit && $this->manip_query[(int)$stmt]) {
 404              @ibase_commit($this->connection);
 405          }*/
 406          if ($this->manip_query[(int)$stmt]) {
 407              $tmp = DB_OK;
 408          } else {
 409              $tmp =& new DB_result($this, $res);
 410          }
 411          return $tmp;
 412      }
 413  
 414      /**
 415       * Free the internal resources associated with a prepared query.
 416       *
 417       * @param $stmt The interbase_query resource type
 418       *
 419       * @return bool true on success, false if $result is invalid
 420       */
 421      function freePrepared($stmt)
 422      {
 423          if (!is_resource($stmt)) {
 424              return false;
 425          }
 426          @ibase_free_query($stmt);
 427          unset($this->prepare_tokens[(int)$stmt]);
 428          unset($this->prepare_types[(int)$stmt]);
 429          unset($this->manip_query[(int)$stmt]);
 430          return true;
 431      }
 432  
 433      // }}}
 434      // {{{ autoCommit()
 435  
 436      function autoCommit($onoff = false)
 437      {
 438          $this->autocommit = $onoff ? 1 : 0;
 439          return DB_OK;
 440      }
 441  
 442      // }}}
 443      // {{{ commit()
 444  
 445      function commit()
 446      {
 447          return @ibase_commit($this->connection);
 448      }
 449  
 450      // }}}
 451      // {{{ rollback()
 452  
 453      function rollback()
 454      {
 455          return @ibase_rollback($this->connection);
 456      }
 457  
 458      // }}}
 459      // {{{ transactionInit()
 460  
 461      function transactionInit($trans_args = 0)
 462      {
 463          return $trans_args ? @ibase_trans($trans_args, $this->connection) : @ibase_trans();
 464      }
 465  
 466      // }}}
 467      // {{{ nextId()
 468  
 469      /**
 470       * Returns the next free id in a sequence
 471       *
 472       * @param string  $seq_name  name of the sequence
 473       * @param boolean $ondemand  when true, the seqence is automatically
 474       *                           created if it does not exist
 475       *
 476       * @return int  the next id number in the sequence.  DB_Error if problem.
 477       *
 478       * @internal
 479       * @see DB_common::nextID()
 480       * @access public
 481       */
 482      function nextId($seq_name, $ondemand = true)
 483      {
 484          $sqn = strtoupper($this->getSequenceName($seq_name));
 485          $repeat = 0;
 486          do {
 487              $this->pushErrorHandling(PEAR_ERROR_RETURN);
 488              $result =& $this->query("SELECT GEN_ID($sqn}, 1) "
 489                                     . 'FROM RDB$GENERATORS '
 490                                     . "WHERE RDB\$GENERATOR_NAME='$sqn}'");
 491              $this->popErrorHandling();
 492              if ($ondemand && DB::isError($result)) {
 493                  $repeat = 1;
 494                  $result = $this->createSequence($seq_name);
 495                  if (DB::isError($result)) {
 496                      return $result;
 497                  }
 498              } else {
 499                  $repeat = 0;
 500              }
 501          } while ($repeat);
 502          if (DB::isError($result)) {
 503              return $this->raiseError($result);
 504          }
 505          $arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
 506          $result->free();
 507          return $arr[0];
 508      }
 509  
 510      // }}}
 511      // {{{ createSequence()
 512  
 513      /**
 514       * Create the sequence
 515       *
 516       * @param string $seq_name the name of the sequence
 517       * @return mixed DB_OK on success or DB error on error
 518       * @access public
 519       */
 520      function createSequence($seq_name)
 521      {
 522          $sqn = strtoupper($this->getSequenceName($seq_name));
 523          $this->pushErrorHandling(PEAR_ERROR_RETURN);
 524          $result = $this->query("CREATE GENERATOR $sqn}");
 525          $this->popErrorHandling();
 526  
 527          return $result;
 528      }
 529  
 530      // }}}
 531      // {{{ dropSequence()
 532  
 533      /**
 534       * Drop a sequence
 535       *
 536       * @param string $seq_name the name of the sequence
 537       * @return mixed DB_OK on success or DB error on error
 538       * @access public
 539       */
 540      function dropSequence($seq_name)
 541      {
 542          $sqn = strtoupper($this->getSequenceName($seq_name));
 543          return $this->query('DELETE FROM RDB$GENERATORS '
 544                              . "WHERE RDB\$GENERATOR_NAME='$sqn}'");
 545      }
 546  
 547      // }}}
 548      // {{{ _ibaseFieldFlags()
 549  
 550      /**
 551       * get the Flags of a Field
 552       *
 553       * @param string $field_name the name of the field
 554       * @param string $table_name the name of the table
 555       *
 556       * @return string The flags of the field ("primary_key", "unique_key", "not_null"
 557       *                "default", "computed" and "blob" are supported)
 558       * @access private
 559       */
 560      function _ibaseFieldFlags($field_name, $table_name)
 561      {
 562          $sql = 'SELECT R.RDB$CONSTRAINT_TYPE CTYPE'
 563                 .' FROM RDB$INDEX_SEGMENTS I'
 564                 .'  JOIN RDB$RELATION_CONSTRAINTS R ON I.RDB$INDEX_NAME=R.RDB$INDEX_NAME'
 565                 .' WHERE I.RDB$FIELD_NAME=\'' . $field_name . '\''
 566                 .'  AND UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\'';
 567  
 568          $result = @ibase_query($this->connection, $sql);
 569          if (!$result) {
 570              return $this->ibaseRaiseError();
 571          }
 572  
 573          $flags = '';
 574          if ($obj = @ibase_fetch_object($result)) {
 575              @ibase_free_result($result);
 576              if (isset($obj->CTYPE)  && trim($obj->CTYPE) == 'PRIMARY KEY') {
 577                  $flags .= 'primary_key ';
 578              }
 579              if (isset($obj->CTYPE)  && trim($obj->CTYPE) == 'UNIQUE') {
 580                  $flags .= 'unique_key ';
 581              }
 582          }
 583  
 584          $sql = 'SELECT R.RDB$NULL_FLAG AS NFLAG,'
 585                 .'  R.RDB$DEFAULT_SOURCE AS DSOURCE,'
 586                 .'  F.RDB$FIELD_TYPE AS FTYPE,'
 587                 .'  F.RDB$COMPUTED_SOURCE AS CSOURCE'
 588                 .' FROM RDB$RELATION_FIELDS R '
 589                 .'  JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME'
 590                 .' WHERE UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\''
 591                 .'  AND R.RDB$FIELD_NAME=\'' . $field_name . '\'';
 592  
 593          $result = @ibase_query($this->connection, $sql);
 594          if (!$result) {
 595              return $this->ibaseRaiseError();
 596          }
 597          if ($obj = @ibase_fetch_object($result)) {
 598              @ibase_free_result($result);
 599              if (isset($obj->NFLAG)) {
 600                  $flags .= 'not_null ';
 601              }
 602              if (isset($obj->DSOURCE)) {
 603                  $flags .= 'default ';
 604              }
 605              if (isset($obj->CSOURCE)) {
 606                  $flags .= 'computed ';
 607              }
 608              if (isset($obj->FTYPE)  && $obj->FTYPE == 261) {
 609                  $flags .= 'blob ';
 610              }
 611          }
 612  
 613          return trim($flags);
 614      }
 615  
 616      // }}}
 617      // {{{ tableInfo()
 618  
 619      /**
 620       * Returns information about a table or a result set.
 621       *
 622       * NOTE: only supports 'table' and 'flags' if <var>$result</var>
 623       * is a table name.
 624       *
 625       * @param object|string  $result  DB_result object from a query or a
 626       *                                string containing the name of a table
 627       * @param int            $mode    a valid tableInfo mode
 628       * @return array  an associative array with the information requested
 629       *                or an error object if something is wrong
 630       * @access public
 631       * @internal
 632       * @see DB_common::tableInfo()
 633       */
 634      function tableInfo($result, $mode = null)
 635      {
 636          if (isset($result->result)) {
 637              /*
 638               * Probably received a result object.
 639               * Extract the result resource identifier.
 640               */
 641              $id = $result->result;
 642              $got_string = false;
 643          } elseif (is_string($result)) {
 644              /*
 645               * Probably received a table name.
 646               * Create a result resource identifier.
 647               */
 648               $id = @ibase_query($this->connection,
 649                                  "SELECT * FROM $result WHERE 1=0");
 650              $got_string = true;
 651          } else {
 652              /*
 653               * Probably received a result resource identifier.
 654               * Copy it.
 655               * Deprecated.  Here for compatibility only.
 656               */
 657               $id = $result;
 658              $got_string = false;
 659          }
 660  
 661          if (!is_resource($id)) {
 662              return $this->ibaseRaiseError(DB_ERROR_NEED_MORE_DATA);
 663          }
 664  
 665          if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
 666              $case_func = 'strtolower';
 667          } else {
 668              $case_func = 'strval';
 669          }
 670  
 671          $count = @ibase_num_fields($id);
 672  
 673          // made this IF due to performance (one if is faster than $count if's)
 674          if (!$mode) {
 675              for ($i=0; $i<$count; $i++) {
 676                  $info = @ibase_field_info($id, $i);
 677                  $res[$i]['table'] = $got_string ? $case_func($result) : '';
 678                  $res[$i]['name']  = $case_func($info['name']);
 679                  $res[$i]['type']  = $info['type'];
 680                  $res[$i]['len']   = $info['length'];
 681                  $res[$i]['flags'] = ($got_string) ? $this->_ibaseFieldFlags($info['name'], $result) : '';
 682              }
 683          } else { // full
 684              $res['num_fields']= $count;
 685  
 686              for ($i=0; $i<$count; $i++) {
 687                  $info = @ibase_field_info($id, $i);
 688                  $res[$i]['table'] = $got_string ? $case_func($result) : '';
 689                  $res[$i]['name']  = $case_func($info['name']);
 690                  $res[$i]['type']  = $info['type'];
 691                  $res[$i]['len']   = $info['length'];
 692                  $res[$i]['flags'] = ($got_string) ? $this->_ibaseFieldFlags($info['name'], $result) : '';
 693  
 694                  if ($mode & DB_TABLEINFO_ORDER) {
 695                      $res['order'][$res[$i]['name']] = $i;
 696                  }
 697                  if ($mode & DB_TABLEINFO_ORDERTABLE) {
 698                      $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
 699                  }
 700              }
 701          }
 702  
 703          // free the result only if we were called on a table
 704          if ($got_string) {
 705              @ibase_free_result($id);
 706          }
 707          return $res;
 708      }
 709  
 710      // }}}
 711      // {{{ ibaseRaiseError()
 712  
 713      /**
 714       * Gather information about an error, then use that info to create a
 715       * DB error object and finally return that object.
 716       *
 717       * @param  integer  $db_errno  PEAR error number (usually a DB constant) if
 718       *                             manually raising an error
 719       * @param  string  $native_errmsg  text of error message if known
 720       * @return object  DB error object
 721       * @see DB_common::errorCode()
 722       * @see DB_common::raiseError()
 723       */
 724      function &ibaseRaiseError($db_errno = null, $native_errmsg = null)
 725      {
 726          if ($native_errmsg === null) {
 727              $native_errmsg = @ibase_errmsg();
 728          }
 729          // memo for the interbase php module hackers: we need something similar
 730          // to mysql_errno() to retrieve error codes instead of this ugly hack
 731          if (preg_match('/^([^0-9\-]+)([0-9\-]+)\s+(.*)$/', $native_errmsg, $m)) {
 732              $native_errno = (int)$m[2];
 733          } else {
 734              $native_errno = null;
 735          }
 736          // try to map the native error to the DB one
 737          if ($db_errno === null) {
 738              if ($native_errno) {
 739                  // try to interpret Interbase error code (that's why we need ibase_errno()
 740                  // in the interbase module to return the real error code)
 741                  switch ($native_errno) {
 742                      case -204:
 743                          if (is_int(strpos($m[3], 'Table unknown'))) {
 744                              $db_errno = DB_ERROR_NOSUCHTABLE;
 745                          }
 746                          break;
 747                      default:
 748                          $db_errno = $this->errorCode($native_errno);
 749                  }
 750              } else {
 751                  $error_regexps = array(
 752                      '/[tT]able not found/' => DB_ERROR_NOSUCHTABLE,
 753                      '/[tT]able .* already exists/' => DB_ERROR_ALREADY_EXISTS,
 754                      '/validation error for column .* value "\*\*\* null/' => DB_ERROR_CONSTRAINT_NOT_NULL,
 755                      '/violation of [\w ]+ constraint/' => DB_ERROR_CONSTRAINT,
 756                      '/conversion error from string/' => DB_ERROR_INVALID_NUMBER,
 757                      '/no permission for/' => DB_ERROR_ACCESS_VIOLATION,
 758                      '/arithmetic exception, numeric overflow, or string truncation/' => DB_ERROR_DIVZERO
 759                  );
 760                  foreach ($error_regexps as $regexp => $code) {
 761                      if (preg_match($regexp, $native_errmsg)) {
 762                          $db_errno = $code;
 763                          $native_errno = null;
 764                          break;
 765                      }
 766                  }
 767              }
 768          }
 769          $tmp =& $this->raiseError($db_errno, null, null, null, $native_errmsg);
 770          return $tmp;
 771      }
 772  
 773      // }}}
 774  
 775  }
 776  
 777  /*
 778   * Local variables:
 779   * tab-width: 4
 780   * c-basic-offset: 4
 781   * End:
 782   */
 783  
 784  ?>


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