For backport to 1.14.

* Made the upgrader work with SQLite
* Implemented missing schema info functionality in DatabaseSqlite
* Merged the SQLite and MySQL schemas into the one file with the help of some replaceVars() hacks.
* Moved all primary key definitions to the field definition, moved all indexes to CREATE INDEX statements, for best SQLite compatibility.
* Made all autoincrement fields primary keys, as required by SQLite.
* Removed meaningless buzzword from the category table comment
* tables.sql: s/'0'/0/
* In SQLite the index names have DB scope. Renamed archive.usertext_timestamp, user_newtalk.user_id, user_newtalk.user_ip
* SQLite does not support UPDATE with LIMIT by default. Removed all instances I could find.
* Made query errors work in the installer.
* Fixed DatabaseSqlite::lastErrno(), made SQLITE_SCHEMA errors automatically reissue the query as suggested on sqlite-users. Otherwise upgrade breaks.
* Removed miscellaneous status information from getServerVersion(), that's not the place to put it
This commit is contained in:
Tim Starling 2009-01-15 06:56:58 +00:00
parent b1b72a85f9
commit 4124558d7b
10 changed files with 1103 additions and 876 deletions

View file

@ -47,11 +47,13 @@ require_once( "$IP/includes/Namespace.php" );
require_once( "$IP/includes/ProfilerStub.php" );
require_once( "$IP/includes/GlobalFunctions.php" );
require_once( "$IP/includes/Hooks.php" );
require_once( "$IP/includes/Exception.php" );
# If we get an exception, the user needs to know
# all the details
$wgShowExceptionDetails = true;
$wgShowSQLErrors = true;
wfInstallExceptionHandler();
## Databases we support:
$ourdb = array();

View file

