[ Index ]
 

Code source de Dolibarr 2.0.1

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/htdocs/includes/pear/DB/ -> mysql.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
   3  // +----------------------------------------------------------------------+
   4  // | PHP Version 4                                                        |
   5  // +----------------------------------------------------------------------+
   6  // | Copyright (c) 1997-2003 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: Stig Bakken <ssb@php.net>                                    |
  17  // +----------------------------------------------------------------------+
  18  //
  19  // $Id: mysql.php,v 1.2 2004/07/20 17:41:40 rodolphe Exp $
  20  //
  21  // Database independent query interface definition for PHP's MySQL
  22  // extension.
  23  //
  24  
  25  //
  26  // XXX legend:
  27  //
  28  // XXX ERRORMSG: The error message from the mysql function should
  29  //               be registered here.
  30  //
  31  
  32  require_once DOL_DOCUMENT_ROOT."/includes/pear/DB/common.php";
  33  
  34  class DB_mysql extends DB_common
  35  {
  36      // {{{ properties
  37  
  38      var $connection;
  39      var $phptype, $dbsyntax;
  40      var $prepare_tokens = array();
  41      var $prepare_types = array();
  42      var $num_rows = array();
  43      var $transaction_opcount = 0;
  44      var $autocommit = true;
  45      var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */
  46      var $_db = false;
  47  
  48      // }}}
  49      // {{{ constructor
  50  
  51      /**
  52       * DB_mysql constructor.
  53       *
  54       * @access public
  55       */
  56  
  57      function DB_mysql()
  58      {
  59          $this->DB_common();
  60          $this->phptype = 'mysql';
  61          $this->dbsyntax = 'mysql';
  62          $this->features = array(
  63              'prepare' => false,
  64              'pconnect' => true,
  65              'transactions' => true,
  66              'limit' => 'alter'
  67          );
  68          $this->errorcode_map = array(
  69              1004 => DB_ERROR_CANNOT_CREATE,
  70              1005 => DB_ERROR_CANNOT_CREATE,
  71              1006 => DB_ERROR_CANNOT_CREATE,
  72              1007 => DB_ERROR_ALREADY_EXISTS,
  73              1008 => DB_ERROR_CANNOT_DROP,
  74              1046 => DB_ERROR_NODBSELECTED,
  75              1050 => DB_ERROR_ALREADY_EXISTS,
  76              1051 => DB_ERROR_NOSUCHTABLE,
  77              1054 => DB_ERROR_NOSUCHFIELD,
  78              1062 => DB_ERROR_ALREADY_EXISTS,
  79              1064 => DB_ERROR_SYNTAX,
  80              1100 => DB_ERROR_NOT_LOCKED,
  81              1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
  82              1146 => DB_ERROR_NOSUCHTABLE,
  83              1048 => DB_ERROR_CONSTRAINT,
  84          );
  85      }
  86  
  87      // }}}
  88  
  89      // {{{ connect()
  90  
  91      /**
  92       * Connect to a database and log in as the specified user.
  93       *
  94       * @param $dsn the data source name (see DB::parseDSN for syntax)
  95       * @param $persistent (optional) whether the connection should
  96       *        be persistent
  97       * @access public
  98       * @return int DB_OK on success, a DB error on failure
  99       */
 100  
 101      function connect($dsninfo, $persistent = false)
 102      {
 103          if (!DB::assertExtension('mysql'))
 104              return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
 105  
 106          $this->dsn = $dsninfo;
 107          if (isset($dsninfo['protocol']) && $dsninfo['protocol'] == 'unix') {
 108              $dbhost = ':' . $dsninfo['socket'];
 109          } else {
 110              $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
 111              if (!empty($dsninfo['port'])) {
 112                  $dbhost .= ':' . $dsninfo['port'];
 113              }
 114          }
 115          $user = $dsninfo['username'];
 116          $pw = $dsninfo['password'];
 117  
 118          $connect_function = $persistent ? 'mysql_pconnect' : 'mysql_connect';
 119  
 120          if ($dbhost && $user && $pw) {
 121              $conn = @$connect_function($dbhost, $user, $pw);
 122          } elseif ($dbhost && $user) {
 123              $conn = @$connect_function($dbhost, $user);
 124          } elseif ($dbhost) {
 125              $conn = @$connect_function($dbhost);
 126          } else {
 127              $conn = false;
 128          }
 129          if (empty($conn)) {
 130              if (($err = @mysql_error()) != '') {
 131                  return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
 132                                           null, $err);
 133              } elseif (empty($php_errormsg)) {
 134                  return $this->raiseError(DB_ERROR_CONNECT_FAILED);
 135              } else {
 136                  return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
 137                                           null, $php_errormsg);
 138              }
 139          }
 140  
 141          if ($dsninfo['database']) {
 142              if (!@mysql_select_db($dsninfo['database'], $conn)) {
 143                 switch(mysql_errno($conn)) {
 144                          case 1049:
 145                              return $this->raiseError(DB_ERROR_NOSUCHDB, null, null,
 146                                                       null, mysql_error($conn));
 147                              break;
 148                          case 1044:
 149                               return $this->raiseError(DB_ERROR_ACCESS_VIOLATION, null, null,
 150                                                        null, mysql_error($conn));
 151                              break;
 152                          default:
 153                              return $this->raiseError(DB_ERROR, null, null,
 154                                                       null, mysql_error($conn));
 155                              break;
 156  
 157                      }
 158              }
 159              // fix to allow calls to different databases in the same script
 160              $this->_db = $dsninfo['database'];
 161          }
 162  
 163          $this->connection = $conn;
 164          return DB_OK;
 165      }
 166  
 167      // }}}
 168      // {{{ disconnect()
 169  
 170      /**
 171       * Log out and disconnect from the database.
 172       *
 173       * @access public
 174       *
 175       * @return bool TRUE on success, FALSE if not connected.
 176       */
 177      function disconnect()
 178      {
 179          $ret = mysql_close($this->connection);
 180          $this->connection = null;
 181          return $ret;
 182      }
 183  
 184      // }}}
 185      // {{{ simpleQuery()
 186  
 187      /**
 188       * Send a query to MySQL and return the results as a MySQL resource
 189       * identifier.
 190       *
 191       * @param the SQL query
 192       *
 193       * @access public
 194       *
 195       * @return mixed returns a valid MySQL result for successful SELECT
 196       * queries, DB_OK for other successful queries.  A DB error is
 197       * returned on failure.
 198       */
 199      function simpleQuery($query)
 200      {
 201          $ismanip = DB::isManip($query);
 202          $this->last_query = $query;
 203          $query = $this->modifyQuery($query);
 204          if ($this->_db) {
 205              if (!@mysql_select_db($this->_db, $this->connection)) {
 206                  return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
 207              }
 208          }
 209          if (!$this->autocommit && $ismanip) {
 210              if ($this->transaction_opcount == 0) {
 211                  $result = @mysql_query('SET AUTOCOMMIT=0', $this->connection);
 212                  $result = @mysql_query('BEGIN', $this->connection);
 213                  if (!$result) {
 214                      return $this->mysqlRaiseError();
 215                  }
 216              }
 217              $this->transaction_opcount++;
 218          }
 219          $result = @mysql_query($query, $this->connection);
 220          if (!$result) {
 221              return $this->mysqlRaiseError();
 222          }
 223          if (is_resource($result)) {
 224              $numrows = $this->numrows($result);
 225              if (is_object($numrows)) {
 226                  return $numrows;
 227              }
 228              $this->num_rows[$result] = $numrows;
 229              return $result;
 230          }
 231          return DB_OK;
 232      }
 233  
 234      // }}}
 235      // {{{ nextResult()
 236  
 237      /**
 238       * Move the internal mysql result pointer to the next available result
 239       *
 240       * This method has not been implemented yet.
 241       *
 242       * @param a valid sql result resource
 243       *
 244       * @access public
 245       *
 246       * @return false
 247       */
 248      function nextResult($result)
 249      {
 250          return false;
 251      }
 252  
 253      // }}}
 254      // {{{ fetchInto()
 255  
 256      /**
 257       * Fetch a row and insert the data into an existing array.
 258       *
 259       * @param $result MySQL result identifier
 260       * @param $arr (reference) array where data from the row is stored
 261       * @param $fetchmode how the array data should be indexed
 262       * @param   $rownum the row number to fetch
 263       * @access public
 264       *
 265       * @return int DB_OK on success, a DB error on failure
 266       */
 267      function fetchInto($result, &$arr, $fetchmode, $rownum=null)
 268      {
 269          if ($rownum !== null) {
 270              if (!@mysql_data_seek($result, $rownum)) {
 271                  return null;
 272              }
 273          }
 274          if ($fetchmode & DB_FETCHMODE_ASSOC) {
 275              $arr = @mysql_fetch_array($result, MYSQL_ASSOC);
 276          } else {
 277              $arr = @mysql_fetch_row($result);
 278          }
 279          if (!$arr) {
 280              // See: http://bugs.php.net/bug.php?id=22328
 281              // for why we can't check errors on fetching
 282              return null;
 283              /*
 284              $errno = @mysql_errno($this->connection);
 285              if (!$errno) {
 286                  return NULL;
 287              }
 288              return $this->mysqlRaiseError($errno);
 289              */
 290          }
 291          return DB_OK;
 292      }
 293  
 294      // }}}
 295      // {{{ freeResult()
 296  
 297      /**
 298       * Free the internal resources associated with $result.
 299       *
 300       * @param $result MySQL result identifier or DB statement identifier
 301       *
 302       * @access public
 303       *
 304       * @return bool TRUE on success, FALSE if $result is invalid
 305       */
 306      function freeResult($result)
 307      {
 308          if (is_resource($result)) {
 309              return mysql_free_result($result);
 310          }
 311  
 312          $result = (int)$result; // $result is a prepared query handle
 313          if (!isset($this->prepare_tokens[$result])) {
 314              return false;
 315          }
 316  
 317  
 318          // I fixed the unset thing.
 319  
 320          $this->prepare_types = array();
 321          $this->prepare_tokens = array();
 322  
 323          return true;
 324      }
 325  
 326      // }}}
 327      // {{{ numCols()
 328  
 329      /**
 330       * Get the number of columns in a result set.
 331       *
 332       * @param $result MySQL result identifier
 333       *
 334       * @access public
 335       *
 336       * @return int the number of columns per row in $result
 337       */
 338      function numCols($result)
 339      {
 340          $cols = @mysql_num_fields($result);
 341  
 342          if (!$cols) {
 343              return $this->mysqlRaiseError();
 344          }
 345  
 346          return $cols;
 347      }
 348  
 349      // }}}
 350      // {{{ numRows()
 351  
 352      /**
 353       * Get the number of rows in a result set.
 354       *
 355       * @param $result MySQL result identifier
 356       *
 357       * @access public
 358       *
 359       * @return int the number of rows in $result
 360       */
 361      function numRows($result)
 362      {
 363          $rows = @mysql_num_rows($result);
 364          if ($rows === null) {
 365              return $this->mysqlRaiseError();
 366          }
 367          return $rows;
 368      }
 369  
 370      // }}}
 371      // {{{ autoCommit()
 372  
 373      /**
 374       * Enable/disable automatic commits
 375       */
 376      function autoCommit($onoff = false)
 377      {
 378          // XXX if $this->transaction_opcount > 0, we should probably
 379          // issue a warning here.
 380          $this->autocommit = $onoff ? true : false;
 381          return DB_OK;
 382      }
 383  
 384      // }}}
 385      // {{{ commit()
 386  
 387      /**
 388       * Commit the current transaction.
 389       */
 390      function commit()
 391      {
 392          if ($this->transaction_opcount > 0) {
 393              if ($this->_db) {
 394                  if (!@mysql_select_db($this->_db, $this->connection)) {
 395                      return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
 396                  }
 397              }
 398              $result = @mysql_query('COMMIT', $this->connection);
 399              $result = @mysql_query('SET AUTOCOMMIT=1', $this->connection);
 400              $this->transaction_opcount = 0;
 401              if (!$result) {
 402                  return $this->mysqlRaiseError();
 403              }
 404          }
 405          return DB_OK;
 406      }
 407  
 408      // }}}
 409      // {{{ rollback()
 410  
 411      /**
 412       * Roll back (undo) the current transaction.
 413       */
 414      function rollback()
 415      {
 416          if ($this->transaction_opcount > 0) {
 417              if ($this->_db) {
 418                  if (!@mysql_select_db($this->_db, $this->connection)) {
 419                      return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
 420                  }
 421              }
 422              $result = @mysql_query('ROLLBACK', $this->connection);
 423              $result = @mysql_query('SET AUTOCOMMIT=1', $this->connection);
 424              $this->transaction_opcount = 0;
 425              if (!$result) {
 426                  return $this->mysqlRaiseError();
 427              }
 428          }
 429          return DB_OK;
 430      }
 431  
 432      // }}}
 433      // {{{ affectedRows()
 434  
 435      /**
 436       * Gets the number of rows affected by the data manipulation
 437       * query.  For other queries, this function returns 0.
 438       *
 439       * @return number of rows affected by the last query
 440       */
 441  
 442      function affectedRows()
 443      {
 444          if (DB::isManip($this->last_query)) {
 445              $result = @mysql_affected_rows($this->connection);
 446          } else {
 447              $result = 0;
 448          }
 449          return $result;
 450       }
 451  
 452      // }}}
 453      // {{{ errorNative()
 454  
 455      /**
 456       * Get the native error code of the last error (if any) that
 457       * occured on the current connection.
 458       *
 459       * @access public
 460       *
 461       * @return int native MySQL error code
 462       */
 463  
 464      function errorNative()
 465      {
 466          return mysql_errno($this->connection);
 467      }
 468  
 469      // }}}
 470      // {{{ nextId()
 471  
 472      /**
 473       * Get the next value in a sequence.  We emulate sequences
 474       * for MySQL.  Will create the sequence if it does not exist.
 475       *
 476       * @access public
 477       *
 478       * @param string $seq_name the name of the sequence
 479       *
 480       * @param bool $ondemand whether to create the sequence table on demand
 481       * (default is true)
 482       *
 483       * @return mixed a sequence integer, or a DB error
 484       */
 485      function nextId($seq_name, $ondemand = true)
 486      {
 487          $seqname = $this->getSequenceName($seq_name);
 488          do {
 489              $repeat = 0;
 490              $this->pushErrorHandling(PEAR_ERROR_RETURN);
 491              $result = $this->query("UPDATE $seqname} ".
 492                                     'SET id=LAST_INSERT_ID(id+1)');
 493              $this->popErrorHandling();
 494              if ($result == DB_OK) {
 495                  /** COMMON CASE **/
 496                  $id = mysql_insert_id($this->connection);
 497                  if ($id != 0) {
 498                      return $id;
 499                  }
 500                  /** EMPTY SEQ TABLE **/
 501                  // Sequence table must be empty for some reason, so fill it and return 1
 502                  // Obtain a user-level lock
 503                  $result = $this->getOne("SELECT GET_LOCK('$seqname}_lock',10)");
 504                  if (DB::isError($result)) {
 505                      return $this->raiseError($result);
 506                  }
 507                  if ($result == 0) {
 508                      // Failed to get the lock, bail with a DB_ERROR_NOT_LOCKED error
 509                      return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
 510                  }
 511  
 512                  // add the default value
 513                  $result = $this->query("REPLACE INTO $seqname} VALUES (0)");
 514                  if (DB::isError($result)) {
 515                      return $this->raiseError($result);
 516                  }
 517  
 518                  // Release the lock
 519                  $result = $this->getOne("SELECT RELEASE_LOCK('$seqname}_lock')");
 520                  if (DB::isError($result)) {
 521                      return $this->raiseError($result);
 522                  }
 523                  // We know what the result will be, so no need to try again
 524                  return 1;
 525  
 526              /** ONDEMAND TABLE CREATION **/
 527              } elseif ($ondemand && DB::isError($result) &&
 528                  $result->getCode() == DB_ERROR_NOSUCHTABLE)
 529              {
 530                  $result = $this->createSequence($seq_name);
 531                  if (DB::isError($result)) {
 532                      return $this->raiseError($result);
 533                  } else {
 534                      $repeat = 1;
 535                  }
 536  
 537              /** BACKWARDS COMPAT **/
 538              } elseif (DB::isError($result) &&
 539                        $result->getCode() == DB_ERROR_ALREADY_EXISTS)
 540              {
 541                  // see _BCsequence() comment
 542                  $result = $this->_BCsequence($seqname);
 543                  if (DB::isError($result)) {
 544                      return $this->raiseError($result);
 545                  }
 546                  $repeat = 1;
 547              }
 548          } while ($repeat);
 549  
 550          return $this->raiseError($result);
 551      }
 552  
 553      // }}}
 554      // {{{ createSequence()
 555  
 556      function createSequence($seq_name)
 557      {
 558          $seqname = $this->getSequenceName($seq_name);
 559          $res = $this->query("CREATE TABLE $seqname} ".
 560                              '(id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'.
 561                              ' PRIMARY KEY(id))');
 562          if (DB::isError($res)) {
 563              return $res;
 564          }
 565          // insert yields value 1, nextId call will generate ID 2
 566          $res = $this->query("INSERT INTO $seqname} VALUES(0)");
 567          if (DB::isError($res)) {
 568              return $res;
 569          }
 570          // so reset to zero

 571          return $this->query("UPDATE $seqname} SET id = 0;");
 572      }
 573  
 574      // }}}
 575      // {{{ dropSequence()
 576  
 577      function dropSequence($seq_name)
 578      {
 579          $seqname = $this->getSequenceName($seq_name);
 580          return $this->query("DROP TABLE $seqname}");
 581      }
 582  
 583      // }}}
 584      // {{{ _BCsequence()
 585  
 586      /**
 587      * Backwards compatibility with old sequence emulation implementation
 588      * (clean up the dupes)
 589      *
 590      * @param string $seqname The sequence name to clean up
 591      * @return mixed DB_Error or true
 592      */
 593      function _BCsequence($seqname)
 594      {
 595          // Obtain a user-level lock... this will release any previous
 596          // application locks, but unlike LOCK TABLES, it does not abort
 597          // the current transaction and is much less frequently used.
 598          $result = $this->getOne("SELECT GET_LOCK('$seqname}_lock',10)");
 599          if (DB::isError($result)) {
 600              return $result;
 601          }
 602          if ($result == 0) {
 603              // Failed to get the lock, can't do the conversion, bail
 604              // with a DB_ERROR_NOT_LOCKED error
 605              return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
 606          }
 607  
 608          $highest_id = $this->getOne("SELECT MAX(id) FROM $seqname}");
 609          if (DB::isError($highest_id)) {
 610              return $highest_id;
 611          }
 612          // This should kill all rows except the highest
 613          // We should probably do something if $highest_id isn't
 614          // numeric, but I'm at a loss as how to handle that...
 615          $result = $this->query("DELETE FROM $seqname} WHERE id <> $highest_id");
 616          if (DB::isError($result)) {
 617              return $result;
 618          }
 619  
 620          // If another thread has been waiting for this lock,
 621          // it will go thru the above procedure, but will have no
 622          // real effect
 623          $result = $this->getOne("SELECT RELEASE_LOCK('$seqname}_lock')");
 624          if (DB::isError($result)) {
 625              return $result;
 626          }
 627          return true;
 628      }
 629  
 630      // }}}
 631      // {{{ quote()
 632  
 633      /**
 634      * Quote the given string so it can be safely used within string delimiters
 635      * in a query.
 636      * @param $string mixed Data to be quoted
 637      * @return mixed "NULL" string, quoted string or original data
 638      */
 639      function quote($str = null)
 640      {
 641          switch (strtolower(gettype($str))) {
 642              case 'null':
 643                  return 'NULL';
 644              case 'integer':
 645              case 'double':
 646                  return $str;
 647              case 'string':
 648              default:
 649                  if(function_exists('mysql_real_escape_string')) {
 650                      return "'".mysql_real_escape_string($str, $this->connection)."'";
 651                  } else {
 652                      return "'".mysql_escape_string($str)."'";
 653                  }
 654          }
 655      }
 656  
 657      // }}}
 658      // {{{ modifyQuery()
 659  
 660      function modifyQuery($query, $subject = null)
 661      {
 662          if ($this->options['optimize'] == 'portability') {
 663              // "DELETE FROM table" gives 0 affected rows in MySQL.
 664              // This little hack lets you know how many rows were deleted.
 665              if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
 666                  $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
 667                                        'DELETE FROM \1 WHERE 1=1', $query);
 668              }
 669          }
 670          return $query;
 671      }
 672  
 673      // }}}
 674      // {{{ modifyLimitQuery()
 675  
 676      function modifyLimitQuery($query, $from, $count)
 677      {
 678          if (DB::isManip($query)) {
 679              return $query . " LIMIT $count";
 680          } else {
 681              return $query . " LIMIT $from, $count";
 682          }
 683      }
 684  
 685      // }}}
 686      // {{{ mysqlRaiseError()
 687  
 688      function mysqlRaiseError($errno = null)
 689      {
 690          if ($errno === null) {
 691              $errno = $this->errorCode(mysql_errno($this->connection));
 692          }
 693          return $this->raiseError($errno, null, null, null,
 694                                   @mysql_errno($this->connection) . " ** " .
 695                                   @mysql_error($this->connection));
 696      }
 697  
 698      // }}}
 699      // {{{ tableInfo()
 700  
 701      function tableInfo($result, $mode = null) {
 702          $count = 0;
 703          $id    = 0;
 704          $res   = array();
 705  
 706          /*
 707           * depending on $mode, metadata returns the following values:
 708           *
 709           * - mode is null (default):
 710           * $result[]:
 711           *   [0]["table"]  table name
 712           *   [0]["name"]   field name
 713           *   [0]["type"]   field type
 714           *   [0]["len"]    field length
 715           *   [0]["flags"]  field flags
 716           *
 717           * - mode is DB_TABLEINFO_ORDER
 718           * $result[]:
 719           *   ["num_fields"] number of metadata records
 720           *   [0]["table"]  table name
 721           *   [0]["name"]   field name
 722           *   [0]["type"]   field type
 723           *   [0]["len"]    field length
 724           *   [0]["flags"]  field flags
 725           *   ["order"][field name]  index of field named "field name"
 726           *   The last one is used, if you have a field name, but no index.
 727           *   Test:  if (isset($result['meta']['myfield'])) { ...
 728           *
 729           * - mode is DB_TABLEINFO_ORDERTABLE
 730           *    the same as above. but additionally
 731           *   ["ordertable"][table name][field name] index of field
 732           *      named "field name"
 733           *
 734           *      this is, because if you have fields from different
 735           *      tables with the same field name * they override each
 736           *      other with DB_TABLEINFO_ORDER
 737           *
 738           *      you can combine DB_TABLEINFO_ORDER and
 739           *      DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
 740           *      DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
 741           */
 742  
 743          // if $result is a string, then we want information about a
 744          // table without a resultset
 745          if (is_string($result)) {
 746              $id = @mysql_list_fields($this->dsn['database'],
 747                                       $result, $this->connection);
 748              if (empty($id)) {
 749                  return $this->mysqlRaiseError();
 750              }
 751          } else { // else we want information about a resultset
 752              $id = $result;
 753              if (empty($id)) {
 754                  return $this->mysqlRaiseError();
 755              }
 756          }
 757  
 758          $count = @mysql_num_fields($id);
 759  
 760          // made this IF due to performance (one if is faster than $count if's)
 761          if (empty($mode)) {
 762              for ($i=0; $i<$count; $i++) {
 763                  $res[$i]['table'] = @mysql_field_table ($id, $i);
 764                  $res[$i]['name']  = @mysql_field_name  ($id, $i);
 765                  $res[$i]['type']  = @mysql_field_type  ($id, $i);
 766                  $res[$i]['len']   = @mysql_field_len   ($id, $i);
 767                  $res[$i]['flags'] = @mysql_field_flags ($id, $i);
 768              }
 769          } else { // full
 770              $res['num_fields']= $count;
 771  
 772              for ($i=0; $i<$count; $i++) {
 773                  $res[$i]['table'] = @mysql_field_table ($id, $i);
 774                  $res[$i]['name']  = @mysql_field_name  ($id, $i);
 775                  $res[$i]['type']  = @mysql_field_type  ($id, $i);
 776                  $res[$i]['len']   = @mysql_field_len   ($id, $i);
 777                  $res[$i]['flags'] = @mysql_field_flags ($id, $i);
 778                  if ($mode & DB_TABLEINFO_ORDER) {
 779                      $res['order'][$res[$i]['name']] = $i;
 780                  }
 781                  if ($mode & DB_TABLEINFO_ORDERTABLE) {
 782                      $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
 783                  }
 784              }
 785          }
 786  
 787          // free the result only if we were called on a table
 788          if (is_string($result)) {
 789              @mysql_free_result($id);
 790          }
 791          return $res;
 792      }
 793  
 794      // }}}
 795      // {{{ getSpecialQuery()
 796  
 797      /**
 798      * Returns the query needed to get some backend info
 799      * @param string $type What kind of info you want to retrieve
 800      * @return string The SQL query string
 801      */
 802      function getSpecialQuery($type)
 803      {
 804          switch ($type) {
 805              case 'tables':
 806                  $sql = "SHOW TABLES";
 807                  break;
 808              case 'views':
 809                  return DB_ERROR_NOT_CAPABLE;
 810              case 'users':
 811                  $sql = "select distinct User from user";
 812                  if($this->dsn['database'] != 'mysql') {
 813                      $dsn = $this->dsn;
 814                      $dsn['database'] = 'mysql';
 815                      if (DB::isError($db = DB::connect($dsn))) {
 816                          return $db;
 817                      }
 818                      $sql = $db->getCol($sql);
 819                      $db->disconnect();
 820                      // XXX Fixme the mysql driver should take care of this
 821                      if (!@mysql_select_db($this->dsn['database'], $this->connection)) {
 822                          return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
 823                      }
 824                  }
 825                  return $sql;
 826                  break;
 827              case 'databases':
 828                  $sql = "SHOW DATABASES";
 829                  break;
 830              default:
 831                  return null;
 832          }
 833          return $sql;
 834      }
 835  
 836      // }}}
 837  
 838      // TODO/wishlist:
 839      // longReadlen
 840      // binmode
 841  }
 842  
 843  ?>


Généré le : Mon Nov 26 12:29:37 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics