web/wp-includes/wp-db.php
changeset 194 32102edaa81b
parent 136 bde1974c263b
child 204 09a1c134465b
--- a/web/wp-includes/wp-db.php	Thu Sep 16 15:45:36 2010 +0000
+++ b/web/wp-includes/wp-db.php	Mon Nov 19 18:26:13 2012 +0100
@@ -12,43 +12,41 @@
 /**
  * @since 0.71
  */
-define('EZSQL_VERSION', 'WP1.25');
+define( 'EZSQL_VERSION', 'WP1.25' );
 
 /**
  * @since 0.71
  */
-define('OBJECT', 'OBJECT', true);
+define( 'OBJECT', 'OBJECT', true );
 
 /**
- * @since {@internal Version Unknown}}
+ * @since 2.5.0
  */
-define('OBJECT_K', 'OBJECT_K', false);
+define( 'OBJECT_K', 'OBJECT_K' );
 
 /**
  * @since 0.71
  */
-define('ARRAY_A', 'ARRAY_A', false);
+define( 'ARRAY_A', 'ARRAY_A' );
 
 /**
  * @since 0.71
  */
-define('ARRAY_N', 'ARRAY_N', false);
+define( 'ARRAY_N', 'ARRAY_N' );
 
 /**
  * WordPress Database Access Abstraction Object
  *
  * It is possible to replace this class with your own
  * by setting the $wpdb global variable in wp-content/db.php
- * file with your class. You can name it wpdb also, since
- * this file will not be included, if the other file is
- * available.
+ * file to your class. The wpdb class will still be included,
+ * so you can extend it or simply use your own.
  *
  * @link http://codex.wordpress.org/Function_Reference/wpdb_Class
  *
  * @package WordPress
  * @subpackage Database
  * @since 0.71
- * @final
  */
 class wpdb {
 
@@ -65,7 +63,7 @@
 	 * Whether to suppress errors during the DB bootstrapping.
 	 *
 	 * @access private
-	 * @since {@internal Version Unknown}}
+	 * @since 2.5.0
 	 * @var bool
 	 */
 	var $suppress_errors = false;
@@ -73,7 +71,7 @@
 	/**
 	 * The last error during query.
 	 *
-	 * @since {@internal Version Unknown}}
+	 * @since 2.5.0
 	 * @var string
 	 */
 	var $last_error = '';
@@ -88,6 +86,33 @@
 	var $num_queries = 0;
 
 	/**
+	 * Count of rows returned by previous query
+	 *
+	 * @since 1.2.0
+	 * @access private
+	 * @var int
+	 */
+	var $num_rows = 0;
+
+	/**
+	 * Count of affected rows by previous query
+	 *
+	 * @since 0.71
+	 * @access private
+	 * @var int
+	 */
+	var $rows_affected = 0;
+
+	/**
+	 * The ID generated for an AUTO_INCREMENT column by the previous query (usually INSERT).
+	 *
+	 * @since 0.71
+	 * @access public
+	 * @var int
+	 */
+	var $insert_id = 0;
+
+	/**
 	 * Saved result of the last query made
 	 *
 	 * @since 1.2.0
@@ -97,6 +122,15 @@
 	var $last_query;
 
 	/**
+	 * Results of the last query made
+	 *
+	 * @since 1.0.0
+	 * @access private
+	 * @var array|null
+	 */
+	var $last_result;
+
+	/**
 	 * Saved info on the table column
 	 *
 	 * @since 1.2.0
@@ -137,40 +171,66 @@
 	var $ready = false;
 
 	/**
-	 * WordPress Posts table
+	 * {@internal Missing Description}}
 	 *
-	 * @since 1.5.0
+	 * @since 3.0.0
+	 * @access public
+	 * @var int
+	 */
+	var $blogid = 0;
+
+	/**
+	 * {@internal Missing Description}}
+	 *
+	 * @since 3.0.0
 	 * @access public
-	 * @var string
+	 * @var int
 	 */
-	var $posts;
+	var $siteid = 0;
+
+	/**
+	 * List of WordPress per-blog tables
+	 *
+	 * @since 2.5.0
+	 * @access private
+	 * @see wpdb::tables()
+	 * @var array
+	 */
+	var $tables = array( 'posts', 'comments', 'links', 'options', 'postmeta',
+		'terms', 'term_taxonomy', 'term_relationships', 'commentmeta' );
 
 	/**
-	 * WordPress Users table
+	 * List of deprecated WordPress tables
+	 *
+	 * categories, post2cat, and link2cat were deprecated in 2.3.0, db version 5539
 	 *
-	 * @since 1.5.0
-	 * @access public
-	 * @var string
+	 * @since 2.9.0
+	 * @access private
+	 * @see wpdb::tables()
+	 * @var array
 	 */
-	var $users;
+	var $old_tables = array( 'categories', 'post2cat', 'link2cat' );
 
 	/**
-	 * WordPress Categories table
+	 * List of WordPress global tables
 	 *
-	 * @since 1.5.0
-	 * @access public
-	 * @var string
+	 * @since 3.0.0
+	 * @access private
+	 * @see wpdb::tables()
+	 * @var array
 	 */
-	var $categories;
+	var $global_tables = array( 'users', 'usermeta' );
 
 	/**
-	 * WordPress Post to Category table
+	 * List of Multisite global tables
 	 *
-	 * @since 1.5.0
-	 * @access public
-	 * @var string
+	 * @since 3.0.0
+	 * @access private
+	 * @see wpdb::tables()
+	 * @var array
 	 */
-	var $post2cat;
+	var $ms_global_tables = array( 'blogs', 'signups', 'site', 'sitemeta',
+		'sitecategories', 'registration_log', 'blog_versions' );
 
 	/**
 	 * WordPress Comments table
@@ -182,6 +242,15 @@
 	var $comments;
 
 	/**
+	 * WordPress Comment Metadata table
+	 *
+	 * @since 2.9.0
+	 * @access public
+	 * @var string
+	 */
+	var $commentmeta;
+
+	/**
 	 * WordPress Links table
 	 *
 	 * @since 1.5.0
@@ -202,29 +271,20 @@
 	/**
 	 * WordPress Post Metadata table
 	 *
-	 * @since {@internal Version Unknown}}
+	 * @since 1.5.0
 	 * @access public
 	 * @var string
 	 */
 	var $postmeta;
 
 	/**
-	 * WordPress Comment Metadata table
+	 * WordPress Posts table
 	 *
-	 * @since 2.9
+	 * @since 1.5.0
 	 * @access public
 	 * @var string
 	 */
-	var $commentmeta;
-
-	/**
-	 * WordPress User Metadata table
-	 *
-	 * @since 2.3.0
-	 * @access public
-	 * @var string
-	 */
-	var $usermeta;
+	var $posts;
 
 	/**
 	 * WordPress Terms table
@@ -236,15 +296,6 @@
 	var $terms;
 
 	/**
-	 * WordPress Term Taxonomy table
-	 *
-	 * @since 2.3.0
-	 * @access public
-	 * @var string
-	 */
-	var $term_taxonomy;
-
-	/**
 	 * WordPress Term Relationships table
 	 *
 	 * @since 2.3.0
@@ -254,36 +305,112 @@
 	var $term_relationships;
 
 	/**
-	 * List of WordPress tables
+	 * WordPress Term Taxonomy table
+	 *
+	 * @since 2.3.0
+	 * @access public
+	 * @var string
+	 */
+	var $term_taxonomy;
+
+	/*
+	 * Global and Multisite tables
+	 */
+
+	/**
+	 * WordPress User Metadata table
+	 *
+	 * @since 2.3.0
+	 * @access public
+	 * @var string
+	 */
+	var $usermeta;
+
+	/**
+	 * WordPress Users table
 	 *
-	 * @since {@internal Version Unknown}}
-	 * @access private
-	 * @var array
+	 * @since 1.5.0
+	 * @access public
+	 * @var string
 	 */
