Add @deprecated tags to DatabaseBase
[lhc/web/wiklou.git] / includes / libs / rdbms / database / Database.php
index 189eaf2..d1230e0 100644 (file)
@@ -677,6 +677,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                );
        }
 
+       public function preCommitCallbacksPending() {
+               return $this->trxLevel && $this->trxPreCommitCallbacks;
+       }
+
        /**
         * @return string|null
         */
@@ -722,17 +726,15 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        /**
-        * Get the list of method names that have pending write queries or callbacks
-        * for this transaction
+        * List the methods that have write queries or callbacks for the current transaction
         *
-        * @return array
+        * This method should not be used outside of Database/LoadBalancer
+        *
+        * @return string[]
+        * @since 1.32
         */
-       protected function pendingWriteAndCallbackCallers() {
-               if ( !$this->trxLevel ) {
-                       return [];
-               }
-
-               $fnames = $this->trxWriteCallers;
+       public function pendingWriteAndCallbackCallers() {
+               $fnames = $this->pendingWriteCallers();
                foreach ( [
                        $this->trxIdleCallbacks,
                        $this->trxPreCommitCallbacks,
@@ -960,12 +962,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                // Sanity check that no callbacks are dangling
-               if (
-                       $this->trxIdleCallbacks || $this->trxPreCommitCallbacks || $this->trxEndCallbacks
-               ) {
+               $fnames = $this->pendingWriteAndCallbackCallers();
+               if ( $fnames ) {
                        throw new RuntimeException(
-                               "Transaction callbacks are still pending:\n" .
-                               implode( ', ', $this->pendingWriteAndCallbackCallers() )
+                               "Transaction callbacks are still pending:\n" . implode( ', ', $fnames )
                        );
                }
 
@@ -991,17 +991,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        abstract protected function closeConnection();
 
        /**
-        * @param string $error Fallback error message, used if none is given by DB
+        * @deprecated since 1.32
+        * @param string $error Fallback message, if none is given by DB
         * @throws DBConnectionError
         */
        public function reportConnectionError( $error = 'Unknown error' ) {
-               $myError = $this->lastError();
-               if ( $myError ) {
-                       $error = $myError;
-               }
-
-               # New method
-               throw new DBConnectionError( $this, $error );
+               call_user_func( $this->deprecationLogger, 'Use of ' . __METHOD__ . ' is deprecated.' );
+               throw new DBConnectionError( $this, $this->lastError() ?: $error );
        }
 
        /**
@@ -3296,7 +3292,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->trxEndCallbacks[] = [ $callback, $fname, $this->currentAtomicSectionId() ];
        }
 
-       final public function onTransactionIdle( callable $callback, $fname = __METHOD__ ) {
+       final public function onTransactionCommitOrIdle( callable $callback, $fname = __METHOD__ ) {
                if ( !$this->trxLevel && $this->getTransactionRoundId() ) {
                        // Start an implicit transaction similar to how query() does
                        $this->begin( __METHOD__, self::TRANSACTION_INTERNAL );
@@ -3309,6 +3305,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
        }
 
+       final public function onTransactionIdle( callable $callback, $fname = __METHOD__ ) {
+               $this->onTransactionCommitOrIdle( $callback, $fname );
+       }
+
        final public function onTransactionPreCommitOrIdle( callable $callback, $fname = __METHOD__ ) {
                if ( !$this->trxLevel && $this->getTransactionRoundId() ) {
                        // Start an implicit transaction similar to how query() does
@@ -3418,19 +3418,25 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        /**
-        * Actually run and consume any "on transaction idle/resolution" callbacks.
+        * Actually consume and run any "on transaction idle/resolution" callbacks.
         *
         * This method should not be used outside of Database/LoadBalancer
         *
         * @param int $trigger IDatabase::TRIGGER_* constant
+        * @return int Number of callbacks attempted
         * @since 1.20
         * @throws Exception
         */
        public function runOnTransactionIdleCallbacks( $trigger ) {
+               if ( $this->trxLevel ) { // sanity
+                       throw new DBUnexpectedError( $this, __METHOD__ . ': a transaction is still open.' );
+               }
+
                if ( $this->trxEndCallbacksSuppressed ) {
-                       return;
+                       return 0;
                }
 
+               $count = 0;
                $autoTrx = $this->getFlag( self::DBO_TRX ); // automatic begin() enabled?
                /** @var Exception $e */
                $e = null; // first exception
@@ -3443,6 +3449,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $this->trxEndCallbacks = []; // consumed (recursion guard)
                        foreach ( $callbacks as $callback ) {
                                try {
+                                       ++$count;
                                        list( $phpCallback ) = $callback;
                                        $this->clearFlag( self::DBO_TRX ); // make each query its own transaction
                                        call_user_func( $phpCallback, $trigger, $this );
@@ -3466,23 +3473,29 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                if ( $e instanceof Exception ) {
                        throw $e; // re-throw any first exception
                }
+
+               return $count;
        }
 
        /**
-        * Actually run and consume any "on transaction pre-commit" callbacks.
+        * Actually consume and run any "on transaction pre-commit" callbacks.
         *
         * This method should not be used outside of Database/LoadBalancer
         *
         * @since 1.22
+        * @return int Number of callbacks attempted
         * @throws Exception
         */
        public function runOnTransactionPreCommitCallbacks() {
+               $count = 0;
+
                $e = null; // first exception
                do { // callbacks may add callbacks :)
                        $callbacks = $this->trxPreCommitCallbacks;
                        $this->trxPreCommitCallbacks = []; // consumed (and recursion guard)
                        foreach ( $callbacks as $callback ) {
                                try {
+                                       ++$count;
                                        list( $phpCallback ) = $callback;
                                        call_user_func( $phpCallback, $this );
                                } catch ( Exception $ex ) {
@@ -3495,6 +3508,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                if ( $e instanceof Exception ) {
                        throw $e; // re-throw any first exception
                }
+
+               return $count;
        }
 
        /**
@@ -3595,7 +3610,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $savepointId = $cancelable === self::ATOMIC_CANCELABLE ? self::$NOT_APPLICABLE : null;
 
                if ( !$this->trxLevel ) {
-                       $this->begin( $fname, self::TRANSACTION_INTERNAL );
+                       $this->begin( $fname, self::TRANSACTION_INTERNAL ); // sets trxAutomatic
                        // If DBO_TRX is set, a series of startAtomic/endAtomic pairs will result
                        // in all changes being in one transaction to keep requests transactional.
                        if ( $this->getFlag( self::DBO_TRX ) ) {
@@ -3849,8 +3864,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        );
                }
 
-               $this->runOnTransactionIdleCallbacks( self::TRIGGER_COMMIT );
-               $this->runTransactionListenerCallbacks( self::TRIGGER_COMMIT );
+               // With FLUSHING_ALL_PEERS, callbacks will be explicitly run later
+               if ( $flush !== self::FLUSHING_ALL_PEERS ) {
+                       $this->runOnTransactionIdleCallbacks( self::TRIGGER_COMMIT );
+                       $this->runTransactionListenerCallbacks( self::TRIGGER_COMMIT );
+               }
        }
 
        /**
@@ -3899,7 +3917,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->trxIdleCallbacks = [];
                $this->trxPreCommitCallbacks = [];
 
-               if ( $trxActive ) {
+               // With FLUSHING_ALL_PEERS, callbacks will be explicitly run later
+               if ( $trxActive && $flush !== self::FLUSHING_ALL_PEERS ) {
                        try {
                                $this->runOnTransactionIdleCallbacks( self::TRIGGER_ROLLBACK );
                        } catch ( Exception $e ) {
@@ -4619,5 +4638,12 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 }
 
-class_alias( Database::class, 'DatabaseBase' ); // b/c for old name
-class_alias( Database::class, 'Database' ); // b/c global alias
+/**
+ * @deprecated since 1.28
+ */
+class_alias( Database::class, 'DatabaseBase' );
+
+/**
+ * @deprecated since 1.29
+ */
+class_alias( Database::class, 'Database' );