From: Brion Vibber Date: Mon, 28 Mar 2005 10:47:12 +0000 (+0000) Subject: Decouple revision.rev_id from text.old_id X-Git-Tag: 1.5.0alpha1~474 X-Git-Url: http://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/exercices/modifier.php?a=commitdiff_plain;h=0b86f637f22416a54a6bd1e48a282826d7bc11cd;p=lhc%2Fweb%2Fwiklou.git Decouple revision.rev_id from text.old_id * This will allow the backend text storage to use different id numbers * Revisions noting metadata changes can be added to history without duplicating text (implemented for page move) This changes the revision table schema and requires running update.php or maintenance/archives/patch-rev_text_id.sql on existing test wikis. PostgreSQL table defs are still not in sync, so not updated. --- diff --git a/includes/MessageCache.php b/includes/MessageCache.php index 2627f099c0..7a0616c454 100755 --- a/includes/MessageCache.php +++ b/includes/MessageCache.php @@ -144,9 +144,9 @@ class MessageCache $conditions['page_title']=MessageCacheHints::get(); } } - $res = $dbr->select( array( 'page', 'text' ), + $res = $dbr->select( array( 'page', 'revision', 'text' ), array( 'page_title', 'old_text', 'old_flags' ), - 'page_is_redirect=0 AND page_namespace = '.NS_MEDIAWIKI.' AND page_latest = old_id', + 'page_is_redirect=0 AND page_namespace='.NS_MEDIAWIKI.' AND page_latest=rev_id AND rev_text_id=old_id', $fname ); diff --git a/includes/Revision.php b/includes/Revision.php index 3d9cedd437..02d7c520fe 100644 --- a/includes/Revision.php +++ b/includes/Revision.php @@ -165,6 +165,7 @@ class Revision { 'page_latest', 'rev_id', 'rev_page', + 'rev_text_id', 'rev_comment', 'rev_user_text', 'rev_user', @@ -183,6 +184,7 @@ class Revision { if( is_object( $row ) ) { $this->mId = IntVal( $row->rev_id ); $this->mPage = IntVal( $row->rev_page ); + $this->mTextId = IntVal( $row->rev_text_id ); $this->mComment = $row->rev_comment; $this->mUserText = $row->rev_user_text; $this->mUser = IntVal( $row->rev_user ); @@ -204,6 +206,7 @@ class Revision { $this->mId = isset( $row['id'] ) ? IntVal( $row['id'] ) : null; $this->mPage = isset( $row['page'] ) ? IntVal( $row['page'] ) : null; + $this->mTextId = isset( $row['text_id'] ) ? IntVal( $row['text_id'] ) : null; $this->mComment = isset( $row['comment'] ) ? StrVal( $row['comment'] ) : null; $this->mUserText = isset( $row['user_text'] ) ? StrVal( $row['user_text'] ) : $wgUser->getName(); $this->mUser = isset( $row['user'] ) ? IntVal( $row['user'] ) : $wgUser->getId(); @@ -229,6 +232,13 @@ class Revision { return $this->mId; } + /** + * @return int + */ + function getTextId() { + return $this->mTextId; + } + /** * Returns the title of the page associated with this entry. * @return Title @@ -433,23 +443,27 @@ class Revision { $flags = Revision::compressRevisionText( $mungedText ); # Record the text to the text table - $old_id = isset( $this->mId ) - ? $this->mId - : $dbw->nextSequenceValue( 'text_old_id_val' ); - $dbw->insert( 'text', - array( - 'old_id' => $old_id, - 'old_text' => $mungedText, - 'old_flags' => $flags, - ), $fname - ); - $revisionId = $dbw->insertId(); + if( !isset( $this->mTextId ) ) { + $old_id = $dbw->nextSequenceValue( 'text_old_id_val' ); + $dbw->insert( 'text', + array( + 'old_id' => $old_id, + 'old_text' => $mungedText, + 'old_flags' => $flags, + ), $fname + ); + $this->mTextId = $dbw->insertId(); + } # Record the edit in revisions + $rev_id = isset( $this->mId ) + ? $this->mId + : $dbw->nextSequenceValue( 'rev_rev_id_val' ); $dbw->insert( 'revision', array( - 'rev_id' => $revisionId, + 'rev_id' => $rev_id, 'rev_page' => $this->mPage, + 'rev_text_id' => $this->mTextId, 'rev_comment' => $this->mComment, 'rev_minor_edit' => $this->mMinorEdit ? 1 : 0, 'rev_user' => $this->mUser, @@ -458,10 +472,10 @@ class Revision { ), $fname ); - $this->mId = $revisionId; + $this->mId = $dbw->insertId(); wfProfileOut( $fname ); - return $revisionId; + return $this->mId; } /** @@ -478,7 +492,7 @@ class Revision { $dbr =& wfGetDB( DB_SLAVE ); $row = $dbr->selectRow( 'text', array( 'old_text', 'old_flags' ), - array( 'old_id' => $this->getId() ), + array( 'old_id' => $this->getTextId() ), $fname); $text = Revision::getRevisionText( $row ); @@ -486,5 +500,48 @@ class Revision { return $text; } + + /** + * Create a new null-revision for insertion into a page's + * history. This will not re-save the text, but simply refer + * to the text from the previous version. + * + * Such revisions can for instance identify page rename + * operations and other such meta-modifications. + * + * @param Database $dbw + * @param int $pageId ID number of the page to read from + * @param string $summary + * @param bool $minor + * @return Revision + */ + function &newNullRevision( &$dbw, $pageId, $summary, $minor ) { + $fname = 'Revision::newNullRevision'; + wfProfileIn( $fname ); + + $current = $dbw->selectRow( + array( 'page', 'revision' ), + array( 'page_latest', 'rev_text_id' ), + array( + 'page_id' => $pageId, + 'page_latest=rev_id', + ), + $fname ); + + if( $current ) { + $revision = new Revision( array( + 'page' => $pageId, + 'comment' => $summary, + 'minor_edit' => $minor, + 'text_id' => $current->rev_text_id, + ) ); + } else { + $revision = null; + } + + wfProfileOut( $fname ); + return $revision; + } + } ?> \ No newline at end of file diff --git a/includes/SearchMySQL3.php b/includes/SearchMySQL3.php index bd2a0ede53..948c97b6c9 100644 --- a/includes/SearchMySQL3.php +++ b/includes/SearchMySQL3.php @@ -82,12 +82,13 @@ class SearchMySQL3 extends SearchEngine { function queryMain( $filteredTerm, $fulltext ) { $match = $this->parseQuery( $filteredTerm, $fulltext ); - $page = $this->db->tableName( 'page' ); - $text = $this->db->tableName( 'text' ); + $page = $this->db->tableName( 'page' ); + $revision = $this->db->tableName( 'revision' ); + $text = $this->db->tableName( 'text' ); $searchindex = $this->db->tableName( 'searchindex' ); return 'SELECT page_id, page_namespace, page_title, old_flags, old_text ' . - "FROM $page,$text,$searchindex " . - 'WHERE page_id=si_page AND page_latest=old_id AND ' . $match; + "FROM $page,$revision,$text,$searchindex " . + 'WHERE page_id=si_page AND page_latest=rev_id AND rev_text_id=old_id AND ' . $match; } function update( $id, $title, $text ) { diff --git a/includes/SearchMySQL4.php b/includes/SearchMySQL4.php index 6847ac1d0a..20bbfbcfc5 100644 --- a/includes/SearchMySQL4.php +++ b/includes/SearchMySQL4.php @@ -81,12 +81,13 @@ class SearchMySQL4 extends SearchEngine { /** @todo document */ function queryMain( $filteredTerm, $fulltext ) { $match = $this->parseQuery( $filteredTerm, $fulltext ); - $page = $this->db->tableName( 'page' ); - $text = $this->db->tableName( 'text' ); + $page = $this->db->tableName( 'page' ); + $revision = $this->db->tableName( 'revision' ); + $text = $this->db->tableName( 'text' ); $searchindex = $this->db->tableName( 'searchindex' ); return 'SELECT page_id, page_namespace, page_title, old_flags, old_text ' . - "FROM $page,$text,$searchindex " . - 'WHERE page_id=si_page AND page_latest=old_id AND ' . $match; + "FROM $page,$revision,$text,$searchindex " . + 'WHERE page_id=si_page AND page_latest=rev_id AND rev_text_id=old_id AND ' . $match; } /** @todo document */ diff --git a/includes/Title.php b/includes/Title.php index 4fb3dc27e5..dc9e743a7c 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -1502,12 +1502,19 @@ class Title { # a conflict on the unique namespace+title index... $dbw->delete( 'page', array( 'page_id' => $newid ), $fname ); + # Save a null revision in the page's history notifying of the move + $nullRevision = Revision::newNullRevision( $dbw, $oldid, + wfMsg( '1movedto2', $this->getPrefixedText(), $nt->getPrefixedText() ), + true ); + $nullRevId = $nullRevision->insertOn( $dbw ); + # Change the name of the target page: $dbw->update( 'page', /* SET */ array( - 'page_touched' => $dbw->timestamp($now), + 'page_touched' => $dbw->timestamp($now), 'page_namespace' => $nt->getNamespace(), - 'page_title' => $nt->getDBkey() + 'page_title' => $nt->getDBkey(), + 'page_latest' => $nullRevId, ), /* WHERE */ array( 'page_id' => $oldid ), $fname @@ -1610,12 +1617,19 @@ class Title { wfSeedRandom(); $rand = wfRandom(); + # Save a null revision in the page's history notifying of the move + $nullRevision = Revision::newNullRevision( $dbw, $oldid, + wfMsg( '1movedto2', $this->getPrefixedText(), $nt->getPrefixedText() ), + true ); + $nullRevId = $nullRevision->insertOn( $dbw ); + # Rename cur entry $dbw->update( 'page', /* SET */ array( - 'page_touched' => $now, + 'page_touched' => $now, 'page_namespace' => $nt->getNamespace(), - 'page_title' => $nt->getDBkey() + 'page_title' => $nt->getDBkey(), + 'page_latest' => $nullRevId, ), /* WHERE */ array( 'page_id' => $oldid ), $fname @@ -1685,9 +1699,9 @@ class Title { # Is it a redirect? $id = $nt->getArticleID(); - $obj = $dbw->selectRow( array( 'page', 'text') , - array( 'page_is_redirect','old_text' ), - array( 'page_id' => $id, 'page_latest=old_id' ), + $obj = $dbw->selectRow( array( 'page', 'revision', 'text'), + array( 'page_is_redirect','old_text' ), + array( 'page_id' => $id, 'page_latest=rev_id', 'rev_text_id=old_id' ), $fname, 'FOR UPDATE' ); if ( !$obj || 0 == $obj->page_is_redirect ) { diff --git a/maintenance/archives/patch-rev_text_id.sql b/maintenance/archives/patch-rev_text_id.sql new file mode 100644 index 0000000000..44ef438ce6 --- /dev/null +++ b/maintenance/archives/patch-rev_text_id.sql @@ -0,0 +1,17 @@ +-- +-- Adds rev_text_id field to revision table. +-- This is a key to text.old_id, so that revisions can be stored +-- for non-save operations without duplicating text, and so that +-- a back-end storage system can provide its own numbering system +-- if necessary. +-- +-- rev.rev_id and text.old_id are no longer assumed to be the same. +-- +-- 2005-03-28 +-- + +ALTER TABLE /*$wgDBprefix*/revision + ADD rev_text_id int(8) unsigned NOT NULL; + +UPDATE /*$wgDBprefix*/revision + SET rev_text_id=rev_id; diff --git a/maintenance/tables.sql b/maintenance/tables.sql index 4e0651f9d8..15cda2be92 100644 --- a/maintenance/tables.sql +++ b/maintenance/tables.sql @@ -64,6 +64,7 @@ CREATE TABLE /*$wgDBprefix*/page ( CREATE TABLE /*$wgDBprefix*/revision ( rev_id int(8) unsigned NOT NULL auto_increment, rev_page int(8) unsigned NOT NULL, + rev_text_id int(8) unsigned NOT NULL, rev_comment tinyblob NOT NULL default '', rev_user int(5) unsigned NOT NULL default '0', rev_user_text varchar(255) binary NOT NULL default '', diff --git a/maintenance/updaters.inc b/maintenance/updaters.inc index 6bd12a4fef..b388c3fdde 100644 --- a/maintenance/updaters.inc +++ b/maintenance/updaters.inc @@ -421,6 +421,18 @@ function do_inverse_timestamp() { } } +function do_text_id() { + global $wgDatabase; + if( $wgDatabase->fieldExists( 'revision', 'rev_text_id' ) ) { + echo "...rev_text_id already in place.\n"; + } else { + echo "Adding rev_text_id field... "; + dbsource( 'maintenance/archives/patch-rev_text_id.sql', $wgDatabase ); + echo "ok\n"; + } +} + + function do_all_updates() { global $wgNewTables, $wgNewFields; @@ -452,6 +464,7 @@ function do_all_updates() { do_schema_restructuring(); flush(); do_inverse_timestamp(); flush(); + do_text_id(); flush(); initialiseMessages(); flush(); }