Index: branches/snapshot-work/maintenance/tables.sql |
— | — | @@ -1009,4 +1009,56 @@ |
1010 | 1010 | |
1011 | 1011 | ) TYPE=InnoDB; |
1012 | 1012 | |
| 1013 | +-- Information on tagged page revisions |
| 1014 | +CREATE TABLE /*$wgDBprefix*/snapshot ( |
| 1015 | + -- Unique id of snapshot state |
| 1016 | + snap_id INT auto_increment PRIMARY KEY, |
| 1017 | + |
| 1018 | + -- Key to page_id of the page being tagged |
| 1019 | + snap_page INT, |
| 1020 | + |
| 1021 | + -- Tag identifier; machine-readable such as "reviewed" |
| 1022 | + -- There may be multiple versions with a given tag on a given page, |
| 1023 | + -- for updatable states where the latest with a given tag will be shown. |
| 1024 | + snap_tag VARCHAR(16) BINARY, |
| 1025 | + |
| 1026 | + -- Time at which the thingy was snapped |
| 1027 | + snap_timestamp CHAR(14) BINARY, |
| 1028 | + |
| 1029 | + -- Key to user_id of tagger |
| 1030 | + snap_user INT, |
| 1031 | + |
| 1032 | + -- Allow lookup of the latest given tag |
| 1033 | + KEY (snap_page, snap_tag, snap_timestamp), |
| 1034 | + |
| 1035 | + -- Allow lookup of tags by a given user |
| 1036 | + KEY (snap_user, snap_timestamp), |
| 1037 | + |
| 1038 | +) TYPE=InnoDB; |
| 1039 | + |
| 1040 | +-- Stores the revision number of each resource on a page state snapshot |
| 1041 | +-- Includes the primary page and all its included templates. |
| 1042 | +-- This allows a stable page snapshot to avoid sucking in vandalized templates. |
| 1043 | +-- Currently does not apply to image & media versions; when that's handled more |
| 1044 | +-- cleanly another table perhaps will have to be added. |
| 1045 | +CREATE TABLE /*$wgDBprefix*/snapshot_revs ( |
| 1046 | + -- Key to snap_id |
| 1047 | + sr_snap INT, |
| 1048 | + |
| 1049 | + -- Key to page_namespace, page_title |
| 1050 | + sr_namespace INT, |
| 1051 | + sr_title VARCHAR(255) BINARY, |
| 1052 | + |
| 1053 | + -- Key to rev_id |
| 1054 | + sr_rev INT, |
| 1055 | + |
| 1056 | + -- Main key for grabbing data |
| 1057 | + KEY (sr_snap) |
| 1058 | + |
| 1059 | + -- Allow lookup by page to clear caches on deletion... ? |
| 1060 | + -- Allow lookup by revision to clear caches on deletion... ? |
| 1061 | + |
| 1062 | +) TYPE=InnoDB; |
| 1063 | + |
| 1064 | + |
1013 | 1065 | -- vim: sw=2 sts=2 et |
Index: branches/snapshot-work/includes/Parser.php |
— | — | @@ -11,7 +11,7 @@ |
12 | 12 | * changes in an incompatible way, so the parser cache |
13 | 13 | * can automatically discard old data. |
14 | 14 | */ |
15 | | -define( 'MW_PARSER_VERSION', '1.6.1' ); |
| 15 | +define( 'MW_PARSER_VERSION', '1.8alpha' ); |
16 | 16 | |
17 | 17 | /** |
18 | 18 | * Variable substitution O(N^2) attack |
— | — | @@ -210,6 +210,7 @@ |
211 | 211 | 'titles' => array() |
212 | 212 | ); |
213 | 213 | $this->mRevisionId = null; |
| 214 | + $this->mSnapshot = new Snapshot(); |
214 | 215 | |
215 | 216 | /** |
216 | 217 | * Prefix for temporary replacement strings for the multipass parser. |
— | — | @@ -250,9 +251,10 @@ |
251 | 252 | * @param boolean $linestart |
252 | 253 | * @param boolean $clearState |
253 | 254 | * @param int $revid number to pass in {{REVISIONID}} |
| 255 | + * @param Snapshot $snapshot <- this is a damn dirty hack, fix up this interface it's awful |
254 | 256 | * @return ParserOutput a ParserOutput |
255 | 257 | */ |
256 | | - function parse( $text, &$title, $options, $linestart = true, $clearState = true, $revid = null ) { |
| 258 | + function parse( $text, &$title, $options, $linestart = true, $clearState = true, $revid = null, $snapshot = null ) { |
257 | 259 | /** |
258 | 260 | * First pass--just handle <nowiki> sections, pass the rest off |
259 | 261 | * to internalParse() which does all the real work. |
— | — | @@ -268,7 +270,14 @@ |
269 | 271 | |
270 | 272 | $this->mOptions = $options; |
271 | 273 | $this->mTitle =& $title; |
272 | | - $this->mRevisionId = $revid; |
| 274 | + |
| 275 | + if( $revid != null ) { |
| 276 | + $this->mRevisionId = $revid; |
| 277 | + } |
| 278 | + if( $snapshot != null ) { |
| 279 | + $this->mSnapshot = $snapshot; |
| 280 | + } |
| 281 | + |
273 | 282 | $this->mOutputType = OT_HTML; |
274 | 283 | |
275 | 284 | //$text = $this->strip( $text, $this->mStripState ); |
— | — | @@ -2993,11 +3002,13 @@ |
2994 | 3003 | $text = false; |
2995 | 3004 | // Loop to fetch the article, with up to 1 redirect |
2996 | 3005 | for ( $i = 0; $i < 2 && is_object( $title ); $i++ ) { |
2997 | | - $rev = Revision::newFromTitle( $title ); |
| 3006 | + $rev = Revision::newFromTitle( $title, |
| 3007 | + $this->mSnapshot->getPageRevision( $title ) ); |
2998 | 3008 | $this->mOutput->addTemplate( $title, $title->getArticleID() ); |
2999 | 3009 | if ( !$rev ) { |
3000 | 3010 | break; |
3001 | 3011 | } |
| 3012 | + $this->mOutput->addSnapshotPage( $title, $rev->getId() ); |
3002 | 3013 | $text = $rev->getText(); |
3003 | 3014 | if ( $text === false ) { |
3004 | 3015 | break; |
— | — | @@ -4422,6 +4433,7 @@ |
4423 | 4434 | $this->mSubtitle = "" ; |
4424 | 4435 | $this->mNewSection = false; |
4425 | 4436 | $this->mNoGallery = false; |
| 4437 | + $this->mSnapshot = new Snapshot(); |
4426 | 4438 | } |
4427 | 4439 | |
4428 | 4440 | function getText() { return $this->mText; } |
— | — | @@ -4435,6 +4447,7 @@ |
4436 | 4448 | function &getImages() { return $this->mImages; } |
4437 | 4449 | function &getExternalLinks() { return $this->mExternalLinks; } |
4438 | 4450 | function getNoGallery() { return $this->mNoGallery; } |
| 4451 | + function getSnapshot() { return clone( $this->mSnapshot ); } |
4439 | 4452 | |
4440 | 4453 | function containsOldMagic() { return $this->mContainsOldMagic; } |
4441 | 4454 | function setText( $text ) { return wfSetVar( $this->mText, $text ); } |
— | — | @@ -4473,6 +4486,10 @@ |
4474 | 4487 | } |
4475 | 4488 | $this->mTemplates[$ns][$dbk] = $id; |
4476 | 4489 | } |
| 4490 | + |
| 4491 | + function addSnapshotPage( $title, $rev ) { |
| 4492 | + $this->mSnapshot->addPage( $title, $rev ); |
| 4493 | + } |
4477 | 4494 | |
4478 | 4495 | /** |
4479 | 4496 | * Return true if this cached output object predates the global or |
Index: branches/snapshot-work/includes/AutoLoader.php |
— | — | @@ -146,6 +146,7 @@ |
147 | 147 | 'MediaWiki_I18N' => 'includes/SkinTemplate.php', |
148 | 148 | 'SkinTemplate' => 'includes/SkinTemplate.php', |
149 | 149 | 'QuickTemplate' => 'includes/SkinTemplate.php', |
| 150 | + 'Snapshot' => 'includes/Snapshot.php', |
150 | 151 | 'SpecialAllpages' => 'includes/SpecialAllpages.php', |
151 | 152 | 'AncientPagesPage' => 'includes/SpecialAncientpages.php', |
152 | 153 | 'IPBlockForm' => 'includes/SpecialBlockip.php', |
Index: branches/snapshot-work/includes/Snapshot.php |
— | — | @@ -0,0 +1,83 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class Snapshot { |
| 5 | + function __construct() { |
| 6 | + $this->mRevs = array(); |
| 7 | + } |
| 8 | + |
| 9 | + /** |
| 10 | + * Get the revision number for a given page resource as embedded |
| 11 | + * in the snapshot. Note that this particular revision may no |
| 12 | + * longer exist, for instance if the referred page has been |
| 13 | + * deleted. |
| 14 | + * |
| 15 | + * Will return 0 for resources not listed in the snapshot; this |
| 16 | + * usually will allow for loading the current version. |
| 17 | + * |
| 18 | + * @param Title $title |
| 19 | + * @return int |
| 20 | + */ |
| 21 | + public function getPageRevision( $title ) { |
| 22 | + $key = $title->getPrefixedDbKey(); |
| 23 | + if( isset( $this->mRevs[$key] ) ) { |
| 24 | + return $this->mRevs[$key]; |
| 25 | + } |
| 26 | + return 0; |
| 27 | + } |
| 28 | + |
| 29 | + /** |
| 30 | + * Load a particular snapshot out of the database. |
| 31 | + */ |
| 32 | + public static function newFromId( $snapId ) { |
| 33 | + return Snapshot::fetchBy( |
| 34 | + array( 'snap_id' => $snapId ) ); |
| 35 | + } |
| 36 | + |
| 37 | + /** |
| 38 | + * Load the most recent snapshot with a given tag name on this page. |
| 39 | + * @return Snapshot or null if no snapshot exists |
| 40 | + */ |
| 41 | + public static function newFromTag( $pageId, $tag ) { |
| 42 | + return Snapshot::fetchBy( |
| 43 | + array( |
| 44 | + 'snap_page' => $pageId, |
| 45 | + 'snap_tag' => $tag |
| 46 | + ), |
| 47 | + array( 'ORDER BY' => 'snap_timestamp DESC' ) ); |
| 48 | + } |
| 49 | + |
| 50 | + |
| 51 | + /** |
| 52 | + * Load a Snapshot object from a particluar snapshot ID |
| 53 | + */ |
| 54 | + private static function fetchBy( $where, $options ) { |
| 55 | + $dbr = wfGetDB( DB_SLAVE ); |
| 56 | + $revs = Snapshot::loadFromId( $dbr, $id ); |
| 57 | + |
| 58 | + if( !$revs ) { |
| 59 | + $dbw = wfGetDB( DB_MASTER ); |
| 60 | + $revs = Snapshot::loadFromId( $dbw, $id ); |
| 61 | + } |
| 62 | + |
| 63 | + $this->mRevs = $revs; |
| 64 | + } |
| 65 | + |
| 66 | + private static function loadFromId( $db, $id ) { |
| 67 | + $result = $db->select( 'snapshot_revs', |
| 68 | + array( 'sr_namespace', 'sr_title', 'sr_rev' ), |
| 69 | + array( 'sr_snap' => $id ), |
| 70 | + __METHOD__ ); |
| 71 | + |
| 72 | + $revs = array(); |
| 73 | + while( $row = $db->fetchObject( $result ) ) { |
| 74 | + $title = Title::makeTitle( $row->sr_namespace, $row->sr_title ); |
| 75 | + $key = $title->getPrefixedDbKey(); |
| 76 | + $revs[$key] = $row->sr_rev; |
| 77 | + } |
| 78 | + |
| 79 | + $db->freeResult( $result ); |
| 80 | + return $revs; |
| 81 | + } |
| 82 | +} |
| 83 | + |
| 84 | +?> |
\ No newline at end of file |
Property changes on: branches/snapshot-work/includes/Snapshot.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 85 | + native |