[ Index ]
 

Code source de PHP PEAR 1.4.5

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

title

Body

[fermer]

/DB/ -> sybase.php (source)

   1  <?php
   2  
   3  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
   4  
   5  /**
   6   * The PEAR DB driver for PHP's sybase extension
   7   * for interacting with Sybase databases
   8   *
   9   * PHP versions 4 and 5
  10   *
  11   * LICENSE: This source file is subject to version 3.0 of the PHP license
  12   * that is available through the world-wide-web at the following URI:
  13   * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  14   * the PHP License and are unable to obtain it through the web, please
  15   * send a note to license@php.net so we can mail you a copy immediately.
  16   *
  17   * @category   Database
  18   * @package    DB
  19   * @author     Sterling Hughes <sterling@php.net>
  20   * @author     Antônio Carlos Venâncio Júnior <floripa@php.net>
  21   * @author     Daniel Convissor <danielc@php.net>
  22   * @copyright  1997-2005 The PHP Group
  23   * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  24   * @version    CVS: $Id: sybase.php,v 1.85 2007/02/06 07:35:07 aharvey Exp $
  25   * @link       http://pear.php.net/package/DB
  26   */
  27  
  28  /**
  29   * Obtain the DB_common class so it can be extended from
  30   */
  31  require_once  'DB/common.php';
  32  
  33  /**
  34   * The methods PEAR DB uses to interact with PHP's sybase extension
  35   * for interacting with Sybase databases
  36   *
  37   * These methods overload the ones declared in DB_common.
  38   *
  39   * WARNING:  This driver may fail with multiple connections under the
  40   * same user/pass/host and different databases.
  41   *
  42   * @category   Database
  43   * @package    DB
  44   * @author     Sterling Hughes <sterling@php.net>
  45   * @author     Antônio Carlos Venâncio Júnior <floripa@php.net>
  46   * @author     Daniel Convissor <danielc@php.net>
  47   * @copyright  1997-2005 The PHP Group
  48   * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  49   * @version    Release: 1.7.9
  50   * @link       http://pear.php.net/package/DB
  51   */
  52  class DB_sybase extends DB_common
  53  {
  54      // {{{ properties
  55  
  56      /**
  57       * The DB driver type (mysql, oci8, odbc, etc.)
  58       * @var string
  59       */
  60      var $phptype = 'sybase';
  61  
  62      /**
  63       * The database syntax variant to be used (db2, access, etc.), if any
  64       * @var string
  65       */
  66      var $dbsyntax = 'sybase';
  67  
  68      /**
  69       * The capabilities of this DB implementation
  70       *
  71       * The 'new_link' element contains the PHP version that first provided
  72       * new_link support for this DBMS.  Contains false if it's unsupported.
  73       *
  74       * Meaning of the 'limit' element:
  75       *   + 'emulate' = emulate with fetch row by number
  76       *   + 'alter'   = alter the query
  77       *   + false     = skip rows
  78       *
  79       * @var array
  80       */
  81      var $features = array(
  82          'limit'         => 'emulate',
  83          'new_link'      => false,
  84          'numrows'       => true,
  85          'pconnect'      => true,
  86          'prepare'       => false,
  87          'ssl'           => false,
  88          'transactions'  => true,
  89      );
  90  
  91      /**
  92       * A mapping of native error codes to DB error codes
  93       * @var array
  94       */
  95      var $errorcode_map = array(
  96      );
  97  
  98      /**
  99       * The raw database connection created by PHP
 100       * @var resource
 101       */
 102      var $connection;
 103  
 104      /**
 105       * The DSN information for connecting to a database
 106       * @var array
 107       */
 108      var $dsn = array();
 109  
 110  
 111      /**
 112       * Should data manipulation queries be committed automatically?
 113       * @var bool
 114       * @access private
 115       */
 116      var $autocommit = true;
 117  
 118      /**
 119       * The quantity of transactions begun
 120       *
 121       * {@internal  While this is private, it can't actually be designated
 122       * private in PHP 5 because it is directly accessed in the test suite.}}
 123       *
 124       * @var integer
 125       * @access private
 126       */
 127      var $transaction_opcount = 0;
 128  
 129      /**
 130       * The database specified in the DSN
 131       *
 132       * It's a fix to allow calls to different databases in the same script.
 133       *
 134       * @var string
 135       * @access private
 136       */
 137      var $_db = '';
 138  
 139  
 140      // }}}
 141      // {{{ constructor
 142  
 143      /**
 144       * This constructor calls <kbd>$this->DB_common()</kbd>
 145       *
 146       * @return void
 147       */
 148      function DB_sybase()
 149      {
 150          $this->DB_common();
 151      }
 152  
 153      // }}}
 154      // {{{ connect()
 155  
 156      /**
 157       * Connect to the database server, log in and open the database
 158       *
 159       * Don't call this method directly.  Use DB::connect() instead.
 160       *
 161       * PEAR DB's sybase driver supports the following extra DSN options:
 162       *   + appname       The application name to use on this connection.
 163       *                   Available since PEAR DB 1.7.0.
 164       *   + charset       The character set to use on this connection.
 165       *                   Available since PEAR DB 1.7.0.
 166       *
 167       * @param array $dsn         the data source name
 168       * @param bool  $persistent  should the connection be persistent?
 169       *
 170       * @return int  DB_OK on success. A DB_Error object on failure.
 171       */
 172      function connect($dsn, $persistent = false)
 173      {
 174          if (!PEAR::loadExtension('sybase') &&
 175              !PEAR::loadExtension('sybase_ct'))
 176          {
 177              return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
 178          }
 179  
 180          $this->dsn = $dsn;
 181          if ($dsn['dbsyntax']) {
 182              $this->dbsyntax = $dsn['dbsyntax'];
 183          }
 184  
 185          $dsn['hostspec'] = $dsn['hostspec'] ? $dsn['hostspec'] : 'localhost';
 186          $dsn['password'] = !empty($dsn['password']) ? $dsn['password'] : false;
 187          $dsn['charset'] = isset($dsn['charset']) ? $dsn['charset'] : false;
 188          $dsn['appname'] = isset($dsn['appname']) ? $dsn['appname'] : false;
 189  
 190          $connect_function = $persistent ? 'sybase_pconnect' : 'sybase_connect';
 191  
 192          if ($dsn['username']) {
 193              $this->connection = @$connect_function($dsn['hostspec'],
 194                                                     $dsn['username'],
 195                                                     $dsn['password'],
 196                                                     $dsn['charset'],
 197                                                     $dsn['appname']);
 198          } else {
 199              return $this->raiseError(DB_ERROR_CONNECT_FAILED,
 200                                       null, null, null,
 201                                       'The DSN did not contain a username.');
 202          }
 203  
 204          if (!$this->connection) {
 205              return $this->raiseError(DB_ERROR_CONNECT_FAILED,
 206                                       null, null, null,
 207                                       @sybase_get_last_message());
 208          }
 209  
 210          if ($dsn['database']) {
 211              if (!@sybase_select_db($dsn['database'], $this->connection)) {
 212                  return $this->raiseError(DB_ERROR_NODBSELECTED,
 213                                           null, null, null,
 214                                           @sybase_get_last_message());
 215              }
 216              $this->_db = $dsn['database'];
 217          }
 218  
 219          return DB_OK;
 220      }
 221  
 222      // }}}
 223      // {{{ disconnect()
 224  
 225      /**
 226       * Disconnects from the database server
 227       *
 228       * @return bool  TRUE on success, FALSE on failure
 229       */
 230      function disconnect()
 231      {
 232          $ret = @sybase_close($this->connection);
 233          $this->connection = null;
 234          return $ret;
 235      }
 236  
 237      // }}}
 238      // {{{ simpleQuery()
 239  
 240      /**
 241       * Sends a query to the database server
 242       *
 243       * @param string  the SQL query string
 244       *
 245       * @return mixed  + a PHP result resrouce for successful SELECT queries
 246       *                + the DB_OK constant for other successful queries
 247       *                + a DB_Error object on failure
 248       */
 249      function simpleQuery($query)
 250      {
 251          $ismanip = $this->_checkManip($query);
 252          $this->last_query = $query;
 253          if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
 254              return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
 255          }
 256          $query = $this->modifyQuery($query);
 257          if (!$this->autocommit && $ismanip) {
 258              if ($this->transaction_opcount == 0) {
 259                  $result = @sybase_query('BEGIN TRANSACTION', $this->connection);
 260                  if (!$result) {
 261                      return $this->sybaseRaiseError();
 262                  }
 263              }
 264              $this->transaction_opcount++;
 265          }
 266          $result = @sybase_query($query, $this->connection);
 267          if (!$result) {
 268              return $this->sybaseRaiseError();
 269          }
 270          if (is_resource($result)) {
 271              return $result;
 272          }
 273          // Determine which queries that should return data, and which
 274          // should return an error code only.
 275          return $ismanip ? DB_OK : $result;
 276      }
 277  
 278      // }}}
 279      // {{{ nextResult()
 280  
 281      /**
 282       * Move the internal sybase result pointer to the next available result
 283       *
 284       * @param a valid sybase result resource
 285       *
 286       * @access public
 287       *
 288       * @return true if a result is available otherwise return false
 289       */
 290      function nextResult($result)
 291      {
 292          return false;
 293      }
 294  
 295      // }}}
 296      // {{{ fetchInto()
 297  
 298      /**
 299       * Places a row from the result set into the given array
 300       *
 301       * Formating of the array and the data therein are configurable.
 302       * See DB_result::fetchInto() for more information.
 303       *
 304       * This method is not meant to be called directly.  Use
 305       * DB_result::fetchInto() instead.  It can't be declared "protected"
 306       * because DB_result is a separate object.
 307       *
 308       * @param resource $result    the query result resource
 309       * @param array    $arr       the referenced array to put the data in
 310       * @param int      $fetchmode how the resulting array should be indexed
 311       * @param int      $rownum    the row number to fetch (0 = first row)
 312       *
 313       * @return mixed  DB_OK on success, NULL when the end of a result set is
 314       *                 reached or on failure
 315       *
 316       * @see DB_result::fetchInto()
 317       */
 318      function fetchInto($result, &$arr, $fetchmode, $rownum = null)
 319      {
 320          if ($rownum !== null) {
 321              if (!@sybase_data_seek($result, $rownum)) {
 322                  return null;
 323              }
 324          }
 325          if ($fetchmode & DB_FETCHMODE_ASSOC) {
 326              if (function_exists('sybase_fetch_assoc')) {
 327                  $arr = @sybase_fetch_assoc($result);
 328              } else {
 329                  if ($arr = @sybase_fetch_array($result)) {
 330                      foreach ($arr as $key => $value) {
 331                          if (is_int($key)) {
 332                              unset($arr[$key]);
 333                          }
 334                      }
 335                  }
 336              }
 337              if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
 338                  $arr = array_change_key_case($arr, CASE_LOWER);
 339              }
 340          } else {
 341              $arr = @sybase_fetch_row($result);
 342          }
 343          if (!$arr) {
 344              return null;
 345          }
 346          if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
 347              $this->_rtrimArrayValues($arr);
 348          }
 349          if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
 350              $this->_convertNullArrayValuesToEmpty($arr);
 351          }
 352          return DB_OK;
 353      }
 354  
 355      // }}}
 356      // {{{ freeResult()
 357  
 358      /**
 359       * Deletes the result set and frees the memory occupied by the result set
 360       *
 361       * This method is not meant to be called directly.  Use
 362       * DB_result::free() instead.  It can't be declared "protected"
 363       * because DB_result is a separate object.
 364       *
 365       * @param resource $result  PHP's query result resource
 366       *
 367       * @return bool  TRUE on success, FALSE if $result is invalid
 368       *
 369       * @see DB_result::free()
 370       */
 371      function freeResult($result)
 372      {
 373          return is_resource($result) ? sybase_free_result($result) : false;
 374      }
 375  
 376      // }}}
 377      // {{{ numCols()
 378  
 379      /**
 380       * Gets the number of columns in a result set
 381       *
 382       * This method is not meant to be called directly.  Use
 383       * DB_result::numCols() instead.  It can't be declared "protected"
 384       * because DB_result is a separate object.
 385       *
 386       * @param resource $result  PHP's query result resource
 387       *
 388       * @return int  the number of columns.  A DB_Error object on failure.
 389       *
 390       * @see DB_result::numCols()
 391       */
 392      function numCols($result)
 393      {
 394          $cols = @sybase_num_fields($result);
 395          if (!$cols) {
 396              return $this->sybaseRaiseError();
 397          }
 398          return $cols;
 399      }
 400  
 401      // }}}
 402      // {{{ numRows()
 403  
 404      /**
 405       * Gets the number of rows in a result set
 406       *
 407       * This method is not meant to be called directly.  Use
 408       * DB_result::numRows() instead.  It can't be declared "protected"
 409       * because DB_result is a separate object.
 410       *
 411       * @param resource $result  PHP's query result resource
 412       *
 413       * @return int  the number of rows.  A DB_Error object on failure.
 414       *
 415       * @see DB_result::numRows()
 416       */
 417      function numRows($result)
 418      {
 419          $rows = @sybase_num_rows($result);
 420          if ($rows === false) {
 421              return $this->sybaseRaiseError();
 422          }
 423          return $rows;
 424      }
 425  
 426      // }}}
 427      // {{{ affectedRows()
 428  
 429      /**
 430       * Determines the number of rows affected by a data maniuplation query
 431       *
 432       * 0 is returned for queries that don't manipulate data.
 433       *
 434       * @return int  the number of rows.  A DB_Error object on failure.
 435       */
 436      function affectedRows()
 437      {
 438          if ($this->_last_query_manip) {
 439              $result = @sybase_affected_rows($this->connection);
 440          } else {
 441              $result = 0;
 442          }
 443          return $result;
 444       }
 445  
 446      // }}}
 447      // {{{ nextId()
 448  
 449      /**
 450       * Returns the next free id in a sequence
 451       *
 452       * @param string  $seq_name  name of the sequence
 453       * @param boolean $ondemand  when true, the seqence is automatically
 454       *                            created if it does not exist
 455       *
 456       * @return int  the next id number in the sequence.
 457       *               A DB_Error object on failure.
 458       *
 459       * @see DB_common::nextID(), DB_common::getSequenceName(),
 460       *      DB_sybase::createSequence(), DB_sybase::dropSequence()
 461       */
 462      function nextId($seq_name, $ondemand = true)
 463      {
 464          $seqname = $this->getSequenceName($seq_name);
 465          if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
 466              return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
 467          }
 468          $repeat = 0;
 469          do {
 470              $this->pushErrorHandling(PEAR_ERROR_RETURN);
 471              $result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)");
 472              $this->popErrorHandling();
 473              if ($ondemand && DB::isError($result) &&
 474                  ($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE))
 475              {
 476                  $repeat = 1;
 477                  $result = $this->createSequence($seq_name);
 478                  if (DB::isError($result)) {
 479                      return $this->raiseError($result);
 480                  }
 481              } elseif (!DB::isError($result)) {
 482                  $result =& $this->query("SELECT @@IDENTITY FROM $seqname");
 483                  $repeat = 0;
 484              } else {
 485                  $repeat = false;
 486              }
 487          } while ($repeat);
 488          if (DB::isError($result)) {
 489              return $this->raiseError($result);
 490          }
 491          $result = $result->fetchRow(DB_FETCHMODE_ORDERED);
 492          return $result[0];
 493      }
 494  
 495      /**
 496       * Creates a new sequence
 497       *
 498       * @param string $seq_name  name of the new sequence
 499       *
 500       * @return int  DB_OK on success.  A DB_Error object on failure.
 501       *
 502       * @see DB_common::createSequence(), DB_common::getSequenceName(),
 503       *      DB_sybase::nextID(), DB_sybase::dropSequence()
 504       */
 505      function createSequence($seq_name)
 506      {
 507          return $this->query('CREATE TABLE '
 508                              . $this->getSequenceName($seq_name)
 509                              . ' (id numeric(10, 0) IDENTITY NOT NULL,'
 510                              . ' vapor int NULL)');
 511      }
 512  
 513      // }}}
 514      // {{{ dropSequence()
 515  
 516      /**
 517       * Deletes a sequence
 518       *
 519       * @param string $seq_name  name of the sequence to be deleted
 520       *
 521       * @return int  DB_OK on success.  A DB_Error object on failure.
 522       *
 523       * @see DB_common::dropSequence(), DB_common::getSequenceName(),
 524       *      DB_sybase::nextID(), DB_sybase::createSequence()
 525       */
 526      function dropSequence($seq_name)
 527      {
 528          return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
 529      }
 530  
 531      // }}}
 532      // {{{ quoteFloat()
 533  
 534      /**
 535       * Formats a float value for use within a query in a locale-independent
 536       * manner.
 537       *
 538       * @param float the float value to be quoted.
 539       * @return string the quoted string.
 540       * @see DB_common::quoteSmart()
 541       * @since Method available since release 1.7.8.
 542       */
 543      function quoteFloat($float) {
 544          return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
 545      }
 546       
 547      // }}}
 548      // {{{ autoCommit()
 549  
 550      /**
 551       * Enables or disables automatic commits
 552       *
 553       * @param bool $onoff  true turns it on, false turns it off
 554       *
 555       * @return int  DB_OK on success.  A DB_Error object if the driver
 556       *               doesn't support auto-committing transactions.
 557       */
 558      function autoCommit($onoff = false)
 559      {
 560          // XXX if $this->transaction_opcount > 0, we should probably
 561          // issue a warning here.
 562          $this->autocommit = $onoff ? true : false;
 563          return DB_OK;
 564      }
 565  
 566      // }}}
 567      // {{{ commit()
 568  
 569      /**
 570       * Commits the current transaction
 571       *
 572       * @return int  DB_OK on success.  A DB_Error object on failure.
 573       */
 574      function commit()
 575      {
 576          if ($this->transaction_opcount > 0) {
 577              if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
 578                  return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
 579              }
 580              $result = @sybase_query('COMMIT', $this->connection);
 581              $this->transaction_opcount = 0;
 582              if (!$result) {
 583                  return $this->sybaseRaiseError();
 584              }
 585          }
 586          return DB_OK;
 587      }
 588  
 589      // }}}
 590      // {{{ rollback()
 591  
 592      /**
 593       * Reverts the current transaction
 594       *
 595       * @return int  DB_OK on success.  A DB_Error object on failure.
 596       */
 597      function rollback()
 598      {
 599          if ($this->transaction_opcount > 0) {
 600              if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
 601                  return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
 602              }
 603              $result = @sybase_query('ROLLBACK', $this->connection);
 604              $this->transaction_opcount = 0;
 605              if (!$result) {
 606                  return $this->sybaseRaiseError();
 607              }
 608          }
 609          return DB_OK;
 610      }
 611  
 612      // }}}
 613      // {{{ sybaseRaiseError()
 614  
 615      /**
 616       * Produces a DB_Error object regarding the current problem
 617       *
 618       * @param int $errno  if the error is being manually raised pass a
 619       *                     DB_ERROR* constant here.  If this isn't passed
 620       *                     the error information gathered from the DBMS.
 621       *
 622       * @return object  the DB_Error object
 623       *
 624       * @see DB_common::raiseError(),
 625       *      DB_sybase::errorNative(), DB_sybase::errorCode()
 626       */
 627      function sybaseRaiseError($errno = null)
 628      {
 629          $native = $this->errorNative();
 630          if ($errno === null) {
 631              $errno = $this->errorCode($native);
 632          }
 633          return $this->raiseError($errno, null, null, null, $native);
 634      }
 635  
 636      // }}}
 637      // {{{ errorNative()
 638  
 639      /**
 640       * Gets the DBMS' native error message produced by the last query
 641       *
 642       * @return string  the DBMS' error message
 643       */
 644      function errorNative()
 645      {
 646          return @sybase_get_last_message();
 647      }
 648  
 649      // }}}
 650      // {{{ errorCode()
 651  
 652      /**
 653       * Determines PEAR::DB error code from the database's text error message.
 654       *
 655       * @param  string  $errormsg  error message returned from the database
 656       * @return integer  an error number from a DB error constant
 657       */
 658      function errorCode($errormsg)
 659      {
 660          static $error_regexps;
 661          
 662          // PHP 5.2+ prepends the function name to $php_errormsg, so we need
 663          // this hack to work around it, per bug #9599.
 664          $errormsg = preg_replace('/^sybase[a-z_]+\(\): /', '', $errormsg);
 665          
 666          if (!isset($error_regexps)) {
 667              $error_regexps = array(
 668                  '/Incorrect syntax near/'
 669                      => DB_ERROR_SYNTAX,
 670                  '/^Unclosed quote before the character string [\"\'].*[\"\']\./'
 671                      => DB_ERROR_SYNTAX,
 672                  '/Implicit conversion (from datatype|of NUMERIC value)/i'
 673                      => DB_ERROR_INVALID_NUMBER,
 674                  '/Cannot drop the table [\"\'].+[\"\'], because it doesn\'t exist in the system catalogs\./'
 675                      => DB_ERROR_NOSUCHTABLE,
 676                  '/Only the owner of object [\"\'].+[\"\'] or a user with System Administrator \(SA\) role can run this command\./'
 677                      => DB_ERROR_ACCESS_VIOLATION,
 678                  '/^.+ permission denied on object .+, database .+, owner .+/'
 679                      => DB_ERROR_ACCESS_VIOLATION,
 680                  '/^.* permission denied, database .+, owner .+/'
 681                      => DB_ERROR_ACCESS_VIOLATION,
 682                  '/[^.*] not found\./'
 683                      => DB_ERROR_NOSUCHTABLE,
 684                  '/There is already an object named/'
 685                      => DB_ERROR_ALREADY_EXISTS,
 686                  '/Invalid column name/'
 687                      => DB_ERROR_NOSUCHFIELD,
 688                  '/does not allow null values/'
 689                      => DB_ERROR_CONSTRAINT_NOT_NULL,
 690                  '/Command has been aborted/'
 691                      => DB_ERROR_CONSTRAINT,
 692                  '/^Cannot drop the index .* because it doesn\'t exist/i'
 693                      => DB_ERROR_NOT_FOUND,
 694                  '/^There is already an index/i'
 695                      => DB_ERROR_ALREADY_EXISTS,
 696                  '/^There are fewer columns in the INSERT statement than values specified/i'
 697                      => DB_ERROR_VALUE_COUNT_ON_ROW,
 698                  '/Divide by zero/i'
 699                      => DB_ERROR_DIVZERO,
 700              );
 701          }
 702  
 703          foreach ($error_regexps as $regexp => $code) {
 704              if (preg_match($regexp, $errormsg)) {
 705                  return $code;
 706              }
 707          }
 708          return DB_ERROR;
 709      }
 710  
 711      // }}}
 712      // {{{ tableInfo()
 713  
 714      /**
 715       * Returns information about a table or a result set
 716       *
 717       * NOTE: only supports 'table' and 'flags' if <var>$result</var>
 718       * is a table name.
 719       *
 720       * @param object|string  $result  DB_result object from a query or a
 721       *                                 string containing the name of a table.
 722       *                                 While this also accepts a query result
 723       *                                 resource identifier, this behavior is
 724       *                                 deprecated.
 725       * @param int            $mode    a valid tableInfo mode
 726       *
 727       * @return array  an associative array with the information requested.
 728       *                 A DB_Error object on failure.
 729       *
 730       * @see DB_common::tableInfo()
 731       * @since Method available since Release 1.6.0
 732       */
 733      function tableInfo($result, $mode = null)
 734      {
 735          if (is_string($result)) {
 736              /*
 737               * Probably received a table name.
 738               * Create a result resource identifier.
 739               */
 740              if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
 741                  return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
 742              }
 743              $id = @sybase_query("SELECT * FROM $result WHERE 1=0",
 744                                  $this->connection);
 745              $got_string = true;
 746          } elseif (isset($result->result)) {
 747              /*
 748               * Probably received a result object.
 749               * Extract the result resource identifier.
 750               */
 751              $id = $result->result;
 752              $got_string = false;
 753          } else {
 754              /*
 755               * Probably received a result resource identifier.
 756               * Copy it.
 757               * Deprecated.  Here for compatibility only.
 758               */
 759              $id = $result;
 760              $got_string = false;
 761          }
 762  
 763          if (!is_resource($id)) {
 764              return $this->sybaseRaiseError(DB_ERROR_NEED_MORE_DATA);
 765          }
 766  
 767          if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
 768              $case_func = 'strtolower';
 769          } else {
 770              $case_func = 'strval';
 771          }
 772  
 773          $count = @sybase_num_fields($id);
 774          $res   = array();
 775  
 776          if ($mode) {
 777              $res['num_fields'] = $count;
 778          }
 779  
 780          for ($i = 0; $i < $count; $i++) {
 781              $f = @sybase_fetch_field($id, $i);
 782              // column_source is often blank
 783              $res[$i] = array(
 784                  'table' => $got_string
 785                             ? $case_func($result)
 786                             : $case_func($f->column_source),
 787                  'name'  => $case_func($f->name),
 788                  'type'  => $f->type,
 789                  'len'   => $f->max_length,
 790                  'flags' => '',
 791              );
 792              if ($res[$i]['table']) {
 793                  $res[$i]['flags'] = $this->_sybase_field_flags(
 794                          $res[$i]['table'], $res[$i]['name']);
 795              }
 796              if ($mode & DB_TABLEINFO_ORDER) {
 797                  $res['order'][$res[$i]['name']] = $i;
 798              }
 799              if ($mode & DB_TABLEINFO_ORDERTABLE) {
 800                  $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
 801              }
 802          }
 803  
 804          // free the result only if we were called on a table
 805          if ($got_string) {
 806              @sybase_free_result($id);
 807          }
 808          return $res;
 809      }
 810  
 811      // }}}
 812      // {{{ _sybase_field_flags()
 813  
 814      /**
 815       * Get the flags for a field
 816       *
 817       * Currently supports:
 818       *  + <samp>unique_key</samp>    (unique index, unique check or primary_key)
 819       *  + <samp>multiple_key</samp>  (multi-key index)
 820       *
 821       * @param string  $table   the table name
 822       * @param string  $column  the field name
 823       *
 824       * @return string  space delimited string of flags.  Empty string if none.
 825       *
 826       * @access private
 827       */
 828      function _sybase_field_flags($table, $column)
 829      {
 830          static $tableName = null;
 831          static $flags = array();
 832  
 833          if ($table != $tableName) {
 834              $flags = array();
 835              $tableName = $table;
 836  
 837              /* We're running sp_helpindex directly because it doesn't exist in
 838               * older versions of ASE -- unfortunately, we can't just use
 839               * DB::isError() because the user may be using callback error
 840               * handling. */
 841              $res = @sybase_query("sp_helpindex $table", $this->connection);
 842  
 843              if ($res === false || $res === true) {
 844                  // Fake a valid response for BC reasons.
 845                  return '';
 846              }
 847  
 848              while (($val = sybase_fetch_assoc($res)) !== false) {
 849                  if (!isset($val['index_keys'])) {
 850                      /* No useful information returned. Break and be done with
 851                       * it, which preserves the pre-1.7.9 behaviour. */
 852                      break;
 853                  }
 854  
 855                  $keys = explode(', ', trim($val['index_keys']));
 856  
 857                  if (sizeof($keys) > 1) {
 858                      foreach ($keys as $key) {
 859                          $this->_add_flag($flags[$key], 'multiple_key');
 860                      }
 861                  }
 862  
 863                  if (strpos($val['index_description'], 'unique')) {
 864                      foreach ($keys as $key) {
 865                          $this->_add_flag($flags[$key], 'unique_key');
 866                      }
 867                  }
 868              }
 869  
 870              sybase_free_result($res);
 871  
 872          }
 873  
 874          if (array_key_exists($column, $flags)) {
 875              return(implode(' ', $flags[$column]));
 876          }
 877  
 878          return '';
 879      }
 880  
 881      // }}}
 882      // {{{ _add_flag()
 883  
 884      /**
 885       * Adds a string to the flags array if the flag is not yet in there
 886       * - if there is no flag present the array is created
 887       *
 888       * @param array  $array  reference of flags array to add a value to
 889       * @param mixed  $value  value to add to the flag array
 890       *
 891       * @return void
 892       *
 893       * @access private
 894       */
 895      function _add_flag(&$array, $value)
 896      {
 897          if (!is_array($array)) {
 898              $array = array($value);
 899          } elseif (!in_array($value, $array)) {
 900              array_push($array, $value);
 901          }
 902      }
 903  
 904      // }}}
 905      // {{{ getSpecialQuery()
 906  
 907      /**
 908       * Obtains the query string needed for listing a given type of objects
 909       *
 910       * @param string $type  the kind of objects you want to retrieve
 911       *
 912       * @return string  the SQL query string or null if the driver doesn't
 913       *                  support the object type requested
 914       *
 915       * @access protected
 916       * @see DB_common::getListOf()
 917       */
 918      function getSpecialQuery($type)
 919      {
 920          switch ($type) {
 921              case 'tables':
 922                  return "SELECT name FROM sysobjects WHERE type = 'U'"
 923                         . ' ORDER BY name';
 924              case 'views':
 925                  return "SELECT name FROM sysobjects WHERE type = 'V'";
 926              default:
 927                  return null;
 928          }
 929      }
 930  
 931      // }}}
 932  
 933  }
 934  
 935  /*
 936   * Local variables:
 937   * tab-width: 4
 938   * c-basic-offset: 4
 939   * End:
 940   */
 941  
 942  ?>


Généré le : Sun Feb 25 14:08:00 2007 par Balluche grâce à PHPXref 0.7