r58320 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r58319‎ | r58320 | r58321 >
Date:15:49, 29 October 2009
Author:maxsem
Status:deferred
Tags:
Comment:
Refactored rebuildtextindex.php to support other databases. Does Postgres really not need it?
Modified paths:
  • /branches/sqlite/maintenance/rebuildtextindex.php (modified) (history)

Diff [purge]

Index: branches/sqlite/maintenance/rebuildtextindex.php
@@ -1,9 +1,8 @@
22 <?php
33 /**
4 - * Rebuild search index table from scratch. This takes several
 4+ * Rebuild search index table from scratch. This may take several
55 * hours, depending on the database size and server configuration.
66 *
7 - * This is only for MySQL (see bug 9905).
87 * Postgres is trigger-based and should never need rebuilding.
98 *
109 * This program is free software; you can redistribute it and/or modify
@@ -28,9 +27,9 @@
2928 require_once( dirname(__FILE__) . '/Maintenance.php' );
3029
3130 class RebuildTextIndex extends Maintenance {
 31+ const RTI_CHUNK_SIZE = 500;
 32+ private $db;
3233
33 - const RTI_CHUNK_SIZE = 500;
34 -
3534 public function __construct() {
3635 parent::__construct();
3736 $this->mDescription = "Rebuild search index table from scratch";
@@ -41,46 +40,34 @@
4241 }
4342
4443 public function execute() {
45 - global $wgTitle;
46 -
47 - // Only do this for MySQL
48 - $database = wfGetDB( DB_MASTER );
49 - if( !$database instanceof DatabaseMysql ) {
50 - $this->error( "This script is only for MySQL.", true );
 44+ global $wgTitle, $wgDBtype;
 45+
 46+ // Shouldn't be needed for Postgres
 47+ if ( $wgDBtype == 'postgres' ) {
 48+ $this->error( "This script does not work with PostgreSQL.\n", true );
5149 }
52 -
 50+
 51+ $this->db = wfGetDB( DB_MASTER );
5352 $wgTitle = Title::newFromText( "Rebuild text index script" );
5453
55 - $this->dropTextIndex( $database );
56 - $this->doRebuildTextIndex( $database );
57 - $this->createTextIndex( $database );
 54+ if ( $wgDBtype == 'mysql' ) {
 55+ $this->dropMysqlTextIndex();
 56+ $this->populateSearchIndex();
 57+ $this->createMysqlTextIndex();
 58+ } else {
 59+ $this->clearSearchIndex();
 60+ $this->populateSearchIndex();
 61+ }
5862
5963 $this->output( "Done.\n" );
6064 }
61 -
62 - private function dropTextIndex( &$database ) {
63 - $searchindex = $database->tableName( 'searchindex' );
64 - if ( $database->indexExists( "searchindex", "si_title" ) ) {
65 - $this->output( "Dropping index...\n" );
66 - $sql = "ALTER TABLE $searchindex DROP INDEX si_title, DROP INDEX si_text";
67 - $database->query($sql, "dropTextIndex" );
68 - }
69 - }
7065
71 - private function createTextIndex( &$database ) {
72 - $searchindex = $database->tableName( 'searchindex' );
73 - $this->output( "\nRebuild the index...\n" );
74 - $sql = "ALTER TABLE $searchindex ADD FULLTEXT si_title (si_title), " .
75 - "ADD FULLTEXT si_text (si_text)";
76 - $database->query($sql, "createTextIndex" );
77 - }
78 -
79 - private function doRebuildTextIndex( &$database ) {
80 - list ($page, $revision, $text, $searchindex) = $database->tableNamesN( 'page', 'revision', 'text', 'searchindex' );
81 -
82 - $sql = "SELECT MAX(page_id) AS count FROM $page";
83 - $res = $database->query($sql, "rebuildTextIndex" );
84 - $s = $database->fetchObject($res);
 66+ /**
 67+ * Populates the search index with content from all pages
 68+ */
 69+ protected function populateSearchIndex() {
 70+ $res = $this->db->select( 'page', 'MAX(page_id) AS count' );
 71+ $s = $this->db->fetchObject($res);
8572 $count = $s->count;
8673 $this->output( "Rebuilding index fields for {$count} pages...\n" );
8774 $n = 0;
@@ -88,22 +75,54 @@
8976 while ( $n < $count ) {
9077 $this->output( $n . "\n" );
9178 $end = $n + self::RTI_CHUNK_SIZE - 1;
92 - $sql = "SELECT page_id, page_namespace, page_title, old_flags, old_text
93 - FROM $page, $revision, $text
94 - WHERE page_id BETWEEN $n AND $end
95 - AND page_latest=rev_id
96 - AND rev_text_id=old_id";
97 - $res = $database->query($sql, "rebuildTextIndex" );
 79+
 80+ $res = $this->db->select( array( 'page', 'revision', 'text' ),
 81+ array( 'page_id', 'page_namespace', 'page_title', 'old_flags', 'old_text' ),
 82+ array( "page_id BETWEEN $n AND $end", 'page_latest = rev_id', 'rev_text_id = old_id' ),
 83+ __METHOD__
 84+ );
9885
9986 foreach( $res as $s ) {
10087 $revtext = Revision::getRevisionText( $s );
10188 $u = new SearchUpdate( $s->page_id, $s->page_title, $revtext );
10289 $u->doUpdate();
10390 }
104 - $database->freeResult( $res );
 91+ $this->db->freeResult( $res );
10592 $n += self::RTI_CHUNK_SIZE;
10693 }
10794 }
 95+
 96+ /**
 97+ * (MySQL only) Drops fulltext index before populating the table.
 98+ */
 99+ private function dropMysqlTextIndex() {
 100+ $searchindex = $this->db->tableName( 'searchindex' );
 101+ if ( $this->db->indexExists( 'searchindex', 'si_title' ) ) {
 102+ $this->output( "Dropping index...\n" );
 103+ $sql = "ALTER TABLE $searchindex DROP INDEX si_title, DROP INDEX si_text";
 104+ $this->db->query($sql, __METHOD__ );
 105+ }
 106+ }
 107+
 108+ /**
 109+ * (MySQL only) Adds back fulltext index after populating the table.
 110+ */
 111+ private function createMysqlTextIndex() {
 112+ $searchindex = $this->db->tableName( 'searchindex' );
 113+ $this->output( "\nRebuild the index...\n" );
 114+ $sql = "ALTER TABLE $searchindex ADD FULLTEXT si_title (si_title), " .
 115+ "ADD FULLTEXT si_text (si_text)";
 116+ $this->db->query( $sql, __METHOD__ );
 117+ }
 118+
 119+ /**
 120+ * Deletes everything from search index.
 121+ */
 122+ private function clearSearchIndex() {
 123+ $this->output( 'Clearing searchindex table...' );
 124+ $this->db->delete( 'searchindex', '*', __METHOD__ );
 125+ $this->output( "Done\n" );
 126+ }
108127 }
109128
110129 $maintClass = "RebuildTextIndex";

Status & tagging log