Commit 71d76b15 authored by Derick Rethans's avatar Derick Rethans

Merged pull request #541

parents baf85f46 331c3fbb
......@@ -17,6 +17,12 @@ interface: phpmethod
operation: ~
optional: true
---
source:
file: apiargs-MongoDBGridFSBucket-common-option.yaml
ref: disableMD5
post: |
.. versionadded: 1.4
---
source:
file: apiargs-common-option.yaml
ref: readConcern
......
......@@ -18,6 +18,17 @@ operation: ~
optional: true
---
arg_name: option
name: disableMD5
type: boolean
description: |
Whether to disable automatic MD5 generation when storing files.
Defaults to ``false``.
interface: phpmethod
operation: ~
optional: true
---
arg_name: option
name: metadata
type: array|object
description: |
......
......@@ -17,6 +17,12 @@ interface: phpmethod
operation: ~
optional: true
---
source:
file: apiargs-MongoDBGridFSBucket-common-option.yaml
ref: disableMD5
post: |
.. versionadded: 1.4
---
source:
file: apiargs-common-option.yaml
ref: readConcern
......
......@@ -6,6 +6,12 @@ source:
file: apiargs-MongoDBGridFSBucket-common-option.yaml
ref: chunkSizeBytes
---
source:
file: apiargs-MongoDBGridFSBucket-common-option.yaml
ref: disableMD5
post: |
.. versionadded: 1.4
---
source:
file: apiargs-MongoDBGridFSBucket-common-option.yaml
ref: metadata
......
......@@ -6,6 +6,12 @@ source:
file: apiargs-MongoDBGridFSBucket-common-option.yaml
ref: chunkSizeBytes
---
source:
file: apiargs-MongoDBGridFSBucket-common-option.yaml
ref: disableMD5
post: |
.. versionadded: 1.4
---
source:
file: apiargs-MongoDBGridFSBucket-common-option.yaml
ref: metadata
......
......@@ -51,6 +51,7 @@ class Bucket
private $databaseName;
private $manager;
private $bucketName;
private $disableMD5;
private $chunkSizeBytes;
private $readConcern;
private $readPreference;
......@@ -68,6 +69,9 @@ class Bucket
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to
* 261120 (i.e. 255 KiB).
*
* * disableMD5 (boolean): When true, no MD5 sum will be generated for
* each stored file. Defaults to "false".
*
* * readConcern (MongoDB\Driver\ReadConcern): Read concern.
*
* * readPreference (MongoDB\Driver\ReadPreference): Read preference.
......@@ -86,6 +90,7 @@ class Bucket
$options += [
'bucketName' => self::$defaultBucketName,
'chunkSizeBytes' => self::$defaultChunkSizeBytes,
'disableMD5' => false,
];
if (isset($options['bucketName']) && ! is_string($options['bucketName'])) {
......@@ -100,6 +105,10 @@ class Bucket
throw new InvalidArgumentException(sprintf('Expected "chunkSizeBytes" option to be >= 1, %d given', $options['chunkSizeBytes']));
}
if (isset($options['disableMD5']) && ! is_bool($options['disableMD5'])) {
throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean');
}
if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], 'MongoDB\Driver\ReadConcern');
}
......@@ -120,6 +129,7 @@ class Bucket
$this->databaseName = (string) $databaseName;
$this->bucketName = $options['bucketName'];
$this->chunkSizeBytes = $options['chunkSizeBytes'];
$this->disableMD5 = $options['disableMD5'];
$this->readConcern = isset($options['readConcern']) ? $options['readConcern'] : $this->manager->getReadConcern();
$this->readPreference = isset($options['readPreference']) ? $options['readPreference'] : $this->manager->getReadPreference();
$this->typeMap = isset($options['typeMap']) ? $options['typeMap'] : self::$defaultTypeMap;
......@@ -470,6 +480,9 @@ class Bucket
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the
* bucket's chunk size.
*
* * disableMD5 (boolean): When true, no MD5 sum will be generated for
* the stored file. Defaults to "false".
*
* * metadata (document): User data for the "metadata" field of the files
* collection document.
*
......@@ -533,6 +546,9 @@ class Bucket
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the
* bucket's chunk size.
*
* * disableMD5 (boolean): When true, no MD5 sum will be generated for
* the stored file. Defaults to "false".
*
* * metadata (document): User data for the "metadata" field of the files
* collection document.
*
......
......@@ -36,9 +36,10 @@ class WritableStream
private $buffer = '';
private $chunkOffset = 0;
private $chunkSize;
private $disableMD5;
private $collectionWrapper;
private $ctx;
private $file;
private $hashCtx;
private $isClosed = false;
private $length = 0;
......@@ -56,6 +57,9 @@ class WritableStream
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to
* 261120 (i.e. 255 KiB).
*
* * disableMD5 (boolean): When true, no MD5 sum will be generated.
* Defaults to "false".
*
* * contentType (string): DEPRECATED content type to be stored with the
* file. This information should now be added to the metadata.
*
......@@ -72,6 +76,7 @@ class WritableStream
$options += [
'_id' => new ObjectId,
'chunkSizeBytes' => self::$defaultChunkSizeBytes,
'disableMD5' => false,
];
if (isset($options['aliases']) && ! \MongoDB\is_string_array($options['aliases'])) {
......@@ -86,6 +91,10 @@ class WritableStream
throw new InvalidArgumentException(sprintf('Expected "chunkSizeBytes" option to be >= 1, %d given', $options['chunkSizeBytes']));
}
if (isset($options['disableMD5']) && ! is_bool($options['disableMD5'])) {
throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean');
}
if (isset($options['contentType']) && ! is_string($options['contentType'])) {
throw InvalidArgumentException::invalidType('"contentType" option', $options['contentType'], 'string');
}
......@@ -96,7 +105,11 @@ class WritableStream
$this->chunkSize = $options['chunkSizeBytes'];
$this->collectionWrapper = $collectionWrapper;
$this->ctx = hash_init('md5');
$this->disableMD5 = $options['disableMD5'];
if ( ! $this->disableMD5) {
$this->hashCtx = hash_init('md5');
}
$this->file = [
'_id' => $options['_id'],
......@@ -167,7 +180,7 @@ class WritableStream
* written. Since seeking is not supported and writes are appended, this is
* always the end of the stream.
*
* @see WriteableStream::getSize()
* @see WritableStream::getSize()
* @return integer
*/
public function tell()
......@@ -219,12 +232,13 @@ class WritableStream
private function fileCollectionInsert()
{
$md5 = hash_final($this->ctx);
$this->file['length'] = $this->length;
$this->file['md5'] = $md5;
$this->file['uploadDate'] = new UTCDateTime;
if ( ! $this->disableMD5) {
$this->file['md5'] = hash_final($this->hashCtx);
}
try {
$this->collectionWrapper->insertFile($this->file);
} catch (DriverRuntimeException $e) {
......@@ -251,7 +265,9 @@ class WritableStream
'data' => new Binary($data, Binary::TYPE_GENERIC),
];
hash_update($this->ctx, $data);
if ( ! $this->disableMD5) {
hash_update($this->hashCtx, $data);
}
try {
$this->collectionWrapper->insertChunk($chunk);
......
......@@ -54,6 +54,10 @@ class BucketFunctionalTest extends FunctionalTestCase
$options[][] = ['chunkSizeBytes' => $value];
}
foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['disableMD5' => $value];
}
foreach ($this->getInvalidReadConcernValues() as $value) {
$options[][] = ['readConcern' => $value];
}
......
......@@ -49,6 +49,10 @@ class WritableStreamFunctionalTest extends FunctionalTestCase
$options[][] = ['chunkSizeBytes' => $value];
}
foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['disableMD5' => $value];
}
foreach ($this->getInvalidDocumentValues() as $value) {
$options[][] = ['metadata' => $value];
}
......
......@@ -382,6 +382,85 @@
}
]
}
},
{
"description": "Upload when length is 0 sans MD5",
"act": {
"operation": "upload",
"arguments": {
"filename": "filename",
"source": {
"$hex": ""
},
"options": {
"chunkSizeBytes": 4,
"disableMD5": true
}
}
},
"assert": {
"result": "&result",
"data": [
{
"insert": "expected.files",
"documents": [
{
"_id": "*result",
"length": 0,
"chunkSize": 4,
"uploadDate": "*actual",
"filename": "filename"
}
]
}
]
}
},
{
"description": "Upload when length is 1 sans MD5",
"act": {
"operation": "upload",
"arguments": {
"filename": "filename",
"source": {
"$hex": "11"
},
"options": {
"chunkSizeBytes": 4,
"disableMD5": true
}
}
},
"assert": {
"result": "&result",
"data": [
{
"insert": "expected.files",
"documents": [
{
"_id": "*result",
"length": 1,
"chunkSize": 4,
"uploadDate": "*actual",
"filename": "filename"
}
]
},
{
"insert": "expected.chunks",
"documents": [
{
"_id": "*actual",
"files_id": "*result",
"n": 0,
"data": {
"$hex": "11"
}
}
]
}
]
}
}
]
}
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