[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/deferred/ -> SqlDataUpdate.php (source)

   1  <?php
   2  /**
   3   * Base code for update jobs that put some secondary data extracted
   4   * from article content into the database.
   5   *
   6   * This program is free software; you can redistribute it and/or modify
   7   * it under the terms of the GNU General Public License as published by
   8   * the Free Software Foundation; either version 2 of the License, or
   9   * (at your option) any later version.
  10   *
  11   * This program is distributed in the hope that it will be useful,
  12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14   * GNU General Public License for more details.
  15   *
  16   * You should have received a copy of the GNU General Public License along
  17   * with this program; if not, write to the Free Software Foundation, Inc.,
  18   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19   * http://www.gnu.org/copyleft/gpl.html
  20   *
  21   * @file
  22   */
  23  
  24  /**
  25   * Abstract base class for update jobs that put some secondary data extracted
  26   * from article content into the database.
  27   *
  28   * @note subclasses should NOT start or commit transactions in their doUpdate() method,
  29   *       a transaction will automatically be wrapped around the update. Starting another
  30   *       one would break the outer transaction bracket. If need be, subclasses can override
  31   *       the beginTransaction() and commitTransaction() methods.
  32   */
  33  abstract class SqlDataUpdate extends DataUpdate {
  34      /** @var DatabaseBase Database connection reference */
  35      protected $mDb;
  36  
  37      /** @var array SELECT options to be used (array) */
  38      protected $mOptions;
  39  
  40      /** @var bool Whether a transaction is open on this object (internal use only!) */
  41      private $mHasTransaction;
  42  
  43      /** @var bool Whether this update should be wrapped in a transaction */
  44      protected $mUseTransaction;
  45  
  46      /**
  47       * Constructor
  48       *
  49       * @param bool $withTransaction Whether this update should be wrapped in a
  50       *   transaction (default: true). A transaction is only started if no
  51       *   transaction is already in progress, see beginTransaction() for details.
  52       */
  53  	public function __construct( $withTransaction = true ) {
  54          global $wgAntiLockFlags;
  55  
  56          parent::__construct();
  57  
  58          if ( $wgAntiLockFlags & ALF_NO_LINK_LOCK ) {
  59              $this->mOptions = array();
  60          } else {
  61              $this->mOptions = array( 'FOR UPDATE' );
  62          }
  63  
  64          // @todo Get connection only when it's needed? Make sure that doesn't
  65          // break anything, especially transactions!
  66          $this->mDb = wfGetDB( DB_MASTER );
  67  
  68          $this->mWithTransaction = $withTransaction;
  69          $this->mHasTransaction = false;
  70      }
  71  
  72      /**
  73       * Begin a database transaction, if $withTransaction was given as true in
  74       * the constructor for this SqlDataUpdate.
  75       *
  76       * Because nested transactions are not supported by the Database class,
  77       * this implementation checks Database::trxLevel() and only opens a
  78       * transaction if none is already active.
  79       */
  80  	public function beginTransaction() {
  81          if ( !$this->mWithTransaction ) {
  82              return;
  83          }
  84  
  85          // NOTE: nested transactions are not supported, only start a transaction if none is open
  86          if ( $this->mDb->trxLevel() === 0 ) {
  87              $this->mDb->begin( get_class( $this ) . '::beginTransaction' );
  88              $this->mHasTransaction = true;
  89          }
  90      }
  91  
  92      /**
  93       * Commit the database transaction started via beginTransaction (if any).
  94       */
  95  	public function commitTransaction() {
  96          if ( $this->mHasTransaction ) {
  97              $this->mDb->commit( get_class( $this ) . '::commitTransaction' );
  98              $this->mHasTransaction = false;
  99          }
 100      }
 101  
 102      /**
 103       * Abort the database transaction started via beginTransaction (if any).
 104       */
 105  	public function abortTransaction() {
 106          if ( $this->mHasTransaction ) { //XXX: actually... maybe always?
 107              $this->mDb->rollback( get_class( $this ) . '::abortTransaction' );
 108              $this->mHasTransaction = false;
 109          }
 110      }
 111  
 112      /**
 113       * Invalidate the cache of a list of pages from a single namespace.
 114       * This is intended for use by subclasses.
 115       *
 116       * @param int $namespace Namespace number
 117       * @param array $dbkeys
 118       */
 119  	protected function invalidatePages( $namespace, array $dbkeys ) {
 120          if ( $dbkeys === array() ) {
 121              return;
 122          }
 123  
 124          /**
 125           * Determine which pages need to be updated
 126           * This is necessary to prevent the job queue from smashing the DB with
 127           * large numbers of concurrent invalidations of the same page
 128           */
 129          $now = $this->mDb->timestamp();
 130          $ids = array();
 131          $res = $this->mDb->select( 'page', array( 'page_id' ),
 132              array(
 133                  'page_namespace' => $namespace,
 134                  'page_title' => $dbkeys,
 135                  'page_touched < ' . $this->mDb->addQuotes( $now )
 136              ), __METHOD__
 137          );
 138  
 139          foreach ( $res as $row ) {
 140              $ids[] = $row->page_id;
 141          }
 142  
 143          if ( $ids === array() ) {
 144              return;
 145          }
 146  
 147          /**
 148           * Do the update
 149           * We still need the page_touched condition, in case the row has changed since
 150           * the non-locking select above.
 151           */
 152          $this->mDb->update( 'page', array( 'page_touched' => $now ),
 153              array(
 154                  'page_id' => $ids,
 155                  'page_touched < ' . $this->mDb->addQuotes( $now )
 156              ), __METHOD__
 157          );
 158      }
 159  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1