Commit 3269ce9f authored by Will Banfield's avatar Will Banfield Committed by Jeremy Mikola

PHPLIB-154: implement downloadByName

parent 8f2aaeab
......@@ -171,4 +171,19 @@ class Bucket
'projection' => ['_id' => 1],
]);
}
public function findFileRevision($filename, $revision)
{
if ($revision < 0) {
$skip = abs($revision) -1;
$sortOrder = -1;
} else {
$skip = $revision;
$sortOrder = 1;
}
$file = $this->filesCollection->findOne(["filename"=> $filename], ["sort" => ["uploadDate"=> $sortOrder], "limit"=>1, "skip" => $skip]);
if(is_null($file)) {
throw new \MongoDB\Exception\GridFSFileNotFoundException($filename, $this->getBucketName(), $this->getDatabaseName());;
}
return $file;
}
}
......@@ -84,4 +84,33 @@ class BucketReadWriter
$this->bucket->getFilesCollection()->deleteOne(['_id' => $id], $options);
}
/**
* Open a stream to download a file from the GridFS bucket. Searches for the file by the specified name then returns a stream to the specified file
* @param string $filename name of the file to download
* @param int $revision the revision of the file to download
* @throws GridFSFileNotFoundException
*/
public function openDownloadStreamByName($filename, $revision = -1)
{
$file = $this->bucket->findFileRevision($filename, $revision);
$options = ['bucket' => $this->bucket,
'file' => $file
];
$context = stream_context_create(['gridfs' => $options]);
return fopen(sprintf('gridfs://%s/%s', $this->bucket->getDatabaseName(), $filename), 'r', false, $context);
}
/**
* Download a file from the GridFS bucket by name. Searches for the file by the specified name then loads data into the stream
*
* @param string $filename name of the file to download
* @param int $revision the revision of the file to download
* @throws GridFSFileNotFoundException
*/
public function downloadToStreamByName($filename, $destination, $revision=-1)
{
$file = $this->bucket->findFileRevision($filename, $revision);
$gridFsStream = new GridFsDownload($this->bucket, null, $file);
$gridFsStream->downloadToStream($destination);
}
}
......@@ -40,12 +40,17 @@ class GridFsDownload extends GridFsStream
*/
public function __construct(
Bucket $bucket,
ObjectId $objectId
$objectId,
$file = null
)
{
$this->file = $bucket->getFilesCollection()->findOne(['_id' => $objectId]);
if (is_null($this->file)) {
throw new \MongoDB\Exception\GridFSFileNotFoundException($objectId, $bucket->getBucketName(), $bucket->getDatabaseName());
if(!is_null($file)) {
$this->file = $file;
} else {
$this->file = $bucket->getFilesCollection()->findOne(['_id' => $objectId]);
if (is_null($this->file)) {
throw new \MongoDB\Exception\GridFSFileNotFoundException($objectId, $bucket->getBucketName(), $bucket->getDatabaseName());
}
}
if ($this->file->length > 0) {
$cursor = $bucket->getChunksCollection()->find(['files_id' => $this->file->_id], ['sort' => ['n' => 1]]);
......
......@@ -72,9 +72,15 @@ class StreamWrapper
$this->gridFsStream = new GridFsUpload($this->bucket, $this->identifier, $options);
return true;
}
public function openReadStream() {
$objectId = new \MongoDB\BSON\ObjectId($this->identifier);
$this->gridFsStream = new GridFsDownload($this->bucket, $objectId);
$context = stream_context_get_options($this->context);
if(isset($context['gridfs']['file'])){
$this->gridFsStream = new GridFsDownload($this->bucket, null, $context['gridfs']['file']);
} else {
$objectId = new \MongoDB\BSON\ObjectId($this->identifier);
$this->gridFsStream = new GridFsDownload($this->bucket, $objectId);
}
return true;
}
}
......@@ -91,7 +91,7 @@ class SpecificationTests extends FunctionalTestCase
public function provideSpecificationTests()
{
$testPath=getcwd().'/tests/GridFS/Specification/tests/delete.json';
$testPath=getcwd().'/tests/GridFS/Specification/tests/download_by_name.json';
$testArgs = [];
foreach(glob($testPath) as $filename) {
......@@ -237,6 +237,19 @@ class SpecificationTests extends FunctionalTestCase
}
function download_by_nameCommand($args)
{
$args = $this->fixTypes($args, false);
$streamWrapper = new \MongoDB\GridFS\StreamWrapper();
$streamWrapper->register($this->manager);
$stream = fopen('php://temp', 'w+');
if(isset($args['options']['revision'])) {
$this->bucketReadWriter->downloadToStreamByName($args['filename'], $stream, $args['options']['revision']);
} else {
$this->bucketReadWriter->downloadToStreamByName($args['filename'], $stream);
}
rewind($stream);
$result = stream_get_contents($stream);
fclose($stream);
return $result;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment