[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/maintenance/ -> rebuildtextindex.php (source)

   1  <?php
   2  /**
   3   * Rebuild search index table from scratch.  This may take several
   4   * hours, depending on the database size and server configuration.
   5   *
   6   * Postgres is trigger-based and should never need rebuilding.
   7   *
   8   * This program is free software; you can redistribute it and/or modify
   9   * it under the terms of the GNU General Public License as published by
  10   * the Free Software Foundation; either version 2 of the License, or
  11   * (at your option) any later version.
  12   *
  13   * This program is distributed in the hope that it will be useful,
  14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16   * GNU General Public License for more details.
  17   *
  18   * You should have received a copy of the GNU General Public License along
  19   * with this program; if not, write to the Free Software Foundation, Inc.,
  20   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  21   * http://www.gnu.org/copyleft/gpl.html
  22   *
  23   * @file
  24   * @ingroup Maintenance
  25   * @todo document
  26   */
  27  
  28  require_once  __DIR__ . '/Maintenance.php';
  29  
  30  /**
  31   * Maintenance script that rebuilds search index table from scratch.
  32   *
  33   * @ingroup Maintenance
  34   */
  35  class RebuildTextIndex extends Maintenance {
  36      const RTI_CHUNK_SIZE = 500;
  37  
  38      /**
  39       * @var DatabaseBase
  40       */
  41      private $db;
  42  
  43  	public function __construct() {
  44          parent::__construct();
  45          $this->mDescription = "Rebuild search index table from scratch";
  46      }
  47  
  48  	public function getDbType() {
  49          return Maintenance::DB_ADMIN;
  50      }
  51  
  52  	public function execute() {
  53          // Shouldn't be needed for Postgres
  54          $this->db = wfGetDB( DB_MASTER );
  55          if ( $this->db->getType() == 'postgres' ) {
  56              $this->error( "This script is not needed when using Postgres.\n", true );
  57          }
  58  
  59          $this->db = wfGetDB( DB_MASTER );
  60          if ( $this->db->getType() == 'sqlite' ) {
  61              if ( !DatabaseSqlite::getFulltextSearchModule() ) {
  62                  $this->error( "Your version of SQLite module for PHP doesn't "
  63                      . "support full-text search (FTS3).\n", true );
  64              }
  65              if ( !$this->db->checkForEnabledSearch() ) {
  66                  $this->error( "Your database schema is not configured for "
  67                      . "full-text search support. Run update.php.\n", true );
  68              }
  69          }
  70  
  71          if ( $this->db->getType() == 'mysql' ) {
  72              $this->dropMysqlTextIndex();
  73              $this->populateSearchIndex();
  74              $this->createMysqlTextIndex();
  75          } else {
  76              $this->clearSearchIndex();
  77              $this->populateSearchIndex();
  78          }
  79  
  80          $this->output( "Done.\n" );
  81      }
  82  
  83      /**
  84       * Populates the search index with content from all pages
  85       */
  86  	protected function populateSearchIndex() {
  87          $res = $this->db->select( 'page', 'MAX(page_id) AS count' );
  88          $s = $this->db->fetchObject( $res );
  89          $count = $s->count;
  90          $this->output( "Rebuilding index fields for {$count} pages...\n" );
  91          $n = 0;
  92  
  93          $fields = array_merge(
  94              Revision::selectPageFields(),
  95              Revision::selectFields(),
  96              Revision::selectTextFields()
  97          );
  98  
  99          while ( $n < $count ) {
 100              if ( $n ) {
 101                  $this->output( $n . "\n" );
 102              }
 103              $end = $n + self::RTI_CHUNK_SIZE - 1;
 104  
 105              $res = $this->db->select( array( 'page', 'revision', 'text' ), $fields,
 106                  array( "page_id BETWEEN $n AND $end", 'page_latest = rev_id', 'rev_text_id = old_id' ),
 107                  __METHOD__
 108              );
 109  
 110              foreach ( $res as $s ) {
 111                  try {
 112                      $title = Title::makeTitle( $s->page_namespace, $s->page_title );
 113  
 114                      $rev = new Revision( $s );
 115                      $content = $rev->getContent();
 116  
 117                      $u = new SearchUpdate( $s->page_id, $title, $content );
 118                      $u->doUpdate();
 119                  } catch ( MWContentSerializationException $ex ) {
 120                      $this->output( "Failed to deserialize content of revision {$s->rev_id} of page "
 121                          . "`" . $title->getPrefixedDBkey() . "`!\n" );
 122                  }
 123              }
 124              $n += self::RTI_CHUNK_SIZE;
 125          }
 126      }
 127  
 128      /**
 129       * (MySQL only) Drops fulltext index before populating the table.
 130       */
 131  	private function dropMysqlTextIndex() {
 132          $searchindex = $this->db->tableName( 'searchindex' );
 133          if ( $this->db->indexExists( 'searchindex', 'si_title', __METHOD__ ) ) {
 134              $this->output( "Dropping index...\n" );
 135              $sql = "ALTER TABLE $searchindex DROP INDEX si_title, DROP INDEX si_text";
 136              $this->db->query( $sql, __METHOD__ );
 137          }
 138      }
 139  
 140      /**
 141       * (MySQL only) Adds back fulltext index after populating the table.
 142       */
 143  	private function createMysqlTextIndex() {
 144          $searchindex = $this->db->tableName( 'searchindex' );
 145          $this->output( "\nRebuild the index...\n" );
 146          $sql = "ALTER TABLE $searchindex ADD FULLTEXT si_title (si_title), " .
 147              "ADD FULLTEXT si_text (si_text)";
 148          $this->db->query( $sql, __METHOD__ );
 149      }
 150  
 151      /**
 152       * Deletes everything from search index.
 153       */
 154  	private function clearSearchIndex() {
 155          $this->output( 'Clearing searchindex table...' );
 156          $this->db->delete( 'searchindex', '*', __METHOD__ );
 157          $this->output( "Done\n" );
 158      }
 159  }
 160  
 161  $maintClass = "RebuildTextIndex";
 162  require_once RUN_MAINTENANCE_IF_MAIN;


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