Fix mysqli support
[lhc/web/wiklou.git] / includes / db / Database.php
index 623010f..1f7a830 100644 (file)
@@ -360,6 +360,8 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
         * code should use lastErrno() and lastError() to handle the
         * situation as appropriate.
         *
+        * Do not use this function outside of the Database classes.
+        *
         * @param $ignoreErrors bool|null
         *
         * @return bool The previous value of the flag.
@@ -582,7 +584,6 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
         * @param $flag Integer: DBO_* constants from Defines.php:
         *   - DBO_DEBUG: output some debug info (same as debug())
         *   - DBO_NOBUFFER: don't buffer results (inverse of bufferResults())
-        *   - DBO_IGNORE: ignore errors (same as ignoreErrors())
         *   - DBO_TRX: automatically start transactions
         *   - DBO_DEFAULT: automatically sets DBO_TRX if not in command line mode
         *       and removes it in command line mode
@@ -716,7 +717,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
        /**
         * Given a DB type, construct the name of the appropriate child class of
         * DatabaseBase. This is designed to replace all of the manual stuff like:
-        *      $class = 'Database' . ucfirst( strtolower( $type ) );
+        *      $class = 'Database' . ucfirst( strtolower( $dbType ) );
         * as well as validate against the canonical list of DB types we have
         *
         * This factory function is mostly useful for when you need to connect to a
@@ -731,17 +732,47 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
         *
         * @param string $dbType A possible DB type
         * @param array $p An array of options to pass to the constructor.
-        *    Valid options are: host, user, password, dbname, flags, tablePrefix
+        *    Valid options are: host, user, password, dbname, flags, tablePrefix, driver
         * @return DatabaseBase subclass or null
         */
        final public static function factory( $dbType, $p = array() ) {
                $canonicalDBTypes = array(
-                       'mysql', 'postgres', 'sqlite', 'oracle', 'mssql'
+                       'mysql'    => array( 'mysqli', 'mysql' ),
+                       'postgres' => array(),
+                       'sqlite'   => array(),
+                       'oracle'   => array(),
+                       'mssql'    => array(),
                );
+
+               $driver = false;
                $dbType = strtolower( $dbType );
-               $class = 'Database' . ucfirst( $dbType );
+               if ( isset( $canonicalDBTypes[$dbType] ) && $canonicalDBTypes[$dbType] ) {
+                       $possibleDrivers = $canonicalDBTypes[$dbType];
+                       if ( !empty( $p['driver'] ) ) {
+                               if ( in_array( $p['driver'], $possibleDrivers ) ) {
+                                       $driver = $p['driver'];
+                               } else {
+                                       throw new MWException( __METHOD__ .
+                                               " cannot construct Database with type '$dbType' and driver '{$p['driver']}'" );
+                               }
+                       } else {
+                               foreach ( $possibleDrivers as $posDriver ) {
+                                       if ( extension_loaded( $posDriver ) ) {
+                                               $driver = $posDriver;
+                                               break;
+                                       }
+                               }
+                       }
+               } else {
+                       $driver = $dbType;
+               }
+               if ( $driver === false ) {
+                       throw new MWException( __METHOD__ .
+                               " no viable database extension found for type '$dbType'" );
+               }
 
-               if ( in_array( $dbType, $canonicalDBTypes ) || ( class_exists( $class ) && is_subclass_of( $class, 'DatabaseBase' ) ) ) {
+               $class = 'Database' . ucfirst( $driver );
+               if ( class_exists( $class ) && is_subclass_of( $class, 'DatabaseBase' ) ) {
                        return new $class(
                                isset( $p['host'] ) ? $p['host'] : false,
                                isset( $p['user'] ) ? $p['user'] : false,
@@ -882,22 +913,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
         *     for a successful read query, or false on failure if $tempIgnore set
         */
        public function query( $sql, $fname = __METHOD__, $tempIgnore = false ) {
-               $isMaster = !is_null( $this->getLBInfo( 'master' ) );
-               if ( !Profiler::instance()->isStub() ) {
-                       # generalizeSQL will probably cut down the query to reasonable
-                       # logging size most of the time. The substr is really just a sanity check.
-
-                       if ( $isMaster ) {
-                               $queryProf = 'query-m: ' . substr( DatabaseBase::generalizeSQL( $sql ), 0, 255 );
-                               $totalProf = 'DatabaseBase::query-master';
-                       } else {
-                               $queryProf = 'query: ' . substr( DatabaseBase::generalizeSQL( $sql ), 0, 255 );
-                               $totalProf = 'DatabaseBase::query';
-                       }
-
-                       wfProfileIn( $totalProf );
-                       wfProfileIn( $queryProf );
-               }
+               global $wgUser, $wgDebugDBTransactions;
 
                $this->mLastQuery = $sql;
                if ( !$this->mDoneWrites && $this->isWriteQuery( $sql ) ) {
@@ -907,7 +923,6 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                }
 
                # Add a comment for easy SHOW PROCESSLIST interpretation
-               global $wgUser;
                if ( is_object( $wgUser ) && $wgUser->isItemLoaded( 'name' ) ) {
                        $userName = $wgUser->getName();
                        if ( mb_strlen( $userName ) > 15 ) {
@@ -931,7 +946,6 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                        # is really used by application
                        $sqlstart = substr( $sql, 0, 10 ); // very much worth it, benchmark certified(tm)
                        if ( strpos( $sqlstart, "SHOW " ) !== 0 && strpos( $sqlstart, "SET " ) !== 0 ) {
-                               global $wgDebugDBTransactions;
                                if ( $wgDebugDBTransactions ) {
                                        wfDebug( "Implicit transaction start.\n" );
                                }
@@ -946,6 +960,21 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                        Profiler::instance()->transactionWritingIn( $this->mServer, $this->mDBname );
                }
 
+               $isMaster = !is_null( $this->getLBInfo( 'master' ) );
+               if ( !Profiler::instance()->isStub() ) {
+                       # generalizeSQL will probably cut down the query to reasonable
+                       # logging size most of the time. The substr is really just a sanity check.
+                       if ( $isMaster ) {
+                               $queryProf = 'query-m: ' . substr( DatabaseBase::generalizeSQL( $sql ), 0, 255 );
+                               $totalProf = 'DatabaseBase::query-master';
+                       } else {
+                               $queryProf = 'query: ' . substr( DatabaseBase::generalizeSQL( $sql ), 0, 255 );
+                               $totalProf = 'DatabaseBase::query';
+                       }
+                       wfProfileIn( $totalProf );
+                       wfProfileIn( $queryProf );
+               }
+
                if ( $this->debug() ) {
                        static $cnt = 0;
 
@@ -1607,7 +1636,8 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                $sql = preg_replace( '/\s+/', ' ', $sql );
 
                # All numbers => N
-               $sql = preg_replace( '/-?[0-9]+/s', 'N', $sql );
+               $sql = preg_replace( '/-?\d+(,-?\d+)+/s', 'N,...,N', $sql );
+               $sql = preg_replace( '/-?\d+/s', 'N', $sql );
 
                return $sql;
        }
@@ -2301,8 +2331,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
        }
 
        /**
-        * If it's a string, adds quotes and backslashes
-        * Otherwise returns as-is
+        * Adds quotes and backslashes.
         *
         * @param $s string
         *