[ Index ]

PHP Cross Reference of Joomla 1.5.26 DE

title

Body

[close]

/libraries/joomla/database/database/ -> mysql.php (source)

   1  <?php
   2  /**
   3  * @version        $Id: mysql.php 16385 2010-04-23 10:44:15Z ian $
   4  * @package        Joomla.Framework
   5  * @subpackage    Database
   6  * @copyright    Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
   7  * @license        GNU/GPL, see LICENSE.php
   8  * Joomla! is free software. This version may have been modified pursuant
   9  * to the GNU General Public License, and as distributed it includes or
  10  * is derivative of works licensed under the GNU General Public License or
  11  * other free or open source software licenses.
  12  * See COPYRIGHT.php for copyright notices and details.
  13  */
  14  
  15  // Check to ensure this file is within the rest of the framework
  16  defined('JPATH_BASE') or die();
  17  
  18  /**
  19   * MySQL database driver
  20   *
  21   * @package        Joomla.Framework
  22   * @subpackage    Database
  23   * @since        1.0
  24   */
  25  class JDatabaseMySQL extends JDatabase
  26  {
  27      /**
  28       * The database driver name
  29       *
  30       * @var string
  31       */
  32      var $name            = 'mysql';
  33  
  34      /**
  35       *  The null/zero date string
  36       *
  37       * @var string
  38       */
  39      var $_nullDate        = '0000-00-00 00:00:00';
  40  
  41      /**
  42       * Quote for named objects
  43       *
  44       * @var string
  45       */
  46      var $_nameQuote        = '`';
  47  
  48      /**
  49      * Database object constructor
  50      *
  51      * @access    public
  52      * @param    array    List of options used to configure the connection
  53      * @since    1.5
  54      * @see        JDatabase
  55      */
  56  	function __construct( $options )
  57      {
  58          $host        = array_key_exists('host', $options)    ? $options['host']        : 'localhost';
  59          $user        = array_key_exists('user', $options)    ? $options['user']        : '';
  60          $password    = array_key_exists('password',$options)    ? $options['password']    : '';
  61          $database    = array_key_exists('database',$options)    ? $options['database']    : '';
  62          $prefix        = array_key_exists('prefix', $options)    ? $options['prefix']    : 'jos_';
  63          $select        = array_key_exists('select', $options)    ? $options['select']    : true;
  64  
  65          // perform a number of fatality checks, then return gracefully
  66          if (!function_exists( 'mysql_connect' )) {
  67              $this->_errorNum = 1;
  68              $this->_errorMsg = 'The MySQL adapter "mysql" is not available.';
  69              return;
  70          }
  71  
  72          // connect to the server
  73          if (!($this->_resource = @mysql_connect( $host, $user, $password, true ))) {
  74              $this->_errorNum = 2;
  75              $this->_errorMsg = 'Could not connect to MySQL';
  76              return;
  77          }
  78  
  79          // finalize initialization
  80          parent::__construct($options);
  81  
  82          // select the database
  83          if ( $select ) {
  84              $this->select($database);
  85          }
  86      }
  87  
  88      /**
  89       * Database object destructor
  90       *
  91       * @return boolean
  92       * @since 1.5
  93       */
  94  	function __destruct()
  95      {
  96          $return = false;
  97          if (is_resource($this->_resource)) {
  98              $return = mysql_close($this->_resource);
  99          }
 100          return $return;
 101      }
 102  
 103      /**
 104       * Test to see if the MySQL connector is available
 105       *
 106       * @static
 107       * @access public
 108       * @return boolean  True on success, false otherwise.
 109       */
 110  	function test()
 111      {
 112          return (function_exists( 'mysql_connect' ));
 113      }
 114  
 115      /**
 116       * Determines if the connection to the server is active.
 117       *
 118       * @access    public
 119       * @return    boolean
 120       * @since    1.5
 121       */
 122  	function connected()
 123      {
 124          if(is_resource($this->_resource)) {
 125              return mysql_ping($this->_resource);
 126          }
 127          return false;
 128      }
 129  
 130      /**
 131       * Select a database for use
 132       *
 133       * @access    public
 134       * @param    string $database
 135       * @return    boolean True if the database has been successfully selected
 136       * @since    1.5
 137       */
 138  	function select($database)
 139      {
 140          if ( ! $database )
 141          {
 142              return false;
 143          }
 144  
 145          if ( !mysql_select_db( $database, $this->_resource )) {
 146              $this->_errorNum = 3;
 147              $this->_errorMsg = 'Could not connect to database';
 148              return false;
 149          }
 150  
 151          // if running mysql 5, set sql-mode to mysql40 - thereby circumventing strict mode problems
 152          if ( strpos( $this->getVersion(), '5' ) === 0 ) {
 153              $this->setQuery( "SET sql_mode = 'MYSQL40'" );
 154              $this->query();
 155          }
 156  
 157          return true;
 158      }
 159  
 160      /**
 161       * Determines UTF support
 162       *
 163       * @access    public
 164       * @return boolean True - UTF is supported
 165       */
 166  	function hasUTF()
 167      {
 168          $verParts = explode( '.', $this->getVersion() );
 169          return ($verParts[0] == 5 || ($verParts[0] == 4 && $verParts[1] == 1 && (int)$verParts[2] >= 2));
 170      }
 171  
 172      /**
 173       * Custom settings for UTF support
 174       *
 175       * @access    public
 176       */
 177  	function setUTF()
 178      {
 179          mysql_query( "SET NAMES 'utf8'", $this->_resource );
 180      }
 181  
 182      /**
 183       * Get a database escaped string
 184       *
 185       * @param    string    The string to be escaped
 186       * @param    boolean    Optional parameter to provide extra escaping
 187       * @return    string
 188       * @access    public
 189       * @abstract
 190       */
 191  	function getEscaped( $text, $extra = false )
 192      {
 193          $result = mysql_real_escape_string( $text, $this->_resource );
 194          if ($extra) {
 195              $result = addcslashes( $result, '%_' );
 196          }
 197          return $result;
 198      }
 199  
 200      /**
 201       * Execute the query
 202       *
 203       * @access    public
 204       * @return mixed A database resource if successful, FALSE if not.
 205       */
 206  	function query()
 207      {
 208          if (!is_resource($this->_resource)) {
 209              return false;
 210          }
 211  
 212          // Take a local copy so that we don't modify the original query and cause issues later
 213          $sql = $this->_sql;
 214          if ($this->_limit > 0 || $this->_offset > 0) {
 215              $sql .= ' LIMIT ' . max($this->_offset, 0) . ', ' . max($this->_limit, 0);
 216          }
 217          if ($this->_debug) {
 218              $this->_ticker++;
 219              $this->_log[] = $sql;
 220          }
 221          $this->_errorNum = 0;
 222          $this->_errorMsg = '';
 223          $this->_cursor = mysql_query( $sql, $this->_resource );
 224  
 225          if (!$this->_cursor)
 226          {
 227              $this->_errorNum = mysql_errno( $this->_resource );
 228              $this->_errorMsg = mysql_error( $this->_resource )." SQL=$sql";
 229  
 230              if ($this->_debug) {
 231                  JError::raiseError(500, 'JDatabaseMySQL::query: '.$this->_errorNum.' - '.$this->_errorMsg );
 232              }
 233              return false;
 234          }
 235          return $this->_cursor;
 236      }
 237  
 238      /**
 239       * Description
 240       *
 241       * @access    public
 242       * @return int The number of affected rows in the previous operation
 243       * @since 1.0.5
 244       */
 245  	function getAffectedRows()
 246      {
 247          return mysql_affected_rows( $this->_resource );
 248      }
 249  
 250      /**
 251       * Execute a batch query
 252       *
 253       * @access    public
 254       * @return mixed A database resource if successful, FALSE if not.
 255       */
 256  	function queryBatch( $abort_on_error=true, $p_transaction_safe = false)
 257      {
 258          $this->_errorNum = 0;
 259          $this->_errorMsg = '';
 260          if ($p_transaction_safe) {
 261              $this->_sql = rtrim($this->_sql, "; \t\r\n\0");
 262              $si = $this->getVersion();
 263              preg_match_all( "/(\d+)\.(\d+)\.(\d+)/i", $si, $m );
 264              if ($m[1] >= 4) {
 265                  $this->_sql = 'START TRANSACTION;' . $this->_sql . '; COMMIT;';
 266              } else if ($m[2] >= 23 && $m[3] >= 19) {
 267                  $this->_sql = 'BEGIN WORK;' . $this->_sql . '; COMMIT;';
 268              } else if ($m[2] >= 23 && $m[3] >= 17) {
 269                  $this->_sql = 'BEGIN;' . $this->_sql . '; COMMIT;';
 270              }
 271          }
 272          $query_split = $this->splitSql($this->_sql);
 273          $error = 0;
 274          foreach ($query_split as $command_line) {
 275              $command_line = trim( $command_line );
 276              if ($command_line != '') {
 277                  $this->_cursor = mysql_query( $command_line, $this->_resource );
 278                  if ($this->_debug) {
 279                      $this->_ticker++;
 280                      $this->_log[] = $command_line;
 281                  }
 282                  if (!$this->_cursor) {
 283                      $error = 1;
 284                      $this->_errorNum .= mysql_errno( $this->_resource ) . ' ';
 285                      $this->_errorMsg .= mysql_error( $this->_resource )." SQL=$command_line <br />";
 286                      if ($abort_on_error) {
 287                          return $this->_cursor;
 288                      }
 289                  }
 290              }
 291          }
 292          return $error ? false : true;
 293      }
 294  
 295      /**
 296       * Diagnostic function
 297       *
 298       * @access    public
 299       * @return    string
 300       */
 301  	function explain()
 302      {
 303          $temp = $this->_sql;
 304          $this->_sql = "EXPLAIN $this->_sql";
 305  
 306          if (!($cur = $this->query())) {
 307              return null;
 308          }
 309          $first = true;
 310  
 311          $buffer = '<table id="explain-sql">';
 312          $buffer .= '<thead><tr><td colspan="99">'.$this->getQuery().'</td></tr>';
 313          while ($row = mysql_fetch_assoc( $cur )) {
 314              if ($first) {
 315                  $buffer .= '<tr>';
 316                  foreach ($row as $k=>$v) {
 317                      $buffer .= '<th>'.$k.'</th>';
 318                  }
 319                  $buffer .= '</tr>';
 320                  $first = false;
 321              }
 322              $buffer .= '</thead><tbody><tr>';
 323              foreach ($row as $k=>$v) {
 324                  $buffer .= '<td>'.$v.'</td>';
 325              }
 326              $buffer .= '</tr>';
 327          }
 328          $buffer .= '</tbody></table>';
 329          mysql_free_result( $cur );
 330  
 331          $this->_sql = $temp;
 332  
 333          return $buffer;
 334      }
 335  
 336      /**
 337       * Description
 338       *
 339       * @access    public
 340       * @return int The number of rows returned from the most recent query.
 341       */
 342  	function getNumRows( $cur=null )
 343      {
 344          return mysql_num_rows( $cur ? $cur : $this->_cursor );
 345      }
 346  
 347      /**
 348       * This method loads the first field of the first row returned by the query.
 349       *
 350       * @access    public
 351       * @return The value returned in the query or null if the query failed.
 352       */
 353  	function loadResult()
 354      {
 355          if (!($cur = $this->query())) {
 356              return null;
 357          }
 358          $ret = null;
 359          if ($row = mysql_fetch_row( $cur )) {
 360              $ret = $row[0];
 361          }
 362          mysql_free_result( $cur );
 363          return $ret;
 364      }
 365  
 366      /**
 367       * Load an array of single field results into an array
 368       *
 369       * @access    public
 370       */
 371  	function loadResultArray($numinarray = 0)
 372      {
 373          if (!($cur = $this->query())) {
 374              return null;
 375          }
 376          $array = array();
 377          while ($row = mysql_fetch_row( $cur )) {
 378              $array[] = $row[$numinarray];
 379          }
 380          mysql_free_result( $cur );
 381          return $array;
 382      }
 383  
 384      /**
 385      * Fetch a result row as an associative array
 386      *
 387      * @access    public
 388      * @return array
 389      */
 390  	function loadAssoc()
 391      {
 392          if (!($cur = $this->query())) {
 393              return null;
 394          }
 395          $ret = null;
 396          if ($array = mysql_fetch_assoc( $cur )) {
 397              $ret = $array;
 398          }
 399          mysql_free_result( $cur );
 400          return $ret;
 401      }
 402  
 403      /**
 404      * Load a assoc list of database rows
 405      *
 406      * @access    public
 407      * @param string The field name of a primary key
 408      * @return array If <var>key</var> is empty as sequential list of returned records.
 409      */
 410  	function loadAssocList( $key='' )
 411      {
 412          if (!($cur = $this->query())) {
 413              return null;
 414          }
 415          $array = array();
 416          while ($row = mysql_fetch_assoc( $cur )) {
 417              if ($key) {
 418                  $array[$row[$key]] = $row;
 419              } else {
 420                  $array[] = $row;
 421              }
 422          }
 423          mysql_free_result( $cur );
 424          return $array;
 425      }
 426  
 427      /**
 428      * This global function loads the first row of a query into an object
 429      *
 430      * @access    public
 431      * @return     object
 432      */
 433  	function loadObject( )
 434      {
 435          if (!($cur = $this->query())) {
 436              return null;
 437          }
 438          $ret = null;
 439          if ($object = mysql_fetch_object( $cur )) {
 440              $ret = $object;
 441          }
 442          mysql_free_result( $cur );
 443          return $ret;
 444      }
 445  
 446      /**
 447      * Load a list of database objects
 448      *
 449      * If <var>key</var> is not empty then the returned array is indexed by the value
 450      * the database key.  Returns <var>null</var> if the query fails.
 451      *
 452      * @access    public
 453      * @param string The field name of a primary key
 454      * @return array If <var>key</var> is empty as sequential list of returned records.
 455      */
 456  	function loadObjectList( $key='' )
 457      {
 458          if (!($cur = $this->query())) {
 459              return null;
 460          }
 461          $array = array();
 462          while ($row = mysql_fetch_object( $cur )) {
 463              if ($key) {
 464                  $array[$row->$key] = $row;
 465              } else {
 466                  $array[] = $row;
 467              }
 468          }
 469          mysql_free_result( $cur );
 470          return $array;
 471      }
 472  
 473      /**
 474       * Description
 475       *
 476       * @access    public
 477       * @return The first row of the query.
 478       */
 479  	function loadRow()
 480      {
 481          if (!($cur = $this->query())) {
 482              return null;
 483          }
 484          $ret = null;
 485          if ($row = mysql_fetch_row( $cur )) {
 486              $ret = $row;
 487          }
 488          mysql_free_result( $cur );
 489          return $ret;
 490      }
 491  
 492      /**
 493      * Load a list of database rows (numeric column indexing)
 494      *
 495      * @access public
 496      * @param string The field name of a primary key
 497      * @return array If <var>key</var> is empty as sequential list of returned records.
 498      * If <var>key</var> is not empty then the returned array is indexed by the value
 499      * the database key.  Returns <var>null</var> if the query fails.
 500      */
 501  	function loadRowList( $key=null )
 502      {
 503          if (!($cur = $this->query())) {
 504              return null;
 505          }
 506          $array = array();
 507          while ($row = mysql_fetch_row( $cur )) {
 508              if ($key !== null) {
 509                  $array[$row[$key]] = $row;
 510              } else {
 511                  $array[] = $row;
 512              }
 513          }
 514          mysql_free_result( $cur );
 515          return $array;
 516      }
 517  
 518      /**
 519       * Inserts a row into a table based on an objects properties
 520       *
 521       * @access    public
 522       * @param    string    The name of the table
 523       * @param    object    An object whose properties match table fields
 524       * @param    string    The name of the primary key. If provided the object property is updated.
 525       */
 526  	function insertObject( $table, &$object, $keyName = NULL )
 527      {
 528          $fmtsql = 'INSERT INTO '.$this->nameQuote($table).' ( %s ) VALUES ( %s ) ';
 529          $fields = array();
 530          foreach (get_object_vars( $object ) as $k => $v) {
 531              if (is_array($v) or is_object($v) or $v === NULL) {
 532                  continue;
 533              }
 534              if ($k[0] == '_') { // internal field
 535                  continue;
 536              }
 537              $fields[] = $this->nameQuote( $k );
 538              $values[] = $this->isQuoted( $k ) ? $this->Quote( $v ) : (int) $v;
 539          }
 540          $this->setQuery( sprintf( $fmtsql, implode( ",", $fields ) ,  implode( ",", $values ) ) );
 541          if (!$this->query()) {
 542              return false;
 543          }
 544          $id = $this->insertid();
 545          if ($keyName && $id) {
 546              $object->$keyName = $id;
 547          }
 548          return true;
 549      }
 550  
 551      /**
 552       * Description
 553       *
 554       * @access public
 555       * @param [type] $updateNulls
 556       */
 557  	function updateObject( $table, &$object, $keyName, $updateNulls=true )
 558      {
 559          $fmtsql = 'UPDATE '.$this->nameQuote($table).' SET %s WHERE %s';
 560          $tmp = array();
 561          foreach (get_object_vars( $object ) as $k => $v)
 562          {
 563              if( is_array($v) or is_object($v) or $k[0] == '_' ) { // internal or NA field
 564                  continue;
 565              }
 566              if( $k == $keyName ) { // PK not to be updated
 567                  $where = $keyName . '=' . $this->Quote( $v );
 568                  continue;
 569              }
 570              if ($v === null)
 571              {
 572                  if ($updateNulls) {
 573                      $val = 'NULL';
 574                  } else {
 575                      continue;
 576                  }
 577              } else {
 578                  $val = $this->isQuoted( $k ) ? $this->Quote( $v ) : (int) $v;
 579              }
 580              $tmp[] = $this->nameQuote( $k ) . '=' . $val;
 581          }
 582          $this->setQuery( sprintf( $fmtsql, implode( ",", $tmp ) , $where ) );
 583          return $this->query();
 584      }
 585  
 586      /**
 587       * Description
 588       *
 589       * @access public
 590       */
 591  	function insertid()
 592      {
 593          return mysql_insert_id( $this->_resource );
 594      }
 595  
 596      /**
 597       * Description
 598       *
 599       * @access public
 600       */
 601  	function getVersion()
 602      {
 603          return mysql_get_server_info( $this->_resource );
 604      }
 605  
 606      /**
 607       * Assumes database collation in use by sampling one text field in one table
 608       *
 609       * @access    public
 610       * @return string Collation in use
 611       */
 612  	function getCollation ()
 613      {
 614          if ( $this->hasUTF() ) {
 615              $this->setQuery( 'SHOW FULL COLUMNS FROM #__content' );
 616              $array = $this->loadAssocList();
 617              return $array['4']['Collation'];
 618          } else {
 619              return "N/A (mySQL < 4.1.2)";
 620          }
 621      }
 622  
 623      /**
 624       * Description
 625       *
 626       * @access    public
 627       * @return array A list of all the tables in the database
 628       */
 629  	function getTableList()
 630      {
 631          $this->setQuery( 'SHOW TABLES' );
 632          return $this->loadResultArray();
 633      }
 634  
 635      /**
 636       * Shows the CREATE TABLE statement that creates the given tables
 637       *
 638       * @access    public
 639       * @param     array|string     A table name or a list of table names
 640       * @return     array A list the create SQL for the tables
 641       */
 642  	function getTableCreate( $tables )
 643      {
 644          settype($tables, 'array'); //force to array
 645          $result = array();
 646  
 647          foreach ($tables as $tblval) {
 648              $this->setQuery( 'SHOW CREATE table ' . $this->getEscaped( $tblval ) );
 649              $rows = $this->loadRowList();
 650              foreach ($rows as $row) {
 651                  $result[$tblval] = $row[1];
 652              }
 653          }
 654  
 655          return $result;
 656      }
 657  
 658      /**
 659       * Retrieves information about the given tables
 660       *
 661       * @access    public
 662       * @param     array|string     A table name or a list of table names
 663       * @param    boolean            Only return field types, default true
 664       * @return    array An array of fields by table
 665       */
 666  	function getTableFields( $tables, $typeonly = true )
 667      {
 668          settype($tables, 'array'); //force to array
 669          $result = array();
 670  
 671          foreach ($tables as $tblval)
 672          {
 673              $this->setQuery( 'SHOW FIELDS FROM ' . $tblval );
 674              $fields = $this->loadObjectList();
 675  
 676              if($typeonly)
 677              {
 678                  foreach ($fields as $field) {
 679                      $result[$tblval][$field->Field] = preg_replace("/[(0-9)]/",'', $field->Type );
 680                  }
 681              }
 682              else
 683              {
 684                  foreach ($fields as $field) {
 685                      $result[$tblval][$field->Field] = $field;
 686                  }
 687              }
 688          }
 689  
 690          return $result;
 691      }
 692  }


Generated: Wed Mar 28 15:54:07 2012 Cross-referenced by PHPXref 0.7.1