/**
  * Set the log reader to return only entries of the given type.
  * Type restrictions enforced here
  *
  * @param string|array $types Log types ('upload', 'delete', etc);
  *   empty string means no restriction
  */
 private function limitType($types)
 {
     global $wgLogRestrictions;
     $user = $this->getUser();
     // If $types is not an array, make it an array
     $types = $types === '' ? array() : (array) $types;
     // Don't even show header for private logs; don't recognize it...
     $needReindex = false;
     foreach ($types as $type) {
         if (isset($wgLogRestrictions[$type]) && !$user->isAllowed($wgLogRestrictions[$type])) {
             $needReindex = true;
             $types = array_diff($types, array($type));
         }
     }
     if ($needReindex) {
         // Lots of this code makes assumptions that
         // the first entry in the array is $types[0].
         $types = array_values($types);
     }
     $this->types = $types;
     // Don't show private logs to unprivileged users.
     // Also, only show them upon specific request to avoid suprises.
     $audience = $types ? 'user' : 'public';
     $hideLogs = LogEventsList::getExcludeClause($this->mDb, $audience, $user);
     if ($hideLogs !== false) {
         $this->mConds[] = $hideLogs;
     }
     if (count($types)) {
         $this->mConds['log_type'] = $types;
         // Set typeCGI; used in url param for paging
         if (count($types) == 1) {
             $this->typeCGI = $types[0];
         }
     }
 }
 public function execute()
 {
     $params = $this->extractRequestParams();
     $db = $this->getDB();
     $prop = array_flip($params['prop']);
     $this->fld_ids = isset($prop['ids']);
     $this->fld_title = isset($prop['title']);
     $this->fld_type = isset($prop['type']);
     $this->fld_action = isset($prop['action']);
     $this->fld_user = isset($prop['user']);
     $this->fld_userid = isset($prop['userid']);
     $this->fld_timestamp = isset($prop['timestamp']);
     $this->fld_comment = isset($prop['comment']);
     $this->fld_parsedcomment = isset($prop['parsedcomment']);
     $this->fld_details = isset($prop['details']);
     $this->fld_tags = isset($prop['tags']);
     $hideLogs = LogEventsList::getExcludeClause($db);
     if ($hideLogs !== false) {
         $this->addWhere($hideLogs);
     }
     // Order is significant here
     $this->addTables(array('logging', 'user', 'page'));
     $this->addOption('STRAIGHT_JOIN');
     $this->addJoinConds(array('user' => array('JOIN', 'user_id=log_user'), 'page' => array('LEFT JOIN', array('log_namespace=page_namespace', 'log_title=page_title'))));
     $index = array('logging' => 'times');
     // default, may change
     $this->addFields(array('log_type', 'log_action', 'log_timestamp', 'log_deleted'));
     $this->addFieldsIf(array('log_id', 'page_id'), $this->fld_ids);
     $this->addFieldsIf(array('log_user', 'user_name'), $this->fld_user);
     $this->addFieldsIf('user_id', $this->fld_userid);
     $this->addFieldsIf(array('log_namespace', 'log_title'), $this->fld_title || $this->fld_parsedcomment);
     $this->addFieldsIf('log_comment', $this->fld_comment || $this->fld_parsedcomment);
     $this->addFieldsIf('log_params', $this->fld_details);
     if ($this->fld_tags) {
         $this->addTables('tag_summary');
         $this->addJoinConds(array('tag_summary' => array('LEFT JOIN', 'log_id=ts_log_id')));
         $this->addFields('ts_tags');
     }
     if (!is_null($params['tag'])) {
         $this->addTables('change_tag');
         $this->addJoinConds(array('change_tag' => array('INNER JOIN', array('log_id=ct_log_id'))));
         $this->addWhereFld('ct_tag', $params['tag']);
         global $wgOldChangeTagsIndex;
         $index['change_tag'] = $wgOldChangeTagsIndex ? 'ct_tag' : 'change_tag_tag_id';
     }
     if (!is_null($params['action'])) {
         list($type, $action) = explode('/', $params['action']);
         $this->addWhereFld('log_type', $type);
         $this->addWhereFld('log_action', $action);
     } elseif (!is_null($params['type'])) {
         $this->addWhereFld('log_type', $params['type']);
         $index['logging'] = 'type_time';
     }
     $this->addTimestampWhereRange('log_timestamp', $params['dir'], $params['start'], $params['end']);
     $limit = $params['limit'];
     $this->addOption('LIMIT', $limit + 1);
     $user = $params['user'];
     if (!is_null($user)) {
         $userid = User::idFromName($user);
         if (!$userid) {
             $this->dieUsage("User name {$user} not found", 'param_user');
         }
         $this->addWhereFld('log_user', $userid);
         $index['logging'] = 'user_time';
     }
     $title = $params['title'];
     if (!is_null($title)) {
         $titleObj = Title::newFromText($title);
         if (is_null($titleObj)) {
             $this->dieUsage("Bad title value '{$title}'", 'param_title');
         }
         $this->addWhereFld('log_namespace', $titleObj->getNamespace());
         $this->addWhereFld('log_title', $titleObj->getDBkey());
         // Use the title index in preference to the user index if there is a conflict
         $index['logging'] = is_null($user) ? 'page_time' : array('page_time', 'user_time');
     }
     $prefix = $params['prefix'];
     if (!is_null($prefix)) {
         global $wgMiserMode;
         if ($wgMiserMode) {
             $this->dieUsage('Prefix search disabled in Miser Mode', 'prefixsearchdisabled');
         }
         $title = Title::newFromText($prefix);
         if (is_null($title)) {
             $this->dieUsage("Bad title value '{$prefix}'", 'param_prefix');
         }
         $this->addWhereFld('log_namespace', $title->getNamespace());
         $this->addWhere('log_title ' . $db->buildLike($title->getDBkey(), $db->anyString()));
     }
     $this->addOption('USE INDEX', $index);
     // Paranoia: avoid brute force searches (bug 17342)
     if (!is_null($title)) {
         $this->addWhere($db->bitAnd('log_deleted', LogPage::DELETED_ACTION) . ' = 0');
     }
     if (!is_null($user)) {
         $this->addWhere($db->bitAnd('log_deleted', LogPage::DELETED_USER) . ' = 0');
     }
     $count = 0;
     $res = $this->select(__METHOD__);
     $result = $this->getResult();
     foreach ($res as $row) {
         if (++$count > $limit) {
             // We've reached the one extra which shows that there are additional pages to be had. Stop here...
             $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->log_timestamp));
             break;
         }
         $vals = $this->extractRowInfo($row);
         if (!$vals) {
             continue;
         }
         $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals);
         if (!$fit) {
             $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->log_timestamp));
             break;
         }
     }
     $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'item');
 }
 /**
  * @param string $cond
  * @throws MWException
  * @throws Exception
  */
 protected function dumpFrom($cond = '')
 {
     wfProfileIn(__METHOD__);
     # For logging dumps...
     if ($this->history & self::LOGS) {
         $where = array('user_id = log_user');
         # Hide private logs
         $hideLogs = LogEventsList::getExcludeClause($this->db);
         if ($hideLogs) {
             $where[] = $hideLogs;
         }
         # Add on any caller specified conditions
         if ($cond) {
             $where[] = $cond;
         }
         # Get logging table name for logging.* clause
         $logging = $this->db->tableName('logging');
         if ($this->buffer == WikiExporter::STREAM) {
             $prev = $this->db->bufferResults(false);
         }
         $wrapper = null;
         // Assuring $wrapper is not undefined, if exception occurs early
         try {
             $result = $this->db->select(array('logging', 'user'), array("{$logging}.*", 'user_name'), $where, __METHOD__, array('ORDER BY' => 'log_id', 'USE INDEX' => array('logging' => 'PRIMARY')));
             $wrapper = $this->db->resultObject($result);
             $this->outputLogStream($wrapper);
             if ($this->buffer == WikiExporter::STREAM) {
                 $this->db->bufferResults($prev);
             }
         } catch (Exception $e) {
             // Throwing the exception does not reliably free the resultset, and
             // would also leave the connection in unbuffered mode.
             // Freeing result
             try {
                 if ($wrapper) {
                     $wrapper->free();
                 }
             } catch (Exception $e2) {
                 // Already in panic mode -> ignoring $e2 as $e has
                 // higher priority
             }
             // Putting database back in previous buffer mode
             try {
                 if ($this->buffer == WikiExporter::STREAM) {
                     $this->db->bufferResults($prev);
                 }
             } catch (Exception $e2) {
                 // Already in panic mode -> ignoring $e2 as $e has
                 // higher priority
             }
             // Inform caller about problem
             wfProfileOut(__METHOD__);
             throw $e;
         }
         # For page dumps...
     } else {
         $tables = array('page', 'revision');
         $opts = array('ORDER BY' => 'page_id ASC');
         $opts['USE INDEX'] = array();
         $join = array();
         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 = '>';
                 $opts['ORDER BY'] = 'rev_timestamp ASC';
             } else {
                 $op = '<';
                 $opts['ORDER BY'] = 'rev_timestamp DESC';
             }
             # Set offset
             if (!empty($this->history['offset'])) {
                 $revJoin .= " AND rev_timestamp {$op} " . $this->db->addQuotes($this->db->timestamp($this->history['offset']));
             }
             $join['revision'] = array('INNER JOIN', $revJoin);
             # Set query limit
             if (!empty($this->history['limit'])) {
                 $opts['LIMIT'] = intval($this->history['limit']);
             }
         } elseif ($this->history & WikiExporter::FULL) {
             # Full history dumps...
             $join['revision'] = array('INNER JOIN', 'page_id=rev_page');
         } elseif ($this->history & WikiExporter::CURRENT) {
             # Latest revision dumps...
             if ($this->list_authors && $cond != '') {
                 // List authors, if so desired
                 $this->do_list_authors($cond);
             }
             $join['revision'] = array('INNER JOIN', 'page_id=rev_page AND page_latest=rev_id');
         } elseif ($this->history & WikiExporter::STABLE) {
             # "Stable" revision dumps...
             # Default JOIN, to be overridden...
             $join['revision'] = array('INNER JOIN', 'page_id=rev_page AND page_latest=rev_id');
             # One, and only one hook should set this, and return false
             if (wfRunHooks('WikiExporter::dumpStableQuery', array(&$tables, &$opts, &$join))) {
                 wfProfileOut(__METHOD__);
                 throw new MWException(__METHOD__ . " given invalid history dump type.");
             }
         } elseif ($this->history & WikiExporter::RANGE) {
             # Dump of revisions within a specified range
             $join['revision'] = array('INNER JOIN', 'page_id=rev_page');
             $opts['ORDER BY'] = array('rev_page ASC', 'rev_id ASC');
         } else {
             # Unknown history specification parameter?
             wfProfileOut(__METHOD__);
             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'] = array('INNER JOIN', 'rev_text_id=old_id');
         }
         if ($this->buffer == WikiExporter::STREAM) {
             $prev = $this->db->bufferResults(false);
         }
         $wrapper = null;
         // Assuring $wrapper is not undefined, if exception occurs early
         try {
             wfRunHooks('ModifyExportQuery', array($this->db, &$tables, &$cond, &$opts, &$join));
             # Do the query!
             $result = $this->db->select($tables, '*', $cond, __METHOD__, $opts, $join);
             $wrapper = $this->db->resultObject($result);
             # Output dump results
             $this->outputPageStream($wrapper);
             if ($this->buffer == WikiExporter::STREAM) {
                 $this->db->bufferResults($prev);
             }
         } catch (Exception $e) {
             // Throwing the exception does not reliably free the resultset, and
             // would also leave the connection in unbuffered mode.
             // Freeing result
             try {
                 if ($wrapper) {
                     $wrapper->free();
                 }
             } catch (Exception $e2) {
                 // Already in panic mode -> ignoring $e2 as $e has
                 // higher priority
             }
             // Putting database back in previous buffer mode
             try {
                 if ($this->buffer == WikiExporter::STREAM) {
                     $this->db->bufferResults($prev);
                 }
             } catch (Exception $e2) {
                 // Already in panic mode -> ignoring $e2 as $e has
                 // higher priority
             }
             // Inform caller about problem
             throw $e;
         }
     }
     wfProfileOut(__METHOD__);
 }
