This supercedes I6d03bf2a, using better names for the new classes and
incorporating the changes requested by Aaron.
This change introduces the base class SecondaryDataUpdate to be used for any
updates that need to be applied when a page is changed or deleted. Until now,
this was done by the LinksUpdate class for updates and WikiPage::doDeletionUpdates
upon deletion. This patch uses a list of SecondaryDataUpdates in both cases.
This allows extensions (e.g. via the ContentHandler facility, once that is in) to
easily specify what needs to be done when a page is updated or deleted in order to
keep any secondary data stores (such as link tables) in sync.
Note that limited transactional logic is also introduced, so SecondaryDataUpdate
can be implemented to only commit their changes if all updates were performed
sucessfully.
Patch Set 2: fixing some coding style issues mentioned by Nikerabbit.
Patch Set 4: some stuff I kept from the old LinksUpdate class needs cleanup,
but might break extensions when changed. Marking as todo for now.
Patch Set 5: fixed misnamed member in LinksDeletionUpdate (thanks Aaron).
Change-Id: Ibe3e88fadd8c1d4063cf13bb6972f2a23569a73f
115 lines
3.1 KiB
PHP
115 lines
3.1 KiB
PHP
<?php
|
|
/**
|
|
* See docs/deferred.txt
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*
|
|
* Abstract base class for update jobs that do something with some secondary
|
|
* data extracted from article.
|
|
*/
|
|
abstract class DataUpdate implements DeferrableUpdate {
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
public function __construct( ) {
|
|
# noop
|
|
}
|
|
|
|
/**
|
|
* Begin an appropriate transaction, if any.
|
|
* This default implementation does nothing.
|
|
*/
|
|
public function beginTransaction() {
|
|
//noop
|
|
}
|
|
|
|
/**
|
|
* Commit the transaction started via beginTransaction, if any.
|
|
* This default implementation does nothing.
|
|
*/
|
|
public function commitTransaction() {
|
|
//noop
|
|
}
|
|
|
|
/**
|
|
* Abort / roll back the transaction started via beginTransaction, if any.
|
|
* This default implementation does nothing.
|
|
*/
|
|
public function rollbackTransaction() {
|
|
//noop
|
|
}
|
|
|
|
/**
|
|
* Convenience method, calls doUpdate() on every DataUpdate in the array.
|
|
*
|
|
* This methods supports transactions logic by first calling beginTransaction()
|
|
* on all updates in the array, then calling doUpdate() on each, and, if all goes well,
|
|
* then calling commitTransaction() on each update. If an error occurrs,
|
|
* rollbackTransaction() will be called on any update object that had beginTranscation()
|
|
* called but not yet commitTransaction().
|
|
*
|
|
* This allows for limited transactional logic across multiple backends for storing
|
|
* secondary data.
|
|
*
|
|
* @static
|
|
* @param $updates array a list of DataUpdate instances
|
|
*/
|
|
public static function runUpdates( $updates ) {
|
|
if ( empty( $updates ) ) return; # nothing to do
|
|
|
|
$open_transactions = array();
|
|
$exception = null;
|
|
|
|
/**
|
|
* @var $update StorageUpdate
|
|
* @var $trans StorageUpdate
|
|
*/
|
|
|
|
try {
|
|
// begin transactions
|
|
foreach ( $updates as $update ) {
|
|
$update->beginTransaction();
|
|
$open_transactions[] = $update;
|
|
}
|
|
|
|
// do work
|
|
foreach ( $updates as $update ) {
|
|
$update->doUpdate();
|
|
}
|
|
|
|
// commit transactions
|
|
while ( count( $open_transactions ) > 0 ) {
|
|
$trans = array_pop( $open_transactions );
|
|
$trans->commitTransaction();
|
|
}
|
|
} catch ( Exception $ex ) {
|
|
$exception = $ex;
|
|
wfDebug( "Caught exception, will rethrow after rollback: " . $ex->getMessage() );
|
|
}
|
|
|
|
// rollback remaining transactions
|
|
while ( count( $open_transactions ) > 0 ) {
|
|
$trans = array_pop( $open_transactions );
|
|
$trans->rollbackTransaction();
|
|
}
|
|
|
|
if ( $exception ) {
|
|
throw $exception; // rethrow after cleanup
|
|
}
|
|
}
|
|
|
|
}
|