X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Fexport%2FWikiExporter.php;h=6c7a449372513b156ddcebc1d1a5584a3510d6bb;hp=943aa045f9820c83e1fcb875def9f19dfc4b3f44;hb=a2c8c2969420a0f150c03f76e3a0bf9028fcda43;hpb=783e689d7d06ed4e5509c716a22e99769eee3e29 diff --git a/includes/export/WikiExporter.php b/includes/export/WikiExporter.php index 943aa045f9..6c7a449372 100644 --- a/includes/export/WikiExporter.php +++ b/includes/export/WikiExporter.php @@ -106,7 +106,7 @@ class WikiExporter { * various row objects and XML output for filtering. Filters * can be chained or used as callbacks. * - * @param DumpOutput $sink + * @param DumpOutput &$sink */ public function setOutputSink( &$sink ) { $this->sink =& $sink; @@ -227,15 +227,20 @@ class WikiExporter { $this->author_list = ""; // rev_deleted + $revQuery = Revision::getQueryInfo( [ 'page' ] ); $res = $this->db->select( - [ 'page', 'revision' ], - [ 'DISTINCT rev_user_text', 'rev_user' ], + $revQuery['tables'], + [ + 'rev_user_text' => $revQuery['fields']['rev_user_text'], + 'rev_user' => $revQuery['fields']['rev_user'], + ], [ $this->db->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0', $cond, - 'page_id = rev_id', ], - __METHOD__ + __METHOD__, + [ 'DISTINCT' ], + $revQuery['joins'] ); foreach ( $res as $row ) { @@ -253,13 +258,14 @@ class WikiExporter { /** * @param string $cond + * @param bool $orderRevs * @throws MWException * @throws Exception */ protected function dumpFrom( $cond = '', $orderRevs = false ) { # For logging dumps... if ( $this->history & self::LOGS ) { - $where = [ 'user_id = log_user' ]; + $where = []; # Hide private logs $hideLogs = LogEventsList::getExcludeClause( $this->db ); if ( $hideLogs ) { @@ -276,12 +282,20 @@ class WikiExporter { $prev = $this->db->bufferResults( false ); } $result = null; // Assuring $result is not undefined, if exception occurs early + + $commentQuery = CommentStore::getStore()->getJoin( 'log_comment' ); + $actorQuery = ActorMigration::newMigration()->getJoin( 'log_user' ); + try { - $result = $this->db->select( [ 'logging', 'user' ], - [ "{$logging}.*", 'user_name' ], // grab the user name + $result = $this->db->select( + array_merge( [ 'logging' ], $commentQuery['tables'], $actorQuery['tables'], [ 'user' ] ), + [ "{$logging}.*", 'user_name' ] + $commentQuery['fields'] + $actorQuery['fields'], $where, __METHOD__, - [ 'ORDER BY' => 'log_id', 'USE INDEX' => [ 'logging' => 'PRIMARY' ] ] + [ 'ORDER BY' => 'log_id', 'USE INDEX' => [ 'logging' => 'PRIMARY' ] ], + [ + 'user' => [ 'JOIN', 'user_id = ' . $actorQuery['fields']['log_user'] ] + ] + $commentQuery['joins'] + $actorQuery['joins'] ); $this->outputLogStream( $result ); if ( $this->buffer == self::STREAM ) { @@ -316,13 +330,29 @@ class WikiExporter { } # For page dumps... } else { - $tables = [ 'page', 'revision' ]; + $revOpts = [ 'page' ]; + if ( $this->text != self::STUB ) { + $revOpts[] = 'text'; + } + $revQuery = Revision::getQueryInfo( $revOpts ); + + // We want page primary rather than revision + $tables = array_merge( [ 'page' ], array_diff( $revQuery['tables'], [ 'page' ] ) ); + $join = $revQuery['joins'] + [ + 'revision' => $revQuery['joins']['page'] + ]; + unset( $join['page'] ); + + $fields = array_merge( $revQuery['fields'], [ 'page_restrictions' ] ); + + $conds = []; + if ( $cond !== '' ) { + $conds[] = $cond; + } $opts = [ 'ORDER BY' => 'page_id ASC' ]; $opts['USE INDEX'] = []; - $join = []; if ( is_array( $this->history ) ) { # Time offset/limit for all pages/history... - $revJoin = 'page_id=rev_page'; # Set time order if ( $this->history['dir'] == 'asc' ) { $op = '>'; @@ -333,10 +363,9 @@ class WikiExporter { } # Set offset if ( !empty( $this->history['offset'] ) ) { - $revJoin .= " AND rev_timestamp $op " . + $conds[] = "rev_timestamp $op " . $this->db->addQuotes( $this->db->timestamp( $this->history['offset'] ) ); } - $join['revision'] = [ 'INNER JOIN', $revJoin ]; # Set query limit if ( !empty( $this->history['limit'] ) ) { $opts['LIMIT'] = intval( $this->history['limit'] ); @@ -345,13 +374,11 @@ class WikiExporter { # Full history dumps... # query optimization for history stub dumps if ( $this->text == self::STUB && $orderRevs ) { - $tables = [ 'revision', 'page' ]; - $opts[] = 'STRAIGHT_JOIN'; + $tables = $revQuery['tables']; $opts['ORDER BY'] = [ 'rev_page ASC', 'rev_id ASC' ]; $opts['USE INDEX']['revision'] = 'rev_page_id'; + unset( $join['revision'] ); $join['page'] = [ 'INNER JOIN', 'rev_page=page_id' ]; - } else { - $join['revision'] = [ 'INNER JOIN', 'page_id=rev_page' ]; } } elseif ( $this->history & self::CURRENT ) { # Latest revision dumps... @@ -369,22 +396,11 @@ class WikiExporter { } } elseif ( $this->history & self::RANGE ) { # Dump of revisions within a specified range - $join['revision'] = [ 'INNER JOIN', 'page_id=rev_page' ]; $opts['ORDER BY'] = [ 'rev_page ASC', 'rev_id ASC' ]; } else { # Unknown history specification parameter? throw new MWException( __METHOD__ . " given invalid history dump type." ); } - # Query optimization hacks - if ( $cond == '' ) { - $opts[] = 'STRAIGHT_JOIN'; - $opts['USE INDEX']['page'] = 'PRIMARY'; - } - # Build text join options - if ( $this->text != self::STUB ) { // 1-pass - $tables[] = 'text'; - $join['text'] = [ 'INNER JOIN', 'rev_text_id=old_id' ]; - } if ( $this->buffer == self::STREAM ) { $prev = $this->db->bufferResults( false ); @@ -395,7 +411,14 @@ class WikiExporter { [ $this->db, &$tables, &$cond, &$opts, &$join ] ); # Do the query! - $result = $this->db->select( $tables, '*', $cond, __METHOD__, $opts, $join ); + $result = $this->db->select( + $tables, + $fields, + $conds, + __METHOD__, + $opts, + $join + ); # Output dump results $this->outputPageStream( $result );