Example #4
0
 protected function dumpFrom($cond = '')
 {
     wfProfileIn(__METHOD__);
     # For logging dumps...
     if ($this->history & self::LOGS) {
         if ($this->buffer == WikiExporter::STREAM) {
             $prev = $this->db->bufferResults(false);
         }
         $where = array('user_id = log_user');
         # Hide private logs
         $hideLogs = LogEventsList::getExcludeClause($this->db);
         if ($hideLogs) {
             $where[] = $hideLogs;
         }
         # Add on any caller specified conditions
         if ($cond) {
             $where[] = $cond;
         }
         # Get logging table name for logging.* clause
         $logging = $this->db->tableName('logging');
         $result = $this->db->select(array('logging', 'user'), array("{$logging}.*", 'user_name'), $where, __METHOD__, array('ORDER BY' => 'log_id', 'USE INDEX' => array('logging' => 'PRIMARY')));
         $wrapper = $this->db->resultObject($result);
         if ($this->buffer == WikiExporter::STREAM) {
             $this->db->bufferResults($prev);
         }
         $this->outputLogStream($wrapper);
         # For page dumps...
     } else {
         $tables = array('page', 'revision');
         $opts = array('ORDER BY' => 'page_id ASC');
         $opts['USE INDEX'] = array();
         $join = array();
         # Full history dumps...
         if ($this->history & WikiExporter::FULL) {
             $join['revision'] = array('INNER JOIN', 'page_id=rev_page');
             # Latest revision dumps...
         } elseif ($this->history & WikiExporter::CURRENT) {
             if ($this->list_authors && $cond != '') {
                 // List authors, if so desired
                 list($page, $revision) = $this->db->tableNamesN('page', 'revision');
                 $this->do_list_authors($page, $revision, $cond);
             }
             $join['revision'] = array('INNER JOIN', 'page_id=rev_page AND page_latest=rev_id');
             # "Stable" revision dumps...
         } elseif ($this->history & WikiExporter::STABLE) {
             # Default JOIN, to be overridden...
             $join['revision'] = array('INNER JOIN', 'page_id=rev_page AND page_latest=rev_id');
             # One, and only one hook should set this, and return false
             if (wfRunHooks('WikiExporter::dumpStableQuery', array(&$tables, &$opts, &$join))) {
                 wfProfileOut(__METHOD__);
                 return new WikiError(__METHOD__ . " given invalid history dump type.");
             }
             # Time offset/limit for all pages/history...
         } elseif (is_array($this->history)) {
             $revJoin = 'page_id=rev_page';
             # Set time order
             if ($this->history['dir'] == 'asc') {
                 $op = '>';
                 $opts['ORDER BY'] = 'rev_timestamp ASC';
             } else {
                 $op = '<';
                 $opts['ORDER BY'] = 'rev_timestamp DESC';
             }
             # Set offset
             if (!empty($this->history['offset'])) {
                 $revJoin .= " AND rev_timestamp {$op} " . $this->db->addQuotes($this->db->timestamp($this->history['offset']));
             }
             $join['revision'] = array('INNER JOIN', $revJoin);
             # Set query limit
             if (!empty($this->history['limit'])) {
                 $opts['LIMIT'] = intval($this->history['limit']);
             }
             # Uknown history specification parameter?
         } else {
             wfProfileOut(__METHOD__);
             return new WikiError(__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'] = array('INNER JOIN', 'rev_text_id=old_id');
         }
         if ($this->buffer == WikiExporter::STREAM) {
             $prev = $this->db->bufferResults(false);
         }
         # Do the query!
         $result = $this->db->select($tables, '*', $cond, __METHOD__, $opts, $join);
         $wrapper = $this->db->resultObject($result);
         # Output dump results
         $this->outputPageStream($wrapper);
         if ($this->list_authors) {
             $this->outputPageStream($wrapper);
         }
         if ($this->buffer == WikiExporter::STREAM) {
             $this->db->bufferResults($prev);
         }
     }
     wfProfileOut(__METHOD__);
 }
 public function getCacheMode($params)
 {
     if ($this->userCanSeeRevDel()) {
         return 'private';
     }
     if (!is_null($params['prop']) && in_array('parsedcomment', $params['prop'])) {
         // formatComment() calls wfMessage() among other things
         return 'anon-public-user-private';
     } elseif (LogEventsList::getExcludeClause($this->getDB(), 'user', $this->getUser()) === LogEventsList::getExcludeClause($this->getDB(), 'public')) {
         // Output can only contain public data.
         return 'public';
     } else {
         return 'anon-public-user-private';
     }
 }
Example #6
0
 public function execute()
 {
     $params = $this->extractRequestParams();
     $db = $this->getDB();
     $prop = $params['prop'];
     $this->fld_ids = in_array('ids', $prop);
     $this->fld_title = in_array('title', $prop);
     $this->fld_type = in_array('type', $prop);
     $this->fld_user = in_array('user', $prop);
     $this->fld_timestamp = in_array('timestamp', $prop);
     $this->fld_comment = in_array('comment', $prop);
     $this->fld_details = in_array('details', $prop);
     list($tbl_logging, $tbl_page, $tbl_user) = $db->tableNamesN('logging', 'page', 'user');
     $hideLogs = LogEventsList::getExcludeClause($db);
     if ($hideLogs !== false) {
         $this->addWhere($hideLogs);
     }
     // Order is significant here
     $this->addTables(array('logging', 'user', 'page'));
     $this->addOption('STRAIGHT_JOIN');
     $this->addJoinConds(array('user' => array('JOIN', 'user_id=log_user'), 'page' => array('LEFT JOIN', array('log_namespace=page_namespace', 'log_title=page_title'))));
     $index = 'times';
     // default, may change
     $this->addFields(array('log_type', 'log_action', 'log_timestamp', 'log_deleted'));
     $this->addFieldsIf('log_id', $this->fld_ids);
     $this->addFieldsIf('page_id', $this->fld_ids);
     $this->addFieldsIf('log_user', $this->fld_user);
     $this->addFieldsIf('user_name', $this->fld_user);
     $this->addFieldsIf('log_namespace', $this->fld_title);
     $this->addFieldsIf('log_title', $this->fld_title);
     $this->addFieldsIf('log_comment', $this->fld_comment);
     $this->addFieldsIf('log_params', $this->fld_details);
     if (!is_null($params['type'])) {
         $this->addWhereFld('log_type', $params['type']);
         $index = 'type_time';
     }
     $this->addWhereRange('log_timestamp', $params['dir'], $params['start'], $params['end']);
     $limit = $params['limit'];
     $this->addOption('LIMIT', $limit + 1);
     $user = $params['user'];
     if (!is_null($user)) {
         $userid = User::idFromName($user);
         if (!$userid) {
             $this->dieUsage("User name {$user} not found", 'param_user');
         }
         $this->addWhereFld('log_user', $userid);
         $index = 'user_time';
     }
     $title = $params['title'];
     if (!is_null($title)) {
         $titleObj = Title::newFromText($title);
         if (is_null($titleObj)) {
             $this->dieUsage("Bad title value '{$title}'", 'param_title');
         }
         $this->addWhereFld('log_namespace', $titleObj->getNamespace());
         $this->addWhereFld('log_title', $titleObj->getDBkey());
         // Use the title index in preference to the user index if there is a conflict
         $index = is_null($user) ? 'page_time' : array('page_time', 'user_time');
     }
     $this->addOption('USE INDEX', array('logging' => $index));
     // Paranoia: avoid brute force searches (bug 17342)
     if (!is_null($title)) {
         $this->addWhere('log_deleted & ' . LogPage::DELETED_ACTION . ' = 0');
     }
     if (!is_null($user)) {
         $this->addWhere('log_deleted & ' . LogPage::DELETED_USER . ' = 0');
     }
     $count = 0;
     $res = $this->select(__METHOD__);
     while ($row = $db->fetchObject($res)) {
         if (++$count > $limit) {
             // We've reached the one extra which shows that there are additional pages to be had. Stop here...
             $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->log_timestamp));
             break;
         }
         $vals = $this->extractRowInfo($row);
         if (!$vals) {
             continue;
         }
         $fit = $this->getResult()->addValue(array('query', $this->getModuleName()), null, $vals);
         if (!$fit) {
             $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->log_timestamp));
             break;
         }
     }
     $db->freeResult($res);
     $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'item');
 }
