if ( $current ) {
$fields = [
- 'page' => $title->getArticleID(),
- 'user_text' => $user->getName(),
- 'user' => $user->getId(),
- 'actor' => $user->getActorId(),
- 'comment' => $comment,
- 'minor_edit' => $minor,
- 'text_id' => $current->rev_text_id,
- 'parent_id' => $current->page_latest,
- 'len' => $current->rev_len,
- 'sha1' => $current->rev_sha1
+ 'page' => $title->getArticleID(),
+ 'user_text' => $user->getName(),
+ 'user' => $user->getId(),
+ 'actor' => $user->getActorId(),
+ 'comment' => $comment,
+ 'minor_edit' => $minor,
+ 'text_id' => $current->rev_text_id,
+ 'parent_id' => $current->page_latest,
+ 'slot_origin' => $current->page_latest,
+ 'len' => $current->rev_len,
+ 'sha1' => $current->rev_sha1
];
if ( $this->contentHandlerUseDB ) {
$mainSlotRow->content_address = 'tt:' . $row->rev_text_id;
}
+ // This is used by null-revisions
+ $mainSlotRow->slot_origin = isset( $row->slot_origin )
+ ? intval( $row->slot_origin )
+ : null;
+
if ( isset( $row->old_text ) ) {
// this happens when the text-table gets joined directly, in the pre-1.30 schema
$blobData = isset( $row->old_text ) ? strval( $row->old_text ) : null;
$mainSlotRow->slot_content_id = isset( $row['text_id'] )
? intval( $row['text_id'] )
: null;
+ $mainSlotRow->slot_origin = isset( $row['slot_origin'] )
+ ? intval( $row['slot_origin'] )
+ : null;
$mainSlotRow->content_address = isset( $row['text_id'] )
? 'tt:' . intval( $row['text_id'] )
: null;
throw new MWException( 'Revision constructor passed invalid row format.' );
}
- // With the old schema, the content changes with every revision.
- // ...except for null-revisions. Would be nice if we could detect them.
- $mainSlotRow->slot_inherited = 0;
+ // With the old schema, the content changes with every revision,
+ // except for null-revisions.
+ if ( !isset( $mainSlotRow->slot_origin ) ) {
+ $mainSlotRow->slot_origin = $mainSlotRow->slot_revision_id;
+ }
if ( $mainSlotRow->model_name === null ) {
$mainSlotRow->model_name = function ( SlotRecord $slot ) use ( $title ) {
* @return RevisionRecord|null
*/
public function getRevisionByTimestamp( $title, $timestamp ) {
+ $db = $this->getDBConnection( DB_REPLICA );
return $this->newRevisionFromConds(
[
- 'rev_timestamp' => $timestamp,
+ 'rev_timestamp' => $db->timestamp( $timestamp ),
'page_namespace' => $title->getNamespace(),
'page_title' => $title->getDBkey()
],
// 1.31
[ 'addTable', 'slots', 'patch-slots.sql' ],
+ [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
[ 'addTable', 'content', 'patch-content.sql' ],
[ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
[ 'addTable', 'content_models', 'patch-content_models.sql' ],
[ 'migrateArchiveText' ],
[ 'addTable', 'actor', 'patch-actor-table.sql' ],
[ 'migrateActors' ],
+ [ 'modifyField', 'revision', 'rev_text_id', 'patch-rev_text_id-default.sql' ],
];
}
// 1.31
[ 'addTable', 'slots', 'patch-slots.sql' ],
+ [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
[ 'addTable', 'content', 'patch-content.sql' ],
[ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
[ 'addTable', 'content_models', 'patch-content_models.sql' ],
[ 'migrateArchiveText' ],
[ 'addTable', 'actor', 'patch-actor-table.sql' ],
[ 'migrateActors' ],
+ [ 'modifyField', 'revision', 'rev_text_id', 'patch-rev_text_id-default.sql' ],
];
}
[ 'addTable', 'content', 'patch-content.sql' ],
[ 'addTable', 'content_models', 'patch-content_models.sql' ],
[ 'addTable', 'slots', 'patch-slots.sql' ],
+ [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
[ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
[ 'migrateArchiveText' ],
[ 'addTable', 'actor', 'patch-actor-table.sql' ],
[ 'migrateActors' ],
+ [ 'modifyField', 'revision', 'rev_text_id', 'patch-rev_text_id-default.sql' ],
];
}
CREATE TABLE /*_*/revision (
rev_id INT NOT NULL UNIQUE IDENTITY(0,1),
rev_page INT NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
- rev_text_id INT NOT NULL, -- FK added later
+ rev_text_id INT NOT NULL CONSTRAINT DF_rev_text_id DEFAULT 0, -- FK added later
rev_comment NVARCHAR(255) NOT NULL CONSTRAINT DF_rev_comment DEFAULT '',
rev_user INT REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
rev_user_text NVARCHAR(255) NOT NULL DEFAULT '',
-- reference to content_id
slot_content_id bigint unsigned NOT NULL CONSTRAINT FK_slots_content_id FOREIGN KEY REFERENCES content(content_id),
- -- whether the content is inherited (1) or new in this revision (0)
- slot_inherited tinyint unsigned NOT NULL CONSTRAINT DF_slot_inherited DEFAULT 0,
+ -- The revision ID of the revision that originated the slot's content.
+ -- To find revisions that changed slots, look for slot_origin = slot_revision_id.
+ slot_origin bigint NOT NULL,
CONSTRAINT PK_slots PRIMARY KEY (slot_revision_id, slot_role_id)
);
-- Index for finding revisions that modified a specific slot
- CREATE INDEX /*i*/slot_role_inherited ON /*_*/slots (slot_revision_id, slot_role_id, slot_inherited);
+ CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);
--
-- The content table represents content objects. It's primary purpose is to provide the necessary
-- It's possible for multiple revisions to use the same text,
-- for instance revisions where only metadata is altered
-- or a rollback to a previous version.
- rev_text_id int unsigned NOT NULL,
+ rev_text_id int unsigned NOT NULL default 0,
-- Text comment summarizing the change. Deprecated in favor of
-- revision_comment_temp.revcomment_comment_id.
-- reference to content_id
slot_content_id bigint unsigned NOT NULL,
- -- whether the content is inherited (1) or new in this revision (0)
- slot_inherited tinyint unsigned NOT NULL DEFAULT 0,
+ -- The revision ID of the revision that originated the slot's content.
+ -- To find revisions that changed slots, look for slot_origin = slot_revision_id.
+ slot_origin bigint unsigned NOT NULL,
PRIMARY KEY ( slot_revision_id, slot_role_id )
) /*$wgDBTableOptions*/;
-- Index for finding revisions that modified a specific slot
- CREATE INDEX /*i*/slot_role_inherited ON /*_*/slots (slot_revision_id, slot_role_id, slot_inherited);
+ CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);
--
-- The content table represents content objects. It's primary purpose is to provide the necessary
ct_rev_id int unsigned NULL,
-- Tag applied
ct_tag varchar(255) NOT NULL,
- -- Parameters for the tag, presently unused
+ -- Parameters for the tag; used by some extensions
ct_params blob NULL
) /*$wgDBTableOptions*/;