<rule ref="MediaWiki.NamingConventions.PrefixedGlobalFunctions">
<properties>
<!--
- includes/compat/normal/UtfNormalUtil.php
- * codepointToUtf8
- * escapeSingleString
- * hexSequenceToUtf8
- * utf8ToCodepoint
- * utf8ToHexSequence
includes/GlobalFunctions.php
* mimeTypeMatch
- maintenance/benchmarks/bench_strtr_str_replace.php
- * bfNormalizeTitleStrReplace
- * bfNormalizeTitleStrTr
maintenance/cdb.php
* cdbShowHelp
maintenance/language/transstat.php
tests/qunit/data/styleTest.css.php
* cssfilter
-->
- <property name="ignoreList" type="array" value="bfNormalizeTitleStrReplace,bfNormalizeTitleStrTr,cdbShowHelp,codepointToUtf8,compare_point,cssfilter,escapeSingleString,getEscapedProfileUrl,hexSequenceToUtf8,mccGetHelp,mccShowUsage,mimeTypeMatch,moveToExternal,NothingFunction,NothingFunctionData,resolveStub,resolveStubs,showUsage,utf8ToCodepoint,utf8ToHexSequence" />
+ <property name="ignoreList" type="array" value="cdbShowHelp,compare_point,cssfilter,getEscapedProfileUrl,mccGetHelp,mccShowUsage,mimeTypeMatch,moveToExternal,NothingFunction,NothingFunctionData,resolveStub,resolveStubs,showUsage" />
</properties>
</rule>
<rule ref="MediaWiki.NamingConventions.ValidGlobalName">
<exclude-pattern>*/maintenance/benchmarks/bench_Wikimedia_base_convert\.php</exclude-pattern>
<exclude-pattern>*/maintenance/benchmarks/bench_delete_truncate\.php</exclude-pattern>
<exclude-pattern>*/maintenance/benchmarks/bench_if_switch\.php</exclude-pattern>
- <exclude-pattern>*/maintenance/benchmarks/bench_strtr_str_replace\.php</exclude-pattern>
<exclude-pattern>*/maintenance/benchmarks/bench_utf8_title_check\.php</exclude-pattern>
<exclude-pattern>*/maintenance/benchmarks/bench_wfIsWindows\.php</exclude-pattern>
<exclude-pattern>*/maintenance/cleanupTable.inc</exclude-pattern>
<exclude-pattern>*/includes/HistoryBlob\.php</exclude-pattern>
<exclude-pattern>*/includes/htmlform/HTMLFormElement\.php</exclude-pattern>
<exclude-pattern>*/includes/jobqueue/aggregator/JobQueueAggregator\.php</exclude-pattern>
- <exclude-pattern>*/includes/jobqueue/JobQueue\.php</exclude-pattern>
<exclude-pattern>*/includes/libs/filebackend/FileBackendStore\.php</exclude-pattern>
<exclude-pattern>*/includes/libs/filebackend/FSFileBackend\.php</exclude-pattern>
<exclude-pattern>*/includes/libs/filebackend/SwiftFileBackend\.php</exclude-pattern>
IP addresses, internationalized domain names, and possibly mailto links.
* (T193868) $wgChangeTagsSchemaMigrationStage — This temporary setting, added in
MediaWiki 1.32, now defaults to MIGRATION_NEW instead of MIGRATION_WRITE_BOTH.
+* Special:ActiveUsers will no longer filter out users who became inactive since
+ the last time the active users query cache was updated.
==== Removed configuration ====
* (T199334) $wgTagStatisticsNewTable — This temporary setting, added in
* $wgEnableParserCache, deprecated since 1.26, was removed.
If disabling the parser cache is still desirable,
set `$wgParserCacheType = CACHE_NONE;` instead.
+* $wgCommentTableSchemaMigrationStage has been removed. Extension code finding
+ it unset should treat it as being MIGRATION_NEW.
=== New features in 1.33 ===
* (T96041) __EXPECTUNUSEDCATEGORY__ on a category page causes the category
==== Changed external libraries ====
* Updated OOUI from v0.29.2 to v0.30.2.
+* Updated OOjs Router from pre-release to v0.2.0.
* Updated wikimedia/xmp-reader from 0.6.0 to 0.6.1.
* Updated wikimedia/scoped-callback from 2.0.0 to 3.0.0.
* Updated wikimedia/ip-set from 1.2.0 to 2.0.0.
* (T126091) The 'ResourceLoaderTestModules' hook, which lets you declare QUnit
testing code for your JavaScript modules, is deprecated. Instead, you can now
use the new extension registration key 'QUnitTestModule'.
+* (T213426) The jquery.throttle-debounce module has been deprecated. JavaScript
+ code that needs this behaviour should use OO.ui.debounce/throttle.
=== Other changes in 1.33 ===
* (T208871) The hard-coded Google search form on the database error page was
'JobQueueAggregator' => __DIR__ . '/includes/jobqueue/aggregator/JobQueueAggregator.php',
'JobQueueAggregatorNull' => __DIR__ . '/includes/jobqueue/aggregator/JobQueueAggregator.php',
'JobQueueAggregatorRedis' => __DIR__ . '/includes/jobqueue/aggregator/JobQueueAggregatorRedis.php',
- 'JobQueueConnectionError' => __DIR__ . '/includes/jobqueue/JobQueue.php',
+ 'JobQueueConnectionError' => __DIR__ . '/includes/jobqueue/exception/JobQueueConnectionError.php',
'JobQueueDB' => __DIR__ . '/includes/jobqueue/JobQueueDB.php',
'JobQueueEnqueueUpdate' => __DIR__ . '/includes/deferred/JobQueueEnqueueUpdate.php',
- 'JobQueueError' => __DIR__ . '/includes/jobqueue/JobQueue.php',
+ 'JobQueueError' => __DIR__ . '/includes/jobqueue/exception/JobQueueError.php',
'JobQueueFederated' => __DIR__ . '/includes/jobqueue/JobQueueFederated.php',
'JobQueueGroup' => __DIR__ . '/includes/jobqueue/JobQueueGroup.php',
'JobQueueMemory' => __DIR__ . '/includes/jobqueue/JobQueueMemory.php',
- 'JobQueueReadOnlyError' => __DIR__ . '/includes/jobqueue/JobQueue.php',
+ 'JobQueueReadOnlyError' => __DIR__ . '/includes/jobqueue/exception/JobQueueReadOnlyError.php',
'JobQueueRedis' => __DIR__ . '/includes/jobqueue/JobQueueRedis.php',
'JobRunner' => __DIR__ . '/includes/jobqueue/JobRunner.php',
'JobSpecification' => __DIR__ . '/includes/jobqueue/JobSpecification.php',
*/
protected $key = null;
- /** @var int One of the MIGRATION_* constants */
+ /**
+ * @var int One of the MIGRATION_* constants
+ * @todo Deprecate and remove once extensions seem unlikely to need to use
+ * it for migration anymore.
+ */
protected $stage;
/** @var array[] Cache for `self::getJoin()` */
/**
* @param Language $lang Language to use for comment truncation. Defaults
* to content language.
- * @param int $migrationStage One of the MIGRATION_* constants
+ * @param int $migrationStage One of the MIGRATION_* constants. Always
+ * MIGRATION_NEW for MediaWiki core since 1.33.
*/
public function __construct( Language $lang, $migrationStage ) {
$this->stage = $migrationStage;
* @return CommentStore
*/
public static function newKey( $key ) {
- global $wgCommentTableSchemaMigrationStage;
wfDeprecated( __METHOD__, '1.31' );
- $store = new CommentStore( MediaWikiServices::getInstance()->getContentLanguage(),
- $wgCommentTableSchemaMigrationStage );
+ $store = new CommentStore(
+ MediaWikiServices::getInstance()->getContentLanguage(), MIGRATION_NEW
+ );
$store->key = $key;
return $store;
}
*/
$wgInterwikiPrefixDisplayTypes = [];
-/**
- * Comment table schema migration stage.
- * @since 1.30
- * @var int One of the MIGRATION_* constants
- */
-$wgCommentTableSchemaMigrationStage = MIGRATION_NEW;
-
/**
* RevisionStore table schema migration stage (content, slots, content_models & slot_roles tables).
* Use the SCHEMA_COMPAT_XXX flags. Supported values:
* @return array
*/
private function getSummaryInputAttributes( array $inputAttrs = null ) {
- $conf = $this->context->getConfig();
- $oldCommentSchema = $conf->get( 'CommentTableSchemaMigrationStage' ) === MIGRATION_OLD;
// HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
// (e.g. emojis) count for two each. This limit is overridden in JS to instead count
- // Unicode codepoints (or 255 UTF-8 bytes for old schema).
+ // Unicode codepoints.
return ( is_array( $inputAttrs ) ? $inputAttrs : [] ) + [
'id' => 'wpSummary',
'name' => 'wpSummary',
- 'maxlength' => $oldCommentSchema ? 200 : CommentStore::COMMENT_CHARACTER_LIMIT,
+ 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
'tabindex' => 1,
'size' => 60,
'spellcheck' => 'true',
private function showForm() {
global $wgOut, $wgUser, $wgRequest;
- $conf = RequestContext::getMain()->getConfig();
- $oldCommentSchema = $conf->get( 'CommentTableSchemaMigrationStage' ) === MIGRATION_OLD;
-
$wgOut->addModules( 'mediawiki.action.delete.file' );
$checkWatch = $wgUser->getBoolOption( 'watchdeletion' ) || $wgUser->isWatched( $this->title );
// HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
// (e.g. emojis) count for two each. This limit is overridden in JS to instead count
- // Unicode codepoints (or 255 UTF-8 bytes for old schema).
+ // Unicode codepoints.
$fields[] = new OOUI\FieldLayout(
new OOUI\TextInputWidget( [
'name' => 'wpReason',
'inputId' => 'wpReason',
'tabIndex' => 2,
- 'maxLength' => $oldCommentSchema ? 255 : CommentStore::COMMENT_CHARACTER_LIMIT,
+ 'maxLength' => CommentStore::COMMENT_CHARACTER_LIMIT,
'infusable' => true,
'value' => $wgRequest->getText( 'wpReason' ),
'autofocus' => true,
$lang = $context->getLanguage();
$conf = $context->getConfig();
$cascadingRestrictionLevels = $conf->get( 'CascadingRestrictionLevels' );
- $oldCommentSchema = $conf->get( 'CommentTableSchemaMigrationStage' ) === MIGRATION_OLD;
$out = '';
if ( !$this->disabled ) {
$output->addModules( 'mediawiki.legacy.protect' );
// HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
// (e.g. emojis) count for two each. This limit is overridden in JS to instead count
- // Unicode codepoints (or 180 UTF-8 bytes for old schema).
+ // Unicode codepoints.
// Subtract arbitrary 75 to leave some space for the autogenerated null edit's summary
// and other texts chosen by dropdown menus on this page.
- $maxlength = $oldCommentSchema ? 180 : CommentStore::COMMENT_CHARACTER_LIMIT - 75;
+ $maxlength = CommentStore::COMMENT_CHARACTER_LIMIT - 75;
$out .= Xml::openElement( 'table', [ 'id' => 'mw-protect-table3' ] ) .
Xml::openElement( 'tbody' );
'CommentStore' => function ( MediaWikiServices $services ) : CommentStore {
return new CommentStore(
$services->getContentLanguage(),
- $services->getMainConfig()->get( 'CommentTableSchemaMigrationStage' )
+ MIGRATION_NEW
);
},
$infoMap = [];
// Make sure at least the current wiki is set, for simple configurations.
// This also makes it the first in the map, which is useful for common cases.
- $wikiId = self::getWikiIdFromDomain( self::getCurrentWikiDomain() );
+ $wikiId = self::getWikiIdFromDbDomain( self::getCurrentWikiDbDomain() );
$infoMap[$wikiId] = [
'url' => $wgCanonicalServer,
'parts' => wfParseUrl( $wgCanonicalServer )
*
* @param string|DatabaseDomain $domain
* @return string
+ * @since 1.31
*/
- public static function getWikiIdFromDomain( $domain ) {
+ public static function getWikiIdFromDbDomain( $domain ) {
$domain = DatabaseDomain::newFromId( $domain );
if ( !in_array( $domain->getSchema(), [ null, 'mediawiki' ], true ) ) {
: (string)$domain->getDatabase();
}
+ /**
+ * @param string $domain
+ * @return string
+ * @deprecated Since 1.33; use getWikiIdFromDbDomain()
+ */
+ public static function getWikiIdFromDomain( $domain ) {
+ return self::getWikiIdFromDbDomain( $domain );
+ }
+
/**
* @return DatabaseDomain Database domain of the current wiki
* @since 1.33
*/
- public static function getCurrentWikiDomain() {
+ public static function getCurrentWikiDbDomain() {
global $wgDBname, $wgDBmwschema, $wgDBprefix;
// Avoid invoking LBFactory to avoid any chance of recursion
return new DatabaseDomain( $wgDBname, $wgDBmwschema, (string)$wgDBprefix );
* @return bool Whether $domain has the same DB/prefix as the current wiki
* @since 1.33
*/
- public static function isCurrentWikiDomain( $domain ) {
+ public static function isCurrentWikiDbDomain( $domain ) {
$domain = DatabaseDomain::newFromId( $domain );
- $curDomain = self::getCurrentWikiDomain();
+ $curDomain = self::getCurrentWikiDbDomain();
if ( !in_array( $curDomain->getSchema(), [ null, 'mediawiki' ], true ) ) {
// Include the schema if it is set and is not the default placeholder.
* @since 1.33
*/
public static function isCurrentWikiId( $wikiId ) {
- return ( self::getWikiIdFromDomain( self::getCurrentWikiDomain() ) === $wikiId );
+ return ( self::getWikiIdFromDbDomain( self::getCurrentWikiDbDomain() ) === $wikiId );
}
}
protected function getFormFields() {
$request = $this->getRequest();
- $config = $this->context->getConfig();
- $oldCommentSchema = $config->get( 'CommentTableSchemaMigrationStage' ) === MIGRATION_OLD;
$ret = [
'diff' => [
'type' => 'info',
'name' => 'wpSummary',
'cssclass' => 'mw-summary',
'label-message' => 'summary',
- 'maxlength' => $oldCommentSchema ? 200 : CommentStore::COMMENT_CHARACTER_LIMIT,
+ 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
'value' => $request->getVal( 'wpSummary', '' ),
'size' => 60,
'spellcheck' => 'true',
$date = $d->format( 'D M j G:i:s T Y' );
$host = wfHostname();
- $wiki = WikiMap::getWikiIdFromDomain( WikiMap::getCurrentWikiDomain() );
+ $wiki = WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() );
$text = "{$date}\t{$host}\t{$wiki}\t{$message}\n";
return $text;
*/
protected static function formatAsWfDebugLog( $channel, $message, $context ) {
$time = wfTimestamp( TS_DB );
- $wiki = WikiMap::getWikiIdFromDomain( WikiMap::getCurrentWikiDomain() );
+ $wiki = WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() );
$host = wfHostname();
$text = "{$time} {$host} {$wiki}: {$message}\n";
return $text;
public function __invoke( array $record ) {
global $wgVersion;
$record['extra']['host'] = wfHostname();
- $record['extra']['wiki'] = WikiMap::getWikiIdFromDomain( WikiMap::getCurrentWikiDomain() );
+ $record['extra']['wiki'] = WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() );
$record['extra']['mwversion'] = $wgVersion;
$record['extra']['reqId'] = \WebRequest::getRequestId();
if ( wfIsCLI() && isset( $_SERVER['argv'] ) ) {
public function getAsJobSpecification() {
return [
- 'wiki' => WikiMap::getWikiIdFromDomain( $this->getDB()->getDomainID() ),
+ 'wiki' => WikiMap::getWikiIdFromDbDomain( $this->getDB()->getDomainID() ),
'job' => new JobSpecification(
'deleteLinks',
[ 'pageId' => $this->pageId, 'timestamp' => $this->timestamp ],
}
return [
- 'wiki' => WikiMap::getWikiIdFromDomain( $this->getDB()->getDomainID() ),
+ 'wiki' => WikiMap::getWikiIdFromDbDomain( $this->getDB()->getDomainID() ),
'job' => new JobSpecification(
'refreshLinksPrioritized',
[
*/
public static function singleton( $domain = false ) {
if ( $domain === false ) {
- $domain = WikiMap::getCurrentWikiDomain()->getId();
+ $domain = WikiMap::getCurrentWikiDbDomain()->getId();
}
if ( !isset( self::$instances[$domain] ) ) {
$oldver, $comment, $pageText, $props = false, $timestamp = false, $user = null, $tags = [],
$createNullRevision = true
) {
- global $wgCommentTableSchemaMigrationStage, $wgActorTableSchemaMigrationStage;
+ global $wgActorTableSchemaMigrationStage;
if ( is_null( $user ) ) {
global $wgUser;
'oi_width' => 'img_width',
'oi_height' => 'img_height',
'oi_bits' => 'img_bits',
+ 'oi_description_id' => 'img_description_id',
'oi_timestamp' => 'img_timestamp',
'oi_metadata' => 'img_metadata',
'oi_media_type' => 'img_media_type',
];
$joins = [];
- if ( $wgCommentTableSchemaMigrationStage <= MIGRATION_WRITE_BOTH ) {
- $fields['oi_description'] = 'img_description';
- }
- if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRITE_BOTH ) {
- $fields['oi_description_id'] = 'img_description_id';
- }
-
- if ( $wgCommentTableSchemaMigrationStage !== MIGRATION_OLD &&
- $wgCommentTableSchemaMigrationStage !== MIGRATION_NEW
- ) {
- // Upgrade any rows that are still old-style. Otherwise an upgrade
- // might be missed if a deletion happens while the migration script
- // is running.
- $res = $dbw->select(
- [ 'image' ],
- [ 'img_name', 'img_description' ],
- [
- 'img_name' => $this->getName(),
- 'img_description_id' => 0,
- ],
- __METHOD__
- );
- foreach ( $res as $row ) {
- $imgFields = $commentStore->insert( $dbw, 'img_description', $row->img_description );
- $dbw->update(
- 'image',
- $imgFields,
- [ 'img_name' => $row->img_name ],
- __METHOD__
- );
- }
- }
-
if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) {
$fields['oi_user'] = 'img_user';
$fields['oi_user_text'] = 'img_user_text';
}
protected function doDBInserts() {
- global $wgCommentTableSchemaMigrationStage, $wgActorTableSchemaMigrationStage;
+ global $wgActorTableSchemaMigrationStage;
$now = time();
$dbw = $this->file->repo->getMasterDB();
'fa_media_type' => 'img_media_type',
'fa_major_mime' => 'img_major_mime',
'fa_minor_mime' => 'img_minor_mime',
+ 'fa_description_id' => 'img_description_id',
'fa_timestamp' => 'img_timestamp',
'fa_sha1' => 'img_sha1'
];
$commentStore->insert( $dbw, 'fa_deleted_reason', $this->reason )
);
- if ( $wgCommentTableSchemaMigrationStage <= MIGRATION_WRITE_BOTH ) {
- $fields['fa_description'] = 'img_description';
- }
- if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRITE_BOTH ) {
- $fields['fa_description_id'] = 'img_description_id';
- }
-
- if ( $wgCommentTableSchemaMigrationStage !== MIGRATION_OLD &&
- $wgCommentTableSchemaMigrationStage !== MIGRATION_NEW
- ) {
- // Upgrade any rows that are still old-style. Otherwise an upgrade
- // might be missed if a deletion happens while the migration script
- // is running.
- $res = $dbw->select(
- [ 'image' ],
- [ 'img_name', 'img_description' ],
- [
- 'img_name' => $this->file->getName(),
- 'img_description_id' => 0,
- ],
- __METHOD__
- );
- foreach ( $res as $row ) {
- $imgFields = $commentStore->insert( $dbw, 'img_description', $row->img_description );
- $dbw->update(
- 'image',
- $imgFields,
- [ 'img_name' => $row->img_name ],
- __METHOD__
- );
- }
- }
-
if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) {
$fields['fa_user'] = 'img_user';
$fields['fa_user_text'] = 'img_user_text';
* @since 1.30
*/
protected function migrateComments() {
- global $wgCommentTableSchemaMigrationStage;
- if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRITE_NEW &&
- !$this->updateRowExists( 'MigrateComments' )
- ) {
+ if ( !$this->updateRowExists( 'MigrateComments' ) ) {
$this->output(
"Migrating comments to the 'comments' table, printing progress markers. For large\n" .
"databases, you may want to hit Ctrl-C and do this manually with\n" .
* @since 1.32
*/
protected function migrateImageCommentTemp() {
- global $wgCommentTableSchemaMigrationStage;
-
if ( $this->tableExists( 'image_comment_temp' ) ) {
- if ( $wgCommentTableSchemaMigrationStage > MIGRATION_OLD ) {
- $this->output( "Merging image_comment_temp into the image table\n" );
- $task = $this->maintenance->runChild(
- MigrateImageCommentTemp::class, 'migrateImageCommentTemp.php'
- );
- $task->setForce();
- $ok = $task->execute();
- $this->output( $ok ? "done.\n" : "errors were encountered.\n" );
- } else {
- $ok = true;
- }
+ $this->output( "Merging image_comment_temp into the image table\n" );
+ $task = $this->maintenance->runChild(
+ MigrateImageCommentTemp::class, 'migrateImageCommentTemp.php'
+ );
+ $task->setForce();
+ $ok = $task->execute();
+ $this->output( $ok ? "done.\n" : "errors were encountered.\n" );
if ( $ok ) {
$this->dropTable( 'image_comment_temp' );
}
[ 'dropField', 'change_tag', 'ct_tag', 'patch-drop-ct_tag.sql' ],
[ 'dropTable', 'valid_tag' ],
[ 'dropTable', 'tag_summary' ],
+ [ 'dropField', 'protected_titles', 'pt_reason', 'patch-drop-comment-fields.sql' ],
];
}
[ 'dropField', 'change_tag', 'ct_tag', 'patch-drop-ct_tag.sql' ],
[ 'dropTable', 'valid_tag' ],
[ 'dropTable', 'tag_summary' ],
+ [ 'dropField', 'protected_titles', 'pt_reason', 'patch-drop-comment-fields.sql' ],
];
}
[ 'dropField', 'change_tag', 'ct_tag', 'patch-drop-ct_tag.sql' ],
[ 'dropTable', 'valid_tag' ],
[ 'dropTable', 'tag_summary' ],
+ [ 'dropField', 'protected_titles', 'pt_reason', 'patch-drop-comment-fields.sql' ],
// KEEP THIS AT THE BOTTOM!!
[ 'doRebuildDuplicateFunction' ],
[ 'dropField', 'change_tag', 'ct_tag', 'patch-drop-ct_tag.sql' ],
[ 'dropTable', 'valid_tag' ],
[ 'dropTable', 'tag_summary' ],
+ [ 'dropPgField', 'archive', 'ar_comment' ],
+ [ 'dropDefault', 'archive', 'ar_comment_id' ],
+ [ 'dropPgField', 'ipblocks', 'ipb_reason' ],
+ [ 'dropDefault', 'ipblocks', 'ipb_reason_id' ],
+ [ 'dropPgField', 'image', 'img_description' ],
+ [ 'dropDefault', 'image', 'img_description_id' ],
+ [ 'dropPgField', 'oldimage', 'oi_description' ],
+ [ 'dropDefault', 'oldimage', 'oi_description_id' ],
+ [ 'dropPgField', 'filearchive', 'fa_deleted_reason' ],
+ [ 'dropDefault', 'filearchive', 'fa_deleted_reason_id' ],
+ [ 'dropPgField', 'filearchive', 'fa_description' ],
+ [ 'dropDefault', 'filearchive', 'fa_description_id' ],
+ [ 'dropPgField', 'recentchanges', 'rc_comment' ],
+ [ 'dropDefault', 'recentchanges', 'rc_comment_id' ],
+ [ 'dropPgField', 'logging', 'log_comment' ],
+ [ 'dropDefault', 'logging', 'log_comment_id' ],
+ [ 'dropPgField', 'protected_titles', 'pt_reason' ],
+ [ 'dropDefault', 'protected_titles', 'pt_reason_id' ],
];
}
protected function setDefault( $table, $field, $default ) {
$info = $this->db->fieldInfo( $table, $field );
- if ( $info->defaultValue() !== $default ) {
+ if ( $info && $info->defaultValue() !== $default ) {
$this->output( "Changing '$table.$field' default value\n" );
$this->db->query( "ALTER TABLE $table ALTER $field SET DEFAULT "
. $this->db->addQuotes( $default ) );
[ 'dropField', 'change_tag', 'ct_tag', 'patch-drop-ct_tag.sql' ],
[ 'dropTable', 'valid_tag' ],
[ 'dropTable', 'tag_summary' ],
+ [ 'dropField', 'archive', 'ar_comment', 'patch-archive-drop-ar_comment.sql' ],
+ [ 'dropField', 'ipblocks', 'ipb_reason', 'patch-ipblocks-drop-ipb_reason.sql' ],
+ [ 'dropField', 'image', 'img_description', 'patch-image-drop-img_description.sql' ],
+ [ 'dropField', 'oldimage', 'oi_description', 'patch-oldimage-drop-oi_description.sql' ],
+ [ 'dropField', 'filearchive', 'fa_description', 'patch-filearchive-drop-fa_description.sql' ],
+ [ 'dropField', 'recentchanges', 'rc_comment', 'patch-recentchanges-drop-rc_comment.sql' ],
+ [ 'dropField', 'logging', 'log_comment', 'patch-logging-drop-log_comment.sql' ],
+ [ 'dropField', 'protected_titles', 'pt_reason', 'patch-protected_titles-drop-pt_reason.sql' ],
];
}
private function getInterwikiCacheEntry( $prefix ) {
wfDebug( __METHOD__ . "( $prefix )\n" );
- $wikiId = WikiMap::getWikiIdFromDomain( WikiMap::getCurrentWikiDomain() );
+ $wikiId = WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() );
$value = false;
try {
private function getAllPrefixesCached( $local ) {
wfDebug( __METHOD__ . "()\n" );
- $wikiId = WikiMap::getWikiIdFromDomain( WikiMap::getCurrentWikiDomain() );
+ $wikiId = WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() );
$data = [];
try {
global $wgJobClasses;
$this->assertNotReadOnly();
- if ( !WikiMap::isCurrentWikiDomain( $this->domain ) ) {
+ if ( !WikiMap::isCurrentWikiDbDomain( $this->domain ) ) {
throw new MWException(
"Cannot pop '{$this->type}' job off foreign '{$this->domain}' wiki queue." );
} elseif ( !isset( $wgJobClasses[$this->type] ) ) {
$stats->updateCount( "jobqueue.{$key}.{$type}", $delta );
}
}
-
-/**
- * @ingroup JobQueue
- * @since 1.22
- */
-class JobQueueError extends MWException {
-}
-
-class JobQueueConnectionError extends JobQueueError {
-}
-
-class JobQueueReadOnlyError extends JobQueueError {
-
-}
global $wgLocalDatabases;
if ( $domain === false ) {
- $domain = WikiMap::getCurrentWikiDomain()->getId();
+ $domain = WikiMap::getCurrentWikiDbDomain()->getId();
}
if ( !isset( self::$instances[$domain] ) ) {
self::$instances[$domain] = new self( $domain, wfConfiguredReadOnlyReason() );
// Make sure jobs are not getting pushed to bogus wikis. This can confuse
// the job runner system into spawning endless RPC requests that fail (T171371).
- $wikiId = WikiMap::getWikiIdFromDomain( $domain );
+ $wikiId = WikiMap::getWikiIdFromDbDomain( $domain );
if (
- !WikiMap::isCurrentWikiDomain( $domain ) &&
+ !WikiMap::isCurrentWikiDbDomain( $domain ) &&
!in_array( $wikiId, $wgLocalDatabases )
) {
self::$instances[$domain]->invalidDomain = true;
*/
private function getCachedConfigVar( $name ) {
// @TODO: cleanup this whole method with a proper config system
- if ( WikiMap::isCurrentWikiDomain( $this->domain ) ) {
+ if ( WikiMap::isCurrentWikiDbDomain( $this->domain ) ) {
return $GLOBALS[$name]; // common case
} else {
- $wiki = WikiMap::getWikiIdFromDomain( $this->domain );
+ $wiki = WikiMap::getWikiIdFromDbDomain( $this->domain );
$cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
$value = $cache->getWithSetCallback(
$cache->makeGlobalKey( 'jobqueue', 'configvalue', $this->domain, $name ),
$type = is_string( $type ) ? $type : $this->type;
// Use wiki ID for b/c
- $keyspace = WikiMap::getWikiIdFromDomain( $this->domain );
+ $keyspace = WikiMap::getWikiIdFromDbDomain( $this->domain );
$parts = [ $keyspace, 'jobqueue', $type, $prop ];
--- /dev/null
+<?php
+/**
+ * Job queue base code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @defgroup JobQueue JobQueue
+ */
+
+/**
+ * @ingroup JobQueue
+ * @since 1.22
+ */
+class JobQueueConnectionError extends JobQueueError {
+}
--- /dev/null
+<?php
+/**
+ * Job queue base code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @defgroup JobQueue JobQueue
+ */
+
+/**
+ * @ingroup JobQueue
+ * @since 1.22
+ */
+class JobQueueError extends MWException {
+}
--- /dev/null
+<?php
+/**
+ * Job queue base code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @defgroup JobQueue JobQueue
+ */
+
+/**
+ * @ingroup JobQueue
+ * @since 1.22
+ */
+class JobQueueReadOnlyError extends JobQueueError {
+
+}
static function makeMsgId() {
global $wgSMTP, $wgServer;
- $domainId = WikiMap::getCurrentWikiDomain()->getId();
+ $domainId = WikiMap::getCurrentWikiDbDomain()->getId();
$msgid = uniqid( $domainId . ".", true /** for cygwin */ );
if ( is_array( $wgSMTP ) && isset( $wgSMTP['IDHost'] ) && $wgSMTP['IDHost'] ) {
$domain = $wgSMTP['IDHost'];
return $keyspace;
}
- return WikiMap::getCurrentWikiDomain()->getId();
+ return WikiMap::getCurrentWikiDbDomain()->getId();
}
/**
// HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
// (e.g. emojis) count for two each. This limit is overridden in JS to instead count
- // Unicode codepoints (or 255 UTF-8 bytes for old schema).
- $conf = $this->getContext()->getConfig();
- $oldCommentSchema = $conf->get( 'CommentTableSchemaMigrationStage' ) === MIGRATION_OLD;
+ // Unicode codepoints.
$fields[] = new OOUI\FieldLayout(
new OOUI\TextInputWidget( [
'name' => 'wpReason',
'inputId' => 'wpReason',
'tabIndex' => 2,
- 'maxLength' => $oldCommentSchema ? 255 : CommentStore::COMMENT_CHARACTER_LIMIT,
+ 'maxLength' => CommentStore::COMMENT_CHARACTER_LIMIT,
'infusable' => true,
'value' => $reason,
'autofocus' => true,
*/
protected function archiveRevisions( $dbw, $id, $suppress ) {
global $wgContentHandlerUseDB, $wgMultiContentRevisionSchemaMigrationStage,
- $wgCommentTableSchemaMigrationStage, $wgActorTableSchemaMigrationStage,
- $wgDeleteRevisionsBatchSize;
+ $wgActorTableSchemaMigrationStage, $wgDeleteRevisionsBatchSize;
// Given the lock above, we can be confident in the title and page ID values
$namespace = $this->getTitle()->getNamespace();
$dbw->insert( 'archive', $rowsInsert, __METHOD__ );
$dbw->delete( 'revision', [ 'rev_id' => $revids ], __METHOD__ );
- if ( $wgCommentTableSchemaMigrationStage > MIGRATION_OLD ) {
- $dbw->delete( 'revision_comment_temp', [ 'revcomment_rev' => $revids ], __METHOD__ );
- }
+ $dbw->delete( 'revision_comment_temp', [ 'revcomment_rev' => $revids ], __METHOD__ );
if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
$dbw->delete( 'revision_actor_temp', [ 'revactor_rev' => $revids ], __METHOD__ );
}
// Clear caches
self::onArticleDelete( $this->mTitle );
ResourceLoaderWikiModule::invalidateModuleCache(
- $this->mTitle, $revision, null, wfWikiID()
+ $this->mTitle,
+ $revision,
+ null,
+ WikiMap::getCurrentWikiDbDomain()->getId()
);
// Reset this object and the Title object
if ( $wgUseRCPatrol ) {
// Mark all reverted edits as patrolled
- $set['rc_patrolled'] = RecentChange::PRC_PATROLLED;
+ $set['rc_patrolled'] = RecentChange::PRC_AUTOPATROLLED;
}
if ( count( $set ) ) {
// means that some cache invalidations happen that are not strictly needed.
$cache->makeGlobalKey(
'interwiki-page',
- WikiMap::getCurrentWikiDomain()->getId(),
+ WikiMap::getCurrentWikiDbDomain()->getId(),
$title->getDBkey()
)
);
*/
public function getProfileID() {
if ( $this->profileID === false ) {
- return WikiMap::getCurrentWikiDomain()->getId();
+ return WikiMap::getCurrentWikiDbDomain()->getId();
} else {
return $this->profileID;
}
$packet['server_name'] = $wgServerName;
$packet['server_script_path'] = $wgScriptPath ?: '/';
- $packet['wiki'] = WikiMap::getWikiIdFromDomain( WikiMap::getCurrentWikiDomain() );
+ $packet['wiki'] = WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() );
return $this->formatArray( $packet );
}
}
$illegalFileChars = $conf->get( 'IllegalFileChars' );
- $oldCommentSchema = $conf->get( 'CommentTableSchemaMigrationStage' ) === MIGRATION_OLD;
// Build list of variables
$skin = $context->getSkin();
'wgResourceLoaderStorageEnabled' => $conf->get( 'ResourceLoaderStorageEnabled' ),
'wgForeignUploadTargets' => $conf->get( 'ForeignUploadTargets' ),
'wgEnableUploads' => $conf->get( 'EnableUploads' ),
- 'wgCommentByteLimit' => $oldCommentSchema ? 255 : null,
- 'wgCommentCodePointLimit' => $oldCommentSchema ? null : CommentStore::COMMENT_CHARACTER_LIMIT,
+ 'wgCommentByteLimit' => null,
+ 'wgCommentCodePointLimit' => CommentStore::COMMENT_CHARACTER_LIMIT,
];
Hooks::run( 'ResourceLoaderGetConfigVars', [ &$vars, $skin ] );
* @param Title $title
* @param Revision|null $old Prior page revision
* @param Revision|null $new New page revision
- * @param string $wikiId
+ * @param string $domain Database domain ID
* @since 1.28
*/
public static function invalidateModuleCache(
- Title $title, Revision $old = null, Revision $new = null, $wikiId
+ Title $title, Revision $old = null, Revision $new = null, $domain
) {
static $formats = [ CONTENT_FORMAT_CSS, CONTENT_FORMAT_JAVASCRIPT ];
- Assert::parameterType( 'string', $wikiId, '$wikiId' );
+ Assert::parameterType( 'string', $domain, '$domain' );
// TODO: MCR: differentiate between page functionality and content model!
// Not all pages containing CSS or JS have to be modules! [PageType]
if ( $purge ) {
$cache = ObjectCache::getMainWANInstance();
- $key = $cache->makeGlobalKey( 'resourceloader', 'titleinfo', $wikiId );
+ $key = $cache->makeGlobalKey( 'resourceloader', 'titleinfo', $domain );
$cache->touchCheckKey( $key );
}
}
$dbw->update( 'recentchanges',
[
'rc_deleted' => $bits,
- 'rc_patrolled' => RecentChange::PRC_PATROLLED
+ 'rc_patrolled' => RecentChange::PRC_AUTOPATROLLED
],
[
'rc_logid' => $this->row->log_id,
$dbw->update( 'recentchanges',
[
'rc_deleted' => $bits,
- 'rc_patrolled' => RecentChange::PRC_PATROLLED
+ 'rc_patrolled' => RecentChange::PRC_AUTOPATROLLED
],
[
'rc_this_oldid' => $this->revision->getId(), // condition
$suggestedDurations = self::getSuggestedDurations();
$conf = $this->getConfig();
- $oldCommentSchema = $conf->get( 'CommentTableSchemaMigrationStage' ) === MIGRATION_OLD;
$enablePartialBlocks = $conf->get( 'EnablePartialBlocks' );
$a = [];
'type' => 'selectandother',
// HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
// (e.g. emojis) count for two each. This limit is overridden in JS to instead count
- // Unicode codepoints (or 255 UTF-8 bytes for old schema).
- 'maxlength' => $oldCommentSchema ? 255 : CommentStore::COMMENT_CHARACTER_LIMIT,
+ // Unicode codepoints.
+ 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
'maxlength-unit' => 'codepoints',
'options-message' => 'ipbreason-dropdown',
'section' => 'reason',
$title = Title::newFromText( $text );
// Use the link cache since the title has already been loaded when
// the field was validated.
- $restriction = new PageRestriction( 0, $title->getArticleId() );
+ $restriction = new PageRestriction( 0, $title->getArticleID() );
$restriction->setTitle( $title );
return $restriction;
}, explode( "\n", $data['PageRestrictions'] ) );
// Show form if the user can submit
if ( $this->isAllowed ) {
- $conf = $this->getConfig();
- $oldCommentSchema = $conf->get( 'CommentTableSchemaMigrationStage' ) === MIGRATION_OLD;
-
$form = Xml::openElement( 'form', [ 'method' => 'post',
'action' => $this->getPageTitle()->getLocalURL( [ 'action' => 'submit' ] ),
'id' => 'mw-revdel-form-revisions' ] ) .
'id' => 'wpReason',
// HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
// (e.g. emojis) count for two each. This limit is overridden in JS to instead count
- // Unicode codepoints (or 255 UTF-8 bytes for old schema).
+ // Unicode codepoints.
// "- 155" is to leave room for the auto-generated part of the log entry.
- 'maxlength' => $oldCommentSchema ? 100 : CommentStore::COMMENT_CHARACTER_LIMIT - 155,
+ 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT - 155,
] ) .
'</td>' .
"</tr><tr>\n" .
// HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
// (e.g. emojis) count for two each. This limit is overridden in JS to instead count
- // Unicode codepoints (or 255 UTF-8 bytes for old schema).
- $conf = $this->getConfig();
- $oldCommentSchema = $conf->get( 'CommentTableSchemaMigrationStage' ) === MIGRATION_OLD;
+ // Unicode codepoints.
$fields[] = new OOUI\FieldLayout(
new OOUI\TextInputWidget( [
'name' => 'wpReason',
'id' => 'wpReason',
- 'maxLength' => $oldCommentSchema ? 200 : CommentStore::COMMENT_CHARACTER_LIMIT,
+ 'maxLength' => CommentStore::COMMENT_CHARACTER_LIMIT,
'infusable' => true,
'value' => $this->reason,
] ),
$out->addModules( [ 'mediawiki.special.revisionDelete' ] );
$out->addModuleStyles( 'mediawiki.special' );
- $conf = $this->getConfig();
- $oldCommentSchema = $conf->get( 'CommentTableSchemaMigrationStage' ) === MIGRATION_OLD;
-
$form = Xml::openElement( 'form', [ 'method' => 'post',
'action' => $this->getPageTitle()->getLocalURL( [ 'action' => 'submit' ] ),
'id' => 'mw-revdel-form-revisions' ] ) .
'id' => 'wpReason',
// HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
// (e.g. emojis) count for two each. This limit is overridden in JS to instead count
- // Unicode codepoints (or 255 UTF-8 bytes for old schema).
+ // Unicode codepoints.
// "- 155" is to leave room for the 'wpRevDeleteReasonList' value.
- 'maxlength' => $oldCommentSchema ? 100 : CommentStore::COMMENT_CHARACTER_LIMIT - 155,
+ 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT - 155,
] ) .
'</td>' .
"</tr><tr>\n" .
'content' => new OOUI\HtmlSnippet( $this->msg( 'undeleteextrahelp' )->parseAsBlock() )
] );
- $conf = $this->getConfig();
- $oldCommentSchema = $conf->get( 'CommentTableSchemaMigrationStage' ) === MIGRATION_OLD;
-
$fields[] = new OOUI\FieldLayout(
new OOUI\TextInputWidget( [
'name' => 'wpComment',
'autofocus' => true,
// HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
// (e.g. emojis) count for two each. This limit is overridden in JS to instead count
- // Unicode codepoints (or 255 UTF-8 bytes for old schema).
- 'maxLength' => $oldCommentSchema ? 255 : CommentStore::COMMENT_CHARACTER_LIMIT,
+ // Unicode codepoints.
+ 'maxLength' => CommentStore::COMMENT_CHARACTER_LIMIT,
] ),
[
'label' => $this->msg( 'undeletecomment' )->text(),
->rawParams( $userToolLinks )->parse()
);
if ( $canChangeAny ) {
- $conf = $this->getConfig();
- $oldCommentSchema = $conf->get( 'CommentTableSchemaMigrationStage' ) === MIGRATION_OLD;
$this->getOutput()->addHTML(
$this->msg( 'userrights-groups-help', $user->getName() )->parse() .
$grouplist .
'id' => 'wpReason',
// HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
// (e.g. emojis) count for two each. This limit is overridden in JS to instead count
- // Unicode codepoints (or 255 UTF-8 bytes for old schema).
- 'maxlength' => $oldCommentSchema ? 255 : CommentStore::COMMENT_CHARACTER_LIMIT,
+ // Unicode codepoints.
+ 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
] ) .
"</td>
</tr>
return 'qcc_title';
}
- function getQueryInfo() {
+ function getQueryInfo( $data = null ) {
$dbr = $this->getDatabase();
- $rcQuery = ActorMigration::newMigration()->getJoin( 'rc_user' );
+ $useActor = (bool)(
+ $this->getConfig()->get( 'ActorTableSchemaMigrationStage' ) & SCHEMA_COMPAT_READ_NEW
+ );
$activeUserSeconds = $this->getConfig()->get( 'ActiveUserDays' ) * 86400;
$timestamp = $dbr->timestamp( wfTimestamp( TS_UNIX ) - $activeUserSeconds );
- $tables = [ 'querycachetwo', 'user', 'rc' => [ 'recentchanges' ] + $rcQuery['tables'] ];
+ $fname = __METHOD__ . ' (' . $this->getSqlComment() . ')';
+
+ // Inner subselect to pull the active users out of querycachetwo
+ $tables = [ 'querycachetwo', 'user' ];
+ $fields = [ 'qcc_title', 'user_id' ];
$jconds = [
'user' => [ 'JOIN', 'user_name = qcc_title' ],
- 'rc' => [ 'JOIN', $rcQuery['fields']['rc_user_text'] . ' = qcc_title' ],
- ] + $rcQuery['joins'];
+ ];
$conds = [
'qcc_type' => 'activeusers',
'qcc_namespace' => NS_USER,
- 'rc_type != ' . $dbr->addQuotes( RC_EXTERNAL ), // Don't count wikidata.
- 'rc_type != ' . $dbr->addQuotes( RC_CATEGORIZE ), // Don't count categorization changes.
- 'rc_log_type IS NULL OR rc_log_type != ' . $dbr->addQuotes( 'newusers' ),
- 'rc_timestamp >= ' . $dbr->addQuotes( $timestamp ),
];
+ $options = [];
+ if ( $data !== null ) {
+ $options['ORDER BY'] = 'qcc_title ' . $data['dir'];
+ $options['LIMIT'] = $data['limit'];
+ $conds = array_merge( $conds, $data['conds'] );
+ }
if ( $this->requestedUser != '' ) {
$conds[] = 'qcc_title >= ' . $dbr->addQuotes( $this->requestedUser );
}
if ( $this->groups !== [] ) {
- $tables[] = 'user_groups';
- $jconds['user_groups'] = [ 'JOIN', [ 'ug_user = user_id' ] ];
- $conds['ug_group'] = $this->groups;
- $conds[] = 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() );
+ $tables['ug1'] = 'user_groups';
+ $jconds['ug1'] = [ 'JOIN', 'ug1.ug_user = user_id' ];
+ $conds['ug1.ug_group'] = $this->groups;
+ $conds[] = 'ug1.ug_expiry IS NULL OR ug1.ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() );
}
if ( $this->excludegroups !== [] ) {
- foreach ( $this->excludegroups as $group ) {
- $conds[] = 'NOT EXISTS (' . $dbr->selectSQLText(
- 'user_groups', '1', [
- 'ug_user = user_id',
- 'ug_group' => $group,
- 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
- ]
- ) . ')';
- }
+ $tables['ug2'] = 'user_groups';
+ $jconds['ug2'] = [ 'LEFT JOIN', [
+ 'ug2.ug_user = user_id',
+ 'ug2.ug_group' => $this->excludegroups,
+ 'ug2.ug_expiry IS NULL OR ug2.ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() ),
+ ] ];
+ $conds['ug2.ug_user'] = null;
}
if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
$conds[] = 'NOT EXISTS (' . $dbr->selectSQLText(
'ipblocks', '1', [ 'ipb_user=user_id', 'ipb_deleted' => 1 ]
) . ')';
}
+ if ( $useActor ) {
+ $tables[] = 'actor';
+ $jconds['actor'] = [
+ 'JOIN',
+ 'actor_user = user_id',
+ ];
+ $fields[] = 'actor_id';
+ }
+ $subquery = $dbr->buildSelectSubquery( $tables, $fields, $conds, $fname, $options, $jconds );
+
+ // Outer query to select the recent edit counts for the selected active users
+ $tables = [ 'qcc_users' => $subquery, 'recentchanges' ];
+ $jconds = [ 'recentchanges' => [
+ 'JOIN', $useActor ? 'rc_actor = actor_id' : 'rc_user_text = qcc_title',
+ ] ];
+ $conds = [
+ 'rc_type != ' . $dbr->addQuotes( RC_EXTERNAL ), // Don't count wikidata.
+ 'rc_type != ' . $dbr->addQuotes( RC_CATEGORIZE ), // Don't count categorization changes.
+ 'rc_log_type IS NULL OR rc_log_type != ' . $dbr->addQuotes( 'newusers' ),
+ 'rc_timestamp >= ' . $dbr->addQuotes( $timestamp ),
+ ];
return [
'tables' => $tables,
'fields' => [
'qcc_title',
'user_name' => 'qcc_title',
- 'user_id' => 'MAX(user_id)',
+ 'user_id' => 'user_id',
'recentedits' => 'COUNT(*)'
],
'options' => [ 'GROUP BY' => [ 'qcc_title' ] ],
];
}
+ protected function buildQueryInfo( $offset, $limit, $descending ) {
+ $fname = __METHOD__ . ' (' . $this->getSqlComment() . ')';
+
+ $sortColumns = array_merge( [ $this->mIndexField ], $this->mExtraSortFields );
+ if ( $descending ) {
+ $orderBy = $sortColumns;
+ $operator = $this->mIncludeOffset ? '>=' : '>';
+ } else {
+ $orderBy = [];
+ foreach ( $sortColumns as $col ) {
+ $orderBy[] = $col . ' DESC';
+ }
+ $operator = $this->mIncludeOffset ? '<=' : '<';
+ }
+ $info = $this->getQueryInfo( [
+ 'limit' => intval( $limit ),
+ 'order' => $descending ? 'DESC' : 'ASC',
+ 'conds' =>
+ $offset != '' ? [ $this->mIndexField . $operator . $this->mDb->addQuotes( $offset ) ] : [],
+ ] );
+
+ $tables = $info['tables'];
+ $fields = $info['fields'];
+ $conds = $info['conds'];
+ $options = $info['options'];
+ $join_conds = $info['join_conds'];
+ $options['ORDER BY'] = $orderBy;
+ return [ $tables, $fields, $conds, $fname, $options, $join_conds ];
+ }
+
protected function doBatchLookups() {
parent::doBatchLookups();
* @return string
*/
protected function getCacheKey( WANObjectCache $cache ) {
- $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
$lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
return $cache->makeGlobalKey( 'user', 'id', $lbFactory->getLocalDomainID(), $this->mId );
* @since 1.25
*/
protected function loadFromCache() {
- $cache = ObjectCache::getMainWANInstance();
+ $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
$data = $cache->getWithSetCallback(
$this->getCacheKey( $cache ),
$cache::TTL_HOUR,
$rev = $timestamp ? Revision::loadFromTimestamp( $dbr, $utp, $timestamp ) : null;
return [
[
- 'wiki' => WikiMap::getWikiIdFromDomain( WikiMap::getCurrentWikiDomain() ),
+ 'wiki' => WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() ),
'link' => $utp->getLocalURL(),
'rev' => $rev
]
return;
}
- $cache = ObjectCache::getMainWANInstance();
+ $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
$key = $this->getCacheKey( $cache );
if ( $mode === 'refresh' ) {
$cache->delete( $key, 1 );
--- /dev/null
+--
+-- patch-drop-comment-fields.sql
+--
+-- T166732. Drop old xx_comment fields, and defaults from xx_comment_id fields.
+
+ALTER TABLE /*_*/archive
+ DROP COLUMN ar_comment,
+ ALTER COLUMN ar_comment_id DROP DEFAULT;
+
+ALTER TABLE /*_*/ipblocks
+ DROP COLUMN ipb_reason,
+ ALTER COLUMN ipb_reason_id DROP DEFAULT;
+
+ALTER TABLE /*_*/image
+ DROP COLUMN img_description,
+ ALTER COLUMN img_description_id DROP DEFAULT;
+
+ALTER TABLE /*_*/oldimage
+ DROP COLUMN oi_description,
+ ALTER COLUMN oi_description_id DROP DEFAULT;
+
+ALTER TABLE /*_*/filearchive
+ DROP COLUMN fa_deleted_reason,
+ ALTER COLUMN fa_deleted_reason_id DROP DEFAULT,
+ DROP COLUMN fa_description,
+ ALTER COLUMN fa_description_id DROP DEFAULT;
+
+ALTER TABLE /*_*/recentchanges
+ DROP COLUMN rc_comment,
+ ALTER COLUMN rc_comment_id DROP DEFAULT;
+
+ALTER TABLE /*_*/logging
+ DROP COLUMN log_comment,
+ ALTER COLUMN log_comment_id DROP DEFAULT;
+
+ALTER TABLE /*_*/protected_titles
+ DROP COLUMN pt_reason,
+ ALTER COLUMN pt_reason_id DROP DEFAULT;
}
protected function doDBUpdates() {
- global $wgCommentTableSchemaMigrationStage;
-
- if ( $wgCommentTableSchemaMigrationStage < MIGRATION_WRITE_NEW ) {
- $this->output(
- "...cannot update while \$wgCommentTableSchemaMigrationStage < MIGRATION_WRITE_NEW\n"
- );
- return false;
- }
-
$this->migrateToTemp(
'revision', 'rev_id', 'rev_comment', 'revcomment_rev', 'revcomment_comment_id'
);
* @param string $oldField Old comment field name
*/
protected function migrate( $table, $primaryKey, $oldField ) {
+ $dbw = $this->getDB( DB_MASTER );
+ if ( !$dbw->fieldExists( $table, $oldField, __METHOD__ ) ) {
+ $this->output( "No need to migrate $table.$oldField, field does not exist\n" );
+ return;
+ }
+
$newField = $oldField . '_id';
$primaryKey = (array)$primaryKey;
$pkFilter = array_flip( $primaryKey );
$this->output( "Beginning migration of $table.$oldField to $table.$newField\n" );
wfWaitForSlaves();
- $dbw = $this->getDB( DB_MASTER );
$next = '1=1';
$countUpdated = 0;
$countComments = 0;
* @param string $newField New comment field name
*/
protected function migrateToTemp( $table, $primaryKey, $oldField, $newPrimaryKey, $newField ) {
+ $dbw = $this->getDB( DB_MASTER );
+ if ( !$dbw->fieldExists( $table, $oldField, __METHOD__ ) ) {
+ $this->output( "No need to migrate $table.$oldField, field does not exist\n" );
+ return;
+ }
+
$newTable = $table . '_comment_temp';
$this->output( "Beginning migration of $table.$oldField to $newTable.$newField\n" );
wfWaitForSlaves();
--- /dev/null
+--
+-- patch-drop-comment-fields.sql
+--
+-- T166732. Drop old xx_comment fields, and defaults from xx_comment_id fields.
+
+DECLARE @sql nvarchar(max),
+ @id sysname;
+
+ALTER TABLE /*_*/archive DROP CONSTRAINT DF_ar_comment, COLUMN ar_comment;
+ALTER TABLE /*_*/archive DROP CONSTRAINT DF_ar_comment_id;
+
+ALTER TABLE /*_*/ipblocks DROP CONSTRAINT DF_ipb_reason, COLUMN ipb_reason;
+ALTER TABLE /*_*/ipblocks DROP CONSTRAINT DF_ipb_reason_id;
+
+ALTER TABLE /*_*/image DROP CONSTRAINT DF_img_description, COLUMN img_description;
+ALTER TABLE /*_*/image DROP CONSTRAINT DF_img_description_id;
+
+ALTER TABLE /*_*/oldimage DROP CONSTRAINT DF_oi_description, COLUMN oi_description;
+ALTER TABLE /*_*/oldimage DROP CONSTRAINT DF_oi_description_id;
+
+ALTER TABLE /*_*/filearchive DROP CONSTRAINT DF_fa_deleted_reason, COLUMN fa_deleted_reason;
+ALTER TABLE /*_*/filearchive DROP CONSTRAINT DF_fa_deleted_reason_id;
+ALTER TABLE /*_*/filearchive DROP CONSTRAINT DF_fa_description, COLUMN fa_description;
+ALTER TABLE /*_*/filearchive DROP CONSTRAINT DF_fa_description_id;
+
+SET @sql = 'ALTER TABLE /*_*/recentchanges DROP CONSTRAINT ';
+SELECT @id = df.name
+FROM sys.default_constraints df
+JOIN sys.columns c
+ ON c.object_id = df.parent_object_id
+ AND c.column_id = df.parent_column_id
+WHERE
+ df.parent_object_id = OBJECT_ID('/*_*/recentchanges')
+ AND c.name = 'rc_comment';
+SET @sql = @sql + @id;
+EXEC sp_executesql @sql;
+ALTER TABLE /*_*/recentchanges DROP COLUMN rc_comment;
+ALTER TABLE /*_*/recentchanges DROP CONSTRAINT DF_rc_comment_id;
+
+SET @sql = 'ALTER TABLE /*_*/logging DROP CONSTRAINT ';
+SELECT @id = df.name
+FROM sys.default_constraints df
+JOIN sys.columns c
+ ON c.object_id = df.parent_object_id
+ AND c.column_id = df.parent_column_id
+WHERE
+ df.parent_object_id = OBJECT_ID('/*_*/logging')
+ AND c.name = 'log_comment';
+SET @sql = @sql + @id;
+EXEC sp_executesql @sql;
+ALTER TABLE /*_*/logging DROP COLUMN log_comment;
+ALTER TABLE /*_*/logging DROP CONSTRAINT DF_log_comment_id;
+
+ALTER TABLE /*_*/protected_titles DROP CONSTRAINT DF_pt_reason, COLUMN pt_reason;
+ALTER TABLE /*_*/protected_titles DROP CONSTRAINT DF_pt_reason_id;
ar_id int NOT NULL PRIMARY KEY IDENTITY,
ar_namespace SMALLINT NOT NULL DEFAULT 0,
ar_title NVARCHAR(255) NOT NULL DEFAULT '',
- ar_comment NVARCHAR(255) NOT NULL CONSTRAINT DF_ar_comment DEFAULT '',
- ar_comment_id bigint NOT NULL CONSTRAINT DF_ar_comment_id DEFAULT 0 CONSTRAINT FK_ar_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+ ar_comment_id bigint NOT NULL CONSTRAINT FK_ar_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
ar_user INT CONSTRAINT ar_user__user_id__fk FOREIGN KEY REFERENCES /*_*/mwuser(user_id),
ar_user_text NVARCHAR(255) NOT NULL CONSTRAINT DF_ar_user_text DEFAULT '',
ar_actor bigint NOT NULL CONSTRAINT DF_ar_actor DEFAULT 0,
-- User name of blocker
ipb_by_text nvarchar(255) NOT NULL default '',
- -- Text comment made by blocker.
- ipb_reason nvarchar(255) NOT NULL CONSTRAINT DF_ipb_reason DEFAULT '',
-
-- Key to comment_id. Text comment made by blocker.
- -- ("DEFAULT 0" is temporary, signaling that ipb_reason should be used)
- ipb_reason_id bigint NOT NULL CONSTRAINT DF_ipb_reason_id DEFAULT 0 CONSTRAINT FK_ipb_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+ ipb_reason_id bigint NOT NULL CONSTRAINT FK_ipb_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
-- Creation (or refresh) date in standard YMDHMS form.
-- IP blocks expire automatically.
-- Description field as entered by the uploader.
-- This is displayed in image upload history and logs.
- img_description nvarchar(255) NOT NULL CONSTRAINT DF_img_description DEFAULT '',
- img_description_id bigint NOT NULL CONSTRAINT DF_img_description_id DEFAULT 0 CONSTRAINT FK_img_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+ img_description_id bigint NOT NULL CONSTRAINT FK_img_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
-- user_id and user_name of uploader.
img_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
oi_width int NOT NULL default 0,
oi_height int NOT NULL default 0,
oi_bits int NOT NULL default 0,
- oi_description nvarchar(255) NOT NULL CONSTRAINT DF_oi_description DEFAULT '',
- oi_description_id bigint NOT NULL CONSTRAINT DF_oi_description_id DEFAULT 0 CONSTRAINT FK_oi_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+ oi_description_id bigint NOT NULL CONSTRAINT FK_oi_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
oi_user int REFERENCES /*_*/mwuser(user_id),
oi_user_text nvarchar(255) NOT NULL CONSTRAINT DF_oi_user_text DEFAULT '',
oi_actor bigint NOT NULL CONSTRAINT DF_oi_actor DEFAULT 0,
-- Deletion information, if this file is deleted.
fa_deleted_user int,
fa_deleted_timestamp varchar(14) default '',
- fa_deleted_reason nvarchar(max) CONSTRAINT DF_fa_deleted_reason DEFAULT '',
- fa_deleted_reason_id bigint NOT NULL CONSTRAINT DF_fa_deleted_reason_id DEFAULT 0 CONSTRAINT FK_fa_deleted_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+ fa_deleted_reason_id bigint NOT NULL CONSTRAINT FK_fa_deleted_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
-- Duped fields from image
fa_size int default 0,
fa_media_type varchar(16) default null,
fa_major_mime varchar(16) not null default 'unknown',
fa_minor_mime nvarchar(100) default 'unknown',
- fa_description nvarchar(255) CONSTRAINT DF_fa_description DEFAULT '',
- fa_description_id bigint NOT NULL CONSTRAINT DF_fa_description_id DEFAULT 0 CONSTRAINT FK_fa_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+ fa_description_id bigint NOT NULL CONSTRAINT FK_fa_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
fa_user int default 0 REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
fa_user_text nvarchar(255) CONSTRAINT DF_fa_user_text DEFAULT '',
fa_actor bigint NOT NULL CONSTRAINT DF_fa_actor DEFAULT 0,
rc_title nvarchar(255) NOT NULL default '',
-- as in revision...
- rc_comment nvarchar(255) NOT NULL default '',
- rc_comment_id bigint NOT NULL CONSTRAINT DF_rc_comment_id DEFAULT 0 CONSTRAINT FK_rc_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+ rc_comment_id bigint NOT NULL CONSTRAINT FK_rc_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
rc_minor bit NOT NULL default 0,
-- Edits by user accounts with the 'bot' rights key are
log_title nvarchar(255) NOT NULL default '',
log_page int NULL, -- NOT an FK, logging entries are inserted for deleted pages which still reference the deleted page ids
- -- Freeform text. Interpreted as edit history comments.
- log_comment nvarchar(255) NOT NULL default '',
-
-- Key to comment_id. Comment summarizing the change.
- -- ("DEFAULT 0" is temporary, signaling that log_comment should be used)
- log_comment_id bigint NOT NULL CONSTRAINT DF_log_comment_id DEFAULT 0 CONSTRAINT FK_log_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+ log_comment_id bigint NOT NULL CONSTRAINT FK_log_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
-- miscellaneous parameters:
-- LF separated list (old system) or serialized PHP array (new system)
pt_namespace int NOT NULL,
pt_title nvarchar(255) NOT NULL,
pt_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
- pt_reason nvarchar(255) CONSTRAINT DF_pt_reason DEFAULT '',
- pt_reason_id bigint NOT NULL CONSTRAINT DF_pt_reason_id DEFAULT 0 CONSTRAINT FK_pt_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+ pt_reason_id bigint NOT NULL CONSTRAINT FK_pt_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
pt_timestamp varchar(14) NOT NULL,
pt_expiry varchar(14) NOT NULL,
pt_create_perm nvarchar(60) NOT NULL,
--- /dev/null
+--
+-- patch-drop-comment-fields.sql
+--
+-- T166732. Drop old xx_comment fields, and defaults from xx_comment_id fields.
+
+ALTER TABLE &mw_prefix.archive DROP COLUMN ar_comment;
+ALTER TABLE &mw_prefix.archive MODIFY ar_comment_id DEFAULT NULL;
+
+ALTER TABLE &mw_prefix.ipblocks DROP COLUMN ipb_reason;
+ALTER TABLE &mw_prefix.ipblocks MODIFY ipb_reason_id DEFAULT NULL;
+
+ALTER TABLE &mw_prefix.image DROP COLUMN img_description;
+ALTER TABLE &mw_prefix.image MODIFY img_description_id DEFAULT NULL;
+
+ALTER TABLE &mw_prefix.oldimage DROP COLUMN oi_description;
+ALTER TABLE &mw_prefix.oldimage MODIFY oi_description_id DEFAULT NULL;
+
+ALTER TABLE &mw_prefix.filearchive DROP COLUMN fa_deleted_reason;
+ALTER TABLE &mw_prefix.filearchive MODIFY fa_deleted_reason_id DEFAULT NULL,
+ALTER TABLE &mw_prefix.filearchive DROP COLUMN fa_description;
+ALTER TABLE &mw_prefix.filearchive MODIFY fa_description_id DEFAULT NULL;
+
+ALTER TABLE &mw_prefix.recentchanges DROP COLUMN rc_comment;
+ALTER TABLE &mw_prefix.recentchanges MODIFY rc_comment_id DEFAULT NULL;
+
+ALTER TABLE &mw_prefix.logging DROP COLUMN log_comment;
+ALTER TABLE &mw_prefix.logging MODIFY log_comment_id DEFAULT NULL;
+
+ALTER TABLE &mw_prefix.protected_titles DROP COLUMN pt_reason;
+ALTER TABLE &mw_prefix.protected_titles MODIFY pt_reason_id DEFAULT NULL;
ar_id NUMBER NOT NULL,
ar_namespace NUMBER DEFAULT 0 NOT NULL,
ar_title VARCHAR2(255) NOT NULL,
- ar_comment VARCHAR2(255),
- ar_comment_id NUMBER DEFAULT 0 NOT NULL,
+ ar_comment_id NUMBER NOT NULL,
ar_user NUMBER DEFAULT 0 NOT NULL,
ar_user_text VARCHAR2(255) NULL,
ar_actor NUMBER DEFAULT 0 NOT NULL,
ipb_by NUMBER DEFAULT 0 NOT NULL,
ipb_by_text VARCHAR2(255) NULL,
ipb_by_actor NUMBER DEFAULT 0 NOT NULL,
- ipb_reason VARCHAR2(255) NULL,
- ipb_reason_id NUMBER DEFAULT 0 NOT NULL,
+ ipb_reason_id NUMBER NOT NULL,
ipb_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL,
ipb_auto CHAR(1) DEFAULT '0' NOT NULL,
ipb_anon_only CHAR(1) DEFAULT '0' NOT NULL,
img_media_type VARCHAR2(32),
img_major_mime VARCHAR2(32) DEFAULT 'unknown',
img_minor_mime VARCHAR2(100) DEFAULT 'unknown',
- img_description VARCHAR2(255),
- img_description_id NUMBER DEFAULT 0 NOT NULL,
+ img_description_id NUMBER NOT NULL,
img_user NUMBER DEFAULT 0 NOT NULL,
img_user_text VARCHAR2(255) NULL,
img_actor NUMBER DEFAULT 0 NOT NULL,
oi_width NUMBER DEFAULT 0 NOT NULL,
oi_height NUMBER DEFAULT 0 NOT NULL,
oi_bits NUMBER DEFAULT 0 NOT NULL,
- oi_description VARCHAR2(255),
- oi_description_id NUMBER DEFAULT 0 NOT NULL,
+ oi_description_id NUMBER NOT NULL,
oi_user NUMBER DEFAULT 0 NOT NULL,
oi_user_text VARCHAR2(255) NULL,
oi_actor NUMBER DEFAULT 0 NOT NULL,
fa_storage_key VARCHAR2(64),
fa_deleted_user NUMBER DEFAULT 0 NOT NULL,
fa_deleted_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL,
- fa_deleted_reason CLOB,
- fa_deleted_reason_id NUMBER DEFAULT 0 NOT NULL,
+ fa_deleted_reason_id NUMBER NOT NULL,
fa_size NUMBER DEFAULT 0 NOT NULL,
fa_width NUMBER DEFAULT 0 NOT NULL,
fa_height NUMBER DEFAULT 0 NOT NULL,
fa_media_type VARCHAR2(32) DEFAULT NULL,
fa_major_mime VARCHAR2(32) DEFAULT 'unknown',
fa_minor_mime VARCHAR2(100) DEFAULT 'unknown',
- fa_description VARCHAR2(255),
- fa_description_id NUMBER DEFAULT 0 NOT NULL,
+ fa_description_id NUMBER NOT NULL,
fa_user NUMBER DEFAULT 0 NOT NULL,
fa_user_text VARCHAR2(255) NULL,
fa_actor NUMBER DEFAULT 0 NOT NULL,
rc_actor NUMBER DEFAULT 0 NOT NULL,
rc_namespace NUMBER DEFAULT 0 NOT NULL,
rc_title VARCHAR2(255) NOT NULL,
- rc_comment VARCHAR2(255),
- rc_comment_id NUMBER DEFAULT 0 NOT NULL,
+ rc_comment_id NUMBER NOT NULL,
rc_minor CHAR(1) DEFAULT '0' NOT NULL,
rc_bot CHAR(1) DEFAULT '0' NOT NULL,
rc_new CHAR(1) DEFAULT '0' NOT NULL,
log_namespace NUMBER DEFAULT 0 NOT NULL,
log_title VARCHAR2(255) NOT NULL,
log_page NUMBER,
- log_comment VARCHAR2(255),
- log_comment_id NUMBER DEFAULT 0 NOT NULL,
+ log_comment_id NUMBER NOT NULL,
log_params CLOB,
log_deleted CHAR(1) DEFAULT '0' NOT NULL
);
pt_namespace NUMBER DEFAULT 0 NOT NULL,
pt_title VARCHAR2(255) NOT NULL,
pt_user NUMBER NOT NULL,
- pt_reason VARCHAR2(255),
- pt_reason_id NUMBER DEFAULT 0 NOT NULL,
+ pt_reason_id NUMBER NOT NULL,
pt_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL,
pt_expiry VARCHAR2(14) NOT NULL,
pt_create_perm VARCHAR2(60) NOT NULL
$rev = null;
$mainPage = Title::newMainPage();
- $pageId = $mainPage ? $mainPage->getArticleId() : null;
+ $pageId = $mainPage ? $mainPage->getArticleID() : null;
if ( $pageId ) {
$rev = $dbw->selectRow(
'revision',
ar_page_id INTEGER NULL,
ar_parent_id INTEGER NULL,
ar_sha1 TEXT NOT NULL DEFAULT '',
- ar_comment TEXT NOT NULL DEFAULT '',
- ar_comment_id INTEGER NOT NULL DEFAULT 0,
+ ar_comment_id INTEGER NOT NULL,
ar_user INTEGER NOT NULL DEFAULT 0 REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
ar_user_text TEXT NOT NULL DEFAULT '',
ar_actor INTEGER NOT NULL DEFAULT 0,
ipb_by INTEGER NOT NULL DEFAULT 0 REFERENCES mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
ipb_by_text TEXT NOT NULL DEFAULT '',
ipb_by_actor INTEGER NOT NULL DEFAULT 0,
- ipb_reason TEXT NOT NULL DEFAULT '',
- ipb_reason_id INTEGER NOT NULL DEFAULT 0,
+ ipb_reason_id INTEGER NOT NULL,
ipb_timestamp TIMESTAMPTZ NOT NULL,
ipb_auto SMALLINT NOT NULL DEFAULT 0,
ipb_anon_only SMALLINT NOT NULL DEFAULT 0,
img_media_type TEXT,
img_major_mime TEXT DEFAULT 'unknown',
img_minor_mime TEXT DEFAULT 'unknown',
- img_description TEXT NOT NULL DEFAULT '',
- img_description_id INTEGER NOT NULL DEFAULT 0,
+ img_description_id INTEGER NOT NULL,
img_user INTEGER NOT NULL DEFAULT 0 REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
img_user_text TEXT NOT NULL DEFAULT '',
img_actor INTEGER NOT NULL DEFAULT 0,
oi_width INTEGER NOT NULL,
oi_height INTEGER NOT NULL,
oi_bits SMALLINT NULL,
- oi_description TEXT NOT NULL DEFAULT '',
- oi_description_id INTEGER NOT NULL DEFAULT 0,
+ oi_description_id INTEGER NOT NULL,
oi_user INTEGER NOT NULL DEFAULT 0 REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
oi_user_text TEXT NOT NULL DEFAULT '',
oi_actor INTEGER NOT NULL DEFAULT 0,
fa_storage_key TEXT,
fa_deleted_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
fa_deleted_timestamp TIMESTAMPTZ NOT NULL,
- fa_deleted_reason TEXT NOT NULL DEFAULT '',
- fa_deleted_reason_id INTEGER NOT NULL DEFAULT 0,
+ fa_deleted_reason_id INTEGER NOT NULL,
fa_size INTEGER NOT NULL,
fa_width INTEGER NOT NULL,
fa_height INTEGER NOT NULL,
fa_media_type TEXT,
fa_major_mime TEXT DEFAULT 'unknown',
fa_minor_mime TEXT DEFAULT 'unknown',
- fa_description TEXT NOT NULL DEFAULT '',
- fa_description_id INTEGER NOT NULL DEFAULT 0,
+ fa_description_id INTEGER NOT NULL,
fa_user INTEGER NOT NULL DEFAULT 0 REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
fa_user_text TEXT NOT NULL DEFAULT '',
fa_actor INTEGER NOT NULL DEFAULT 0,
rc_actor INTEGER NOT NULL DEFAULT 0,
rc_namespace SMALLINT NOT NULL,
rc_title TEXT NOT NULL,
- rc_comment TEXT NOT NULL DEFAULT '',
- rc_comment_id INTEGER NOT NULL DEFAULT 0,
+ rc_comment_id INTEGER NOT NULL,
rc_minor SMALLINT NOT NULL DEFAULT 0,
rc_bot SMALLINT NOT NULL DEFAULT 0,
rc_new SMALLINT NOT NULL DEFAULT 0,
log_actor INTEGER NOT NULL DEFAULT 0,
log_namespace SMALLINT NOT NULL,
log_title TEXT NOT NULL,
- log_comment TEXT NOT NULL DEFAULT '',
- log_comment_id INTEGER NOT NULL DEFAULT 0,
+ log_comment_id INTEGER NOT NULL,
log_params TEXT,
log_deleted SMALLINT NOT NULL DEFAULT 0,
log_user_text TEXT NOT NULL DEFAULT '',
pt_namespace SMALLINT NOT NULL,
pt_title TEXT NOT NULL,
pt_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
- pt_reason TEXT NOT NULL DEFAULT '',
- pt_reason_id INTEGER NOT NULL DEFAULT 0,
+ pt_reason_id INTEGER NOT NULL,
pt_timestamp TIMESTAMPTZ NOT NULL,
pt_expiry TIMESTAMPTZ NULL,
pt_create_perm TEXT NOT NULL DEFAULT '',
package/LICENSE-MIT:
package/README.md:
+oojs-router:
+ type: tar
+ src: https://registry.npmjs.org/oojs-router/-/oojs-router-0.2.0.tgz
+ integrity: sha384-VngYqdQ3vTDMXbm4e4FUZCCGos7fB0Jkr9V+kBL5MElprK1h0yQZOzBNnMHtSJS/
+ dest:
+ package/dist/oojs-router.js:
+ package/LICENSE:
+ package/AUTHORS.txt:
+ package/History.md:
+
ooui:
type: tar
src: https://registry.npmjs.org/oojs-ui/-/oojs-ui-0.30.2.tgz
--- /dev/null
+--
+-- patch-archive-drop-ar_comment.sql
+--
+-- T166732. Drop old xx_comment fields, and defaults from xx_comment_id fields.
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/archive_tmp;
+CREATE TABLE /*_*/archive_tmp (
+ ar_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ ar_namespace int NOT NULL default 0,
+ ar_title varchar(255) binary NOT NULL default '',
+ ar_comment_id bigint unsigned NOT NULL,
+ ar_user int unsigned NOT NULL default 0,
+ ar_user_text varchar(255) binary NOT NULL DEFAULT '',
+ ar_actor bigint unsigned NOT NULL DEFAULT 0,
+ ar_timestamp binary(14) NOT NULL default '',
+ ar_minor_edit tinyint NOT NULL default 0,
+ ar_rev_id int unsigned NOT NULL,
+ ar_text_id int unsigned NOT NULL DEFAULT 0,
+ ar_deleted tinyint unsigned NOT NULL default 0,
+ ar_len int unsigned,
+ ar_page_id int unsigned,
+ ar_parent_id int unsigned default NULL,
+ ar_sha1 varbinary(32) NOT NULL default '',
+ ar_content_model varbinary(32) DEFAULT NULL,
+ ar_content_format varbinary(64) DEFAULT NULL
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/archive_tmp (
+ ar_id, ar_namespace, ar_title, ar_comment_id, ar_user, ar_user_text, ar_actor,
+ ar_timestamp, ar_minor_edit, ar_rev_id, ar_text_id, ar_deleted,
+ ar_len, ar_page_id, ar_parent_id, ar_sha1, ar_content_model, ar_content_format
+ ) SELECT
+ ar_id, ar_namespace, ar_title, ar_comment_id, ar_user, ar_user_text, ar_actor,
+ ar_timestamp, ar_minor_edit, ar_rev_id, ar_text_id, ar_deleted,
+ ar_len, ar_page_id, ar_parent_id, ar_sha1, ar_content_model, ar_content_format
+ FROM /*_*/archive;
+
+DROP TABLE /*_*/archive;
+ALTER TABLE /*_*/archive_tmp RENAME TO /*_*/archive;
+CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp);
+CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp);
+CREATE INDEX /*i*/ar_actor_timestamp ON /*_*/archive (ar_actor,ar_timestamp);
+CREATE UNIQUE INDEX /*i*/ar_revid_uniq ON /*_*/archive (ar_rev_id);
+
+COMMIT;
--- /dev/null
+--
+-- patch-filearchive-drop-fa_description.sql
+--
+-- T166732. Drop old xx_comment fields, and defaults from xx_comment_id fields.
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/filearchive_tmp;
+CREATE TABLE /*_*/filearchive_tmp (
+ fa_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ fa_name varchar(255) binary NOT NULL default '',
+ fa_archive_name varchar(255) binary default '',
+ fa_storage_group varbinary(16),
+ fa_storage_key varbinary(64) default '',
+ fa_deleted_user int,
+ fa_deleted_timestamp binary(14) default '',
+ fa_deleted_reason_id bigint unsigned NOT NULL,
+ fa_size int unsigned default 0,
+ fa_width int default 0,
+ fa_height int default 0,
+ fa_metadata mediumblob,
+ fa_bits int default 0,
+ fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
+ fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") default "unknown",
+ fa_minor_mime varbinary(100) default "unknown",
+ fa_description_id bigint unsigned NOT NULL,
+ fa_user int unsigned default 0,
+ fa_user_text varchar(255) binary DEFAULT '',
+ fa_actor bigint unsigned NOT NULL DEFAULT 0,
+ fa_timestamp binary(14) default '',
+ fa_deleted tinyint unsigned NOT NULL default 0,
+ fa_sha1 varbinary(32) NOT NULL default ''
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/filearchive_tmp (
+ fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key,
+ fa_deleted_user, fa_deleted_timestamp, fa_deleted_reason_id,
+ fa_size, fa_width, fa_height, fa_metadata, fa_bits,
+ fa_media_type, fa_major_mime, fa_minor_mime, fa_description_id,
+ fa_user, fa_user_text, fa_actor, fa_timestamp, fa_deleted, fa_sha1
+ ) SELECT
+ fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key,
+ fa_deleted_user, fa_deleted_timestamp, fa_deleted_reason_id,
+ fa_size, fa_width, fa_height, fa_metadata, fa_bits,
+ fa_media_type, fa_major_mime, fa_minor_mime, fa_description_id,
+ fa_user, fa_user_text, fa_actor, fa_timestamp, fa_deleted, fa_sha1
+ FROM /*_*/filearchive;
+
+DROP TABLE /*_*/filearchive;
+ALTER TABLE /*_*/filearchive_tmp RENAME TO /*_*/filearchive;
+CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp);
+CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key);
+CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp);
+CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp);
+CREATE INDEX /*i*/fa_actor_timestamp ON /*_*/filearchive (fa_actor,fa_timestamp);
+CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1(10));
+
+COMMIT;
--- /dev/null
+--
+-- patch-image-drop-img_description.sql
+--
+-- T166732. Drop old xx_comment fields, and defaults from xx_comment_id fields.
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/image_tmp;
+CREATE TABLE /*_*/image_tmp (
+ img_name varchar(255) binary NOT NULL default '' PRIMARY KEY,
+ img_size int unsigned NOT NULL default 0,
+ img_width int NOT NULL default 0,
+ img_height int NOT NULL default 0,
+ img_metadata mediumblob NOT NULL,
+ img_bits int NOT NULL default 0,
+ img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
+ img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
+ img_minor_mime varbinary(100) NOT NULL default "unknown",
+ img_description_id bigint unsigned NOT NULL,
+ img_user int unsigned NOT NULL default 0,
+ img_user_text varchar(255) binary NOT NULL DEFAULT '',
+ img_actor bigint unsigned NOT NULL DEFAULT 0,
+ img_timestamp varbinary(14) NOT NULL default '',
+ img_sha1 varbinary(32) NOT NULL default ''
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/image_tmp (
+ img_name, img_size, img_width, img_height, img_metadata, img_bits,
+ img_media_type, img_major_mime, img_minor_mime, img_description_id, img_user,
+ img_user_text, img_actor, img_timestamp, img_sha1
+ ) SELECT
+ img_name, img_size, img_width, img_height, img_metadata, img_bits,
+ img_media_type, img_major_mime, img_minor_mime, img_description_id, img_user,
+ img_user_text, img_actor, img_timestamp, img_sha1
+ FROM /*_*/image;
+
+DROP TABLE /*_*/image;
+ALTER TABLE /*_*/image_tmp RENAME TO /*_*/image;
+CREATE INDEX /*i*/img_user_timestamp ON /*_*/image (img_user,img_timestamp);
+CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp);
+CREATE INDEX /*i*/img_actor_timestamp ON /*_*/image (img_actor,img_timestamp);
+CREATE INDEX /*i*/img_size ON /*_*/image (img_size);
+CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp);
+CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1(10));
+CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,img_minor_mime);
+
+COMMIT;
--- /dev/null
+--
+-- patch-ipblocks-drop-ipb_reason.sql
+--
+-- T166732. Drop old xx_comment fields, and defaults from xx_comment_id fields.
+
+BEGIN;
+
+DROP TABLE IF EXISTS ipblocks_tmp;
+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_by_actor bigint unsigned NOT NULL DEFAULT 0,
+ ipb_reason_id bigint unsigned NOT NULL,
+ ipb_timestamp binary(14) NOT NULL default '',
+ ipb_auto bool NOT NULL default 0,
+ 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,
+ ipb_parent_block_id int default NULL,
+ ipb_sitewide bool NOT NULL default 1
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/ipblocks_tmp (
+ ipb_id, ipb_address, ipb_user, ipb_by, ipb_by_text, ipb_by_actor, ipb_reason_id,
+ ipb_timestamp, ipb_auto, ipb_anon_only, ipb_create_account,
+ ipb_enable_autoblock, ipb_expiry, ipb_range_start, ipb_range_end,
+ ipb_deleted, ipb_block_email, ipb_allow_usertalk, ipb_parent_block_id, ipb_sitewide
+ ) SELECT
+ ipb_id, ipb_address, ipb_user, ipb_by, ipb_by_text, ipb_by_actor, ipb_reason_id,
+ ipb_timestamp, ipb_auto, ipb_anon_only, ipb_create_account,
+ ipb_enable_autoblock, ipb_expiry, ipb_range_start, ipb_range_end,
+ ipb_deleted, ipb_block_email, ipb_allow_usertalk, ipb_parent_block_id, ipb_sitewide
+ FROM /*_*/ipblocks;
+
+DROP TABLE /*_*/ipblocks;
+ALTER TABLE /*_*/ipblocks_tmp RENAME TO /*_*/ipblocks;
+CREATE UNIQUE INDEX /*i*/ipb_address ON /*_*/ipblocks (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only);
+CREATE INDEX /*i*/ipb_user ON /*_*/ipblocks (ipb_user);
+CREATE INDEX /*i*/ipb_range ON /*_*/ipblocks (ipb_range_start(8), ipb_range_end(8));
+CREATE INDEX /*i*/ipb_timestamp ON /*_*/ipblocks (ipb_timestamp);
+CREATE INDEX /*i*/ipb_expiry ON /*_*/ipblocks (ipb_expiry);
+CREATE INDEX /*i*/ipb_parent_block_id ON /*_*/ipblocks (ipb_parent_block_id);
+
+COMMIT;
--- /dev/null
+--
+-- patch-logging-drop-log_comment.sql
+--
+-- T166732. Drop old xx_comment fields, and defaults from xx_comment_id fields.
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/logging_tmp;
+CREATE TABLE /*_*/logging_tmp (
+ log_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ log_type varbinary(32) NOT NULL default '',
+ log_action varbinary(32) NOT NULL default '',
+ log_timestamp binary(14) NOT NULL default '19700101000000',
+ log_user int unsigned NOT NULL default 0,
+ log_user_text varchar(255) binary NOT NULL default '',
+ log_actor bigint unsigned NOT NULL DEFAULT 0,
+ log_namespace int NOT NULL default 0,
+ log_title varchar(255) binary NOT NULL default '',
+ log_page int unsigned NULL,
+ log_comment_id bigint unsigned NOT NULL,
+ log_params blob NOT NULL,
+ log_deleted tinyint unsigned NOT NULL default 0
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/logging_tmp (
+ log_id, log_type, log_action, log_timestamp, log_user, log_user_text, log_actor,
+ log_namespace, log_title, log_page, log_comment_id, log_params, log_deleted
+ ) SELECT
+ log_id, log_type, log_action, log_timestamp, log_user, log_user_text, log_actor,
+ log_namespace, log_title, log_page, log_comment_id, log_params, log_deleted
+ FROM /*_*/logging;
+
+DROP TABLE /*_*/logging;
+ALTER TABLE /*_*/logging_tmp RENAME TO /*_*/logging;
+CREATE INDEX /*i*/type_time ON /*_*/logging (log_type, log_timestamp);
+CREATE INDEX /*i*/user_time ON /*_*/logging (log_user, log_timestamp);
+CREATE INDEX /*i*/actor_time ON /*_*/logging (log_actor, log_timestamp);
+CREATE INDEX /*i*/page_time ON /*_*/logging (log_namespace, log_title, log_timestamp);
+CREATE INDEX /*i*/times ON /*_*/logging (log_timestamp);
+CREATE INDEX /*i*/log_user_type_time ON /*_*/logging (log_user, log_type, log_timestamp);
+CREATE INDEX /*i*/log_actor_type_time ON /*_*/logging (log_actor, log_type, log_timestamp);
+CREATE INDEX /*i*/log_page_id_time ON /*_*/logging (log_page,log_timestamp);
+CREATE INDEX /*i*/log_type_action ON /*_*/logging (log_type, log_action, log_timestamp);
+CREATE INDEX /*i*/log_user_text_type_time ON /*_*/logging (log_user_text, log_type, log_timestamp);
+CREATE INDEX /*i*/log_user_text_time ON /*_*/logging (log_user_text, log_timestamp);
+
+COMMIT;
--- /dev/null
+--
+-- patch-oldimage-drop-oi_description.sql
+--
+-- T166732. Drop old xx_comment fields, and defaults from xx_comment_id fields.
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/oldimage_tmp;
+CREATE TABLE /*_*/oldimage_tmp (
+ oi_name varchar(255) binary NOT NULL default '',
+ oi_archive_name varchar(255) binary NOT NULL default '',
+ oi_size int unsigned NOT NULL default 0,
+ oi_width int NOT NULL default 0,
+ oi_height int NOT NULL default 0,
+ oi_bits int NOT NULL default 0,
+ oi_description_id bigint unsigned NOT NULL,
+ oi_user int unsigned NOT NULL default 0,
+ oi_user_text varchar(255) binary NOT NULL DEFAULT '',
+ oi_actor bigint unsigned NOT NULL DEFAULT 0,
+ oi_timestamp binary(14) NOT NULL default '',
+ oi_metadata mediumblob NOT NULL,
+ oi_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
+ oi_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
+ oi_minor_mime varbinary(100) NOT NULL default "unknown",
+ oi_deleted tinyint unsigned NOT NULL default 0,
+ oi_sha1 varbinary(32) NOT NULL default ''
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/oldimage_tmp (
+ oi_name, oi_archive_name, oi_size, oi_width, oi_height, oi_bits,
+ oi_description_id, oi_user, oi_user_text, oi_actor, oi_timestamp, oi_metadata,
+ oi_media_type, oi_major_mime, oi_minor_mime, oi_deleted, oi_sha1
+ ) SELECT
+ oi_name, oi_archive_name, oi_size, oi_width, oi_height, oi_bits,
+ oi_description_id, oi_user, oi_user_text, oi_actor, oi_timestamp, oi_metadata,
+ oi_media_type, oi_major_mime, oi_minor_mime, oi_deleted, oi_sha1
+ FROM /*_*/oldimage;
+
+DROP TABLE /*_*/oldimage;
+ALTER TABLE /*_*/oldimage_tmp RENAME TO /*_*/oldimage;
+CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp);
+CREATE INDEX /*i*/oi_actor_timestamp ON /*_*/oldimage (oi_actor,oi_timestamp);
+CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp);
+CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name(14));
+CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1(10));
+
+COMMIT;
--- /dev/null
+--
+-- patch-protected_titles-drop-pt_reason.sql
+--
+-- T166732. Drop old xx_comment fields, and defaults from xx_comment_id fields.
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/protected_titles_tmp;
+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_id bigint unsigned NOT NULL,
+ pt_timestamp binary(14) NOT NULL,
+ pt_expiry varbinary(14) NOT NULL default '',
+ pt_create_perm varbinary(60) NOT NULL,
+ PRIMARY KEY (pt_namespace,pt_title)
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/protected_titles_tmp (
+ pt_namespace, pt_title, pt_user, pt_reason_id, pt_timestamp, pt_expiry, pt_create_perm
+ ) SELECT
+ pt_namespace, pt_title, pt_user, pt_reason_id, pt_timestamp, pt_expiry, pt_create_perm
+ FROM /*_*/protected_titles;
+
+DROP TABLE /*_*/protected_titles;
+ALTER TABLE /*_*/protected_titles_tmp RENAME TO /*_*/protected_titles;
+CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp);
+
+COMMIT;
--- /dev/null
+--
+-- patch-recentchanges-drop-rc_comment.sql
+--
+-- T166732. Drop old xx_comment fields, and defaults from xx_comment_id fields.
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/recentchanges_tmp;
+CREATE TABLE /*_*/recentchanges_tmp (
+ rc_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ rc_timestamp varbinary(14) NOT NULL default '',
+ rc_user int unsigned NOT NULL default 0,
+ rc_user_text varchar(255) binary NOT NULL DEFAULT '',
+ rc_actor bigint unsigned NOT NULL DEFAULT 0,
+ rc_namespace int NOT NULL default 0,
+ rc_title varchar(255) binary NOT NULL default '',
+ rc_comment_id bigint unsigned NOT NULL,
+ rc_minor tinyint unsigned NOT NULL default 0,
+ rc_bot tinyint unsigned NOT NULL default 0,
+ rc_new tinyint unsigned NOT NULL default 0,
+ rc_cur_id int unsigned NOT NULL default 0,
+ rc_this_oldid int unsigned NOT NULL default 0,
+ rc_last_oldid int unsigned NOT NULL default 0,
+ rc_type tinyint unsigned NOT NULL default 0,
+ rc_source varchar(16) binary not null default '',
+ rc_patrolled tinyint unsigned NOT NULL default 0,
+ rc_ip varbinary(40) NOT NULL default '',
+ rc_old_len int,
+ rc_new_len int,
+ rc_deleted tinyint unsigned NOT NULL default 0,
+ rc_logid int unsigned NOT NULL default 0,
+ rc_log_type varbinary(255) NULL default NULL,
+ rc_log_action varbinary(255) NULL default NULL,
+ rc_params blob NULL
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/recentchanges_tmp (
+ rc_id, rc_timestamp, rc_user, rc_user_text, rc_actor, rc_namespace, rc_title,
+ rc_comment_id, rc_minor, rc_bot, rc_new, rc_cur_id, rc_this_oldid, rc_last_oldid,
+ rc_type, rc_source, rc_patrolled, rc_ip, rc_old_len, rc_new_len, rc_deleted,
+ rc_logid, rc_log_type, rc_log_action, rc_params
+ ) SELECT
+ rc_id, rc_timestamp, rc_user, rc_user_text, rc_actor, rc_namespace, rc_title,
+ rc_comment_id, rc_minor, rc_bot, rc_new, rc_cur_id, rc_this_oldid, rc_last_oldid,
+ rc_type, rc_source, rc_patrolled, rc_ip, rc_old_len, rc_new_len, rc_deleted,
+ rc_logid, rc_log_type, rc_log_action, rc_params
+ FROM /*_*/recentchanges;
+
+DROP TABLE /*_*/recentchanges;
+ALTER TABLE /*_*/recentchanges_tmp RENAME TO /*_*/recentchanges;
+CREATE INDEX /*i*/rc_timestamp ON /*_*/recentchanges (rc_timestamp);
+CREATE INDEX /*i*/rc_namespace_title_timestamp ON /*_*/recentchanges (rc_namespace, rc_title, rc_timestamp);
+CREATE INDEX /*i*/rc_cur_id ON /*_*/recentchanges (rc_cur_id);
+CREATE INDEX /*i*/new_name_timestamp ON /*_*/recentchanges (rc_new,rc_namespace,rc_timestamp);
+CREATE INDEX /*i*/rc_ip ON /*_*/recentchanges (rc_ip);
+CREATE INDEX /*i*/rc_ns_usertext ON /*_*/recentchanges (rc_namespace, rc_user_text);
+CREATE INDEX /*i*/rc_ns_actor ON /*_*/recentchanges (rc_namespace, rc_actor);
+CREATE INDEX /*i*/rc_user_text ON /*_*/recentchanges (rc_user_text, rc_timestamp);
+CREATE INDEX /*i*/rc_actor ON /*_*/recentchanges (rc_actor, rc_timestamp);
+CREATE INDEX /*i*/rc_name_type_patrolled_timestamp ON /*_*/recentchanges (rc_namespace, rc_type, rc_patrolled, rc_timestamp);
+CREATE INDEX /*i*/rc_this_oldid ON /*_*/recentchanges (rc_this_oldid);
+
+COMMIT;
ar_title varchar(255) binary NOT NULL default '',
-- Basic revision stuff...
- ar_comment varbinary(767) NOT NULL default '', -- Deprecated in favor of ar_comment_id
- ar_comment_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that ar_comment should be used)
+ ar_comment_id bigint unsigned NOT NULL,
ar_user int unsigned NOT NULL default 0, -- Deprecated in favor of ar_actor
ar_user_text varchar(255) binary NOT NULL DEFAULT '', -- Deprecated in favor of ar_actor
ar_actor bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that ar_user/ar_user_text should be used)
-- Actor who made the block.
ipb_by_actor bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that ipb_by/ipb_by_text should be used)
- -- Text comment made by blocker. Deprecated in favor of ipb_reason_id
- ipb_reason varbinary(767) NOT NULL default '',
-
-- Key to comment_id. Text comment made by blocker.
- -- ("DEFAULT 0" is temporary, signaling that ipb_reason should be used)
- ipb_reason_id bigint unsigned NOT NULL DEFAULT 0,
+ ipb_reason_id bigint unsigned NOT NULL,
-- Creation (or refresh) date in standard YMDHMS form.
-- IP blocks expire automatically.
-- Description field as entered by the uploader.
-- This is displayed in image upload history and logs.
- -- Deprecated in favor of img_description_id.
- img_description varbinary(767) NOT NULL default '',
-
- img_description_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that img_description should be used)
+ img_description_id bigint unsigned NOT NULL,
-- user_id and user_name of uploader.
-- Deprecated in favor of img_actor.
oi_width int NOT NULL default 0,
oi_height int NOT NULL default 0,
oi_bits int NOT NULL default 0,
- oi_description varbinary(767) NOT NULL default '', -- Deprecated.
- oi_description_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that oi_description should be used)
+ oi_description_id bigint unsigned NOT NULL,
oi_user int unsigned NOT NULL default 0, -- Deprecated in favor of oi_actor
oi_user_text varchar(255) binary NOT NULL DEFAULT '', -- Deprecated in favor of oi_actor
oi_actor bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that oi_user/oi_user_text should be used)
-- Deletion information, if this file is deleted.
fa_deleted_user int,
fa_deleted_timestamp binary(14) default '',
- fa_deleted_reason varbinary(767) default '', -- Deprecated
- fa_deleted_reason_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that fa_deleted_reason should be used)
+ fa_deleted_reason_id bigint unsigned NOT NULL,
-- Duped fields from image
fa_size int unsigned default 0,
fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") default "unknown",
fa_minor_mime varbinary(100) default "unknown",
- fa_description varbinary(767) default '', -- Deprecated
- fa_description_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that fa_description should be used)
+ fa_description_id bigint unsigned NOT NULL,
fa_user int unsigned default 0, -- Deprecated in favor of fa_actor
fa_user_text varchar(255) binary DEFAULT '', -- Deprecated in favor of fa_actor
fa_actor bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that fa_user/fa_user_text should be used)
rc_title varchar(255) binary NOT NULL default '',
-- as in revision...
- rc_comment varbinary(767) NOT NULL default '', -- Deprecated.
- rc_comment_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that rc_comment should be used)
+ rc_comment_id bigint unsigned NOT NULL,
rc_minor tinyint unsigned NOT NULL default 0,
-- Edits by user accounts with the 'bot' rights key are
log_title varchar(255) binary NOT NULL default '',
log_page int unsigned NULL,
- -- Freeform text. Interpreted as edit history comments.
- -- Deprecated in favor of log_comment_id.
- log_comment varbinary(767) NOT NULL default '',
-
-- Key to comment_id. Comment summarizing the change.
- -- ("DEFAULT 0" is temporary, signaling that log_comment should be used)
- log_comment_id bigint unsigned NOT NULL DEFAULT 0,
+ log_comment_id bigint unsigned NOT NULL,
-- miscellaneous parameters:
-- LF separated list (old system) or serialized PHP array (new system)
pt_namespace int NOT NULL,
pt_title varchar(255) binary NOT NULL,
pt_user int unsigned NOT NULL,
- pt_reason varbinary(767) default '', -- Deprecated.
- pt_reason_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that pt_reason should be used)
+ pt_reason_id bigint unsigned NOT NULL,
pt_timestamp binary(14) NOT NULL,
pt_expiry varbinary(14) NOT NULL default '',
pt_create_perm varbinary(60) NOT NULL,
'scripts' => 'resources/lib/jquery.fullscreen.js',
],
'jquery.getAttrs' => [
- 'targets' => [ 'desktop', 'mobile' ],
'scripts' => 'resources/src/jquery/jquery.getAttrs.js',
'targets' => [ 'desktop', 'mobile' ],
],
'targets' => [ 'mobile', 'desktop' ],
],
'jquery.throttle-debounce' => [
+ 'deprecated' => 'Please use OO.ui.throttle/debounce instead. See '
+ . 'https://phabricator.wikimedia.org/T213426',
'scripts' => 'resources/lib/jquery.ba-throttle-debounce.js',
'targets' => [ 'desktop', 'mobile' ],
],
'deprecated' => true,
'scripts' => 'resources/lib/jquery.ui/jquery.ui.widget.js',
'group' => 'jquery.ui',
+ 'targets' => [ 'desktop', 'mobile' ],
],
// Effects
'jquery.effects.core' => [
+Ed Sanders <esanders@wikimedia.org>
+James D. Forrester <jforrester@wikimedia.org>
Jon Robson <jdlrobson@gmail.com>
+Kunal Mehta <legoktm@member.fsf.org>
+MarcoAurelio <maurelio@tools.wmflabs.org>
+Prateek Saxena <prtksxna@gmail.com>
+Timo Tijhof <krinklemail@gmail.com>
--- /dev/null
+# OOjs Router Release History
+## v0.2.0 / 2019-02-06
+* build: Misc clean up (Timo Tijhof)
+* Code style fixes and refactoring (Ed Sanders)
+* build: Switch to ESLint (Timo Tijhof)
+* Unit tests (Jon Robson)
+* Add .gitreview (Christian Aistleitner)
+* Remove .arcconfig & .arclint (MarcoAurelio)
+* Add jsduck config (Prateek Saxena)
+* build: Update devDependencies (Ed Sanders)
+* Use standard coverage reporting configuration (Kunal Mehta)
+* Update eslint-config-wikimedia to 0.9.0 (Ed Sanders)
+* build: Update devDependencies (Ed Sanders)
+* build: Structure updates (Timo Tijhof)
+* OOjs Router method to provide access to replaceState (Jon Robson)
+* build: Switch from prepublish to prepare for modern npm (James D. Forrester)
+* build: Bump package-lock.json for npm audit (James D. Forrester)
+* build: Add AUTHORS.txt to package manifest (James D. Forrester)
+* AUTHORS.txt: Add everyone from `git shortlog` (James D. Forrester)
+
+## v0.1.0 / 2016-05-05
+* Initial commit (Jon Robson)
+* Add build, CI infrastructure (James D. Forrester)
--- /dev/null
+Copyright 2011-2016 OOjs Team and other contributors.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+++ /dev/null
-Copyright 2011-2016 OOjs Team and other contributors.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/*!
- * OOjs Router v0.1.0
- * https://www.mediawiki.org/wiki/OOjs
+ * OOjs Router v0.2.0
+ * https://www.mediawiki.org/wiki/OOjs_Router
*
- * Copyright 2011-2016 OOjs Team and other contributors.
+ * Copyright 2011-2019 OOjs Team and other contributors.
* Released under the MIT license
- * http://oojs-router.mit-license.org
+ * http://oojs.mit-license.org
*
- * Date: 2016-05-05T19:27:58Z
+ * Date: 2019-02-06T21:26:01Z
*/
( function ( $ ) {
'use strict';
-/**
- * Does hash match entry.path? If it does apply the
- * callback for the Entry object.
- *
- * @method
- * @private
- * @ignore
- * @param {string} hash string to match
- * @param {Object} entry Entry object
- * @return {boolean} Whether hash matches entry.path
- */
-function matchRoute( hash, entry ) {
- var match = hash.match( entry.path );
- if ( match ) {
- entry.callback.apply( this, match.slice( 1 ) );
- return true;
- }
- return false;
-}
-
/**
* Provides navigation routing and location information
*
- * @class Router
- * @mixins OO.EventEmitter
+ * @class OO.Router
+ * @extends OO.Registry
*/
-function Router() {
- var self = this;
- OO.EventEmitter.call( this );
- // use an object instead of an array for routes so that we don't
- // duplicate entries that already exist
- this.routes = {};
+OO.Router = function OoRouter() {
+ var router = this;
+
+ // Parent constructor
+ OO.Router.parent.call( this );
+
this.enabled = true;
this.oldHash = this.getPath();
$( window ).on( 'popstate', function () {
- self.emit( 'popstate' );
+ router.emit( 'popstate' );
} );
$( window ).on( 'hashchange', function () {
- self.emit( 'hashchange' );
+ router.emit( 'hashchange' );
} );
this.on( 'hashchange', function () {
- // ev.originalEvent.newURL is undefined on Android 2.x
- var routeEv;
+ // event.originalEvent.newURL is undefined on Android 2.x
+ var routeEvent;
- if ( self.enabled ) {
- routeEv = $.Event( 'route', {
- path: self.getPath()
+ if ( router.enabled ) {
+ routeEvent = $.Event( 'route', {
+ path: router.getPath()
} );
- self.emit( 'route', routeEv );
+ router.emit( 'route', routeEvent );
- if ( !routeEv.isDefaultPrevented() ) {
- self.checkRoute();
+ if ( !routeEvent.isDefaultPrevented() ) {
+ router.checkRoute();
} else {
// if route was prevented, ignore the next hash change and revert the
// hash to its old value
- self.enabled = false;
- self.navigate( self.oldHash );
+ router.enabled = false;
+ router.navigate( router.oldHash );
}
} else {
- self.enabled = true;
+ router.enabled = true;
}
- self.oldHash = self.getPath();
+ router.oldHash = router.getPath();
} );
-}
-OO.mixinClass( Router, OO.EventEmitter );
+};
+
+/* Inheritance */
+
+OO.inheritClass( OO.Router, OO.Registry );
+
+/* Events */
/**
- * Check the current route and run appropriate callback if it matches.
+ * @event popstate
+ */
+
+/**
+ * @event hashchange
+ */
+
+/**
+ * @event route
+ * @param {jQuery.Event} routeEvent
+ */
+
+/* Static Methods */
+
+/**
+ * Determine if current browser supports this router
*
- * @method
+ * @return {boolean} The browser is supported
*/
-Router.prototype.checkRoute = function () {
- var hash = this.getPath();
+OO.Router.static.isSupported = function () {
+ return 'onhashchange' in window;
+};
- $.each( this.routes, function ( id, entry ) {
- return !matchRoute( hash, entry );
- } );
+/* Methods */
+
+/**
+ * Check the current route and run appropriate callback if it matches.
+ */
+OO.Router.prototype.checkRoute = function () {
+ var id, entry, match,
+ hash = this.getPath();
+
+ for ( id in this.registry ) {
+ entry = this.registry[ id ];
+ match = hash.match( entry.path );
+ if ( match ) {
+ entry.callback.apply( this, match.slice( 1 ) );
+ return;
+ }
+ }
};
/**
* Bind a specific callback to a hash-based route, e.g.
*
* @example
- * route( 'alert', function () { alert( 'something' ); } );
- * route( /hi-(.*)/, function ( name ) { alert( 'Hi ' + name ) } );
+ * addRoute( 'alert', function () { alert( 'something' ); } );
+ * addRoute( /hi-(.*)/, function ( name ) { alert( 'Hi ' + name ) } );
+ *
* Note that after defining all available routes it is up to the caller
* to check the existing route via the checkRoute method.
*
- * @method
- * @param {Object} path string or RegExp to match.
+ * @param {string|RegExp} path Path to match, string or regular expression
* @param {Function} callback Callback to be run when hash changes to one
* that matches.
*/
-Router.prototype.route = function ( path, callback ) {
+OO.Router.prototype.addRoute = function ( path, callback ) {
var entry = {
path: typeof path === 'string' ?
- new RegExp( '^' + path.replace( /[\\^$*+?.()|[\]{}]/g, '\\$&' ) + '$' )
- : path,
+ new RegExp( '^' + path.replace( /[\\^$*+?.()|[\]{}]/g, '\\$&' ) + '$' ) :
+ path,
callback: callback
};
- this.routes[ entry.path ] = entry;
+ this.register( entry.path.toString(), entry );
};
+/**
+ * @deprecated Use #addRoute
+ */
+OO.Router.prototype.route = OO.Router.prototype.addRoute;
+
/**
* Navigate to a specific route.
*
- * @method
- * @param {string} path string with a route (hash without #).
+ * @param {string} title of new page
+ * @param {Object} options
+ * @param {string} options.path e.g. '/path/' or '/path/#foo'
+ * @param {boolean} options.useReplaceState Set replaceStateState to use pushState when you want to
+ * avoid long history queues.
*/
-Router.prototype.navigate = function ( path ) {
- var history = window.history;
+OO.Router.prototype.navigateTo = function ( title, options ) {
+ if ( options.useReplaceState ) {
+ history.replaceState( null, title, options.path );
+ } else {
+ history.pushState( null, title, options.path );
+ }
+};
+
+/**
+ * Navigate to a specific ''hash fragment'' route.
+ *
+ * @param {string} path String with a route (hash without #).
+ * @deprecated use navigateTo instead
+ */
+OO.Router.prototype.navigate = function ( path ) {
// Take advantage of `pushState` when available, to clear the hash and
// not leave `#` in the history. An entry with `#` in the history has
// the side-effect of resetting the scroll position when navigating the
// history.
- if ( path === '' && history && history.pushState ) {
+ if ( path === '' ) {
// To clear the hash we need to cut the hash from the URL.
path = window.location.href.replace( /#.*$/, '' );
history.pushState( null, document.title, path );
}
};
-/**
- * Triggers back on the window
- */
-Router.prototype.goBack = function () {
- window.history.back();
-};
-
/**
* Navigate to the previous route. This is a wrapper for window.history.back
*
- * @method
- * @return {jQuery.Deferred}
+ * @return {jQuery.Promise} Promise which resolves when the back navigation is complete
*/
-Router.prototype.back = function () {
- var deferredRequest = $.Deferred(),
- self = this,
- timeoutID;
+OO.Router.prototype.back = function () {
+ var timeoutID,
+ router = this,
+ deferred = $.Deferred();
this.once( 'popstate', function () {
clearTimeout( timeoutID );
- deferredRequest.resolve();
+ deferred.resolve();
} );
- this.goBack();
+ window.history.back();
// If for some reason (old browser, bug in IE/windows 8.1, etc) popstate doesn't fire,
// resolve manually. Since we don't know for sure which browsers besides IE10/11 have
// See https://connect.microsoft.com/IE/feedback/details/793618/history-back-popstate-not-working-as-expected-in-webview-control
// Give browser a few ms to update its history.
timeoutID = setTimeout( function () {
- self.off( 'popstate' );
- deferredRequest.resolve();
+ router.off( 'popstate' );
+ deferred.resolve();
}, 50 );
- return deferredRequest;
+ return deferred.promise();
};
/**
* Get current path (hash).
*
- * @method
* @return {string} Current path.
*/
-Router.prototype.getPath = function () {
+OO.Router.prototype.getPath = function () {
return window.location.hash.slice( 1 );
};
/**
- * Determine if current browser supports onhashchange event
- *
- * @method
- * @return {boolean}
+ * @deprecated Use static method
*/
-Router.prototype.isSupported = function () {
- return 'onhashchange' in window;
-};
+OO.Router.prototype.isSupported = OO.Router.static.isSupported;
-module.exports = Router;
+if ( typeof module !== 'undefined' && module.exports ) {
+ module.exports = OO.Router;
+}
}( jQuery ) );
* @return array
*/
private function listTables() {
- global $wgCommentTableSchemaMigrationStage, $wgActorTableSchemaMigrationStage;
+ global $wgActorTableSchemaMigrationStage;
$tables = [ 'user', 'user_properties', 'user_former_groups', 'page', 'page_restrictions',
'protected_titles', 'revision', 'ip_changes', 'text', 'pagelinks', 'imagelinks',
'querycache', 'objectcache', 'job', 'l10n_cache', 'redirect', 'querycachetwo',
'archive', 'user_groups', 'page_props', 'category',
'slots', 'content', 'slot_roles', 'content_models',
+ 'comment', 'revision_comment_temp',
];
- if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRITE_BOTH ) {
- // The new tables for comments are in use
- $tables[] = 'comment';
- $tables[] = 'revision_comment_temp';
- }
-
if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
// The new tables for actors are in use
$tables[] = 'actor';
public static function provideInsertRoundTrip() {
$db = wfGetDB( DB_REPLICA ); // for timestamps
- $ipbfields = [
- ];
- $revfields = [
- ];
+ $comment = MediaWikiServices::getInstance()->getCommentStore()
+ ->createComment( wfGetDB( DB_MASTER ), '' );
return [
'recentchanges' => [ 'recentchanges', 'rc_user', 'rc_id', [
'rc_this_oldid' => 42,
'rc_last_oldid' => 41,
'rc_source' => 'test',
+ 'rc_comment_id' => $comment->id,
] ],
'ipblocks' => [ 'ipblocks', 'ipb_by', 'ipb_id', [
'ipb_range_start' => '',
'ipb_range_end' => '',
'ipb_timestamp' => $db->timestamp(),
'ipb_expiry' => $db->getInfinity(),
+ 'ipb_reason_id' => $comment->id,
] ],
'revision' => [ 'revision', 'rev_user', 'rev_id', [
'rev_page' => 42,
'comment',
];
+ protected function getSchemaOverrides( IMaintainableDatabase $db ) {
+ return [
+ 'scripts' => [
+ __DIR__ . '/CommentStoreTest.sql',
+ ],
+ 'drop' => [],
+ 'create' => [ 'commentstore1', 'commentstore2', 'commentstore2_temp' ],
+ 'alter' => [],
+ ];
+ }
+
/**
* Create a store for a particular stage
* @param int $stage
*/
protected function makeStore( $stage ) {
$store = new CommentStore( MediaWikiServices::getInstance()->getContentLanguage(), $stage );
+
+ TestingAccessWrapper::newFromObject( $store )->tempTables += [ 'cs2_comment' => [
+ 'table' => 'commentstore2_temp',
+ 'pk' => 'cs2t_id',
+ 'field' => 'cs2t_comment_id',
+ 'joinPK' => 'cs2_id',
+ 'stage' => MIGRATION_OLD,
+ 'deprecatedIn' => null,
+ ] ];
+
return $store;
}
$this->hideDeprecated( 'CommentStore::newKey' );
$store = CommentStore::newKey( $key );
TestingAccessWrapper::newFromObject( $store )->stage = $stage;
+
+ TestingAccessWrapper::newFromObject( $store )->tempTables += [ 'cs2_comment' => [
+ 'table' => 'commentstore2_temp',
+ 'pk' => 'cs2t_id',
+ 'field' => 'cs2t_comment_id',
+ 'joinPK' => 'cs2_id',
+ 'stage' => MIGRATION_OLD,
+ 'deprecatedIn' => null,
+ ] ];
+
return $store;
}
* @param string $table
* @param string $key
* @param string $pk
- * @param string $extraFields
* @param string|Message $comment
* @param array|null $data
* @param array $expect
*/
- public function testInsertRoundTrip( $table, $key, $pk, $extraFields, $comment, $data, $expect ) {
+ public function testInsertRoundTrip( $table, $key, $pk, $comment, $data, $expect ) {
+ static $id = 1;
+
$expectOld = [
'text' => $expect['text'],
'message' => new RawMessage( '$1', [ $expect['text'] ] ),
];
foreach ( $stages as $writeStage => $possibleReadStages ) {
- if ( $key === 'ipb_reason' ) {
- $extraFields['ipb_address'] = __CLASS__ . "#$writeStage";
- }
-
$wstore = $this->makeStore( $writeStage );
- $usesTemp = $key === 'rev_comment';
+ $usesTemp = $key === 'cs2_comment';
if ( $usesTemp ) {
list( $fields, $callback ) = $wstore->insertWithTempTable(
$this->assertArrayNotHasKey( "{$key}_id", $fields, "new field, stage=$writeStage" );
}
- $this->db->insert( $table, $extraFields + $fields, __METHOD__ );
- $id = $this->db->insertId();
+ $this->db->insert( $table, [ $pk => ++$id ] + $fields, __METHOD__ );
if ( $usesTemp ) {
$callback( $id );
}
* @param string $table
* @param string $key
* @param string $pk
- * @param string $extraFields
* @param string|Message $comment
* @param array|null $data
* @param array $expect
*/
public function testInsertRoundTrip_withKeyConstruction(
- $table, $key, $pk, $extraFields, $comment, $data, $expect
+ $table, $key, $pk, $comment, $data, $expect
) {
+ static $id = 1000;
+
$expectOld = [
'text' => $expect['text'],
'message' => new RawMessage( '$1', [ $expect['text'] ] ),
];
foreach ( $stages as $writeStage => $possibleReadStages ) {
- if ( $key === 'ipb_reason' ) {
- $extraFields['ipb_address'] = __CLASS__ . "#$writeStage";
- }
-
$wstore = $this->makeStoreWithKey( $writeStage, $key );
- $usesTemp = $key === 'rev_comment';
+ $usesTemp = $key === 'cs2_comment';
if ( $usesTemp ) {
list( $fields, $callback ) = $wstore->insertWithTempTable(
$this->assertArrayNotHasKey( "{$key}_id", $fields, "new field, stage=$writeStage" );
}
- $this->db->insert( $table, $extraFields + $fields, __METHOD__ );
- $id = $this->db->insertId();
+ $this->db->insert( $table, [ $pk => ++$id ] + $fields, __METHOD__ );
if ( $usesTemp ) {
$callback( $id );
}
$msgComment = new Message( 'parentheses', [ 'message comment' ] );
$textCommentMsg = new RawMessage( '$1', [ 'text comment' ] );
$nestedMsgComment = new Message( [ 'parentheses', 'rawmessage' ], [ new Message( 'mainpage' ) ] );
- $ipbfields = [
- 'ipb_range_start' => '',
- 'ipb_range_end' => '',
- 'ipb_timestamp' => $db->timestamp(),
- 'ipb_expiry' => $db->getInfinity(),
- ];
- $revfields = [
- 'rev_page' => 42,
- 'rev_text_id' => 42,
- 'rev_len' => 0,
- 'rev_timestamp' => $db->timestamp(),
- ];
$comStoreComment = new CommentStoreComment(
null, 'comment store comment', null, [ 'foo' => 'bar' ]
);
return [
'Simple table, text comment' => [
- 'ipblocks', 'ipb_reason', 'ipb_id', $ipbfields, 'text comment', null, [
+ 'commentstore1', 'cs1_comment', 'cs1_id', 'text comment', null, [
'text' => 'text comment',
'message' => $textCommentMsg,
'data' => null,
]
],
'Simple table, text comment with data' => [
- 'ipblocks', 'ipb_reason', 'ipb_id', $ipbfields, 'text comment', [ 'message' => 42 ], [
+ 'commentstore1', 'cs1_comment', 'cs1_id', 'text comment', [ 'message' => 42 ], [
'text' => 'text comment',
'message' => $textCommentMsg,
'data' => [ 'message' => 42 ],
]
],
'Simple table, message comment' => [
- 'ipblocks', 'ipb_reason', 'ipb_id', $ipbfields, $msgComment, null, [
+ 'commentstore1', 'cs1_comment', 'cs1_id', $msgComment, null, [
'text' => '(message comment)',
'message' => $msgComment,
'data' => null,
]
],
'Simple table, message comment with data' => [
- 'ipblocks', 'ipb_reason', 'ipb_id', $ipbfields, $msgComment, [ 'message' => 42 ], [
+ 'commentstore1', 'cs1_comment', 'cs1_id', $msgComment, [ 'message' => 42 ], [
'text' => '(message comment)',
'message' => $msgComment,
'data' => [ 'message' => 42 ],
]
],
'Simple table, nested message comment' => [
- 'ipblocks', 'ipb_reason', 'ipb_id', $ipbfields, $nestedMsgComment, null, [
+ 'commentstore1', 'cs1_comment', 'cs1_id', $nestedMsgComment, null, [
'text' => '(Main Page)',
'message' => $nestedMsgComment,
'data' => null,
]
],
'Simple table, CommentStoreComment' => [
- 'ipblocks', 'ipb_reason', 'ipb_id', $ipbfields, clone $comStoreComment, [ 'baz' => 'baz' ], [
+ 'commentstore1', 'cs1_comment', 'cs1_id', clone $comStoreComment, [ 'baz' => 'baz' ], [
'text' => 'comment store comment',
'message' => $comStoreComment->message,
'data' => [ 'foo' => 'bar' ],
],
'Revision, text comment' => [
- 'revision', 'rev_comment', 'rev_id', $revfields, 'text comment', null, [
+ 'commentstore2', 'cs2_comment', 'cs2_id', 'text comment', null, [
'text' => 'text comment',
'message' => $textCommentMsg,
'data' => null,
]
],
'Revision, text comment with data' => [
- 'revision', 'rev_comment', 'rev_id', $revfields, 'text comment', [ 'message' => 42 ], [
+ 'commentstore2', 'cs2_comment', 'cs2_id', 'text comment', [ 'message' => 42 ], [
'text' => 'text comment',
'message' => $textCommentMsg,
'data' => [ 'message' => 42 ],
]
],
'Revision, message comment' => [
- 'revision', 'rev_comment', 'rev_id', $revfields, $msgComment, null, [
+ 'commentstore2', 'cs2_comment', 'cs2_id', $msgComment, null, [
'text' => '(message comment)',
'message' => $msgComment,
'data' => null,
]
],
'Revision, message comment with data' => [
- 'revision', 'rev_comment', 'rev_id', $revfields, $msgComment, [ 'message' => 42 ], [
+ 'commentstore2', 'cs2_comment', 'cs2_id', $msgComment, [ 'message' => 42 ], [
'text' => '(message comment)',
'message' => $msgComment,
'data' => [ 'message' => 42 ],
]
],
'Revision, nested message comment' => [
- 'revision', 'rev_comment', 'rev_id', $revfields, $nestedMsgComment, null, [
+ 'commentstore2', 'cs2_comment', 'cs2_id', $nestedMsgComment, null, [
'text' => '(Main Page)',
'message' => $nestedMsgComment,
'data' => null,
]
],
'Revision, CommentStoreComment' => [
- 'revision', 'rev_comment', 'rev_id', $revfields, clone $comStoreComment, [ 'baz' => 'baz' ], [
+ 'commentstore2', 'cs2_comment', 'cs2_id', clone $comStoreComment, [ 'baz' => 'baz' ], [
'text' => 'comment store comment',
'message' => $comStoreComment->message,
'data' => [ 'foo' => 'bar' ],
--- /dev/null
+-- These are carefully crafted to work in all five supported databases
+
+CREATE TABLE /*_*/commentstore1 (
+ cs1_id integer not null,
+ cs1_comment varchar(200),
+ cs1_comment_id integer
+);
+
+CREATE TABLE /*_*/commentstore2 (
+ cs2_id integer not null,
+ cs2_comment varchar(200)
+);
+
+CREATE TABLE /*_*/commentstore2_temp (
+ cs2t_id integer not null,
+ cs2t_comment_id integer
+);
return $fields;
}
- protected function getOldCommentQueryFields( $prefix ) {
- return [
- "{$prefix}_comment_text" => "{$prefix}_comment",
- "{$prefix}_comment_data" => 'NULL',
- "{$prefix}_comment_cid" => 'NULL',
- ];
- }
-
- protected function getCompatCommentQueryFields( $prefix ) {
- return [
- "{$prefix}_comment_text"
- => "COALESCE( comment_{$prefix}_comment.comment_text, {$prefix}_comment )",
- "{$prefix}_comment_data" => "comment_{$prefix}_comment.comment_data",
- "{$prefix}_comment_cid" => "comment_{$prefix}_comment.comment_id",
- ];
- }
-
protected function getNewCommentQueryFields( $prefix ) {
return [
"{$prefix}_comment_text" => "comment_{$prefix}_comment.comment_text",
];
}
- protected function getCompatCommentJoins( $prefix ) {
- return [
- "temp_{$prefix}_comment" => [
- "LEFT JOIN",
- "temp_{$prefix}_comment.revcomment_{$prefix} = {$prefix}_id",
- ],
- "comment_{$prefix}_comment" => [
- "LEFT JOIN",
- "comment_{$prefix}_comment.comment_id = temp_{$prefix}_comment.revcomment_comment_id",
- ],
- ];
- }
-
protected function getTextQueryFields() {
return [
'old_text',
yield 'MCR, comment, actor' => [
[
'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_NEW,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
],
[
'wgContentHandlerUseDB' => true,
'wgMultiContentRevisionSchemaMigrationStage'
=> SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_WRITE_NEW,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
],
[
'fields' => array_merge(
$this->getArchiveQueryFields( false ),
$this->getNewActorQueryFields( 'ar' ),
- $this->getCompatCommentQueryFields( 'ar' )
+ $this->getNewCommentQueryFields( 'ar' )
),
'joins' => [
'comment_ar_comment'
- => [ 'LEFT JOIN', 'comment_ar_comment.comment_id = ar_comment_id' ],
+ => [ 'JOIN', 'comment_ar_comment.comment_id = ar_comment_id' ],
'actor_ar_user' => [ 'JOIN', 'actor_ar_user.actor_id = ar_actor' ],
],
]
'wgContentHandlerUseDB' => true,
'wgMultiContentRevisionSchemaMigrationStage'
=> SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_WRITE_BOTH,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
],
[
$this->getArchiveQueryFields( true ),
$this->getContentHandlerQueryFields( 'ar' ),
$this->getOldActorQueryFields( 'ar' ),
- $this->getCompatCommentQueryFields( 'ar' )
+ $this->getNewCommentQueryFields( 'ar' )
),
'joins' => [
'comment_ar_comment'
- => [ 'LEFT JOIN', 'comment_ar_comment.comment_id = ar_comment_id' ],
+ => [ 'JOIN', 'comment_ar_comment.comment_id = ar_comment_id' ],
],
]
];
[
'wgContentHandlerUseDB' => false,
'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_OLD,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
],
[
'tables' => [
'archive',
+ 'comment_ar_comment' => 'comment',
],
'fields' => array_merge(
$this->getArchiveQueryFields( true ),
$this->getOldActorQueryFields( 'ar' ),
- $this->getOldCommentQueryFields( 'ar' )
+ $this->getNewCommentQueryFields( 'ar' )
),
- 'joins' => [],
+ 'joins' => [
+ 'comment_ar_comment'
+ => [ 'JOIN', 'comment_ar_comment.comment_id = ar_comment_id' ],
+ ],
]
];
}
[
'wgContentHandlerUseDB' => true,
'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_NEW,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
],
[ 'page', 'user' ],
'wgContentHandlerUseDB' => true,
'wgMultiContentRevisionSchemaMigrationStage'
=> SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_WRITE_NEW,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
],
[ 'page', 'user' ],
$this->getPageQueryFields(),
$this->getUserQueryFields(),
$this->getNewActorQueryFields( 'rev', 'temp_rev_user.revactor_actor' ),
- $this->getCompatCommentQueryFields( 'rev' )
+ $this->getNewCommentQueryFields( 'rev' )
),
'joins' => array_merge(
[
'user_id = actor_rev_user.actor_user',
]
],
+ 'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+ 'comment_rev_comment'
+ => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
],
- $this->getNewActorJoins( 'rev' ),
- $this->getCompatCommentJoins( 'rev' )
+ $this->getNewActorJoins( 'rev' )
),
]
];
'wgContentHandlerUseDB' => true,
'wgMultiContentRevisionSchemaMigrationStage'
=> SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_WRITE_NEW,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
],
[ 'page', 'user' ],
$this->getPageQueryFields(),
$this->getUserQueryFields(),
$this->getNewActorQueryFields( 'rev', 'temp_rev_user.revactor_actor' ),
- $this->getCompatCommentQueryFields( 'rev' )
+ $this->getNewCommentQueryFields( 'rev' )
),
'joins' => array_merge(
[
'user_id = actor_rev_user.actor_user'
]
],
+ 'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+ 'comment_rev_comment'
+ => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
],
- $this->getNewActorJoins( 'rev' ),
- $this->getCompatCommentJoins( 'rev' )
+ $this->getNewActorJoins( 'rev' )
),
]
];
'wgContentHandlerUseDB' => true,
'wgMultiContentRevisionSchemaMigrationStage'
=> SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_WRITE_BOTH,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
],
[],
$this->getRevisionQueryFields( true ),
$this->getContentHandlerQueryFields( 'rev' ),
$this->getOldActorQueryFields( 'rev', 'temp_rev_user.revactor_actor' ),
- $this->getCompatCommentQueryFields( 'rev' )
+ $this->getNewCommentQueryFields( 'rev' )
),
- 'joins' => array_merge(
- $this->getCompatCommentJoins( 'rev' )
- ),
+ 'joins' => [
+ 'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+ 'comment_rev_comment'
+ => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
+ ],
]
];
yield 'MCR write-both/read-old, page, user' => [
'wgContentHandlerUseDB' => true,
'wgMultiContentRevisionSchemaMigrationStage'
=> SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_WRITE_BOTH,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
],
[ 'page', 'user' ],
$this->getUserQueryFields(),
$this->getPageQueryFields(),
$this->getOldActorQueryFields( 'rev', 'temp_rev_user.revactor_actor' ),
- $this->getCompatCommentQueryFields( 'rev' )
+ $this->getNewCommentQueryFields( 'rev' )
),
'joins' => array_merge(
[
'user_id = rev_user'
]
],
- ],
- $this->getCompatCommentJoins( 'rev' )
+ 'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+ 'comment_rev_comment'
+ => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
+ ]
),
]
];
[
'wgContentHandlerUseDB' => true,
'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_OLD,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
],
[],
[
- 'tables' => [ 'revision' ],
+ 'tables' => [
+ 'revision',
+ 'temp_rev_comment' => 'revision_comment_temp',
+ 'comment_rev_comment' => 'comment',
+ ],
'fields' => array_merge(
$this->getRevisionQueryFields( true ),
$this->getContentHandlerQueryFields( 'rev' ),
$this->getOldActorQueryFields( 'rev' ),
- $this->getOldCommentQueryFields( 'rev' )
+ $this->getNewCommentQueryFields( 'rev' )
),
- 'joins' => [],
+ 'joins' => [
+ 'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+ 'comment_rev_comment'
+ => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
+ ],
]
];
yield 'pre-MCR, page, user' => [
[
'wgContentHandlerUseDB' => true,
'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_OLD,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
],
[ 'page', 'user' ],
[
- 'tables' => [ 'revision', 'page', 'user' ],
+ 'tables' => [
+ 'revision', 'page', 'user',
+ 'temp_rev_comment' => 'revision_comment_temp',
+ 'comment_rev_comment' => 'comment',
+ ],
'fields' => array_merge(
$this->getRevisionQueryFields( true ),
$this->getContentHandlerQueryFields( 'rev' ),
$this->getPageQueryFields(),
$this->getUserQueryFields(),
$this->getOldActorQueryFields( 'rev' ),
- $this->getOldCommentQueryFields( 'rev' )
+ $this->getNewCommentQueryFields( 'rev' )
),
'joins' => [
'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
'user' => [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
+ 'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+ 'comment_rev_comment'
+ => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
],
]
];
[
'wgContentHandlerUseDB' => false,
'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_OLD,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
],
[],
[
- 'tables' => [ 'revision' ],
+ 'tables' => [
+ 'revision',
+ 'temp_rev_comment' => 'revision_comment_temp',
+ 'comment_rev_comment' => 'comment',
+ ],
'fields' => array_merge(
$this->getRevisionQueryFields( true ),
$this->getOldActorQueryFields( 'rev' ),
- $this->getOldCommentQueryFields( 'rev' )
+ $this->getNewCommentQueryFields( 'rev' )
),
- 'joins' => [],
+ 'joins' => [
+ 'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+ 'comment_rev_comment'
+ => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
+ ],
],
];
yield 'pre-MCR, no model, page' => [
[
'wgContentHandlerUseDB' => false,
'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_OLD,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
],
[ 'page' ],
[
- 'tables' => [ 'revision', 'page' ],
+ 'tables' => [
+ 'revision', 'page',
+ 'temp_rev_comment' => 'revision_comment_temp',
+ 'comment_rev_comment' => 'comment',
+ ],
'fields' => array_merge(
$this->getRevisionQueryFields( true ),
$this->getPageQueryFields(),
$this->getOldActorQueryFields( 'rev' ),
- $this->getOldCommentQueryFields( 'rev' )
+ $this->getNewCommentQueryFields( 'rev' )
),
'joins' => [
'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ], ],
+ 'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+ 'comment_rev_comment'
+ => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
],
],
];
[
'wgContentHandlerUseDB' => false,
'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_OLD,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
],
[ 'user' ],
[
- 'tables' => [ 'revision', 'user' ],
+ 'tables' => [
+ 'revision', 'user',
+ 'temp_rev_comment' => 'revision_comment_temp',
+ 'comment_rev_comment' => 'comment',
+ ],
'fields' => array_merge(
$this->getRevisionQueryFields( true ),
$this->getUserQueryFields(),
$this->getOldActorQueryFields( 'rev' ),
- $this->getOldCommentQueryFields( 'rev' )
+ $this->getNewCommentQueryFields( 'rev' )
),
'joins' => [
'user' => [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
+ 'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+ 'comment_rev_comment'
+ => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
],
],
];
[
'wgContentHandlerUseDB' => false,
'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_OLD,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
],
[ 'text' ],
[
- 'tables' => [ 'revision', 'text' ],
+ 'tables' => [
+ 'revision', 'text',
+ 'temp_rev_comment' => 'revision_comment_temp',
+ 'comment_rev_comment' => 'comment',
+ ],
'fields' => array_merge(
$this->getRevisionQueryFields( true ),
$this->getTextQueryFields(),
$this->getOldActorQueryFields( 'rev' ),
- $this->getOldCommentQueryFields( 'rev' )
+ $this->getNewCommentQueryFields( 'rev' )
),
'joins' => [
'text' => [ 'INNER JOIN', [ 'rev_text_id=old_id' ] ],
+ 'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+ 'comment_rev_comment'
+ => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
],
],
];
[
'wgContentHandlerUseDB' => false,
'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_OLD,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
],
[ 'text', 'page', 'user' ],
[
'tables' => [
- 'revision', 'page', 'user', 'text'
+ 'revision', 'page', 'user', 'text',
+ 'temp_rev_comment' => 'revision_comment_temp',
+ 'comment_rev_comment' => 'comment',
],
'fields' => array_merge(
$this->getRevisionQueryFields( true ),
$this->getUserQueryFields(),
$this->getTextQueryFields(),
$this->getOldActorQueryFields( 'rev' ),
- $this->getOldCommentQueryFields( 'rev' )
+ $this->getNewCommentQueryFields( 'rev' )
),
'joins' => [
'page' => [
'INNER JOIN',
[ 'rev_text_id=old_id' ],
],
+ 'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+ 'comment_rev_comment'
+ => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
],
],
];
yield 'with model, comment, and actor' => [
[
'wgContentHandlerUseDB' => true,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_WRITE_BOTH,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
],
'fields' => array_merge(
],
$this->getContentHandlerQueryFields( 'rev' ),
[
- 'rev_comment_old' => 'rev_comment',
'rev_comment_pk' => 'rev_id',
]
),
yield 'no mode, no comment, no actor' => [
[
'wgContentHandlerUseDB' => false,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_OLD,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
],
'fields' => array_merge(
'rev_len',
'rev_parent_id',
'rev_sha1',
- ],
- $this->getOldCommentQueryFields( 'rev' )
+ 'rev_comment_pk' => 'rev_id',
+ ]
),
];
}
yield 'with model, comment, and actor' => [
[
'wgContentHandlerUseDB' => true,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_WRITE_BOTH,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
],
'fields' => array_merge(
],
$this->getContentHandlerQueryFields( 'ar' ),
[
- 'ar_comment_old' => 'ar_comment',
'ar_comment_id' => 'ar_comment_id',
]
),
yield 'no mode, no comment, no actor' => [
[
'wgContentHandlerUseDB' => false,
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_OLD,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
],
'fields' => array_merge(
'ar_len',
'ar_parent_id',
'ar_sha1',
- ],
- $this->getOldCommentQueryFields( 'ar' )
+ 'ar_comment_id' => 'ar_comment_id',
+ ]
),
];
}
$this->setMwGlobals( [
'wgMultiContentRevisionSchemaMigrationStage' => $this->getMcrMigrationStage(),
'wgContentHandlerUseDB' => $this->getContentHandlerUseDB(),
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_NEW,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
] );
$this->setMwGlobals( [
'wgMultiContentRevisionSchemaMigrationStage' => $this->getMcrMigrationStage(),
'wgContentHandlerUseDB' => $this->getContentHandlerUseDB(),
- 'wgCommentTableSchemaMigrationStage' => MIGRATION_NEW,
'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
] );
* @covers \MediaWiki\Revision\RevisionStore::newMutableRevisionFromArray
*/
public function testConstructFromRowWithBadPageId() {
- $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_NEW );
$this->overrideMwServices();
Wikimedia\suppressWarnings();
$rev = new Revision( (object)[
* @covers Revision::loadFromTitle
*/
public function testLoadFromTitle() {
- $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_NEW );
$this->setMwGlobals( 'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_OLD );
$this->overrideMwServices();
$title = $this->getMockTitle();
/**
* @dataProvider provideGetWikiIdFromDomain
- * @covers WikiMap::getWikiIdFromDomain()
+ * @covers WikiMap::getWikiIdFromDbDomain()
*/
public function testGetWikiIdFromDomain( $domain, $wikiId ) {
- $this->assertEquals( $wikiId, WikiMap::getWikiIdFromDomain( $domain ) );
+ $this->assertEquals( $wikiId, WikiMap::getWikiIdFromDbDomain( $domain ) );
}
/**
- * @covers WikiMap::isCurrentWikiDomain()
- * @covers WikiMap::getCurrentWikiDomain()
+ * @covers WikiMap::isCurrentWikiDbDomain()
+ * @covers WikiMap::getCurrentWikiDbDomain()
*/
public function testIsCurrentWikiDomain() {
- $this->assertTrue( WikiMap::isCurrentWikiDomain( wfWikiID() ) );
+ $this->assertTrue( WikiMap::isCurrentWikiDbDomain( wfWikiID() ) );
$localDomain = DatabaseDomain::newFromId( wfWikiID() );
$domain1 = new DatabaseDomain(
$domain2 = new DatabaseDomain(
$localDomain->getDatabase(), null, $localDomain->getTablePrefix() );
- $this->assertTrue( WikiMap::isCurrentWikiDomain( $domain1 ), 'Schema ignored' );
- $this->assertTrue( WikiMap::isCurrentWikiDomain( $domain2 ), 'Schema ignored' );
+ $this->assertTrue( WikiMap::isCurrentWikiDbDomain( $domain1 ), 'Schema ignored' );
+ $this->assertTrue( WikiMap::isCurrentWikiDbDomain( $domain2 ), 'Schema ignored' );
- $this->assertTrue( WikiMap::isCurrentWikiDomain( WikiMap::getCurrentWikiDomain() ) );
+ $this->assertTrue( WikiMap::isCurrentWikiDbDomain( WikiMap::getCurrentWikiDbDomain() ) );
}
public function provideIsCurrentWikiId() {
/**
* @dataProvider provideIsCurrentWikiId
* @covers WikiMap::isCurrentWikiId()
- * @covers WikiMap::getCurrentWikiDomain()
- * @covers WikiMap::getWikiIdFromDomain()
+ * @covers WikiMap::getCurrentWikiDbDomain()
+ * @covers WikiMap::getWikiIdFromDbDomain()
*/
public function testIsCurrentWikiId( $wikiId, $db, $schema, $prefix ) {
$this->setMwGlobals(
self::$repl['revA2'] = $this->addPage( 'A', 'A 2' );
self::$repl['revA3'] = $this->addPage( 'A', 'A 3' );
self::$repl['revA4'] = $this->addPage( 'A', 'A 4' );
- self::$repl['pageA'] = Title::newFromText( 'ApiComparePagesTest A' )->getArticleId();
+ self::$repl['pageA'] = Title::newFromText( 'ApiComparePagesTest A' )->getArticleID();
self::$repl['revB1'] = $this->addPage( 'B', 'B 1' );
self::$repl['revB2'] = $this->addPage( 'B', 'B 2' );
self::$repl['revB3'] = $this->addPage( 'B', 'B 3' );
self::$repl['revB4'] = $this->addPage( 'B', 'B 4' );
- self::$repl['pageB'] = Title::newFromText( 'ApiComparePagesTest B' )->getArticleId();
+ self::$repl['pageB'] = Title::newFromText( 'ApiComparePagesTest B' )->getArticleID();
self::$repl['revC1'] = $this->addPage( 'C', 'C 1' );
self::$repl['revC2'] = $this->addPage( 'C', 'C 2' );
self::$repl['revC3'] = $this->addPage( 'C', 'C 3' );
- self::$repl['pageC'] = Title::newFromText( 'ApiComparePagesTest C' )->getArticleId();
+ self::$repl['pageC'] = Title::newFromText( 'ApiComparePagesTest C' )->getArticleID();
$id = $this->addPage( 'D', 'D 1' );
- self::$repl['pageD'] = Title::newFromText( 'ApiComparePagesTest D' )->getArticleId();
+ self::$repl['pageD'] = Title::newFromText( 'ApiComparePagesTest D' )->getArticleID();
wfGetDB( DB_MASTER )->delete( 'revision', [ 'rev_id' => $id ] );
self::$repl['revE1'] = $this->addPage( 'E', 'E 1' );
self::$repl['revE2'] = $this->addPage( 'E', 'E 2' );
self::$repl['revE3'] = $this->addPage( 'E', 'E 3' );
self::$repl['revE4'] = $this->addPage( 'E', 'E 4' );
- self::$repl['pageE'] = Title::newFromText( 'ApiComparePagesTest E' )->getArticleId();
+ self::$repl['pageE'] = Title::newFromText( 'ApiComparePagesTest E' )->getArticleID();
wfGetDB( DB_MASTER )->update(
'page', [ 'page_latest' => 0 ], [ 'page_id' => self::$repl['pageE'] ]
);
self::$repl['revF1'] = $this->addPage( 'F', "== Section 1 ==\nF 1.1\n\n== Section 2 ==\nF 1.2" );
- self::$repl['pageF'] = Title::newFromText( 'ApiComparePagesTest F' )->getArticleId();
+ self::$repl['pageF'] = Title::newFromText( 'ApiComparePagesTest F' )->getArticleID();
self::$repl['revG1'] = $this->addPage( 'G', "== Section 1 ==\nG 1.1", CONTENT_MODEL_TEXT );
- self::$repl['pageG'] = Title::newFromText( 'ApiComparePagesTest G' )->getArticleId();
+ self::$repl['pageG'] = Title::newFromText( 'ApiComparePagesTest G' )->getArticleID();
WikiPage::factory( Title::newFromText( 'ApiComparePagesTest C' ) )
->doDeleteArticleReal( 'Test for ApiComparePagesTest' );
$this->assertSame( $toTitle->getPrefixedText(), $target->getPrefixedText() );
}
- $this->assertSame( $id, $toTitle->getArticleId() );
+ $this->assertSame( $id, $toTitle->getArticleID() );
}
/**
'to' => '[',
] );
} finally {
- $this->assertSame( $id, Title::newFromText( $name )->getArticleId() );
+ $this->assertSame( $id, Title::newFromText( $name )->getArticleID() );
}
}
'to' => "$name 3",
] );
} finally {
- $this->assertSame( $id, Title::newFromText( "$name 2" )->getArticleId() );
+ $this->assertSame( $id, Title::newFromText( "$name 2" )->getArticleID() );
$this->assertFalse( Title::newFromText( "$name 3" )->exists(),
"\"$name 3\" should not exist" );
}
'tags' => 'custom tag',
] );
} finally {
- $this->assertSame( $id, Title::newFromText( $name )->getArticleId() );
+ $this->assertSame( $id, Title::newFromText( $name )->getArticleID() );
$this->assertFalse( Title::newFromText( "$name 2" )->exists(),
"\"$name 2\" should not exist" );
}
] );
$this->assertMoved( $name, "$name 2", $id );
- $this->assertSame( $talkId, Title::newFromText( "Talk:$name" )->getArticleId() );
+ $this->assertSame( $talkId, Title::newFromText( "Talk:$name" )->getArticleID() );
$this->assertSame( $talkDestinationId,
- Title::newFromText( "Talk:$name 2" )->getArticleId() );
+ Title::newFromText( "Talk:$name 2" )->getArticleID() );
$this->assertSame( [ [
'message' => 'articleexists',
'params' => [],
}
$this->assertSame( $ids["$name/error"],
- Title::newFromText( "$name/error" )->getArticleId() );
+ Title::newFromText( "$name/error" )->getArticleID() );
$this->assertSame( $ids["$name 2/error"],
- Title::newFromText( "$name 2/error" )->getArticleId() );
+ Title::newFromText( "$name 2/error" )->getArticleID() );
$results = array_merge( $res[0]['move']['subpages'], $res[0]['move']['subpages-talk'] );
foreach ( $results as $arr ) {
'to' => "$name 2",
], null, $user );
} finally {
- $this->assertSame( $id, Title::newFromText( "$name" )->getArticleId() );
+ $this->assertSame( $id, Title::newFromText( "$name" )->getArticleID() );
$this->assertFalse( Title::newFromText( "$name 2" )->exists(),
"\"$name 2\" should not exist" );
}
] );
$this->assertMoved( "Talk:$name", $name, $idBase );
- $this->assertSame( $idSub, Title::newFromText( "Talk:$name/1" )->getArticleId() );
+ $this->assertSame( $idSub, Title::newFromText( "Talk:$name/1" )->getArticleID() );
$this->assertFalse( Title::newFromText( "$name/1" )->exists(),
"\"$name/1\" should not exist" );
$restriction = new $class( 1, 1 );
$title = \Title::newFromId( 1 );
- $this->assertEquals( $title->getArticleId(), $restriction->getTitle()->getArticleId() );
+ $this->assertEquals( $title->getArticleID(), $restriction->getTitle()->getArticleID() );
}
public function testNewFromRow() {
protected function assertRecentChangeByCategorization(
Title $pageTitle, ParserOutput $parserOutput, Title $categoryTitle, $expectedRows
) {
- global $wgCommentTableSchemaMigrationStage;
-
- if ( $wgCommentTableSchemaMigrationStage <= MIGRATION_WRITE_BOTH ) {
- $this->assertSelect(
- 'recentchanges',
- 'rc_title, rc_comment',
- [
- 'rc_type' => RC_CATEGORIZE,
- 'rc_namespace' => NS_CATEGORY,
- 'rc_title' => $categoryTitle->getDBkey()
- ],
- $expectedRows
- );
- }
- if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRITE_BOTH ) {
- $this->assertSelect(
- [ 'recentchanges', 'comment' ],
- 'rc_title, comment_text',
- [
- 'rc_type' => RC_CATEGORIZE,
- 'rc_namespace' => NS_CATEGORY,
- 'rc_title' => $categoryTitle->getDBkey(),
- 'comment_id = rc_comment_id',
- ],
- $expectedRows
- );
- }
+ $this->assertSelect(
+ [ 'recentchanges', 'comment' ],
+ 'rc_title, comment_text',
+ [
+ 'rc_type' => RC_CATEGORIZE,
+ 'rc_namespace' => NS_CATEGORY,
+ 'rc_title' => $categoryTitle->getDBkey(),
+ 'comment_id = rc_comment_id',
+ ],
+ $expectedRows
+ );
}
private function runAllRelatedJobs() {
* @param array $selectFields
* @param string[]|null $row
* @param string[]|null $expectedFields
- * @param int $commentMigration
* @param int $actorMigration
*/
public function testNewFromId( $id,
array $selectFields,
array $row = null,
array $expectedFields = null,
- $commentMigration,
$actorMigration
) {
$this->setMwGlobals( [
- 'wgCommentTableSchemaMigrationStage' => $commentMigration,
'wgActorTableSchemaMigrationStage' => $actorMigration,
] );
public function provideNewFromId() {
$oldTables = [
- 'tables' => [ 'logging', 'user' ],
+ 'tables' => [
+ 'logging', 'user',
+ 'comment_log_comment' => 'comment',
+ ],
'fields' => [
'log_id',
'log_type',
'user_id',
'user_name',
'user_editcount',
- 'log_comment_text' => 'log_comment',
- 'log_comment_data' => 'NULL',
- 'log_comment_cid' => 'NULL',
+ 'log_comment_text' => 'comment_log_comment.comment_text',
+ 'log_comment_data' => 'comment_log_comment.comment_data',
+ 'log_comment_cid' => 'comment_log_comment.comment_id',
'log_user' => 'log_user',
'log_user_text' => 'log_user_text',
'log_actor' => 'NULL',
],
'options' => [],
- 'join_conds' => [ 'user' => [ 'LEFT JOIN', 'user_id=log_user' ] ],
+ 'join_conds' => [
+ 'user' => [ 'LEFT JOIN', 'user_id=log_user' ],
+ 'comment_log_comment' => [ 'JOIN', 'comment_log_comment.comment_id = log_comment_id' ],
+ ],
];
$newTables = [
'tables' => [
$oldTables + [ 'conds' => [ 'log_id' => 0 ] ],
null,
null,
- MIGRATION_OLD,
SCHEMA_COMPAT_OLD,
],
[
'log_comment_data' => null,
],
[ 'type' => 'foobarize', 'comment' => 'test!' ],
- MIGRATION_OLD,
SCHEMA_COMPAT_OLD,
],
[
'log_comment_data' => null,
],
[ 'type' => 'foobarize', 'comment' => 'test!' ],
- MIGRATION_NEW,
SCHEMA_COMPAT_NEW,
],
];
$this->tablesUsed += $this->getMcrTablesToReset();
- $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_NEW );
$this->setMwGlobals( 'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_OLD );
$this->setMwGlobals( 'wgContentHandlerUseDB', $this->getContentHandlerUseDB() );
$this->setMwGlobals(
$this->assertTrue( $page->wasLoadedFrom( IDBAccessObject::READ_EXCLUSIVE ) );
}
- /**
- * @dataProvider provideCommentMigrationOnDeletion
- *
- * @param int $writeStage
- * @param int $readStage
- */
- public function testCommentMigrationOnDeletion( $writeStage, $readStage ) {
- $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', $writeStage );
- $this->overrideMwServices();
-
- $dbr = wfGetDB( DB_REPLICA );
-
- $page = $this->createPage(
- __METHOD__,
- "foo",
- CONTENT_MODEL_WIKITEXT
- );
- $revid = $page->getLatest();
- if ( $writeStage > MIGRATION_OLD ) {
- $comment_id = $dbr->selectField(
- 'revision_comment_temp',
- 'revcomment_comment_id',
- [ 'revcomment_rev' => $revid ],
- __METHOD__
- );
- }
-
- $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', $readStage );
- $this->overrideMwServices();
-
- $page->doDeleteArticle( "testing deletion" );
-
- if ( $readStage > MIGRATION_OLD ) {
- // Didn't leave behind any 'revision_comment_temp' rows
- $n = $dbr->selectField(
- 'revision_comment_temp', 'COUNT(*)', [ 'revcomment_rev' => $revid ], __METHOD__
- );
- $this->assertEquals( 0, $n, 'no entry in revision_comment_temp after deletion' );
-
- // Copied or upgraded the comment_id, as applicable
- $ar_comment_id = $dbr->selectField(
- 'archive',
- 'ar_comment_id',
- [ 'ar_rev_id' => $revid ],
- __METHOD__
- );
- if ( $writeStage > MIGRATION_OLD ) {
- $this->assertSame( $comment_id, $ar_comment_id );
- } else {
- $this->assertNotEquals( 0, $ar_comment_id );
- }
- }
-
- // Copied rev_comment, if applicable
- if ( $readStage <= MIGRATION_WRITE_BOTH && $writeStage <= MIGRATION_WRITE_BOTH ) {
- $ar_comment = $dbr->selectField(
- 'archive',
- 'ar_comment',
- [ 'ar_rev_id' => $revid ],
- __METHOD__
- );
- $this->assertSame( 'testing', $ar_comment );
- }
- }
-
- public function provideCommentMigrationOnDeletion() {
- return [
- [ MIGRATION_OLD, MIGRATION_OLD ],
- [ MIGRATION_OLD, MIGRATION_WRITE_BOTH ],
- [ MIGRATION_OLD, MIGRATION_WRITE_NEW ],
- [ MIGRATION_WRITE_BOTH, MIGRATION_OLD ],
- [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_BOTH ],
- [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW ],
- [ MIGRATION_WRITE_BOTH, MIGRATION_NEW ],
- [ MIGRATION_WRITE_NEW, MIGRATION_WRITE_BOTH ],
- [ MIGRATION_WRITE_NEW, MIGRATION_WRITE_NEW ],
- [ MIGRATION_WRITE_NEW, MIGRATION_NEW ],
- [ MIGRATION_NEW, MIGRATION_WRITE_BOTH ],
- [ MIGRATION_NEW, MIGRATION_WRITE_NEW ],
- [ MIGRATION_NEW, MIGRATION_NEW ],
- ];
- }
-
/**
* @covers WikiPage::updateCategoryCounts
*/
$restriction = $restrictions[0];
$this->assertEquals( $page->getId(), $restriction->getValue() );
- $this->assertEquals( $page->getId(), $restriction->getTitle()->getArticleId() );
+ $this->assertEquals( $page->getId(), $restriction->getTitle()->getArticleID() );
$this->assertEquals( $title->getDBKey(), $restriction->getTitle()->getDBKey() );
$this->assertEquals( $title->getNamespace(), $restriction->getTitle()->getNamespace() );
$dbw = wfGetDB( DB_MASTER );
$logs = [];
+ $comment = \MediaWiki\MediaWikiServices::getInstance()->getCommentStore()
+ ->createComment( $dbw, '' );
+
// Manual patrolling
$logs[] = [
'log_type' => 'patrol',
'log_timestamp' => $dbw->timestamp( '20041223210426' ),
'log_namespace' => NS_MAIN,
'log_title' => 'DeleteAutoPatrolLogs',
+ 'log_comment_id' => $comment->id,
];
// Autopatrol #1
'log_timestamp' => $dbw->timestamp( '20051223210426' ),
'log_namespace' => NS_MAIN,
'log_title' => 'DeleteAutoPatrolLogs',
+ 'log_comment_id' => $comment->id,
];
// Block
'log_timestamp' => $dbw->timestamp( '20061223210426' ),
'log_namespace' => NS_MAIN,
'log_title' => 'DeleteAutoPatrolLogs',
+ 'log_comment_id' => $comment->id,
];
// Very old/ invalid patrol
'log_timestamp' => $dbw->timestamp( '20061223210426' ),
'log_namespace' => NS_MAIN,
'log_title' => 'DeleteAutoPatrolLogs',
+ 'log_comment_id' => $comment->id,
];
// Autopatrol #2
'log_timestamp' => $dbw->timestamp( '20071223210426' ),
'log_namespace' => NS_MAIN,
'log_title' => 'DeleteAutoPatrolLogs',
+ 'log_comment_id' => $comment->id,
];
// Autopatrol #3 old way
'log_timestamp' => $dbw->timestamp( '20081223210426' ),
'log_namespace' => NS_MAIN,
'log_title' => 'DeleteAutoPatrolLogs',
+ 'log_comment_id' => $comment->id,
];
// Manual patrol #2 old way
'log_timestamp' => $dbw->timestamp( '20091223210426' ),
'log_namespace' => NS_MAIN,
'log_title' => 'DeleteAutoPatrolLogs',
+ 'log_comment_id' => $comment->id,
];
// Autopatrol #4 very old way
'log_timestamp' => $dbw->timestamp( '20081223210426' ),
'log_namespace' => NS_MAIN,
'log_title' => 'DeleteAutoPatrolLogs',
+ 'log_comment_id' => $comment->id,
];
// Manual patrol #3 very old way
'log_timestamp' => $dbw->timestamp( '20091223210426' ),
'log_namespace' => NS_MAIN,
'log_title' => 'DeleteAutoPatrolLogs',
+ 'log_comment_id' => $comment->id,
];
$dbw->insert( 'logging', $logs );