Example #7
0
 /**
  * Set the log reader to return only entries of the given type.
  * Type restrictions enforced here
  *
  * @param $types String or array: Log types ('upload', 'delete', etc);
  *   empty string means no restriction
  */
 private function limitType($types)
 {
     global $wgLogRestrictions, $wgUser;
     // If $types is not an array, make it an array
     $types = $types === '' ? array() : (array) $types;
     // Don't even show header for private logs; don't recognize it...
     foreach ($types as $type) {
         if (isset($wgLogRestrictions[$type]) && !$wgUser->isAllowed($wgLogRestrictions[$type])) {
             $types = array_diff($types, array($type));
         }
     }
     $this->types = $types;
     // Don't show private logs to unprivileged users.
     // Also, only show them upon specific request to avoid suprises.
     $audience = $types ? 'user' : 'public';
     $hideLogs = LogEventsList::getExcludeClause($this->mDb, $audience);
     if ($hideLogs !== false) {
         $this->mConds[] = $hideLogs;
     }
     if (count($types)) {
         $this->mConds['log_type'] = $types;
         // Set typeCGI; used in url param for paging
         if (count($types) == 1) {
             $this->typeCGI = $types[0];
         }
     }
 }
Example #8
0
 /**
  * Set the log reader to return only entries of the given type.
  * Type restrictions enforced here
  * @param $type String: A log type ('upload', 'delete', etc)
  */
 private function limitType($type)
 {
     global $wgLogRestrictions, $wgUser;
     // Don't even show header for private logs; don't recognize it...
     if (isset($wgLogRestrictions[$type]) && !$wgUser->isAllowed($wgLogRestrictions[$type])) {
         $type = '';
     }
     // Don't show private logs to unpriviledged users
     $hideLogs = LogEventsList::getExcludeClause($this->mDb);
     if ($hideLogs !== false) {
         $this->mConds[] = $hideLogs;
     }
     if (!$type) {
         return false;
     }
     $this->type = $type;
     $this->mConds['log_type'] = $type;
 }
