Merge "maintenance: Explicitly declare all used properties"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 9 Sep 2019 19:11:52 +0000 (19:11 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 9 Sep 2019 19:11:52 +0000 (19:11 +0000)
83 files changed:
RELEASE-NOTES-1.34
api.php
docs/extension.schema.v1.json
docs/extension.schema.v2.json
img_auth.php
includes/ActorMigration.php
includes/DefaultSettings.php
includes/PHPVersionCheck.php
includes/Revision.php
includes/ServiceWiring.php
includes/Setup.php
includes/actions/InfoAction.php
includes/api/ApiQueryAllRevisions.php
includes/api/ApiQueryAllUsers.php
includes/api/ApiQueryContributors.php
includes/api/ApiQueryRevisions.php
includes/api/ApiQueryUserContribs.php
includes/api/ApiQueryUserInfo.php
includes/auth/AuthenticationRequest.php
includes/block/DatabaseBlock.php
includes/cache/UserCache.php
includes/changes/RecentChange.php
includes/dao/DBAccessBase.php
includes/diff/DifferenceEngine.php
includes/filerepo/file/ArchivedFile.php
includes/filerepo/file/LocalFile.php
includes/filerepo/file/LocalFileDeleteBatch.php
includes/filerepo/file/OldLocalFile.php
includes/installer/DatabaseUpdater.php
includes/installer/MysqlUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteUpdater.php
includes/logging/ManualLogEntry.php
includes/page/WikiPage.php
includes/revisiondelete/RevDelList.php
includes/revisiondelete/RevisionDeleteUser.php
includes/specialpage/SpecialPageFactory.php
includes/specials/SpecialContributions.php
includes/specials/SpecialLog.php
includes/specials/SpecialPageData.php
includes/specials/pagers/ActiveUsersPager.php
includes/specials/pagers/NewFilesPager.php
includes/user/User.php
index.php
load.php
maintenance/Maintenance.php
maintenance/archives/patch-drop-user-fields.sql [new file with mode: 0644]
maintenance/getReplicaServer.php
maintenance/includes/MigrateActors.php
maintenance/postgres/tables.sql
maintenance/reassignEdits.php
maintenance/removeUnusedAccounts.php
maintenance/sqlite/archives/patch-archive-drop-ar_user.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-filearchive-drop-fa_user.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-image-drop-img_user.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-ipblocks-drop-ipb_by.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-logging-drop-log_user.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-oldimage-drop-oi_user.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-recentchanges-drop-rc_user.sql [new file with mode: 0644]
maintenance/tables.sql
opensearch_desc.php
profileinfo.php
resources/Resources.php
resources/src/mediawiki.RegExp.js [deleted file]
resources/src/mediawiki.Title/Title.js
resources/src/mediawiki.util/util.js
rest.php
tests/parser/ParserTestRunner.php
tests/phpunit/includes/ActorMigrationTest.php
tests/phpunit/includes/ActorMigrationTest.sql [new file with mode: 0644]
tests/phpunit/includes/Revision/RevisionQueryInfoTest.php
tests/phpunit/includes/Revision/RevisionStoreDbTestBase.php
tests/phpunit/includes/RevisionDbTestBase.php
tests/phpunit/includes/RevisionTest.php
tests/phpunit/includes/api/query/ApiQueryUserContribsTest.php
tests/phpunit/includes/logging/DatabaseLogEntryTest.php
tests/phpunit/includes/page/PageArchiveTestBase.php
tests/phpunit/includes/specialpage/ChangesListSpecialPageTest.php
tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php
tests/phpunit/includes/user/UserTest.php
tests/phpunit/maintenance/deleteAutoPatrolLogsTest.php
thumb.php
thumb_handler.php

index d764b48..9ac26e8 100644 (file)
@@ -91,6 +91,8 @@ $wgPasswordPolicy['policies']['default']['PasswordNotInLargeBlacklist'] = false;
 * $wgDBOracleDRCP - If you must use persistent connections, set DBO_PERSISTENT
   in the 'flags' field for servers in $wgDBServers (or $wgLBFactoryConf).
 * $wgMemCachedDebug - Set the cache "debug" field in $wgObjectCaches instead.
+* $wgActorTableSchemaMigrationStage has been removed. Extension code for
+  MediaWiki 1.31+ finding it unset should treat it as being SCHEMA_COMPAT_NEW.
 
 === New user-facing features in 1.34 ===
 * Special:Mute has been added as a quick way for users to block unwanted emails
@@ -118,6 +120,9 @@ $wgPasswordPolicy['policies']['default']['PasswordNotInLargeBlacklist'] = false;
   GetBlockedStatus.
 * ObjectFactory is available as a service. When used as a service, the object
   specs can now specify needed DI services.
+* (T222388) Special pages can now be specified as an ObjectFactory spec,
+  allowing the construction of special pages that require services to be
+  injected in their constructor.
 
 === External library changes in 1.34 ===
 
@@ -372,7 +377,19 @@ because of Phabricator reports.
   should only be used to unblock a blocked user.
 * Parameters for index.php from PATH_INFO, such as the title, are no longer
   written to $_GET.
-* â€¦
+* The selectFields() methods on classes LocalFile, ArchivedFile, OldLocalFile,
+  DatabaseBlock, and RecentChange, deprecated in 1.31, have been removed. Use
+  the corresponding getQueryInfo() methods instead.
+* The following methods on Revision, deprecated since 1.31, have been removed.
+  Use RevisionStore::getQueryInfo() or RevisionStore::getArchiveQueryInfo()
+  instead.
+  * Revision::userJoinCond()
+  * Revision::pageJoinCond()
+  * Revision::selectFields()
+  * Revision::selectArchiveFields()
+  * Revision::selectTextFields()
+  * Revision::selectPageFields()
+  * Revision::selectUserFields()
 
 === Deprecations in 1.34 ===
 * The MWNamespace class is deprecated. Use NamespaceInfo.
@@ -493,6 +510,13 @@ because of Phabricator reports.
   or extend RevisionSearchResult.
 * Skin::getSkinNameMessages() is deprecated and no longer used.
 * The mediawiki.RegExp module is deprecated; use mw.util.escapeRegExp() instead.
+* Specifying a SpecialPage object for the list of special pages (either through
+  the SpecialPage_initList hook or by adding to $wgSpecialPages) is now
+  deprecated.
+* Use of ActorMigration with 'ar_user', 'img_user', 'oi_user', 'fa_user',
+  'rc_user', 'log_user', and 'ipb_by' is deprecated. Queries should be adjusted
+  to use the corresponding actor fields directly. Note that use with
+  'rev_user' is *not* deprecated at this time.
 
 === Other changes in 1.34 ===
 * â€¦
diff --git a/api.php b/api.php
index fe13263..6f4bac3 100644 (file)
--- a/api.php
+++ b/api.php
@@ -31,6 +31,7 @@ use MediaWiki\Logger\LegacyLogger;
 
 // So extensions (and other code) can check whether they're running in API mode
 define( 'MW_API', true );
+define( 'MW_ENTRY_POINT', 'api' );
 
 require __DIR__ . '/includes/WebStart.php';
 
index 9ce016f..06701cd 100644 (file)
                },
                "SpecialPages": {
                        "type": "object",
-                       "description": "SpecialPages implemented in this extension (mapping of page name to class name)"
+                       "description": "SpecialPages implemented in this extension (mapping of page name to class name or to ObjectFactory spec)"
                },
                "AutoloadNamespaces": {
                        "type": "object",
index 9d874f4..56d274b 100644 (file)
                },
                "SpecialPages": {
                        "type": "object",
-                       "description": "SpecialPages implemented in this extension (mapping of page name to class name)"
+                       "description": "SpecialPages implemented in this extension (mapping of page name to class name or to ObjectFactory spec)"
                },
                "AutoloadNamespaces": {
                        "type": "object",
index 6e45e4e..f23de4f 100644 (file)
@@ -39,6 +39,7 @@
  */
 
 define( 'MW_NO_OUTPUT_COMPRESSION', 1 );
+define( 'MW_ENTRY_POINT', 'img_auth' );
 require __DIR__ . '/includes/WebStart.php';
 
 # Set action base paths so that WebRequest::getPathInfo()
index 5dde8a0..c79074d 100644 (file)
@@ -28,15 +28,18 @@ use Wikimedia\Rdbms\IDatabase;
  * This class handles the logic for the actor table migration.
  *
  * This is not intended to be a long-term part of MediaWiki; it will be
- * deprecated and removed along with $wgActorTableSchemaMigrationStage.
+ * deprecated and removed once actor migration is complete.
  *
  * @since 1.31
+ * @since 1.34 Use with 'ar_user', 'img_user', 'oi_user', 'fa_user',
+ *  'rc_user', 'log_user', and 'ipb_by' is deprecated. Callers should
+ *  reference the corresponding actor fields directly.
  */
 class ActorMigration {
 
        /**
         * Constant for extensions to feature-test whether $wgActorTableSchemaMigrationStage
-        * expects MIGRATION_* or SCHEMA_COMPAT_*
+        * (in MW <1.34) expects MIGRATION_* or SCHEMA_COMPAT_*
         */
        const MIGRATION_STAGE_SCHEMA_COMPAT = 1;
 
@@ -68,6 +71,28 @@ class ActorMigration {
         */
        private static $formerTempTables = [];
 
+       /**
+        * Define fields that are deprecated for use with this class.
+        * @var (string|null)[] Keys are '$key', value is null for soft deprecation
+        *  or a string naming the deprecated version for hard deprecation.
+        */
+       private static $deprecated = [
+               'ar_user' => null, // 1.34
+               'img_user' => null, // 1.34
+               'oi_user' => null, // 1.34
+               'fa_user' => null, // 1.34
+               'rc_user' => null, // 1.34
+               'log_user' => null, // 1.34
+               'ipb_by' => null, // 1.34
+       ];
+
+       /**
+        * Define fields that are removed for use with this class.
+        * @var string[] Keys are '$key', value is the MediaWiki version in which
+        *  use was removed.
+        */
+       private static $removed = [];
+
        /**
         * Define fields that use non-standard mapping
         * @var array Keys are the user id column name, values are arrays with two
@@ -112,6 +137,21 @@ class ActorMigration {
                return MediaWikiServices::getInstance()->getActorMigration();
        }
 
+       /**
+        * Issue deprecation warning/error as appropriate.
+        * @param string $key
+        */
+       private static function checkDeprecation( $key ) {
+               if ( isset( self::$removed[$key] ) ) {
+                       throw new InvalidArgumentException(
+                               "Use of " . static::class . " for '$key' was removed in MediaWiki " . self::$removed[$key]
+                       );
+               }
+               if ( !empty( self::$deprecated[$key] ) ) {
+                       wfDeprecated( static::class . " for '$key'", self::$deprecated[$key], false, 3 );
+               }
+       }
+
        /**
         * Return an SQL condition to test if a user field is anonymous
         * @param string $field Field name or SQL fragment
@@ -152,6 +192,8 @@ class ActorMigration {
         * @phan-return array{tables:string[],fields:string[],joins:array}
         */
        public function getJoin( $key ) {
+               self::checkDeprecation( $key );
+
                if ( !isset( $this->joinCache[$key] ) ) {
                        $tables = [];
                        $fields = [];
@@ -203,6 +245,8 @@ class ActorMigration {
         * @return array to merge into `$values` to `IDatabase->update()` or `$a` to `IDatabase->insert()`
         */
        public function getInsertValues( IDatabase $dbw, $key, UserIdentity $user ) {
+               self::checkDeprecation( $key );
+
                if ( isset( self::$tempTables[$key] ) ) {
                        throw new InvalidArgumentException( "Must use getInsertValuesWithTempTable() for $key" );
                }
@@ -236,6 +280,8 @@ class ActorMigration {
         *    and extra fields needed for the temp table.
         */
        public function getInsertValuesWithTempTable( IDatabase $dbw, $key, UserIdentity $user ) {
+               self::checkDeprecation( $key );
+
                if ( isset( self::$formerTempTables[$key] ) ) {
                        wfDeprecated( __METHOD__ . " for $key", self::$formerTempTables[$key] );
                } elseif ( !isset( self::$tempTables[$key] ) ) {
@@ -319,6 +365,8 @@ class ActorMigration {
         *  All tables and joins are aliased, so `+` is safe to use.
         */
        public function getWhere( IDatabase $db, $key, $users, $useId = true ) {
+               self::checkDeprecation( $key );
+
                $tables = [];
                $conds = [];
                $joins = [];
index 00708f4..f6ac342 100644 (file)
@@ -8979,24 +8979,6 @@ $wgMultiContentRevisionSchemaMigrationStage = SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_
  */
 $wgXmlDumpSchemaVersion = XML_DUMP_SCHEMA_VERSION_10;
 
-/**
- * Actor table schema migration stage.
- *
- * Use the SCHEMA_COMPAT_XXX flags. Supported values:
- * - SCHEMA_COMPAT_OLD
- * - SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
- * - SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
- * - SCHEMA_COMPAT_NEW
- *
- * Note that reading the old and new schema at the same time is not supported
- * in 1.32, but was (with significant query performance issues) in 1.31.
- *
- * @since 1.31
- * @since 1.32 changed allowed flags
- * @var int An appropriate combination of SCHEMA_COMPAT_XXX flags.
- */
-$wgActorTableSchemaMigrationStage = SCHEMA_COMPAT_NEW;
-
 /**
  * Flag to enable Partial Blocks. This allows an admin to prevent a user from editing specific pages
  * or namespaces.
index b63a84d..bf138c4 100644 (file)
@@ -31,8 +31,6 @@
  *
  * @note This class uses setter methods instead of a constructor so that
  * it can be compatible with PHP 4, PHP 5 and PHP 7 (without warnings).
- *
- * @class
  */
 class PHPVersionCheck {
        /* @var string The number of the MediaWiki version used. */
index c6e727e..292d6ba 100644 (file)
@@ -298,203 +298,6 @@ class Revision implements IDBAccessObject {
                return $rec ? new Revision( $rec ) : null;
        }
 
-       /**
-        * Return the value of a select() JOIN conds array for the user table.
-        * This will get user table rows for logged-in users.
-        * @since 1.19
-        * @deprecated since 1.31, use RevisionStore::getQueryInfo( [ 'user' ] ) instead.
-        * @return array
-        */
-       public static function userJoinCond() {
-               global $wgActorTableSchemaMigrationStage;
-
-               wfDeprecated( __METHOD__, '1.31' );
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                       // If code is using this instead of self::getQueryInfo(), there's
-                       // no way the join it's trying to do can work once the old fields
-                       // aren't being used anymore.
-                       throw new BadMethodCallException(
-                               'Cannot use ' . __METHOD__
-                                       . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
-                       );
-               }
-
-               return [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ];
-       }
-
-       /**
-        * Return the value of a select() page conds array for the page table.
-        * This will assure that the revision(s) are not orphaned from live pages.
-        * @since 1.19
-        * @deprecated since 1.31, use RevisionStore::getQueryInfo( [ 'page' ] ) instead.
-        * @return array
-        */
-       public static function pageJoinCond() {
-               wfDeprecated( __METHOD__, '1.31' );
-               return [ 'JOIN', [ 'page_id = rev_page' ] ];
-       }
-
-       /**
-        * Return the list of revision fields that should be selected to create
-        * a new revision.
-        * @deprecated since 1.31, use RevisionStore::getQueryInfo() instead.
-        * @return array
-        */
-       public static function selectFields() {
-               global $wgContentHandlerUseDB, $wgActorTableSchemaMigrationStage;
-               global $wgMultiContentRevisionSchemaMigrationStage;
-
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                       // If code is using this instead of self::getQueryInfo(), there's a
-                       // decent chance it's going to try to directly access
-                       // $row->rev_user or $row->rev_user_text and we can't give it
-                       // useful values here once those aren't being used anymore.
-                       throw new BadMethodCallException(
-                               'Cannot use ' . __METHOD__
-                                       . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
-                       );
-               }
-
-               if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
-                       // If code is using this instead of self::getQueryInfo(), there's a
-                       // decent chance it's going to try to directly access
-                       // $row->rev_text_id or $row->rev_content_model and we can't give it
-                       // useful values here once those aren't being written anymore,
-                       // and may not exist at all.
-                       throw new BadMethodCallException(
-                               'Cannot use ' . __METHOD__ . ' when $wgMultiContentRevisionSchemaMigrationStage '
-                               . 'does not have SCHEMA_COMPAT_WRITE_OLD set.'
-                       );
-               }
-
-               wfDeprecated( __METHOD__, '1.31' );
-
-               $fields = [
-                       'rev_id',
-                       'rev_page',
-                       'rev_text_id',
-                       'rev_timestamp',
-                       'rev_user_text',
-                       'rev_user',
-                       'rev_actor' => 'NULL',
-                       'rev_minor_edit',
-                       'rev_deleted',
-                       'rev_len',
-                       'rev_parent_id',
-                       'rev_sha1',
-               ];
-
-               $fields += CommentStore::getStore()->getFields( 'rev_comment' );
-
-               if ( $wgContentHandlerUseDB ) {
-                       $fields[] = 'rev_content_format';
-                       $fields[] = 'rev_content_model';
-               }
-
-               return $fields;
-       }
-
-       /**
-        * Return the list of revision fields that should be selected to create
-        * a new revision from an archive row.
-        * @deprecated since 1.31, use RevisionStore::getArchiveQueryInfo() instead.
-        * @return array
-        */
-       public static function selectArchiveFields() {
-               global $wgContentHandlerUseDB, $wgActorTableSchemaMigrationStage;
-               global $wgMultiContentRevisionSchemaMigrationStage;
-
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                       // If code is using this instead of self::getQueryInfo(), there's a
-                       // decent chance it's going to try to directly access
-                       // $row->ar_user or $row->ar_user_text and we can't give it
-                       // useful values here once those aren't being used anymore.
-                       throw new BadMethodCallException(
-                               'Cannot use ' . __METHOD__
-                                       . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
-                       );
-               }
-
-               if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
-                       // If code is using this instead of self::getQueryInfo(), there's a
-                       // decent chance it's going to try to directly access
-                       // $row->ar_text_id or $row->ar_content_model and we can't give it
-                       // useful values here once those aren't being written anymore,
-                       // and may not exist at all.
-                       throw new BadMethodCallException(
-                               'Cannot use ' . __METHOD__ . ' when $wgMultiContentRevisionSchemaMigrationStage '
-                               . 'does not have SCHEMA_COMPAT_WRITE_OLD set.'
-                       );
-               }
-
-               wfDeprecated( __METHOD__, '1.31' );
-
-               $fields = [
-                       'ar_id',
-                       'ar_page_id',
-                       'ar_rev_id',
-                       'ar_text_id',
-                       'ar_timestamp',
-                       'ar_user_text',
-                       'ar_user',
-                       'ar_actor' => 'NULL',
-                       'ar_minor_edit',
-                       'ar_deleted',
-                       'ar_len',
-                       'ar_parent_id',
-                       'ar_sha1',
-               ];
-
-               $fields += CommentStore::getStore()->getFields( 'ar_comment' );
-
-               if ( $wgContentHandlerUseDB ) {
-                       $fields[] = 'ar_content_format';
-                       $fields[] = 'ar_content_model';
-               }
-               return $fields;
-       }
-
-       /**
-        * Return the list of text fields that should be selected to read the
-        * revision text
-        * @deprecated since 1.31, use RevisionStore::getQueryInfo( [ 'text' ] ) instead.
-        * @return array
-        */
-       public static function selectTextFields() {
-               wfDeprecated( __METHOD__, '1.31' );
-               return [
-                       'old_text',
-                       'old_flags'
-               ];
-       }
-
-       /**
-        * Return the list of page fields that should be selected from page table
-        * @deprecated since 1.31, use RevisionStore::getQueryInfo( [ 'page' ] ) instead.
-        * @return array
-        */
-       public static function selectPageFields() {
-               wfDeprecated( __METHOD__, '1.31' );
-               return [
-                       'page_namespace',
-                       'page_title',
-                       'page_id',
-                       'page_latest',
-                       'page_is_redirect',
-                       'page_len',
-               ];
-       }
-
-       /**
-        * Return the list of user fields that should be selected from user table
-        * @deprecated since 1.31, use RevisionStore::getQueryInfo( [ 'user' ] ) instead.
-        * @return array
-        */
-       public static function selectUserFields() {
-               wfDeprecated( __METHOD__, '1.31' );
-               return [ 'user_name' ];
-       }
-
        /**
         * Return the tables, fields, and join conditions to be selected to create
         * a new revision object.
index 740377c..0b0aaf5 100644 (file)
@@ -77,9 +77,7 @@ use Wikimedia\ObjectFactory;
 
 return [
        'ActorMigration' => function ( MediaWikiServices $services ) : ActorMigration {
-               return new ActorMigration(
-                       $services->getMainConfig()->get( 'ActorTableSchemaMigrationStage' )
-               );
+               return new ActorMigration( SCHEMA_COMPAT_NEW );
        },
 
        'BadFileLookup' => function ( MediaWikiServices $services ) : BadFileLookup {
@@ -734,7 +732,8 @@ return [
                return new SpecialPageFactory(
                        new ServiceOptions(
                                SpecialPageFactory::$constructorOptions, $services->getMainConfig() ),
-                       $services->getContentLanguage()
+                       $services->getContentLanguage(),
+                       $services->getObjectFactory()
                );
        },
 
index cfb2ac1..39f0c81 100644 (file)
@@ -52,6 +52,17 @@ if ( ini_get( 'mbstring.func_overload' ) ) {
        die( 'MediaWiki does not support installations where mbstring.func_overload is non-zero.' );
 }
 
+// Define MW_ENTRY_POINT if it's not already, so that config code can check the
+// value without using defined()
+if ( !defined( 'MW_ENTRY_POINT' ) ) {
+       /**
+        * The entry point, which may be either the script filename without the
+        * file extension, or "cli" for maintenance scripts, or "unknown" for any
+        * entry point that does not set the constant.
+        */
+       define( 'MW_ENTRY_POINT', 'unknown' );
+}
+
 // Start the autoloader, so that extensions can derive classes from core files
 require_once "$IP/includes/AutoLoader.php";
 
index 7bcfc88..207721e 100644 (file)
@@ -743,8 +743,6 @@ class InfoAction extends FormlessAction {
                        self::getCacheKey( $cache, $page->getTitle(), $page->getLatest() ),
                        WANObjectCache::TTL_WEEK,
                        function ( $oldValue, &$ttl, &$setOpts ) use ( $page, $config, $fname, $services ) {
-                               global $wgActorTableSchemaMigrationStage;
-
                                $title = $page->getTitle();
                                $id = $title->getArticleID();
 
@@ -752,19 +750,11 @@ class InfoAction extends FormlessAction {
                                $dbrWatchlist = wfGetDB( DB_REPLICA, 'watchlist' );
                                $setOpts += Database::getCacheSetOptions( $dbr, $dbrWatchlist );
 
-                               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                                       $tables = [ 'revision_actor_temp' ];
-                                       $field = 'revactor_actor';
-                                       $pageField = 'revactor_page';
-                                       $tsField = 'revactor_timestamp';
-                                       $joins = [];
-                               } else {
-                                       $tables = [ 'revision' ];
-                                       $field = 'rev_user_text';
-                                       $pageField = 'rev_page';
-                                       $tsField = 'rev_timestamp';
-                                       $joins = [];
-                               }
+                               $tables = [ 'revision_actor_temp' ];
+                               $field = 'revactor_actor';
+                               $pageField = 'revactor_page';
+                               $tsField = 'revactor_timestamp';
+                               $joins = [];
 
                                $watchedItemStore = $services->getWatchedItemStore();
 
index 3751102..3d4c49b 100644 (file)
@@ -40,8 +40,6 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
         * @return void
         */
        protected function run( ApiPageSet $resultPageSet = null ) {
-               global $wgActorTableSchemaMigrationStage;
-
                $db = $this->getDB();
                $params = $this->extractRequestParams( false );
                $services = MediaWikiServices::getInstance();
@@ -54,9 +52,7 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
                $tsField = 'rev_timestamp';
                $idField = 'rev_id';
                $pageField = 'rev_page';
-               if ( $params['user'] !== null &&
-                       ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW )
-               ) {
+               if ( $params['user'] !== null ) {
                        // The query is probably best done using the actor_timestamp index on
                        // revision_actor_temp. Use the denormalized fields from that table.
                        $tsField = 'revactor_timestamp';
index e0513e2..a7d4fb9 100644 (file)
@@ -41,8 +41,6 @@ class ApiQueryAllUsers extends ApiQueryBase {
        }
 
        public function execute() {
-               global $wgActorTableSchemaMigrationStage;
-
                $params = $this->extractRequestParams();
                $activeUserDays = $this->getConfig()->get( 'ActiveUserDays' );
 
@@ -181,22 +179,17 @@ class ApiQueryAllUsers extends ApiQueryBase {
                        ] ] );
 
                        // Actually count the actions using a subquery (T66505 and T66507)
-                       $tables = [ 'recentchanges' ];
-                       $joins = [];
-                       if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_OLD ) {
-                               $userCond = 'rc_user_text = user_name';
-                       } else {
-                               $tables[] = 'actor';
-                               $joins['actor'] = [ 'JOIN', 'rc_actor = actor_id' ];
-                               $userCond = 'actor_user = user_id';
-                       }
+                       $tables = [ 'recentchanges', 'actor' ];
+                       $joins = [
+                               'actor' => [ 'JOIN', 'rc_actor = actor_id' ],
+                       ];
                        $timestamp = $db->timestamp( wfTimestamp( TS_UNIX ) - $activeUserSeconds );
                        $this->addFields( [
                                'recentactions' => '(' . $db->selectSQLText(
                                        $tables,
                                        'COUNT(*)',
                                        [
-                                               $userCond,
+                                               'actor_user = user_id',
                                                'rc_type != ' . $db->addQuotes( RC_EXTERNAL ), // no wikidata
                                                'rc_log_type IS NULL OR rc_log_type != ' . $db->addQuotes( 'newusers' ),
                                                'rc_timestamp >= ' . $db->addQuotes( $timestamp ),
index a1945c4..f2e306f 100644 (file)
@@ -46,8 +46,6 @@ class ApiQueryContributors extends ApiQueryBase {
        }
 
        public function execute() {
-               global $wgActorTableSchemaMigrationStage;
-
                $db = $this->getDB();
                $params = $this->extractRequestParams();
                $this->requireMaxOneParameter( $params, 'group', 'excludegroup', 'rights', 'excluderights' );
@@ -80,14 +78,10 @@ class ApiQueryContributors extends ApiQueryBase {
                $result = $this->getResult();
                $revQuery = MediaWikiServices::getInstance()->getRevisionStore()->getQueryInfo();
 
-               // For SCHEMA_COMPAT_READ_NEW, target indexes on the
-               // revision_actor_temp table, otherwise on the revision table.
-               $pageField = ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW )
-                       ? 'revactor_page' : 'rev_page';
-               $idField = ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW )
-                       ? 'revactor_actor' : $revQuery['fields']['rev_user'];
-               $countField = ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW )
-                       ? 'revactor_actor' : $revQuery['fields']['rev_user_text'];
+               // Target indexes on the revision_actor_temp table.
+               $pageField = 'revactor_page';
+               $idField = 'revactor_actor';
+               $countField = 'revactor_actor';
 
                // First, count anons
                $this->addTables( $revQuery['tables'] );
index d616ad4..5b2b1b7 100644 (file)
@@ -85,8 +85,6 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
        }
 
        protected function run( ApiPageSet $resultPageSet = null ) {
-               global $wgActorTableSchemaMigrationStage;
-
                $params = $this->extractRequestParams( false );
                $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
 
@@ -137,9 +135,7 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
                $idField = 'rev_id';
                $tsField = 'rev_timestamp';
                $pageField = 'rev_page';
-               if ( $params['user'] !== null &&
-                       ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW )
-               ) {
+               if ( $params['user'] !== null ) {
                        // We're going to want to use the page_actor_timestamp index (on revision_actor_temp)
                        // so use that table's denormalized fields.
                        $idField = 'revactor_rev';
index 919c763..189f957 100644 (file)
@@ -42,8 +42,6 @@ class ApiQueryUserContribs extends ApiQueryBase {
                $fld_patrolled = false, $fld_tags = false, $fld_size = false, $fld_sizediff = false;
 
        public function execute() {
-               global $wgActorTableSchemaMigrationStage;
-
                // Parse some parameters
                $this->params = $this->extractRequestParams();
 
@@ -82,8 +80,6 @@ class ApiQueryUserContribs extends ApiQueryBase {
                        // a wiki with users "Test00000001" to "Test99999999"), use a
                        // generator with batched lookup and continuation.
                        $userIter = call_user_func( function () use ( $dbSecondary, $sort, $op, $fname ) {
-                               global $wgActorTableSchemaMigrationStage;
-
                                $fromName = false;
                                if ( !is_null( $this->params['continue'] ) ) {
                                        $continue = explode( '|', $this->params['continue'] );
@@ -97,26 +93,13 @@ class ApiQueryUserContribs extends ApiQueryBase {
 
                                do {
                                        $from = $fromName ? "$op= " . $dbSecondary->addQuotes( $fromName ) : false;
-
-                                       // For the new schema, pull from the actor table. For the
-                                       // old, pull from rev_user.
-                                       if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                                               $res = $dbSecondary->select(
-                                                       'actor',
-                                                       [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
-                                                       array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
-                                                       $fname,
-                                                       [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ]
-                                               );
-                                       } else {
-                                               $res = $dbSecondary->select(
-                                                       'revision',
-                                                       [ 'actor_id' => 'NULL', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
-                                                       array_merge( [ "rev_user_text$like" ], $from ? [ "rev_user_text $from" ] : [] ),
-                                                       $fname,
-                                                       [ 'DISTINCT', 'ORDER BY' => [ "rev_user_text $sort" ], 'LIMIT' => $limit ]
-                                               );
-                                       }
+                                       $res = $dbSecondary->select(
+                                               'actor',
+                                               [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
+                                               array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
+                                               $fname,
+                                               [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ]
+                                       );
 
                                        $count = 0;
                                        $fromName = false;
@@ -159,25 +142,13 @@ class ApiQueryUserContribs extends ApiQueryBase {
                                $from = "$op= $fromId";
                        }
 
-                       // For the new schema, just select from the actor table. For the
-                       // old, select from user.
-                       if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                               $res = $dbSecondary->select(
-                                       'actor',
-                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
-                                       array_merge( [ 'actor_user' => $ids ], $from ? [ "actor_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "user_id $sort" ]
-                               );
-                       } else {
-                               $res = $dbSecondary->select(
-                                       'user',
-                                       [ 'actor_id' => 'NULL', 'user_id' => 'user_id', 'user_name' => 'user_name' ],
-                                       array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "user_id $sort" ]
-                               );
-                       }
+                       $res = $dbSecondary->select(
+                               'actor',
+                               [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
+                               array_merge( [ 'actor_user' => $ids ], $from ? [ "actor_id $from" ] : [] ),
+                               __METHOD__,
+                               [ 'ORDER BY' => "user_id $sort" ]
+                       );
                        $userIter = UserArray::newFromResult( $res );
                        $batchSize = count( $ids );
                } else {
@@ -222,57 +193,22 @@ class ApiQueryUserContribs extends ApiQueryBase {
                                $from = "$op= " . $dbSecondary->addQuotes( $fromName );
                        }
 
-                       // For the new schema, just select from the actor table. For the
-                       // old, select from user then merge in any unknown users (IPs and imports).
-                       if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                               $res = $dbSecondary->select(
-                                       'actor',
-                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
-                                       array_merge( [ 'actor_name' => array_keys( $names ) ], $from ? [ "actor_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "actor_name $sort" ]
-                               );
-                               $userIter = UserArray::newFromResult( $res );
-                       } else {
-                               $res = $dbSecondary->select(
-                                       'user',
-                                       [ 'actor_id' => 'NULL', 'user_id', 'user_name' ],
-                                       array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
-                                       __METHOD__
-                               );
-                               foreach ( $res as $row ) {
-                                       $names[$row->user_name] = $row;
-                               }
-                               if ( $this->params['dir'] == 'newer' ) {
-                                       ksort( $names, SORT_STRING );
-                               } else {
-                                       krsort( $names, SORT_STRING );
-                               }
-                               $neg = $op === '>' ? -1 : 1;
-                               $userIter = call_user_func( function () use ( $names, $fromName, $neg ) {
-                                       foreach ( $names as $name => $row ) {
-                                               if ( $fromName === false || $neg * strcmp( $name, $fromName ) <= 0 ) {
-                                                       $user = $row ? User::newFromRow( $row ) : User::newFromName( $name, false );
-                                                       yield $user;
-                                               }
-                                       }
-                               } );
-                       }
+                       $res = $dbSecondary->select(
+                               'actor',
+                               [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
+                               array_merge( [ 'actor_name' => array_keys( $names ) ], $from ? [ "actor_id $from" ] : [] ),
+                               __METHOD__,
+                               [ 'ORDER BY' => "actor_name $sort" ]
+                       );
+                       $userIter = UserArray::newFromResult( $res );
                        $batchSize = count( $names );
                }
 
-               // With the new schema, the DB query will order by actor so update $this->orderBy to match.
-               if ( $batchSize > 1 && ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) ) {
+               // The DB query will order by actor so update $this->orderBy to match.
+               if ( $batchSize > 1 ) {
                        $this->orderBy = 'actor';
                }
 
-               // Use the 'contributions' replica, but only if we're querying by user ID (T216656).
-               if ( $this->orderBy === 'id' &&
-                       !( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW )
-               ) {
-                       $this->selectNamedDB( 'contributions', DB_REPLICA, 'contributions' );
-               }
-
                $count = 0;
                $limit = $this->params['limit'];
                $userIter->rewind();
@@ -325,47 +261,33 @@ class ApiQueryUserContribs extends ApiQueryBase {
         * @param int $limit
         */
        private function prepareQuery( array $users, $limit ) {
-               global $wgActorTableSchemaMigrationStage;
-
                $this->resetQueryParams();
                $db = $this->getDB();
 
                $revQuery = MediaWikiServices::getInstance()->getRevisionStore()->getQueryInfo( [ 'page' ] );
 
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                       $revWhere = ActorMigration::newMigration()->getWhere( $db, 'rev_user', $users );
-                       $orderUserField = 'rev_actor';
-                       $userField = $this->orderBy === 'actor' ? 'revactor_actor' : 'actor_name';
-                       $tsField = 'revactor_timestamp';
-                       $idField = 'revactor_rev';
-
-                       // T221511: MySQL/MariaDB (10.1.37) can sometimes irrationally decide that querying `actor`
-                       // before `revision_actor_temp` and filesorting is somehow better than querying $limit+1 rows
-                       // from `revision_actor_temp`. Tell it not to reorder the query (and also reorder it ourselves
-                       // because as generated by RevisionStore it'll have `revision` first rather than
-                       // `revision_actor_temp`). But not when uctag is used, as it seems as likely to be harmed as
-                       // helped in that case, and not when there's only one User because in that case it fetches
-                       // the one `actor` row as a constant and doesn't filesort.
-                       if ( count( $users ) > 1 && !isset( $this->params['tag'] ) ) {
-                               $revQuery['joins']['revision'] = $revQuery['joins']['temp_rev_user'];
-                               unset( $revQuery['joins']['temp_rev_user'] );
-                               $this->addOption( 'STRAIGHT_JOIN' );
-                               // It isn't actually necesssary to reorder $revQuery['tables'] as Database does the right thing
-                               // when join conditions are given for all joins, but GergÅ‘ is wary of relying on that so pull
-                               // `revision_actor_temp` to the start.
-                               $revQuery['tables'] =
-                                       [ 'temp_rev_user' => $revQuery['tables']['temp_rev_user'] ] + $revQuery['tables'];
-                       }
-               } else {
-                       // If we're dealing with user names (rather than IDs) in read-old mode,
-                       // pass false for ActorMigration::getWhere()'s $useId parameter so
-                       // $revWhere['conds'] isn't an OR.
-                       $revWhere = ActorMigration::newMigration()
-                               ->getWhere( $db, 'rev_user', $users, $this->orderBy === 'id' );
-                       $orderUserField = $this->orderBy === 'id' ? 'rev_user' : 'rev_user_text';
-                       $userField = $revQuery['fields'][$orderUserField];
-                       $tsField = 'rev_timestamp';
-                       $idField = 'rev_id';
+               $revWhere = ActorMigration::newMigration()->getWhere( $db, 'rev_user', $users );
+               $orderUserField = 'rev_actor';
+               $userField = $this->orderBy === 'actor' ? 'revactor_actor' : 'actor_name';
+               $tsField = 'revactor_timestamp';
+               $idField = 'revactor_rev';
+
+               // T221511: MySQL/MariaDB (10.1.37) can sometimes irrationally decide that querying `actor`
+               // before `revision_actor_temp` and filesorting is somehow better than querying $limit+1 rows
+               // from `revision_actor_temp`. Tell it not to reorder the query (and also reorder it ourselves
+               // because as generated by RevisionStore it'll have `revision` first rather than
+               // `revision_actor_temp`). But not when uctag is used, as it seems as likely to be harmed as
+               // helped in that case, and not when there's only one User because in that case it fetches
+               // the one `actor` row as a constant and doesn't filesort.
+               if ( count( $users ) > 1 && !isset( $this->params['tag'] ) ) {
+                       $revQuery['joins']['revision'] = $revQuery['joins']['temp_rev_user'];
+                       unset( $revQuery['joins']['temp_rev_user'] );
+                       $this->addOption( 'STRAIGHT_JOIN' );
+                       // It isn't actually necesssary to reorder $revQuery['tables'] as Database does the right thing
+                       // when join conditions are given for all joins, but GergÅ‘ is wary of relying on that so pull
+                       // `revision_actor_temp` to the start.
+                       $revQuery['tables'] =
+                               [ 'temp_rev_user' => $revQuery['tables']['temp_rev_user'] ] + $revQuery['tables'];
                }
 
                $this->addTables( $revQuery['tables'] );
index 12d7435..28dea3b 100644 (file)
@@ -303,32 +303,17 @@ class ApiQueryUserInfo extends ApiQueryBase {
         * @return string|null ISO 8601 timestamp of current user's last contribution or null if none
         */
        protected function getLatestContributionTime() {
-               global $wgActorTableSchemaMigrationStage;
-
                $user = $this->getUser();
                $dbr = $this->getDB();
 
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                       if ( $user->getActorId() === null ) {
-                               return null;
-                       }
-                       $res = $dbr->selectField( 'revision_actor_temp',
-                               'MAX(revactor_timestamp)',
-                               [ 'revactor_actor' => $user->getActorId() ],
-                               __METHOD__
-                       );
-               } else {
-                       if ( $user->isLoggedIn() ) {
-                               $conds = [ 'rev_user' => $user->getId() ];
-                       } else {
-                               $conds = [ 'rev_user_text' => $user->getName() ];
-                       }
-                       $res = $dbr->selectField( 'revision',
-                               'MAX(rev_timestamp)',
-                               $conds,
-                               __METHOD__
-                       );
+               if ( $user->getActorId() === null ) {
+                       return null;
                }
+               $res = $dbr->selectField( 'revision_actor_temp',
+                       'MAX(revactor_timestamp)',
+                       [ 'revactor_actor' => $user->getActorId() ],
+                       __METHOD__
+               );
 
                return $res ? wfTimestamp( TS_ISO_8601, $res ) : null;
        }
index 168ae85..bc70d5e 100644 (file)
@@ -246,10 +246,11 @@ abstract class AuthenticationRequest {
        }
 
        /**
+        * Select a request by class name.
+        *
         * @codingStandardsIgnoreStart
-        * @template T
+        * @phan-template T
         * @codingStandardsIgnoreEnd
-        * Select a request by class name.
         * @param AuthenticationRequest[] $reqs
         * @param string $class Class name
         * @phan-param class-string<T> $class
index 6007abd..b1a8e21 100644 (file)
@@ -24,7 +24,6 @@ namespace MediaWiki\Block;
 
 use ActorMigration;
 use AutoCommitUpdate;
-use BadMethodCallException;
 use CommentStore;
 use DeferredUpdates;
 use Hooks;
@@ -161,47 +160,6 @@ class DatabaseBlock extends AbstractBlock {
                }
        }
 
-       /**
-        * Return the list of ipblocks fields that should be selected to create
-        * a new block.
-        * @deprecated since 1.31, use self::getQueryInfo() instead.
-        * @return array
-        */
-       public static function selectFields() {
-               global $wgActorTableSchemaMigrationStage;
-
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                       // If code is using this instead of self::getQueryInfo(), there's a
-                       // decent chance it's going to try to directly access
-                       // $row->ipb_by or $row->ipb_by_text and we can't give it
-                       // useful values here once those aren't being used anymore.
-                       throw new BadMethodCallException(
-                               'Cannot use ' . __METHOD__
-                                       . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
-                       );
-               }
-
-               wfDeprecated( __METHOD__, '1.31' );
-               return [
-                       'ipb_id',
-                       'ipb_address',
-                       'ipb_by',
-                       'ipb_by_text',
-                       'ipb_by_actor' => 'NULL',
-                       'ipb_timestamp',
-                       'ipb_auto',
-                       'ipb_anon_only',
-                       'ipb_create_account',
-                       'ipb_enable_autoblock',
-                       'ipb_expiry',
-                       'ipb_deleted',
-                       'ipb_block_email',
-                       'ipb_allow_usertalk',
-                       'ipb_parent_block_id',
-                       'ipb_sitewide',
-               ] + CommentStore::getStore()->getFields( 'ipb_reason' );
-       }
-
        /**
         * Return the tables, fields, and join conditions to be selected to create
         * a new block object.
index 8f816d9..bc0bbfa 100644 (file)
@@ -78,8 +78,6 @@ class UserCache {
         * @param string $caller The calling method
         */
        public function doQuery( array $userIds, $options = [], $caller = '' ) {
-               global $wgActorTableSchemaMigrationStage;
-
                $usersToCheck = [];
                $usersToQuery = [];
 
@@ -100,21 +98,12 @@ class UserCache {
                // Lookup basic info for users not yet loaded...
                if ( count( $usersToQuery ) ) {
                        $dbr = wfGetDB( DB_REPLICA );
-                       $tables = [ 'user' ];
+                       $tables = [ 'user', 'actor' ];
                        $conds = [ 'user_id' => $usersToQuery ];
-                       $fields = [ 'user_name', 'user_real_name', 'user_registration', 'user_id' ];
-                       $joinConds = [];
-
-                       // Technically we shouldn't allow this without SCHEMA_COMPAT_READ_NEW,
-                       // but it does little harm and might be needed for write callers loading a User.
-                       if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_NEW ) {
-                               $tables[] = 'actor';
-                               $fields[] = 'actor_id';
-                               $joinConds['actor'] = [
-                                       ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) ? 'JOIN' : 'LEFT JOIN',
-                                       [ 'actor_user = user_id' ]
-                               ];
-                       }
+                       $fields = [ 'user_name', 'user_real_name', 'user_registration', 'user_id', 'actor_id' ];
+                       $joinConds = [
+                               'actor' => [ 'JOIN', 'actor_user = user_id' ],
+                       ];
 
                        $comment = __METHOD__;
                        if ( strval( $caller ) !== '' ) {
@@ -127,9 +116,7 @@ class UserCache {
                                $this->cache[$userId]['name'] = $row->user_name;
                                $this->cache[$userId]['real_name'] = $row->user_real_name;
                                $this->cache[$userId]['registration'] = $row->user_registration;
-                               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_NEW ) {
-                                       $this->cache[$userId]['actor'] = $row->actor_id;
-                               }
+                               $this->cache[$userId]['actor'] = $row->actor_id;
                                $usersToCheck[$userId] = $row->user_name;
                        }
                }
index 1d590d9..e184825 100644 (file)
@@ -221,55 +221,6 @@ class RecentChange implements Taggable {
                }
        }
 
-       /**
-        * Return the list of recentchanges fields that should be selected to create
-        * a new recentchanges object.
-        * @deprecated since 1.31, use self::getQueryInfo() instead.
-        * @return array
-        */
-       public static function selectFields() {
-               global $wgActorTableSchemaMigrationStage;
-
-               wfDeprecated( __METHOD__, '1.31' );
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                       // If code is using this instead of self::getQueryInfo(), there's a
-                       // decent chance it's going to try to directly access
-                       // $row->rc_user or $row->rc_user_text and we can't give it
-                       // useful values here once those aren't being used anymore.
-                       throw new BadMethodCallException(
-                               'Cannot use ' . __METHOD__
-                                       . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
-                       );
-               }
-
-               return [
-                       'rc_id',
-                       'rc_timestamp',
-                       'rc_user',
-                       'rc_user_text',
-                       'rc_actor' => 'NULL',
-                       'rc_namespace',
-                       'rc_title',
-                       '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',
-               ] + CommentStore::getStore()->getFields( 'rc_comment' );
-       }
-
        /**
         * Return the tables, fields, and join conditions to be selected to create
         * a new recentchanges object.
index e099b38..09314ed 100644 (file)
@@ -32,24 +32,24 @@ use Wikimedia\Rdbms\ILoadBalancer;
  * @author Daniel Kinzler
  */
 abstract class DBAccessBase implements IDBAccessObject {
-       /**
-        * @var string|bool $wiki The target wiki's name. This must be an ID
-        * that LBFactory can understand.
-        */
-       protected $wiki = false;
+       /** @var ILoadBalancer */
+       private $lb;
+
+       /** @var string|bool The target wiki's DB domain */
+       protected $dbDomain = false;
 
        /**
-        * @param string|bool $wiki The target wiki's name. This must be an ID
-        * that LBFactory can understand.
+        * @param string|bool $dbDomain The target wiki's DB domain
         */
-       public function __construct( $wiki = false ) {
-               $this->wiki = $wiki;
+       public function __construct( $dbDomain = false ) {
+               $this->dbDomain = $dbDomain;
+               $this->lb = MediaWikiServices::getInstance()->getDBLoadBalancerFactory()
+                       ->getMainLB( $dbDomain );
        }
 
        /**
         * Returns a database connection.
         *
-        * @see wfGetDB()
         * @see LoadBalancer::getConnection()
         *
         * @since 1.21
@@ -60,9 +60,7 @@ abstract class DBAccessBase implements IDBAccessObject {
         * @return IDatabase
         */
        protected function getConnection( $id, array $groups = [] ) {
-               $loadBalancer = $this->getLoadBalancer();
-
-               return $loadBalancer->getConnection( $id, $groups, $this->wiki );
+               return $this->getLoadBalancer()->getConnectionRef( $id, $groups, $this->dbDomain );
        }
 
        /**
@@ -73,12 +71,10 @@ abstract class DBAccessBase implements IDBAccessObject {
         * @since 1.21
         *
         * @param IDatabase $db The database connection to release.
+        * @deprecated Since 1.34
         */
        protected function releaseConnection( IDatabase $db ) {
-               if ( $this->wiki !== false ) {
-                       $loadBalancer = $this->getLoadBalancer();
-                       $loadBalancer->reuseConnection( $db );
-               }
+               // no-op
        }
 
        /**
@@ -90,8 +86,7 @@ abstract class DBAccessBase implements IDBAccessObject {
         *
         * @return ILoadBalancer The database load balancer object
         */
-       public function getLoadBalancer() {
-               $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
-               return $lbFactory->getMainLB( $this->wiki );
+       protected function getLoadBalancer() {
+               return $this->lb;
        }
 }
index 7fcda4c..8a5caa2 100644 (file)
@@ -544,7 +544,7 @@ class DifferenceEngine extends ContextSource {
                        if ( $samePage && $this->mNewPage && $permissionManager->quickUserCan(
                                'edit', $user, $this->mNewPage
                        ) ) {
-                               if ( $this->mNewRev->isCurrent() && $permissionManager->userCan(
+                               if ( $this->mNewRev->isCurrent() && $permissionManager->quickUserCan(
                                        'rollback', $user, $this->mNewPage
                                ) ) {
                                        $rollbackLink = Linker::generateRollback( $this->mNewRev, $this->getContext(),
index 6a3e819..17fa146 100644 (file)
@@ -213,50 +213,6 @@ class ArchivedFile {
                return $file;
        }
 
-       /**
-        * Fields in the filearchive table
-        * @deprecated since 1.31, use self::getQueryInfo() instead.
-        * @return string[]
-        */
-       static function selectFields() {
-               global $wgActorTableSchemaMigrationStage;
-
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                       // If code is using this instead of self::getQueryInfo(), there's a
-                       // decent chance it's going to try to directly access
-                       // $row->fa_user or $row->fa_user_text and we can't give it
-                       // useful values here once those aren't being used anymore.
-                       throw new BadMethodCallException(
-                               'Cannot use ' . __METHOD__
-                                       . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
-                       );
-               }
-
-               wfDeprecated( __METHOD__, '1.31' );
-               return [
-                       'fa_id',
-                       'fa_name',
-                       'fa_archive_name',
-                       'fa_storage_key',
-                       'fa_storage_group',
-                       'fa_size',
-                       'fa_bits',
-                       'fa_width',
-                       'fa_height',
-                       'fa_metadata',
-                       'fa_media_type',
-                       'fa_major_mime',
-                       'fa_minor_mime',
-                       'fa_user',
-                       'fa_user_text',
-                       'fa_actor' => 'NULL',
-                       'fa_timestamp',
-                       'fa_deleted',
-                       'fa_deleted_timestamp', /* Used by LocalFileRestoreBatch */
-                       'fa_sha1',
-               ] + MediaWikiServices::getInstance()->getCommentStore()->getFields( 'fa_description' );
-       }
-
        /**
         * Return the tables, fields, and join conditions to be selected to create
         * a new archivedfile object.
index 3090632..ceb8dda 100644 (file)
@@ -202,44 +202,6 @@ class LocalFile extends File {
                }
        }
 
-       /**
-        * Fields in the image table
-        * @deprecated since 1.31, use self::getQueryInfo() instead.
-        * @return string[]
-        */
-       static function selectFields() {
-               global $wgActorTableSchemaMigrationStage;
-
-               wfDeprecated( __METHOD__, '1.31' );
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                       // If code is using this instead of self::getQueryInfo(), there's a
-                       // decent chance it's going to try to directly access
-                       // $row->img_user or $row->img_user_text and we can't give it
-                       // useful values here once those aren't being used anymore.
-                       throw new BadMethodCallException(
-                               'Cannot use ' . __METHOD__
-                                       . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
-                       );
-               }
-
-               return [
-                       'img_name',
-                       'img_size',
-                       'img_width',
-                       'img_height',
-                       'img_metadata',
-                       'img_bits',
-                       'img_media_type',
-                       'img_major_mime',
-                       'img_minor_mime',
-                       'img_user',
-                       'img_user_text',
-                       'img_actor' => 'NULL',
-                       'img_timestamp',
-                       'img_sha1',
-               ] + MediaWikiServices::getInstance()->getCommentStore()->getFields( 'img_description' );
-       }
-
        /**
         * Return the tables, fields, and join conditions to be selected to create
         * a new localfile object.
@@ -1449,8 +1411,6 @@ class LocalFile extends File {
                $oldver, $comment, $pageText, $props = false, $timestamp = false, $user = null, $tags = [],
                $createNullRevision = true, $revert = false
        ) {
-               global $wgActorTableSchemaMigrationStage;
-
                if ( is_null( $user ) ) {
                        global $wgUser;
                        $user = $wgUser;
@@ -1553,40 +1513,10 @@ class LocalFile extends File {
                                'oi_major_mime' => 'img_major_mime',
                                'oi_minor_mime' => 'img_minor_mime',
                                'oi_sha1' => 'img_sha1',
+                               'oi_actor' => 'img_actor',
                        ];
                        $joins = [];
 
-                       if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) {
-                               $fields['oi_user'] = 'img_user';
-                               $fields['oi_user_text'] = 'img_user_text';
-                       }
-                       if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                               $fields['oi_actor'] = 'img_actor';
-                       }
-
-                       if (
-                               ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_BOTH ) === SCHEMA_COMPAT_WRITE_BOTH
-                       ) {
-                               // 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_user', 'img_user_text' ],
-                                       [ 'img_name' => $this->getName(), 'img_actor' => 0 ],
-                                       __METHOD__
-                               );
-                               foreach ( $res as $row ) {
-                                       $actorId = User::newFromAnyId( $row->img_user, $row->img_user_text, null )->getActorId( $dbw );
-                                       $dbw->update(
-                                               'image',
-                                               [ 'img_actor' => $actorId ],
-                                               [ 'img_name' => $row->img_name, 'img_actor' => 0 ],
-                                               __METHOD__
-                                       );
-                               }
-                       }
-
                        # (T36993) Note: $oldver can be empty here, if the previous
                        # version of the file was broken. Allow registration of the new
                        # version to continue anyway, because that's better than having
index 61faa09..85988f6 100644 (file)
@@ -178,8 +178,6 @@ class LocalFileDeleteBatch {
        }
 
        protected function doDBInserts() {
-               global $wgActorTableSchemaMigrationStage;
-
                $now = time();
                $dbw = $this->file->repo->getMasterDB();
 
@@ -225,7 +223,8 @@ class LocalFileDeleteBatch {
                                'fa_minor_mime' => 'img_minor_mime',
                                'fa_description_id' => 'img_description_id',
                                'fa_timestamp' => 'img_timestamp',
-                               'fa_sha1' => 'img_sha1'
+                               'fa_sha1' => 'img_sha1',
+                               'fa_actor' => 'img_actor',
                        ];
                        $joins = [];
 
@@ -234,37 +233,6 @@ class LocalFileDeleteBatch {
                                $commentStore->insert( $dbw, 'fa_deleted_reason', $this->reason )
                        );
 
-                       if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) {
-                               $fields['fa_user'] = 'img_user';
-                               $fields['fa_user_text'] = 'img_user_text';
-                       }
-                       if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                               $fields['fa_actor'] = 'img_actor';
-                       }
-
-                       if (
-                               ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_BOTH ) === SCHEMA_COMPAT_WRITE_BOTH
-                       ) {
-                               // 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_user', 'img_user_text' ],
-                                       [ 'img_name' => $this->file->getName(), 'img_actor' => 0 ],
-                                       __METHOD__
-                               );
-                               foreach ( $res as $row ) {
-                                       $actorId = User::newFromAnyId( $row->img_user, $row->img_user_text, null )->getActorId( $dbw );
-                                       $dbw->update(
-                                               'image',
-                                               [ 'img_actor' => $actorId ],
-                                               [ 'img_name' => $row->img_name, 'img_actor' => 0 ],
-                                               __METHOD__
-                                       );
-                               }
-                       }
-
                        $dbw->insertSelect( 'filearchive', $tables, $fields,
                                [ 'img_name' => $this->file->getName() ], __METHOD__, [], [], $joins );
                }
index 584e001..f5b7d43 100644 (file)
@@ -106,46 +106,6 @@ class OldLocalFile extends LocalFile {
                }
        }
 
-       /**
-        * Fields in the oldimage table
-        * @deprecated since 1.31, use self::getQueryInfo() instead.
-        * @return string[]
-        */
-       static function selectFields() {
-               global $wgActorTableSchemaMigrationStage;
-
-               wfDeprecated( __METHOD__, '1.31' );
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                       // If code is using this instead of self::getQueryInfo(), there's a
-                       // decent chance it's going to try to directly access
-                       // $row->oi_user or $row->oi_user_text and we can't give it
-                       // useful values here once those aren't being used anymore.
-                       throw new BadMethodCallException(
-                               'Cannot use ' . __METHOD__
-                                       . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
-                       );
-               }
-
-               return [
-                       'oi_name',
-                       'oi_archive_name',
-                       'oi_size',
-                       'oi_width',
-                       'oi_height',
-                       'oi_metadata',
-                       'oi_bits',
-                       'oi_media_type',
-                       'oi_major_mime',
-                       'oi_minor_mime',
-                       'oi_user',
-                       'oi_user_text',
-                       'oi_actor' => 'NULL',
-                       'oi_timestamp',
-                       'oi_deleted',
-                       'oi_sha1',
-               ] + MediaWikiServices::getInstance()->getCommentStore()->getFields( 'oi_description' );
-       }
-
        /**
         * Return the tables, fields, and join conditions to be selected to create
         * a new oldlocalfile object.
index e1df844..3412aef 100644 (file)
@@ -1308,10 +1308,7 @@ abstract class DatabaseUpdater {
         * @since 1.31
         */
        protected function migrateActors() {
-               global $wgActorTableSchemaMigrationStage;
-               if ( ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) &&
-                       !$this->updateRowExists( 'MigrateActors' )
-               ) {
+               if ( !$this->updateRowExists( 'MigrateActors' ) ) {
                        $this->output(
                                "Migrating actors to the 'actor' table, printing progress markers. For large\n" .
                                "databases, you may want to hit Ctrl-C and do this manually with\n" .
@@ -1401,4 +1398,43 @@ abstract class DatabaseUpdater {
                        }
                }
        }
+
+       /**
+        * Only run a function if the `actor` table does not exist
+        *
+        * The transition to the actor table is dropping several indexes (and a few
+        * fields) that old upgrades want to add. This function is used to prevent
+        * those from running to re-add things when the `actor` table exists, while
+        * still allowing them to run if this really is an upgrade from an old MW
+        * version.
+        *
+        * @since 1.34
+        * @param string|array|static $func Normally this is the string naming the method on $this to
+        *  call. It may also be an array callable. If passed $this, it's assumed to be a call from
+        *  runUpdates() with $passSelf = true: $params[0] is assumed to be the real $func and $this
+        *  is prepended to the rest of $params.
+        * @param mixed ...$params Parameters for `$func`
+        * @return mixed Whatever $func returns, or null when skipped.
+        */
+       protected function ifNoActorTable( $func, ...$params ) {
+               if ( $this->tableExists( 'actor' ) ) {
+                       return null;
+               }
+
+               // Handle $passSelf from runUpdates().
+               $passSelf = false;
+               if ( $func === $this ) {
+                       $passSelf = true;
+                       $func = array_shift( $params );
+               }
+
+               if ( !is_array( $func ) && method_exists( $this, $func ) ) {
+                       $func = [ $this, $func ];
+               } elseif ( $passSelf ) {
+                       array_unshift( $params, $this );
+               }
+
+               // @phan-suppress-next-line PhanUndeclaredInvokeInCallable Phan is confused
+               return $func( ...$params );
+       }
 }
index 0d516b4..64c017b 100644 (file)
@@ -101,8 +101,10 @@ class MysqlUpdater extends DatabaseUpdater {
                        [ 'addTable', 'querycache_info', 'patch-querycacheinfo.sql' ],
                        [ 'addTable', 'filearchive', 'patch-filearchive.sql' ],
                        [ 'addField', 'ipblocks', 'ipb_anon_only', 'patch-ipb_anon_only.sql' ],
-                       [ 'addIndex', 'recentchanges', 'rc_ns_usertext', 'patch-recentchanges-utindex.sql' ],
-                       [ 'addIndex', 'recentchanges', 'rc_user_text', 'patch-rc_user_text-index.sql' ],
+                       [ 'ifNoActorTable', 'addIndex', 'recentchanges', 'rc_ns_usertext',
+                               'patch-recentchanges-utindex.sql' ],
+                       [ 'ifNoActorTable', 'addIndex', 'recentchanges', 'rc_user_text',
+                               'patch-rc_user_text-index.sql' ],
 
                        // 1.9
                        [ 'addField', 'user', 'user_newpass_time', 'patch-user_newpass_time.sql' ],
@@ -130,9 +132,12 @@ class MysqlUpdater extends DatabaseUpdater {
                        [ 'addField', 'ipblocks', 'ipb_block_email', 'patch-ipb_emailban.sql' ],
                        [ 'doCategorylinksIndicesUpdate' ],
                        [ 'addField', 'oldimage', 'oi_metadata', 'patch-oi_metadata.sql' ],
-                       [ 'addIndex', 'archive', 'usertext_timestamp', 'patch-archive-user-index.sql' ],
-                       [ 'addIndex', 'image', 'img_usertext_timestamp', 'patch-image-user-index.sql' ],
-                       [ 'addIndex', 'oldimage', 'oi_usertext_timestamp', 'patch-oldimage-user-index.sql' ],
+                       [ 'ifNoActorTable', 'addIndex', 'archive', 'usertext_timestamp',
+                               'patch-archive-user-index.sql' ],
+                       [ 'ifNoActorTable', 'addIndex', 'image', 'img_usertext_timestamp',
+                               'patch-image-user-index.sql' ],
+                       [ 'ifNoActorTable', 'addIndex', 'oldimage', 'oi_usertext_timestamp',
+                               'patch-oldimage-user-index.sql' ],
                        [ 'addField', 'archive', 'ar_page_id', 'patch-archive-page_id.sql' ],
                        [ 'addField', 'image', 'img_sha1', 'patch-img_sha1.sql' ],
 
@@ -140,7 +145,7 @@ class MysqlUpdater extends DatabaseUpdater {
                        [ 'addTable', 'protected_titles', 'patch-protected_titles.sql' ],
 
                        // 1.13
-                       [ 'addField', 'ipblocks', 'ipb_by_text', 'patch-ipb_by_text.sql' ],
+                       [ 'ifNoActorTable', 'addField', 'ipblocks', 'ipb_by_text', 'patch-ipb_by_text.sql' ],
                        [ 'addTable', 'page_props', 'patch-page_props.sql' ],
                        [ 'addTable', 'updatelog', 'patch-updatelog.sql' ],
                        [ 'addTable', 'category', 'patch-category.sql' ],
@@ -150,7 +155,7 @@ class MysqlUpdater extends DatabaseUpdater {
                        [ 'doPopulateParentId' ],
                        [ 'checkBin', 'protected_titles', 'pt_title', 'patch-pt_title-encoding.sql', ],
                        [ 'doMaybeProfilingMemoryUpdate' ],
-                       [ 'doFilearchiveIndicesUpdate' ],
+                       [ 'ifNoActorTable', 'doFilearchiveIndicesUpdate' ],
 
                        // 1.14
                        [ 'addField', 'site_stats', 'ss_active_users', 'patch-ss_active_users.sql' ],
@@ -163,9 +168,9 @@ class MysqlUpdater extends DatabaseUpdater {
                        // 1.16
                        [ 'addTable', 'user_properties', 'patch-user_properties.sql' ],
                        [ 'addTable', 'log_search', 'patch-log_search.sql' ],
-                       [ 'addField', 'logging', 'log_user_text', 'patch-log_user_text.sql' ],
+                       [ 'ifNoActorTable', 'addField', 'logging', 'log_user_text', 'patch-log_user_text.sql' ],
                        # listed separately from the previous update because 1.16 was released without this update
-                       [ 'doLogUsertextPopulation' ],
+                       [ 'ifNoActorTable', 'doLogUsertextPopulation' ],
                        [ 'doLogSearchPopulation' ],
                        [ 'addTable', 'l10n_cache', 'patch-l10n_cache.sql' ],
                        [ 'dropIndex', 'change_tag', 'ct_rc_id', 'patch-change_tag-indexes.sql' ],
@@ -240,9 +245,10 @@ class MysqlUpdater extends DatabaseUpdater {
 
                        // 1.23
                        [ 'addField', 'recentchanges', 'rc_source', 'patch-rc_source.sql' ],
-                       [ 'addIndex', 'logging', 'log_user_text_type_time',
+                       [ 'ifNoActorTable', 'addIndex', 'logging', 'log_user_text_type_time',
                                'patch-logging_user_text_type_time_index.sql' ],
-                       [ 'addIndex', 'logging', 'log_user_text_time', 'patch-logging_user_text_time_index.sql' ],
+                       [ 'ifNoActorTable', 'addIndex', 'logging', 'log_user_text_time',
+                               'patch-logging_user_text_time_index.sql' ],
                        [ 'addField', 'page', 'page_links_updated', 'patch-page_links_updated.sql' ],
                        [ 'addField', 'user', 'user_password_expires', 'patch-user_password_expire.sql' ],
 
@@ -288,13 +294,14 @@ class MysqlUpdater extends DatabaseUpdater {
                        [ 'doNonUniquePlTlIl' ],
                        [ 'addField', 'change_tag', 'ct_id', 'patch-change_tag-ct_id.sql' ],
                        [ 'modifyField', 'recentchanges', 'rc_ip', 'patch-rc_ip_modify.sql' ],
-                       [ 'addIndex', 'archive', 'usertext_timestamp', 'patch-rename-ar_usertext_timestamp.sql' ],
+                       [ 'ifNoActorTable', 'addIndex', 'archive', 'usertext_timestamp',
+                               'patch-rename-ar_usertext_timestamp.sql' ],
 
                        // 1.29
                        [ 'addField', 'externallinks', 'el_index_60', 'patch-externallinks-el_index_60.sql' ],
                        [ 'dropIndex', 'user_groups', 'ug_user_group', 'patch-user_groups-primary-key.sql' ],
                        [ 'addField', 'user_groups', 'ug_expiry', 'patch-user_groups-ug_expiry.sql' ],
-                       [ 'addIndex', 'image', 'img_user_timestamp', 'patch-image-user-index-2.sql' ],
+                       [ 'ifNoActorTable', 'addIndex', 'image', 'img_user_timestamp', 'patch-image-user-index-2.sql' ],
 
                        // 1.30
                        [ 'modifyField', 'image', 'img_media_type', 'patch-add-3d.sql' ],
@@ -377,6 +384,9 @@ class MysqlUpdater extends DatabaseUpdater {
                        [ 'dropTable', 'tag_summary' ],
                        [ 'dropField', 'protected_titles', 'pt_reason', 'patch-drop-comment-fields.sql' ],
                        [ 'modifyTable', 'job', 'patch-job-params-mediumblob.sql' ],
+
+                       // 1.34
+                       [ 'dropField', 'logging', 'log_user', 'patch-drop-user-fields.sql' ],
                ];
        }
 
index 31827a1..b2c7d66 100644 (file)
@@ -110,7 +110,7 @@ class PostgresUpdater extends DatabaseUpdater {
                        [ 'addPgField', 'image', 'img_sha1', "TEXT NOT NULL DEFAULT ''" ],
                        [ 'addPgField', 'ipblocks', 'ipb_allow_usertalk', 'SMALLINT NOT NULL DEFAULT 0' ],
                        [ 'addPgField', 'ipblocks', 'ipb_anon_only', 'SMALLINT NOT NULL DEFAULT 0' ],
-                       [ 'addPgField', 'ipblocks', 'ipb_by_text', "TEXT NOT NULL DEFAULT ''" ],
+                       [ 'ifNoActorTable', 'addPgField', 'ipblocks', 'ipb_by_text', "TEXT NOT NULL DEFAULT ''" ],
                        [ 'addPgField', 'ipblocks', 'ipb_block_email', 'SMALLINT NOT NULL DEFAULT 0' ],
                        [ 'addPgField', 'ipblocks', 'ipb_create_account', 'SMALLINT NOT NULL DEFAULT 1' ],
                        [ 'addPgField', 'ipblocks', 'ipb_deleted', 'SMALLINT NOT NULL DEFAULT 0' ],
@@ -152,7 +152,7 @@ class PostgresUpdater extends DatabaseUpdater {
                        [ 'addPgField', 'revision', 'rev_content_format', 'TEXT' ],
                        [ 'addPgField', 'site_stats', 'ss_active_users', "INTEGER DEFAULT '-1'" ],
                        [ 'addPgField', 'user_newtalk', 'user_last_timestamp', 'TIMESTAMPTZ' ],
-                       [ 'addPgField', 'logging', 'log_user_text', "TEXT NOT NULL DEFAULT ''" ],
+                       [ 'ifNoActorTable', 'addPgField', 'logging', 'log_user_text', "TEXT NOT NULL DEFAULT ''" ],
                        [ 'addPgField', 'logging', 'log_page', 'INTEGER' ],
                        [ 'addPgField', 'interwiki', 'iw_api', "TEXT NOT NULL DEFAULT ''" ],
                        [ 'addPgField', 'interwiki', 'iw_wikiid', "TEXT NOT NULL DEFAULT ''" ],
@@ -240,7 +240,7 @@ class PostgresUpdater extends DatabaseUpdater {
                        [ 'checkOiDeleted' ],
 
                        # New indexes
-                       [ 'addPgIndex', 'archive', 'archive_user_text', '(ar_user_text)' ],
+                       [ 'ifNoActorTable', 'addPgIndex', 'archive', 'archive_user_text', '(ar_user_text)' ],
                        [ 'addPgIndex', 'image', 'img_sha1', '(img_sha1)' ],
                        [ 'addPgIndex', 'ipblocks', 'ipb_parent_block_id', '(ipb_parent_block_id)' ],
                        [ 'addPgIndex', 'oldimage', 'oi_sha1', '(oi_sha1)' ],
@@ -253,7 +253,7 @@ class PostgresUpdater extends DatabaseUpdater {
                        [ 'addPgIndex', 'watchlist', 'wl_user', '(wl_user)' ],
                        [ 'addPgIndex', 'watchlist', 'wl_user_notificationtimestamp',
                                '(wl_user, wl_notificationtimestamp)' ],
-                       [ 'addPgIndex', 'logging', 'logging_user_type_time',
+                       [ 'ifNoActorTable', 'addPgIndex', 'logging', 'logging_user_type_time',
                                '(log_user, log_type, log_timestamp)' ],
                        [ 'addPgIndex', 'logging', 'logging_page_id_time', '(log_page,log_timestamp)' ],
                        [ 'addPgIndex', 'iwlinks', 'iwl_prefix_from_title', '(iwl_prefix, iwl_from, iwl_title)' ],
@@ -263,9 +263,10 @@ class PostgresUpdater extends DatabaseUpdater {
                        [ 'addPgIndex', 'job', 'job_cmd_token', '(job_cmd, job_token, job_random)' ],
                        [ 'addPgIndex', 'job', 'job_cmd_token_id', '(job_cmd, job_token, job_id)' ],
                        [ 'addPgIndex', 'filearchive', 'fa_sha1', '(fa_sha1)' ],
-                       [ 'addPgIndex', 'logging', 'logging_user_text_type_time',
+                       [ 'ifNoActorTable', 'addPgIndex', 'logging', 'logging_user_text_type_time',
                                '(log_user_text, log_type, log_timestamp)' ],
-                       [ 'addPgIndex', 'logging', 'logging_user_text_time', '(log_user_text, log_timestamp)' ],
+                       [ 'ifNoActorTable', 'addPgIndex', 'logging', 'logging_user_text_time',
+                               '(log_user_text, log_timestamp)' ],
 
                        [ 'checkIndex', 'pagelink_unique', [
                                [ 'pl_from', 'int4_ops', 'btree', 0 ],
@@ -363,30 +364,36 @@ class PostgresUpdater extends DatabaseUpdater {
                        [ 'checkIwlPrefix' ],
 
                        # All FK columns should be deferred
-                       [ 'changeFkeyDeferrable', 'archive', 'ar_user', 'mwuser(user_id) ON DELETE SET NULL' ],
+                       [ 'ifNoActorTable', 'changeFkeyDeferrable', 'archive', 'ar_user',
+                               'mwuser(user_id) ON DELETE SET NULL' ],
                        [ 'changeFkeyDeferrable', 'categorylinks', 'cl_from', 'page(page_id) ON DELETE CASCADE' ],
                        [ 'changeFkeyDeferrable', 'externallinks', 'el_from', 'page(page_id) ON DELETE CASCADE' ],
                        [ 'changeFkeyDeferrable', 'filearchive', 'fa_deleted_user',
                                'mwuser(user_id) ON DELETE SET NULL' ],
-                       [ 'changeFkeyDeferrable', 'filearchive', 'fa_user', 'mwuser(user_id) ON DELETE SET NULL' ],
-                       [ 'changeFkeyDeferrable', 'image', 'img_user', 'mwuser(user_id) ON DELETE SET NULL' ],
+                       [ 'ifNoActorTable', 'changeFkeyDeferrable', 'filearchive', 'fa_user',
+                               'mwuser(user_id) ON DELETE SET NULL' ],
+                       [ 'ifNoActorTable', 'changeFkeyDeferrable', 'image', 'img_user',
+                               'mwuser(user_id) ON DELETE SET NULL' ],
                        [ 'changeFkeyDeferrable', 'imagelinks', 'il_from', 'page(page_id) ON DELETE CASCADE' ],
-                       [ 'changeFkeyDeferrable', 'ipblocks', 'ipb_by', 'mwuser(user_id) ON DELETE CASCADE' ],
+                       [ 'ifNoActorTable', 'changeFkeyDeferrable', 'ipblocks', 'ipb_by',
+                               'mwuser(user_id) ON DELETE CASCADE' ],
                        [ 'changeFkeyDeferrable', 'ipblocks', 'ipb_user', 'mwuser(user_id) ON DELETE SET NULL' ],
                        [ 'changeFkeyDeferrable', 'ipblocks', 'ipb_parent_block_id',
                                'ipblocks(ipb_id) ON DELETE SET NULL' ],
                        [ 'changeFkeyDeferrable', 'langlinks', 'll_from', 'page(page_id) ON DELETE CASCADE' ],
-                       [ 'changeFkeyDeferrable', 'logging', 'log_user', 'mwuser(user_id) ON DELETE SET NULL' ],
+                       [ 'ifNoActorTable', 'changeFkeyDeferrable', 'logging', 'log_user',
+                               'mwuser(user_id) ON DELETE SET NULL' ],
                        [ 'changeFkeyDeferrable', 'oldimage', 'oi_name',
                                'image(img_name) ON DELETE CASCADE ON UPDATE CASCADE' ],
-                       [ 'changeFkeyDeferrable', 'oldimage', 'oi_user', 'mwuser(user_id) ON DELETE SET NULL' ],
+                       [ 'ifNoActorTable', 'changeFkeyDeferrable', 'oldimage', 'oi_user',
+                               'mwuser(user_id) ON DELETE SET NULL' ],
                        [ 'changeFkeyDeferrable', 'pagelinks', 'pl_from', 'page(page_id) ON DELETE CASCADE' ],
                        [ 'changeFkeyDeferrable', 'page_props', 'pp_page', 'page (page_id) ON DELETE CASCADE' ],
                        [ 'changeFkeyDeferrable', 'page_restrictions', 'pr_page',
                                'page(page_id) ON DELETE CASCADE' ],
                        [ 'changeFkeyDeferrable', 'protected_titles', 'pt_user',
                                'mwuser(user_id) ON DELETE SET NULL' ],
-                       [ 'changeFkeyDeferrable', 'recentchanges', 'rc_user',
+                       [ 'ifNoActorTable', 'changeFkeyDeferrable', 'recentchanges', 'rc_user',
                                'mwuser(user_id) ON DELETE SET NULL' ],
                        [ 'changeFkeyDeferrable', 'redirect', 'rd_from', 'page(page_id) ON DELETE CASCADE' ],
                        [ 'changeFkeyDeferrable', 'revision', 'rev_page', 'page (page_id) ON DELETE CASCADE' ],
@@ -618,6 +625,34 @@ class PostgresUpdater extends DatabaseUpdater {
                        [ 'dropDefault', 'logging', 'log_comment_id' ],
                        [ 'dropPgField', 'protected_titles', 'pt_reason' ],
                        [ 'dropDefault', 'protected_titles', 'pt_reason_id' ],
+
+                       // 1.34
+                       [ 'dropPgIndex', 'archive', 'archive_user_text' ],
+                       [ 'dropPgField', 'archive', 'ar_user' ],
+                       [ 'dropPgField', 'archive', 'ar_user_text' ],
+                       [ 'dropDefault', 'archive', 'ar_actor' ],
+                       [ 'dropPgField', 'ipblocks', 'ipb_by' ],
+                       [ 'dropPgField', 'ipblocks', 'ipb_by_text' ],
+                       [ 'dropDefault', 'ipblocks', 'ipb_by_actor' ],
+                       [ 'dropPgField', 'image', 'img_user' ],
+                       [ 'dropPgField', 'image', 'img_user_text' ],
+                       [ 'dropDefault', 'image', 'img_actor' ],
+                       [ 'dropPgField', 'oldimage', 'oi_user' ],
+                       [ 'dropPgField', 'oldimage', 'oi_user_text' ],
+                       [ 'dropDefault', 'oldimage', 'oi_actor' ],
+                       [ 'dropPgField', 'filearchive', 'fa_user' ],
+                       [ 'dropPgField', 'filearchive', 'fa_user_text' ],
+                       [ 'dropDefault', 'filearchive', 'fa_actor' ],
+                       [ 'dropPgField', 'recentchanges', 'rc_user' ],
+                       [ 'dropPgField', 'recentchanges', 'rc_user_text' ],
+                       [ 'dropDefault', 'recentchanges', 'rc_actor' ],
+                       [ 'dropPgIndex', 'logging', 'logging_user_time' ],
+                       [ 'dropPgIndex', 'logging', 'logging_user_type_time' ],
+                       [ 'dropPgIndex', 'logging', 'logging_user_text_type_time' ],
+                       [ 'dropPgIndex', 'logging', 'logging_user_text_time' ],
+                       [ 'dropPgField', 'logging', 'log_user' ],
+                       [ 'dropPgField', 'logging', 'log_user_text' ],
+                       [ 'dropDefault', 'logging', 'log_actor' ],
                ];
        }
 
index 17ced50..7c3878c 100644 (file)
@@ -47,9 +47,9 @@ class SqliteUpdater extends DatabaseUpdater {
                        // 1.16
                        [ 'addTable', 'user_properties', 'patch-user_properties.sql' ],
                        [ 'addTable', 'log_search', 'patch-log_search.sql' ],
-                       [ 'addField', 'logging', 'log_user_text', 'patch-log_user_text.sql' ],
+                       [ 'ifNoActorTable', 'addField', 'logging', 'log_user_text', 'patch-log_user_text.sql' ],
                        # listed separately from the previous update because 1.16 was released without this update
-                       [ 'doLogUsertextPopulation' ],
+                       [ 'ifNoActorTable', 'doLogUsertextPopulation' ],
                        [ 'doLogSearchPopulation' ],
                        [ 'addTable', 'l10n_cache', 'patch-l10n_cache.sql' ],
                        [ 'dropIndex', 'change_tag', 'ct_rc_id', 'patch-change_tag-indexes.sql' ],
@@ -119,9 +119,10 @@ class SqliteUpdater extends DatabaseUpdater {
 
                        // 1.23
                        [ 'addField', 'recentchanges', 'rc_source', 'patch-rc_source.sql' ],
-                       [ 'addIndex', 'logging', 'log_user_text_type_time',
+                       [ 'ifNoActorTable', 'addIndex', 'logging', 'log_user_text_type_time',
                                'patch-logging_user_text_type_time_index.sql' ],
-                       [ 'addIndex', 'logging', 'log_user_text_time', 'patch-logging_user_text_time_index.sql' ],
+                       [ 'ifNoActorTable', 'addIndex', 'logging', 'log_user_text_time',
+                               'patch-logging_user_text_time_index.sql' ],
                        [ 'addField', 'page', 'page_links_updated', 'patch-page_links_updated.sql' ],
                        [ 'addField', 'user', 'user_password_expires', 'patch-user_password_expire.sql' ],
 
@@ -159,7 +160,7 @@ class SqliteUpdater extends DatabaseUpdater {
                        // 1.29
                        [ 'addField', 'externallinks', 'el_index_60', 'patch-externallinks-el_index_60.sql' ],
                        [ 'addField', 'user_groups', 'ug_expiry', 'patch-user_groups-ug_expiry.sql' ],
-                       [ 'addIndex', 'image', 'img_user_timestamp', 'patch-image-user-index-2.sql' ],
+                       [ 'ifNoActorTable', 'addIndex', 'image', 'img_user_timestamp', 'patch-image-user-index-2.sql' ],
 
                        // 1.30
                        [ 'modifyField', 'image', 'img_media_type', 'patch-add-3d.sql' ],
@@ -249,6 +250,15 @@ class SqliteUpdater extends DatabaseUpdater {
                        [ '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' ],
+
+                       // 1.34
+                       [ 'dropField', 'archive', 'ar_user', 'patch-archive-drop-ar_user.sql' ],
+                       [ 'dropField', 'ipblocks', 'ipb_by', 'patch-ipblocks-drop-ipb_by.sql' ],
+                       [ 'dropField', 'image', 'img_user', 'patch-image-drop-img_user.sql' ],
+                       [ 'dropField', 'oldimage', 'oi_user', 'patch-oldimage-drop-oi_user.sql' ],
+                       [ 'dropField', 'filearchive', 'fa_user', 'patch-filearchive-drop-fa_user.sql' ],
+                       [ 'dropField', 'recentchanges', 'rc_user', 'patch-recentchanges-drop-rc_user.sql' ],
+                       [ 'dropField', 'logging', 'log_user', 'patch-logging-drop-log_user.sql' ],
                ];
        }
 
index 5326705..523a2f8 100644 (file)
@@ -253,8 +253,6 @@ class ManualLogEntry extends LogEntryBase implements Taggable {
         * @throws MWException
         */
        public function insert( IDatabase $dbw = null ) {
-               global $wgActorTableSchemaMigrationStage;
-
                $dbw = $dbw ?: wfGetDB( DB_MASTER );
 
                if ( $this->timestamp === null ) {
@@ -267,31 +265,6 @@ class ManualLogEntry extends LogEntryBase implements Taggable {
                $params = $this->getParameters();
                $relations = $this->relations;
 
-               // Ensure actor relations are set
-               if ( ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) &&
-                       empty( $relations['target_author_actor'] )
-               ) {
-                       $actorIds = [];
-                       if ( !empty( $relations['target_author_id'] ) ) {
-                               foreach ( $relations['target_author_id'] as $id ) {
-                                       $actorIds[] = User::newFromId( $id )->getActorId( $dbw );
-                               }
-                       }
-                       if ( !empty( $relations['target_author_ip'] ) ) {
-                               foreach ( $relations['target_author_ip'] as $ip ) {
-                                       $actorIds[] = User::newFromName( $ip, false )->getActorId( $dbw );
-                               }
-                       }
-                       if ( $actorIds ) {
-                               $relations['target_author_actor'] = $actorIds;
-                               $params['authorActors'] = $actorIds;
-                       }
-               }
-               if ( !( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
-                       unset( $relations['target_author_id'], $relations['target_author_ip'] );
-                       unset( $params['authorIds'], $params['authorIPs'] );
-               }
-
                // Additional fields for which there's no space in the database table schema
                $revId = $this->getAssociatedRevId();
                if ( $revId ) {
index fea1bf6..c167f3a 100644 (file)
@@ -2841,7 +2841,7 @@ class WikiPage implements Page, IDBAccessObject {
         */
        protected function archiveRevisions( $dbw, $id, $suppress ) {
                global $wgContentHandlerUseDB, $wgMultiContentRevisionSchemaMigrationStage,
-                       $wgActorTableSchemaMigrationStage, $wgDeleteRevisionsBatchSize;
+                       $wgDeleteRevisionsBatchSize;
 
                // Given the lock above, we can be confident in the title and page ID values
                $namespace = $this->getTitle()->getNamespace();
@@ -2968,9 +2968,7 @@ class WikiPage implements Page, IDBAccessObject {
 
                        $dbw->delete( 'revision', [ 'rev_id' => $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__ );
-                       }
+                       $dbw->delete( 'revision_actor_temp', [ 'revactor_rev' => $revids ], __METHOD__ );
 
                        // Also delete records from ip_changes as applicable.
                        if ( count( $ipRevIds ) > 0 ) {
index 74dd7bc..f4ea54f 100644 (file)
@@ -113,8 +113,6 @@ abstract class RevDelList extends RevisionListBase {
         * @since 1.23 Added 'perItemStatus' param
         */
        public function setVisibility( array $params ) {
-               global $wgActorTableSchemaMigrationStage;
-
                $status = Status::newGood();
 
                $bitPars = $params['value'];
@@ -143,7 +141,7 @@ abstract class RevDelList extends RevisionListBase {
                $missing = array_flip( $this->ids );
                $this->clearFileOps();
                $idsForLog = [];
-               $authorIds = $authorIPs = $authorActors = [];
+               $authorActors = [];
 
                if ( $perItemStatus ) {
                        $status->itemStatuses = [];
@@ -225,29 +223,7 @@ abstract class RevDelList extends RevisionListBase {
                                $virtualOldBits |= $removedBits;
 
                                $status->successCount++;
-                               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) {
-                                       if ( $item->getAuthorId() > 0 ) {
-                                               $authorIds[] = $item->getAuthorId();
-                                       } elseif ( IP::isIPAddress( $item->getAuthorName() ) ) {
-                                               $authorIPs[] = $item->getAuthorName();
-                                       }
-                                       if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                                               $actorId = $item->getAuthorActor();
-                                               // During migration, the actor field might be empty. If so, populate
-                                               // it here.
-                                               if ( !$actorId ) {
-                                                       if ( $item->getAuthorId() > 0 ) {
-                                                               $user = User::newFromId( $item->getAuthorId() );
-                                                       } else {
-                                                               $user = User::newFromName( $item->getAuthorName(), false );
-                                                       }
-                                                       $actorId = $user->getActorId( $dbw );
-                                               }
-                                               $authorActors[] = $actorId;
-                                       }
-                               } elseif ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                                       $authorActors[] = $item->getAuthorActor();
-                               }
+                               $authorActors[] = $item->getAuthorActor();
 
                                // Save the old and new bits in $visibilityChangeMap for
                                // later use.
@@ -291,13 +267,7 @@ abstract class RevDelList extends RevisionListBase {
 
                // Log it
                $authorFields = [];
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) {
-                       $authorFields['authorIds'] = $authorIds;
-                       $authorFields['authorIPs'] = $authorIPs;
-               }
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                       $authorFields['authorActors'] = $authorActors;
-               }
+               $authorFields['authorActors'] = $authorActors;
                $this->updateLog(
                        $logType,
                        [
@@ -363,8 +333,6 @@ abstract class RevDelList extends RevisionListBase {
         *     title:           The target title
         *     ids:             The ID list
         *     comment:         The log comment
-        *     authorIds:       The array of the user IDs of the offenders
-        *     authorIPs:       The array of the IP/anon user offenders
         *     authorActors:    The array of the actor IDs of the offenders
         *     tags:            The array of change tags to apply to the log entry
         * @throws MWException
@@ -387,12 +355,6 @@ abstract class RevDelList extends RevisionListBase {
                $relations = [
                        $field => $params['ids'],
                ];
-               if ( isset( $params['authorIds'] ) ) {
-                       $relations += [
-                               'target_author_id' => $params['authorIds'],
-                               'target_author_ip' => $params['authorIPs'],
-                       ];
-               }
                if ( isset( $params['authorActors'] ) ) {
                        $relations += [
                                'target_author_actor' => $params['authorActors'],
index 5644b95..9a9ab19 100644 (file)
@@ -44,8 +44,6 @@ class RevisionDeleteUser {
         * @return bool True on success, false on failure (e.g. invalid user ID)
         */
        private static function setUsernameBitfields( $name, $userId, $op, IDatabase $dbw = null ) {
-               global $wgActorTableSchemaMigrationStage;
-
                if ( !$userId || ( $op !== '|' && $op !== '&' ) ) {
                        return false; // sanity check
                }
@@ -69,19 +67,26 @@ class RevisionDeleteUser {
                $userTitle = Title::makeTitleSafe( NS_USER, $name );
                $userDbKey = $userTitle->getDBkey();
 
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) {
+               $actorId = $dbw->selectField( 'actor', 'actor_id', [ 'actor_name' => $name ], __METHOD__ );
+               if ( $actorId ) {
                        # Hide name from live edits
-                       $dbw->update(
-                               'revision',
-                               [ self::buildSetBitDeletedField( 'rev_deleted', $op, $delUser, $dbw ) ],
-                               [ 'rev_user' => $userId ],
-                               __METHOD__ );
+                       $ids = $dbw->selectFieldValues(
+                               'revision_actor_temp', 'revactor_rev', [ 'revactor_actor' => $actorId ], __METHOD__
+                       );
+                       if ( $ids ) {
+                               $dbw->update(
+                                       'revision',
+                                       [ self::buildSetBitDeletedField( 'rev_deleted', $op, $delUser, $dbw ) ],
+                                       [ 'rev_id' => $ids ],
+                                       __METHOD__
+                               );
+                       }
 
                        # Hide name from deleted edits
                        $dbw->update(
                                'archive',
                                [ self::buildSetBitDeletedField( 'ar_deleted', $op, $delUser, $dbw ) ],
-                               [ 'ar_user_text' => $name ],
+                               [ 'ar_actor' => $actorId ],
                                __METHOD__
                        );
 
@@ -89,7 +94,7 @@ class RevisionDeleteUser {
                        $dbw->update(
                                'logging',
                                [ self::buildSetBitDeletedField( 'log_deleted', $op, $delUser, $dbw ) ],
-                               [ 'log_user' => $userId, 'log_type != ' . $dbw->addQuotes( 'suppress' ) ],
+                               [ 'log_actor' => $actorId, 'log_type != ' . $dbw->addQuotes( 'suppress' ) ],
                                __METHOD__
                        );
 
@@ -97,7 +102,7 @@ class RevisionDeleteUser {
                        $dbw->update(
                                'recentchanges',
                                [ self::buildSetBitDeletedField( 'rc_deleted', $op, $delUser, $dbw ) ],
-                               [ 'rc_user_text' => $name ],
+                               [ 'rc_actor' => $actorId ],
                                __METHOD__
                        );
 
@@ -105,7 +110,7 @@ class RevisionDeleteUser {
                        $dbw->update(
                                'oldimage',
                                [ self::buildSetBitDeletedField( 'oi_deleted', $op, $delUser, $dbw ) ],
-                               [ 'oi_user_text' => $name ],
+                               [ 'oi_actor' => $actorId ],
                                __METHOD__
                        );
 
@@ -113,69 +118,11 @@ class RevisionDeleteUser {
                        $dbw->update(
                                'filearchive',
                                [ self::buildSetBitDeletedField( 'fa_deleted', $op, $delUser, $dbw ) ],
-                               [ 'fa_user_text' => $name ],
+                               [ 'fa_actor' => $actorId ],
                                __METHOD__
                        );
                }
 
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                       $actorId = $dbw->selectField( 'actor', 'actor_id', [ 'actor_name' => $name ], __METHOD__ );
-                       if ( $actorId ) {
-                               # Hide name from live edits
-                               $ids = $dbw->selectFieldValues(
-                                       'revision_actor_temp', 'revactor_rev', [ 'revactor_actor' => $actorId ], __METHOD__
-                               );
-                               if ( $ids ) {
-                                       $dbw->update(
-                                               'revision',
-                                               [ self::buildSetBitDeletedField( 'rev_deleted', $op, $delUser, $dbw ) ],
-                                               [ 'rev_id' => $ids ],
-                                               __METHOD__
-                                       );
-                               }
-
-                               # Hide name from deleted edits
-                               $dbw->update(
-                                       'archive',
-                                       [ self::buildSetBitDeletedField( 'ar_deleted', $op, $delUser, $dbw ) ],
-                                       [ 'ar_actor' => $actorId ],
-                                       __METHOD__
-                               );
-
-                               # Hide name from logs
-                               $dbw->update(
-                                       'logging',
-                                       [ self::buildSetBitDeletedField( 'log_deleted', $op, $delUser, $dbw ) ],
-                                       [ 'log_actor' => $actorId, 'log_type != ' . $dbw->addQuotes( 'suppress' ) ],
-                                       __METHOD__
-                               );
-
-                               # Hide name from RC
-                               $dbw->update(
-                                       'recentchanges',
-                                       [ self::buildSetBitDeletedField( 'rc_deleted', $op, $delUser, $dbw ) ],
-                                       [ 'rc_actor' => $actorId ],
-                                       __METHOD__
-                               );
-
-                               # Hide name from live images
-                               $dbw->update(
-                                       'oldimage',
-                                       [ self::buildSetBitDeletedField( 'oi_deleted', $op, $delUser, $dbw ) ],
-                                       [ 'oi_actor' => $actorId ],
-                                       __METHOD__
-                               );
-
-                               # Hide name from deleted images
-                               $dbw->update(
-                                       'filearchive',
-                                       [ self::buildSetBitDeletedField( 'fa_deleted', $op, $delUser, $dbw ) ],
-                                       [ 'fa_actor' => $actorId ],
-                                       __METHOD__
-                               );
-                       }
-               }
-
                # Hide log entries pointing to the user page
                $dbw->update(
                        'logging',
index 8134c9a..2737e35 100644 (file)
@@ -34,6 +34,7 @@ use RequestContext;
 use SpecialPage;
 use Title;
 use User;
+use Wikimedia\ObjectFactory;
 
 /**
  * Factory for handling the special page list and generating SpecialPage objects.
@@ -221,6 +222,9 @@ class SpecialPageFactory {
        /** @var Language */
        private $contLang;
 
+       /** @var ObjectFactory */
+       private $objectFactory;
+
        /**
         * TODO Make this a const when HHVM support is dropped (T192166)
         *
@@ -241,11 +245,17 @@ class SpecialPageFactory {
        /**
         * @param ServiceOptions $options
         * @param Language $contLang
+        * @param ObjectFactory $objectFactory
         */
-       public function __construct( ServiceOptions $options, Language $contLang ) {
+       public function __construct(
+               ServiceOptions $options,
+               Language $contLang,
+               ObjectFactory $objectFactory
+       ) {
                $options->assertRequiredOptions( self::$constructorOptions );
                $this->options = $options;
                $this->contLang = $contLang;
+               $this->objectFactory = $objectFactory;
        }
 
        /**
@@ -412,14 +422,22 @@ class SpecialPageFactory {
                if ( isset( $specialPageList[$realName] ) ) {
                        $rec = $specialPageList[$realName];
 
-                       if ( is_callable( $rec ) ) {
-                               // Use callback to instantiate the special page
-                               $page = $rec();
-                       } elseif ( is_string( $rec ) ) {
-                               $className = $rec;
-                               $page = new $className;
-                       } elseif ( $rec instanceof SpecialPage ) {
+                       if ( $rec instanceof SpecialPage ) {
+                               wfDeprecated(
+                                       "a SpecialPage instance (for $realName) in " .
+                                       '$wgSpecialPages or from the SpecialPage_initList hook',
+                                       '1.34'
+                               );
+
                                $page = $rec; // XXX: we should deep clone here
+                       } elseif ( is_array( $rec ) || is_string( $rec ) || is_callable( $rec ) ) {
+                               $page = $this->objectFactory->createObject(
+                                       $rec,
+                                       [
+                                               'allowClassName' => true,
+                                               'allowCallable' => true
+                                       ]
+                               );
                        } else {
                                $page = null;
                        }
index 4599b22..40c0edf 100644 (file)
@@ -554,13 +554,9 @@ class SpecialContributions extends IncludableSpecialPage {
                        $filterSelection = Html::rawElement( 'div', [], '' );
                }
 
-               $labelUsername = Xml::radioLabel(
+               $labelUsername = Xml::label(
                        $this->msg( 'sp-contributions-username' )->text(),
-                       'contribs',
-                       'user',
-                       'user',
-                       true,
-                       [ 'class' => 'mw-input' ]
+                       'mw-target-user-or-ip'
                );
                $input = Html::input(
                        'target',
index c6927c1..ac8baa1 100644 (file)
@@ -35,8 +35,6 @@ class SpecialLog extends SpecialPage {
        }
 
        public function execute( $par ) {
-               global $wgActorTableSchemaMigrationStage;
-
                $this->setHeaders();
                $this->outputHeader();
                $out = $this->getOutput();
@@ -107,13 +105,7 @@ class SpecialLog extends SpecialPage {
                        $offenderName = $opts->getValue( 'offender' );
                        $offender = empty( $offenderName ) ? null : User::newFromName( $offenderName, false );
                        if ( $offender ) {
-                               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                                       $qc = [ 'ls_field' => 'target_author_actor', 'ls_value' => $offender->getActorId() ];
-                               } elseif ( $offender->getId() > 0 ) {
-                                       $qc = [ 'ls_field' => 'target_author_id', 'ls_value' => $offender->getId() ];
-                               } else {
-                                       $qc = [ 'ls_field' => 'target_author_ip', 'ls_value' => $offender->getName() ];
-                               }
+                               $qc = [ 'ls_field' => 'target_author_actor', 'ls_value' => $offender->getActorId() ];
                        }
                } else {
                        // Allow extensions to add relations to their search types
index 978efa7..df8bce1 100644 (file)
@@ -25,7 +25,6 @@
  * The web server should generally be configured to make this accessible via a canonical URL/URI,
  * such as <http://my.domain.org/data/main/Foo>.
  *
- * @class
  * @ingroup SpecialPage
  */
 class SpecialPageData extends SpecialPage {
index 7703e20..0f5355d 100644 (file)
@@ -79,19 +79,16 @@ class ActiveUsersPager extends UsersPager {
        function getQueryInfo( $data = null ) {
                $dbr = $this->getDatabase();
 
-               $useActor = (bool)(
-                       $this->getConfig()->get( 'ActorTableSchemaMigrationStage' ) & SCHEMA_COMPAT_READ_NEW
-               );
-
                $activeUserSeconds = $this->getConfig()->get( 'ActiveUserDays' ) * 86400;
                $timestamp = $dbr->timestamp( wfTimestamp( TS_UNIX ) - $activeUserSeconds );
                $fname = __METHOD__ . ' (' . $this->getSqlComment() . ')';
 
                // Inner subselect to pull the active users out of querycachetwo
-               $tables = [ 'querycachetwo', 'user' ];
-               $fields = [ 'qcc_title', 'user_id' ];
+               $tables = [ 'querycachetwo', 'user', 'actor' ];
+               $fields = [ 'qcc_title', 'user_id', 'actor_id' ];
                $jconds = [
                        'user' => [ 'JOIN', 'user_name = qcc_title' ],
+                       'actor' => [ 'JOIN', 'actor_user = user_id' ],
                ];
                $conds = [
                        'qcc_type' => 'activeusers',
@@ -126,20 +123,12 @@ class ActiveUsersPager extends UsersPager {
                                        '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' => [ 'LEFT JOIN', [
-                       $useActor ? 'rc_actor = actor_id' : 'rc_user_text = qcc_title',
+                       'rc_actor = actor_id',
                        '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' ),
index f1b0b9a..be4a1bd 100644 (file)
@@ -97,27 +97,17 @@ class NewFilesPager extends RangeChronologicalPager {
                }
 
                if ( $opts->getValue( 'hidepatrolled' ) ) {
-                       global $wgActorTableSchemaMigrationStage;
-
                        $tables[] = 'recentchanges';
                        $conds['rc_type'] = RC_LOG;
                        $conds['rc_log_type'] = 'upload';
                        $conds['rc_patrolled'] = RecentChange::PRC_UNPATROLLED;
                        $conds['rc_namespace'] = NS_FILE;
 
-                       if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
-                               $jcond = 'rc_actor = ' . $imgQuery['fields']['img_actor'];
-                       } else {
-                               $rcQuery = ActorMigration::newMigration()->getJoin( 'rc_user' );
-                               $tables += $rcQuery['tables'];
-                               $jconds += $rcQuery['joins'];
-                               $jcond = $rcQuery['fields']['rc_user'] . ' = ' . $imgQuery['fields']['img_user'];
-                       }
                        $jconds['recentchanges'] = [
                                'JOIN',
                                [
                                        'rc_title = img_name',
-                                       $jcond,
+                                       'rc_actor = ' . $imgQuery['fields']['img_actor'],
                                        'rc_timestamp = img_timestamp'
                                ]
                        ];
index 7068879..666f2b6 100644 (file)
@@ -64,7 +64,7 @@ class User implements IDBAccessObject, UserIdentity {
         * Version number to tag cached versions of serialized User objects. Should be increased when
         * {@link $mCacheVars} or one of it's members changes.
         */
-       const VERSION = 13;
+       const VERSION = 14;
 
        /**
         * Exclude user options that are set to their default value.
@@ -327,22 +327,6 @@ class User implements IDBAccessObject, UserIdentity {
                        case 'defaults':
                                $this->loadDefaults();
                                break;
-                       case 'name':
-                               // Make sure this thread sees its own changes
-                               $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
-                               if ( $lb->hasOrMadeRecentMasterChanges() ) {
-                                       $flags |= self::READ_LATEST;
-                                       $this->queryFlagsUsed = $flags;
-                               }
-
-                               $this->mId = self::idFromName( $this->mName, $flags );
-                               if ( !$this->mId ) {
-                                       // Nonexistent user placeholder object
-                                       $this->loadDefaults( $this->mName );
-                               } else {
-                                       $this->loadFromId( $flags );
-                               }
-                               break;
                        case 'id':
                                // Make sure this thread sees its own changes, if the ID isn't 0
                                if ( $this->mId != 0 ) {
@@ -356,6 +340,7 @@ class User implements IDBAccessObject, UserIdentity {
                                $this->loadFromId( $flags );
                                break;
                        case 'actor':
+                       case 'name':
                                // Make sure this thread sees its own changes
                                $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
                                if ( $lb->hasOrMadeRecentMasterChanges() ) {
@@ -366,20 +351,20 @@ class User implements IDBAccessObject, UserIdentity {
                                list( $index, $options ) = DBAccessObjectUtils::getDBOptions( $flags );
                                $row = wfGetDB( $index )->selectRow(
                                        'actor',
-                                       [ 'actor_user', 'actor_name' ],
-                                       [ 'actor_id' => $this->mActorId ],
+                                       [ 'actor_id', 'actor_user', 'actor_name' ],
+                                       $this->mFrom === 'name' ? [ 'actor_name' => $this->mName ] : [ 'actor_id' => $this->mActorId ],
                                        __METHOD__,
                                        $options
                                );
 
                                if ( !$row ) {
                                        // Ugh.
-                                       $this->loadDefaults();
+                                       $this->loadDefaults( $this->mFrom === 'name' ? $this->mName : false );
                                } elseif ( $row->actor_user ) {
                                        $this->mId = $row->actor_user;
                                        $this->loadFromId( $flags );
                                } else {
-                                       $this->loadDefaults( $row->actor_name );
+                                       $this->loadDefaults( $row->actor_name, $row->actor_id );
                                }
                                break;
                        case 'session':
@@ -567,17 +552,6 @@ class User implements IDBAccessObject, UserIdentity {
         * @return User The corresponding User object
         */
        public static function newFromActorId( $id ) {
-               global $wgActorTableSchemaMigrationStage;
-
-               // Technically we shouldn't allow this without SCHEMA_COMPAT_READ_NEW,
-               // but it does little harm and might be needed for write callers loading a User.
-               if ( !( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_NEW ) ) {
-                       throw new BadMethodCallException(
-                               'Cannot use ' . __METHOD__
-                                       . ' when $wgActorTableSchemaMigrationStage lacks SCHEMA_COMPAT_NEW'
-                       );
-               }
-
                $u = new User;
                $u->mActorId = $id;
                $u->mFrom = 'actor';
@@ -620,8 +594,6 @@ class User implements IDBAccessObject, UserIdentity {
         * @return User
         */
        public static function newFromAnyId( $userId, $userName, $actorId, $dbDomain = false ) {
-               global $wgActorTableSchemaMigrationStage;
-
                // Stop-gap solution for the problem described in T222212.
                // Force the User ID and Actor ID to zero for users loaded from the database
                // of another wiki, to prevent subtle data corruption and confusing failure modes.
@@ -633,9 +605,7 @@ class User implements IDBAccessObject, UserIdentity {
                $user = new User;
                $user->mFrom = 'defaults';
 
-               // Technically we shouldn't allow this without SCHEMA_COMPAT_READ_NEW,
-               // but it does little harm and might be needed for write callers loading a User.
-               if ( ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_NEW ) && $actorId !== null ) {
+               if ( $actorId !== null ) {
                        $user->mActorId = (int)$actorId;
                        if ( $user->mActorId !== 0 ) {
                                $user->mFrom = 'actor';
@@ -1220,11 +1190,12 @@ class User implements IDBAccessObject, UserIdentity {
         *       the constructor does that instead.
         *
         * @param string|bool $name
+        * @param int|null $actorId
         */
-       public function loadDefaults( $name = false ) {
+       public function loadDefaults( $name = false, $actorId = null ) {
                $this->mId = 0;
                $this->mName = $name;
-               $this->mActorId = null;
+               $this->mActorId = $actorId;
                $this->mRealName = '';
                $this->mEmail = '';
                $this->mOptionOverrides = null;
@@ -1375,8 +1346,6 @@ class User implements IDBAccessObject, UserIdentity {
         *  user_properties   Array with properties out of the user_properties table
         */
        protected function loadFromRow( $row, $data = null ) {
-               global $wgActorTableSchemaMigrationStage;
-
                if ( !is_object( $row ) ) {
                        throw new InvalidArgumentException( '$row must be an object' );
                }
@@ -1385,18 +1354,14 @@ class User implements IDBAccessObject, UserIdentity {
 
                $this->mGroupMemberships = null; // deferred
 
-               // Technically we shouldn't allow this without SCHEMA_COMPAT_READ_NEW,
-               // but it does little harm and might be needed for write callers loading a User.
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_NEW ) {
-                       if ( isset( $row->actor_id ) ) {
-                               $this->mActorId = (int)$row->actor_id;
-                               if ( $this->mActorId !== 0 ) {
-                                       $this->mFrom = 'actor';
-                               }
-                               $this->setItemLoaded( 'actor' );
-                       } else {
-                               $all = false;
+               if ( isset( $row->actor_id ) ) {
+                       $this->mActorId = (int)$row->actor_id;
+                       if ( $this->mActorId !== 0 ) {
+                               $this->mFrom = 'actor';
                        }
+                       $this->setItemLoaded( 'actor' );
+               } else {
+                       $all = false;
                }
 
                if ( isset( $row->user_name ) && $row->user_name !== '' ) {
@@ -2214,7 +2179,9 @@ class User implements IDBAccessObject, UserIdentity {
         * @return int The user's ID; 0 if the user is anonymous or nonexistent
         */
        public function getId() {
-               if ( $this->mId === null && $this->mName !== null && self::isIP( $this->mName ) ) {
+               if ( $this->mId === null && $this->mName !== null &&
+                       ( self::isIP( $this->mName ) || ExternalUserNames::isExternal( $this->mName ) )
+               ) {
                        // Special case, we know the user is anonymous
                        return 0;
                }
@@ -2280,62 +2247,43 @@ class User implements IDBAccessObject, UserIdentity {
         * @return int The actor's ID, or 0 if no actor ID exists and $dbw was null
         */
        public function getActorId( IDatabase $dbw = null ) {
-               global $wgActorTableSchemaMigrationStage;
-
-               // Technically we should always return 0 without SCHEMA_COMPAT_READ_NEW,
-               // but it does little harm and might be needed for write callers loading a User.
-               if ( !( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) ) {
-                       return 0;
-               }
-
                if ( !$this->isItemLoaded( 'actor' ) ) {
                        $this->load();
                }
 
-               // Currently $this->mActorId might be null if $this was loaded from a
-               // cache entry that was written when $wgActorTableSchemaMigrationStage
-               // was SCHEMA_COMPAT_OLD. Once that is no longer a possibility (i.e. when
-               // User::VERSION is incremented after $wgActorTableSchemaMigrationStage
-               // has been removed), that condition may be removed.
-               if ( $this->mActorId === null || !$this->mActorId && $dbw ) {
+               if ( !$this->mActorId && $dbw ) {
                        $q = [
                                'actor_user' => $this->getId() ?: null,
                                'actor_name' => (string)$this->getName(),
                        ];
-                       if ( $dbw ) {
-                               if ( $q['actor_user'] === null && self::isUsableName( $q['actor_name'] ) ) {
+                       if ( $q['actor_user'] === null && self::isUsableName( $q['actor_name'] ) ) {
+                               throw new CannotCreateActorException(
+                                       'Cannot create an actor for a usable name that is not an existing user'
+                               );
+                       }
+                       if ( $q['actor_name'] === '' ) {
+                               throw new CannotCreateActorException( 'Cannot create an actor for a user with no name' );
+                       }
+                       $dbw->insert( 'actor', $q, __METHOD__, [ 'IGNORE' ] );
+                       if ( $dbw->affectedRows() ) {
+                               $this->mActorId = (int)$dbw->insertId();
+                       } else {
+                               // Outdated cache?
+                               // Use LOCK IN SHARE MODE to bypass any MySQL REPEATABLE-READ snapshot.
+                               $this->mActorId = (int)$dbw->selectField(
+                                       'actor',
+                                       'actor_id',
+                                       $q,
+                                       __METHOD__,
+                                       [ 'LOCK IN SHARE MODE' ]
+                               );
+                               if ( !$this->mActorId ) {
                                        throw new CannotCreateActorException(
-                                               'Cannot create an actor for a usable name that is not an existing user'
-                                       );
-                               }
-                               if ( $q['actor_name'] === '' ) {
-                                       throw new CannotCreateActorException( 'Cannot create an actor for a user with no name' );
-                               }
-                               $dbw->insert( 'actor', $q, __METHOD__, [ 'IGNORE' ] );
-                               if ( $dbw->affectedRows() ) {
-                                       $this->mActorId = (int)$dbw->insertId();
-                               } else {
-                                       // Outdated cache?
-                                       // Use LOCK IN SHARE MODE to bypass any MySQL REPEATABLE-READ snapshot.
-                                       $this->mActorId = (int)$dbw->selectField(
-                                               'actor',
-                                               'actor_id',
-                                               $q,
-                                               __METHOD__,
-                                               [ 'LOCK IN SHARE MODE' ]
+                                               "Cannot create actor ID for user_id={$this->getId()} user_name={$this->getName()}"
                                        );
-                                       if ( !$this->mActorId ) {
-                                               throw new CannotCreateActorException(
-                                                       "Cannot create actor ID for user_id={$this->getId()} user_name={$this->getName()}"
-                                               );
-                                       }
                                }
-                               $this->invalidateCache();
-                       } else {
-                               list( $index, $options ) = DBAccessObjectUtils::getDBOptions( $this->queryFlagsUsed );
-                               $db = wfGetDB( $index );
-                               $this->mActorId = (int)$db->selectField( 'actor', 'actor_id', $q, __METHOD__, $options );
                        }
+                       $this->invalidateCache();
                        $this->setItemLoaded( 'actor' );
                }
 
@@ -3979,8 +3927,6 @@ class User implements IDBAccessObject, UserIdentity {
 
                $dbw = wfGetDB( DB_MASTER );
                $dbw->doAtomicSection( __METHOD__, function ( IDatabase $dbw, $fname ) use ( $newTouched ) {
-                       global $wgActorTableSchemaMigrationStage;
-
                        $dbw->update( 'user',
                                [ /* SET */
                                        'user_name' => $this->mName,
@@ -4010,14 +3956,12 @@ class User implements IDBAccessObject, UserIdentity {
                                );
                        }
 
-                       if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                               $dbw->update(
-                                       'actor',
-                                       [ 'actor_name' => $this->mName ],
-                                       [ 'actor_user' => $this->mId ],
-                                       $fname
-                               );
-                       }
+                       $dbw->update(
+                               'actor',
+                               [ 'actor_name' => $this->mName ],
+                               [ 'actor_user' => $this->mId ],
+                               $fname
+                       );
                } );
 
                $this->mTouched = $newTouched;
@@ -4216,16 +4160,12 @@ class User implements IDBAccessObject, UserIdentity {
         * @param IDatabase $dbw Writable database handle
         */
        private function updateActorId( IDatabase $dbw ) {
-               global $wgActorTableSchemaMigrationStage;
-
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                       $dbw->insert(
-                               'actor',
-                               [ 'actor_user' => $this->mId, 'actor_name' => $this->mName ],
-                               __METHOD__
-                       );
-                       $this->mActorId = (int)$dbw->insertId();
-               }
+               $dbw->insert(
+                       'actor',
+                       [ 'actor_user' => $this->mId, 'actor_name' => $this->mName ],
+                       __METHOD__
+               );
+               $this->mActorId = (int)$dbw->insertId();
        }
 
        /**
@@ -5296,10 +5236,8 @@ class User implements IDBAccessObject, UserIdentity {
         *   - joins: (array) to include in the `$join_conds` to `IDatabase->select()`
         */
        public static function getQueryInfo() {
-               global $wgActorTableSchemaMigrationStage;
-
                $ret = [
-                       'tables' => [ 'user' ],
+                       'tables' => [ 'user', 'user_actor' => 'actor' ],
                        'fields' => [
                                'user_id',
                                'user_name',
@@ -5312,21 +5250,13 @@ class User implements IDBAccessObject, UserIdentity {
                                'user_email_token_expires',
                                'user_registration',
                                'user_editcount',
+                               'user_actor.actor_id',
+                       ],
+                       'joins' => [
+                               'user_actor' => [ 'JOIN', 'user_actor.actor_user = user_id' ],
                        ],
-                       'joins' => [],
                ];
 
-               // Technically we shouldn't allow this without SCHEMA_COMPAT_READ_NEW,
-               // but it does little harm and might be needed for write callers loading a User.
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_NEW ) {
-                       $ret['tables']['user_actor'] = 'actor';
-                       $ret['fields'][] = 'user_actor.actor_id';
-                       $ret['joins']['user_actor'] = [
-                               ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) ? 'JOIN' : 'LEFT JOIN',
-                               [ 'user_actor.actor_user = user_id' ]
-                       ];
-               }
-
                return $ret;
        }
 
index 0df4cd0..5c2d290 100644 (file)
--- a/index.php
+++ b/index.php
@@ -30,6 +30,8 @@
  * @file
  */
 
+define( 'MW_ENTRY_POINT', 'index' );
+
 // Bail on old versions of PHP, or if composer has not been run yet to install
 // dependencies. Using dirname( __FILE__ ) here because __DIR__ is PHP5.3+.
 // phpcs:ignore MediaWiki.Usage.DirUsage.FunctionFound
index 6edb7ec..3f0c3df 100644 (file)
--- a/load.php
+++ b/load.php
@@ -28,6 +28,8 @@ use MediaWiki\MediaWikiServices;
 // details of the session. Enforce this constraint with respect to session use.
 define( 'MW_NO_SESSION', 1 );
 
+define( 'MW_ENTRY_POINT', 'load' );
+
 require __DIR__ . '/includes/WebStart.php';
 
 // URL safety checks
index 6d6dbe5..f89fa62 100644 (file)
@@ -20,6 +20,8 @@
  * @defgroup Maintenance Maintenance
  */
 
+define( 'MW_ENTRY_POINT', 'cli' );
+
 // Bail on old versions of PHP, or if composer has not been run yet to install
 // dependencies.
 require_once __DIR__ . '/../includes/PHPVersionCheck.php';
diff --git a/maintenance/archives/patch-drop-user-fields.sql b/maintenance/archives/patch-drop-user-fields.sql
new file mode 100644 (file)
index 0000000..7faa593
--- /dev/null
@@ -0,0 +1,50 @@
+--
+-- patch-drop-user-fields.sql
+--
+-- T188327. Drop old xx_user and xx_user_text fields, and defaults from xx_actor fields.
+
+ALTER TABLE /*_*/archive
+  DROP INDEX /*i*/ar_usertext_timestamp,
+  DROP COLUMN ar_user,
+  DROP COLUMN ar_user_text,
+  ALTER COLUMN ar_actor DROP DEFAULT;
+
+ALTER TABLE /*_*/ipblocks
+  DROP COLUMN ipb_by,
+  DROP COLUMN ipb_by_text,
+  ALTER COLUMN ipb_by_actor DROP DEFAULT;
+
+ALTER TABLE /*_*/image
+  DROP INDEX /*i*/img_user_timestamp,
+  DROP INDEX /*i*/img_usertext_timestamp,
+  DROP COLUMN img_user,
+  DROP COLUMN img_user_text,
+  ALTER COLUMN img_actor DROP DEFAULT;
+
+ALTER TABLE /*_*/oldimage
+  DROP INDEX /*i*/oi_usertext_timestamp,
+  DROP COLUMN oi_user,
+  DROP COLUMN oi_user_text,
+  ALTER COLUMN oi_actor DROP DEFAULT;
+
+ALTER TABLE /*_*/filearchive
+  DROP INDEX /*i*/fa_user_timestamp,
+  DROP COLUMN fa_user,
+  DROP COLUMN fa_user_text,
+  ALTER COLUMN fa_actor DROP DEFAULT;
+
+ALTER TABLE /*_*/recentchanges
+  DROP INDEX /*i*/rc_ns_usertext,
+  DROP INDEX /*i*/rc_user_text,
+  DROP COLUMN rc_user,
+  DROP COLUMN rc_user_text,
+  ALTER COLUMN rc_actor DROP DEFAULT;
+
+ALTER TABLE /*_*/logging
+  DROP INDEX /*i*/user_time,
+  DROP INDEX /*i*/log_user_type_time,
+  DROP INDEX /*i*/log_user_text_type_time,
+  DROP INDEX /*i*/log_user_text_time,
+  DROP COLUMN log_user,
+  DROP COLUMN log_user_text,
+  ALTER COLUMN log_actor DROP DEFAULT;
index d861348..7e9104c 100644 (file)
@@ -38,9 +38,7 @@ class GetReplicaServer extends Maintenance {
        }
 
        public function execute() {
-               if ( $this->getConfig()->get( 'AllDBsAreLocalhost' ) ) {
-                       $host = 'localhost';
-               } elseif ( $this->hasOption( 'group' ) ) {
+               if ( $this->hasOption( 'group' ) ) {
                        $db = $this->getDB( DB_REPLICA, $this->getOption( 'group' ) );
                        $host = $db->getServer();
                } else {
index 1b35a20..48dcf8d 100644 (file)
@@ -51,15 +51,6 @@ class MigrateActors extends LoggedUpdateMaintenance {
        }
 
        protected function doDBUpdates() {
-               $actorTableSchemaMigrationStage = $this->getConfig()->get( 'ActorTableSchemaMigrationStage' );
-
-               if ( !( $actorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) ) {
-                       $this->output(
-                               "...cannot update while \$wgActorTableSchemaMigrationStage lacks SCHEMA_COMPAT_WRITE_NEW\n"
-                       );
-                       return false;
-               }
-
                $tables = $this->getOption( 'tables' );
                if ( $tables !== null ) {
                        $this->tables = explode( ',', $tables );
@@ -265,6 +256,12 @@ class MigrateActors extends LoggedUpdateMaintenance {
                        return 0;
                }
 
+               $dbw = $this->getDB( DB_MASTER );
+               if ( !$dbw->fieldExists( $table, $userField, __METHOD__ ) ) {
+                       $this->output( "No need to migrate $table.$userField, field does not exist\n" );
+                       return 0;
+               }
+
                $complainedAboutUsers = [];
 
                $primaryKey = (array)$primaryKey;
@@ -274,7 +271,6 @@ class MigrateActors extends LoggedUpdateMaintenance {
                );
                wfWaitForSlaves();
 
-               $dbw = $this->getDB( DB_MASTER );
                $actorIdSubquery = $this->makeActorIdSubquery( $dbw, $userField, $nameField );
                $next = '1=1';
                $countUpdated = 0;
@@ -357,6 +353,7 @@ class MigrateActors extends LoggedUpdateMaintenance {
         * @param string $nameField User name field name
         * @param string $newPrimaryKey Primary key of the new table.
         * @param string $actorField Actor field name
+        * @return int Number of errors
         */
        protected function migrateToTemp(
                $table, $primaryKey, $extra, $userField, $nameField, $newPrimaryKey, $actorField
@@ -366,6 +363,12 @@ class MigrateActors extends LoggedUpdateMaintenance {
                        return 0;
                }
 
+               $dbw = $this->getDB( DB_MASTER );
+               if ( !$dbw->fieldExists( $table, $userField, __METHOD__ ) ) {
+                       $this->output( "No need to migrate $table.$userField, field does not exist\n" );
+                       return 0;
+               }
+
                $complainedAboutUsers = [];
 
                $newTable = $table . '_actor_temp';
@@ -374,7 +377,6 @@ class MigrateActors extends LoggedUpdateMaintenance {
                );
                wfWaitForSlaves();
 
-               $dbw = $this->getDB( DB_MASTER );
                $actorIdSubquery = $this->makeActorIdSubquery( $dbw, $userField, $nameField );
                $next = [];
                $countUpdated = 0;
index 87fb396..20096a2 100644 (file)
@@ -244,9 +244,7 @@ CREATE TABLE archive (
   ar_parent_id      INTEGER          NULL,
   ar_sha1           TEXT         NOT NULL DEFAULT '',
   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,
+  ar_actor          INTEGER      NOT NULL,
   ar_timestamp      TIMESTAMPTZ  NOT NULL,
   ar_minor_edit     SMALLINT     NOT NULL  DEFAULT 0,
   ar_rev_id         INTEGER      NOT NULL,
@@ -258,7 +256,6 @@ CREATE TABLE archive (
 );
 ALTER SEQUENCE archive_ar_id_seq OWNED BY archive.ar_id;
 CREATE INDEX archive_name_title_timestamp ON archive (ar_namespace,ar_title,ar_timestamp);
-CREATE INDEX archive_user_text            ON archive (ar_user_text);
 CREATE INDEX archive_actor                ON archive (ar_actor);
 CREATE UNIQUE INDEX ar_revid_uniq ON archive (ar_rev_id);
 
@@ -404,9 +401,7 @@ CREATE TABLE ipblocks (
   ipb_id                INTEGER      NOT NULL  PRIMARY KEY DEFAULT nextval('ipblocks_ipb_id_seq'),
   ipb_address           TEXT             NULL,
   ipb_user              INTEGER          NULL  REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
-  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_by_actor          INTEGER      NOT NULL,
   ipb_reason_id         INTEGER      NOT NULL,
   ipb_timestamp         TIMESTAMPTZ  NOT NULL,
   ipb_auto              SMALLINT     NOT NULL  DEFAULT 0,
@@ -448,9 +443,7 @@ CREATE TABLE image (
   img_major_mime   TEXT                DEFAULT 'unknown',
   img_minor_mime   TEXT                DEFAULT 'unknown',
   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,
+  img_actor        INTEGER   NOT NULL,
   img_timestamp    TIMESTAMPTZ,
   img_sha1         TEXT      NOT NULL  DEFAULT ''
 );
@@ -466,9 +459,7 @@ CREATE TABLE oldimage (
   oi_height        INTEGER      NOT NULL,
   oi_bits          SMALLINT         NULL,
   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,
+  oi_actor         INTEGER      NOT NULL,
   oi_timestamp     TIMESTAMPTZ      NULL,
   oi_metadata      BYTEA        NOT NULL DEFAULT '',
   oi_media_type    TEXT             NULL,
@@ -502,9 +493,7 @@ CREATE TABLE filearchive (
   fa_major_mime         TEXT                   DEFAULT 'unknown',
   fa_minor_mime         TEXT                   DEFAULT 'unknown',
   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,
+  fa_actor              INTEGER      NOT NULL,
   fa_timestamp          TIMESTAMPTZ,
   fa_deleted            SMALLINT     NOT NULL DEFAULT 0,
   fa_sha1               TEXT         NOT NULL DEFAULT ''
@@ -548,9 +537,7 @@ CREATE SEQUENCE recentchanges_rc_id_seq;
 CREATE TABLE recentchanges (
   rc_id              INTEGER      NOT NULL  PRIMARY KEY DEFAULT nextval('recentchanges_rc_id_seq'),
   rc_timestamp       TIMESTAMPTZ  NOT NULL,
-  rc_user            INTEGER      NOT NULL  DEFAULT 0 REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
-  rc_user_text       TEXT         NOT NULL  DEFAULT '',
-  rc_actor           INTEGER      NOT NULL  DEFAULT 0,
+  rc_actor           INTEGER      NOT NULL,
   rc_namespace       SMALLINT     NOT NULL,
   rc_title           TEXT         NOT NULL,
   rc_comment_id      INTEGER      NOT NULL,
@@ -646,27 +633,21 @@ CREATE TABLE logging (
   log_type        TEXT         NOT NULL,
   log_action      TEXT         NOT NULL,
   log_timestamp   TIMESTAMPTZ  NOT NULL,
-  log_user        INTEGER      NOT NULL DEFAULT 0 REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
-  log_actor       INTEGER      NOT NULL DEFAULT 0,
+  log_actor       INTEGER      NOT NULL,
   log_namespace   SMALLINT     NOT NULL,
   log_title       TEXT         NOT NULL,
   log_comment_id  INTEGER      NOT NULL,
   log_params      TEXT,
   log_deleted     SMALLINT     NOT NULL DEFAULT 0,
-  log_user_text   TEXT         NOT NULL DEFAULT '',
   log_page        INTEGER
 );
 ALTER SEQUENCE logging_log_id_seq OWNED BY logging.log_id;
 CREATE INDEX logging_type_name ON logging (log_type, log_timestamp);
-CREATE INDEX logging_user_time ON logging (log_timestamp, log_user);
 CREATE INDEX logging_actor_time_backwards ON logging (log_timestamp, log_actor);
 CREATE INDEX logging_page_time ON logging (log_namespace, log_title, log_timestamp);
 CREATE INDEX logging_times ON logging (log_timestamp);
-CREATE INDEX logging_user_type_time ON logging (log_user, log_type, log_timestamp);
 CREATE INDEX logging_actor_type_time ON logging (log_actor, log_type, log_timestamp);
 CREATE INDEX logging_page_id_time ON logging (log_page, log_timestamp);
-CREATE INDEX logging_user_text_type_time ON logging (log_user_text, log_type, log_timestamp);
-CREATE INDEX logging_user_text_time ON logging (log_user_text, log_timestamp);
 CREATE INDEX logging_actor_time ON logging (log_actor, log_timestamp);
 CREATE INDEX logging_type_action ON logging (log_type, log_action, log_timestamp);
 
index 54f1862..f3b856c 100644 (file)
@@ -23,8 +23,6 @@
  * @license GPL-2.0-or-later
  */
 
-use Wikimedia\Rdbms\IDatabase;
-
 require_once __DIR__ . '/Maintenance.php';
 
 /**
@@ -76,8 +74,6 @@ class ReassignEdits extends Maintenance {
         * @return int Number of entries changed, or that would be changed
         */
        private function doReassignEdits( &$from, &$to, $rc = false, $report = false ) {
-               $actorTableSchemaMigrationStage = $this->getConfig()->get( 'ActorTableSchemaMigrationStage' );
-
                $dbw = $this->getDB( DB_MASTER );
                $this->beginTransaction( $dbw, __METHOD__ );
 
@@ -136,36 +132,22 @@ class ReassignEdits extends Maintenance {
                        if ( $total ) {
                                # Reassign edits
                                $this->output( "\nReassigning current edits..." );
-                               if ( $actorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) {
-                                       $dbw->update(
-                                               'revision',
-                                               [
-                                                       'rev_user' => $to->getId(),
-                                                       'rev_user_text' => $to->getName(),
-                                               ],
-                                               $from->isLoggedIn()
-                                                       ? [ 'rev_user' => $from->getId() ] : [ 'rev_user_text' => $from->getName() ],
-                                               __METHOD__
-                                       );
-                               }
-                               if ( $actorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                                       $dbw->update(
-                                               'revision_actor_temp',
-                                               [ 'revactor_actor' => $to->getActorId( $dbw ) ],
-                                               [ 'revactor_actor' => $from->getActorId() ],
-                                               __METHOD__
-                                       );
-                               }
+                               $dbw->update(
+                                       'revision_actor_temp',
+                                       [ 'revactor_actor' => $to->getActorId( $dbw ) ],
+                                       [ 'revactor_actor' => $from->getActorId() ],
+                                       __METHOD__
+                               );
                                $this->output( "done.\nReassigning deleted edits..." );
                                $dbw->update( 'archive',
-                                       $this->userSpecification( $dbw, $to, 'ar_user', 'ar_user_text', 'ar_actor' ),
+                                       [ 'ar_actor' => $to->getActorId( $dbw ) ],
                                        [ $arQueryInfo['conds'] ], __METHOD__ );
                                $this->output( "done.\n" );
                                # Update recent changes if required
                                if ( $rc ) {
                                        $this->output( "Updating recent changes..." );
                                        $dbw->update( 'recentchanges',
-                                               $this->userSpecification( $dbw, $to, 'rc_user', 'rc_user_text', 'rc_actor' ),
+                                               [ 'rc_actor' => $to->getActorId( $dbw ) ],
                                                [ $rcQueryInfo['conds'] ], __METHOD__ );
                                        $this->output( "done.\n" );
                                }
@@ -177,33 +159,6 @@ class ReassignEdits extends Maintenance {
                return (int)$total;
        }
 
-       /**
-        * Return user specifications for an UPDATE
-        * i.e. user => id, user_text => text
-        *
-        * @param IDatabase $dbw Database handle
-        * @param User $user User for the spec
-        * @param string $idfield Field name containing the identifier
-        * @param string $utfield Field name containing the user text
-        * @param string $acfield Field name containing the actor ID
-        * @return array
-        */
-       private function userSpecification( IDatabase $dbw, &$user, $idfield, $utfield, $acfield ) {
-               $actorTableSchemaMigrationStage = $this->getConfig()->get( 'ActorTableSchemaMigrationStage' );
-
-               $ret = [];
-               if ( $actorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) {
-                       $ret += [
-                               $idfield => $user->getId(),
-                               $utfield => $user->getName(),
-                       ];
-               }
-               if ( $actorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                       $ret += [ $acfield => $user->getActorId( $dbw ) ];
-               }
-               return $ret;
-       }
-
        /**
         * Initialise the user object
         *
index 16a7346..ca90468 100644 (file)
@@ -39,8 +39,6 @@ class RemoveUnusedAccounts extends Maintenance {
        }
 
        public function execute() {
-               $actorTableSchemaMigrationStage = $this->getConfig()->get( 'ActorTableSchemaMigrationStage' );
-
                $this->output( "Remove unused accounts\n\n" );
 
                # Do an initial scan for inactive accounts and report the result
@@ -48,18 +46,14 @@ class RemoveUnusedAccounts extends Maintenance {
                $delUser = [];
                $delActor = [];
                $dbr = $this->getDB( DB_REPLICA );
-               if ( $actorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                       $res = $dbr->select(
-                               [ 'user', 'actor' ],
-                               [ 'user_id', 'user_name', 'user_touched', 'actor_id' ],
-                               '',
-                               __METHOD__,
-                               [],
-                               [ 'actor' => [ 'LEFT JOIN', 'user_id = actor_user' ] ]
-                       );
-               } else {
-                       $res = $dbr->select( 'user', [ 'user_id', 'user_name', 'user_touched' ], '', __METHOD__ );
-               }
+               $res = $dbr->select(
+                       [ 'user', 'actor' ],
+                       [ 'user_id', 'user_name', 'user_touched', 'actor_id' ],
+                       '',
+                       __METHOD__,
+                       [],
+                       [ 'actor' => [ 'LEFT JOIN', 'user_id = actor_user' ] ]
+               );
                if ( $this->hasOption( 'ignore-groups' ) ) {
                        $excludedGroups = explode( ',', $this->getOption( 'ignore-groups' ) );
                } else {
@@ -94,30 +88,22 @@ class RemoveUnusedAccounts extends Maintenance {
                        $this->output( "\nDeleting unused accounts..." );
                        $dbw = $this->getDB( DB_MASTER );
                        $dbw->delete( 'user', [ 'user_id' => $delUser ], __METHOD__ );
-                       if ( $actorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                               # Keep actor rows referenced from ipblocks
-                               $keep = $dbw->selectFieldValues(
-                                       'ipblocks', 'ipb_by_actor', [ 'ipb_by_actor' => $delActor ], __METHOD__
-                               );
-                               $del = array_diff( $delActor, $keep );
-                               if ( $del ) {
-                                       $dbw->delete( 'actor', [ 'actor_id' => $del ], __METHOD__ );
-                               }
-                               if ( $keep ) {
-                                       $dbw->update( 'actor', [ 'actor_user' => 0 ], [ 'actor_id' => $keep ], __METHOD__ );
-                               }
+                       # Keep actor rows referenced from ipblocks
+                       $keep = $dbw->selectFieldValues(
+                               'ipblocks', 'ipb_by_actor', [ 'ipb_by_actor' => $delActor ], __METHOD__
+                       );
+                       $del = array_diff( $delActor, $keep );
+                       if ( $del ) {
+                               $dbw->delete( 'actor', [ 'actor_id' => $del ], __METHOD__ );
+                       }
+                       if ( $keep ) {
+                               $dbw->update( 'actor', [ 'actor_user' => 0 ], [ 'actor_id' => $keep ], __METHOD__ );
                        }
                        $dbw->delete( 'user_groups', [ 'ug_user' => $delUser ], __METHOD__ );
                        $dbw->delete( 'user_former_groups', [ 'ufg_user' => $delUser ], __METHOD__ );
                        $dbw->delete( 'user_properties', [ 'up_user' => $delUser ], __METHOD__ );
-                       if ( $actorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                               $dbw->delete( 'logging', [ 'log_actor' => $delActor ], __METHOD__ );
-                               $dbw->delete( 'recentchanges', [ 'rc_actor' => $delActor ], __METHOD__ );
-                       }
-                       if ( $actorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) {
-                               $dbw->delete( 'logging', [ 'log_user' => $delUser ], __METHOD__ );
-                               $dbw->delete( 'recentchanges', [ 'rc_user' => $delUser ], __METHOD__ );
-                       }
+                       $dbw->delete( 'logging', [ 'log_actor' => $delActor ], __METHOD__ );
+                       $dbw->delete( 'recentchanges', [ 'rc_actor' => $delActor ], __METHOD__ );
                        $this->output( "done.\n" );
                        # Update the site_stats.ss_users field
                        $users = $dbw->selectField( 'user', 'COUNT(*)', [], __METHOD__ );
diff --git a/maintenance/sqlite/archives/patch-archive-drop-ar_user.sql b/maintenance/sqlite/archives/patch-archive-drop-ar_user.sql
new file mode 100644 (file)
index 0000000..ceb7d7d
--- /dev/null
@@ -0,0 +1,44 @@
+--
+-- patch-archive-drop-ar_user.sql
+--
+-- T188327. Drop old xx_user and xx_user_text fields, and defaults from xx_actor 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_actor bigint unsigned NOT NULL,
+  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_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_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_actor_timestamp ON /*_*/archive (ar_actor,ar_timestamp);
+CREATE UNIQUE INDEX /*i*/ar_revid_uniq ON /*_*/archive (ar_rev_id);
+
+COMMIT;
diff --git a/maintenance/sqlite/archives/patch-filearchive-drop-fa_user.sql b/maintenance/sqlite/archives/patch-filearchive-drop-fa_user.sql
new file mode 100644 (file)
index 0000000..0a20a56
--- /dev/null
@@ -0,0 +1,55 @@
+--
+-- patch-filearchive-drop-fa_user.sql
+--
+-- T188327. Drop old xx_user and xx_user_text fields, and defaults from xx_actor 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_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_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_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_actor_timestamp ON /*_*/filearchive (fa_actor,fa_timestamp);
+CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1(10));
+
+COMMIT;
diff --git a/maintenance/sqlite/archives/patch-image-drop-img_user.sql b/maintenance/sqlite/archives/patch-image-drop-img_user.sql
new file mode 100644 (file)
index 0000000..d93e122
--- /dev/null
@@ -0,0 +1,43 @@
+--
+-- patch-image-drop-img_description.sql
+--
+-- T188327. Drop old xx_user and xx_user_text fields, and defaults from xx_actor 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_actor bigint unsigned NOT NULL,
+  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_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_actor, img_timestamp, img_sha1
+  FROM /*_*/image;
+
+DROP TABLE /*_*/image;
+ALTER TABLE /*_*/image_tmp RENAME TO /*_*/image;
+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;
diff --git a/maintenance/sqlite/archives/patch-ipblocks-drop-ipb_by.sql b/maintenance/sqlite/archives/patch-ipblocks-drop-ipb_by.sql
new file mode 100644 (file)
index 0000000..2de5e09
--- /dev/null
@@ -0,0 +1,51 @@
+--
+-- patch-ipblocks-drop-ipb_by.sql
+--
+-- T188327. Drop old xx_user and xx_user_text fields, and defaults from xx_actor 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_actor bigint unsigned NOT NULL,
+  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_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_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;
diff --git a/maintenance/sqlite/archives/patch-logging-drop-log_user.sql b/maintenance/sqlite/archives/patch-logging-drop-log_user.sql
new file mode 100644 (file)
index 0000000..0f5871a
--- /dev/null
@@ -0,0 +1,41 @@
+--
+-- patch-logging-drop-log_user.sql
+--
+-- T188327. Drop old xx_user and xx_user_text fields, and defaults from xx_actor 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_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_actor,
+       log_namespace, log_title, log_page, log_comment_id, log_params, log_deleted
+  ) SELECT
+       log_id, log_type, log_action, log_timestamp, 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*/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_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);
+
+COMMIT;
diff --git a/maintenance/sqlite/archives/patch-oldimage-drop-oi_user.sql b/maintenance/sqlite/archives/patch-oldimage-drop-oi_user.sql
new file mode 100644 (file)
index 0000000..8735238
--- /dev/null
@@ -0,0 +1,44 @@
+--
+-- patch-oldimage-drop-oi_user.sql
+--
+-- T188327. Drop old xx_user and xx_user_text fields, and defaults from xx_actor 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_actor bigint unsigned NOT NULL,
+  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_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_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_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;
diff --git a/maintenance/sqlite/archives/patch-recentchanges-drop-rc_user.sql b/maintenance/sqlite/archives/patch-recentchanges-drop-rc_user.sql
new file mode 100644 (file)
index 0000000..ba1f434
--- /dev/null
@@ -0,0 +1,59 @@
+--
+-- patch-recentchanges-drop-rc_user.sql
+--
+-- T188327. Drop old xx_user and xx_user_text fields, and defaults from xx_actor 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_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_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_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_actor ON /*_*/recentchanges (rc_namespace, rc_actor);
+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;
index df15abf..55c6775 100644 (file)
@@ -594,9 +594,7 @@ CREATE TABLE /*_*/archive (
 
   -- Basic revision stuff...
   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)
+  ar_actor bigint unsigned NOT NULL,
   ar_timestamp binary(14) NOT NULL default '',
   ar_minor_edit tinyint NOT NULL default 0,
 
@@ -661,7 +659,6 @@ CREATE TABLE /*_*/archive (
 CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp);
 
 -- Index for Special:DeletedContributions
-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);
 
 -- Index for linking archive rows with tables that normally link with revision
@@ -1034,14 +1031,8 @@ CREATE TABLE /*_*/ipblocks (
   -- Blocked user ID or 0 for IP blocks.
   ipb_user int unsigned NOT NULL default 0,
 
-  -- User ID who made the block.
-  ipb_by int unsigned NOT NULL default 0, -- Deprecated in favor of ipb_by_actor
-
-  -- User name of blocker
-  ipb_by_text varchar(255) binary NOT NULL default '', -- Deprecated in favor of ipb_by_actor
-
   -- 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)
+  ipb_by_actor bigint unsigned NOT NULL,
 
   -- Key to comment_id. Text comment made by blocker.
   ipb_reason_id bigint unsigned NOT NULL,
@@ -1177,14 +1168,8 @@ CREATE TABLE /*_*/image (
   -- This is displayed in image upload history and logs.
   img_description_id bigint unsigned NOT NULL,
 
-  -- user_id and user_name of uploader.
-  -- Deprecated in favor of img_actor.
-  img_user int unsigned NOT NULL default 0,
-  img_user_text varchar(255) binary NOT NULL DEFAULT '',
-
   -- actor_id of the uploader.
-  -- ("DEFAULT 0" is temporary, signaling that img_user/img_user_text should be used)
-  img_actor bigint unsigned NOT NULL DEFAULT 0,
+  img_actor bigint unsigned NOT NULL,
 
   -- Time of the upload.
   img_timestamp varbinary(14) NOT NULL default '',
@@ -1194,8 +1179,6 @@ CREATE TABLE /*_*/image (
 ) /*$wgDBTableOptions*/;
 
 -- Used by Special:Newimages and ApiQueryAllImages
-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);
 -- Used by Special:ListFiles for sort-by-size
 CREATE INDEX /*i*/img_size ON /*_*/image (img_size);
@@ -1226,9 +1209,7 @@ CREATE TABLE /*_*/oldimage (
   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, -- 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)
+  oi_actor bigint unsigned NOT NULL,
   oi_timestamp binary(14) NOT NULL default '',
 
   oi_metadata mediumblob NOT NULL,
@@ -1239,7 +1220,6 @@ CREATE TABLE /*_*/oldimage (
   oi_sha1 varbinary(32) NOT NULL default ''
 ) /*$wgDBTableOptions*/;
 
-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);
 -- oi_archive_name truncated to 14 to avoid key length overflow
@@ -1287,9 +1267,7 @@ CREATE TABLE /*_*/filearchive (
   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, -- 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)
+  fa_actor bigint unsigned NOT NULL,
   fa_timestamp binary(14) default '',
 
   -- Visibility of deleted revisions, bitfield
@@ -1306,7 +1284,6 @@ CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_sto
 -- sort by deletion time
 CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp);
 -- sort by uploader
-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);
 -- find file by sha1, 10 bytes will be enough for hashes to be indexed
 CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1(10));
@@ -1378,9 +1355,7 @@ CREATE TABLE /*_*/recentchanges (
   rc_timestamp varbinary(14) NOT NULL default '',
 
   -- As in revision
-  rc_user int unsigned NOT NULL default 0, -- Deprecated in favor of rc_actor
-  rc_user_text varchar(255) binary NOT NULL DEFAULT '', -- Deprecated in favor of rc_actor
-  rc_actor bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that rc_user/rc_user_text should be used)
+  rc_actor bigint unsigned NOT NULL,
 
   -- When pages are renamed, their RC entries do _not_ change.
   rc_namespace int NOT NULL default 0,
@@ -1461,11 +1436,9 @@ CREATE INDEX /*i*/new_name_timestamp ON /*_*/recentchanges (rc_new,rc_namespace,
 CREATE INDEX /*i*/rc_ip ON /*_*/recentchanges (rc_ip);
 
 -- Probably intended for Special:NewPages namespace filter
-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);
 
 -- SiteStats active user count, Special:ActiveUsers, Special:NewPages user filter
-CREATE INDEX /*i*/rc_user_text ON /*_*/recentchanges (rc_user_text, rc_timestamp);
 CREATE INDEX /*i*/rc_actor ON /*_*/recentchanges (rc_actor, rc_timestamp);
 
 -- ApiQueryRecentChanges (T140108)
@@ -1595,14 +1568,8 @@ CREATE TABLE /*_*/logging (
   -- Timestamp. Duh.
   log_timestamp binary(14) NOT NULL default '19700101000000',
 
-  -- The user who performed this action; key to user_id
-  log_user int unsigned NOT NULL default 0, -- Deprecated in favor of log_actor
-
-  -- Name of the user who performed this action
-  log_user_text varchar(255) binary NOT NULL default '', -- Deprecated in favor of log_actor
-
   -- The actor who performed this action
-  log_actor bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that log_user/log_user_text should be used)
+  log_actor bigint unsigned NOT NULL,
 
   -- Key to the page affected. Where a user is the target,
   -- this will point to the user page.
@@ -1625,7 +1592,6 @@ CREATE TABLE /*_*/logging (
 CREATE INDEX /*i*/type_time ON /*_*/logging (log_type, log_timestamp);
 
 -- Special:Log performer filter
-CREATE INDEX /*i*/user_time ON /*_*/logging (log_user, log_timestamp);
 CREATE INDEX /*i*/actor_time ON /*_*/logging (log_actor, log_timestamp);
 
 -- Special:Log title filter, log extract
@@ -1635,7 +1601,6 @@ CREATE INDEX /*i*/page_time ON /*_*/logging (log_namespace, log_title, log_times
 CREATE INDEX /*i*/times ON /*_*/logging (log_timestamp);
 
 -- Special:Log filter by performer and type
-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);
 
 -- Apparently just used for a few maintenance pages (findMissingFiles.php, Flow).
@@ -1645,12 +1610,6 @@ CREATE INDEX /*i*/log_page_id_time ON /*_*/logging (log_page,log_timestamp);
 -- Special:Log action filter
 CREATE INDEX /*i*/log_type_action ON /*_*/logging (log_type, log_action, log_timestamp);
 
--- Special:Log filter by type and anonymous performer
-CREATE INDEX /*i*/log_user_text_type_time ON /*_*/logging (log_user_text, log_type, log_timestamp);
-
--- Special:Log filter by anonymous performer
-CREATE INDEX /*i*/log_user_text_time ON /*_*/logging (log_user_text, log_timestamp);
-
 
 CREATE TABLE /*_*/log_search (
   -- The type of ID (rev ID, log ID, rev timestamp, username)
index b546cbf..6425238 100644 (file)
@@ -24,6 +24,8 @@
 // details of the session. Enforce this constraint with respect to session use.
 define( 'MW_NO_SESSION', 1 );
 
+define( 'MW_ENTRY_POINT', 'opensearch_desc' );
+
 require_once __DIR__ . '/includes/WebStart.php';
 
 if ( $wgRequest->getVal( 'ctype' ) == 'application/xml' ) {
index dccdd38..7b652b7 100644 (file)
@@ -40,6 +40,8 @@
 // details of the session. Enforce this constraint with respect to session use.
 define( 'MW_NO_SESSION', 1 );
 
+define( 'MW_ENTRY_POINT', 'profileinfo' );
+
 ini_set( 'zlib.output_compression', 'off' );
 
 require __DIR__ . '/includes/WebStart.php';
index b3aee84..1388128 100644 (file)
@@ -1028,7 +1028,6 @@ return [
        ],
        'mediawiki.RegExp' => [
                'deprecated' => 'Please use mw.util.escapeRegExp() instead.',
-               'scripts' => 'resources/src/mediawiki.RegExp.js',
                'targets' => [ 'desktop', 'mobile' ],
                'dependencies' => [
                        'mediawiki.util',
@@ -1702,7 +1701,6 @@ return [
                        'mediawiki.util',
                        'mediawiki.Title',
                        'mediawiki.jqueryMsg',
-                       'mediawiki.util',
                ],
                'messages' => [
                        'watch',
diff --git a/resources/src/mediawiki.RegExp.js b/resources/src/mediawiki.RegExp.js
deleted file mode 100644 (file)
index 258bc2c..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-( function () {
-       mw.RegExp = {};
-       // Backwards-compatible alias; @deprecated since 1.34
-       mw.log.deprecate( mw.RegExp, 'escape', mw.util.escapeRegExp, 'Use mw.util.escapeRegExp() instead.', 'mw.RegExp.escape' );
-}() );
index 3084e12..3f39fd1 100644 (file)
@@ -137,11 +137,11 @@ var
                '[^' + mw.config.get( 'wgLegalTitleChars' ) + ']' +
                // URL percent encoding sequences interfere with the ability
                // to round-trip titles -- you can't link to them consistently.
-               '|%[0-9A-Fa-f]{2}' +
+               '|%[\\dA-Fa-f]{2}' +
                // XML/HTML character references produce similar issues.
-               '|&[A-Za-z0-9\u0080-\uFFFF]+;' +
-               '|&#[0-9]+;' +
-               '|&#x[0-9A-Fa-f]+;'
+               '|&[\\dA-Za-z\u0080-\uFFFF]+;' +
+               '|&#\\d+;' +
+               '|&#x[\\dA-Fa-f]+;'
        ),
 
        // From MediaWikiTitleCodec::splitTitleString() in PHP
@@ -149,7 +149,7 @@ var
        rWhitespace = /[ _\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+/g,
 
        // From MediaWikiTitleCodec::splitTitleString() in PHP
-       rUnicodeBidi = /[\u200E\u200F\u202A-\u202E]/g,
+       rUnicodeBidi = /[\u200E\u200F\u202A-\u202E]+/g,
 
        /**
         * Slightly modified from Flinfo. Credit goes to Lupo and Flominator.
@@ -173,13 +173,13 @@ var
                },
                // URL encoding (possibly)
                {
-                       pattern: /%([0-9A-Fa-f]{2})/g,
+                       pattern: /%([\dA-Fa-f]{2})/g,
                        replace: '% $1',
                        generalRule: true
                },
                // HTML-character-entities
                {
-                       pattern: /&(([A-Za-z0-9\x80-\xff]+|#[0-9]+|#x[0-9A-Fa-f]+);)/g,
+                       pattern: /&(([\dA-Za-z\x80-\xff]+|#\d+|#x[\dA-Fa-f]+);)/g,
                        replace: '& $1',
                        generalRule: true
                },
@@ -228,7 +228,7 @@ var
         * @return {Object|boolean}
         */
        parse = function ( title, defaultNamespace ) {
-               var namespace, m, id, i, fragment, ext;
+               var namespace, m, id, i, fragment;
 
                namespace = defaultNamespace === undefined ? NS_MAIN : defaultNamespace;
 
@@ -294,7 +294,7 @@ var
                }
 
                // Reject illegal characters
-               if ( title.match( rInvalid ) ) {
+               if ( rInvalid.test( title ) ) {
                        return false;
                }
 
@@ -336,21 +336,9 @@ var
                        return false;
                }
 
-               // For backwards-compatibility with old mw.Title, we separate the extension from the
-               // rest of the title.
-               i = title.lastIndexOf( '.' );
-               if ( i === -1 || title.length <= i + 1 ) {
-                       // Extensions are the non-empty segment after the last dot
-                       ext = null;
-               } else {
-                       ext = title.slice( i + 1 );
-                       title = title.slice( 0, i );
-               }
-
                return {
                        namespace: namespace,
                        title: title,
-                       ext: ext,
                        fragment: fragment
                };
        },
@@ -438,7 +426,6 @@ function Title( title, namespace ) {
 
        this.namespace = parsed.namespace;
        this.title = parsed.title;
-       this.ext = parsed.ext;
        this.fragment = parsed.fragment;
 }
 
@@ -465,7 +452,6 @@ Title.newFromText = function ( title, namespace ) {
        t = Object.create( Title.prototype );
        t.namespace = parsed.namespace;
        t.title = parsed.title;
-       t.ext = parsed.ext;
        t.fragment = parsed.fragment;
 
        return t;
@@ -600,7 +586,6 @@ Title.newFromUserInput = function ( title, defaultNamespaceOrOptions, options )
  * @return {mw.Title|null} A valid Title object or null if the title is invalid
  */
 Title.newFromFileName = function ( uncleanName ) {
-
        return Title.newFromUserInput( 'File:' + uncleanName, {
                forUploading: true
        } );
@@ -622,10 +607,10 @@ Title.newFromImg = function ( img ) {
                thumbPhpRegex = /thumb\.php/,
                regexes = [
                        // Thumbnails
-                       /\/[a-f0-9]\/[a-f0-9]{2}\/([^\s/]+)\/[^\s/]+-[^\s/]*$/,
+                       /\/[\da-f]\/[\da-f]{2}\/([^\s/]+)\/[^\s/]+-[^\s/]*$/,
 
                        // Full size images
-                       /\/[a-f0-9]\/[a-f0-9]{2}\/([^\s/]+)$/,
+                       /\/[\da-f]\/[\da-f]{2}\/([^\s/]+)$/,
 
                        // Thumbnails in non-hashed upload directories
                        /\/([^\s/]+)\/[^\s/]+-(?:\1|thumbnail)[^\s/]*$/,
@@ -638,9 +623,7 @@ Title.newFromImg = function ( img ) {
 
        src = img.jquery ? img[ 0 ].src : img.src;
 
-       matches = src.match( thumbPhpRegex );
-
-       if ( matches ) {
+       if ( thumbPhpRegex.test( src ) ) {
                return mw.Title.newFromText( 'File:' + mw.util.getParamValue( 'f', src ) );
        }
 
@@ -759,16 +742,16 @@ Title.exist = {
 Title.normalizeExtension = function ( extension ) {
        var
                lower = extension.toLowerCase(),
-               squish = {
+               normalizations = {
                        htm: 'html',
                        jpeg: 'jpg',
                        mpeg: 'mpg',
                        tiff: 'tif',
                        ogv: 'ogg'
                };
-       if ( Object.prototype.hasOwnProperty.call( squish, lower ) ) {
-               return squish[ lower ];
-       } else if ( /^[0-9a-z]+$/.test( lower ) ) {
+       if ( Object.hasOwnProperty.call( normalizations, lower ) ) {
+               return normalizations[ lower ];
+       } else if ( /^[\da-z]+$/.test( lower ) ) {
                return lower;
        } else {
                return '';
@@ -824,13 +807,11 @@ Title.prototype = {
         * @return {string}
         */
        getName: function () {
-               if (
-                       mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( this.namespace ) !== -1 ||
-                       !this.title.length
-               ) {
-                       return this.title;
+               var ext = this.getExtension();
+               if ( ext === null ) {
+                       return this.getMain();
                }
-               return mw.Title.phpCharToUpper( this.title[ 0 ] ) + this.title.slice( 1 );
+               return this.getMain().slice( 0, -ext.length - 1 );
        },
 
        /**
@@ -852,7 +833,11 @@ Title.prototype = {
         * @return {string|null} Name extension or null if there is none
         */
        getExtension: function () {
-               return this.ext;
+               var lastDot = this.title.lastIndexOf( '.' );
+               if ( lastDot === -1 ) {
+                       return null;
+               }
+               return this.title.slice( lastDot + 1 ) || null;
        },
 
        /**
@@ -863,7 +848,8 @@ Title.prototype = {
         * @return {string}
         */
        getDotExtension: function () {
-               return this.ext === null ? '' : '.' + this.ext;
+               var ext = this.getExtension();
+               return ext === null ? '' : '.' + ext;
        },
 
        /**
@@ -874,7 +860,13 @@ Title.prototype = {
         * @return {string}
         */
        getMain: function () {
-               return this.getName() + this.getDotExtension();
+               if (
+                       mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( this.namespace ) !== -1 ||
+                       !this.title.length
+               ) {
+                       return this.title;
+               }
+               return mw.Title.phpCharToUpper( this.title[ 0 ] ) + this.title.slice( 1 );
        },
 
        /**
index 6342011..e8823e1 100644 (file)
@@ -533,6 +533,11 @@ util = {
        }
 };
 
+// Backwards-compatible alias for mediawiki.RegExp module.
+// @deprecated since 1.34
+mw.RegExp = {};
+mw.log.deprecate( mw.RegExp, 'escape', util.escapeRegExp, 'Use mw.util.escapeRegExp() instead.', 'mw.RegExp.escape' );
+
 // Not allowed outside unit tests
 if ( window.QUnit ) {
        util.setOptionsForTest = function ( opts ) {
index 3ac532e..f647f91 100644 (file)
--- a/rest.php
+++ b/rest.php
@@ -23,6 +23,9 @@
 
 use MediaWiki\Rest\EntryPoint;
 
+define( 'MW_REST_API', true );
+define( 'MW_ENTRY_POINT', 'rest' );
+
 require __DIR__ . '/includes/WebStart.php';
 
 EntryPoint::main();
index c8b8ef9..91c3d40 100644 (file)
@@ -1246,8 +1246,6 @@ class ParserTestRunner {
         * @return array
         */
        private function listTables() {
-               global $wgActorTableSchemaMigrationStage;
-
                $tables = [ 'user', 'user_properties', 'user_former_groups', 'page', 'page_restrictions',
                        'protected_titles', 'revision', 'ip_changes', 'text', 'pagelinks', 'imagelinks',
                        'categorylinks', 'templatelinks', 'externallinks', 'langlinks', 'iwlinks',
@@ -1256,15 +1254,9 @@ class ParserTestRunner {
                        'querycache', 'objectcache', 'job', 'l10n_cache', 'redirect', 'querycachetwo',
                        'archive', 'user_groups', 'page_props', 'category',
                        'slots', 'content', 'slot_roles', 'content_models',
-                       'comment', 'revision_comment_temp',
+                       'comment', 'revision_comment_temp', 'actor', 'revision_actor_temp',
                ];
 
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                       // The new tables for actors are in use
-                       $tables[] = 'actor';
-                       $tables[] = 'revision_actor_temp';
-               }
-
                if ( in_array( $this->db->getType(), [ 'mysql', 'sqlite' ] ) ) {
                        array_push( $tables, 'searchindex' );
                }
index 46c0c42..a82b697 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 use MediaWiki\User\UserIdentity;
-use MediaWiki\MediaWikiServices;
+use Wikimedia\ScopedCallback;
 use Wikimedia\TestingAccessWrapper;
 
 /**
@@ -10,14 +10,60 @@ use Wikimedia\TestingAccessWrapper;
  */
 class ActorMigrationTest extends MediaWikiLangTestCase {
 
+       protected $resetActorMigration = null;
+       protected static $amId = 0;
+
        protected $tablesUsed = [
-               'revision',
-               'revision_actor_temp',
-               'ipblocks',
-               'recentchanges',
                'actor',
        ];
 
+       protected function setUp() {
+               parent::setUp();
+
+               $w = TestingAccessWrapper::newFromClass( ActorMigration::class );
+               $data = [
+                       'tempTables' => $w->tempTables,
+                       'formerTempTables' => $w->formerTempTables,
+                       'deprecated' => $w->deprecated,
+                       'removed' => $w->removed,
+                       'specialFields' => $w->specialFields,
+               ];
+               $this->resetActorMigration = new ScopedCallback( function ( $w, $data ) {
+                       foreach ( $data as $k => $v ) {
+                               $w->$k = $v;
+                       }
+               }, [ $w, $data ] );
+
+               $w->tempTables = [
+                       'am2_user' => [
+                               'table' => 'actormigration2_temp',
+                               'pk' => 'am2t_id',
+                               'field' => 'am2t_actor',
+                               'joinPK' => 'am2_id',
+                               'extra' => [],
+                       ]
+               ];
+               $w->specialFields = [
+                       'am3_xxx' => [ 'am3_xxx_text', 'am3_xxx_actor' ],
+               ];
+       }
+
+       protected function tearDown() {
+               parent::tearDown();
+               ScopedCallback::consume( $this->resetActorMigration );
+       }
+
+       protected function getSchemaOverrides( IMaintainableDatabase $db ) {
+               return [
+                       'scripts' => [
+                               __DIR__ . '/ActorMigrationTest.sql',
+                       ],
+                       'drop' => [],
+                       'create' => [ 'actormigration1', 'actormigration2', 'actormigration2_temp', 'actormigration3' ],
+                       'alter' => [],
+               ];
+       }
+
        /**
         * @dataProvider provideConstructor
         * @param int $stage
@@ -80,156 +126,156 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
        public static function provideGetJoin() {
                return [
                        'Simple table, old' => [
-                               SCHEMA_COMPAT_OLD, 'rc_user', [
+                               SCHEMA_COMPAT_OLD, 'am1_user', [
                                        'tables' => [],
                                        'fields' => [
-                                               'rc_user' => 'rc_user',
-                                               'rc_user_text' => 'rc_user_text',
-                                               'rc_actor' => 'NULL',
+                                               'am1_user' => 'am1_user',
+                                               'am1_user_text' => 'am1_user_text',
+                                               'am1_actor' => 'NULL',
                                        ],
                                        'joins' => [],
                                ],
                        ],
                        'Simple table, read-old' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'rc_user', [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am1_user', [
                                        'tables' => [],
                                        'fields' => [
-                                               'rc_user' => 'rc_user',
-                                               'rc_user_text' => 'rc_user_text',
-                                               'rc_actor' => 'NULL',
+                                               'am1_user' => 'am1_user',
+                                               'am1_user_text' => 'am1_user_text',
+                                               'am1_actor' => 'NULL',
                                        ],
                                        'joins' => [],
                                ],
                        ],
                        'Simple table, read-new' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'rc_user', [
-                                       'tables' => [ 'actor_rc_user' => 'actor' ],
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am1_user', [
+                                       'tables' => [ 'actor_am1_user' => 'actor' ],
                                        'fields' => [
-                                               'rc_user' => 'actor_rc_user.actor_user',
-                                               'rc_user_text' => 'actor_rc_user.actor_name',
-                                               'rc_actor' => 'rc_actor',
+                                               'am1_user' => 'actor_am1_user.actor_user',
+                                               'am1_user_text' => 'actor_am1_user.actor_name',
+                                               'am1_actor' => 'am1_actor',
                                        ],
                                        'joins' => [
-                                               'actor_rc_user' => [ 'JOIN', 'actor_rc_user.actor_id = rc_actor' ],
+                                               'actor_am1_user' => [ 'JOIN', 'actor_am1_user.actor_id = am1_actor' ],
                                        ],
                                ],
                        ],
                        'Simple table, new' => [
-                               SCHEMA_COMPAT_NEW, 'rc_user', [
-                                       'tables' => [ 'actor_rc_user' => 'actor' ],
+                               SCHEMA_COMPAT_NEW, 'am1_user', [
+                                       'tables' => [ 'actor_am1_user' => 'actor' ],
                                        'fields' => [
-                                               'rc_user' => 'actor_rc_user.actor_user',
-                                               'rc_user_text' => 'actor_rc_user.actor_name',
-                                               'rc_actor' => 'rc_actor',
+                                               'am1_user' => 'actor_am1_user.actor_user',
+                                               'am1_user_text' => 'actor_am1_user.actor_name',
+                                               'am1_actor' => 'am1_actor',
                                        ],
                                        'joins' => [
-                                               'actor_rc_user' => [ 'JOIN', 'actor_rc_user.actor_id = rc_actor' ],
+                                               'actor_am1_user' => [ 'JOIN', 'actor_am1_user.actor_id = am1_actor' ],
                                        ],
                                ],
                        ],
 
-                       'ipblocks, old' => [
-                               SCHEMA_COMPAT_OLD, 'ipb_by', [
+                       'Special name, old' => [
+                               SCHEMA_COMPAT_OLD, 'am3_xxx', [
                                        'tables' => [],
                                        'fields' => [
-                                               'ipb_by' => 'ipb_by',
-                                               'ipb_by_text' => 'ipb_by_text',
-                                               'ipb_by_actor' => 'NULL',
+                                               'am3_xxx' => 'am3_xxx',
+                                               'am3_xxx_text' => 'am3_xxx_text',
+                                               'am3_xxx_actor' => 'NULL',
                                        ],
                                        'joins' => [],
                                ],
                        ],
-                       'ipblocks, read-old' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'ipb_by', [
+                       'Special name, read-old' => [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am3_xxx', [
                                        'tables' => [],
                                        'fields' => [
-                                               'ipb_by' => 'ipb_by',
-                                               'ipb_by_text' => 'ipb_by_text',
-                                               'ipb_by_actor' => 'NULL',
+                                               'am3_xxx' => 'am3_xxx',
+                                               'am3_xxx_text' => 'am3_xxx_text',
+                                               'am3_xxx_actor' => 'NULL',
                                        ],
                                        'joins' => [],
                                ],
                        ],
-                       'ipblocks, read-new' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'ipb_by', [
-                                       'tables' => [ 'actor_ipb_by' => 'actor' ],
+                       'Special name, read-new' => [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am3_xxx', [
+                                       'tables' => [ 'actor_am3_xxx' => 'actor' ],
                                        'fields' => [
-                                               'ipb_by' => 'actor_ipb_by.actor_user',
-                                               'ipb_by_text' => 'actor_ipb_by.actor_name',
-                                               'ipb_by_actor' => 'ipb_by_actor',
+                                               'am3_xxx' => 'actor_am3_xxx.actor_user',
+                                               'am3_xxx_text' => 'actor_am3_xxx.actor_name',
+                                               'am3_xxx_actor' => 'am3_xxx_actor',
                                        ],
                                        'joins' => [
-                                               'actor_ipb_by' => [ 'JOIN', 'actor_ipb_by.actor_id = ipb_by_actor' ],
+                                               'actor_am3_xxx' => [ 'JOIN', 'actor_am3_xxx.actor_id = am3_xxx_actor' ],
                                        ],
                                ],
                        ],
-                       'ipblocks, new' => [
-                               SCHEMA_COMPAT_NEW, 'ipb_by', [
-                                       'tables' => [ 'actor_ipb_by' => 'actor' ],
+                       'Special name, new' => [
+                               SCHEMA_COMPAT_NEW, 'am3_xxx', [
+                                       'tables' => [ 'actor_am3_xxx' => 'actor' ],
                                        'fields' => [
-                                               'ipb_by' => 'actor_ipb_by.actor_user',
-                                               'ipb_by_text' => 'actor_ipb_by.actor_name',
-                                               'ipb_by_actor' => 'ipb_by_actor',
+                                               'am3_xxx' => 'actor_am3_xxx.actor_user',
+                                               'am3_xxx_text' => 'actor_am3_xxx.actor_name',
+                                               'am3_xxx_actor' => 'am3_xxx_actor',
                                        ],
                                        'joins' => [
-                                               'actor_ipb_by' => [ 'JOIN', 'actor_ipb_by.actor_id = ipb_by_actor' ],
+                                               'actor_am3_xxx' => [ 'JOIN', 'actor_am3_xxx.actor_id = am3_xxx_actor' ],
                                        ],
                                ],
                        ],
 
-                       'Revision, old' => [
-                               SCHEMA_COMPAT_OLD, 'rev_user', [
+                       'Temp table, old' => [
+                               SCHEMA_COMPAT_OLD, 'am2_user', [
                                        'tables' => [],
                                        'fields' => [
-                                               'rev_user' => 'rev_user',
-                                               'rev_user_text' => 'rev_user_text',
-                                               'rev_actor' => 'NULL',
+                                               'am2_user' => 'am2_user',
+                                               'am2_user_text' => 'am2_user_text',
+                                               'am2_actor' => 'NULL',
                                        ],
                                        'joins' => [],
                                ],
                        ],
-                       'Revision, read-old' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'rev_user', [
+                       'Temp table, read-old' => [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am2_user', [
                                        'tables' => [],
                                        'fields' => [
-                                               'rev_user' => 'rev_user',
-                                               'rev_user_text' => 'rev_user_text',
-                                               'rev_actor' => 'NULL',
+                                               'am2_user' => 'am2_user',
+                                               'am2_user_text' => 'am2_user_text',
+                                               'am2_actor' => 'NULL',
                                        ],
                                        'joins' => [],
                                ],
                        ],
-                       'Revision, read-new' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'rev_user', [
+                       'Temp table, read-new' => [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am2_user', [
                                        'tables' => [
-                                               'temp_rev_user' => 'revision_actor_temp',
-                                               'actor_rev_user' => 'actor',
+                                               'temp_am2_user' => 'actormigration2_temp',
+                                               'actor_am2_user' => 'actor',
                                        ],
                                        'fields' => [
-                                               'rev_user' => 'actor_rev_user.actor_user',
-                                               'rev_user_text' => 'actor_rev_user.actor_name',
-                                               'rev_actor' => 'temp_rev_user.revactor_actor',
+                                               'am2_user' => 'actor_am2_user.actor_user',
+                                               'am2_user_text' => 'actor_am2_user.actor_name',
+                                               'am2_actor' => 'temp_am2_user.am2t_actor',
                                        ],
                                        'joins' => [
-                                               'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
-                                               'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
+                                               'temp_am2_user' => [ 'JOIN', 'temp_am2_user.am2t_id = am2_id' ],
+                                               'actor_am2_user' => [ 'JOIN', 'actor_am2_user.actor_id = temp_am2_user.am2t_actor' ],
                                        ],
                                ],
                        ],
-                       'Revision, new' => [
-                               SCHEMA_COMPAT_NEW, 'rev_user', [
+                       'Temp table, new' => [
+                               SCHEMA_COMPAT_NEW, 'am2_user', [
                                        'tables' => [
-                                               'temp_rev_user' => 'revision_actor_temp',
-                                               'actor_rev_user' => 'actor',
+                                               'temp_am2_user' => 'actormigration2_temp',
+                                               'actor_am2_user' => 'actor',
                                        ],
                                        'fields' => [
-                                               'rev_user' => 'actor_rev_user.actor_user',
-                                               'rev_user_text' => 'actor_rev_user.actor_name',
-                                               'rev_actor' => 'temp_rev_user.revactor_actor',
+                                               'am2_user' => 'actor_am2_user.actor_user',
+                                               'am2_user_text' => 'actor_am2_user.actor_name',
+                                               'am2_actor' => 'temp_am2_user.am2t_actor',
                                        ],
                                        'joins' => [
-                                               'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
-                                               'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
+                                               'temp_am2_user' => [ 'JOIN', 'temp_am2_user.am2t_id = am2_id' ],
+                                               'actor_am2_user' => [ 'JOIN', 'actor_am2_user.actor_id = temp_am2_user.am2t_actor' ],
                                        ],
                                ],
                        ],
@@ -276,164 +322,164 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
 
                return [
                        'Simple table, old' => [
-                               SCHEMA_COMPAT_OLD, 'rc_user', $genericUser, true, [
+                               SCHEMA_COMPAT_OLD, 'am1_user', $genericUser, true, [
                                        'tables' => [],
-                                       'orconds' => [ 'userid' => "rc_user = '1'" ],
+                                       'orconds' => [ 'userid' => "am1_user = '1'" ],
                                        'joins' => [],
                                ],
                        ],
                        'Simple table, read-old' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'rc_user', $genericUser, true, [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am1_user', $genericUser, true, [
                                        'tables' => [],
-                                       'orconds' => [ 'userid' => "rc_user = '1'" ],
+                                       'orconds' => [ 'userid' => "am1_user = '1'" ],
                                        'joins' => [],
                                ],
                        ],
                        'Simple table, read-new' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'rc_user', $genericUser, true, [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am1_user', $genericUser, true, [
                                        'tables' => [],
-                                       'orconds' => [ 'actor' => "rc_actor = '11'" ],
+                                       'orconds' => [ 'actor' => "am1_actor = '11'" ],
                                        'joins' => [],
                                ],
                        ],
                        'Simple table, new' => [
-                               SCHEMA_COMPAT_NEW, 'rc_user', $genericUser, true, [
+                               SCHEMA_COMPAT_NEW, 'am1_user', $genericUser, true, [
                                        'tables' => [],
-                                       'orconds' => [ 'actor' => "rc_actor = '11'" ],
+                                       'orconds' => [ 'actor' => "am1_actor = '11'" ],
                                        'joins' => [],
                                ],
                        ],
 
-                       'ipblocks, old' => [
-                               SCHEMA_COMPAT_OLD, 'ipb_by', $genericUser, true, [
+                       'Special name, old' => [
+                               SCHEMA_COMPAT_OLD, 'am3_xxx', $genericUser, true, [
                                        'tables' => [],
-                                       'orconds' => [ 'userid' => "ipb_by = '1'" ],
+                                       'orconds' => [ 'userid' => "am3_xxx = '1'" ],
                                        'joins' => [],
                                ],
                        ],
-                       'ipblocks, read-old' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'ipb_by', $genericUser, true, [
+                       'Special name, read-old' => [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am3_xxx', $genericUser, true, [
                                        'tables' => [],
-                                       'orconds' => [ 'userid' => "ipb_by = '1'" ],
+                                       'orconds' => [ 'userid' => "am3_xxx = '1'" ],
                                        'joins' => [],
                                ],
                        ],
-                       'ipblocks, read-new' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'ipb_by', $genericUser, true, [
+                       'Special name, read-new' => [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am3_xxx', $genericUser, true, [
                                        'tables' => [],
-                                       'orconds' => [ 'actor' => "ipb_by_actor = '11'" ],
+                                       'orconds' => [ 'actor' => "am3_xxx_actor = '11'" ],
                                        'joins' => [],
                                ],
                        ],
-                       'ipblocks, new' => [
-                               SCHEMA_COMPAT_NEW, 'ipb_by', $genericUser, true, [
+                       'Special name, new' => [
+                               SCHEMA_COMPAT_NEW, 'am3_xxx', $genericUser, true, [
                                        'tables' => [],
-                                       'orconds' => [ 'actor' => "ipb_by_actor = '11'" ],
+                                       'orconds' => [ 'actor' => "am3_xxx_actor = '11'" ],
                                        'joins' => [],
                                ],
                        ],
 
-                       'Revision, old' => [
-                               SCHEMA_COMPAT_OLD, 'rev_user', $genericUser, true, [
+                       'Temp table, old' => [
+                               SCHEMA_COMPAT_OLD, 'am2_user', $genericUser, true, [
                                        'tables' => [],
-                                       'orconds' => [ 'userid' => "rev_user = '1'" ],
+                                       'orconds' => [ 'userid' => "am2_user = '1'" ],
                                        'joins' => [],
                                ],
                        ],
-                       'Revision, read-old' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'rev_user', $genericUser, true, [
+                       'Temp table, read-old' => [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am2_user', $genericUser, true, [
                                        'tables' => [],
-                                       'orconds' => [ 'userid' => "rev_user = '1'" ],
+                                       'orconds' => [ 'userid' => "am2_user = '1'" ],
                                        'joins' => [],
                                ],
                        ],
-                       'Revision, read-new' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'rev_user', $genericUser, true, [
+                       'Temp table, read-new' => [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am2_user', $genericUser, true, [
                                        'tables' => [
-                                               'temp_rev_user' => 'revision_actor_temp',
+                                               'temp_am2_user' => 'actormigration2_temp',
                                        ],
-                                       'orconds' => [ 'actor' => "temp_rev_user.revactor_actor = '11'" ],
+                                       'orconds' => [ 'actor' => "temp_am2_user.am2t_actor = '11'" ],
                                        'joins' => [
-                                               'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                               'temp_am2_user' => [ 'JOIN', 'temp_am2_user.am2t_id = am2_id' ],
                                        ],
                                ],
                        ],
-                       'Revision, new' => [
-                               SCHEMA_COMPAT_NEW, 'rev_user', $genericUser, true, [
+                       'Temp table, new' => [
+                               SCHEMA_COMPAT_NEW, 'am2_user', $genericUser, true, [
                                        'tables' => [
-                                               'temp_rev_user' => 'revision_actor_temp',
+                                               'temp_am2_user' => 'actormigration2_temp',
                                        ],
-                                       'orconds' => [ 'actor' => "temp_rev_user.revactor_actor = '11'" ],
+                                       'orconds' => [ 'actor' => "temp_am2_user.am2t_actor = '11'" ],
                                        'joins' => [
-                                               'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                               'temp_am2_user' => [ 'JOIN', 'temp_am2_user.am2t_id = am2_id' ],
                                        ],
                                ],
                        ],
 
                        'Multiple users, old' => [
-                               SCHEMA_COMPAT_OLD, 'rc_user', $complicatedUsers, true, [
+                               SCHEMA_COMPAT_OLD, 'am1_user', $complicatedUsers, true, [
                                        'tables' => [],
                                        'orconds' => [
-                                               'userid' => "rc_user IN ('1','2','3') ",
-                                               'username' => "rc_user_text IN ('192.168.12.34','192.168.12.35') "
+                                               'userid' => "am1_user IN ('1','2','3') ",
+                                               'username' => "am1_user_text IN ('192.168.12.34','192.168.12.35') "
                                        ],
                                        'joins' => [],
                                ],
                        ],
                        'Multiple users, read-old' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'rc_user', $complicatedUsers, true, [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am1_user', $complicatedUsers, true, [
                                        'tables' => [],
                                        'orconds' => [
-                                               'userid' => "rc_user IN ('1','2','3') ",
-                                               'username' => "rc_user_text IN ('192.168.12.34','192.168.12.35') "
+                                               'userid' => "am1_user IN ('1','2','3') ",
+                                               'username' => "am1_user_text IN ('192.168.12.34','192.168.12.35') "
                                        ],
                                        'joins' => [],
                                ],
                        ],
                        'Multiple users, read-new' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'rc_user', $complicatedUsers, true, [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am1_user', $complicatedUsers, true, [
                                        'tables' => [],
-                                       'orconds' => [ 'actor' => "rc_actor IN ('11','12','34') " ],
+                                       'orconds' => [ 'actor' => "am1_actor IN ('11','12','34') " ],
                                        'joins' => [],
                                ],
                        ],
                        'Multiple users, new' => [
-                               SCHEMA_COMPAT_NEW, 'rc_user', $complicatedUsers, true, [
+                               SCHEMA_COMPAT_NEW, 'am1_user', $complicatedUsers, true, [
                                        'tables' => [],
-                                       'orconds' => [ 'actor' => "rc_actor IN ('11','12','34') " ],
+                                       'orconds' => [ 'actor' => "am1_actor IN ('11','12','34') " ],
                                        'joins' => [],
                                ],
                        ],
 
                        'Multiple users, no use ID, old' => [
-                               SCHEMA_COMPAT_OLD, 'rc_user', $complicatedUsers, false, [
+                               SCHEMA_COMPAT_OLD, 'am1_user', $complicatedUsers, false, [
                                        'tables' => [],
                                        'orconds' => [
-                                               'username' => "rc_user_text IN ('User1','User2','User3','192.168.12.34','192.168.12.35') "
+                                               'username' => "am1_user_text IN ('User1','User2','User3','192.168.12.34','192.168.12.35') "
                                        ],
                                        'joins' => [],
                                ],
                        ],
                        'Multiple users, read-old' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'rc_user', $complicatedUsers, false, [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am1_user', $complicatedUsers, false, [
                                        'tables' => [],
                                        'orconds' => [
-                                               'username' => "rc_user_text IN ('User1','User2','User3','192.168.12.34','192.168.12.35') "
+                                               'username' => "am1_user_text IN ('User1','User2','User3','192.168.12.34','192.168.12.35') "
                                        ],
                                        'joins' => [],
                                ],
                        ],
                        'Multiple users, read-new' => [
-                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'rc_user', $complicatedUsers, false, [
+                               SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am1_user', $complicatedUsers, false, [
                                        'tables' => [],
-                                       'orconds' => [ 'actor' => "rc_actor IN ('11','12','34') " ],
+                                       'orconds' => [ 'actor' => "am1_actor IN ('11','12','34') " ],
                                        'joins' => [],
                                ],
                        ],
                        'Multiple users, new' => [
-                               SCHEMA_COMPAT_NEW, 'rc_user', $complicatedUsers, false, [
+                               SCHEMA_COMPAT_NEW, 'am1_user', $complicatedUsers, false, [
                                        'tables' => [],
-                                       'orconds' => [ 'actor' => "rc_actor IN ('11','12','34') " ],
+                                       'orconds' => [ 'actor' => "am1_actor IN ('11','12','34') " ],
                                        'joins' => [],
                                ],
                        ],
@@ -445,23 +491,14 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
         * @param string $table
         * @param string $key
         * @param string $pk
-        * @param array $extraFields
+        * @param bool $usesTemp
         */
-       public function testInsertRoundTrip( $table, $key, $pk, $extraFields ) {
+       public function testInsertRoundTrip( $table, $key, $pk, $usesTemp ) {
                $u = $this->getTestUser()->getUser();
                $user = $this->getMock( UserIdentity::class );
                $user->method( 'getId' )->willReturn( $u->getId() );
                $user->method( 'getName' )->willReturn( $u->getName() );
-               if ( $u->getActorId( $this->db ) ) {
-                       $user->method( 'getActorId' )->willReturn( $u->getActorId() );
-               } else {
-                       $this->db->insert(
-                               'actor',
-                               [ 'actor_user' => $u->getId(), 'actor_name' => $u->getName() ],
-                               __METHOD__
-                       );
-                       $user->method( 'getActorId' )->willReturn( $this->db->insertId() );
-               }
+               $user->method( 'getActorId' )->willReturn( $u->getActorId( $this->db ) );
 
                $stageNames = [
                        SCHEMA_COMPAT_OLD => 'old',
@@ -494,15 +531,10 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
                ];
 
                $nameKey = $key . '_text';
-               $actorKey = $key === 'ipb_by' ? 'ipb_by_actor' : substr( $key, 0, -5 ) . '_actor';
+               $actorKey = ( $key === 'am3_xxx' ? $key : substr( $key, 0, -5 ) ) . '_actor';
 
                foreach ( $stages as $writeStage => $possibleReadStages ) {
-                       if ( $key === 'ipb_by' ) {
-                               $extraFields['ipb_address'] = __CLASS__ . "#{$stageNames[$writeStage]}";
-                       }
-
                        $w = new ActorMigration( $writeStage );
-                       $usesTemp = $key === 'rev_user';
 
                        if ( $usesTemp ) {
                                list( $fields, $callback ) = $w->getInsertValuesWithTempTable( $this->db, $key, $user );
@@ -527,10 +559,10 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
                                        "new field, stage={$stageNames[$writeStage]}" );
                        }
 
-                       $this->db->insert( $table, $extraFields + $fields, __METHOD__ );
-                       $id = $this->db->insertId();
+                       $id = ++self::$amId;
+                       $this->db->insert( $table, [ $pk => $id ] + $fields, __METHOD__ );
                        if ( $usesTemp ) {
-                               $callback( $id, $extraFields );
+                               $callback( $id, [] );
                        }
 
                        foreach ( $possibleReadStages as $readStage ) {
@@ -560,33 +592,10 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
        }
 
        public static function provideInsertRoundTrip() {
-               $db = wfGetDB( DB_REPLICA ); // for timestamps
-
-               $comment = MediaWikiServices::getInstance()->getCommentStore()
-                       ->createComment( wfGetDB( DB_MASTER ), '' );
-
                return [
-                       'recentchanges' => [ 'recentchanges', 'rc_user', 'rc_id', [
-                               'rc_timestamp' => $db->timestamp(),
-                               'rc_namespace' => 0,
-                               'rc_title' => 'Test',
-                               '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,
-                               'rev_len' => 0,
-                               'rev_timestamp' => $db->timestamp(),
-                       ] ],
+                       'normal' => [ 'actormigration1', 'am1_user', 'am1_id', false ],
+                       'temp table' => [ 'actormigration2', 'am2_user', 'am2_id', true ],
+                       'special name' => [ 'actormigration3', 'am3_xxx', 'am3_id', false ],
                ];
        }
 
@@ -603,22 +612,22 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
         * @dataProvider provideStages
         * @param int $stage
         * @expectedException InvalidArgumentException
-        * @expectedExceptionMessage Must use getInsertValuesWithTempTable() for rev_user
+        * @expectedExceptionMessage Must use getInsertValuesWithTempTable() for am2_user
         */
        public function testInsertWrong( $stage ) {
                $m = new ActorMigration( $stage );
-               $m->getInsertValues( $this->db, 'rev_user', $this->getTestUser()->getUser() );
+               $m->getInsertValues( $this->db, 'am2_user', $this->getTestUser()->getUser() );
        }
 
        /**
         * @dataProvider provideStages
         * @param int $stage
         * @expectedException InvalidArgumentException
-        * @expectedExceptionMessage Must use getInsertValues() for rc_user
+        * @expectedExceptionMessage Must use getInsertValues() for am1_user
         */
        public function testInsertWithTempTableWrong( $stage ) {
                $m = new ActorMigration( $stage );
-               $m->getInsertValuesWithTempTable( $this->db, 'rc_user', $this->getTestUser()->getUser() );
+               $m->getInsertValuesWithTempTable( $this->db, 'am1_user', $this->getTestUser()->getUser() );
        }
 
        /**
@@ -627,12 +636,12 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
         */
        public function testInsertWithTempTableDeprecated( $stage ) {
                $wrap = TestingAccessWrapper::newFromClass( ActorMigration::class );
-               $wrap->formerTempTables += [ 'rc_user' => '1.30' ];
+               $wrap->formerTempTables += [ 'am1_user' => '1.30' ];
 
-               $this->hideDeprecated( 'ActorMigration::getInsertValuesWithTempTable for rc_user' );
+               $this->hideDeprecated( 'ActorMigration::getInsertValuesWithTempTable for am1_user' );
                $m = new ActorMigration( $stage );
                list( $fields, $callback )
-                       = $m->getInsertValuesWithTempTable( $this->db, 'rc_user', $this->getTestUser()->getUser() );
+                       = $m->getInsertValuesWithTempTable( $this->db, 'am1_user', $this->getTestUser()->getUser() );
                $this->assertTrue( is_callable( $callback ) );
        }
 
@@ -640,12 +649,23 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
         * @dataProvider provideStages
         * @param int $stage
         * @expectedException InvalidArgumentException
-        * @expectedExceptionMessage $extra[rev_timestamp] is not provided
+        * @expectedExceptionMessage $extra[foo_timestamp] is not provided
         */
        public function testInsertWithTempTableCallbackMissingFields( $stage ) {
+               $w = TestingAccessWrapper::newFromClass( ActorMigration::class );
+               $w->tempTables = [
+                       'foo_user' => [
+                               'table' => 'foo_temp',
+                               'pk' => 'footmp_id',
+                               'field' => 'footmp_actor',
+                               'joinPK' => 'foo_id',
+                               'extra' => [ 'footmp_timestamp' => 'foo_timestamp' ],
+                       ],
+               ];
+
                $m = new ActorMigration( $stage );
                list( $fields, $callback )
-                       = $m->getInsertValuesWithTempTable( $this->db, 'rev_user', $this->getTestUser()->getUser() );
+                       = $m->getInsertValuesWithTempTable( $this->db, 'foo_user', $this->getTestUser()->getUser() );
                $callback( 1, [] );
        }
 
@@ -654,41 +674,33 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
         * @param int $stage
         */
        public function testInsertUserIdentity( $stage ) {
-               $this->setMwGlobals( [
-                       // for User::getActorId()
-                       'wgActorTableSchemaMigrationStage' => $stage
-               ] );
-
                $user = $this->getMutableTestUser()->getUser();
                $userIdentity = $this->getMock( UserIdentity::class );
                $userIdentity->method( 'getId' )->willReturn( $user->getId() );
                $userIdentity->method( 'getName' )->willReturn( $user->getName() );
                $userIdentity->method( 'getActorId' )->willReturn( 0 );
 
-               list( $cFields, $cCallback ) = MediaWikiServices::getInstance()->getCommentStore()
-                       ->insertWithTempTable( $this->db, 'rev_comment', '' );
                $m = new ActorMigration( $stage );
                list( $fields, $callback ) =
-                       $m->getInsertValuesWithTempTable( $this->db, 'rev_user', $userIdentity );
-               $extraFields = [
-                       'rev_page' => 42,
-                       'rev_len' => 0,
-                       'rev_timestamp' => $this->db->timestamp(),
-               ] + $cFields;
-               $this->db->insert( 'revision', $extraFields + $fields, __METHOD__ );
-               $id = $this->db->insertId();
-               $callback( $id, $extraFields );
-               $cCallback( $id );
-
-               $qi = $m->getJoin( 'rev_user' );
+                       $m->getInsertValuesWithTempTable( $this->db, 'am2_user', $userIdentity );
+               $id = ++self::$amId;
+               $this->db->insert( 'actormigration2', [ 'am2_id' => $id ] + $fields, __METHOD__ );
+               $callback( $id, [] );
+
+               $qi = $m->getJoin( 'am2_user' );
                $row = $this->db->selectRow(
-                       [ 'revision' ] + $qi['tables'], $qi['fields'], [ 'rev_id' => $id ], __METHOD__, [], $qi['joins']
+                       [ 'actormigration2' ] + $qi['tables'],
+                       $qi['fields'],
+                       [ 'am2_id' => $id ],
+                       __METHOD__,
+                       [],
+                       $qi['joins']
                );
-               $this->assertSame( $user->getId(), (int)$row->rev_user );
-               $this->assertSame( $user->getName(), $row->rev_user_text );
+               $this->assertSame( $user->getId(), (int)$row->am2_user );
+               $this->assertSame( $user->getName(), $row->am2_user_text );
                $this->assertSame(
                        ( $stage & SCHEMA_COMPAT_READ_NEW ) ? $user->getActorId() : 0,
-                       (int)$row->rev_actor
+                       (int)$row->am2_actor
                );
 
                $m = new ActorMigration( $stage );
@@ -736,4 +748,24 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
                ];
        }
 
+       public function testCheckDeprecation() {
+               $wrap = TestingAccessWrapper::newFromClass( ActorMigration::class );
+               $wrap->deprecated += [ 'soft' => null, 'hard' => '1.34' ];
+               $wrap->removed += [ 'gone' => '1.34' ];
+
+               $this->hideDeprecated( 'ActorMigration for \'hard\'' );
+
+               $wrap->checkDeprecation( 'valid' );
+               $wrap->checkDeprecation( 'soft' );
+               $wrap->checkDeprecation( 'hard' );
+               try {
+                       $wrap->checkDeprecation( 'gone' );
+               } catch ( InvalidArgumentException $ex ) {
+                       $this->assertSame(
+                               'Use of ActorMigration for \'gone\' was removed in MediaWiki 1.34',
+                               $ex->getMessage()
+                       );
+               }
+       }
+
 }
diff --git a/tests/phpunit/includes/ActorMigrationTest.sql b/tests/phpunit/includes/ActorMigrationTest.sql
new file mode 100644 (file)
index 0000000..f387dac
--- /dev/null
@@ -0,0 +1,26 @@
+-- These are carefully crafted to work in all five supported databases
+
+CREATE TABLE /*_*/actormigration1 (
+  am1_id integer not null,
+  am1_user integer,
+  am1_user_text varchar(200),
+  am1_actor integer
+);
+
+CREATE TABLE /*_*/actormigration2 (
+  am2_id integer not null,
+  am2_user integer,
+  am2_user_text varchar(200)
+);
+
+CREATE TABLE /*_*/actormigration2_temp (
+  am2t_id integer not null,
+  am2t_actor integer
+);
+
+CREATE TABLE /*_*/actormigration3 (
+  am3_id integer not null,
+  am3_xxx integer,
+  am3_xxx_text varchar(200),
+  am3_xxx_actor integer
+);
index 5cc3646..949b664 100644 (file)
@@ -61,32 +61,11 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                ];
        }
 
-       protected function getOldActorQueryFields( $prefix ) {
-               return [
-                       "{$prefix}_user" => "{$prefix}_user",
-                       "{$prefix}_user_text" => "{$prefix}_user_text",
-                       "{$prefix}_actor" => 'NULL',
-               ];
-       }
-
        protected function getNewActorQueryFields( $prefix, $tmp = false ) {
                return [
                        "{$prefix}_user" => "actor_{$prefix}_user.actor_user",
                        "{$prefix}_user_text" => "actor_{$prefix}_user.actor_name",
-                       "{$prefix}_actor" => $tmp ?: "{$prefix}_actor",
-               ];
-       }
-
-       protected function getNewActorJoins( $prefix ) {
-               return [
-                       "temp_{$prefix}_user" => [
-                               "JOIN",
-                               "temp_{$prefix}_user.revactor_{$prefix} = {$prefix}_id",
-                       ],
-                       "actor_{$prefix}_user" => [
-                               "JOIN",
-                               "actor_{$prefix}_user.actor_id = temp_{$prefix}_user.revactor_actor",
-                       ],
+                       "{$prefix}_actor" => $tmp ? "temp_{$prefix}_user.{$prefix}actor_actor" : "{$prefix}_actor",
                ];
        }
 
@@ -125,7 +104,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                yield 'MCR, comment, actor' => [
                        [
                                'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
                        ],
                        [
                                'tables' => [
@@ -150,7 +128,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                'wgContentHandlerUseDB' => true,
                                'wgMultiContentRevisionSchemaMigrationStage'
                                        => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
                        ],
                        [
                                'tables' => [
@@ -175,22 +152,23 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                'wgContentHandlerUseDB' => true,
                                'wgMultiContentRevisionSchemaMigrationStage'
                                        => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
                        ],
                        [
                                'tables' => [
                                        'archive',
+                                       'actor_ar_user' => 'actor',
                                        'comment_ar_comment' => 'comment',
                                ],
                                'fields' => array_merge(
                                        $this->getArchiveQueryFields( true ),
                                        $this->getContentHandlerQueryFields( 'ar' ),
-                                       $this->getOldActorQueryFields( 'ar' ),
+                                       $this->getNewActorQueryFields( 'ar' ),
                                        $this->getNewCommentQueryFields( 'ar' )
                                ),
                                'joins' => [
                                        'comment_ar_comment'
                                                => [ 'JOIN', 'comment_ar_comment.comment_id = ar_comment_id' ],
+                                       'actor_ar_user' => [ 'JOIN', 'actor_ar_user.actor_id = ar_actor' ],
                                ],
                        ]
                ];
@@ -198,21 +176,22 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                        [
                                'wgContentHandlerUseDB' => false,
                                'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
                        ],
                        [
                                'tables' => [
                                        'archive',
+                                       'actor_ar_user' => 'actor',
                                        'comment_ar_comment' => 'comment',
                                ],
                                'fields' => array_merge(
                                        $this->getArchiveQueryFields( true ),
-                                       $this->getOldActorQueryFields( 'ar' ),
+                                       $this->getNewActorQueryFields( 'ar' ),
                                        $this->getNewCommentQueryFields( 'ar' )
                                ),
                                'joins' => [
                                        'comment_ar_comment'
                                                => [ 'JOIN', 'comment_ar_comment.comment_id = ar_comment_id' ],
+                                       'actor_ar_user' => [ 'JOIN', 'actor_ar_user.actor_id = ar_actor' ],
                                ],
                        ]
                ];
@@ -224,7 +203,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                        [
                                'wgContentHandlerUseDB' => true,
                                'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
                        ],
                        [ 'page', 'user' ],
                        [
@@ -260,6 +238,8 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        ],
                                        'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
                                        'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
+                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
                                ],
                        ]
                ];
@@ -268,7 +248,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                'wgContentHandlerUseDB' => true,
                                'wgMultiContentRevisionSchemaMigrationStage'
                                        => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
                        ],
                        [ 'page', 'user' ],
                        [
@@ -288,22 +267,21 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        $this->getNewActorQueryFields( 'rev', 'temp_rev_user.revactor_actor' ),
                                        $this->getNewCommentQueryFields( 'rev' )
                                ),
-                               'joins' => array_merge(
-                                       [
-                                               'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
-                                               'user' => [
-                                                       'LEFT JOIN',
-                                                       [
-                                                               'actor_rev_user.actor_user != 0',
-                                                               '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' ],
+                               'joins' => [
+                                       'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
+                                       'user' => [
+                                               'LEFT JOIN',
+                                               [
+                                                       'actor_rev_user.actor_user != 0',
+                                                       'user_id = actor_rev_user.actor_user',
+                                               ]
                                        ],
-                                       $this->getNewActorJoins( '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' ],
+                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
+                               ],
                        ]
                ];
                yield 'MCR read-new' => [
@@ -311,7 +289,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                'wgContentHandlerUseDB' => true,
                                'wgMultiContentRevisionSchemaMigrationStage'
                                        => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
                        ],
                        [ 'page', 'user' ],
                        [
@@ -331,22 +308,21 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        $this->getNewActorQueryFields( 'rev', 'temp_rev_user.revactor_actor' ),
                                        $this->getNewCommentQueryFields( 'rev' )
                                ),
-                               'joins' => array_merge(
-                                       [
-                                               'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
-                                               'user' => [
-                                                       'LEFT JOIN',
-                                                       [
-                                                               'actor_rev_user.actor_user != 0',
-                                                               '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' ],
+                               'joins' => [
+                                       'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
+                                       'user' => [
+                                               'LEFT JOIN',
+                                               [
+                                                       'actor_rev_user.actor_user != 0',
+                                                       'user_id = actor_rev_user.actor_user'
+                                               ]
                                        ],
-                                       $this->getNewActorJoins( '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' ],
+                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
+                               ],
                        ]
                ];
                yield 'MCR write-both/read-old' => [
@@ -354,7 +330,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                'wgContentHandlerUseDB' => true,
                                'wgMultiContentRevisionSchemaMigrationStage'
                                        => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
                        ],
                        [],
                        [
@@ -362,17 +337,21 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        'revision',
                                        'temp_rev_comment' => 'revision_comment_temp',
                                        'comment_rev_comment' => 'comment',
+                                       'temp_rev_user' => 'revision_actor_temp',
+                                       'actor_rev_user' => 'actor',
                                ],
                                'fields' => array_merge(
                                        $this->getRevisionQueryFields( true ),
                                        $this->getContentHandlerQueryFields( 'rev' ),
-                                       $this->getOldActorQueryFields( 'rev', 'temp_rev_user.revactor_actor' ),
+                                       $this->getNewActorQueryFields( 'rev', 'temp_rev_user.revactor_actor' ),
                                        $this->getNewCommentQueryFields( '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' ],
+                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
                                ],
                        ]
                ];
@@ -381,7 +360,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                'wgContentHandlerUseDB' => true,
                                'wgMultiContentRevisionSchemaMigrationStage'
                                        => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
                        ],
                        [ 'page', 'user' ],
                        [
@@ -391,37 +369,38 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        'user',
                                        'temp_rev_comment' => 'revision_comment_temp',
                                        'comment_rev_comment' => 'comment',
+                                       'temp_rev_user' => 'revision_actor_temp',
+                                       'actor_rev_user' => 'actor',
                                ],
                                'fields' => array_merge(
                                        $this->getRevisionQueryFields( true ),
                                        $this->getContentHandlerQueryFields( 'rev' ),
                                        $this->getUserQueryFields(),
                                        $this->getPageQueryFields(),
-                                       $this->getOldActorQueryFields( 'rev', 'temp_rev_user.revactor_actor' ),
+                                       $this->getNewActorQueryFields( 'rev', 'temp_rev_user.revactor_actor' ),
                                        $this->getNewCommentQueryFields( 'rev' )
                                ),
-                               'joins' => array_merge(
-                                       [
-                                               'page' => [ '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' ],
-                                       ]
-                               ),
+                               'joins' => [
+                                       'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
+                                       'user' => [
+                                               'LEFT JOIN',
+                                               [
+                                                       'actor_rev_user.actor_user != 0',
+                                                       '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' ],
+                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
+                               ],
                        ]
                ];
                yield 'pre-MCR' => [
                        [
                                'wgContentHandlerUseDB' => true,
                                'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
                        ],
                        [],
                        [
@@ -429,17 +408,21 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        'revision',
                                        'temp_rev_comment' => 'revision_comment_temp',
                                        'comment_rev_comment' => 'comment',
+                                       'temp_rev_user' => 'revision_actor_temp',
+                                       'actor_rev_user' => 'actor',
                                ],
                                'fields' => array_merge(
                                        $this->getRevisionQueryFields( true ),
                                        $this->getContentHandlerQueryFields( 'rev' ),
-                                       $this->getOldActorQueryFields( 'rev' ),
+                                       $this->getNewActorQueryFields( 'rev', true ),
                                        $this->getNewCommentQueryFields( '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' ],
+                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
                                ],
                        ]
                ];
@@ -447,7 +430,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                        [
                                'wgContentHandlerUseDB' => true,
                                'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
                        ],
                        [ 'page', 'user' ],
                        [
@@ -455,21 +437,28 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        'revision', 'page', 'user',
                                        'temp_rev_comment' => 'revision_comment_temp',
                                        'comment_rev_comment' => 'comment',
+                                       'temp_rev_user' => 'revision_actor_temp',
+                                       'actor_rev_user' => 'actor',
                                ],
                                'fields' => array_merge(
                                        $this->getRevisionQueryFields( true ),
                                        $this->getContentHandlerQueryFields( 'rev' ),
                                        $this->getPageQueryFields(),
                                        $this->getUserQueryFields(),
-                                       $this->getOldActorQueryFields( 'rev' ),
+                                       $this->getNewActorQueryFields( 'rev', true ),
                                        $this->getNewCommentQueryFields( 'rev' )
                                ),
                                'joins' => [
                                        'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
-                                       'user' => [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
+                                       'user' => [ 'LEFT JOIN', [
+                                               'actor_rev_user.actor_user != 0',
+                                               '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' ],
+                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
                                ],
                        ]
                ];
@@ -477,7 +466,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                        [
                                'wgContentHandlerUseDB' => false,
                                'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
                        ],
                        [],
                        [
@@ -485,16 +473,20 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        'revision',
                                        'temp_rev_comment' => 'revision_comment_temp',
                                        'comment_rev_comment' => 'comment',
+                                       'temp_rev_user' => 'revision_actor_temp',
+                                       'actor_rev_user' => 'actor',
                                ],
                                'fields' => array_merge(
                                        $this->getRevisionQueryFields( true ),
-                                       $this->getOldActorQueryFields( 'rev' ),
+                                       $this->getNewActorQueryFields( 'rev', true ),
                                        $this->getNewCommentQueryFields( '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' ],
+                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
                                ],
                        ],
                ];
@@ -502,7 +494,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                        [
                                'wgContentHandlerUseDB' => false,
                                'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
                        ],
                        [ 'page' ],
                        [
@@ -510,11 +501,13 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        'revision', 'page',
                                        'temp_rev_comment' => 'revision_comment_temp',
                                        'comment_rev_comment' => 'comment',
+                                       'temp_rev_user' => 'revision_actor_temp',
+                                       'actor_rev_user' => 'actor',
                                ],
                                'fields' => array_merge(
                                        $this->getRevisionQueryFields( true ),
                                        $this->getPageQueryFields(),
-                                       $this->getOldActorQueryFields( 'rev' ),
+                                       $this->getNewActorQueryFields( 'rev', true ),
                                        $this->getNewCommentQueryFields( 'rev' )
                                ),
                                'joins' => [
@@ -522,6 +515,8 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        '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' ],
+                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
                                ],
                        ],
                ];
@@ -529,7 +524,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                        [
                                'wgContentHandlerUseDB' => false,
                                'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
                        ],
                        [ 'user' ],
                        [
@@ -537,18 +531,25 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        'revision', 'user',
                                        'temp_rev_comment' => 'revision_comment_temp',
                                        'comment_rev_comment' => 'comment',
+                                       'temp_rev_user' => 'revision_actor_temp',
+                                       'actor_rev_user' => 'actor',
                                ],
                                'fields' => array_merge(
                                        $this->getRevisionQueryFields( true ),
                                        $this->getUserQueryFields(),
-                                       $this->getOldActorQueryFields( 'rev' ),
+                                       $this->getNewActorQueryFields( 'rev', true ),
                                        $this->getNewCommentQueryFields( 'rev' )
                                ),
                                'joins' => [
-                                       'user' => [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
+                                       'user' => [ 'LEFT JOIN', [
+                                               'actor_rev_user.actor_user != 0',
+                                               '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' ],
+                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
                                ],
                        ],
                ];
@@ -556,7 +557,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                        [
                                'wgContentHandlerUseDB' => false,
                                'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
                        ],
                        [ 'text' ],
                        [
@@ -564,11 +564,13 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        'revision', 'text',
                                        'temp_rev_comment' => 'revision_comment_temp',
                                        'comment_rev_comment' => 'comment',
+                                       'temp_rev_user' => 'revision_actor_temp',
+                                       'actor_rev_user' => 'actor',
                                ],
                                'fields' => array_merge(
                                        $this->getRevisionQueryFields( true ),
                                        $this->getTextQueryFields(),
-                                       $this->getOldActorQueryFields( 'rev' ),
+                                       $this->getNewActorQueryFields( 'rev', true ),
                                        $this->getNewCommentQueryFields( 'rev' )
                                ),
                                'joins' => [
@@ -576,6 +578,8 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        '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' ],
+                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
                                ],
                        ],
                ];
@@ -583,7 +587,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                        [
                                'wgContentHandlerUseDB' => false,
                                'wgMultiContentRevisionSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
                        ],
                        [ 'text', 'page', 'user' ],
                        [
@@ -591,13 +594,15 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        'revision', 'page', 'user', 'text',
                                        'temp_rev_comment' => 'revision_comment_temp',
                                        'comment_rev_comment' => 'comment',
+                                       'temp_rev_user' => 'revision_actor_temp',
+                                       'actor_rev_user' => 'actor',
                                ],
                                'fields' => array_merge(
                                        $this->getRevisionQueryFields( true ),
                                        $this->getPageQueryFields(),
                                        $this->getUserQueryFields(),
                                        $this->getTextQueryFields(),
-                                       $this->getOldActorQueryFields( 'rev' ),
+                                       $this->getNewActorQueryFields( 'rev', true ),
                                        $this->getNewCommentQueryFields( 'rev' )
                                ),
                                'joins' => [
@@ -608,8 +613,8 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        'user' => [
                                                'LEFT JOIN',
                                                [
-                                                       'rev_user != 0',
-                                                       'user_id = rev_user',
+                                                       'actor_rev_user.actor_user != 0',
+                                                       'user_id = actor_rev_user.actor_user',
                                                ],
                                        ],
                                        'text' => [
@@ -619,6 +624,8 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        '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' ],
+                                       'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
+                                       'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
                                ],
                        ],
                ];
@@ -848,190 +855,6 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                ];
        }
 
-       public function provideSelectFields() {
-               yield 'with model, comment, and actor' => [
-                       [
-                               'wgContentHandlerUseDB' => true,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
-                       ],
-                       'fields' => array_merge(
-                               [
-                                       'rev_id',
-                                       'rev_page',
-                                       'rev_text_id',
-                                       'rev_timestamp',
-                                       'rev_user_text',
-                                       'rev_user',
-                                       'rev_actor' => 'NULL',
-                                       'rev_minor_edit',
-                                       'rev_deleted',
-                                       'rev_len',
-                                       'rev_parent_id',
-                                       'rev_sha1',
-                               ],
-                               $this->getContentHandlerQueryFields( 'rev' ),
-                               [
-                                       'rev_comment_pk' => 'rev_id',
-                               ]
-                       ),
-               ];
-               yield 'no mode, no comment, no actor' => [
-                       [
-                               'wgContentHandlerUseDB' => false,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                       ],
-                       'fields' => array_merge(
-                               [
-                                       'rev_id',
-                                       'rev_page',
-                                       'rev_text_id',
-                                       'rev_timestamp',
-                                       'rev_user_text',
-                                       'rev_user',
-                                       'rev_actor' => 'NULL',
-                                       'rev_minor_edit',
-                                       'rev_deleted',
-                                       'rev_len',
-                                       'rev_parent_id',
-                                       'rev_sha1',
-                                       'rev_comment_pk' => 'rev_id',
-                               ]
-                       ),
-               ];
-       }
-
-       public function provideSelectArchiveFields() {
-               yield 'with model, comment, and actor' => [
-                       [
-                               'wgContentHandlerUseDB' => true,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
-                       ],
-                       'fields' => array_merge(
-                               [
-                                       'ar_id',
-                                       'ar_page_id',
-                                       'ar_rev_id',
-                                       'ar_text_id',
-                                       'ar_timestamp',
-                                       'ar_user_text',
-                                       'ar_user',
-                                       'ar_actor' => 'NULL',
-                                       'ar_minor_edit',
-                                       'ar_deleted',
-                                       'ar_len',
-                                       'ar_parent_id',
-                                       'ar_sha1',
-                               ],
-                               $this->getContentHandlerQueryFields( 'ar' ),
-                               [
-                                       'ar_comment_id' => 'ar_comment_id',
-                               ]
-                       ),
-               ];
-               yield 'no mode, no comment, no actor' => [
-                       [
-                               'wgContentHandlerUseDB' => false,
-                               'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
-                       ],
-                       'fields' => array_merge(
-                               [
-                                       'ar_id',
-                                       'ar_page_id',
-                                       'ar_rev_id',
-                                       'ar_text_id',
-                                       'ar_timestamp',
-                                       'ar_user_text',
-                                       'ar_user',
-                                       'ar_actor' => 'NULL',
-                                       'ar_minor_edit',
-                                       'ar_deleted',
-                                       'ar_len',
-                                       'ar_parent_id',
-                                       'ar_sha1',
-                                       'ar_comment_id' => 'ar_comment_id',
-                               ]
-                       ),
-               ];
-       }
-
-       /**
-        * @dataProvider provideSelectFields
-        * @covers Revision::selectFields
-        */
-       public function testRevisionSelectFields( $migrationStageSettings, $expected ) {
-               $this->setMwGlobals( $migrationStageSettings );
-
-               $this->hideDeprecated( 'Revision::selectFields' );
-               $this->assertArrayEqualsIgnoringIntKeyOrder( $expected, Revision::selectFields() );
-       }
-
-       /**
-        * @dataProvider provideSelectArchiveFields
-        * @covers Revision::selectArchiveFields
-        */
-       public function testRevisionSelectArchiveFields( $migrationStageSettings, $expected ) {
-               $this->setMwGlobals( $migrationStageSettings );
-
-               $this->hideDeprecated( 'Revision::selectArchiveFields' );
-               $this->assertArrayEqualsIgnoringIntKeyOrder( $expected, Revision::selectArchiveFields() );
-       }
-
-       /**
-        * @covers Revision::userJoinCond
-        */
-       public function testRevisionUserJoinCond() {
-               $this->hideDeprecated( 'Revision::userJoinCond' );
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_OLD );
-               $this->assertEquals(
-                       [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
-                       Revision::userJoinCond()
-               );
-       }
-
-       /**
-        * @covers Revision::pageJoinCond
-        */
-       public function testRevisionPageJoinCond() {
-               $this->hideDeprecated( 'Revision::pageJoinCond' );
-               $this->assertEquals(
-                       [ 'JOIN', [ 'page_id = rev_page' ] ],
-                       Revision::pageJoinCond()
-               );
-       }
-
-       /**
-        * @covers Revision::selectTextFields
-        */
-       public function testRevisionSelectTextFields() {
-               $this->hideDeprecated( 'Revision::selectTextFields' );
-               $this->assertEquals(
-                       $this->getTextQueryFields(),
-                       Revision::selectTextFields()
-               );
-       }
-
-       /**
-        * @covers Revision::selectPageFields
-        */
-       public function testRevisionSelectPageFields() {
-               $this->hideDeprecated( 'Revision::selectPageFields' );
-               $this->assertEquals(
-                       $this->getPageQueryFields(),
-                       Revision::selectPageFields()
-               );
-       }
-
-       /**
-        * @covers Revision::selectUserFields
-        */
-       public function testRevisionSelectUserFields() {
-               $this->hideDeprecated( 'Revision::selectUserFields' );
-               $this->assertEquals(
-                       $this->getUserQueryFields(),
-                       Revision::selectUserFields()
-               );
-       }
-
        /**
         * @covers Revision::getArchiveQueryInfo
         * @dataProvider provideArchiveQueryInfo
index b0b9ddf..76190e0 100644 (file)
@@ -81,7 +81,6 @@ abstract class RevisionStoreDbTestBase extends MediaWikiTestCase {
                $this->setMwGlobals( [
                        'wgMultiContentRevisionSchemaMigrationStage' => $this->getMcrMigrationStage(),
                        'wgContentHandlerUseDB' => $this->getContentHandlerUseDB(),
-                       'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
                ] );
        }
 
@@ -1791,8 +1790,6 @@ abstract class RevisionStoreDbTestBase extends MediaWikiTestCase {
         * @covers \MediaWiki\Revision\RevisionStore::getKnownCurrentRevision
         */
        public function testGetKnownCurrentRevision_userNameChange() {
-               global $wgActorTableSchemaMigrationStage;
-
                $cache = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
                $this->setService( 'MainWANObjectCache', $cache );
 
@@ -1811,11 +1808,9 @@ abstract class RevisionStoreDbTestBase extends MediaWikiTestCase {
                $this->db->update( 'user',
                        [ 'user_name' => $newUserName ],
                        [ 'user_id' => $rev->getUser()->getId() ] );
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                       $this->db->update( 'actor',
-                               [ 'actor_name' => $newUserName ],
-                               [ 'actor_user' => $rev->getUser()->getId() ] );
-               }
+               $this->db->update( 'actor',
+                       [ 'actor_name' => $newUserName ],
+                       [ 'actor_user' => $rev->getUser()->getId() ] );
 
                // Reload the revision and regrab the user name.
                $revAfter = $store->getKnownCurrentRevision( $page->getTitle(), $rev->getId() );
@@ -1864,8 +1859,6 @@ abstract class RevisionStoreDbTestBase extends MediaWikiTestCase {
         * @covers \MediaWiki\Revision\RevisionStore::newRevisionFromRow
         */
        public function testNewRevisionFromRow_userNameChange() {
-               global $wgActorTableSchemaMigrationStage;
-
                $page = $this->getTestPage();
                $text = __METHOD__;
                /** @var Revision $rev */
@@ -1895,11 +1888,9 @@ abstract class RevisionStoreDbTestBase extends MediaWikiTestCase {
                $this->db->update( 'user',
                        [ 'user_name' => $newUserName ],
                        [ 'user_id' => $record->getUser()->getId() ] );
-               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
-                       $this->db->update( 'actor',
-                               [ 'actor_name' => $newUserName ],
-                               [ 'actor_user' => $record->getUser()->getId() ] );
-               }
+               $this->db->update( 'actor',
+                       [ 'actor_name' => $newUserName ],
+                       [ 'actor_user' => $record->getUser()->getId() ] );
 
                // Reload the record, passing $fromCache as true to force fresh info from the db,
                // and regrab the user name
index 7b334ee..d41c88f 100644 (file)
@@ -92,7 +92,6 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                $this->setMwGlobals( [
                        'wgMultiContentRevisionSchemaMigrationStage' => $this->getMcrMigrationStage(),
                        'wgContentHandlerUseDB' => $this->getContentHandlerUseDB(),
-                       'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
                ] );
 
                if ( !$this->testPage ) {
index 865bd31..ed4a27f 100644 (file)
@@ -601,7 +601,6 @@ class RevisionTest extends MediaWikiTestCase {
         * @covers Revision::loadFromTitle
         */
        public function testLoadFromTitle() {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_NEW );
                $title = $this->getMockTitle();
 
                $conditions = [
index 301ed10..df643d2 100644 (file)
@@ -8,15 +8,6 @@
  */
 class ApiQueryUserContribsTest extends ApiTestCase {
        public function addDBDataOnce() {
-               global $wgActorTableSchemaMigrationStage;
-
-               $reset = new \Wikimedia\ScopedCallback( function ( $v ) {
-                       $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $v );
-               }, [ $wgActorTableSchemaMigrationStage ] );
-               // Needs to WRITE_BOTH so READ_OLD tests below work. READ mode here doesn't really matter.
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage',
-                       SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW );
-
                $users = [
                        User::newFromName( '192.168.2.2', false ),
                        User::newFromName( '192.168.2.1', false ),
@@ -43,17 +34,14 @@ class ApiQueryUserContribsTest extends ApiTestCase {
 
        /**
         * @dataProvider provideSorting
-        * @param int $stage SCHEMA_COMPAT contants for $wgActorTableSchemaMigrationStage
         * @param array $params Extra parameters for the query
         * @param bool $reverse Reverse order?
         * @param int $revs Number of revisions to expect
         */
-       public function testSorting( $stage, $params, $reverse, $revs ) {
+       public function testSorting( $params, $reverse, $revs ) {
                // FIXME: fails under sqlite
                $this->markTestSkippedIfDbType( 'sqlite' );
 
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
-
                if ( isset( $params['ucuserids'] ) ) {
                        $params['ucuserids'] = implode( '|', array_map( 'User::idFromName', $params['ucuserids'] ) );
                }
@@ -116,38 +104,23 @@ class ApiQueryUserContribsTest extends ApiTestCase {
                $users2 = [ __CLASS__ . ' A', __CLASS__ . ' B', __CLASS__ . ' D' ];
                $ips = [ '192.168.2.1', '192.168.2.2', '192.168.2.3', '192.168.2.4' ];
 
-               foreach (
-                       [
-                               'old' => SCHEMA_COMPAT_OLD,
-                               'read old' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
-                               'read new' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
-                               'new' => SCHEMA_COMPAT_NEW,
-                       ] as $stageName => $stage
-               ) {
-                       foreach ( [ false, true ] as $reverse ) {
-                               $name = $stageName . ( $reverse ? ', reverse' : '' );
-                               yield "Named users, $name" => [ $stage, [ 'ucuser' => $users ], $reverse, 9 ];
-                               yield "Named users including a no-edit user, $name" => [
-                                       $stage, [ 'ucuser' => $users2 ], $reverse, 6
-                               ];
-                               yield "IP users, $name" => [ $stage, [ 'ucuser' => $ips ], $reverse, 9 ];
-                               yield "All users, $name" => [
-                                       $stage, [ 'ucuser' => array_merge( $users, $ips ) ], $reverse, 18
-                               ];
-                               yield "User IDs, $name" => [ $stage, [ 'ucuserids' => $users ], $reverse, 9 ];
-                               yield "Users by prefix, $name" => [ $stage, [ 'ucuserprefix' => __CLASS__ ], $reverse, 9 ];
-                               yield "IPs by prefix, $name" => [ $stage, [ 'ucuserprefix' => '192.168.2.' ], $reverse, 9 ];
-                       }
+               foreach ( [ false, true ] as $reverse ) {
+                       $name = ( $reverse ? ', reverse' : '' );
+                       yield "Named users, $name" => [ [ 'ucuser' => $users ], $reverse, 9 ];
+                       yield "Named users including a no-edit user, $name" => [
+                               [ 'ucuser' => $users2 ], $reverse, 6
+                       ];
+                       yield "IP users, $name" => [ [ 'ucuser' => $ips ], $reverse, 9 ];
+                       yield "All users, $name" => [
+                               [ 'ucuser' => array_merge( $users, $ips ) ], $reverse, 18
+                       ];
+                       yield "User IDs, $name" => [ [ 'ucuserids' => $users ], $reverse, 9 ];
+                       yield "Users by prefix, $name" => [ [ 'ucuserprefix' => __CLASS__ ], $reverse, 9 ];
+                       yield "IPs by prefix, $name" => [ [ 'ucuserprefix' => '192.168.2.' ], $reverse, 9 ];
                }
        }
 
-       /**
-        * @dataProvider provideInterwikiUser
-        * @param int $stage SCHEMA_COMPAT constants for $wgActorTableSchemaMigrationStage
-        */
-       public function testInterwikiUser( $stage ) {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
-
+       public function testInterwikiUser() {
                $params = [
                        'action' => 'query',
                        'list' => 'usercontribs',
@@ -174,13 +147,4 @@ class ApiQueryUserContribsTest extends ApiTestCase {
                $this->assertSame( $sorted, $ids, "IDs are sorted" );
        }
 
-       public static function provideInterwikiUser() {
-               return [
-                       'old' => [ SCHEMA_COMPAT_OLD ],
-                       'read old' => [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD ],
-                       'read new' => [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW ],
-                       'new' => [ SCHEMA_COMPAT_NEW ],
-               ];
-       }
-
 }
index b183cde..a7040e0 100644 (file)
@@ -29,18 +29,12 @@ class DatabaseLogEntryTest extends MediaWikiTestCase {
         * @param array $selectFields
         * @param string[]|null $row
         * @param string[]|null $expectedFields
-        * @param int $actorMigration
         */
        public function testNewFromId( $id,
                array $selectFields,
                array $row = null,
-               array $expectedFields = null,
-               $actorMigration
+               array $expectedFields = null
        ) {
-               $this->setMwGlobals( [
-                       'wgActorTableSchemaMigrationStage' => $actorMigration,
-               ] );
-
                $row = $row ? (object)$row : null;
                $db = $this->getMock( IDatabase::class );
                $db->expects( self::once() )
@@ -67,36 +61,6 @@ class DatabaseLogEntryTest extends MediaWikiTestCase {
        }
 
        public function provideNewFromId() {
-               $oldTables = [
-                       'tables' => [
-                               'logging', 'user',
-                               'comment_log_comment' => 'comment',
-                       ],
-                       'fields' => [
-                               'log_id',
-                               'log_type',
-                               'log_action',
-                               'log_timestamp',
-                               'log_namespace',
-                               'log_title',
-                               'log_params',
-                               'log_deleted',
-                               'user_id',
-                               'user_name',
-                               'user_editcount',
-                               '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' ],
-                               'comment_log_comment' => [ 'JOIN', 'comment_log_comment.comment_id = log_comment_id' ],
-                       ],
-               ];
                $newTables = [
                        'tables' => [
                                'logging',
@@ -133,22 +97,20 @@ class DatabaseLogEntryTest extends MediaWikiTestCase {
                return [
                        [
                                0,
-                               $oldTables + [ 'conds' => [ 'log_id' => 0 ] ],
-                               null,
+                               $newTables + [ 'conds' => [ 'log_id' => 0 ] ],
                                null,
-                               SCHEMA_COMPAT_OLD,
+                               null
                        ],
                        [
                                123,
-                               $oldTables + [ 'conds' => [ 'log_id' => 123 ] ],
+                               $newTables + [ 'conds' => [ 'log_id' => 123 ] ],
                                [
                                        'log_id' => 123,
                                        'log_type' => 'foobarize',
                                        'log_comment_text' => 'test!',
                                        'log_comment_data' => null,
                                ],
-                               [ 'type' => 'foobarize', 'comment' => 'test!' ],
-                               SCHEMA_COMPAT_OLD,
+                               [ 'type' => 'foobarize', 'comment' => 'test!' ]
                        ],
                        [
                                567,
@@ -159,8 +121,7 @@ class DatabaseLogEntryTest extends MediaWikiTestCase {
                                        'log_comment_text' => 'test!',
                                        'log_comment_data' => null,
                                ],
-                               [ 'type' => 'foobarize', 'comment' => 'test!' ],
-                               SCHEMA_COMPAT_NEW,
+                               [ 'type' => 'foobarize', 'comment' => 'test!' ]
                        ],
                ];
        }
index bcbc1ed..90b118c 100644 (file)
@@ -84,7 +84,6 @@ abstract class PageArchiveTestBase extends MediaWikiTestCase {
                $this->tablesUsed += $this->getMcrTablesToReset();
 
                $this->setMwGlobals( [
-                       'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
                        'wgContentHandlerUseDB' => $this->getContentHandlerUseDB(),
                        'wgMultiContentRevisionSchemaMigrationStage' => $this->getMcrMigrationStage(),
                ] );
index 68433c6..ff3e714 100644 (file)
@@ -224,8 +224,6 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
        }
 
        public function testRcHidemyselfFilter() {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_NEW );
-
                $user = $this->getTestUser()->getUser();
                $user->getActorId( wfGetDB( DB_MASTER ) );
                $this->assertConditions(
@@ -253,41 +251,7 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                );
        }
 
-       public function testRcHidemyselfFilter_old() {
-               $this->setMwGlobals(
-                       'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
-               );
-
-               $user = $this->getTestUser()->getUser();
-               $user->getActorId( wfGetDB( DB_MASTER ) );
-               $this->assertConditions(
-                       [ # expected
-                               "NOT((rc_user = '{$user->getId()}'))",
-                       ],
-                       [
-                               'hidemyself' => 1,
-                       ],
-                       "rc conditions: hidemyself=1 (logged in)",
-                       $user
-               );
-
-               $user = User::newFromName( '10.11.12.13', false );
-               $id = $user->getActorId( wfGetDB( DB_MASTER ) );
-               $this->assertConditions(
-                       [ # expected
-                               "NOT((rc_user_text = '10.11.12.13'))",
-                       ],
-                       [
-                               'hidemyself' => 1,
-                       ],
-                       "rc conditions: hidemyself=1 (anon)",
-                       $user
-               );
-       }
-
        public function testRcHidebyothersFilter() {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_NEW );
-
                $user = $this->getTestUser()->getUser();
                $user->getActorId( wfGetDB( DB_MASTER ) );
                $this->assertConditions(
@@ -315,38 +279,6 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                );
        }
 
-       public function testRcHidebyothersFilter_old() {
-               $this->setMwGlobals(
-                       'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
-               );
-
-               $user = $this->getTestUser()->getUser();
-               $user->getActorId( wfGetDB( DB_MASTER ) );
-               $this->assertConditions(
-                       [ # expected
-                               "(rc_user_text = '{$user->getName()}')",
-                       ],
-                       [
-                               'hidebyothers' => 1,
-                       ],
-                       "rc conditions: hidebyothers=1 (logged in)",
-                       $user
-               );
-
-               $user = User::newFromName( '10.11.12.13', false );
-               $id = $user->getActorId( wfGetDB( DB_MASTER ) );
-               $this->assertConditions(
-                       [ # expected
-                               "(rc_user_text = '10.11.12.13')",
-                       ],
-                       [
-                               'hidebyothers' => 1,
-                       ],
-                       "rc conditions: hidebyothers=1 (anon)",
-                       $user
-               );
-       }
-
        public function testRcHidepageedits() {
                $this->assertConditions(
                        [ # expected
@@ -550,8 +482,6 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
        }
 
        public function testFilterUserExpLevelAllExperienceLevels() {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_NEW );
-
                $this->assertConditions(
                        [
                                # expected
@@ -564,26 +494,7 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                );
        }
 
-       public function testFilterUserExpLevelAllExperienceLevels_old() {
-               $this->setMwGlobals(
-                       'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
-               );
-
-               $this->assertConditions(
-                       [
-                               # expected
-                               'rc_user != 0',
-                       ],
-                       [
-                               'userExpLevel' => 'newcomer;learner;experienced',
-                       ],
-                       "rc conditions: userExpLevel=newcomer;learner;experienced"
-               );
-       }
-
-       public function testFilterUserExpLevelRegistrered() {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_NEW );
-
+       public function testFilterUserExpLevelRegistered() {
                $this->assertConditions(
                        [
                                # expected
@@ -596,26 +507,7 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                );
        }
 
-       public function testFilterUserExpLevelRegistrered_old() {
-               $this->setMwGlobals(
-                       'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
-               );
-
-               $this->assertConditions(
-                       [
-                               # expected
-                               'rc_user != 0',
-                       ],
-                       [
-                               'userExpLevel' => 'registered',
-                       ],
-                       "rc conditions: userExpLevel=registered"
-               );
-       }
-
-       public function testFilterUserExpLevelUnregistrered() {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_NEW );
-
+       public function testFilterUserExpLevelUnregistered() {
                $this->assertConditions(
                        [
                                # expected
@@ -628,26 +520,7 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                );
        }
 
-       public function testFilterUserExpLevelUnregistrered_old() {
-               $this->setMwGlobals(
-                       'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
-               );
-
-               $this->assertConditions(
-                       [
-                               # expected
-                               'rc_user = 0',
-                       ],
-                       [
-                               'userExpLevel' => 'unregistered',
-                       ],
-                       "rc conditions: userExpLevel=unregistered"
-               );
-       }
-
-       public function testFilterUserExpLevelRegistreredOrLearner() {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_NEW );
-
+       public function testFilterUserExpLevelRegisteredOrLearner() {
                $this->assertConditions(
                        [
                                # expected
@@ -660,26 +533,7 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                );
        }
 
-       public function testFilterUserExpLevelRegistreredOrLearner_old() {
-               $this->setMwGlobals(
-                       'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
-               );
-
-               $this->assertConditions(
-                       [
-                               # expected
-                               'rc_user != 0',
-                       ],
-                       [
-                               'userExpLevel' => 'registered;learner',
-                       ],
-                       "rc conditions: userExpLevel=registered;learner"
-               );
-       }
-
-       public function testFilterUserExpLevelUnregistreredOrExperienced() {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_NEW );
-
+       public function testFilterUserExpLevelUnregisteredOrExperienced() {
                $conds = $this->buildQuery( [ 'userExpLevel' => 'unregistered;experienced' ] );
 
                $this->assertRegExp(
@@ -690,21 +544,6 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                );
        }
 
-       public function testFilterUserExpLevelUnregistreredOrExperienced_old() {
-               $this->setMwGlobals(
-                       'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
-               );
-
-               $conds = $this->buildQuery( [ 'userExpLevel' => 'unregistered;experienced' ] );
-
-               $this->assertRegExp(
-                       '/\(rc_user = 0\) OR '
-                               . '\(\(user_editcount >= 500\) AND \(user_registration <= \'[^\']+\'\)\)/',
-                       reset( $conds ),
-                       "rc conditions: userExpLevel=unregistered;experienced"
-               );
-       }
-
        public function testFilterUserExpLevel() {
                $now = time();
                $this->setMwGlobals( [
index c0376ad..a5d5946 100644 (file)
@@ -60,6 +60,10 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
                        'callback array' => [
                                [ 'SpecialPageTestHelper', 'newSpecialAllPages' ],
                                false
+                       ],
+                       'object factory spec' => [
+                               [ 'class' => SpecialAllPages::class ],
+                               false
                        ]
                ];
        }
@@ -264,4 +268,29 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
                $this->assertTrue( $called, 'Recursive call succeeded' );
        }
 
+       /**
+        * @covers \MediaWiki\Special\SpecialPageFactory::getPage
+        */
+       public function testSpecialPageCreationThatRequiresService() {
+               $type = null;
+
+               $this->setMwGlobals( 'wgSpecialPages',
+                       [ 'TestPage' => [
+                               'factory' => function ( $spf ) use ( &$type ) {
+                                       $type = get_class( $spf );
+
+                                       return new class() extends SpecialPage {
+
+                                       };
+                               },
+                               'services' => [
+                                       'SpecialPageFactory'
+                               ]
+                       ] ]
+               );
+
+               SpecialPageFactory::getPage( 'TestPage' );
+
+               $this->assertEquals( \MediaWiki\Special\SpecialPageFactory::class, $type );
+       }
 }
index 2d87c78..3005ae9 100644 (file)
@@ -31,7 +31,6 @@ class UserTest extends MediaWikiTestCase {
                $this->setMwGlobals( [
                        'wgGroupPermissions' => [],
                        'wgRevokePermissions' => [],
-                       'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_NEW,
                ] );
 
                $this->setUpPermissionGlobals();
@@ -1075,83 +1074,6 @@ class UserTest extends MediaWikiTestCase {
                        'User::newFromActorId works for an anonymous user' );
        }
 
-       /**
-        * Actor tests with SCHEMA_COMPAT_READ_OLD
-        *
-        * The only thing different from testActorId() is the behavior if the actor
-        * row doesn't exist in the DB, since with SCHEMA_COMPAT_READ_NEW that
-        * situation can't happen. But we copy all the other tests too just for good measure.
-        *
-        * @covers User::newFromActorId
-        */
-       public function testActorId_old() {
-               $this->setMwGlobals( [
-                       'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
-               ] );
-
-               $domain = MediaWikiServices::getInstance()->getDBLoadBalancer()->getLocalDomainID();
-               $this->hideDeprecated( 'User::selectFields' );
-
-               // Newly-created user has an actor ID
-               $user = User::createNew( 'UserTestActorIdOld1' );
-               $id = $user->getId();
-               $this->assertTrue( $user->getActorId() > 0, 'User::createNew sets an actor ID' );
-
-               $user = User::newFromName( 'UserTestActorIdOld2' );
-               $user->addToDatabase();
-               $this->assertTrue( $user->getActorId() > 0, 'User::addToDatabase sets an actor ID' );
-
-               $user = User::newFromName( 'UserTestActorIdOld1' );
-               $this->assertTrue( $user->getActorId() > 0, 'Actor ID can be retrieved for user loaded by name' );
-
-               $user = User::newFromId( $id );
-               $this->assertTrue( $user->getActorId() > 0, 'Actor ID can be retrieved for user loaded by ID' );
-
-               $user2 = User::newFromActorId( $user->getActorId() );
-               $this->assertEquals( $user->getId(), $user2->getId(),
-                       'User::newFromActorId works for an existing user' );
-
-               $row = $this->db->selectRow( 'user', User::selectFields(), [ 'user_id' => $id ], __METHOD__ );
-               $user = User::newFromRow( $row );
-               $this->assertTrue( $user->getActorId() > 0,
-                       'Actor ID can be retrieved for user loaded with User::selectFields()' );
-
-               $this->db->delete( 'actor', [ 'actor_user' => $id ], __METHOD__ );
-               User::purge( $domain, $id );
-               // Because WANObjectCache->delete() stupidly doesn't delete from the process cache.
-
-               MediaWikiServices::getInstance()->getMainWANObjectCache()->clearProcessCache();
-
-               $user = User::newFromId( $id );
-               $this->assertFalse( $user->getActorId() > 0, 'No Actor ID by default if none in database' );
-               $this->assertTrue( $user->getActorId( $this->db ) > 0, 'Actor ID can be created if none in db' );
-
-               $user->setName( 'UserTestActorIdOld4-renamed' );
-               $user->saveSettings();
-               $this->assertEquals(
-                       $user->getName(),
-                       $this->db->selectField(
-                               'actor', 'actor_name', [ 'actor_id' => $user->getActorId() ], __METHOD__
-                       ),
-                       'User::saveSettings updates actor table for name change'
-               );
-
-               // For sanity
-               $ip = '192.168.12.34';
-               $this->db->delete( 'actor', [ 'actor_name' => $ip ], __METHOD__ );
-
-               $user = User::newFromName( $ip, false );
-               $this->assertFalse( $user->getActorId() > 0, 'Anonymous user has no actor ID by default' );
-               $this->assertTrue( $user->getActorId( $this->db ) > 0,
-                       'Actor ID can be created for an anonymous user' );
-
-               $user = User::newFromName( $ip, false );
-               $this->assertTrue( $user->getActorId() > 0, 'Actor ID can be loaded for an anonymous user' );
-               $user2 = User::newFromActorId( $user->getActorId() );
-               $this->assertEquals( $user->getName(), $user2->getName(),
-                       'User::newFromActorId works for an anonymous user' );
-       }
-
        /**
         * @covers User::newFromAnyId
         */
index b8d1383..cd0d7a5 100644 (file)
@@ -37,7 +37,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                $logs[] = [
                        'log_type' => 'patrol',
                        'log_action' => 'patrol',
-                       'log_user' => 7251,
+                       'log_actor' => 7251,
                        'log_params' => '',
                        'log_timestamp' => $dbw->timestamp( '20041223210426' ),
                        'log_namespace' => NS_MAIN,
@@ -49,7 +49,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                $logs[] = [
                        'log_type' => 'patrol',
                        'log_action' => 'autopatrol',
-                       'log_user' => 7252,
+                       'log_actor' => 7252,
                        'log_params' => '',
                        'log_timestamp' => $dbw->timestamp( '20051223210426' ),
                        'log_namespace' => NS_MAIN,
@@ -61,7 +61,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                $logs[] = [
                        'log_type' => 'block',
                        'log_action' => 'block',
-                       'log_user' => 7253,
+                       'log_actor' => 7253,
                        'log_params' => '',
                        'log_timestamp' => $dbw->timestamp( '20061223210426' ),
                        'log_namespace' => NS_MAIN,
@@ -73,7 +73,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                $logs[] = [
                        'log_type' => 'patrol',
                        'log_action' => 'patrol',
-                       'log_user' => 7253,
+                       'log_actor' => 7253,
                        'log_params' => 'nanana',
                        'log_timestamp' => $dbw->timestamp( '20061223210426' ),
                        'log_namespace' => NS_MAIN,
@@ -85,7 +85,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                $logs[] = [
                        'log_type' => 'patrol',
                        'log_action' => 'autopatrol',
-                       'log_user' => 7254,
+                       'log_actor' => 7254,
                        'log_params' => '',
                        'log_timestamp' => $dbw->timestamp( '20071223210426' ),
                        'log_namespace' => NS_MAIN,
@@ -97,7 +97,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                $logs[] = [
                        'log_type' => 'patrol',
                        'log_action' => 'patrol',
-                       'log_user' => 7255,
+                       'log_actor' => 7255,
                        'log_params' => serialize( [ '6::auto' => true ] ),
                        'log_timestamp' => $dbw->timestamp( '20081223210426' ),
                        'log_namespace' => NS_MAIN,
@@ -109,7 +109,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                $logs[] = [
                        'log_type' => 'patrol',
                        'log_action' => 'patrol',
-                       'log_user' => 7256,
+                       'log_actor' => 7256,
                        'log_params' => serialize( [ '6::auto' => false ] ),
                        'log_timestamp' => $dbw->timestamp( '20091223210426' ),
                        'log_namespace' => NS_MAIN,
@@ -121,7 +121,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                $logs[] = [
                        'log_type' => 'patrol',
                        'log_action' => 'patrol',
-                       'log_user' => 7257,
+                       'log_actor' => 7257,
                        'log_params' => "9227851\n0\n1",
                        'log_timestamp' => $dbw->timestamp( '20081223210426' ),
                        'log_namespace' => NS_MAIN,
@@ -133,7 +133,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                $logs[] = [
                        'log_type' => 'patrol',
                        'log_action' => 'patrol',
-                       'log_user' => 7258,
+                       'log_actor' => 7258,
                        'log_params' => "9227851\n0\n0",
                        'log_timestamp' => $dbw->timestamp( '20091223210426' ),
                        'log_namespace' => NS_MAIN,
@@ -149,47 +149,47 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        (object)[
                                'log_type' => 'patrol',
                                'log_action' => 'patrol',
-                               'log_user' => '7251',
+                               'log_actor' => '7251',
                        ],
                        (object)[
                                'log_type' => 'patrol',
                                'log_action' => 'autopatrol',
-                               'log_user' => '7252',
+                               'log_actor' => '7252',
                        ],
                        (object)[
                                'log_type' => 'block',
                                'log_action' => 'block',
-                               'log_user' => '7253',
+                               'log_actor' => '7253',
                        ],
                        (object)[
                                'log_type' => 'patrol',
                                'log_action' => 'patrol',
-                               'log_user' => '7253',
+                               'log_actor' => '7253',
                        ],
                        (object)[
                                'log_type' => 'patrol',
                                'log_action' => 'autopatrol',
-                               'log_user' => '7254',
+                               'log_actor' => '7254',
                        ],
                        (object)[
                                'log_type' => 'patrol',
                                'log_action' => 'patrol',
-                               'log_user' => '7255',
+                               'log_actor' => '7255',
                        ],
                        (object)[
                                'log_type' => 'patrol',
                                'log_action' => 'patrol',
-                               'log_user' => '7256',
+                               'log_actor' => '7256',
                        ],
                        (object)[
                                'log_type' => 'patrol',
                                'log_action' => 'patrol',
-                               'log_user' => '7257',
+                               'log_actor' => '7257',
                        ],
                        (object)[
                                'log_type' => 'patrol',
                                'log_action' => 'patrol',
-                               'log_user' => '7258',
+                               'log_actor' => '7258',
                        ],
                ];
 
@@ -266,7 +266,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
 
                $remainingLogs = wfGetDB( DB_REPLICA )->select(
                        [ 'logging' ],
-                       [ 'log_type', 'log_action', 'log_user' ],
+                       [ 'log_type', 'log_action', 'log_actor' ],
                        [],
                        __METHOD__,
                        [ 'ORDER BY' => 'log_id' ]
@@ -288,7 +288,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
 
                $remainingLogs = wfGetDB( DB_REPLICA )->select(
                        [ 'logging' ],
-                       [ 'log_type', 'log_action', 'log_user' ],
+                       [ 'log_type', 'log_action', 'log_actor' ],
                        [],
                        __METHOD__,
                        [ 'ORDER BY' => 'log_id' ]
@@ -297,12 +297,12 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                $deleted = [
                        'log_type' => 'patrol',
                        'log_action' => 'autopatrol',
-                       'log_user' => '7254',
+                       'log_actor' => '7254',
                ];
                $notDeleted = [
                        'log_type' => 'patrol',
                        'log_action' => 'autopatrol',
-                       'log_user' => '7252',
+                       'log_actor' => '7252',
                ];
 
                $remainingLogs = array_map(
index f425d87..5be1ed0 100644 (file)
--- a/thumb.php
+++ b/thumb.php
@@ -25,6 +25,7 @@ use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
 
 define( 'MW_NO_OUTPUT_COMPRESSION', 1 );
+define( 'MW_ENTRY_POINT', 'thumb' );
 require __DIR__ . '/includes/WebStart.php';
 
 // Don't use fancy MIME detection, just check the file extension for jpg/gif/png
index e2b165b..4e6bbd9 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 define( 'THUMB_HANDLER', true );
+define( 'MW_ENTRY_POINT', 'thumb_handler' );
 
 // Execute thumb.php, having set THUMB_HANDLER so that
 // it knows to extract params from a thumbnail file URL.