Add RepoGroup::findFiles to efficiently find many files if the repo supports it. Added support for this in ApiQueryImageInfo.

This commit is contained in:
Bryan Tong Minh 2008-05-20 17:05:57 +00:00
parent 7bf7bb03c1
commit 06c09e9835
5 changed files with 113 additions and 38 deletions

View file

@ -59,48 +59,47 @@ class ApiQueryImageInfo extends ApiQueryBase {
if (!empty($pageIds[NS_IMAGE])) {
$result = $this->getResult();
foreach ($pageIds[NS_IMAGE] as $dbKey => $pageId) {
$title = Title :: makeTitle(NS_IMAGE, $dbKey);
$img = wfFindFile($title);
$images = RepoGroup::singleton()->findFiles( array_keys( $pageIds[NS_IMAGE] ) );
foreach ( $images as $img ) {
$data = array();
if ( !$img ) {
$repository = '';
} else {
$repository = $img->getRepoName();
// Get information about the current version first
// Check that the current version is within the start-end boundaries
if((is_null($params['start']) || $img->getTimestamp() <= $params['start']) &&
(is_null($params['end']) || $img->getTimestamp() >= $params['end'])) {
$data[] = self::getInfo( $img, $prop, $result, $scale );
}
// Now get the old revisions
// Get one more to facilitate query-continue functionality
$count = count($data);
$oldies = $img->getHistory($params['limit'] - $count + 1, $params['start'], $params['end']);
foreach($oldies as $oldie) {
if(++$count > $params['limit']) {
// We've reached the extra one which shows that there are additional pages to be had. Stop here...
// Only set a query-continue if there was only one title
if(count($pageIds[NS_IMAGE]) == 1)
$this->setContinueEnumParameter('start', $oldie->getTimestamp());
break;
}
$data[] = self::getInfo( $oldie, $prop, $result );
}
// Get information about the current version first
// Check that the current version is within the start-end boundaries
if((is_null($params['start']) || $img->getTimestamp() <= $params['start']) &&
(is_null($params['end']) || $img->getTimestamp() >= $params['end'])) {
$data[] = self::getInfo( $img, $prop, $result, $scale );
}
$result->addValue(array(
'query', 'pages', intval($pageId)),
'imagerepository', $repository
// Now get the old revisions
// Get one more to facilitate query-continue functionality
$count = count($data);
$oldies = $img->getHistory($params['limit'] - $count + 1, $params['start'], $params['end']);
foreach($oldies as $oldie) {
if(++$count > $params['limit']) {
// We've reached the extra one which shows that there are additional pages to be had. Stop here...
// Only set a query-continue if there was only one title
if(count($pageIds[NS_IMAGE]) == 1)
$this->setContinueEnumParameter('start', $oldie->getTimestamp());
break;
}
$data[] = self::getInfo( $oldie, $prop, $result );
}
$pageId = $pageIds[NS_IMAGE][ $img->getOriginalTitle()->getDBkey() ];
wfDebug("id: $pageId\n");
$result->addValue(
array( 'query', 'pages', intval( $pageId ) ),
'imagerepository', $img->getRepoName()
);
if (!empty($data))
$this->addPageSubItems($pageId, $data);
$this->addPageSubItems($pageId, $data);
}
$missing = array_diff( array_keys( $pageIds[NS_IMAGE] ), array_keys( $images ) );
foreach ( $missing as $title )
$result->addValue(
array( 'query', 'pages', intval( $pageIds[NS_IMAGE][$title] ) ),
'imagerepository', ''
);
}
}

View file

@ -46,7 +46,7 @@ abstract class File {
/**
* The following member variables are not lazy-initialised
*/
var $repo, $title, $lastError, $redirected;
var $repo, $title, $lastError, $redirected, $redirectedTitle;
/**
* Call this constructor from child classes
@ -152,6 +152,15 @@ abstract class File {
* Return the associated title object
*/
public function getTitle() { return $this->title; }
/**
* Return the title used to find this file
*/
public function getOriginalTitle() {
if ( $this->redirected )
return $this->getRedirectedTitle();
return $this->title;
}
/**
* Return the URL of the file
@ -1214,6 +1223,14 @@ abstract class File {
function getRedirected() {
return $this->redirected;
}
function getRedirectedTitle() {
if ( $this->redirected ) {
if ( !$this->redirectTitle )
$this->redirectTitle = Title::makeTitle( NS_IMAGE, $this->redirected );
return $this->redirectTitle;
}
}
function redirectedFrom( $from ) {
$this->redirected = $from;

View file

@ -125,6 +125,21 @@ abstract class FileRepo {
return false;
}
/*
* Find many files at once
*/
function findFiles( &$titles, $time = false, $flags ) {
$result = array();
foreach ( $titles as $index => $title ) {
$file = $this->findFile( $title );
if ( $file ) {
$result[$file->getTitle()->getDBkey()] = $file;
unset( $titles[$index] );
}
}
return $result;
}
/**
* Create a new File object from the local repository
* @param mixed $sha1 SHA-1 key

View file

@ -157,4 +157,36 @@ class LocalRepo extends FSRepo {
$res->free();
return $result;
}
function findFiles( &$titles, $time = false, $flags ) {
if ( count( $titles ) == 0 ) return array();
$dbKeys = array();
$indices = array();
foreach ( $titles as $index => $title ) {
if ( !( $title instanceof Title ) )
$title = Title::makeTitleSafe( NS_IMAGE, $title );
if ( is_object( $title ) ) {
$key = $title->getDBkey();
$indices[$key] = $index;
$dbKeys[] = $key;
}
}
$dbr = $this->getSlaveDB();
$res = $dbr->select(
'image',
LocalFile::selectFields(),
array( 'img_name' => $dbKeys )
);
$result = array();
while ( $row = $res->fetchObject() ) {
$result[$row->img_name] = $this->newFileFromRow( $row );
unset( $titles[$indices[$row->img_name]] );
}
$res->free();
return $result;
}
}

View file

@ -76,6 +76,18 @@ class RepoGroup {
}
return false;
}
function findFiles( $titles, $time = false, $flags = 0 ) {
if ( !$this->reposInitialised ) {
$this->initialiseRepos();
}
$images = $this->localRepo->findFiles( $titles, $time, $flags );
foreach ( $this->foreignRepos as $repo ) {
$images = array_merge( $images, $repo->findFiles( $titles, $time, $flags ) );
}
return $images;
}
/**
* Interface for FileRepo::checkRedirect()