From: Brion Vibber Date: Sun, 1 May 2005 08:07:25 +0000 (+0000) Subject: * (bug 2018) Fix deletion for new schema, make work on MySQL 3 again X-Git-Tag: 1.5.0alpha1~42 X-Git-Url: https://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/exercices/bilan.php?a=commitdiff_plain;h=c1ac86e5600e3334d8c0de30ad41cbd3db9f23dc;p=lhc%2Fweb%2Fwiklou.git * (bug 2018) Fix deletion for new schema, make work on MySQL 3 again The archive table now has an ar_text_id field which points at the text record containing the deleted revision's text. Older archive records containing self-contained text are still supported and will be restored by adding a new revision. For now, revision and page records are still removed on deletion, but text records are left intact. This will keep block compression and immutable alternate storage backends working relatively cleanly. A rev_deleted flag field is reserved in revision for further future changes but that won't happen in the 1.5 timeframe. There is no longer a delete-on-join which was present in earlier 1.5 revisions, so deletion should work on MySQL 3.x again. --- diff --git a/includes/Article.php b/includes/Article.php index 2012d7fe23..df050746d7 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -1727,33 +1727,39 @@ class Article { # Client and file cache invalidation Title::touchArray( $linksTo ); - # Move article and history to the "archive" table - $dbw->insertSelect( 'archive', array( 'page','revision', 'text' ), + // For now, shunt the revision data into the archive table. + // Text is *not* removed from the text table; bulk storage + // is left intact to avoid breaking block-compression or + // immutable storage schemes. + // + // For backwards compatibility, note that some older archive + // table entries will have ar_text and ar_flags fields still. + // + // In the future, we may keep revisions and mark them with + // the rev_deleted field, which is reserved for this purpose. + $dbw->insertSelect( 'archive', array( 'page', 'revision' ), array( 'ar_namespace' => 'page_namespace', 'ar_title' => 'page_title', - 'ar_text' => 'old_text', 'ar_comment' => 'rev_comment', 'ar_user' => 'rev_user', 'ar_user_text' => 'rev_user_text', 'ar_timestamp' => 'rev_timestamp', 'ar_minor_edit' => 'rev_minor_edit', - 'ar_flags' => 'old_flags', 'ar_rev_id' => 'rev_id', + 'ar_text_id' => 'rev_text_id', ), array( - 'page_namespace' => $ns, - 'page_title' => $t, - 'page_id = rev_page AND old_id = rev_id' + 'page_id' => $id, + 'page_id = rev_page' ), $fname ); - + # Now that it's safely backed up, delete it - - $dbw->deleteJoin( 'text', 'revision', 'old_id', 'rev_id', array( "rev_page = {$id}" ), $fname ); $dbw->delete( 'revision', array( 'rev_page' => $id ), $fname ); $dbw->delete( 'page', array( 'page_id' => $id ), $fname); - + + # Clean up recentchanges entries... $dbw->delete( 'recentchanges', array( 'rc_namespace' => $ns, 'rc_title' => $t ), $fname ); # Finally, clean up the link tables diff --git a/includes/SpecialUndelete.php b/includes/SpecialUndelete.php index ab078d2864..dd6262a85a 100644 --- a/includes/SpecialUndelete.php +++ b/includes/SpecialUndelete.php @@ -73,13 +73,26 @@ class PageArchive { * @return string */ function getRevisionText( $timestamp ) { + $fname = 'PageArchive::getRevisionText'; $dbr =& wfGetDB( DB_SLAVE ); $row = $dbr->selectRow( 'archive', - array( 'ar_text', 'ar_flags' ), + array( 'ar_text', 'ar_flags', 'ar_text_id' ), array( 'ar_namespace' => $this->title->getNamespace(), 'ar_title' => $this->title->getDbkey(), - 'ar_timestamp' => $dbr->timestamp( $timestamp ) ) ); - return Revision::getRevisionText( $row, "ar_" ); + 'ar_timestamp' => $dbr->timestamp( $timestamp ) ), + $fname ); + if( is_null( $row->ar_text_id ) ) { + // An old row from MediaWiki 1.4 or previous. + // Text is embedded in this row in classic compression format. + return Revision::getRevisionText( $row, "ar_" ); + } else { + // New-style: keyed to the text storage backend. + $text = $dbr->selectRow( 'text', + array( 'old_text', 'old_flags' ), + array( 'old_id' => $row->ar_text_id ), + $fname ); + return Revision::getRevisionText( $text ); + } } /** @@ -189,7 +202,8 @@ class PageArchive { 'ar_user_text', 'ar_timestamp', 'ar_minor_edit', - 'ar_flags' ), + 'ar_flags', + 'ar_text_id' ), /* WHERE */ array( 'ar_namespace' => $this->title->getNamespace(), 'ar_title' => $this->title->getDBkey(), @@ -209,6 +223,7 @@ class PageArchive { 'user_text' => $row->ar_user_text, 'timestamp' => $row->ar_timestamp, 'minor_edit' => $row->ar_minor_edit, + 'text_id' => $row->ar_text_id, ) ); $revision->insertOn( $dbw ); } diff --git a/maintenance/archives/patch-archive-text_id.sql b/maintenance/archives/patch-archive-text_id.sql new file mode 100644 index 0000000000..f59715ff7b --- /dev/null +++ b/maintenance/archives/patch-archive-text_id.sql @@ -0,0 +1,14 @@ +-- New field in archive table to preserve text source IDs across undeletion. +-- +-- Older entries containing NULL in this field will contain text in the +-- ar_text and ar_flags fields, and will cause the (re)creation of a new +-- text record upon undeletion. +-- +-- Newer ones will reference a text.old_id with this field, and the existing +-- entries will be used as-is; only a revision record need be created. +-- +-- Added 2005-05-01 + +ALTER TABLE /*$wgDBprefix*/archive + ADD + ar_text_id int(8) unsigned; diff --git a/maintenance/tables.sql b/maintenance/tables.sql index 114549ab4e..0d5da0deb2 100644 --- a/maintenance/tables.sql +++ b/maintenance/tables.sql @@ -108,6 +108,7 @@ CREATE TABLE /*$wgDBprefix*/archive ( ar_minor_edit tinyint(1) NOT NULL default '0', ar_flags tinyblob NOT NULL default '', ar_rev_id int(8) unsigned, + ar_text_id int(8) unsigned, KEY name_title_timestamp (ar_namespace,ar_title,ar_timestamp) ); diff --git a/maintenance/updaters.inc b/maintenance/updaters.inc index 27f9f2d2bf..48b70d1431 100644 --- a/maintenance/updaters.inc +++ b/maintenance/updaters.inc @@ -36,6 +36,7 @@ $wgNewFields = array( array( 'group', 'group_rights', 'patch-userlevels-rights.sql' ), array( 'logging', 'log_params', 'patch-log_params.sql' ), array( 'archive', 'ar_rev_id', 'patch-archive-rev_id.sql' ), + array( 'archive', 'ar_text_id', 'patch-archive-text_id.sql' ), array( 'page', 'page_len', 'patch-page_len.sql' ), array( 'revision', 'rev_deleted', 'patch-rev_deleted.sql' ), array( 'image', 'img_width', 'patch-img_width.sql' ),