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

Merged pull request #541

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