@ -161,23 +161,26 @@ class MWException extends Exception {
if( $hookResult = $this->runHooks( get_class( $this ) . "Raw" ) ) {
die( $hookResult );
}
echo $this->htmlHeader();
echo $this->getHTML();
echo $this->htmlFooter();
if ( defined( 'MEDIAWIKI_INSTALL' ) ) {
echo $this->getHTML();
} else {
echo $this->htmlHeader();
echo $this->getHTML();
echo $this->htmlFooter();
}
}
}
/**
* Output a report about the exception and takes care of formatting.
* It will be either HTML or plain text based on $wgCommandLineMode.
* It will be either HTML or plain text based on isCommandLine().
*/
function report() {
global $wgCommandLineMode;
$log = $this->getLogMessage();
if ( $log ) {
wfDebugLog( 'exception', $log );
}
if ( $wgCommandLineMode ) {
if ( self::isCommandLine() ) {
wfPrintError( $this->getText() );
} else {
$this->reportHTML();
@ -214,6 +217,10 @@ class MWException extends Exception {
function htmlFooter() {
echo "</body></html>";
}
static function isCommandLine() {
return !empty( $GLOBALS['wgCommandLineMode'] ) && !defined( 'MEDIAWIKI_INSTALL' );
}
}
/**
@ -264,6 +271,7 @@ function wfInstallExceptionHandler() {
* Report an exception to the user
*/
function wfReportException( Exception $e ) {
$cmdLine = MWException::isCommandLine();
if ( $e instanceof MWException ) {
try {
$e->report();
@ -276,7 +284,7 @@ function wfReportException( Exception $e ) {
"\n\nException caught inside exception handler: " .
$e2->__toString() . "\n";
if ( !empty( $GLOBALS['wgCommandLineMode'] ) ) {
if ( $cmdLine ) {
wfPrintError( $message );
} else {
echo nl2br( htmlspecialchars( $message ) ). "\n";
@ -288,7 +296,7 @@ function wfReportException( Exception $e ) {
if ( $GLOBALS['wgShowExceptionDetails'] ) {
$message .= "\n" . $e->getTraceAsString() ."\n";
}
if ( !empty( $GLOBALS['wgCommandLineMode'] ) ) {
if ( $cmdLine ) {
wfPrintError( $message );
} else {
echo nl2br( htmlspecialchars( $message ) ). "\n";
@ -298,7 +306,7 @@ function wfReportException( Exception $e ) {
/**
* Print a message, if possible to STDERR.
* Use this in command line mode only (see wgCommandLineMode)
* Use this in command line mode only (see isCommandLine)
*/
function wfPrintError( $message ) {
#NOTE: STDERR may not be available, especially if php-cgi is used from the command line (bug #15602).

View file

@ -222,7 +222,7 @@ class SiteStatsUpdate {
if ( $updates ) {
$site_stats = $dbw->tableName( 'site_stats' );
$sql = $dbw->limitResultForUpdate("UPDATE $site_stats SET $updates", 1);
$sql = "UPDATE $site_stats SET $updates";
# Need a separate transaction because this a global lock
$dbw->begin();
@ -240,7 +240,7 @@ class SiteStatsUpdate {
__METHOD__ );
$dbw->update( 'site_stats',
array( 'ss_active_users' => intval($activeUsers) ),
array( 'ss_row_id' => 1 ), __METHOD__, array( 'LIMIT' => 1 )
array( 'ss_row_id' => 1 ), __METHOD__
);
}
}

View file

@ -570,7 +570,7 @@ class Database {
$ret = $this->doQuery( $commentedSql );
# Try reconnecting if the connection was lost
if ( false === $ret && ( $this->lastErrno() == 2013 || $this->lastErrno() == 2006 ) ) {
if ( false === $ret && $this->wasErrorReissuable() ) {
# Transaction is gone, like it or not
$this->mTrxLevel = 0;
wfDebug( "Connection lost, reconnecting...\n" );
@ -1816,6 +1816,14 @@ class Database {
return $this->lastErrno() == 1213;
}
/**
* Determines if the last query error was something that should be dealt
* with by pinging the connection and reissuing the query
*/
function wasErrorReissuable() {
return $this->lastErrno() == 2013 || $this->lastErrno() == 2006;
}
/**
* Perform a deadlock-prone transaction.
*

View file

@ -15,6 +15,7 @@ class DatabaseSqlite extends Database {
var $mAffectedRows;
var $mLastResult;
var $mDatabaseFile;
var $mName;
/**
* Constructor
@ -26,6 +27,7 @@ class DatabaseSqlite extends Database {
$this->mFailFunction = $failFunction;
$this->mFlags = $flags;
$this->mDatabaseFile = "$wgSQLiteDataDir/$dbName.sqlite";
$this->mName = $dbName;
$this->open($server, $user, $password, $dbName);
}
@ -89,8 +91,9 @@ class DatabaseSqlite extends Database {
*/
function doQuery($sql) {
$res = $this->mConn->query($sql);
if ($res === false) $this->reportQueryError($this->lastError(),$this->lastErrno(),$sql,__FUNCTION__);
else {
if ($res === false) {
return false;
} else {
$r = $res instanceof ResultWrapper ? $res->result : $res;
$this->mAffectedRows = $r->rowCount();
$res = new ResultWrapper($this,$r->fetchAll());
@ -173,8 +176,12 @@ class DatabaseSqlite extends Database {
}
function lastErrno() {
if (!is_object($this->mConn)) return "Cannot return last error, no db connection";
return $this->mConn->errorCode();
if (!is_object($this->mConn)) {
return "Cannot return last error, no db connection";
} else {
$info = $this->mConn->errorInfo();
return $info[1];
}
}
function affectedRows() {
@ -183,14 +190,43 @@ class DatabaseSqlite extends Database {
/**
* Returns information about an index
* Returns false if the index does not exist
* - if errors are explicitly ignored, returns NULL on failure
*/
function indexInfo($table, $index, $fname = 'Database::indexExists') {
return false;
$sql = 'PRAGMA index_info(' . $this->addQuotes( $index ) . ')';
$res = $this->query( $sql, $fname );
if ( !$res ) {
return null;
}
if ( $res->numRows() == 0 ) {
return false;
}
$info = array();
foreach ( $res as $row ) {
$info[] = $row->name;
}
return $info;
}
function indexUnique($table, $index, $fname = 'Database::indexUnique') {
return false;
$row = $this->selectRow( 'sqlite_master', '*',
array(
'type' => 'index',
'name' => $index,
), $fname );
if ( !$row || !isset( $row->sql ) ) {
return null;
}
// $row->sql will be of the form CREATE [UNIQUE] INDEX ...
$indexPos = strpos( $row->sql, 'INDEX' );
if ( $indexPos === false ) {
return null;
}
$firstPart = substr( $row->sql, 0, $indexPos );
$options = explode( ' ', $firstPart );
return in_array( 'UNIQUE', $options );
}
/**
@ -228,7 +264,10 @@ class DatabaseSqlite extends Database {
return '';
}
# Returns the size of a text field, or -1 for "unlimited"
/**
* Returns the size of a text field, or -1 for "unlimited"
* In SQLite this is SQLITE_MAX_LENGTH, by default 1GB. No way to query it though.
*/
function textFieldSize($table, $field) {
return -1;
}
@ -252,6 +291,10 @@ class DatabaseSqlite extends Database {
return $this->lastErrno() == SQLITE_BUSY;
}
function wasErrorReissuable() {
return $this->lastErrno() == SQLITE_SCHEMA;
}
/**
* @return string wikitext of a link to the server software's web site
*/
@ -265,17 +308,32 @@ class DatabaseSqlite extends Database {
function getServerVersion() {
global $wgContLang;
$ver = $this->mConn->getAttribute(PDO::ATTR_SERVER_VERSION);
$size = $wgContLang->formatSize(filesize($this->mDatabaseFile));
$file = basename($this->mDatabaseFile);
return $ver." ($file: $size)";
return $ver;
}
/**
* Query whether a given column exists in the mediawiki schema
*/
function fieldExists($table, $field) { return true; }
function fieldExists($table, $field) {
$info = $this->fieldInfo( $table, $field );
return (bool)$info;
}
function fieldInfo($table, $field) { return SQLiteField::fromText($this, $table, $field); }
/**
* Get information about a given field
* Returns false if the field does not exist.
*/
function fieldInfo($table, $field) {
$tableName = $this->tableName( $table );
$sql = 'PRAGMA table_info(' . $this->addQuotes( $tableName ) . ')';
$res = $this->query( $sql, __METHOD__ );
foreach ( $res as $row ) {
if ( $row->name == $field ) {
return new SQLiteField( $row, $tableName );
}
}
return false;
}
function begin() {
if ($this->mTrxLevel == 1) $this->commit();
@ -296,7 +354,7 @@ class DatabaseSqlite extends Database {
}
function limitResultForUpdate($sql, $num) {
return $sql;
return $this->limitResult( $sql, $num );
}
function strencode($s) {
@ -325,17 +383,25 @@ class DatabaseSqlite extends Database {
function quote_ident($s) { return $s; }
/**
* For now, does nothing
* Not possible in SQLite
* We have ATTACH_DATABASE but that requires database selectors before the
* table names and in any case is really a different concept to MySQL's USE
*/
function selectDB($db) { return true; }
function selectDB($db) {
if ( $db != $this->mName ) {
throw new MWException( 'selectDB is not implemented in SQLite' );
}
}
/**
* not done
*/
public function setTimeout($timeout) { return; }
/**
* No-op for a non-networked database
*/
function ping() {
wfDebug("Function ping() not written for SQLite yet");
return true;
}
@ -353,39 +419,16 @@ class DatabaseSqlite extends Database {
public function setup_database() {
global $IP,$wgSQLiteDataDir,$wgDBTableOptions;
$wgDBTableOptions = '';
$mysql_tmpl = "$IP/maintenance/tables.sql";
$mysql_iw = "$IP/maintenance/interwiki.sql";
$sqlite_tmpl = "$IP/maintenance/sqlite/tables.sql";
# Make an SQLite template file if it doesn't exist (based on the same one MySQL uses to create a new wiki db)
if (!file_exists($sqlite_tmpl)) {
$sql = file_get_contents($mysql_tmpl);
$sql = preg_replace('/^\s*--.*?$/m','',$sql); # strip comments
$sql = preg_replace('/^\s*(UNIQUE)?\s*(PRIMARY)?\s*KEY.+?$/m','',$sql);
$sql = preg_replace('/^\s*(UNIQUE )?INDEX.+?$/m','',$sql); # These indexes should be created with a CREATE INDEX query
$sql = preg_replace('/^\s*FULLTEXT.+?$/m','',$sql); # Full text indexes
$sql = preg_replace('/ENUM\(.+?\)/','TEXT',$sql); # Make ENUM's into TEXT's
$sql = preg_replace('/binary\(\d+\)/','BLOB',$sql);
$sql = preg_replace('/(TYPE|MAX_ROWS|AVG_ROW_LENGTH)=\w+/','',$sql);
$sql = preg_replace('/,\s*\)/s',')',$sql); # removing previous items may leave a trailing comma
$sql = str_replace('binary','',$sql);
$sql = str_replace('auto_increment','PRIMARY KEY AUTOINCREMENT',$sql);
$sql = str_replace(' unsigned','',$sql);
$sql = str_replace(' int ',' INTEGER ',$sql);
$sql = str_replace('NOT NULL','',$sql);
# Tidy up and write file
$sql = preg_replace('/^\s*^/m','',$sql); # Remove empty lines
$sql = preg_replace('/;$/m',";\n",$sql); # Separate each statement with an empty line
file_put_contents($sqlite_tmpl,$sql);
# Process common MySQL/SQLite table definitions
$err = $this->sourceFile( "$IP/maintenance/tables.sql" );
if ($err !== true) {
$this->reportQueryError($err,0,$sql,__FUNCTION__);
exit( 1 );
}
# Parse the SQLite template replacing inline variables such as /*$wgDBprefix*/
$err = $this->sourceFile($sqlite_tmpl);
if ($err !== true) $this->reportQueryError($err,0,$sql,__FUNCTION__);
# Use DatabasePostgres's code to populate interwiki from MySQL template
$f = fopen($mysql_iw,'r');
$f = fopen("$IP/maintenance/interwiki.sql",'r');
if ($f == false) dieout("<li>Could not find the interwiki.sql file");
$sql = "INSERT INTO interwiki(iw_prefix,iw_url,iw_local) VALUES ";
while (!feof($f)) {
@ -418,22 +461,80 @@ class DatabaseSqlite extends Database {
$function = array_shift( $args );
return call_user_func_array( $function, $args );
}
}
/**
* @ingroup Database
*/
class SQLiteField extends MySQLField {
function __construct() {
}
static function fromText($db, $table, $field) {
$n = new SQLiteField;
$n->name = $field;
$n->tablename = $table;
return $n;
protected function replaceVars( $s ) {
$s = parent::replaceVars( $s );
if ( preg_match( '/^\s*CREATE TABLE/i', $s ) ) {
// CREATE TABLE hacks to allow schema file sharing with MySQL
// binary/varbinary column type -> blob
$s = preg_replace( '/\b(var)?binary(\(\d+\))/i', 'blob\1', $s );
// no such thing as unsigned
$s = preg_replace( '/\bunsigned\b/i', '', $s );
// INT -> INTEGER for primary keys
$s = preg_replacE( '/\bint\b/i', 'integer', $s );
// No ENUM type
$s = preg_replace( '/enum\([^)]*\)/i', 'blob', $s );
// binary collation type -> nothing
$s = preg_replace( '/\bbinary\b/i', '', $s );
// auto_increment -> autoincrement
$s = preg_replace( '/\bauto_increment\b/i', 'autoincrement', $s );
// No explicit options
$s = preg_replace( '/\)[^)]*$/', ')', $s );
} elseif ( preg_match( '/^\s*CREATE (\s*(?:UNIQUE|FULLTEXT)\s+)?INDEX/i', $s ) ) {
// No truncated indexes
$s = preg_replace( '/\(\d+\)/', '', $s );
// No FULLTEXT
$s = preg_replace( '/\bfulltext\b/i', '', $s );
}
return $s;
}
} // end DatabaseSqlite class
/**
* @ingroup Database
*/
class SQLiteField {
private $info, $tableName;
function __construct( $info, $tableName ) {
$this->info = $info;
$this->tableName = $tableName;
}
function name() {
return $this->info->name;
}
function tableName() {
return $this->tableName;
}
function defaultValue() {
if ( is_string( $this->info->dflt_value ) ) {
// Typically quoted
if ( preg_match( '/^\'(.*)\'$', $this->info->dflt_value ) ) {
return str_replace( "''", "'", $this->info->dflt_value );
}
}
return $this->info->dflt_value;
}
function maxLength() {
return -1;
}
function nullable() {
// SQLite dynamic types are always nullable
return true;
}
# isKey(), isMultipleKey() not implemented, MySQL-specific concept.
# Suggest removal from base class [TS]
function type() {
return $this->info->type;
}
} // end SQLiteField

12
maintenance/sqlite/README Normal file
View file

@ -0,0 +1,12 @@
SQLite shares the MySQL schema file at maintenance/tables.sql, with a set of
compatibility regexes to convert MySQL syntax to SQLite syntax:
* BINARY() and VARBINARY() fields are converted to BLOB
* the UNSIGNED modifier is removed
* "INT" fields are converted to "INTEGER"
* ENUM is converted to BLOB
* the BINARY collation modifier is removed
* AUTO_INCREMENT is converted to AUTOINCREMENT
* Any table options are removed
* Truncated indexes are upgraded to full-width indexes
* FULLTEXT indexes are converted to ordinary indexes

View file

@ -0,0 +1,417 @@
-- Correct for the total lack of indexes in the MW 1.13 SQLite schema
--
-- Unique indexes need to be handled with INSERT SELECT since just running
-- the CREATE INDEX statement will fail if there are duplicate values.
--
-- Ignore duplicates, several tables will have them (e.g. bug 16966) but in
-- most cases it's harmless to discard them. We'll keep the old tables with
-- duplicates in so that the user can recover them in case of disaster.
--------------------------------------------------------------------------------
-- Drop temporary tables from aborted runs
--------------------------------------------------------------------------------
DROP TABLE IF EXISTS /*_*/user_tmp;
DROP TABLE IF EXISTS /*_*/user_groups_tmp;
DROP TABLE IF EXISTS /*_*/page_tmp;
DROP TABLE IF EXISTS /*_*/revision_tmp;
DROP TABLE IF EXISTS /*_*/pagelinks_tmp;
DROP TABLE IF EXISTS /*_*/templatelinks_tmp;
DROP TABLE IF EXISTS /*_*/imagelinks_tmp;
DROP TABLE IF EXISTS /*_*/categorylinks_tmp;
DROP TABLE IF EXISTS /*_*/category_tmp;
DROP TABLE IF EXISTS /*_*/langlinks_tmp;
DROP TABLE IF EXISTS /*_*/site_stats_tmp;
DROP TABLE IF EXISTS /*_*/ipblocks_tmp;
DROP TABLE IF EXISTS /*_*/watchlist_tmp;
DROP TABLE IF EXISTS /*_*/math_tmp;
DROP TABLE IF EXISTS /*_*/interwiki_tmp;
DROP TABLE IF EXISTS /*_*/page_restrictions_tmp;
DROP TABLE IF EXISTS /*_*/protected_titles_tmp;
DROP TABLE IF EXISTS /*_*/page_props_tmp;
--------------------------------------------------------------------------------
-- Create new tables
--------------------------------------------------------------------------------
CREATE TABLE /*_*/user_tmp (
user_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
user_name varchar(255) binary NOT NULL default '',
user_real_name varchar(255) binary NOT NULL default '',
user_password tinyblob NOT NULL,
user_newpassword tinyblob NOT NULL,
user_newpass_time binary(14),
user_email tinytext NOT NULL,
user_options blob NOT NULL,
user_touched binary(14) NOT NULL default '',
user_token binary(32) NOT NULL default '',
user_email_authenticated binary(14),
user_email_token binary(32),
user_email_token_expires binary(14),
user_registration binary(14),
user_editcount int
);
CREATE UNIQUE INDEX user_name ON /*_*/user_tmp (user_name);
CREATE INDEX user_email_token ON /*_*/user_tmp (user_email_token);
CREATE TABLE /*_*/user_groups_tmp (
ug_user int unsigned NOT NULL default 0,
ug_group varbinary(16) NOT NULL default ''
);
CREATE UNIQUE INDEX ug_user_group ON /*_*/user_groups_tmp (ug_user,ug_group);
CREATE INDEX ug_group ON /*_*/user_groups_tmp (ug_group);
CREATE TABLE /*_*/page_tmp (
page_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
page_namespace int NOT NULL,
page_title varchar(255) binary NOT NULL,
page_restrictions tinyblob NOT NULL,
page_counter bigint unsigned NOT NULL default 0,
page_is_redirect tinyint unsigned NOT NULL default 0,
page_is_new tinyint unsigned NOT NULL default 0,
page_random real unsigned NOT NULL,
page_touched binary(14) NOT NULL default '',
page_latest int unsigned NOT NULL,
page_len int unsigned NOT NULL
);
CREATE UNIQUE INDEX name_title ON /*_*/page_tmp (page_namespace,page_title);
CREATE INDEX page_random ON /*_*/page_tmp (page_random);
CREATE INDEX page_len ON /*_*/page_tmp (page_len);
CREATE TABLE /*_*/revision_tmp (
rev_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
rev_page int unsigned NOT NULL,
rev_text_id int unsigned NOT NULL,
rev_comment tinyblob NOT NULL,
rev_user int unsigned NOT NULL default 0,
rev_user_text varchar(255) binary NOT NULL default '',
rev_timestamp binary(14) NOT NULL default '',
rev_minor_edit tinyint unsigned NOT NULL default 0,
rev_deleted tinyint unsigned NOT NULL default 0,
rev_len int unsigned,
rev_parent_id int unsigned default NULL
);
CREATE UNIQUE INDEX rev_page_id ON /*_*/revision_tmp (rev_page, rev_id);
CREATE INDEX rev_timestamp ON /*_*/revision_tmp (rev_timestamp);
CREATE INDEX page_timestamp ON /*_*/revision_tmp (rev_page,rev_timestamp);
CREATE INDEX user_timestamp ON /*_*/revision_tmp (rev_user,rev_timestamp);
CREATE INDEX usertext_timestamp ON /*_*/revision_tmp (rev_user_text,rev_timestamp);
CREATE TABLE /*_*/pagelinks_tmp (
pl_from int unsigned NOT NULL default 0,
pl_namespace int NOT NULL default 0,
pl_title varchar(255) binary NOT NULL default ''
);
CREATE UNIQUE INDEX pl_from ON /*_*/pagelinks_tmp (pl_from,pl_namespace,pl_title);
CREATE INDEX pl_namespace_title ON /*_*/pagelinks_tmp (pl_namespace,pl_title,pl_from);
CREATE TABLE /*_*/templatelinks_tmp (
tl_from int unsigned NOT NULL default 0,
tl_namespace int NOT NULL default 0,
tl_title varchar(255) binary NOT NULL default ''
);
CREATE UNIQUE INDEX tl_from ON /*_*/templatelinks_tmp (tl_from,tl_namespace,tl_title);
CREATE INDEX tl_namespace_title ON /*_*/templatelinks_tmp (tl_namespace,tl_title,tl_from);
CREATE TABLE /*_*/imagelinks_tmp (
il_from int unsigned NOT NULL default 0,
il_to varchar(255) binary NOT NULL default ''
) /*$wgDBTableOptions*/;
CREATE UNIQUE INDEX il_from ON /*_*/imagelinks_tmp (il_from,il_to);
CREATE INDEX il_to ON /*_*/imagelinks_tmp (il_to,il_from);
CREATE TABLE /*_*/categorylinks_tmp (
cl_from int unsigned NOT NULL default 0,
cl_to varchar(255) binary NOT NULL default '',
cl_sortkey varchar(70) binary NOT NULL default '',
cl_timestamp timestamp NOT NULL
);
CREATE UNIQUE INDEX cl_from ON /*_*/categorylinks_tmp (cl_from,cl_to);
CREATE INDEX cl_sortkey ON /*_*/categorylinks_tmp (cl_to,cl_sortkey,cl_from);
CREATE INDEX cl_timestamp ON /*_*/categorylinks_tmp (cl_to,cl_timestamp);
CREATE TABLE /*_*/category_tmp (
cat_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
cat_title varchar(255) binary NOT NULL,
cat_pages int signed NOT NULL default 0,
cat_subcats int signed NOT NULL default 0,
cat_files int signed NOT NULL default 0,
cat_hidden tinyint unsigned NOT NULL default 0
);
CREATE UNIQUE INDEX cat_title ON /*_*/category_tmp (cat_title);
CREATE INDEX cat_pages ON /*_*/category_tmp (cat_pages);
CREATE TABLE /*_*/langlinks_tmp (
ll_from int unsigned NOT NULL default 0,
ll_lang varbinary(20) NOT NULL default '',
ll_title varchar(255) binary NOT NULL default ''
);
CREATE UNIQUE INDEX ll_from ON /*_*/langlinks_tmp (ll_from, ll_lang);
CREATE INDEX ll_lang_title ON /*_*/langlinks_tmp (ll_lang, ll_title);
CREATE TABLE /*_*/site_stats_tmp (
ss_row_id int unsigned NOT NULL,
ss_total_views bigint unsigned default 0,
ss_total_edits bigint unsigned default 0,
ss_good_articles bigint unsigned default 0,
ss_total_pages bigint default '-1',
ss_users bigint default '-1',
ss_active_users bigint default '-1',
ss_admins int default '-1',
ss_images int default 0
);
CREATE UNIQUE INDEX ss_row_id ON /*_*/site_stats_tmp (ss_row_id);
CREATE TABLE /*_*/ipblocks_tmp (
ipb_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
ipb_address tinyblob NOT NULL,
ipb_user int unsigned NOT NULL default 0,
ipb_by int unsigned NOT NULL default 0,
ipb_by_text varchar(255) binary NOT NULL default '',
ipb_reason tinyblob NOT NULL,
ipb_timestamp binary(14) NOT NULL default '',
ipb_auto bool NOT NULL default 0,
-- If set to 1, block applies only to logged-out users
ipb_anon_only bool NOT NULL default 0,
ipb_create_account bool NOT NULL default 1,
ipb_enable_autoblock bool NOT NULL default '1',
ipb_expiry varbinary(14) NOT NULL default '',
ipb_range_start tinyblob NOT NULL,
ipb_range_end tinyblob NOT NULL,
ipb_deleted bool NOT NULL default 0,
ipb_block_email bool NOT NULL default 0,
ipb_allow_usertalk bool NOT NULL default 0
);
CREATE UNIQUE INDEX ipb_address ON /*_*/ipblocks_tmp (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only);
CREATE INDEX ipb_user ON /*_*/ipblocks_tmp (ipb_user);
CREATE INDEX ipb_range ON /*_*/ipblocks_tmp (ipb_range_start(8), ipb_range_end(8));
CREATE INDEX ipb_timestamp ON /*_*/ipblocks_tmp (ipb_timestamp);
CREATE INDEX ipb_expiry ON /*_*/ipblocks_tmp (ipb_expiry);
CREATE TABLE /*_*/watchlist_tmp (
wl_user int unsigned NOT NULL,
wl_namespace int NOT NULL default 0,
wl_title varchar(255) binary NOT NULL default '',
wl_notificationtimestamp varbinary(14)
);
CREATE UNIQUE INDEX wl_user_namespace_title ON /*_*/watchlist_tmp (wl_user, wl_namespace, wl_title);
CREATE INDEX namespace_title ON /*_*/watchlist_tmp (wl_namespace, wl_title);
CREATE TABLE /*_*/math_tmp (
math_inputhash varbinary(16) NOT NULL,
math_outputhash varbinary(16) NOT NULL,
math_html_conservativeness tinyint NOT NULL,
math_html text,
math_mathml text
);
CREATE UNIQUE INDEX math_inputhash ON /*_*/math_tmp (math_inputhash);
CREATE TABLE /*_*/interwiki_tmp (
iw_prefix varchar(32) NOT NULL,
iw_url blob NOT NULL,
iw_local bool NOT NULL,
iw_trans tinyint NOT NULL default 0
);
CREATE UNIQUE INDEX iw_prefix ON /*_*/interwiki_tmp (iw_prefix);
CREATE TABLE /*_*/page_restrictions_tmp (
pr_page int NOT NULL,
pr_type varbinary(60) NOT NULL,
pr_level varbinary(60) NOT NULL,
pr_cascade tinyint NOT NULL,
pr_user int NULL,
pr_expiry varbinary(14) NULL,
pr_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT
);
CREATE UNIQUE INDEX pr_pagetype ON /*_*/page_restrictions_tmp (pr_page,pr_type);
CREATE UNIQUE INDEX pr_typelevel ON /*_*/page_restrictions_tmp (pr_type,pr_level);
CREATE UNIQUE INDEX pr_level ON /*_*/page_restrictions_tmp (pr_level);
CREATE UNIQUE INDEX pr_cascade ON /*_*/page_restrictions_tmp (pr_cascade);
CREATE TABLE /*_*/protected_titles_tmp (
pt_namespace int NOT NULL,
pt_title varchar(255) binary NOT NULL,
pt_user int unsigned NOT NULL,
pt_reason tinyblob,
pt_timestamp binary(14) NOT NULL,
pt_expiry varbinary(14) NOT NULL default '',
pt_create_perm varbinary(60) NOT NULL
);
CREATE UNIQUE INDEX pt_namespace_title ON /*_*/protected_titles_tmp (pt_namespace,pt_title);
CREATE INDEX pt_timestamp ON /*_*/protected_titles_tmp (pt_timestamp);
CREATE TABLE /*_*/page_props_tmp (
pp_page int NOT NULL,
pp_propname varbinary(60) NOT NULL,
pp_value blob NOT NULL
);
CREATE UNIQUE INDEX pp_page_propname ON /*_*/page_props_tmp (pp_page,pp_propname);
--------------------------------------------------------------------------------
-- Populate the new tables using INSERT SELECT
--------------------------------------------------------------------------------
INSERT OR IGNORE INTO /*_*/user_tmp SELECT * FROM /*_*/user;
INSERT OR IGNORE INTO /*_*/user_groups_tmp SELECT * FROM /*_*/user_groups;
INSERT OR IGNORE INTO /*_*/page_tmp SELECT * FROM /*_*/page;
INSERT OR IGNORE INTO /*_*/revision_tmp SELECT * FROM /*_*/revision;
INSERT OR IGNORE INTO /*_*/pagelinks_tmp SELECT * FROM /*_*/pagelinks;
INSERT OR IGNORE INTO /*_*/templatelinks_tmp SELECT * FROM /*_*/templatelinks;
INSERT OR IGNORE INTO /*_*/imagelinks_tmp SELECT * FROM /*_*/imagelinks;
INSERT OR IGNORE INTO /*_*/categorylinks_tmp SELECT * FROM /*_*/categorylinks;
INSERT OR IGNORE INTO /*_*/category_tmp SELECT * FROM /*_*/category;
INSERT OR IGNORE INTO /*_*/langlinks_tmp SELECT * FROM /*_*/langlinks;
INSERT OR IGNORE INTO /*_*/site_stats_tmp SELECT * FROM /*_*/site_stats;
INSERT OR IGNORE INTO /*_*/ipblocks_tmp SELECT * FROM /*_*/ipblocks;
INSERT OR IGNORE INTO /*_*/watchlist_tmp SELECT * FROM /*_*/watchlist;
INSERT OR IGNORE INTO /*_*/math_tmp SELECT * FROM /*_*/math;
INSERT OR IGNORE INTO /*_*/interwiki_tmp SELECT * FROM /*_*/interwiki;
INSERT OR IGNORE INTO /*_*/page_restrictions_tmp SELECT * FROM /*_*/page_restrictions;
INSERT OR IGNORE INTO /*_*/protected_titles_tmp SELECT * FROM /*_*/protected_titles;
INSERT OR IGNORE INTO /*_*/page_props_tmp SELECT * FROM /*_*/page_props;
--------------------------------------------------------------------------------
-- Do the table renames
--------------------------------------------------------------------------------
ALTER TABLE /*_*/user RENAME TO /*_*/user_old_13;
ALTER TABLE /*_*/user_tmp RENAME TO /*_*/user;
ALTER TABLE /*_*/user_groups RENAME TO /*_*/user_groups_old_13;
ALTER TABLE /*_*/user_groups_tmp RENAME TO /*_*/user_groups;
ALTER TABLE /*_*/page RENAME TO /*_*/page_old_13;
ALTER TABLE /*_*/page_tmp RENAME TO /*_*/page;
ALTER TABLE /*_*/revision RENAME TO /*_*/revision_old_13;
ALTER TABLE /*_*/revision_tmp RENAME TO /*_*/revision;
ALTER TABLE /*_*/pagelinks RENAME TO /*_*/pagelinks_old_13;
ALTER TABLE /*_*/pagelinks_tmp RENAME TO /*_*/pagelinks;
ALTER TABLE /*_*/templatelinks RENAME TO /*_*/templatelinks_old_13;
ALTER TABLE /*_*/templatelinks_tmp RENAME TO /*_*/templatelinks;
ALTER TABLE /*_*/imagelinks RENAME TO /*_*/imagelinks_old_13;
ALTER TABLE /*_*/imagelinks_tmp RENAME TO /*_*/imagelinks;
ALTER TABLE /*_*/categorylinks RENAME TO /*_*/categorylinks_old_13;
ALTER TABLE /*_*/categorylinks_tmp RENAME TO /*_*/categorylinks;
ALTER TABLE /*_*/category RENAME TO /*_*/category_old_13;
ALTER TABLE /*_*/category_tmp RENAME TO /*_*/category;
ALTER TABLE /*_*/langlinks RENAME TO /*_*/langlinks_old_13;
ALTER TABLE /*_*/langlinks_tmp RENAME TO /*_*/langlinks;
ALTER TABLE /*_*/site_stats RENAME TO /*_*/site_stats_old_13;
ALTER TABLE /*_*/site_stats_tmp RENAME TO /*_*/site_stats;
ALTER TABLE /*_*/ipblocks RENAME TO /*_*/ipblocks_old_13;
ALTER TABLE /*_*/ipblocks_tmp RENAME TO /*_*/ipblocks;
ALTER TABLE /*_*/watchlist RENAME TO /*_*/watchlist_old_13;
ALTER TABLE /*_*/watchlist_tmp RENAME TO /*_*/watchlist;
ALTER TABLE /*_*/math RENAME TO /*_*/math_old_13;
ALTER TABLE /*_*/math_tmp RENAME TO /*_*/math;
ALTER TABLE /*_*/interwiki RENAME TO /*_*/interwiki_old_13;
ALTER TABLE /*_*/interwiki_tmp RENAME TO /*_*/interwiki;
ALTER TABLE /*_*/page_restrictions RENAME TO /*_*/page_restrictions_old_13;
ALTER TABLE /*_*/page_restrictions_tmp RENAME TO /*_*/page_restrictions;
ALTER TABLE /*_*/protected_titles RENAME TO /*_*/protected_titles_old_13;
ALTER TABLE /*_*/protected_titles_tmp RENAME TO /*_*/protected_titles;
ALTER TABLE /*_*/page_props RENAME TO /*_*/page_props_old_13;
ALTER TABLE /*_*/page_props_tmp RENAME TO /*_*/page_props;
--------------------------------------------------------------------------------
-- Drop and create tables with unique indexes but no valuable data
--------------------------------------------------------------------------------
DROP TABLE IF EXISTS /*_*/searchindex;
CREATE TABLE /*_*/searchindex (
si_page int unsigned NOT NULL,
si_title varchar(255) NOT NULL default '',
si_text mediumtext NOT NULL
);
CREATE UNIQUE INDEX si_page ON /*_*/searchindex (si_page);
CREATE INDEX si_title ON /*_*/searchindex (si_title);
CREATE INDEX si_text ON /*_*/searchindex (si_text);
DROP TABLE IF EXISTS /*_*/transcache;
CREATE TABLE /*_*/transcache (
tc_url varbinary(255) NOT NULL,
tc_contents text,
tc_time int NOT NULL
) /*$wgDBTableOptions*/;
CREATE UNIQUE INDEX tc_url_idx ON /*_*/transcache (tc_url);
DROP TABLE IF EXISTS /*_*/querycache_info;
CREATE TABLE /*_*/querycache_info (
qci_type varbinary(32) NOT NULL default '',
qci_timestamp binary(14) NOT NULL default '19700101000000'
) /*$wgDBTableOptions*/;
CREATE UNIQUE INDEX qci_type ON /*_*/querycache_info (qci_type);
--------------------------------------------------------------------------------
-- Empty some cache tables to make the update faster
--------------------------------------------------------------------------------
DELETE FROM /*_*/querycache;
DELETE FROM /*_*/objectcache;
DELETE FROM /*_*/querycachetwo;
--------------------------------------------------------------------------------
-- Add indexes to tables with no unique indexes
--------------------------------------------------------------------------------
CREATE INDEX un_user_id ON /*_*/user_newtalk (user_id);
CREATE INDEX un_user_ip ON /*_*/user_newtalk (user_ip);
CREATE INDEX name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp);
CREATE INDEX ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp);
CREATE INDEX el_from ON /*_*/externallinks (el_from, el_to(40));
CREATE INDEX el_to ON /*_*/externallinks (el_to(60), el_from);
CREATE INDEX el_index ON /*_*/externallinks (el_index(60));
CREATE INDEX img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp);
CREATE INDEX img_size ON /*_*/image (img_size);
CREATE INDEX img_timestamp ON /*_*/image (img_timestamp);
CREATE INDEX img_sha1 ON /*_*/image (img_sha1);
CREATE INDEX oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp);
CREATE INDEX oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp);
CREATE INDEX oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name(14));
CREATE INDEX oi_sha1 ON /*_*/oldimage (oi_sha1);
CREATE INDEX fa_name ON /*_*/filearchive (fa_name, fa_timestamp);
CREATE INDEX fa_group_key ON /*_*/filearchive (fa_storage_group, fa_storage_key);
CREATE INDEX fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp);
CREATE INDEX fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp);
CREATE INDEX rc_timestamp ON /*_*/recentchanges (rc_timestamp);
CREATE INDEX rc_namespace_title ON /*_*/recentchanges (rc_namespace, rc_title);
CREATE INDEX rc_cur_id ON /*_*/recentchanges (rc_cur_id);
CREATE INDEX new_name_timestamp ON /*_*/recentchanges (rc_new,rc_namespace,rc_timestamp);
CREATE INDEX rc_ip ON /*_*/recentchanges (rc_ip);
CREATE INDEX rc_ns_usertext ON /*_*/recentchanges (rc_namespace, rc_user_text);
CREATE INDEX rc_user_text ON /*_*/recentchanges (rc_user_text, rc_timestamp);
CREATE INDEX qc_type_value ON /*_*/querycache (qc_type,qc_value);
CREATE INDEX oc_exptime ON /*_*/objectcache (exptime);
CREATE INDEX type_time ON /*_*/logging (log_type, log_timestamp);
CREATE INDEX user_time ON /*_*/logging (log_user, log_timestamp);
CREATE INDEX page_time ON /*_*/logging (log_namespace, log_title, log_timestamp);
CREATE INDEX times ON /*_*/logging (log_timestamp);
CREATE INDEX tb_page ON /*_*/trackbacks (tb_page);
CREATE INDEX job_cmd_namespace_title ON /*_*/job (job_cmd, job_namespace, job_title);
CREATE INDEX rd_ns_title ON /*_*/redirect (rd_namespace,rd_title,rd_from);
CREATE INDEX qcc_type ON /*_*/querycachetwo (qcc_type,qcc_value);
CREATE INDEX qcc_title ON /*_*/querycachetwo (qcc_type,qcc_namespace,qcc_title);
CREATE INDEX qcc_titletwo ON /*_*/querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo);
INSERT INTO /*_*/updatelog VALUES ('initial_indexes');

View file

@ -1,340 +0,0 @@
CREATE TABLE /*$wgDBprefix*/user (
user_id INTEGER PRIMARY KEY AUTOINCREMENT,
user_name varchar(255) default '',
user_real_name varchar(255) default '',
user_password tinyblob ,
user_newpassword tinyblob ,
user_newpass_time BLOB,
user_email tinytext ,
user_options blob ,
user_touched BLOB default '',
user_token BLOB default '',
user_email_authenticated BLOB,
user_email_token BLOB,
user_email_token_expires BLOB,
user_registration BLOB,
user_editcount int) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/user_groups (
ug_user INTEGER default '0',
ug_group varBLOB default '') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/user_newtalk (
user_id INTEGER default '0',
user_ip varBLOB default '',
user_last_timestamp BLOB default '') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/page (
page_id INTEGER PRIMARY KEY AUTOINCREMENT,
page_namespace INTEGER ,
page_title varchar(255) ,
page_restrictions tinyblob ,
page_counter bigint default '0',
page_is_redirect tinyint default '0',
page_is_new tinyint default '0',
page_random real ,
page_touched BLOB default '',
page_latest INTEGER ,
page_len INTEGER ) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/revision (
rev_id INTEGER PRIMARY KEY AUTOINCREMENT,
rev_page INTEGER ,
rev_text_id INTEGER ,
rev_comment tinyblob ,
rev_user INTEGER default '0',
rev_user_text varchar(255) default '',
rev_timestamp BLOB default '',
rev_minor_edit tinyint default '0',
rev_deleted tinyint default '0',
rev_len int,
rev_parent_id INTEGER default NULL) /*$wgDBTableOptions*/ ;
CREATE TABLE /*$wgDBprefix*/text (
old_id INTEGER PRIMARY KEY AUTOINCREMENT,
old_text mediumblob ,
old_flags tinyblob ) /*$wgDBTableOptions*/ ;
CREATE TABLE /*$wgDBprefix*/archive (
ar_namespace INTEGER default '0',
ar_title varchar(255) default '',
ar_text mediumblob ,
ar_comment tinyblob ,
ar_user INTEGER default '0',
ar_user_text varchar(255) ,
ar_timestamp BLOB default '',
ar_minor_edit tinyint default '0',
ar_flags tinyblob ,
ar_rev_id int,
ar_text_id int,
ar_deleted tinyint default '0',
ar_len int,
ar_page_id int,
ar_parent_id INTEGER default NULL) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/pagelinks (
pl_from INTEGER default '0',
pl_namespace INTEGER default '0',
pl_title varchar(255) default '') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/templatelinks (
tl_from INTEGER default '0',
tl_namespace INTEGER default '0',
tl_title varchar(255) default '') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/imagelinks (
il_from INTEGER default '0',
il_to varchar(255) default '') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/categorylinks (
cl_from INTEGER default '0',
cl_to varchar(255) default '',
cl_sortkey varchar(70) default '',
cl_timestamp timestamp ) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/category (
cat_id INTEGER PRIMARY KEY AUTOINCREMENT,
cat_title varchar(255) ,
cat_pages INTEGER signed default 0,
cat_subcats INTEGER signed default 0,
cat_files INTEGER signed default 0,
cat_hidden tinyint default 0) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/externallinks (
el_from INTEGER default '0',
el_to blob ,
el_index blob ) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/langlinks (
ll_from INTEGER default '0',
ll_lang varBLOB default '',
ll_title varchar(255) default '') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/site_stats (
ss_row_id INTEGER ,
ss_total_views bigint default '0',
ss_total_edits bigint default '0',
ss_good_articles bigint default '0',
ss_total_pages bigint default '-1',
ss_users bigint default '-1',
ss_admins INTEGER default '-1',
ss_images INTEGER default '0') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/hitcounter (
hc_id INTEGER
) ;
CREATE TABLE /*$wgDBprefix*/ipblocks (
ipb_id INTEGER PRIMARY KEY AUTOINCREMENT,
ipb_address tinyblob ,
ipb_user INTEGER default '0',
ipb_by INTEGER default '0',
ipb_by_text varchar(255) default '',
ipb_reason tinyblob ,
ipb_timestamp BLOB default '',
ipb_auto bool default 0,
ipb_anon_only bool default 0,
ipb_create_account bool default 1,
ipb_enable_autoblock bool default '1',
ipb_expiry varBLOB default '',
ipb_range_start tinyblob ,
ipb_range_end tinyblob ,
ipb_deleted bool default 0,
ipb_block_email bool default 0) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/image (
img_name varchar(255) default '',
img_size INTEGER default '0',
img_width INTEGER default '0',
img_height INTEGER default '0',
img_metadata mediumblob ,
img_bits INTEGER default '0',
img_media_type TEXT default NULL,
img_major_mime TEXT default "unknown",
img_minor_mime varBLOB default "unknown",
img_description tinyblob ,
img_user INTEGER default '0',
img_user_text varchar(255) ,
img_timestamp varBLOB default '',
img_sha1 varBLOB default '') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/oldimage (
oi_name varchar(255) default '',
oi_archive_name varchar(255) default '',
oi_size INTEGER default 0,
oi_width INTEGER default 0,
oi_height INTEGER default 0,
oi_bits INTEGER default 0,
oi_description tinyblob ,
oi_user INTEGER default '0',
oi_user_text varchar(255) ,
oi_timestamp BLOB default '',
oi_metadata mediumblob ,
oi_media_type TEXT default NULL,
oi_major_mime TEXT default "unknown",
oi_minor_mime varBLOB default "unknown",
oi_deleted tinyint default '0',
oi_sha1 varBLOB default '') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/filearchive (
fa_id INTEGER PRIMARY KEY AUTOINCREMENT,
fa_name varchar(255) default '',
fa_archive_name varchar(255) default '',
fa_storage_group varBLOB,
fa_storage_key varBLOB default '',
fa_deleted_user int,
fa_deleted_timestamp BLOB default '',
fa_deleted_reason text,
fa_size INTEGER default '0',
fa_width INTEGER default '0',
fa_height INTEGER default '0',
fa_metadata mediumblob,
fa_bits INTEGER default '0',
fa_media_type TEXT default NULL,
fa_major_mime TEXT default "unknown",
fa_minor_mime varBLOB default "unknown",
fa_description tinyblob,
fa_user INTEGER default '0',
fa_user_text varchar(255) ,
fa_timestamp BLOB default '',
fa_deleted tinyint default '0') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/recentchanges (
rc_id INTEGER PRIMARY KEY AUTOINCREMENT,
rc_timestamp varBLOB default '',
rc_cur_time varBLOB default '',
rc_user INTEGER default '0',
rc_user_text varchar(255) ,
rc_namespace INTEGER default '0',
rc_title varchar(255) default '',
rc_comment varchar(255) default '',
rc_minor tinyint default '0',
rc_bot tinyint default '0',
rc_new tinyint default '0',
rc_cur_id INTEGER default '0',
rc_this_oldid INTEGER default '0',
rc_last_oldid INTEGER default '0',
rc_type tinyint default '0',
rc_moved_to_ns tinyint default '0',
rc_moved_to_title varchar(255) default '',
rc_patrolled tinyint default '0',
rc_ip varBLOB default '',
rc_old_len int,
rc_new_len int,
rc_deleted tinyint default '0',
rc_logid INTEGER default '0',
rc_log_type varBLOB NULL default NULL,
rc_log_action varBLOB NULL default NULL,
rc_params blob NULL) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/watchlist (
wl_user INTEGER ,
wl_namespace INTEGER default '0',
wl_title varchar(255) default '',
wl_notificationtimestamp varBLOB) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/math (
math_inputhash varBLOB ,
math_outputhash varBLOB ,
math_html_conservativeness tinyint ,
math_html text,
math_mathml text) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/searchindex (
si_page INTEGER ,
si_title varchar(255) default '',
si_text mediumtext ) ;
CREATE TABLE /*$wgDBprefix*/interwiki (
iw_prefix varchar(32) ,
iw_url blob ,
iw_local bool ,
iw_trans tinyint default 0) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/querycache (
qc_type varBLOB ,
qc_value INTEGER default '0',
qc_namespace INTEGER default '0',
qc_title varchar(255) default '') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/objectcache (
keyname varBLOB default '',
value mediumblob,
exptime datetime) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/transcache (
tc_url varBLOB ,
tc_contents text,
tc_time INTEGER ) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/logging (
log_id INTEGER PRIMARY KEY AUTOINCREMENT,
log_type varBLOB default '',
log_action varBLOB default '',
log_timestamp BLOB default '19700101000000',
log_user INTEGER default 0,
log_namespace INTEGER default 0,
log_title varchar(255) default '',
log_comment varchar(255) default '',
log_params blob ,
log_deleted tinyint default '0') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/trackbacks (
tb_id INTEGER PRIMARY KEY AUTOINCREMENT,
tb_page INTEGER REFERENCES /*$wgDBprefix*/page(page_id) ON DELETE CASCADE,
tb_title varchar(255) ,
tb_url blob ,
tb_ex text,
tb_name varchar(255)) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/job (
job_id INTEGER PRIMARY KEY AUTOINCREMENT,
job_cmd varBLOB default '',
job_namespace INTEGER ,
job_title varchar(255) ,
job_params blob ) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/querycache_info (
qci_type varBLOB default '',
qci_timestamp BLOB default '19700101000000') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/redirect (
rd_from INTEGER default '0',
rd_namespace INTEGER default '0',
rd_title varchar(255) default '') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/querycachetwo (
qcc_type varBLOB ,
qcc_value INTEGER default '0',
qcc_namespace INTEGER default '0',
qcc_title varchar(255) default '',
qcc_namespacetwo INTEGER default '0',
qcc_titletwo varchar(255) default '') /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/page_restrictions (
pr_page INTEGER ,
pr_type varBLOB ,
pr_level varBLOB ,
pr_cascade tinyint ,
pr_user INTEGER NULL,
pr_expiry varBLOB NULL,
pr_id INTEGER PRIMARY KEY AUTOINCREMENT) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/protected_titles (
pt_namespace INTEGER ,
pt_title varchar(255) ,
pt_user INTEGER ,
pt_reason tinyblob,
pt_timestamp BLOB ,
pt_expiry varBLOB default '',
pt_create_perm varBLOB ) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/page_props (
pp_page INTEGER ,
pp_propname varBLOB ,
pp_value blob ) /*$wgDBTableOptions*/;
CREATE TABLE /*$wgDBprefix*/updatelog (
ul_key varchar(255) ) /*$wgDBTableOptions*/;

File diff suppressed because it is too large Load diff

View file

@ -16,138 +16,148 @@ require_once 'deleteDefaultMessages.php';
require_once( "$IP/includes/Hooks.php" );
/**
* List of update functions to call on a MySQL-based MediaWiki installation,
* in sequence. First item is function name, rest are parameters to pass.
* List of update functions to call for each DB type, in sequence. First item
* is function name, rest are parameters to pass.
*/
$wgMysqlUpdates = array(
// 1.2
// update_passwords obsolete
array( 'add_field', 'ipblocks', 'ipb_id', 'patch-ipblocks.sql' ),
array( 'add_field', 'ipblocks', 'ipb_expiry', 'patch-ipb_expiry.sql' ),
array( 'do_interwiki_update' ),
array( 'do_index_update' ),
// do_linkscc_update obsolete
array( 'add_table', 'hitcounter', 'patch-hitcounter.sql' ),
array( 'add_field', 'recentchanges', 'rc_type', 'patch-rc_type.sql' ),
// 1.3
array( 'add_field', 'user', 'user_real_name', 'patch-user-realname.sql' ),
array( 'add_table', 'querycache', 'patch-querycache.sql' ),
array( 'add_table', 'objectcache', 'patch-objectcache.sql' ),
array( 'add_table', 'categorylinks', 'patch-categorylinks.sql' ),
// do_linkscc_1_3_update obsolete
array( 'do_old_links_update' ),
array( 'add_field', 'recentchanges', 'rc_ip', 'patch-rc_ip.sql' ),
// 1.4
array( 'do_image_name_unique_update' ),
array( 'add_field', 'recentchanges', 'rc_id', 'patch-rc_id.sql' ),
array( 'add_field', 'recentchanges', 'rc_patrolled', 'patch-rc-patrol.sql' ),
array( 'add_table', 'logging', 'patch-logging.sql' ),
// do_user_rights_update obsolete
array( 'add_field', 'user', 'user_token', 'patch-user_token.sql' ),
// old, old_articleid, patch-remove-old-title-namespace.sql obsolete
// user_groups, patch-userlevels.sql obsolete
// do_group_update() obsolete
array( 'do_watchlist_update' ),
array( 'do_user_update' ),
// do_copy_newtalk_to_watchlist obsolete
// 1.5
array( 'do_schema_restructuring' ),
array( 'add_field', 'logging', 'log_params', 'patch-log_params.sql' ),
array( 'check_bin', 'logging', 'log_title', 'patch-logging-title.sql', ),
array( 'add_field', 'archive', 'ar_rev_id', 'patch-archive-rev_id.sql' ),
array( 'add_field', 'page', 'page_len', 'patch-page_len.sql' ),
array( 'do_inverse_timestamp' ),
array( 'do_text_id' ),
array( 'add_field', 'revision', 'rev_deleted', 'patch-rev_deleted.sql' ),
array( 'add_field', 'image', 'img_width', 'patch-img_width.sql' ),
array( 'add_field', 'image', 'img_metadata', 'patch-img_metadata.sql' ),
array( 'add_field', 'user', 'user_email_token', 'patch-user_email_token.sql' ),
array( 'add_field', 'archive', 'ar_text_id', 'patch-archive-text_id.sql' ),
array( 'do_namespace_size' ),
array( 'add_field', 'image', 'img_media_type', 'patch-img_media_type.sql' ),
array( 'do_pagelinks_update' ),
array( 'do_drop_img_type' ),
array( 'do_user_unique_update' ),
array( 'do_user_groups_update' ),
array( 'add_field', 'site_stats', 'ss_total_pages', 'patch-ss_total_articles.sql' ),
array( 'add_table', 'user_newtalk', 'patch-usernewtalk2.sql' ),
array( 'add_table', 'transcache', 'patch-transcache.sql' ),
array( 'add_field', 'interwiki', 'iw_trans', 'patch-interwiki-trans.sql' ),
array( 'add_table', 'trackbacks', 'patch-trackbacks.sql' ),
// 1.6
array( 'do_watchlist_null' ),
// do_image_index_update obsolete
array( 'do_logging_timestamp_index' ),
array( 'add_field', 'ipblocks', 'ipb_range_start', 'patch-ipb_range_start.sql' ),
array( 'do_page_random_update' ),
array( 'add_field', 'user', 'user_registration','patch-user_registration.sql' ),
array( 'do_templatelinks_update' ),
array( 'add_table', 'externallinks', 'patch-externallinks.sql' ),
array( 'add_table', 'job', 'patch-job.sql' ),
array( 'add_field', 'site_stats', 'ss_images', 'patch-ss_images.sql' ),
array( 'add_table', 'langlinks', 'patch-langlinks.sql' ),
array( 'add_table', 'querycache_info', 'patch-querycacheinfo.sql' ),
array( 'add_table', 'filearchive', 'patch-filearchive.sql' ),
array( 'add_field', 'ipblocks', 'ipb_anon_only', 'patch-ipb_anon_only.sql' ),
array( 'do_rc_indices_update' ),
// 1.9
array( 'add_field', 'user', 'user_newpass_time', 'patch-user_newpass_time.sql' ),
array( 'add_table', 'redirect', 'patch-redirect.sql' ),
array( 'add_table', 'querycachetwo', 'patch-querycachetwo.sql' ),
array( 'add_field', 'ipblocks', 'ipb_enable_autoblock', 'patch-ipb_optional_autoblock.sql' ),
array( 'do_backlinking_indices_update' ),
array( 'add_field', 'recentchanges', 'rc_old_len', 'patch-rc_len.sql' ),
array( 'add_field', 'user', 'user_editcount', 'patch-user_editcount.sql' ),
// 1.10
array( 'do_restrictions_update' ),
array( 'add_field', 'logging', 'log_id', 'patch-log_id.sql' ),
array( 'add_field', 'revision', 'rev_parent_id', 'patch-rev_parent_id.sql' ),
array( 'add_field', 'page_restrictions', 'pr_id', 'patch-page_restrictions_sortkey.sql' ),
array( 'add_field', 'revision', 'rev_len', 'patch-rev_len.sql' ),
array( 'add_field', 'recentchanges', 'rc_deleted', 'patch-rc_deleted.sql' ),
array( 'add_field', 'logging', 'log_deleted', 'patch-log_deleted.sql' ),
array( 'add_field', 'archive', 'ar_deleted', 'patch-ar_deleted.sql' ),
array( 'add_field', 'ipblocks', 'ipb_deleted', 'patch-ipb_deleted.sql' ),
array( 'add_field', 'filearchive', 'fa_deleted', 'patch-fa_deleted.sql' ),
array( 'add_field', 'archive', 'ar_len', 'patch-ar_len.sql' ),
// 1.11
array( 'add_field', 'ipblocks', 'ipb_block_email', 'patch-ipb_emailban.sql' ),
array( 'do_categorylinks_indices_update' ),
array( 'add_field', 'oldimage', 'oi_metadata', 'patch-oi_metadata.sql'),
array( 'do_archive_user_index' ),
array( 'do_image_user_index' ),
array( 'do_oldimage_user_index' ),
array( 'add_field', 'archive', 'ar_page_id', 'patch-archive-page_id.sql'),
array( 'add_field', 'image', 'img_sha1', 'patch-img_sha1.sql' ),
$wgUpdates = array(
'mysql' => array(
// 1.2
// update_passwords obsolete
array( 'add_field', 'ipblocks', 'ipb_id', 'patch-ipblocks.sql' ),
array( 'add_field', 'ipblocks', 'ipb_expiry', 'patch-ipb_expiry.sql' ),
array( 'do_interwiki_update' ),
array( 'do_index_update' ),
// do_linkscc_update obsolete
array( 'add_table', 'hitcounter', 'patch-hitcounter.sql' ),
array( 'add_field', 'recentchanges', 'rc_type', 'patch-rc_type.sql' ),
// 1.3
array( 'add_field', 'user', 'user_real_name', 'patch-user-realname.sql' ),
array( 'add_table', 'querycache', 'patch-querycache.sql' ),
array( 'add_table', 'objectcache', 'patch-objectcache.sql' ),
array( 'add_table', 'categorylinks', 'patch-categorylinks.sql' ),
// do_linkscc_1_3_update obsolete
array( 'do_old_links_update' ),
array( 'add_field', 'recentchanges', 'rc_ip', 'patch-rc_ip.sql' ),
// 1.4
array( 'do_image_name_unique_update' ),
array( 'add_field', 'recentchanges', 'rc_id', 'patch-rc_id.sql' ),
array( 'add_field', 'recentchanges', 'rc_patrolled', 'patch-rc-patrol.sql' ),
array( 'add_table', 'logging', 'patch-logging.sql' ),
// do_user_rights_update obsolete
array( 'add_field', 'user', 'user_token', 'patch-user_token.sql' ),
// old, old_articleid, patch-remove-old-title-namespace.sql obsolete
// user_groups, patch-userlevels.sql obsolete
// do_group_update() obsolete
array( 'do_watchlist_update' ),
array( 'do_user_update' ),
// do_copy_newtalk_to_watchlist obsolete
// 1.5
array( 'do_schema_restructuring' ),
array( 'add_field', 'logging', 'log_params', 'patch-log_params.sql' ),
array( 'check_bin', 'logging', 'log_title', 'patch-logging-title.sql', ),
array( 'add_field', 'archive', 'ar_rev_id', 'patch-archive-rev_id.sql' ),
array( 'add_field', 'page', 'page_len', 'patch-page_len.sql' ),
array( 'do_inverse_timestamp' ),
array( 'do_text_id' ),
array( 'add_field', 'revision', 'rev_deleted', 'patch-rev_deleted.sql' ),
array( 'add_field', 'image', 'img_width', 'patch-img_width.sql' ),
array( 'add_field', 'image', 'img_metadata', 'patch-img_metadata.sql' ),
array( 'add_field', 'user', 'user_email_token', 'patch-user_email_token.sql' ),
array( 'add_field', 'archive', 'ar_text_id', 'patch-archive-text_id.sql' ),
array( 'do_namespace_size' ),
array( 'add_field', 'image', 'img_media_type', 'patch-img_media_type.sql' ),
array( 'do_pagelinks_update' ),
array( 'do_drop_img_type' ),
array( 'do_user_unique_update' ),
array( 'do_user_groups_update' ),
array( 'add_field', 'site_stats', 'ss_total_pages', 'patch-ss_total_articles.sql' ),
array( 'add_table', 'user_newtalk', 'patch-usernewtalk2.sql' ),
array( 'add_table', 'transcache', 'patch-transcache.sql' ),
array( 'add_field', 'interwiki', 'iw_trans', 'patch-interwiki-trans.sql' ),
array( 'add_table', 'trackbacks', 'patch-trackbacks.sql' ),
// 1.6
array( 'do_watchlist_null' ),
// do_image_index_update obsolete
array( 'do_logging_timestamp_index' ),
array( 'add_field', 'ipblocks', 'ipb_range_start', 'patch-ipb_range_start.sql' ),
array( 'do_page_random_update' ),
array( 'add_field', 'user', 'user_registration','patch-user_registration.sql' ),
array( 'do_templatelinks_update' ),
array( 'add_table', 'externallinks', 'patch-externallinks.sql' ),
array( 'add_table', 'job', 'patch-job.sql' ),
array( 'add_field', 'site_stats', 'ss_images', 'patch-ss_images.sql' ),
array( 'add_table', 'langlinks', 'patch-langlinks.sql' ),
array( 'add_table', 'querycache_info', 'patch-querycacheinfo.sql' ),
array( 'add_table', 'filearchive', 'patch-filearchive.sql' ),
array( 'add_field', 'ipblocks', 'ipb_anon_only', 'patch-ipb_anon_only.sql' ),
array( 'do_rc_indices_update' ),
// 1.9
array( 'add_field', 'user', 'user_newpass_time', 'patch-user_newpass_time.sql' ),
array( 'add_table', 'redirect', 'patch-redirect.sql' ),
array( 'add_table', 'querycachetwo', 'patch-querycachetwo.sql' ),
array( 'add_field', 'ipblocks', 'ipb_enable_autoblock', 'patch-ipb_optional_autoblock.sql' ),
array( 'do_backlinking_indices_update' ),
array( 'add_field', 'recentchanges', 'rc_old_len', 'patch-rc_len.sql' ),
array( 'add_field', 'user', 'user_editcount', 'patch-user_editcount.sql' ),
// 1.10
array( 'do_restrictions_update' ),
array( 'add_field', 'logging', 'log_id', 'patch-log_id.sql' ),
array( 'add_field', 'revision', 'rev_parent_id', 'patch-rev_parent_id.sql' ),
array( 'add_field', 'page_restrictions', 'pr_id', 'patch-page_restrictions_sortkey.sql' ),
array( 'add_field', 'revision', 'rev_len', 'patch-rev_len.sql' ),
array( 'add_field', 'recentchanges', 'rc_deleted', 'patch-rc_deleted.sql' ),
array( 'add_field', 'logging', 'log_deleted', 'patch-log_deleted.sql' ),
array( 'add_field', 'archive', 'ar_deleted', 'patch-ar_deleted.sql' ),
array( 'add_field', 'ipblocks', 'ipb_deleted', 'patch-ipb_deleted.sql' ),
array( 'add_field', 'filearchive', 'fa_deleted', 'patch-fa_deleted.sql' ),
array( 'add_field', 'archive', 'ar_len', 'patch-ar_len.sql' ),
// 1.11
array( 'add_field', 'ipblocks', 'ipb_block_email', 'patch-ipb_emailban.sql' ),
array( 'do_categorylinks_indices_update' ),
array( 'add_field', 'oldimage', 'oi_metadata', 'patch-oi_metadata.sql'),
array( 'do_archive_user_index' ),
array( 'do_image_user_index' ),
array( 'do_oldimage_user_index' ),
array( 'add_field', 'archive', 'ar_page_id', 'patch-archive-page_id.sql'),
array( 'add_field', 'image', 'img_sha1', 'patch-img_sha1.sql' ),
// 1.12
array( 'add_table', 'protected_titles', 'patch-protected_titles.sql' ),
// 1.13
array( 'add_field', 'ipblocks', 'ipb_by_text', 'patch-ipb_by_text.sql' ),
array( 'add_table', 'page_props', 'patch-page_props.sql' ),
array( 'add_table', 'updatelog', 'patch-updatelog.sql' ),
array( 'add_table', 'category', 'patch-category.sql' ),
array( 'do_category_population' ),
array( 'add_field', 'archive', 'ar_parent_id', 'patch-ar_parent_id.sql'),
array( 'add_field', 'user_newtalk', 'user_last_timestamp', 'patch-user_last_timestamp.sql'),
array( 'do_populate_parent_id' ),
array( 'check_bin', 'protected_titles', 'pt_title', 'patch-pt_title-encoding.sql', ),
array( 'maybe_do_profiling_memory_update' ),
array( 'do_filearchive_indices_update' ),
array( 'update_password_format' ),
// 1.14
array( 'add_field', 'site_stats', 'ss_active_users', 'patch-ss_active_users.sql' ),
array( 'do_active_users_init' ),
array( 'add_field', 'ipblocks', 'ipb_allow_usertalk', 'patch-ipb_allow_usertalk.sql' )
// 1.12
array( 'add_table', 'protected_titles', 'patch-protected_titles.sql' ),
// 1.13
array( 'add_field', 'ipblocks', 'ipb_by_text', 'patch-ipb_by_text.sql' ),
array( 'add_table', 'page_props', 'patch-page_props.sql' ),
array( 'add_table', 'updatelog', 'patch-updatelog.sql' ),
array( 'add_table', 'category', 'patch-category.sql' ),
array( 'do_category_population' ),
array( 'add_field', 'archive', 'ar_parent_id', 'patch-ar_parent_id.sql'),
array( 'add_field', 'user_newtalk', 'user_last_timestamp', 'patch-user_last_timestamp.sql'),
array( 'do_populate_parent_id' ),
array( 'check_bin', 'protected_titles', 'pt_title', 'patch-pt_title-encoding.sql', ),
array( 'maybe_do_profiling_memory_update' ),
array( 'do_filearchive_indices_update' ),
array( 'update_password_format' ),
// 1.14
array( 'add_field', 'site_stats', 'ss_active_users', 'patch-ss_active_users.sql' ),
array( 'do_active_users_init' ),
array( 'add_field', 'ipblocks', 'ipb_allow_usertalk', 'patch-ipb_allow_usertalk.sql' ),
),
'sqlite' => array(
// 1.14
array( 'add_field', 'site_stats', 'ss_active_users', 'patch-ss_active_users.sql' ),
array( 'do_active_users_init' ),
array( 'add_field', 'ipblocks', 'ipb_allow_usertalk', 'patch-ipb_allow_usertalk.sql' ),
array( 'sqlite_initial_indexes' ),
),
);
@ -1070,11 +1080,13 @@ function do_all_updates( $shared = false, $purge = true ) {
}
# Run core updates in sequence...
global $wgMysqlUpdates;
foreach( $wgMysqlUpdates as $params ) {
$func = array_shift( $params );
call_user_func_array( $func, $params );
flush();
global $wgUpdates;
if ( isset( $wgUpdates[$wgDBtype] ) ) {
foreach( $wgUpdates[$wgDBtype] as $params ) {
$func = array_shift( $params );
call_user_func_array( $func, $params );
flush();
}
}
/// @fixme clean up this mess too!
@ -1112,10 +1124,9 @@ function do_all_updates( $shared = false, $purge = true ) {
function archive($name) {
global $wgDBtype, $IP;
switch ($wgDBtype) {
case "postgres":
return "$IP/maintenance/postgres/archives/$name";
default:
if ( file_exists( "$IP/maintenance/$wgDBtype/archives/$name" ) ) {
return "$IP/maintenance/$wgDBtype/archives/$name";
} else {
return "$IP/maintenance/archives/$name";
}
}
@ -1243,6 +1254,23 @@ function update_password_format() {
echo "done\n";
}
function sqlite_initial_indexes() {
global $wgDatabase;
if ( update_row_exists( 'initial_indexes' ) ) {
echo "...have initial indexes\n";
return;
}
echo "Adding initial indexes...";
$wgDatabase->sourceFile( archive( 'initial-indexes.sql' ) );
echo "done\n";
}
/***********************************************************************
* Start PG crap
* TODO: merge with above
***********************************************************************/
function
pg_describe_table($table)
{