[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
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;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |