[ Index ]
 

Code source de SPIP Agora 1.4

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

title

Body

[fermer]

/Pear/DB/ -> ifx.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: Tomas V.V.Cox <cox@idecnet.com>                              |
  17  // | Maintainer: Daniel Convissor <danielc@php.net>                       |
  18  // +----------------------------------------------------------------------+
  19  //
  20  // $Id: ifx.php,v 1.47 2004/03/05 01:46:53 danielc Exp $
  21  
  22  
  23  // Legend:
  24  // For more info on Informix errors see:
  25  // http://www.informix.com/answers/english/ierrors.htm
  26  //
  27  // TODO:
  28  //  - set needed env Informix vars on connect
  29  //  - implement native prepare/execute
  30  
  31  
  32  require_once 'DB/common.php';
  33  
  34  /**
  35   * Database independent query interface definition for PHP's Informix
  36   * extension.
  37   *
  38   * @package  DB
  39   * @version  $Id: ifx.php,v 1.47 2004/03/05 01:46:53 danielc Exp $
  40   * @category Database
  41   * @author   Tomas V.V.Cox <cox@idecnet.com>
  42   */
  43  class DB_ifx extends DB_common
  44  {
  45      // {{{ properties
  46  
  47      var $connection;
  48      var $affected = 0;
  49      var $dsn = array();
  50      var $transaction_opcount = 0;
  51      var $autocommit = true;
  52      var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */
  53  
  54      // }}}
  55      // {{{ constructor
  56  
  57      function DB_ifx()
  58      {
  59          $this->phptype = 'ifx';
  60          $this->dbsyntax = 'ifx';
  61          $this->features = array(
  62              'prepare' => false,
  63              'pconnect' => true,
  64              'transactions' => true,
  65              'limit' => 'emulate'
  66          );
  67          $this->errorcode_map = array(
  68              '-201'    => DB_ERROR_SYNTAX,
  69              '-206'    => DB_ERROR_NOSUCHTABLE,
  70              '-217'    => DB_ERROR_NOSUCHFIELD,
  71              '-239'    => DB_ERROR_CONSTRAINT,
  72              '-253'    => DB_ERROR_SYNTAX,
  73              '-292'    => DB_ERROR_CONSTRAINT_NOT_NULL,
  74              '-310'    => DB_ERROR_ALREADY_EXISTS,
  75              '-329'    => DB_ERROR_NODBSELECTED,
  76              '-346'    => DB_ERROR_CONSTRAINT,
  77              '-386'    => DB_ERROR_CONSTRAINT_NOT_NULL,
  78              '-391'    => DB_ERROR_CONSTRAINT_NOT_NULL,
  79              '-554'    => DB_ERROR_SYNTAX,
  80              '-691'    => DB_ERROR_CONSTRAINT,
  81              '-703'    => DB_ERROR_CONSTRAINT_NOT_NULL,
  82              '-1204'   => DB_ERROR_INVALID_DATE,
  83              '-1205'   => DB_ERROR_INVALID_DATE,
  84              '-1206'   => DB_ERROR_INVALID_DATE,
  85              '-1209'   => DB_ERROR_INVALID_DATE,
  86              '-1210'   => DB_ERROR_INVALID_DATE,
  87              '-1212'   => DB_ERROR_INVALID_DATE,
  88              '-1213'   => DB_ERROR_INVALID_NUMBER,
  89          );
  90      }
  91  
  92      // }}}
  93      // {{{ connect()
  94  
  95      /**
  96       * Connect to a database and log in as the specified user.
  97       *
  98       * @param $dsn the data source name (see DB::parseDSN for syntax)
  99       * @param $persistent (optional) whether the connection should
 100       *        be persistent
 101       *
 102       * @return int DB_OK on success, a DB error code on failure
 103       */
 104      function connect($dsninfo, $persistent = false)
 105      {
 106          if (!DB::assertExtension('informix') &&
 107              !DB::assertExtension('Informix'))
 108          {
 109              return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
 110          }
 111          $this->dsn = $dsninfo;
 112          $dbhost = $dsninfo['hostspec'] ? '@' . $dsninfo['hostspec'] : '';
 113          $dbname = $dsninfo['database'] ? $dsninfo['database'] . $dbhost : '';
 114          $user = $dsninfo['username'] ? $dsninfo['username'] : '';
 115          $pw = $dsninfo['password'] ? $dsninfo['password'] : '';
 116  
 117          $connect_function = $persistent ? 'ifx_pconnect' : 'ifx_connect';
 118  
 119          $this->connection = @$connect_function($dbname, $user, $pw);
 120          if (!is_resource($this->connection)) {
 121              return $this->ifxraiseError(DB_ERROR_CONNECT_FAILED);
 122          }
 123          return DB_OK;
 124      }
 125  
 126      // }}}
 127      // {{{ disconnect()
 128  
 129      /**
 130       * Log out and disconnect from the database.
 131       *
 132       * @return bool true on success, false if not connected.
 133       */
 134      function disconnect()
 135      {
 136          $ret = @ifx_close($this->connection);
 137          $this->connection = null;
 138          return $ret;
 139      }
 140  
 141      // }}}
 142      // {{{ simpleQuery()
 143  
 144      /**
 145       * Send a query to Informix and return the results as a
 146       * Informix resource identifier.
 147       *
 148       * @param $query the SQL query
 149       *
 150       * @return int returns a valid Informix result for successful SELECT
 151       * queries, DB_OK for other successful queries.  A DB error code
 152       * is returned on failure.
 153       */
 154      function simpleQuery($query)
 155      {
 156          $ismanip = DB::isManip($query);
 157          $this->last_query = $query;
 158          $this->affected   = null;
 159          if (preg_match('/(SELECT)/i', $query)) {    //TESTME: Use !DB::isManip()?
 160              // the scroll is needed for fetching absolute row numbers
 161              // in a select query result
 162              $result = @ifx_query($query, $this->connection, IFX_SCROLL);
 163          } else {
 164              if (!$this->autocommit && $ismanip) {
 165                  if ($this->transaction_opcount == 0) {
 166                      $result = @ifx_query('BEGIN WORK', $this->connection);
 167                      if (!$result) {
 168                          return $this->ifxraiseError();
 169                      }
 170                  }
 171                  $this->transaction_opcount++;
 172              }
 173              $result = @ifx_query($query, $this->connection);
 174          }
 175          if (!$result) {
 176              return $this->ifxraiseError();
 177          }
 178          $this->affected = @ifx_affected_rows($result);
 179          // Determine which queries should return data, and which
 180          // should return an error code only.
 181          if (preg_match('/(SELECT)/i', $query)) {
 182              return $result;
 183          }
 184          // XXX Testme: free results inside a transaction
 185          // may cause to stop it and commit the work?
 186  
 187          // Result has to be freed even with a insert or update
 188          @ifx_free_result($result);
 189  
 190          return DB_OK;
 191      }
 192  
 193      // }}}
 194      // {{{ nextResult()
 195  
 196      /**
 197       * Move the internal ifx result pointer to the next available result
 198       *
 199       * @param a valid fbsql result resource
 200       *
 201       * @access public
 202       *
 203       * @return true if a result is available otherwise return false
 204       */
 205      function nextResult($result)
 206      {
 207          return false;
 208      }
 209  
 210      // }}}
 211      // {{{ affectedRows()
 212  
 213      /**
 214       * Gets the number of rows affected by the last query.
 215       * if the last query was a select, returns 0.
 216       *
 217       * @return number of rows affected by the last query
 218       */
 219      function affectedRows()
 220      {
 221          if (DB::isManip($this->last_query)) {
 222              return $this->affected;
 223          } else {
 224              return 0;
 225          }
 226          
 227      }
 228  
 229      // }}}
 230      // {{{ fetchInto()
 231  
 232      /**
 233       * Fetch a row and insert the data into an existing array.
 234       *
 235       * Formating of the array and the data therein are configurable.
 236       * See DB_result::fetchInto() for more information.
 237       *
 238       * @param resource $result    query result identifier
 239       * @param array    $arr       (reference) array where data from the row
 240       *                            should be placed
 241       * @param int      $fetchmode how the resulting array should be indexed
 242       * @param int      $rownum    the row number to fetch
 243       *
 244       * @return mixed DB_OK on success, null when end of result set is
 245       *               reached or on failure
 246       *
 247       * @see DB_result::fetchInto()
 248       * @access private
 249       */
 250      function fetchInto($result, &$arr, $fetchmode, $rownum=null)
 251      {
 252          if (($rownum !== null) && ($rownum < 0)) {
 253              return null;
 254          }
 255          if ($rownum === null) {
 256              /*
 257               * Even though fetch_row() should return the next row  if
 258               * $rownum is null, it doesn't in all cases.  Bug 598.
 259               */
 260              $rownum = 'NEXT';
 261          } else {
 262              // Index starts at row 1, unlike most DBMS's starting at 0.
 263              $rownum++;
 264          }
 265          if (!$arr = @ifx_fetch_row($result, $rownum)) {
 266              return null;
 267          }
 268          if ($fetchmode !== DB_FETCHMODE_ASSOC) {
 269              $i=0;
 270              $order = array();
 271              foreach ($arr as $val) {
 272                  $order[$i++] = $val;
 273              }
 274              $arr = $order;
 275          } elseif ($fetchmode == DB_FETCHMODE_ASSOC &&
 276                    $this->options['portability'] & DB_PORTABILITY_LOWERCASE)
 277          {
 278              $arr = array_change_key_case($arr, CASE_LOWER);
 279          }
 280          if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
 281              $this->_rtrimArrayValues($arr);
 282          }
 283          if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
 284              $this->_convertNullArrayValuesToEmpty($arr);
 285          }
 286          return DB_OK;
 287      }
 288  
 289      // }}}
 290      // {{{ numRows()
 291  
 292      function numRows($result)
 293      {
 294          return $this->raiseError(DB_ERROR_NOT_CAPABLE);
 295      }
 296  
 297      // }}}
 298      // {{{ numCols()
 299  
 300      /**
 301       * Get the number of columns in a result set.
 302       *
 303       * @param $result Informix result identifier
 304       *
 305       * @return int the number of columns per row in $result
 306       */
 307      function numCols($result)
 308      {
 309          if (!$cols = @ifx_num_fields($result)) {
 310              return $this->ifxraiseError();
 311          }
 312          return $cols;
 313      }
 314  
 315      // }}}
 316      // {{{ freeResult()
 317  
 318      /**
 319       * Free the internal resources associated with $result.
 320       *
 321       * @param $result Informix result identifier
 322       *
 323       * @return bool true on success, false if $result is invalid
 324       */
 325      function freeResult($result)
 326      {
 327          return @ifx_free_result($result);
 328      }
 329  
 330      // }}}
 331      // {{{ autoCommit()
 332  
 333      /**
 334       * Enable/disable automatic commits
 335       */
 336      function autoCommit($onoff = true)
 337      {
 338          // XXX if $this->transaction_opcount > 0, we should probably
 339          // issue a warning here.
 340          $this->autocommit = $onoff ? true : false;
 341          return DB_OK;
 342      }
 343  
 344      // }}}
 345      // {{{ commit()
 346  
 347      /**
 348       * Commit the current transaction.
 349       */
 350      function commit()
 351      {
 352          if ($this->transaction_opcount > 0) {
 353              $result = @ifx_query('COMMIT WORK', $this->connection);
 354              $this->transaction_opcount = 0;
 355              if (!$result) {
 356                  return $this->ifxRaiseError();
 357              }
 358          }
 359          return DB_OK;
 360      }
 361  
 362      // }}}
 363      // {{{ rollback()
 364  
 365      /**
 366       * Roll back (undo) the current transaction.
 367       */
 368      function rollback()
 369      {
 370          if ($this->transaction_opcount > 0) {
 371              $result = @ifx_query('ROLLBACK WORK', $this->connection);
 372              $this->transaction_opcount = 0;
 373              if (!$result) {
 374                  return $this->ifxRaiseError();
 375              }
 376          }
 377          return DB_OK;
 378      }
 379  
 380      // }}}
 381      // {{{ ifxraiseError()
 382  
 383      /**
 384       * Gather information about an error, then use that info to create a
 385       * DB error object and finally return that object.
 386       *
 387       * @param  integer  $errno  PEAR error number (usually a DB constant) if
 388       *                          manually raising an error
 389       * @return object  DB error object
 390       * @see errorNative()
 391       * @see errorCode()
 392       * @see DB_common::raiseError()
 393       */
 394      function ifxraiseError($errno = null)
 395      {
 396          if ($errno === null) {
 397              $errno = $this->errorCode(ifx_error());
 398          }
 399  
 400          return $this->raiseError($errno, null, null, null,
 401                              $this->errorNative());
 402      }
 403  
 404      // }}}
 405      // {{{ errorCode()
 406  
 407      /**
 408       * Map native error codes to DB's portable ones.
 409       *
 410       * Requires that the DB implementation's constructor fills
 411       * in the <var>$errorcode_map</var> property.
 412       *
 413       * @param  string  $nativecode  error code returned by the database
 414       * @return int a portable DB error code, or DB_ERROR if this DB
 415       * implementation has no mapping for the given error code.
 416       */
 417      function errorCode($nativecode)
 418      {
 419          if (ereg('SQLCODE=(.*)]', $nativecode, $match)) {
 420              $code = $match[1];
 421              if (isset($this->errorcode_map[$code])) {
 422                  return $this->errorcode_map[$code];
 423              }
 424          }
 425          return DB_ERROR;
 426      }
 427  
 428      // }}}
 429      // {{{ errorNative()
 430  
 431      /**
 432       * Get the native error message of the last error (if any) that
 433       * occured on the current connection.
 434       *
 435       * @return int native Informix error code
 436       */
 437      function errorNative()
 438      {
 439          return @ifx_error() . ' ' . @ifx_errormsg();
 440      }
 441  
 442      // }}}
 443      // {{{ getSpecialQuery()
 444  
 445      /**
 446       * Returns the query needed to get some backend info
 447       * @param string $type What kind of info you want to retrieve
 448       * @return string The SQL query string
 449       */
 450      function getSpecialQuery($type)
 451      {
 452          switch ($type) {
 453              case 'tables':
 454                  return 'select tabname from systables where tabid >= 100';
 455              default:
 456                  return null;
 457          }
 458      }
 459  
 460      // }}}
 461      // {{{ tableInfo()
 462  
 463      /**
 464       * Returns information about a table or a result set.
 465       *
 466       * NOTE: only supports 'table' if <var>$result</var> is a table name.
 467       *
 468       * If analyzing a query result and the result has duplicate field names,
 469       * an error will be raised saying
 470       * <samp>can't distinguish duplicate field names</samp>.
 471       *
 472       * @param object|string  $result  DB_result object from a query or a
 473       *                                string containing the name of a table
 474       * @param int            $mode    a valid tableInfo mode
 475       * @return array  an associative array with the information requested
 476       *                or an error object if something is wrong
 477       * @access public
 478       * @internal
 479       * @since 1.6.0
 480       * @see DB_common::tableInfo()
 481       */
 482      function tableInfo($result, $mode = null)
 483      {
 484          if (isset($result->result)) {
 485              /*
 486               * Probably received a result object.
 487               * Extract the result resource identifier.
 488               */
 489              $id = $result->result;
 490              $got_string = false;
 491          } elseif (is_string($result)) {
 492              /*
 493               * Probably received a table name.
 494               * Create a result resource identifier.
 495               */
 496              $id = @ifx_query("SELECT * FROM $result WHERE 1=0",
 497                               $this->connection);
 498              $got_string = true;
 499          } else {
 500              /*
 501               * Probably received a result resource identifier.
 502               * Copy it.
 503               */
 504              $id = $result;
 505              $got_string = false;
 506          }
 507  
 508          if (!is_resource($id)) {
 509              return $this->ifxRaiseError(DB_ERROR_NEED_MORE_DATA);
 510          }
 511  
 512          $flds = @ifx_fieldproperties($id);
 513          $count = @ifx_num_fields($id);
 514  
 515          if (count($flds) != $count) {
 516              return $this->raiseError("can't distinguish duplicate field names");
 517          }
 518  
 519          if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
 520              $case_func = 'strtolower';
 521          } else {
 522              $case_func = 'strval';
 523          }
 524  
 525          $i = 0;
 526          // made this IF due to performance (one if is faster than $count if's)
 527          if (!$mode) {
 528              foreach ($flds as $key => $value) {
 529                  $props = explode(';', $value);
 530  
 531                  $res[$i]['table'] = $got_string ? $case_func($result) : '';
 532                  $res[$i]['name']  = $case_func($key);
 533                  $res[$i]['type']  = $props[0];
 534                  $res[$i]['len']   = $props[1];
 535                  $res[$i]['flags'] = $props[4] == 'N' ? 'not_null' : '';
 536                  $i++;
 537              }
 538  
 539          } else { // full
 540              $res['num_fields'] = $count;
 541  
 542              foreach ($flds as $key => $value) {
 543                  $props = explode(';', $value);
 544  
 545                  $res[$i]['table'] = $got_string ? $case_func($result) : '';
 546                  $res[$i]['name']  = $case_func($key);
 547                  $res[$i]['type']  = $props[0];
 548                  $res[$i]['len']   = $props[1];
 549                  $res[$i]['flags'] = $props[4] == 'N' ? 'not_null' : '';
 550  
 551                  if ($mode & DB_TABLEINFO_ORDER) {
 552                      $res['order'][$res[$i]['name']] = $i;
 553                  }
 554                  if ($mode & DB_TABLEINFO_ORDERTABLE) {
 555                      $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
 556                  }
 557                  $i++;
 558              }
 559          }
 560  
 561          // free the result only if we were called on a table
 562          if ($got_string) {
 563              @ifx_free_result($id);
 564          }
 565          return $res;
 566      }
 567  
 568      // }}}
 569  
 570  }
 571  
 572  /*
 573   * Local variables:
 574   * tab-width: 4
 575   * c-basic-offset: 4
 576   * End:
 577   */
 578  
 579  ?>


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