Revert "Remove unsupported and mostly non-functional Mssql support"
[lhc/web/wiklou.git] / includes / db / Database.php
index 30e92e5..c677d74 100644 (file)
@@ -243,7 +243,6 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
        protected $mTablePrefix;
        protected $mFlags;
        protected $mForeign;
-       protected $mTrxLevel = 0;
        protected $mErrorCount = 0;
        protected $mLBInfo = array();
        protected $mFakeSlaveLag = null, $mFakeMaster = false;
@@ -256,6 +255,14 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
 
        protected $delimiter = ';';
 
+       /**
+        * Either 1 if a transaction is active or 0 otherwise.
+        * The other Trx fields may not be meaningfull if this is 0.
+        *
+        * @var int
+        */
+       protected $mTrxLevel = 0;
+
        /**
         * Remembers the function name given for starting the most recent transaction via begin().
         * Used to provide additional context for error reporting.
@@ -391,16 +398,15 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
        }
 
        /**
-        * Gets or sets the current transaction level.
+        * Gets the current transaction level.
         *
         * Historically, transactions were allowed to be "nested". This is no
         * longer supported, so this function really only returns a boolean.
         *
-        * @param int $level An integer (0 or 1), or omitted to leave it unchanged.
         * @return int The previous value
         */
-       public function trxLevel( $level = null ) {
-               return wfSetVar( $this->mTrxLevel, $level );
+       public function trxLevel() {
+               return $this->mTrxLevel;
        }
 
        /**
@@ -706,7 +712,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                        $tablePrefix = $params['tablePrefix'];
                        $foreign = $params['foreign'];
                } else { // legacy calling pattern
-                       wfDeprecated( __METHOD__ . " method called without parameter array.", "1.22" );
+                       wfDeprecated( __METHOD__ . " method called without parameter array.", "1.23" );
                        $args = func_get_args();
                        $server = isset( $args[0] ) ? $args[0] : false;
                        $user = isset( $args[1] ) ? $args[1] : false;
@@ -1038,9 +1044,9 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                # Try reconnecting if the connection was lost
                if ( false === $ret && $this->wasErrorReissuable() ) {
                        # Transaction is gone, like it or not
+                       $hadTrx = $this->mTrxLevel; // possible lost transaction
+                       wfDebug( "Connection lost, reconnecting...\n" );
                        $this->mTrxLevel = 0;
-                       $this->mTrxIdleCallbacks = array(); // cancel
-                       $this->mTrxPreCommitCallbacks = array(); // cancel
                        wfDebug( "Connection lost, reconnecting...\n" );
 
                        if ( $this->ping() ) {
@@ -1053,7 +1059,10 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                                        # Not a database error to lose a transaction after a minute or two
                                        wfLogDBError( "Connection lost and reconnected after {$elapsed}s, query: $sqlx\n" );
                                }
-                               $ret = $this->doQuery( $commentedSql );
+                               if ( !$hadTrx ) {
+                                       # Should be safe to silently retry
+                                       $ret = $this->doQuery( $commentedSql );
+                               }
                        } else {
                                wfDebug( "Failed\n" );
                        }
@@ -3238,6 +3247,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
         *
         * @since 1.23
         * @param string $fname
+        * @throws DBError
         */
        final public function startAtomic( $fname = __METHOD__ ) {
                if ( !$this->mTrxLevel ) {
@@ -3249,6 +3259,32 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                $this->mTrxAtomicLevels->push( $fname );
        }
 
+       /**
+        * Ends an atomic section of SQL statements
+        *
+        * Ends the next section of atomic SQL statements and commits the transaction
+        * if necessary.
+        *
+        * @since 1.23
+        * @see DatabaseBase::startAtomic
+        * @param string $fname
+        * @throws DBError
+        */
+       final public function endAtomic( $fname = __METHOD__ ) {
+               if ( !$this->mTrxLevel ) {
+                       throw new DBUnexpectedError( $this, 'No atomic transaction is open.' );
+               }
+               if ( $this->mTrxAtomicLevels->isEmpty() ||
+                       $this->mTrxAtomicLevels->pop() !== $fname
+               ) {
+                       throw new DBUnexpectedError( $this, 'Invalid atomic section ended.' );
+               }
+
+               if ( $this->mTrxAtomicLevels->isEmpty() && $this->mTrxAutomaticAtomic ) {
+                       $this->commit( $fname, 'flush' );
+               }
+       }
+
        /**
         * Begin a transaction. If a transaction is already in progress, that transaction will be committed before the
         * new transaction is started.
@@ -3260,6 +3296,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
         * transaction was started automatically because of the DBO_TRX flag.
         *
         * @param $fname string
+        * @throws DBError
         */
        final public function begin( $fname = __METHOD__ ) {
                global $wgDebugDBTransactions;
@@ -3302,6 +3339,8 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                $this->mTrxAutomatic = false;
                $this->mTrxAutomaticAtomic = false;
                $this->mTrxAtomicLevels = new SplStack;
+               $this->mTrxIdleCallbacks = array();
+               $this->mTrxPreCommitCallbacks = array();
        }
 
        /**
@@ -3315,28 +3354,6 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                $this->mTrxLevel = 1;
        }
 
-       /**
-        * Ends an atomic section of SQL statements
-        *
-        * Ends the next section of atomic SQL statements and commits the transaction
-        * if necessary.
-        *
-        * @since 1.23
-        * @see DatabaseBase::startAtomic
-        * @param string $fname
-        */
-       final public function endAtomic( $fname = __METHOD__ ) {
-               if ( $this->mTrxAtomicLevels->isEmpty() ||
-                       $this->mTrxAtomicLevels->pop() !== $fname
-               ) {
-                       throw new DBUnexpectedError( $this, 'Invalid atomic section ended.' );
-               }
-
-               if ( $this->mTrxAtomicLevels->isEmpty() && $this->mTrxAutomaticAtomic ) {
-                       $this->commit( $fname, 'flush' );
-               }
-       }
-
        /**
         * Commits a transaction previously started using begin().
         * If no transaction is in progress, a warning is issued.
@@ -3374,7 +3391,6 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                if ( $this->mTrxDoneWrites ) {
                        Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname );
                }
-               $this->mTrxDoneWrites = false;
                $this->runOnTransactionIdleCallbacks();
        }
 
@@ -3410,7 +3426,6 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                if ( $this->mTrxDoneWrites ) {
                        Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname );
                }
-               $this->mTrxDoneWrites = false;
        }
 
        /**