Example #9
0
 /**
  * Set the log reader to return only entries of the given type.
  * Type restrictions enforced here
  * @param $type String: A log type ('upload', 'delete', etc)
  */
 private function limitType($type)
 {
     global $wgLogRestrictions, $wgUser;
     // Don't even show header for private logs; don't recognize it...
     if (isset($wgLogRestrictions[$type]) && !$wgUser->isAllowed($wgLogRestrictions[$type])) {
         $type = '';
     }
     // Don't show private logs to unpriviledged users.
     // Also, only show them upon specific request to avoid suprises.
     $audience = $type ? 'user' : 'public';
     $hideLogs = LogEventsList::getExcludeClause($this->mDb, $audience);
     if ($hideLogs !== false) {
         $this->mConds[] = $hideLogs;
     }
     if ($type) {
         $this->type = $type;
         $this->mConds['log_type'] = $type;
     }
 }
Example #10
0
 protected function dumpFrom($cond = '')
 {
     $fname = 'WikiExporter::dumpFrom';
     wfProfileIn($fname);
     # For logs dumps...
     if ($this->history & self::LOGS) {
         $where = array('user_id = log_user');
         # Hide private logs
         $where[] = LogEventsList::getExcludeClause($this->db);
         if ($cond) {
             $where[] = $cond;
         }
         $result = $this->db->select(array('logging', 'user'), '*', $where, $fname, array('ORDER BY' => 'log_id', 'USE INDEX' => array('logging' => 'PRIMARY')));
         $wrapper = $this->db->resultObject($result);
         $this->outputLogStream($wrapper);
         # For page dumps...
     } else {
         list($page, $revision, $text) = $this->db->tableNamesN('page', 'revision', 'text');
         $order = 'ORDER BY page_id';
         $limit = '';
         if ($this->history == WikiExporter::FULL) {
             $join = 'page_id=rev_page';
         } elseif ($this->history == WikiExporter::CURRENT) {
             if ($this->list_authors && $cond != '') {
                 // List authors, if so desired
                 $this->do_list_authors($page, $revision, $cond);
             }
             $join = 'page_id=rev_page AND page_latest=rev_id';
         } elseif (is_array($this->history)) {
             $join = 'page_id=rev_page';
             if ($this->history['dir'] == 'asc') {
                 $op = '>';
                 $order .= ', rev_timestamp';
             } else {
                 $op = '<';
                 $order .= ', rev_timestamp DESC';
             }
             if (!empty($this->history['offset'])) {
                 $join .= " AND rev_timestamp {$op} " . $this->db->addQuotes($this->db->timestamp($this->history['offset']));
             }
             if (!empty($this->history['limit'])) {
                 $limitNum = intval($this->history['limit']);
                 if ($limitNum > 0) {
                     $limit = "LIMIT {$limitNum}";
                 }
             }
         } else {
             wfProfileOut($fname);
             return new WikiError("{$fname} given invalid history dump type.");
         }
         $where = $cond == '' ? '' : "{$cond} AND";
         if ($this->buffer == WikiExporter::STREAM) {
             $prev = $this->db->bufferResults(false);
         }
         if ($cond == '') {
             // Optimization hack for full-database dump
             $revindex = $pageindex = $this->db->useIndexClause("PRIMARY");
             $straight = ' /*! STRAIGHT_JOIN */ ';
         } else {
             $pageindex = '';
             $revindex = '';
             $straight = '';
         }
         if ($this->text == WikiExporter::STUB) {
             $sql = "SELECT {$straight} * FROM\n\t\t\t\t\t{$page} {$pageindex},\n\t\t\t\t\t{$revision} {$revindex}\n\t\t\t\t\tWHERE {$where} {$join}\n\t\t\t\t\t{$order} {$limit}";
         } else {
             $sql = "SELECT {$straight} * FROM\n\t\t\t\t\t{$page} {$pageindex},\n\t\t\t\t\t{$revision} {$revindex},\n\t\t\t\t\t{$text}\n\t\t\t\t\tWHERE {$where} {$join} AND rev_text_id=old_id\n\t\t\t\t\t{$order} {$limit}";
         }
         $result = $this->db->query($sql, $fname);
         $wrapper = $this->db->resultObject($result);
         $this->outputPageStream($wrapper);
         if ($this->list_authors) {
             $this->outputPageStream($wrapper);
         }
         if ($this->buffer == WikiExporter::STREAM) {
             $this->db->bufferResults($prev);
         }
     }
     wfProfileOut($fname);
 }