* @param int $buffer One of WikiExporter::BUFFER or WikiExporter::STREAM
* @param int $text One of WikiExporter::TEXT or WikiExporter::STUB
*/
- function __construct( $db, $history = WikiExporter::CURRENT,
- $buffer = WikiExporter::BUFFER, $text = WikiExporter::TEXT ) {
+ function __construct( $db, $history = self::CURRENT,
+ $buffer = self::BUFFER, $text = self::TEXT ) {
$this->db = $db;
$this->history = $history;
$this->buffer = $buffer;
* 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;
$this->author_list = "<contributors>";
// 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 ) {
/**
* @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 ) {
# Get logging table name for logging.* clause
$logging = $this->db->tableName( 'logging' );
- if ( $this->buffer == WikiExporter::STREAM ) {
+ if ( $this->buffer == self::STREAM ) {
$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 == WikiExporter::STREAM ) {
+ if ( $this->buffer == self::STREAM ) {
$this->db->bufferResults( $prev );
}
} catch ( Exception $e ) {
// Putting database back in previous buffer mode
try {
- if ( $this->buffer == WikiExporter::STREAM ) {
+ if ( $this->buffer == self::STREAM ) {
$this->db->bufferResults( $prev );
}
} catch ( Exception $e2 ) {
}
# 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 = '>';
}
# 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'] );
}
- } elseif ( $this->history & WikiExporter::FULL ) {
+ } elseif ( $this->history & self::FULL ) {
# Full history dumps...
# query optimization for history stub dumps
- if ( $this->text == WikiExporter::STUB && $orderRevs ) {
- $tables = [ 'revision', 'page' ];
- $opts[] = 'STRAIGHT_JOIN';
+ if ( $this->text == self::STUB && $orderRevs ) {
+ $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 & WikiExporter::CURRENT ) {
+ } elseif ( $this->history & self::CURRENT ) {
# Latest revision dumps...
if ( $this->list_authors && $cond != '' ) { // List authors, if so desired
$this->do_list_authors( $cond );
}
$join['revision'] = [ 'INNER JOIN', 'page_id=rev_page AND page_latest=rev_id' ];
- } elseif ( $this->history & WikiExporter::STABLE ) {
+ } elseif ( $this->history & self::STABLE ) {
# "Stable" revision dumps...
# Default JOIN, to be overridden...
$join['revision'] = [ 'INNER JOIN', 'page_id=rev_page AND page_latest=rev_id' ];
if ( Hooks::run( 'WikiExporter::dumpStableQuery', [ &$tables, &$opts, &$join ] ) ) {
throw new MWException( __METHOD__ . " given invalid history dump type." );
}
- } elseif ( $this->history & WikiExporter::RANGE ) {
+ } 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 != WikiExporter::STUB ) { // 1-pass
- $tables[] = 'text';
- $join['text'] = [ 'INNER JOIN', 'rev_text_id=old_id' ];
- }
- if ( $this->buffer == WikiExporter::STREAM ) {
+ if ( $this->buffer == self::STREAM ) {
$prev = $this->db->bufferResults( false );
}
$result = null; // Assuring $result is not undefined, if exception occurs early
[ $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 );
- if ( $this->buffer == WikiExporter::STREAM ) {
+ if ( $this->buffer == self::STREAM ) {
$this->db->bufferResults( $prev );
}
} catch ( Exception $e ) {
// Putting database back in previous buffer mode
try {
- if ( $this->buffer == WikiExporter::STREAM ) {
+ if ( $this->buffer == self::STREAM ) {
$this->db->bufferResults( $prev );
}
} catch ( Exception $e2 ) {