Commit 57b40124 authored by Jeremy Mikola's avatar Jeremy Mikola

PHPLIB-215: Accessor method for GridFS stream file document

This adds Bucket::getFileDocumentForStream() and Bucket::getFileIdForStream() methods, the latter of which was renamed from getIdFromStream().

Additionally, this replaces the getId() method in both internal stream classes with a getFile() method. The debug output for ReadableStream has also been simplified to include the entire file document instead of ID, chunkSize, and length.
parent 1e3be59e
...@@ -218,20 +218,44 @@ class Bucket ...@@ -218,20 +218,44 @@ class Bucket
} }
/** /**
* Gets the ID of the GridFS file associated with a stream. * Gets the file document of the GridFS file associated with a stream.
* *
* @param resource $stream GridFS stream * @param resource $stream GridFS stream
* @return mixed * @return stdClass
* @throws InvalidArgumentException
*/ */
public function getIdFromStream($stream) public function getFileDocumentForStream($stream)
{ {
if ( ! is_resource($stream) || get_resource_type($stream) != "stream") {
throw InvalidArgumentException::invalidType('$stream', $stream, 'resource');
}
$metadata = stream_get_meta_data($stream); $metadata = stream_get_meta_data($stream);
if ($metadata['wrapper_data'] instanceof StreamWrapper) { if (!$metadata['wrapper_data'] instanceof StreamWrapper) {
return $metadata['wrapper_data']->getId(); throw InvalidArgumentException::invalidType('$stream wrapper data', $metadata['wrapper_data'], 'MongoDB\Driver\GridFS\StreamWrapper');
}
return $metadata['wrapper_data']->getFile();
}
/**
* Gets the file document's ID of the GridFS file associated with a stream.
*
* @param resource $stream GridFS stream
* @return stdClass
* @throws CorruptFileException
* @throws InvalidArgumentException
*/
public function getFileIdForStream($stream)
{
$file = $this->getFileDocumentForStream($stream);
if ( ! isset($file->_id) && ! property_exists($file, '_id')) {
throw new CorruptFileException('file._id does not exist');
} }
// TODO: Throw if we cannot access the ID return $file->_id;
} }
/** /**
...@@ -379,7 +403,7 @@ class Bucket ...@@ -379,7 +403,7 @@ class Bucket
$destination = $this->openUploadStream($filename, $options); $destination = $this->openUploadStream($filename, $options);
stream_copy_to_stream($source, $destination); stream_copy_to_stream($source, $destination);
return $this->getIdFromStream($destination); return $this->getFileIdForStream($destination);
} }
/** /**
......
...@@ -21,8 +21,8 @@ class ReadableStream ...@@ -21,8 +21,8 @@ class ReadableStream
private $chunkOffset = 0; private $chunkOffset = 0;
private $chunksIterator; private $chunksIterator;
private $collectionWrapper; private $collectionWrapper;
private $file;
private $firstCheck = true; private $firstCheck = true;
private $id;
private $iteratorEmpty = false; private $iteratorEmpty = false;
private $length; private $length;
private $numChunks; private $numChunks;
...@@ -44,15 +44,15 @@ class ReadableStream ...@@ -44,15 +44,15 @@ class ReadableStream
throw new CorruptFileException('file.length is not an integer > 0'); throw new CorruptFileException('file.length is not an integer > 0');
} }
if ( ! isset($file->_id) && ! array_key_exists('_id', (array) $file)) { if ( ! isset($file->_id) && ! property_exists($file, '_id')) {
throw new CorruptFileException('file._id does not exist'); throw new CorruptFileException('file._id does not exist');
} }
$this->id = $file->_id; $this->file = $file;
$this->chunkSize = $file->chunkSize; $this->chunkSize = $file->chunkSize;
$this->length = $file->length; $this->length = $file->length;
$this->chunksIterator = $collectionWrapper->getChunksIteratorByFilesId($this->id); $this->chunksIterator = $collectionWrapper->getChunksIteratorByFilesId($file->_id);
$this->collectionWrapper = $collectionWrapper; $this->collectionWrapper = $collectionWrapper;
$this->numChunks = ceil($this->length / $this->chunkSize); $this->numChunks = ceil($this->length / $this->chunkSize);
$this->initEmptyBuffer(); $this->initEmptyBuffer();
...@@ -69,9 +69,7 @@ class ReadableStream ...@@ -69,9 +69,7 @@ class ReadableStream
return [ return [
'bucketName' => $this->collectionWrapper->getBucketName(), 'bucketName' => $this->collectionWrapper->getBucketName(),
'databaseName' => $this->collectionWrapper->getDatabaseName(), 'databaseName' => $this->collectionWrapper->getDatabaseName(),
'id' => $this->id, 'file' => $this->file,
'chunkSize' => $this->chunkSize,
'length' => $this->length,
]; ];
} }
...@@ -130,13 +128,13 @@ class ReadableStream ...@@ -130,13 +128,13 @@ class ReadableStream
} }
/** /**
* Return the stream's ID (i.e. file document identifier). * Return the stream's file document.
* *
* @return integer * @return stdClass
*/ */
public function getId() public function getFile()
{ {
return $this->id; return $this->file;
} }
/** /**
......
...@@ -22,9 +22,14 @@ class StreamWrapper ...@@ -22,9 +22,14 @@ class StreamWrapper
private $protocol; private $protocol;
private $stream; private $stream;
public function getId() /**
* Return the stream's file document.
*
* @return stdClass
*/
public function getFile()
{ {
return $this->stream->getId(); return $this->stream->getFile();
} }
/** /**
......
...@@ -127,13 +127,13 @@ class WritableStream ...@@ -127,13 +127,13 @@ class WritableStream
} }
/** /**
* Return the stream's ID (i.e. file document identifier). * Return the stream's file document.
* *
* @return integer * @return stdClass
*/ */
public function getId() public function getFile()
{ {
return $this->file['_id']; return (object) $this->file;
} }
/** /**
......
...@@ -323,12 +323,63 @@ class BucketFunctionalTest extends FunctionalTestCase ...@@ -323,12 +323,63 @@ class BucketFunctionalTest extends FunctionalTestCase
$this->assertEquals($this->getDatabaseName(), $this->bucket->getDatabaseName()); $this->assertEquals($this->getDatabaseName(), $this->bucket->getDatabaseName());
} }
public function testGetIdFromStream() public function testGetFileDocumentForStreamWithReadableStream()
{
$metadata = ['foo' => 'bar'];
$id = $this->bucket->uploadFromStream('filename', $this->createStream('foobar'), ['metadata' => $metadata]);
$stream = $this->bucket->openDownloadStream($id);
$fileDocument = $this->bucket->getFileDocumentForStream($stream);
$this->assertEquals($id, $fileDocument->_id);
$this->assertSame('filename', $fileDocument->filename);
$this->assertSame(6, $fileDocument->length);
$this->assertSameDocument($metadata, $fileDocument->metadata);
}
public function testGetFileDocumentForStreamWithWritableStream()
{
$metadata = ['foo' => 'bar'];
$stream = $this->bucket->openUploadStream('filename', ['_id' => 1, 'metadata' => $metadata]);
$fileDocument = $this->bucket->getFileDocumentForStream($stream);
$this->assertEquals(1, $fileDocument->_id);
$this->assertSame('filename', $fileDocument->filename);
$this->assertSameDocument($metadata, $fileDocument->metadata);
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @dataProvider provideInvalidStreamValues
*/
public function testGetFileDocumentForStreamShouldRequireStreamResource($stream)
{
$this->bucket->getFileDocumentForStream($stream);
}
public function testGetFileIdForStreamWithReadableStream()
{ {
$id = $this->bucket->uploadFromStream('filename', $this->createStream('foobar')); $id = $this->bucket->uploadFromStream('filename', $this->createStream('foobar'));
$stream = $this->bucket->openDownloadStream($id); $stream = $this->bucket->openDownloadStream($id);
$this->assertEquals($id, $this->bucket->getIdFromStream($stream)); $this->assertEquals($id, $this->bucket->getFileIdForStream($stream));
}
public function testGetFileIdForStreamWithWritableStream()
{
$stream = $this->bucket->openUploadStream('filename', ['_id' => 1]);
$this->assertEquals(1, $this->bucket->getFileIdForStream($stream));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @dataProvider provideInvalidStreamValues
*/
public function testGetFileIdForStreamShouldRequireStreamResource($stream)
{
$this->bucket->getFileIdForStream($stream);
} }
/** /**
......
...@@ -62,7 +62,7 @@ class WritableStreamFunctionalTest extends FunctionalTestCase ...@@ -62,7 +62,7 @@ class WritableStreamFunctionalTest extends FunctionalTestCase
$stream->close(); $stream->close();
$fileDocument = $this->filesCollection->findOne( $fileDocument = $this->filesCollection->findOne(
['_id' => $stream->getId()], ['_id' => $stream->getFile()->_id],
['projection' => ['md5' => 1, '_id' => 0]] ['projection' => ['md5' => 1, '_id' => 0]]
); );
......
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