Lazy loading of revision text; needed for separate text storage backend.
authorBrion Vibber <brion@users.mediawiki.org>
Fri, 18 Mar 2005 04:32:55 +0000 (04:32 +0000)
committerBrion Vibber <brion@users.mediawiki.org>
Fri, 18 Mar 2005 04:32:55 +0000 (04:32 +0000)
Use Revision for Article::loadLastEdit

includes/Article.php
includes/Group.php
includes/Revision.php
includes/SpecialExport.php

index e68a889..7dd7584 100644 (file)
@@ -501,7 +501,7 @@ class Article {
         */
        function loadLastEdit() {
                global $wgOut;
-
+               
                if ( -1 != $this->mUser )
                        return;
 
@@ -509,19 +509,13 @@ class Article {
                $id = $this->getID();
                if ( 0 == $id ) return;
 
-               $fname = 'Article::loadLastEdit';
-
-               $dbr =& $this->getDB();
-               $s = $dbr->selectRow( array( 'revision', 'page') ,
-                 array( 'rev_user','rev_user_text','rev_timestamp', 'rev_comment','rev_minor_edit' ),
-                 array( 'page_id' => $id, 'page_latest=rev_id' ), $fname, $this->getSelectOptions() );
-
-               if ( $s !== false ) {
-                       $this->mUser = $s->rev_user;
-                       $this->mUserText = $s->rev_user_text;
-                       $this->mTimestamp = wfTimestamp(TS_MW,$s->rev_timestamp);
-                       $this->mComment = $s->rev_comment;
-                       $this->mMinorEdit = $s->rev_minor_edit;
+               $this->mLastRevision = Revision::loadFromPageId( $this->getDB(), $id );
+               if( !is_null( $this->mLastRevision ) ) {
+                       $this->mUser      = $this->mLastRevision->getUser();
+                       $this->mUserText  = $this->mLastRevision->getUserText();
+                       $this->mTimestamp = $this->mLastRevision->getTimestamp();
+                       $this->mComment   = $this->mLastRevision->getComment();
+                       $this->mMinorEdit = $this->mLastRevision->isMinor();
                }
        }
 
index 1502eab..88b5166 100644 (file)
@@ -50,7 +50,10 @@ class Group {
                
                if($this->id) {
                        $dbr =& wfGetDB( DB_SLAVE );
-                       $r = $dbr->selectRow('group', array('group_id', 'group_name', 'group_description', 'group_rights'), array( 'group_id' => $this->id ), $fname );
+                       $r = $dbr->selectRow('group',
+                               array('group_id', 'group_name', 'group_description', 'group_rights'),
+                               array( 'group_id' => $this->id ),
+                               $fname );
                        $this->id = $r->group_id;
                        $this->name = $r->group_name;
                        $this->description = $r->group_description;
@@ -58,7 +61,10 @@ class Group {
                        $this->dataLoaded = true;
                } else {
                        $dbr =& wfGetDB( DB_SLAVE );
-                       $r = $dbr->selectRow('group', array('group_id', 'group_name', 'group_description', 'group_rights'), array( 'group_name' => $this->name ), $fname );
+                       $r = $dbr->selectRow('group',
+                               array('group_id', 'group_name', 'group_description', 'group_rights'),
+                               array( 'group_name' => $this->name ),
+                               $fname );
                        $this->id = $r->group_id;
                        $this->name = $r->group_name;
                        $this->description = $r->group_description;
@@ -100,14 +106,37 @@ class Group {
        }
        
 // Factories
-       /** @param integer $id Group database id */
+       /**
+        * Uses Memcached if available.
+        * @param integer $id Group database id
+        */
        function newFromId($id) {
+               global $wgMemc, $wgDBname;
                $fname = 'Group::newFromId';
+               
+               $key = "$wgDBname:groups:id:$id";
+               if( $group = $wgMemc->get( $key ) ) {
+                       wfDebug( "$fname loaded group $id from cache\n" );
+                       return $group;
+               }
+               
                $g = new Group();
                $name = $g->nameFromId(IntVal($id));
 
-               if($name == '') { return; }
-               else { return $g->newFromName($name); }
+               if($name == '') {
+                       wfDebug( "$fname can't find group $id\n" );
+                       return null;
+               } else {
+                       $group = $g->newFromName($name);
+                       if( $group ) {
+                               wfDebug( "$fname caching group $id (name $name)\n" );
+                               $group->loadFromDatabase();
+                               $wgMemc->add( $key, $group, 3600 );
+                       } else {
+                               wfDebug( "$fname failed to laod group id $d (name $name)\n" );
+                       }
+                       return $group;
+               }
        }
 
 
index 6b099ff..fc9e8d3 100644 (file)
@@ -24,8 +24,7 @@ class Revision {
        function &newFromId( $id ) {
                return Revision::newFromConds(
                        array( 'page_id=rev_page',
-                              'rev_id' => IntVal( $id ),
-                              'rev_id=old_id' ) );
+                              'rev_id' => IntVal( $id ) ) );
        }
        
        /**
@@ -48,8 +47,31 @@ class Revision {
                        array( "rev_id=$matchId",
                               'page_id=rev_page',
                               'page_namespace' => $title->getNamespace(),
-                              'page_title'     => $title->getDbkey(),
-                              'rev_id=old_id' ) );
+                              'page_title'     => $title->getDbkey() ) );
+       }
+       
+       /**
+        * Load either the current, or a specified, revision
+        * that's attached to a given page. If not attached
+        * to that page, will return null.
+        *
+        * @param Database $db
+        * @param int $pageid
+        * @param int $id
+        * @return Revision
+        * @access public
+        */
+       function &loadFromPageId( &$db, $pageid, $id = 0 ) {
+               if( $id ) {
+                       $matchId = IntVal( $id );
+               } else {
+                       $matchId = 'page_latest';
+               }
+               return Revision::loadFromConds(
+                       $db,
+                       array( "rev_id=$matchId",
+                              'rev_page' => IntVal( $pageid ),
+                              'page_id=rev_page' ) );
        }
        
        /**
@@ -61,7 +83,22 @@ class Revision {
         * @access private
         */
        function &newFromConds( $conditions ) {
-               $res =& Revision::fetchFromConds( $conditions );
+               $db =& wfGetDB( DB_SLAVE );
+               return Revision::loadFromConds( $db, $conditions );
+       }
+       
+       /**
+        * Given a set of conditions, fetch a revision from
+        * the given database connection.
+        *
+        * @param Database $db
+        * @param array $conditions
+        * @return Revision
+        * @static
+        * @access private
+        */
+       function &loadFromConds( &$db, $conditions ) {
+               $res =& Revision::fetchFromConds( $db, $conditions );
                if( $res ) {
                        $row = $res->fetchObject();
                        $res->free();
@@ -84,10 +121,10 @@ class Revision {
         */
        function &fetchAllRevisions( &$title ) {
                return Revision::fetchFromConds(
+                       wfGetDB( DB_SLAVE ),
                        array( 'page_namespace' => $title->getNamespace(),
                               'page_title'     => $title->getDbkey(),
-                              'page_id=rev_page',
-                              'rev_id=old_id' ) );             
+                              'page_id=rev_page' ) );          
        }
        
        /**
@@ -102,26 +139,27 @@ class Revision {
         */
        function &fetchRevision( &$title ) {
                return Revision::fetchFromConds(
+                       wfGetDB( DB_SLAVE ),
                        array( 'rev_id=page_latest',
                               'page_namespace' => $title->getNamespace(),
                               'page_title'     => $title->getDbkey(),
-                              'page_id=rev_page',
-                              'rev_id=old_id' ) );             
+                              'page_id=rev_page' ) );          
        }
-               /**
+       
+       /**
         * Given a set of conditions, return a ResultWrapper
         * which will return matching database rows with the
         * fields necessary to build Revision objects.
         *
+        * @param Database $db
         * @param array $conditions
         * @return ResultWrapper
         * @static
         * @access private
         */
-       function &fetchFromConds( $conditions ) {
-               $dbr =& wfGetDB( DB_SLAVE );
-               $res = $dbr->select(
-                       array( 'page', 'revision', 'text' ),
+       function &fetchFromConds( &$db, $conditions ) {
+               $res = $db->select(
+                       array( 'page', 'revision' ),
                        array( 'page_namespace',
                               'page_title',
                               'page_latest',
@@ -131,12 +169,10 @@ class Revision {
                               'rev_user_text',
                               'rev_user',
                               'rev_minor_edit',
-                              'rev_timestamp',
-                              'old_flags',
-                              'old_text' ),
+                              'rev_timestamp' ),
                        $conditions,
                        'Revision::fetchRow' );
-               return $dbr->resultObject( $res );
+               return $db->resultObject( $res );
        }
        
        /**
@@ -156,7 +192,12 @@ class Revision {
                        $this->mCurrent   = ( $row->rev_id == $row->page_latest );
                        $this->mTitle     = Title::makeTitle( $row->page_namespace,
                                                              $row->page_title );
-                       $this->mText      = $this->getRevisionText( $row );
+                       
+                       if( isset( $row->old_text ) ) {
+                               $this->mText  = $this->getRevisionText( $row );
+                       } else {
+                               $this->mText  = null;
+                       }
                } elseif( is_array( $row ) ) {
                        // Build a new revision to be saved...
                        global $wgUser;
@@ -168,7 +209,7 @@ class Revision {
                        $this->mUser      = isset( $row['user']       ) ? IntVal( $row['user']       ) : $wgUser->getId();
                        $this->mMinorEdit = isset( $row['minor_edit'] ) ? IntVal( $row['minor_edit'] ) : 0;
                        $this->mTimestamp = isset( $row['timestamp']  ) ? StrVal( $row['timestamp']  ) : wfTimestamp( TS_MW );
-                       $this->mText      = isset( $row['text']       ) ? StrVal( $row['text']       ) : '';
+                       $this->mText      = isset( $row['text']       ) ? StrVal( $row['text']       ) : null;
                        
                        $this->mTitle     = null; # Load on demand if needed
                        $this->mCurrent   = false;
@@ -249,6 +290,10 @@ class Revision {
         * @return string
         */
        function getText() {
+               if( is_null( $this->mText ) ) {
+                       // Revision text is immutable. Load on demand:
+                       $this->mText = $this->loadText();
+               }
                return $this->mText;
        }
        
@@ -393,8 +438,8 @@ class Revision {
                        : $dbw->nextSequenceValue( 'text_old_id_val' );
                $dbw->insert( 'text',
                        array(
-                               'old_id' => $old_id,
-                               'old_text' => $mungedText,
+                               'old_id'    => $old_id,
+                               'old_text'  => $mungedText,
                                'old_flags' => $flags,
                        ), $fname
                );
@@ -418,5 +463,28 @@ class Revision {
                wfProfileOut( $fname );
                return $revisionId;
        }
+       
+       /**
+        * Lazy-load the revision's text.
+        * Currently hardcoded to the 'text' table storage engine.
+        *
+        * @return string
+        * @access private
+        */
+       function loadText() {
+               $fname = 'Revision::loadText';
+               wfProfileIn( $fname );
+               
+               $dbr =& wfGetDB( DB_SLAVE );
+               $row = $dbr->selectRow( 'text',
+                       array( 'old_text', 'old_flags' ),
+                       array( 'old_id' => $this->getId() ),
+                       $fname);
+               
+               $text = Revision::getRevisionText( $row );
+               wfProfileOut( $fname );
+               
+               return $text;
+       }
 }
 ?>
\ No newline at end of file
index 2dd079f..1101e4f 100644 (file)
@@ -50,7 +50,7 @@ function wfSpecialExport( $page = '' ) {
        
        $wgOut->addWikiText( wfMsg( "exporttext" ) );
        $titleObj = Title::makeTitle( NS_SPECIAL, "Export" );
-       $action = $titleObj->escapeLocalURL();
+       $action = $titleObj->escapeLocalURL( 'action=submit' );
        $wgOut->addHTML( "
 <form method='post' action=\"$action\">
 <input type='hidden' name='action' value='submit' />