-	var $tables = array('users', 'usermeta', 'posts', 'categories', 'post2cat', 'comments', 'links', 'link2cat', 'options',
-			'postmeta', 'terms', 'term_taxonomy', 'term_relationships', 'commentmeta');
+	var $users;
+
+	/**
+	 * Multisite Blogs table
+	 *
+	 * @since 3.0.0
+	 * @access public
+	 * @var string
+	 */
+	var $blogs;
+
+	/**
+	 * Multisite Blog Versions table
+	 *
+	 * @since 3.0.0
+	 * @access public
+	 * @var string
+	 */
+	var $blog_versions;
 
 	/**
-	 * List of deprecated WordPress tables
+	 * Multisite Registration Log table
+	 *
+	 * @since 3.0.0
+	 * @access public
+	 * @var string
+	 */
+	var $registration_log;
+
+	/**
+	 * Multisite Signups table
 	 *
-	 * @since 2.9.0
-	 * @access private
-	 * @var array
+	 * @since 3.0.0
+	 * @access public
+	 * @var string
 	 */
-	var $old_tables = array('categories', 'post2cat', 'link2cat');
+	var $signups;
 
+	/**
+	 * Multisite Sites table
+	 *
+	 * @since 3.0.0
+	 * @access public
+	 * @var string
+	 */
+	var $site;
 
 	/**
-	 * Format specifiers for DB columns. Columns not listed here default to %s.  Initialized in wp-settings.php.
+	 * Multisite Sitewide Terms table
+	 *
+	 * @since 3.0.0
+	 * @access public
+	 * @var string
+	 */
+	var $sitecategories;
+
+	/**
+	 * Multisite Site Metadata table
 	 *
-	 * Keys are colmn names, values are format types: 'ID' => '%d'
+	 * @since 3.0.0
+	 * @access public
+	 * @var string
+	 */
+	var $sitemeta;
+
+	/**
+	 * Format specifiers for DB columns. Columns not listed here default to %s. Initialized during WP load.
+	 *
+	 * Keys are column names, values are format types: 'ID' => '%d'
 	 *
 	 * @since 2.8.0
-	 * @see wpdb:prepare()
-	 * @see wpdb:insert()
-	 * @see wpdb:update()
+	 * @see wpdb::prepare()
+	 * @see wpdb::insert()
+	 * @see wpdb::update()
+	 * @see wpdb::delete()
+	 * @see wp_set_wpdb_vars()
 	 * @access public
-	 * @war array
+	 * @var array
 	 */
 	var $field_types = array();
 
@@ -324,21 +451,27 @@
 	var $dbuser;
 
 	/**
-	 * Connects to the database server and selects a database
+	 * A textual description of the last query/get_row/get_var call
 	 *
-	 * PHP4 compatibility layer for calling the PHP5 constructor.
-	 *
-	 * @uses wpdb::__construct() Passes parameters and returns result
-	 * @since 0.71
+	 * @since 3.0.0
+	 * @access public
+	 * @var string
+	 */
+	var $func_call;
+
+	/**
+	 * Whether MySQL is used as the database engine.
 	 *
-	 * @param string $dbuser MySQL database user
-	 * @param string $dbpassword MySQL database password
-	 * @param string $dbname MySQL database name
-	 * @param string $dbhost MySQL database host
+	 * Set in WPDB::db_connect() to true, by default. This is used when checking
+	 * against the required MySQL version for WordPress. Normally, a replacement
+	 * database drop-in (db.php) will skip these checks, but setting this to true
+	 * will force the checks to occur.
+	 *
+	 * @since 3.3.0
+	 * @access public
+	 * @var bool
 	 */
-	function wpdb($dbuser, $dbpassword, $dbname, $dbhost) {
-		return $this->__construct($dbuser, $dbpassword, $dbname, $dbhost);
-	}
+	public $is_mysql = null;
 
 	/**
 	 * Connects to the database server and selects a database
@@ -347,6 +480,7 @@
 	 * the actual setting up of the class properties and connection
 	 * to the database.
 	 *
+	 * @link http://core.trac.wordpress.org/ticket/3354
 	 * @since 2.0.8
 	 *
 	 * @param string $dbuser MySQL database user
@@ -354,92 +488,244 @@
 	 * @param string $dbname MySQL database name
 	 * @param string $dbhost MySQL database host
 	 */
-	function __construct($dbuser, $dbpassword, $dbname, $dbhost) {
-		register_shutdown_function(array(&$this, "__destruct"));
+	function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) {
+		register_shutdown_function( array( &$this, '__destruct' ) );
 
 		if ( WP_DEBUG )
 			$this->show_errors();
 
-		if ( defined('DB_CHARSET') )
-			$this->charset = DB_CHARSET;
-
-		if ( defined('DB_COLLATE') )
-			$this->collate = DB_COLLATE;
+		$this->init_charset();
 
 		$this->dbuser = $dbuser;
-
-		$this->dbh = @mysql_connect($dbhost, $dbuser, $dbpassword, true);
-		if (!$this->dbh) {
-			$this->bail(sprintf(/*WP_I18N_DB_CONN_ERROR*/'
-<h1>Erreur lors de l&rsquo;établissement de la connexion &agrave; la base de données</h1>
-<p>Cela signifie soit que l&rsquo;identifiant et/ou le mot de passe indiqués dans votre fichier <code>wp-config.php</code> sont incorrects, ou que le serveur de base de données à l&rsquo;adresse <code>%s</code> est inaccessible - ce qui implique que le serveur de base de données de votre hébergeur est sans doute défaillant.</p>
-<ul>
-	<li>Êtes-vous certain(e) d&rsquo;avoir correctement indiqué votre identifiant et votre mot de passe&nbsp;?</li>
-	<li>Êtes-vous certain(e) d&rsquo;avoir entré le bon serveur de base de données&nbsp;?</li>
-	<li>Êtes-vous certain(e) que le serveur de base de données fonctionne correctement&nbsp;?</li>
-</ul>
-<p>Si vous n&rsquo;êtes pas sûr(e) de bien comprendre les mots de cette liste, vous devriez sans doute prendre contact avec votre hébergeur. Si malgré cela cette erreur s&rsquo;affiche toujours, indiquez votre problème au <a href=\'http://www.wordpress-fr.net/support/\'>forum d&rsquo;entraide en français</a>.</p>
-'/*/WP_I18N_DB_CONN_ERROR*/, $dbhost), 'db_connect_fail');
-			return;
-		}
+		$this->dbpassword = $dbpassword;
+		$this->dbname = $dbname;
+		$this->dbhost = $dbhost;
 
-		$this->ready = true;
-
-		if ( $this->has_cap( 'collation' ) && !empty($this->charset) ) {
-			if ( function_exists('mysql_set_charset') ) {
-				mysql_set_charset($this->charset, $this->dbh);
-				$this->real_escape = true;
-			} else {
-				$collation_query = "SET NAMES '{$this->charset}'";
-				if ( !empty($this->collate) )
-					$collation_query .= " COLLATE '{$this->collate}'";
-				$this->query($collation_query);
-			}
-		}
-
-		$this->select($dbname);
+		$this->db_connect();
 	}
 
 	/**
 	 * PHP5 style destructor and will run when database object is destroyed.
 	 *
+	 * @see wpdb::__construct()
 	 * @since 2.0.8
-	 *
-	 * @return bool Always true
+	 * @return bool true
 	 */
 	function __destruct() {
 		return true;
 	}
 
 	/**
-	 * Sets the table prefix for the WordPress tables.
+	 * Set $this->charset and $this->collate
+	 *
+	 * @since 3.1.0
+	 */
+	function init_charset() {
+		if ( function_exists('is_multisite') && is_multisite() ) {
+			$this->charset = 'utf8';
+			if ( defined( 'DB_COLLATE' ) && DB_COLLATE )
+				$this->collate = DB_COLLATE;
+			else
+				$this->collate = 'utf8_general_ci';
+		} elseif ( defined( 'DB_COLLATE' ) ) {
+			$this->collate = DB_COLLATE;
+		}
+
+		if ( defined( 'DB_CHARSET' ) )
+			$this->charset = DB_CHARSET;
+	}
+
+	/**
+	 * Sets the connection's character set.
+	 *
+	 * @since 3.1.0
 	 *
-	 * Also allows for the CUSTOM_USER_TABLE and CUSTOM_USER_META_TABLE to
-	 * override the WordPress users and usersmeta tables that would otherwise be determined by the $prefix.
+	 * @param resource $dbh     The resource given by mysql_connect
+	 * @param string   $charset The character set (optional)
+	 * @param string   $collate The collation (optional)
+	 */
+	function set_charset($dbh, $charset = null, $collate = null) {
+		if ( !isset($charset) )
+			$charset = $this->charset;
+		if ( !isset($collate) )
+			$collate = $this->collate;
+		if ( $this->has_cap( 'collation', $dbh ) && !empty( $charset ) ) {
+			if ( function_exists( 'mysql_set_charset' ) && $this->has_cap( 'set_charset', $dbh ) ) {
+				mysql_set_charset( $charset, $dbh );
+				$this->real_escape = true;
+			} else {
+				$query = $this->prepare( 'SET NAMES %s', $charset );
+				if ( ! empty( $collate ) )
+					$query .= $this->prepare( ' COLLATE %s', $collate );
+				mysql_query( $query, $dbh );
+			}
+		}
+	}
+
+	/**
+	 * Sets the table prefix for the WordPress tables.
 	 *
 	 * @since 2.5.0
 	 *
 	 * @param string $prefix Alphanumeric name for the new prefix.
+	 * @param bool $set_table_names Optional. Whether the table names, e.g. wpdb::$posts, should be updated or not.
 	 * @return string|WP_Error Old prefix or WP_Error on error
 	 */
-	function set_prefix($prefix) {
+	function set_prefix( $prefix, $set_table_names = true ) {
+
+		if ( preg_match( '|[^a-z0-9_]|i', $prefix ) )
+			return new WP_Error('invalid_db_prefix', 'Invalid database prefix' );
+
+		$old_prefix = is_multisite() ? '' : $prefix;
+
+		if ( isset( $this->base_prefix ) )
+			$old_prefix = $this->base_prefix;
+
+		$this->base_prefix = $prefix;
+
+		if ( $set_table_names ) {
+			foreach ( $this->tables( 'global' ) as $table => $prefixed_table )
+				$this->$table = $prefixed_table;
+
+			if ( is_multisite() && empty( $this->blogid ) )
+				return $old_prefix;
+
+			$this->prefix = $this->get_blog_prefix();
+
+			foreach ( $this->tables( 'blog' ) as $table => $prefixed_table )
+				$this->$table = $prefixed_table;
 
-		if ( preg_match('|[^a-z0-9_]|i', $prefix) )
-			return new WP_Error('invalid_db_prefix', /*WP_I18N_DB_BAD_PREFIX*/'Préfixe de la base de données invalide'/*/WP_I18N_DB_BAD_PREFIX*/);
+			foreach ( $this->tables( 'old' ) as $table => $prefixed_table )
+				$this->$table = $prefixed_table;
+		}
+		return $old_prefix;
+	}
 
-		$old_prefix = $this->prefix;
-		$this->prefix = $prefix;
+	/**
+	 * Sets blog id.
+	 *
+	 * @since 3.0.0
+	 * @access public
+	 * @param int $blog_id
+	 * @param int $site_id Optional.
+	 * @return string previous blog id
+	 */
+	function set_blog_id( $blog_id, $site_id = 0 ) {
+		if ( ! empty( $site_id ) )
+			$this->siteid = $site_id;
+
+		$old_blog_id  = $this->blogid;
+		$this->blogid = $blog_id;
+
+		$this->prefix = $this->get_blog_prefix();
+
+		foreach ( $this->tables( 'blog' ) as $table => $prefixed_table )
+			$this->$table = $prefixed_table;
+
+		foreach ( $this->tables( 'old' ) as $table => $prefixed_table )
+			$this->$table = $prefixed_table;
+
+		return $old_blog_id;
+	}
 
-		foreach ( (array) $this->tables as $table )
-			$this->$table = $this->prefix . $table;
+	/**
+	 * Gets blog prefix.
+	 *
+	 * @uses is_multisite()
+	 * @since 3.0.0
+	 * @param int $blog_id Optional.
+	 * @return string Blog prefix.
+	 */
+	function get_blog_prefix( $blog_id = null ) {
+		if ( is_multisite() ) {
+			if ( null === $blog_id )
+				$blog_id = $this->blogid;
+			$blog_id = (int) $blog_id;
+			if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) )
+				return $this->base_prefix;
+			else
+				return $this->base_prefix . $blog_id . '_';
+		} else {
+			return $this->base_prefix;
+		}
+	}
 
-		if ( defined('CUSTOM_USER_TABLE') )
-			$this->users = CUSTOM_USER_TABLE;
+	/**
+	 * Returns an array of WordPress tables.
+	 *
+	 * Also allows for the CUSTOM_USER_TABLE and CUSTOM_USER_META_TABLE to
+	 * override the WordPress users and usermeta tables that would otherwise
+	 * be determined by the prefix.
+	 *
+	 * The scope argument can take one of the following:
+	 *
+	 * 'all' - returns 'all' and 'global' tables. No old tables are returned.
+	 * 'blog' - returns the blog-level tables for the queried blog.
+	 * 'global' - returns the global tables for the installation, returning multisite tables only if running multisite.
+	 * 'ms_global' - returns the multisite global tables, regardless if current installation is multisite.
+	 * 'old' - returns tables which are deprecated.
+	 *
+	 * @since 3.0.0
+	 * @uses wpdb::$tables
+	 * @uses wpdb::$old_tables
+	 * @uses wpdb::$global_tables
+	 * @uses wpdb::$ms_global_tables
+	 * @uses is_multisite()
+	 *
+	 * @param string $scope Optional. Can be all, global, ms_global, blog, or old tables. Defaults to all.
+	 * @param bool $prefix Optional. Whether to include table prefixes. Default true. If blog
+	 * 	prefix is requested, then the custom users and usermeta tables will be mapped.
+	 * @param int $blog_id Optional. The blog_id to prefix. Defaults to wpdb::$blogid. Used only when prefix is requested.
+	 * @return array Table names. When a prefix is requested, the key is the unprefixed table name.
+	 */
+	function tables( $scope = 'all', $prefix = true, $blog_id = 0 ) {
+		switch ( $scope ) {
+			case 'all' :
+				$tables = array_merge( $this->global_tables, $this->tables );
+				if ( is_multisite() )
+					$tables = array_merge( $tables, $this->ms_global_tables );
+				break;
+			case 'blog' :
+				$tables = $this->tables;
+				break;
+			case 'global' :
+				$tables = $this->global_tables;
+				if ( is_multisite() )
+					$tables = array_merge( $tables, $this->ms_global_tables );
+				break;
+			case 'ms_global' :
+				$tables = $this->ms_global_tables;
+				break;
+			case 'old' :
+				$tables = $this->old_tables;
+				break;
+			default :
+				return array();
+				break;
+		}
 
-		if ( defined('CUSTOM_USER_META_TABLE') )
-			$this->usermeta = CUSTOM_USER_META_TABLE;
+		if ( $prefix ) {
+			if ( ! $blog_id )
+				$blog_id = $this->blogid;
+			$blog_prefix = $this->get_blog_prefix( $blog_id );
+			$base_prefix = $this->base_prefix;
+			$global_tables = array_merge( $this->global_tables, $this->ms_global_tables );
+			foreach ( $tables as $k => $table ) {
+				if ( in_array( $table, $global_tables ) )
+					$tables[ $table ] = $base_prefix . $table;
+				else
+					$tables[ $table ] = $blog_prefix . $table;
+				unset( $tables[ $k ] );
+			}
 
-		return $old_prefix;
+			if ( isset( $tables['users'] ) && defined( 'CUSTOM_USER_TABLE' ) )
+				$tables['users'] = CUSTOM_USER_TABLE;
+
+			if ( isset( $tables['usermeta'] ) && defined( 'CUSTOM_USER_META_TABLE' ) )
+				$tables['usermeta'] = CUSTOM_USER_META_TABLE;
+		}
+
+		return $tables;
 	}
 
 	/**
@@ -451,37 +737,73 @@
 	 * @since 0.71
 	 *
 	 * @param string $db MySQL database name
+	 * @param resource $dbh Optional link identifier.
 	 * @return null Always null.
 	 */
-	function select($db) {
-		if (!@mysql_select_db($db, $this->dbh)) {
+	function select( $db, $dbh = null ) {
+		if ( is_null($dbh) )
+			$dbh = $this->dbh;
+
+		if ( !@mysql_select_db( $db, $dbh ) ) {
 			$this->ready = false;
-			$this->bail(sprintf(/*WP_I18N_DB_SELECT_DB*/'
-<h1>Impossible de sélectionner la base de données</h1>
-<p>La connexion au serveur de base de données s&rsquo;est bien faite (donc votre identifiant et votre mot de passe sont les bons), mais la base de données <code>%1$s</code> n&rsquo;a pas pu être sélectionnée.</p>
+			wp_load_translations_early();
+			$this->bail( sprintf( __( '<h1>Can&#8217;t select database</h1>
+<p>We were able to connect to the database server (which means your username and password is okay) but not able to select the <code>%1$s</code> database.</p>
 <ul>
-<li>Êtes-vous certain(e) qu&rsquo;elle existe&nbsp;?</li>
-<li>L&rsquo;utilisateur <code>%2$s</code> a-t-il les droits pour utiliser la base de donn&eacute; <code>%1$s</code>&nbsp;?</li>
-<li>Sur certains systèmes, le nom de votre base de données est préfixée de votre identifiant, donc son nom complet peut être <code>identifiant_nomdelabase</code>. Cela peut-il être la cause du problème&nbps;?</li>
+<li>Are you sure it exists?</li>
+<li>Does the user <code>%2$s</code> have permission to use the <code>%1$s</code> database?</li>
+<li>On some systems the name of your database is prefixed with your username, so it would be like <code>username_%1$s</code>. Could that be the problem?</li>
 </ul>
-<p>Si vous ne savez pas comment régler votre base de données, vous devriez <strong>prendre contact avec votre hébergeur</strong>. Si toutes vos tentatives échouent, peut-être trouverez-vous une réponse sur le <a href=\'http://www.wordpress-fr.net/support/\'>forum d&rsquo;entraide en français</a>.</p>'/*/WP_I18N_DB_SELECT_DB*/, $db, $this->dbuser), 'db_select_fail');
+<p>If you don\'t know how to set up a database you should <strong>contact your host</strong>. If all else fails you may find help at the <a href="http://wordpress.org/support/">WordPress Support Forums</a>.</p>' ), htmlspecialchars( $db, ENT_QUOTES ), htmlspecialchars( $this->dbuser, ENT_QUOTES ) ), 'db_select_fail' );
 			return;
 		}
 	}
 
-	function _weak_escape($string) {
-		return addslashes($string);
+	/**
+	 * Weak escape, using addslashes()
+	 *
+	 * @see addslashes()
+	 * @since 2.8.0
+	 * @access private
+	 *
+	 * @param string $string
+	 * @return string
+	 */
+	function _weak_escape( $string ) {
+		return addslashes( $string );
 	}
 
-	function _real_escape($string) {
+	/**
+	 * Real escape, using mysql_real_escape_string() or addslashes()
+	 *
+	 * @see mysql_real_escape_string()
+	 * @see addslashes()
+	 * @since 2.8.0
+	 * @access private
+	 *
+	 * @param  string $string to escape
+	 * @return string escaped
+	 */
+	function _real_escape( $string ) {
 		if ( $this->dbh && $this->real_escape )
 			return mysql_real_escape_string( $string, $this->dbh );
 		else
 			return addslashes( $string );
 	}
 
-	function _escape($data) {
-		if ( is_array($data) ) {
+	/**
+	 * Escape data. Works on arrays.
+	 *
+	 * @uses wpdb::_escape()
+	 * @uses wpdb::_real_escape()
+	 * @since  2.8.0
+	 * @access private
+	 *
+	 * @param  string|array $data
+	 * @return string|array escaped
+	 */
+	function _escape( $data ) {
+		if ( is_array( $data ) ) {
 			foreach ( (array) $data as $k => $v ) {
 				if ( is_array($v) )
 					$data[$k] = $this->_escape( $v );
@@ -496,17 +818,18 @@
 	}
 
 	/**
-	 * Escapes content for insertion into the database using addslashes(), for security
+	 * Escapes content for insertion into the database using addslashes(), for security.
+	 *
+	 * Works on arrays.
 	 *
 	 * @since 0.71
-	 *
-	 * @param string|array $data
-	 * @return string query safe string
+	 * @param string|array $data to escape
+	 * @return string|array escaped as query safe string
 	 */
-	function escape($data) {
-		if ( is_array($data) ) {
+	function escape( $data ) {
+		if ( is_array( $data ) ) {
 			foreach ( (array) $data as $k => $v ) {
-				if ( is_array($v) )
+				if ( is_array( $v ) )
 					$data[$k] = $this->escape( $v );
 				else
 					$data[$k] = $this->_weak_escape( $v );
@@ -521,18 +844,28 @@
 	/**
 	 * Escapes content by reference for insertion into the database, for security
 	 *
+	 * @uses wpdb::_real_escape()
 	 * @since 2.3.0
-	 *
-	 * @param string $s
+	 * @param string $string to escape
+	 * @return void
 	 */
-	function escape_by_ref(&$string) {
+	function escape_by_ref( &$string ) {
 		$string = $this->_real_escape( $string );
 	}
 
 	/**
-	 * Prepares a SQL query for safe execution.  Uses sprintf()-like syntax.
+	 * Prepares a SQL query for safe execution. Uses sprintf()-like syntax.
 	 *
-	 * This function only supports a small subset of the sprintf syntax; it only supports %d (decimal number), %s (string).
+	 * The following directives can be used in the query format string:
+	 *   %d (integer)
+	 *   %f (float)
+	 *   %s (string)
+	 *   %% (literal percentage sign - no argument needed)
+	 *
+	 * All of %d, %f, and %s are to be left unquoted in the query string and they need an argument passed for them.
+	 * Literals (%) as parts of the query must be properly written as %%.
+	 *
+	 * This function only supports a small subset of the sprintf syntax; it only supports %d (integer), %f (float), and %s (string).
 	 * Does not support sign, padding, alignment, width or precision specifiers.
 	 * Does not support argument numbering/swapping.
 	 *
@@ -541,30 +874,36 @@
 	 * Both %d and %s should be left unquoted in the query string.
 	 *
 	 * <code>
-	 * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", "foo", 1337 )
+	 * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", 'foo', 1337 )
+	 * wpdb::prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' );
 	 * </code>
 	 *
 	 * @link http://php.net/sprintf Description of syntax.
 	 * @since 2.3.0
 	 *
 	 * @param string $query Query statement with sprintf()-like placeholders
-	 * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like {@link http://php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}.
-	 * @param mixed $args,... further variables to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}.
-	 * @return null|string Sanitized query string
+	 * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like
+	 * 	{@link http://php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if
+	 * 	being called like {@link http://php.net/sprintf sprintf()}.
+	 * @param mixed $args,... further variables to substitute into the query's placeholders if being called like
+	 * 	{@link http://php.net/sprintf sprintf()}.
+	 * @return null|false|string Sanitized query string, null if there is no query, false if there is an error and string
+	 * 	if there was something to prepare
 	 */
-	function prepare($query = null) { // ( $query, *$args )
+	function prepare( $query = null ) { // ( $query, *$args )
 		if ( is_null( $query ) )
 			return;
+
 		$args = func_get_args();
-		array_shift($args);
+		array_shift( $args );
 		// If args were passed as an array (as in vsprintf), move them up
-		if ( isset($args[0]) && is_array($args[0]) )
+		if ( isset( $args[0] ) && is_array($args[0]) )
 			$args = $args[0];
-		$query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it
-		$query = str_replace('"%s"', '%s', $query); // doublequote unquoting
-		$query = str_replace('%s', "'%s'", $query); // quote the strings
-		array_walk($args, array(&$this, 'escape_by_ref'));
-		return @vsprintf($query, $args);
+		$query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it
+		$query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting
+		$query = preg_replace( '|(?<!%)%s|', "'%s'", $query ); // quote the strings, avoiding escaped strings like %%s
+		array_walk( $args, array( &$this, 'escape_by_ref' ) );
+		return @vsprintf( $query, $args );
 	}
 
 	/**
@@ -576,43 +915,49 @@
 	 * @param string $str The error to display
 	 * @return bool False if the showing of errors is disabled.
 	 */
-	function print_error($str = '') {
+	function print_error( $str = '' ) {
 		global $EZSQL_ERROR;
 
-		if (!$str) $str = mysql_error($this->dbh);
-		$EZSQL_ERROR[] = array ('query' => $this->last_query, 'error_str' => $str);
+		if ( !$str )
+			$str = mysql_error( $this->dbh );
+		$EZSQL_ERROR[] = array( 'query' => $this->last_query, 'error_str' => $str );
 
 		if ( $this->suppress_errors )
 			return false;
 
+		wp_load_translations_early();
+
 		if ( $caller = $this->get_caller() )
-			$error_str = sprintf(/*WP_I18N_DB_QUERY_ERROR_FULL*/'Erreur de la base de données WordPress %1$s pour la requête %2$s faite par %3$s'/*/WP_I18N_DB_QUERY_ERROR_FULL*/, $str, $this->last_query, $caller);
+			$error_str = sprintf( __( 'WordPress database error %1$s for query %2$s made by %3$s' ), $str, $this->last_query, $caller );
 		else
-			$error_str = sprintf(/*WP_I18N_DB_QUERY_ERROR*/'Erreur de la base de données WordPress %1$s pour la requête %2$s'/*/WP_I18N_DB_QUERY_ERROR*/, $str, $this->last_query);
-
-		$log_error = true;
-		if ( ! function_exists('error_log') )
-			$log_error = false;
+			$error_str = sprintf( __( 'WordPress database error %1$s for query %2$s' ), $str, $this->last_query );
 
-		$log_file = @ini_get('error_log');
-		if ( !empty($log_file) && ('syslog' != $log_file) && !@is_writable($log_file) )
-			$log_error = false;
+		if ( function_exists( 'error_log' )
+			&& ( $log_file = @ini_get( 'error_log' ) )
+			&& ( 'syslog' == $log_file || @is_writable( $log_file ) )
+			)
+			@error_log( $error_str );
 
-		if ( $log_error )
-			@error_log($error_str, 0);
-
-		// Is error output turned on or not..
-		if ( !$this->show_errors )
+		// Are we showing errors?
+		if ( ! $this->show_errors )
 			return false;
 
-		$str = htmlspecialchars($str, ENT_QUOTES);
-		$query = htmlspecialchars($this->last_query, ENT_QUOTES);
+		// If there is an error then take note of it
+		if ( is_multisite() ) {
+			$msg = "WordPress database error: [$str]\n{$this->last_query}\n";
+			if ( defined( 'ERRORLOGFILE' ) )
+				error_log( $msg, 3, ERRORLOGFILE );
+			if ( defined( 'DIEONDBERROR' ) )
+				wp_die( $msg );
+		} else {
+			$str   = htmlspecialchars( $str, ENT_QUOTES );
+			$query = htmlspecialchars( $this->last_query, ENT_QUOTES );
 
-		// If there is an error then take note of it
-		print "<div id='error'>
-		<p class='wpdberror'><strong>WordPress database error:</strong> [$str]<br />
-		<code>$query</code></p>
-		</div>";
+			print "<div id='error'>
+			<p class='wpdberror'><strong>WordPress database error:</strong> [$str]<br />
+			<code>$query</code></p>
+			</div>";
+		}
 	}
 
 	/**
@@ -624,6 +969,7 @@
 	 * errors.
 	 *
 	 * @since 0.71
+	 * @see wpdb::hide_errors()
 	 *
 	 * @param bool $show Whether to show or hide errors
 	 * @return bool Old value for showing errors.
@@ -637,9 +983,12 @@
 	/**
 	 * Disables showing of database errors.
 	 *
-	 * @since 0.71
+	 * By default database errors are not shown.
 	 *
-	 * @return bool Whether showing of errors was active or not
+	 * @since 0.71
+	 * @see wpdb::show_errors()
+	 *
+	 * @return bool Whether showing of errors was active
 	 */
 	function hide_errors() {
 		$show = $this->show_errors;
@@ -650,12 +999,17 @@
 	/**
 	 * Whether to suppress database errors.
 	 *
-	 * @param unknown_type $suppress
-	 * @return unknown
+	 * By default database errors are suppressed, with a simple
+	 * call to this function they can be enabled.
+	 *
+	 * @since 2.5.0
+	 * @see wpdb::hide_errors()
+	 * @param bool $suppress Optional. New value. Defaults to true.
+	 * @return bool Old value
 	 */
 	function suppress_errors( $suppress = true ) {
 		$errors = $this->suppress_errors;
-		$this->suppress_errors = $suppress;
+		$this->suppress_errors = (bool) $suppress;
 		return $errors;
 	}
 
@@ -663,11 +1017,50 @@
 	 * Kill cached query results.
 	 *
 	 * @since 0.71
+	 * @return void
 	 */
 	function flush() {
 		$this->last_result = array();
-		$this->col_info = null;
-		$this->last_query = null;
+		$this->col_info    = null;
+		$this->last_query  = null;
+	}
+
+	/**
+	 * Connect to and select database
+	 *
+	 * @since 3.0.0
+	 */
+	function db_connect() {
+
+		$this->is_mysql = true;
+
+		if ( WP_DEBUG ) {
+			$this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, true );
+		} else {
+			$this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, true );
+		}
+
+		if ( !$this->dbh ) {
+			wp_load_translations_early();
+			$this->bail( sprintf( __( "
+<h1>Error establishing a database connection</h1>
+<p>This either means that the username and password information in your <code>wp-config.php</code> file is incorrect or we can't contact the database server at <code>%s</code>. This could mean your host's database server is down.</p>
+<ul>
+	<li>Are you sure you have the correct username and password?</li>
+	<li>Are you sure that you have typed the correct hostname?</li>
+	<li>Are you sure that the database server is running?</li>
+</ul>
+<p>If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href='http://wordpress.org/support/'>WordPress Support Forums</a>.</p>
+" ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
+
+			return;
+		}
+
+		$this->set_charset( $this->dbh );
+
+		$this->ready = true;
+
+		$this->select( $this->dbname, $this->dbh );
 	}
 
 	/**
@@ -677,19 +1070,16 @@
 	 *
 	 * @since 0.71
 	 *
-	 * @param string $query
+	 * @param string $query Database query
 	 * @return int|false Number of rows affected/selected or false on error
 	 */
-	function query($query) {
+	function query( $query ) {
 		if ( ! $this->ready )
 			return false;
 
-		// filter the query, if filters are available
-		// NOTE: some queries are made before the plugins have been loaded, and thus cannot be filtered with this method
-		if ( function_exists('apply_filters') )
-			$query = apply_filters('query', $query);
+		// some queries are made before the plugins have been loaded, and thus cannot be filtered with this method
+		$query = apply_filters( 'query', $query );
 
-		// initialise return
 		$return_val = 0;
 		$this->flush();
 
@@ -699,49 +1089,49 @@
 		// Keep track of the last query for debug..
 		$this->last_query = $query;
 
-		// Perform the query via std mysql_query function..
-		if ( defined('SAVEQUERIES') && SAVEQUERIES )
+		if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
 			$this->timer_start();
 
-		$this->result = @mysql_query($query, $this->dbh);
-		++$this->num_queries;
+		$this->result = @mysql_query( $query, $this->dbh );
+		$this->num_queries++;
 
-		if ( defined('SAVEQUERIES') && SAVEQUERIES )
+		if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
 			$this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
 
 		// If there is an error then take note of it..
-		if ( $this->last_error = mysql_error($this->dbh) ) {
+		if ( $this->last_error = mysql_error( $this->dbh ) ) {
 			$this->print_error();
 			return false;
 		}
 
-		if ( preg_match("/^\\s*(insert|delete|update|replace|alter) /i",$query) ) {
-			$this->rows_affected = mysql_affected_rows($this->dbh);
+		if ( preg_match( '/^\s*(create|alter|truncate|drop) /i', $query ) ) {
+			$return_val = $this->result;
+		} elseif ( preg_match( '/^\s*(insert|delete|update|replace) /i', $query ) ) {
+			$this->rows_affected = mysql_affected_rows( $this->dbh );
 			// Take note of the insert_id
-			if ( preg_match("/^\\s*(insert|replace) /i",$query) ) {
+			if ( preg_match( '/^\s*(insert|replace) /i', $query ) ) {
 				$this->insert_id = mysql_insert_id($this->dbh);
 			}
 			// Return number of rows affected
 			$return_val = $this->rows_affected;
 		} else {
 			$i = 0;
-			while ($i < @mysql_num_fields($this->result)) {
-				$this->col_info[$i] = @mysql_fetch_field($this->result);
+			while ( $i < @mysql_num_fields( $this->result ) ) {
+				$this->col_info[$i] = @mysql_fetch_field( $this->result );
 				$i++;
 			}
 			$num_rows = 0;
-			while ( $row = @mysql_fetch_object($this->result) ) {
+			while ( $row = @mysql_fetch_object( $this->result ) ) {
 				$this->last_result[$num_rows] = $row;
 				$num_rows++;
 			}
 
-			@mysql_free_result($this->result);
+			@mysql_free_result( $this->result );
 
 			// Log number of rows the query returned
+			// and return number of rows selected
 			$this->num_rows = $num_rows;
-
-			// Return number of rows selected
-			$return_val = $this->num_rows;
+			$return_val     = $num_rows;
 		}
 
 		return $return_val;
@@ -751,61 +1141,115 @@
 	 * Insert a row into a table.
 	 *
 	 * <code>
+	 * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
 	 * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
 	 * </code>
 	 *
 	 * @since 2.5.0
 	 * @see wpdb::prepare()
+	 * @see wpdb::$field_types
+	 * @see wp_set_wpdb_vars()
 	 *
 	 * @param string $table table name
-	 * @param array $data Data to insert (in column => value pairs).  Both $data columns and $data values should be "raw" (neither should be SQL escaped).
-	 * @param array|string $format (optional) An array of formats to be mapped to each of the value in $data.  If string, that format will be used for all of the values in $data.  A format is one of '%d', '%s' (decimal number, string).  If omitted, all values in $data will be treated as strings.
+	 * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
+	 * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data.
+	 * 	A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
 	 * @return int|false The number of rows inserted, or false on error.
 	 */
-	function insert($table, $data, $format = null) {
+	function insert( $table, $data, $format = null ) {
+		return $this->_insert_replace_helper( $table, $data, $format, 'INSERT' );
+	}
+
+	/**
+	 * Replace a row into a table.
+	 *
+	 * <code>
+	 * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
+	 * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
+	 * </code>
+	 *
+	 * @since 3.0.0
+	 * @see wpdb::prepare()
+	 * @see wpdb::$field_types
+	 * @see wp_set_wpdb_vars()
+	 *
+	 * @param string $table table name
+	 * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
+	 * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data.
+	 * 	A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
+	 * @return int|false The number of rows affected, or false on error.
+	 */
+	function replace( $table, $data, $format = null ) {
+		return $this->_insert_replace_helper( $table, $data, $format, 'REPLACE' );
+	}
+
+	/**
+	 * Helper function for insert and replace.
+	 *
+	 * Runs an insert or replace query based on $type argument.
+	 *
+	 * @access private
+	 * @since 3.0.0
+	 * @see wpdb::prepare()
+	 * @see wpdb::$field_types
+	 * @see wp_set_wpdb_vars()
+	 *
+	 * @param string $table table name
+	 * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
+	 * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data.
+	 * 	A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
+	 * @param string $type Optional. What type of operation is this? INSERT or REPLACE. Defaults to INSERT.
+	 * @return int|false The number of rows affected, or false on error.
+	 */
+	function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) {
+		if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) )
+			return false;
 		$formats = $format = (array) $format;
-		$fields = array_keys($data);
+		$fields = array_keys( $data );
 		$formatted_fields = array();
 		foreach ( $fields as $field ) {
-			if ( !empty($format) )
-				$form = ( $form = array_shift($formats) ) ? $form : $format[0];
-			elseif ( isset($this->field_types[$field]) )
+			if ( !empty( $format ) )
+				$form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
+			elseif ( isset( $this->field_types[$field] ) )
 				$form = $this->field_types[$field];
 			else
 				$form = '%s';
 			$formatted_fields[] = $form;
 		}
-		$sql = "INSERT INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES ('" . implode( "','", $formatted_fields ) . "')";
-		return $this->query( $this->prepare( $sql, $data) );
+		$sql = "{$type} INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES (" . implode( ",", $formatted_fields ) . ")";
+		return $this->query( $this->prepare( $sql, $data ) );
 	}
 
-
 	/**
 	 * Update a row in the table
 	 *
 	 * <code>
+	 * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 'bar' ), array( 'ID' => 1 ) )
 	 * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) )
 	 * </code>
 	 *
 	 * @since 2.5.0
 	 * @see wpdb::prepare()
+	 * @see wpdb::$field_types
+	 * @see wp_set_wpdb_vars()
 	 *
 	 * @param string $table table name
-	 * @param array $data Data to update (in column => value pairs).  Both $data columns and $data values should be "raw" (neither should be SQL escaped).
-	 * @param array $where A named array of WHERE clauses (in column => value pairs).  Multiple clauses will be joined with ANDs.  Both $where columns and $where values should be "raw".
-	 * @param array|string $format (optional) An array of formats to be mapped to each of the values in $data.  If string, that format will be used for all of the values in $data.  A format is one of '%d', '%s' (decimal number, string).  If omitted, all values in $data will be treated as strings.
-	 * @param array|string $format_where (optional) An array of formats to be mapped to each of the values in $where.  If string, that format will be used for all of  the items in $where.  A format is one of '%d', '%s' (decimal number, string).  If omitted, all values in $where will be treated as strings.
+	 * @param array $data Data to update (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
+	 * @param array $where A named array of WHERE clauses (in column => value pairs). Multiple clauses will be joined with ANDs. Both $where columns and $where values should be "raw".
+	 * @param array|string $format Optional. An array of formats to be mapped to each of the values in $data. If string, that format will be used for all of the values in $data.
+	 * 	A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
+	 * @param array|string $where_format Optional. An array of formats to be mapped to each of the values in $where. If string, that format will be used for all of the items in $where. A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $where will be treated as strings.
 	 * @return int|false The number of rows updated, or false on error.
 	 */
-	function update($table, $data, $where, $format = null, $where_format = null) {
-		if ( !is_array( $where ) )
+	function update( $table, $data, $where, $format = null, $where_format = null ) {
+		if ( ! is_array( $data ) || ! is_array( $where ) )
 			return false;
 
 		$formats = $format = (array) $format;
 		$bits = $wheres = array();
-		foreach ( (array) array_keys($data) as $field ) {
-			if ( !empty($format) )
-				$form = ( $form = array_shift($formats) ) ? $form : $format[0];
+		foreach ( (array) array_keys( $data ) as $field ) {
+			if ( !empty( $format ) )
+				$form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
 			elseif ( isset($this->field_types[$field]) )
 				$form = $this->field_types[$field];
 			else
@@ -814,10 +1258,10 @@
 		}
 
 		$where_formats = $where_format = (array) $where_format;
-		foreach ( (array) array_keys($where) as $field ) {
-			if ( !empty($where_format) )
-				$form = ( $form = array_shift($where_formats) ) ? $form : $where_format[0];
-			elseif ( isset($this->field_types[$field]) )
+		foreach ( (array) array_keys( $where ) as $field ) {
+			if ( !empty( $where_format ) )
+				$form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
+			elseif ( isset( $this->field_types[$field] ) )
 				$form = $this->field_types[$field];
 			else
 				$form = '%s';
@@ -825,10 +1269,53 @@
 		}
 
 		$sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
-		return $this->query( $this->prepare( $sql, array_merge(array_values($data), array_values($where))) );
+		return $this->query( $this->prepare( $sql, array_merge( array_values( $data ), array_values( $where ) ) ) );
 	}
 
 	/**
+	 * Delete a row in the table
+	 *
+	 * <code>
+	 * wpdb::delete( 'table', array( 'ID' => 1 ) )
+	 * wpdb::delete( 'table', array( 'ID' => 1 ), array( '%d' ) )
+	 * </code>
+	 *
+	 * @since 3.4.0
+	 * @see wpdb::prepare()
+	 * @see wpdb::$field_types
+	 * @see wp_set_wpdb_vars()
+	 *
+	 * @param string $table table name
+	 * @param array $where A named array of WHERE clauses (in column => value pairs). Multiple clauses will be joined with ANDs. Both $where columns and $where values should be "raw".
+	 * @param array|string $where_format Optional. An array of formats to be mapped to each of the values in $where. If string, that format will be used for all of the items in $where. A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $where will be treated as strings unless otherwise specified in wpdb::$field_types.
+	 * @return int|false The number of rows updated, or false on error.
+	 */
+	function delete( $table, $where, $where_format = null ) {
+		if ( ! is_array( $where ) )
+			return false;
+
+		$bits = $wheres = array();
+
+		$where_formats = $where_format = (array) $where_format;
+
+		foreach ( array_keys( $where ) as $field ) {
+			if ( !empty( $where_format ) ) {
+				$form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
+			} elseif ( isset( $this->field_types[ $field ] ) ) {
+				$form = $this->field_types[ $field ];
+			} else {
+				$form = '%s';
+			}
+
+			$wheres[] = "$field = $form";
+		}
+
+		$sql = "DELETE FROM $table WHERE " . implode( ' AND ', $wheres );
+		return $this->query( $this->prepare( $sql, $where ) );
+	}
+
+
+	/**
 	 * Retrieve one variable from the database.
 	 *
 	 * Executes a SQL query and returns the value from the SQL result.
@@ -837,23 +1324,23 @@
 	 *
 	 * @since 0.71
 	 *
-	 * @param string|null $query SQL query.  If null, use the result from the previous query.
-	 * @param int $x (optional) Column of value to return.  Indexed from 0.
-	 * @param int $y (optional) Row of value to return.  Indexed from 0.
-	 * @return string Database query result
+	 * @param string|null $query Optional. SQL query. Defaults to null, use the result from the previous query.
+	 * @param int $x Optional. Column of value to return. Indexed from 0.
+	 * @param int $y Optional. Row of value to return. Indexed from 0.
+	 * @return string|null Database query result (as string), or null on failure
 	 */
-	function get_var($query=null, $x = 0, $y = 0) {
-		$this->func_call = "\$db->get_var(\"$query\",$x,$y)";
+	function get_var( $query = null, $x = 0, $y = 0 ) {
+		$this->func_call = "\$db->get_var(\"$query\", $x, $y)";
 		if ( $query )
-			$this->query($query);
+			$this->query( $query );
 
 		// Extract var out of cached results based x,y vals
 		if ( !empty( $this->last_result[$y] ) ) {
-			$values = array_values(get_object_vars($this->last_result[$y]));
+			$values = array_values( get_object_vars( $this->last_result[$y] ) );
 		}
 
 		// If there is a value return it else return null
-		return (isset($values[$x]) && $values[$x]!=='') ? $values[$x] : null;
+		return ( isset( $values[$x] ) && $values[$x] !== '' ) ? $values[$x] : null;
 	}
 
 	/**
@@ -864,28 +1351,29 @@
 	 * @since 0.71
 	 *
 	 * @param string|null $query SQL query.
-	 * @param string $output (optional) one of ARRAY_A | ARRAY_N | OBJECT constants.  Return an associative array (column => value, ...), a numerically indexed array (0 => value, ...) or an object ( ->column = value ), respectively.
-	 * @param int $y (optional) Row to return.  Indexed from 0.
-	 * @return mixed Database query result in format specifed by $output
+	 * @param string $output Optional. one of ARRAY_A | ARRAY_N | OBJECT constants. Return an associative array (column => value, ...),
+	 * 	a numerically indexed array (0 => value, ...) or an object ( ->column = value ), respectively.
+	 * @param int $y Optional. Row to return. Indexed from 0.
+	 * @return mixed Database query result in format specified by $output or null on failure
 	 */
-	function get_row($query = null, $output = OBJECT, $y = 0) {
+	function get_row( $query = null, $output = OBJECT, $y = 0 ) {
 		$this->func_call = "\$db->get_row(\"$query\",$output,$y)";
 		if ( $query )
-			$this->query($query);
+			$this->query( $query );
 		else
 			return null;
 
-		if ( !isset($this->last_result[$y]) )
+		if ( !isset( $this->last_result[$y] ) )
 			return null;
 
 		if ( $output == OBJECT ) {
 			return $this->last_result[$y] ? $this->last_result[$y] : null;
 		} elseif ( $output == ARRAY_A ) {
-			return $this->last_result[$y] ? get_object_vars($this->last_result[$y]) : null;
+			return $this->last_result[$y] ? get_object_vars( $this->last_result[$y] ) : null;
 		} elseif ( $output == ARRAY_N ) {
-			return $this->last_result[$y] ? array_values(get_object_vars($this->last_result[$y])) : null;
+			return $this->last_result[$y] ? array_values( get_object_vars( $this->last_result[$y] ) ) : null;
 		} else {
-			$this->print_error(/*WP_I18N_DB_GETROW_ERROR*/' $db->get_row(string query, output type, int offset) -- Le type de sortie doit être: OBJECT, ARRAY_A, ARRAY_N'/*/WP_I18N_DB_GETROW_ERROR*/);
+			$this->print_error( " \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N" );
 		}
 	}
 
@@ -898,18 +1386,18 @@
 	 *
 	 * @since 0.71
 	 *
-	 * @param string|null $query SQL query.  If null, use the result from the previous query.
-	 * @param int $x Column to return.  Indexed from 0.
-	 * @return array Database query result.  Array indexed from 0 by SQL result row number.
+	 * @param string|null $query Optional. SQL query. Defaults to previous query.
+	 * @param int $x Optional. Column to return. Indexed from 0.
+	 * @return array Database query result. Array indexed from 0 by SQL result row number.
 	 */
-	function get_col($query = null , $x = 0) {
+	function get_col( $query = null , $x = 0 ) {
 		if ( $query )
-			$this->query($query);
+			$this->query( $query );
 
 		$new_array = array();
 		// Extract the column values
-		for ( $i=0; $i < count($this->last_result); $i++ ) {
-			$new_array[$i] = $this->get_var(null, $x, $i);
+		for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) {
+			$new_array[$i] = $this->get_var( null, $x, $i );
 		}
 		return $new_array;
 	}
@@ -922,17 +1410,20 @@
 	 * @since 0.71
 	 *
 	 * @param string $query SQL query.
-	 * @param string $output (optional) ane of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants.  With one of the first three, return an array of rows indexed from 0 by SQL result row number.  Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively.  With OBJECT_K, return an associative array of row objects keyed by the value of each row's first column's value.  Duplicate keys are discarded.
+	 * @param string $output Optional. Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants. With one of the first three, return an array of rows indexed from 0 by SQL result row number.
+	 * 	Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively.
+	 * 	With OBJECT_K, return an associative array of row objects keyed by the value of each row's first column's value. Duplicate keys are discarded.
 	 * @return mixed Database query results
 	 */
-	function get_results($query = null, $output = OBJECT) {
+	function get_results( $query = null, $output = OBJECT ) {
 		$this->func_call = "\$db->get_results(\"$query\", $output)";
 
 		if ( $query )
-			$this->query($query);
+			$this->query( $query );
 		else
 			return null;
 
+		$new_array = array();
 		if ( $output == OBJECT ) {
 			// Return an integer-keyed array of row objects
 			return $this->last_result;
@@ -940,28 +1431,28 @@
 			// Return an array of row objects with keys from column 1
 			// (Duplicates are discarded)
 			foreach ( $this->last_result as $row ) {
-				$key = array_shift( get_object_vars( $row ) );
-				if ( !isset( $new_array[ $key ] ) )
+				$var_by_ref = get_object_vars( $row );
+				$key = array_shift( $var_by_ref );
+				if ( ! isset( $new_array[ $key ] ) )
 					$new_array[ $key ] = $row;
 			}
 			return $new_array;
 		} elseif ( $output == ARRAY_A || $output == ARRAY_N ) {
 			// Return an integer-keyed array of...
 			if ( $this->last_result ) {
-				$i = 0;
 				foreach( (array) $this->last_result as $row ) {
 					if ( $output == ARRAY_N ) {
 						// ...integer-keyed row arrays
-						$new_array[$i] = array_values( get_object_vars( $row ) );
+						$new_array[] = array_values( get_object_vars( $row ) );
 					} else {
 						// ...column name-keyed row arrays
-						$new_array[$i] = get_object_vars( $row );
+						$new_array[] = get_object_vars( $row );
 					}
-					++$i;
 				}
-				return $new_array;
 			}
+			return $new_array;
 		}
+		return null;
 	}
 
 	/**
@@ -969,14 +1460,15 @@
 	 *
 	 * @since 0.71
 	 *
-	 * @param string $info_type one of name, table, def, max_length, not_null, primary_key, multiple_key, unique_key, numeric, blob, type, unsigned, zerofill
-	 * @param int $col_offset 0: col name. 1: which table the col's in. 2: col's max length. 3: if the col is numeric. 4: col's type
+	 * @param string $info_type Optional. Type one of name, table, def, max_length, not_null, primary_key, multiple_key, unique_key, numeric, blob, type, unsigned, zerofill
+	 * @param int $col_offset Optional. 0: col name. 1: which table the col's in. 2: col's max length. 3: if the col is numeric. 4: col's type
 	 * @return mixed Column Results
 	 */
-	function get_col_info($info_type = 'name', $col_offset = -1) {
+	function get_col_info( $info_type = 'name', $col_offset = -1 ) {
 		if ( $this->col_info ) {
 			if ( $col_offset == -1 ) {
 				$i = 0;
+				$new_array = array();
 				foreach( (array) $this->col_info as $col ) {
 					$new_array[$i] = $col->{$info_type};
 					$i++;
@@ -996,9 +1488,7 @@
 	 * @return true
 	 */
 	function timer_start() {
-		$mtime = microtime();
-		$mtime = explode(' ', $mtime);
-		$this->time_start = $mtime[1] + $mtime[0];
+		$this->time_start = microtime( true );
 		return true;
 	}
 
@@ -1007,14 +1497,10 @@
 	 *
 	 * @since 1.5.0
 	 *
-	 * @return int Total time spent on the query, in milliseconds
+	 * @return float Total time spent on the query, in seconds
 	 */
 	function timer_stop() {
-		$mtime = microtime();
-		$mtime = explode(' ', $mtime);
-		$time_end = $mtime[1] + $mtime[0];
-		$time_total = $time_end - $this->time_start;
-		return $time_total;
+		return ( microtime( true ) - $this->time_start );
 	}
 
 	/**
@@ -1025,12 +1511,12 @@
 	 * @since 1.5.0
 	 *
 	 * @param string $message The Error message
-	 * @param string $error_code (optional) A Computer readable string to identify the error.
+	 * @param string $error_code Optional. A Computer readable string to identify the error.
 	 * @return false|void
 	 */
-	function bail($message, $error_code = '500') {
+	function bail( $message, $error_code = '500' ) {
 		if ( !$this->show_errors ) {
-			if ( class_exists('WP_Error') )
+			if ( class_exists( 'WP_Error' ) )
 				$this->error = new WP_Error($error_code, $message);
 			else
 				$this->error = $message;
@@ -1040,23 +1526,23 @@
 	}
 
 	/**
-	 * Whether or not MySQL database is at least the required minimum version.
+	 * Whether MySQL database is at least the required minimum version.
 	 *
 	 * @since 2.5.0
 	 * @uses $wp_version
+	 * @uses $required_mysql_version
 	 *
 	 * @return WP_Error
 	 */
-	function check_database_version()
-	{
-		global $wp_version;
-		// Make sure the server has MySQL 4.1.2
-		if ( version_compare($this->db_version(), '4.1.2', '<') )
-			return new WP_Error('database_version',sprintf(__('<strong>ERROR</strong>: WordPress %s requires MySQL 4.1.2 or higher'), $wp_version));
+	function check_database_version() {
+		global $wp_version, $required_mysql_version;
+		// Make sure the server has the required MySQL version
+		if ( version_compare($this->db_version(), $required_mysql_version, '<') )
+			return new WP_Error('database_version', sprintf( __( '<strong>ERROR</strong>: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version ));
 	}
 
 	/**
-	 * Whether of not the database supports collation.
+	 * Whether the database supports collation.
 	 *
 	 * Called when WordPress is generating the table scheme.
 	 *
@@ -1069,21 +1555,25 @@
 	}
 
 	/**
-	 * Generic function to determine if a database supports a particular feature
+	 * Determine if a database supports a particular feature
+	 *
+	 * @since 2.7.0
+	 * @see   wpdb::db_version()
+	 *
 	 * @param string $db_cap the feature
-	 * @param false|string|resource $dbh_or_table (not implemented) Which database to test.  False = the currently selected database, string = the database containing the specified table, resource = the database corresponding to the specified mysql resource.
 	 * @return bool
 	 */
 	function has_cap( $db_cap ) {
 		$version = $this->db_version();
 
-		switch ( strtolower( $db_cap ) ) :
-		case 'collation' :    // @since 2.5.0
-		case 'group_concat' : // @since 2.7
-		case 'subqueries' :   // @since 2.7
-			return version_compare($version, '4.1', '>=');
-			break;
-		endswitch;
+		switch ( strtolower( $db_cap ) ) {
+			case 'collation' :    // @since 2.5.0
+			case 'group_concat' : // @since 2.7
+			case 'subqueries' :   // @since 2.7
+				return version_compare( $version, '4.1', '>=' );
+			case 'set_charset' :
+				return version_compare($version, '5.0.7', '>=');
+		};
 
 		return false;
 	}
@@ -1091,7 +1581,7 @@
 	/**
 	 * Retrieve the name of the function that called wpdb.
 	 *
-	 * Requires PHP 4.3 and searches up the list of functions until it reaches
+	 * Searches up the list of functions until it reaches
 	 * the one that would most logically had called this method.
 	 *
 	 * @since 2.5.0
@@ -1099,43 +1589,17 @@
 	 * @return string The name of the calling function
 	 */
 	function get_caller() {
-		// requires PHP 4.3+
-		if ( !is_callable('debug_backtrace') )
-			return '';
-
-		$bt = debug_backtrace();
-		$caller = array();
-
-		$bt = array_reverse( $bt );
-		foreach ( (array) $bt as $call ) {
-			if ( @$call['class'] == __CLASS__ )
-				continue;
-			$function = $call['function'];
-			if ( isset( $call['class'] ) )
-				$function = $call['class'] . "->$function";
-			$caller[] = $function;
-		}
-		$caller = join( ', ', $caller );
-
-		return $caller;
+		return wp_debug_backtrace_summary( __CLASS__ );
 	}
 
 	/**
-	 * The database version number
-	 * @param false|string|resource $dbh_or_table (not implemented) Which database to test.  False = the currently selected database, string = the database containing the specified table, resource = the database corresponding to the specified mysql resource.
+	 * The database version number.
+	 *
+	 * @since 2.7.0
+	 *
 	 * @return false|string false on failure, version number on success
 	 */
 	function db_version() {
-		return preg_replace('/[^0-9.].*/', '', mysql_get_server_info( $this->dbh ));
+		return preg_replace( '/[^0-9.].*/', '', mysql_get_server_info( $this->dbh ) );
 	}
 }
-
-if ( ! isset($wpdb) ) {
-	/**
-	 * WordPress Database Object, if it isn't set already in wp-content/db.php
-	 * @global object $wpdb Creates a new wpdb object based on wp-config.php Constants for the database
-	 * @since 0.71
-	 */
-	$wpdb = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
-}
-?>