Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongo-php-library
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sinan
mongo-php-library
Commits
f2666e19
Commit
f2666e19
authored
Jan 11, 2016
by
Jeremy Mikola
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Apply CS fixes and refactor GridFS classes
parent
0b31800c
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
824 additions
and
303 deletions
+824
-303
GridFSFileNotFoundException.php
src/Exception/GridFSFileNotFoundException.php
+4
-3
Bucket.php
src/GridFS/Bucket.php
+267
-133
GridFSCollectionsWrapper.php
src/GridFS/GridFSCollectionsWrapper.php
+45
-72
GridFSDownload.php
src/GridFS/GridFSDownload.php
+163
-0
GridFSUpload.php
src/GridFS/GridFSUpload.php
+254
-0
StreamWrapper.php
src/GridFS/StreamWrapper.php
+62
-48
BucketFunctionalTest.php
tests/GridFS/BucketFunctionalTest.php
+8
-8
GridFSStreamTest.php
tests/GridFS/GridFSStreamTest.php
+21
-39
No files found.
src/Exception/GridFSFileNotFoundException.php
View file @
f2666e19
...
@@ -4,7 +4,8 @@ namespace MongoDB\Exception;
...
@@ -4,7 +4,8 @@ namespace MongoDB\Exception;
class
GridFSFileNotFoundException
extends
\MongoDB\Driver\Exception\RuntimeException
implements
Exception
class
GridFSFileNotFoundException
extends
\MongoDB\Driver\Exception\RuntimeException
implements
Exception
{
{
public
function
__construct
(
$fname
,
$nameSpace
){
public
function
__construct
(
$filename
,
$namespace
)
parent
::
__construct
(
sprintf
(
'Unable to find file by: %s in %s'
,
$fname
,
$nameSpace
));
{
}
parent
::
__construct
(
sprintf
(
'Unable to find file "%s" in namespace "%s"'
,
$filename
,
$namespace
));
}
}
}
src/GridFS/Bucket.php
View file @
f2666e19
<?php
<?php
namespace
MongoDB\GridFS
;
namespace
MongoDB\GridFS
;
use
MongoDB\Collection
;
use
MongoDB\BSON\ObjectId
;
use
MongoDB\BSON\ObjectId
;
use
MongoDB\Driver\Cursor
;
use
MongoDB\Driver\Manager
;
use
MongoDB\Driver\Manager
;
use
MongoDB\Exception\GridFSFileNotFoundException
;
use
MongoDB\Exception\InvalidArgumentTypeException
;
use
MongoDB\Operation\Find
;
/**
/**
* Bucket provides a public API for interacting with the GridFS files and chunks
* collections.
*
* @api
* @api
* Bucket abstracts the GridFS files and chunks collections.
*/
*/
class
Bucket
class
Bucket
{
{
private
$databaseName
;
private
static
$streamWrapper
;
private
$collectionsWrapper
;
private
$collectionsWrapper
;
private
$databaseName
;
private
$options
;
private
$options
;
private
static
$streamWrapper
;
/**
/**
* Constructs a GridFS bucket.
* Constructs a GridFS bucket.
*
*
...
@@ -29,199 +38,324 @@ class Bucket
...
@@ -29,199 +38,324 @@ class Bucket
*
*
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
*
*
* @param Manager
$manager Manager instance from the driver
* @param Manager $manager Manager instance from the driver
* @param string
$databaseName Database name
* @param string $databaseName Database name
* @param array
$options Bucket options
* @param array $options Bucket options
* @throws InvalidArgumentException
* @throws InvalidArgumentException
*/
*/
public
function
__construct
(
Manager
$manager
,
$databaseName
,
array
$options
=
[])
public
function
__construct
(
Manager
$manager
,
$databaseName
,
array
$options
=
[])
{
{
$options
+=
[
$options
+=
[
'bucketName'
=>
'fs'
,
'chunkSizeBytes'
=>
261120
,
'chunkSizeBytes'
=>
261120
,
'bucketName'
=>
'fs'
];
];
if
(
isset
(
$options
[
'bucketName'
])
&&
!
is_string
(
$options
[
'bucketName'
]))
{
throw
new
InvalidArgumentTypeException
(
'"bucketName" option'
,
$options
[
'bucketName'
],
'string'
);
}
if
(
isset
(
$options
[
'chunkSizeBytes'
])
&&
!
is_integer
(
$options
[
'chunkSizeBytes'
]))
{
throw
new
InvalidArgumentTypeException
(
'"chunkSizeBytes" option'
,
$options
[
'chunkSizeBytes'
],
'integer'
);
}
if
(
isset
(
$options
[
'readPreference'
])
&&
!
$options
[
'readPreference'
]
instanceof
ReadPreference
)
{
throw
new
InvalidArgumentTypeException
(
'"readPreference" option'
,
$options
[
'readPreference'
],
'MongoDB\Driver\ReadPreference'
);
}
if
(
isset
(
$options
[
'writeConcern'
])
&&
!
$options
[
'writeConcern'
]
instanceof
WriteConcern
)
{
throw
new
InvalidArgumentTypeException
(
'"writeConcern" option'
,
$options
[
'writeConcern'
],
'MongoDB\Driver\WriteConcern'
);
}
$this
->
databaseName
=
(
string
)
$databaseName
;
$this
->
databaseName
=
(
string
)
$databaseName
;
$this
->
options
=
$options
;
$this
->
options
=
$options
;
$this
->
collectionsWrapper
=
new
GridFSCollectionsWrapper
(
$manager
,
$databaseName
,
$options
);
$collectionOptions
=
array_intersect_key
(
$options
,
[
'readPreference'
=>
1
,
'writeConcern'
=>
1
]);
$this
->
collectionsWrapper
=
new
GridFSCollectionsWrapper
(
$manager
,
$databaseName
,
$options
[
'bucketName'
],
$collectionOptions
);
$this
->
registerStreamWrapper
(
$manager
);
$this
->
registerStreamWrapper
(
$manager
);
}
}
/**
/**
* Opens a Stream for writing the contents of a file.
* Delete a file from the GridFS bucket.
*
* If the files collection document is not found, this method will still
* attempt to delete orphaned chunks.
*
*
* @param string $filename file to upload
* @param ObjectId $id ObjectId of the file
* @param array $options Stream Options
* @throws GridFSFileNotFoundException
* @return Stream uploadStream
*/
*/
public
function
openUploadStream
(
$filename
,
array
$options
=
[]
)
public
function
delete
(
ObjectId
$id
)
{
{
$options
+=
[
'chunkSizeBytes'
=>
$this
->
options
[
'chunkSizeBytes'
]];
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
'_id'
=>
$id
]);
$streamOptions
=
[
$this
->
collectionsWrapper
->
getChunksCollection
()
->
deleteMany
([
'files_id'
=>
$id
]);
'collectionsWrapper'
=>
$this
->
collectionsWrapper
,
'uploadOptions'
=>
$options
if
(
$file
===
null
)
{
];
throw
new
GridFSFileNotFoundException
(
$id
,
$this
->
collectionsWrapper
->
getFilesCollection
()
->
getNameSpace
());
$context
=
stream_context_create
([
'gridfs'
=>
$streamOptions
]);
}
return
fopen
(
sprintf
(
'gridfs://%s/%s'
,
$this
->
databaseName
,
$filename
),
'w'
,
false
,
$context
);
$this
->
collectionsWrapper
->
getFilesCollection
()
->
deleteOne
([
'_id'
=>
$id
]);
}
}
/**
/**
*
Upload a file to this bucket by specifying the source stream file
*
Writes the contents of a GridFS file to a writable stream.
*
*
* @param String $filename Filename To Insert
* @param ObjectId $id ObjectId of the file
* @param Stream $source Source Stream
* @param resource $destination Writable Stream
* @param array $options Stream Options
* @throws GridFSFileNotFoundException
* @return ObjectId
*/
*/
public
function
uploadFromStream
(
$filename
,
$source
,
array
$options
=
[]
)
public
function
downloadToStream
(
ObjectId
$id
,
$destination
)
{
{
$options
+=
[
'chunkSizeBytes'
=>
$this
->
options
[
'chunkSizeBytes'
]];
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
(
$gridFsStream
=
new
GridFsUpload
(
$this
->
collectionsWrapper
,
$filename
,
$options
);
[
'_id'
=>
$id
],
return
$gridFsStream
->
uploadFromStream
(
$source
);
[
'typeMap'
=>
[
'root'
=>
'stdClass'
]]
);
if
(
$file
===
null
)
{
throw
new
GridFSFileNotFoundException
(
$id
,
$this
->
collectionsWrapper
->
getFilesCollection
()
->
getNameSpace
());
}
$gridFsStream
=
new
GridFSDownload
(
$this
->
collectionsWrapper
,
$file
);
$gridFsStream
->
downloadToStream
(
$destination
);
}
}
/**
/**
* Opens a Stream for reading the contents of a file specified by ID.
* Writes the contents of a GridFS file, which is selected by name and
* revision, to a writable stream.
*
* Supported options:
*
* * revision (integer): Which revision (i.e. documents with the same
* filename and different uploadDate) of the file to retrieve. Defaults
* to -1 (i.e. the most recent revision).
*
* Revision numbers are defined as follows:
*
*
* @param ObjectId $id
* * 0 = the original stored file
* @return Stream
* * 1 = the first revision
* * 2 = the second revision
* * etc…
* * -2 = the second most recent revision
* * -1 = the most recent revision
*
* @param string $filename File name
* @param resource $destination Writable Stream
* @param array $options Download options
* @throws GridFSFileNotFoundException
*/
*/
public
function
openDownloadStream
(
\MongoDB\BSON\ObjectId
$id
)
public
function
downloadToStreamByName
(
$filename
,
$destination
,
array
$options
=
[]
)
{
{
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
'_id'
=>
$id
]);
$options
+=
[
'revision'
=>
-
1
];
if
(
is_null
(
$file
))
{
$file
=
$this
->
findFileRevision
(
$filename
,
$options
[
'revision'
]);
throw
new
\MongoDB\Exception\GridFSFileNotFoundException
(
$id
,
$this
->
collectionsWrapper
->
getFilesCollection
()
->
getNameSpace
());
$gridFsStream
=
new
GridFSDownload
(
$this
->
collectionsWrapper
,
$file
);
}
$gridFsStream
->
downloadToStream
(
$destination
);
return
$this
->
openDownloadStreamByFile
(
$file
);
}
}
/**
* Downloads the contents of the stored file specified by id and writes
/**
* the contents to the destination Stream.
* Find files from the GridFS bucket's files collection.
* @param ObjectId $id GridFS File Id
*
* @param Stream $destination Destination Stream
* @see Find::__construct() for supported options
*/
* @param array|object $filter Query by which to filter documents
public
function
downloadToStream
(
\MongoDB\BSON\ObjectId
$id
,
$destination
)
* @param array $options Additional options
* @return Cursor
*/
public
function
find
(
$filter
,
array
$options
=
[])
{
{
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
'_id'
=>
$id
]);
return
$this
->
collectionsWrapper
->
getFilesCollection
()
->
find
(
$filter
,
$options
);
if
(
is_null
(
$file
))
{
throw
new
\MongoDB\Exception\GridFSFileNotFoundException
(
$id
,
$this
->
collectionsWrapper
->
getFilesCollection
()
->
getNameSpace
());
}
$gridFsStream
=
new
GridFsDownload
(
$this
->
collectionsWrapper
,
$file
);
$gridFsStream
->
downloadToStream
(
$destination
);
}
}
public
function
getCollectionsWrapper
()
{
return
$this
->
collectionsWrapper
;
}
public
function
getDatabaseName
()
{
return
$this
->
databaseName
;
}
/**
/**
* Delete a file from the GridFS bucket. If the file collection entry is not found, still attempts to delete orphaned chunks
* Gets the ID of the GridFS file associated with a stream.
*
*
* @param ObjectId $id file id
* @param resource $stream GridFS stream
* @throws GridFSFileNotFoundException
* @return mixed
*/
*/
public
function
delete
(
\MongoDB\BSON\ObjectId
$id
)
public
function
getIdFromStream
(
$stream
)
{
{
$
file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
'_id'
=>
$id
]
);
$
metadata
=
stream_get_meta_data
(
$stream
);
$this
->
collectionsWrapper
->
getChunksCollection
()
->
deleteMany
([
'files_id'
=>
$id
]);
if
(
is
_null
(
$file
))
{
if
(
is
set
(
$metadata
[
'wrapper_data'
]
->
id
))
{
throw
new
\MongoDB\Exception\GridFSFileNotFoundException
(
$id
,
$this
->
collectionsWrapper
->
getFilesCollection
()
->
getNameSpace
())
;
return
$metadata
[
'wrapper_data'
]
->
id
;
}
}
$this
->
collectionsWrapper
->
getFilesCollection
()
->
deleteOne
([
'_id'
=>
$id
]);
return
;
}
}
/**
/**
* 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
* Opens a readable stream for reading a GridFS file.
* @param string $filename name of the file to download
*
* @param int $revision the revision of the file to download
* @param ObjectId $id ObjectId of the file
* @throws GridFSFileNotFoundException
* @return resource
*/
* @throws GridFSFileNotFoundException
public
function
openDownloadStreamByName
(
$filename
,
$revision
=
-
1
)
*/
{
public
function
openDownloadStream
(
ObjectId
$id
)
$file
=
$this
->
findFileRevision
(
$filename
,
$revision
);
{
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
(
[
'_id'
=>
$id
],
[
'typeMap'
=>
[
'root'
=>
'stdClass'
]]
);
if
(
$file
===
null
)
{
throw
new
GridFSFileNotFoundException
(
$id
,
$this
->
collectionsWrapper
->
getFilesCollection
()
->
getNameSpace
());
}
return
$this
->
openDownloadStreamByFile
(
$file
);
return
$this
->
openDownloadStreamByFile
(
$file
);
}
}
/**
/**
* Download a file from the GridFS bucket by name. Searches for the file by the specified name then loads data into the stream
* Opens a readable stream stream to read a GridFS file, which is selected
*
* by name and revision.
* @param string $filename name of the file to download
*
* @param int $revision the revision of the file to download
* Supported options:
* @throws GridFSFileNotFoundException
*
*/
* * revision (integer): Which revision (i.e. documents with the same
public
function
downloadToStreamByName
(
$filename
,
$destination
,
$revision
=-
1
)
* filename and different uploadDate) of the file to retrieve. Defaults
{
* to -1 (i.e. the most recent revision).
$file
=
$this
->
findFileRevision
(
$filename
,
$revision
);
*
$gridFsStream
=
new
GridFsDownload
(
$this
->
collectionsWrapper
,
$file
);
* Revision numbers are defined as follows:
$gridFsStream
->
downloadToStream
(
$destination
);
*
}
* * 0 = the original stored file
/**
* * 1 = the first revision
* Find files from the GridFS bucket files collection.
* * 2 = the second revision
*
* * etc…
* @param array $filter filter to find by
* * -2 = the second most recent revision
* @param array $options options to
* * -1 = the most recent revision
*/
*
public
function
find
(
$filter
,
array
$options
=
[])
* @param string $filename File name
* @param array $options Download options
* @return resource
* @throws GridFSFileNotFoundException
*/
public
function
openDownloadStreamByName
(
$filename
,
array
$options
=
[])
{
{
return
$this
->
collectionsWrapper
->
getFilesCollection
()
->
find
(
$filter
,
$options
);
$options
+=
[
'revision'
=>
-
1
];
$file
=
$this
->
findFileRevision
(
$filename
,
$options
[
'revision'
]);
return
$this
->
openDownloadStreamByFile
(
$file
);
}
}
/**
/**
* Gets the id of the GridFs file associated with $stream
* Opens a writable stream for writing a GridFS file.
*
*
* @param resource $stream wrapped gridFsStream
* Supported options:
*/
*
public
function
getIdFromStream
(
$stream
)
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the
* bucket's chunk size.
*
* @param string $filename File name
* @param array $options Stream options
* @return resource
*/
public
function
openUploadStream
(
$filename
,
array
$options
=
[])
{
{
$metadata
=
stream_get_meta_data
(
$stream
);
$options
+=
[
'chunkSizeBytes'
=>
$this
->
options
[
'chunkSizeBytes'
]];
if
(
isset
(
$metadata
[
"wrapper_data"
]
->
id
)){
return
$metadata
[
"wrapper_data"
]
->
id
;
$streamOptions
=
[
}
'collectionsWrapper'
=>
$this
->
collectionsWrapper
,
return
null
;
'uploadOptions'
=>
$options
,
];
$context
=
stream_context_create
([
'gridfs'
=>
$streamOptions
]);
return
fopen
(
sprintf
(
'gridfs://%s/%s'
,
$this
->
databaseName
,
$filename
),
'w'
,
false
,
$context
);
}
}
/**
/**
* Gets the id of the GridFs file associated with $stream
* Renames the GridFS file with the specified ID.
*
*
* @param \MongoDB\BSON\ObjectId $id id
of the file to rename
* @param ObjectId $id ID
of the file to rename
* @param string $newFilename new name for the fil
e
* @param string $newFilename New file nam
e
* @throws \MongoDB\Exception\
GridFSFileNotFoundException
* @throws
GridFSFileNotFoundException
*/
*/
public
function
rename
(
\MongoDB\BSON\
ObjectId
$id
,
$newFilename
)
public
function
rename
(
ObjectId
$id
,
$newFilename
)
{
{
$filesCollection
=
$this
->
collectionsWrapper
->
getFilesCollection
();
$filesCollection
=
$this
->
collectionsWrapper
->
getFilesCollection
();
$file
=
$filesCollection
->
findOne
([
"_id"
=>
$id
]);
$file
=
$filesCollection
->
findOne
([
'_id'
=>
$id
]);
if
(
is_null
(
$file
))
{
throw
new
\MongoDB\Exception\GridFSFileNotFoundException
(
$id
,
$this
->
collectionsWrapper
->
getFilesCollection
()
->
getNameSpace
());
if
(
$file
===
null
)
{
throw
new
GridFSFileNotFoundException
(
$id
,
$this
->
collectionsWrapper
->
getFilesCollection
()
->
getNameSpace
());
}
}
$file
->
filename
=
$newFilename
;
$file
->
filename
=
$newFilename
;
$filesCollection
->
replaceOne
([
"_id"
=>
$id
],
$file
);
$filesCollection
->
replaceOne
([
'_id'
=>
$id
],
$file
);
}
public
function
getCollectionsWrapper
()
{
return
$this
->
collectionsWrapper
;
}
}
public
function
getDatabaseName
(){
return
$this
->
databaseName
;
/**
}
* Writes the contents of a readable stream to a GridFS file.
private
function
openDownloadStreamByFile
(
$file
)
*
* Supported options:
*
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the
* bucket's chunk size.
*
* @param string $filename File name
* @param resource $source Readable stream
* @param array $options Stream options
* @return ObjectId
*/
public
function
uploadFromStream
(
$filename
,
$source
,
array
$options
=
[])
{
{
$options
=
[
'collectionsWrapper'
=>
$this
->
collectionsWrapper
,
$options
+=
[
'chunkSizeBytes'
=>
$this
->
options
[
'chunkSizeBytes'
]];
'file'
=>
$file
$gridFsStream
=
new
GridFSUpload
(
$this
->
collectionsWrapper
,
$filename
,
$options
);
];
$context
=
stream_context_create
([
'gridfs'
=>
$options
]);
return
$gridFsStream
->
uploadFromStream
(
$source
);
return
fopen
(
sprintf
(
'gridfs://%s/%s'
,
$this
->
databaseName
,
$file
->
filename
),
'r'
,
false
,
$context
);
}
}
private
function
findFileRevision
(
$filename
,
$revision
)
private
function
findFileRevision
(
$filename
,
$revision
)
{
{
if
(
$revision
<
0
)
{
if
(
$revision
<
0
)
{
$skip
=
abs
(
$revision
)
-
1
;
$skip
=
abs
(
$revision
)
-
1
;
$sortOrder
=
-
1
;
$sortOrder
=
-
1
;
}
else
{
}
else
{
$skip
=
$revision
;
$skip
=
$revision
;
$sortOrder
=
1
;
$sortOrder
=
1
;
}
}
$filesCollection
=
$this
->
collectionsWrapper
->
getFilesCollection
();
$filesCollection
=
$this
->
collectionsWrapper
->
getFilesCollection
();
$file
=
$filesCollection
->
findOne
([
"filename"
=>
$filename
],
[
"sort"
=>
[
"uploadDate"
=>
$sortOrder
],
"limit"
=>
1
,
"skip"
=>
$skip
]);
$file
=
$filesCollection
->
findOne
(
if
(
is_null
(
$file
))
{
[
'filename'
=>
$filename
],
throw
new
\MongoDB\Exception\GridFSFileNotFoundException
(
$filename
,
$filesCollection
->
getNameSpace
());
[
'skip'
=>
$skip
,
'sort'
=>
[
'uploadDate'
=>
$sortOrder
],
'typeMap'
=>
[
'root'
=>
'stdClass'
],
]
);
if
(
$file
===
null
)
{
throw
new
GridFSFileNotFoundException
(
$filename
,
$filesCollection
->
getNameSpace
());
}
}
return
$file
;
return
$file
;
}
}
private
function
registerStreamWrapper
(
$manager
)
private
function
openDownloadStreamByFile
(
$file
)
{
{
if
(
isset
(
Bucket
::
$streamWrapper
)){
$options
=
[
'collectionsWrapper'
=>
$this
->
collectionsWrapper
,
'file'
=>
$file
,
];
$context
=
stream_context_create
([
'gridfs'
=>
$options
]);
return
fopen
(
sprintf
(
'gridfs://%s/%s'
,
$this
->
databaseName
,
$file
->
filename
),
'r'
,
false
,
$context
);
}
private
function
registerStreamWrapper
(
Manager
$manager
)
{
if
(
isset
(
self
::
$streamWrapper
))
{
return
;
return
;
}
}
Bucket
::
$streamWrapper
=
new
\MongoDB\GridFS\StreamWrapper
();
Bucket
::
$streamWrapper
->
register
(
$manager
);
self
::
$streamWrapper
=
new
StreamWrapper
();
self
::
$streamWrapper
->
register
(
$manager
);
}
}
}
}
src/GridFS/GridFSCollectionsWrapper.php
View file @
f2666e19
<?php
<?php
namespace
MongoDB\GridFS
;
namespace
MongoDB\GridFS
;
use
MongoDB\Collection
;
use
MongoDB\Collection
;
use
MongoDB\Driver\Manager
;
use
MongoDB\Driver\ReadPreference
;
use
MongoDB\Driver\ReadPreference
;
use
MongoDB\Driver\WriteConcern
;
use
MongoDB\Driver\WriteConcern
;
use
MongoDB\Driver\Manager
;
use
MongoDB\Exception\InvalidArgumentTypeException
;
use
MongoDB\Exception\InvalidArgumentTypeException
;
/**
/**
* @internal
* GridFSCollectionsWrapper abstracts the GridFS files and chunks collections.
* GridFSCollectionsWrapper abstracts the GridFS files and chunks collections.
*
* @internal
*/
*/
class
GridFSCollectionsWrapper
class
GridFSCollectionsWrapper
{
{
private
$filesCollection
;
private
$chunksCollection
;
private
$chunksCollection
;
private
$ensuredIndexes
=
false
;
private
$ensuredIndexes
=
false
;
private
$filesCollection
;
/**
/**
* Constructs a GridFS bucket.
* Constructs a GridFS collection wrapper.
*
* Supported options:
*
* * bucketName (string): The bucket name, which will be used as a prefix
* for the files and chunks collections. Defaults to "fs".
*
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to
* 261120 (i.e. 255 KiB).
*
*
* * readPreference (MongoDB\Driver\ReadPreference): Read preference.
* @see Collection::__construct() for supported options
*
* @param Manager $manager Manager instance from the driver
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
* @param string $databaseName Database name
*
* @param string $bucketName Bucket name
* @param Manager $manager Manager instance from the driver
* @param array $collectionOptions Collection options
* @param string $databaseName Database name
* @param array $options Bucket options
* @throws InvalidArgumentException
* @throws InvalidArgumentException
*/
*/
public
function
__construct
(
Manager
$manager
,
$databaseName
,
$
options
)
public
function
__construct
(
Manager
$manager
,
$databaseName
,
$
bucketName
,
array
$collectionOptions
=
[]
)
{
{
$collectionOptions
=
[];
$this
->
filesCollection
=
new
Collection
(
$manager
,
sprintf
(
'%s.%s.files'
,
$databaseName
,
$bucketName
),
$collectionOptions
);
$this
->
chunksCollection
=
new
Collection
(
$manager
,
sprintf
(
'%s.%s.chunks'
,
$databaseName
,
$bucketName
),
$collectionOptions
);
if
(
isset
(
$options
[
'bucketName'
])
&&
!
is_string
(
$options
[
'bucketName'
]))
{
throw
new
InvalidArgumentTypeException
(
'"bucketName" option'
,
$options
[
'bucketName'
],
'string'
);
}
if
(
isset
(
$options
[
'chunkSizeBytes'
])
&&
!
is_integer
(
$options
[
'chunkSizeBytes'
]))
{
throw
new
InvalidArgumentTypeException
(
'"chunkSizeBytes" option'
,
$options
[
'chunkSizeBytes'
],
'integer'
);
}
if
(
isset
(
$options
[
'readPreference'
]))
{
if
(
!
$options
[
'readPreference'
]
instanceof
ReadPreference
)
{
throw
new
InvalidArgumentTypeException
(
'"readPreference" option'
,
$options
[
'readPreference'
],
'MongoDB\Driver\ReadPreference'
);
}
else
{
$collectionOptions
[
'readPreference'
]
=
$options
[
'readPreference'
];
}
}
if
(
isset
(
$options
[
'writeConcern'
]))
{
if
(
!
$options
[
'writeConcern'
]
instanceof
WriteConcern
)
{
throw
new
InvalidArgumentTypeException
(
'"writeConcern" option'
,
$options
[
'writeConcern'
],
'MongoDB\Driver\WriteConcern'
);
}
else
{
$collectionOptions
[
'writeConcern'
]
=
$options
[
'writeConcern'
];
}
}
$this
->
filesCollection
=
new
Collection
(
$manager
,
sprintf
(
'%s.%s.files'
,
$databaseName
,
$options
[
'bucketName'
]),
$collectionOptions
);
$this
->
chunksCollection
=
new
Collection
(
$manager
,
sprintf
(
'%s.%s.chunks'
,
$databaseName
,
$options
[
'bucketName'
]),
$collectionOptions
);
}
}
public
function
chunkInsert
(
$toUpload
)
{
$this
->
ensureIndexes
();
$this
->
chunksCollection
->
insertOne
(
$toUpload
);
}
public
function
fileInsert
(
$toUpload
)
{
$this
->
ensureIndexes
();
$this
->
filesCollection
->
insertOne
(
$toUpload
);
}
public
function
getChunksCollection
()
public
function
getChunksCollection
()
{
{
return
$this
->
chunksCollection
;
return
$this
->
chunksCollection
;
}
}
public
function
getFilesCollection
()
public
function
getFilesCollection
()
{
{
return
$this
->
filesCollection
;
return
$this
->
filesCollection
;
}
}
public
function
insertChunk
(
$chunk
)
{
$this
->
ensureIndexes
();
$this
->
chunksCollection
->
insertOne
(
$chunk
);
}
p
rivate
function
ensureIndexes
(
)
p
ublic
function
insertFile
(
$file
)
{
{
if
(
$this
->
ensuredIndexes
)
{
$this
->
ensureIndexes
();
return
;
$this
->
filesCollection
->
insertOne
(
$file
);
}
if
(
!
$this
->
isFilesCollectionEmpty
())
{
return
;
}
$this
->
ensureFilesIndex
();
$this
->
ensureChunksIndex
();
$this
->
ensuredIndexes
=
true
;
}
}
private
function
ensureChunksIndex
()
private
function
ensureChunksIndex
()
{
{
foreach
(
$this
->
chunksCollection
->
listIndexes
()
as
$index
)
{
foreach
(
$this
->
chunksCollection
->
listIndexes
()
as
$index
)
{
...
@@ -110,8 +64,10 @@ class GridFSCollectionsWrapper
...
@@ -110,8 +64,10 @@ class GridFSCollectionsWrapper
return
;
return
;
}
}
}
}
$this
->
chunksCollection
->
createIndex
([
'files_id'
=>
1
,
'n'
=>
1
],
[
'unique'
=>
true
]);
$this
->
chunksCollection
->
createIndex
([
'files_id'
=>
1
,
'n'
=>
1
],
[
'unique'
=>
true
]);
}
}
private
function
ensureFilesIndex
()
private
function
ensureFilesIndex
()
{
{
foreach
(
$this
->
filesCollection
->
listIndexes
()
as
$index
)
{
foreach
(
$this
->
filesCollection
->
listIndexes
()
as
$index
)
{
...
@@ -119,8 +75,25 @@ class GridFSCollectionsWrapper
...
@@ -119,8 +75,25 @@ class GridFSCollectionsWrapper
return
;
return
;
}
}
}
}
$this
->
filesCollection
->
createIndex
([
'filename'
=>
1
,
'uploadDate'
=>
1
]);
$this
->
filesCollection
->
createIndex
([
'filename'
=>
1
,
'uploadDate'
=>
1
]);
}
}
private
function
ensureIndexes
()
{
if
(
$this
->
ensuredIndexes
)
{
return
;
}
if
(
!
$this
->
isFilesCollectionEmpty
())
{
return
;
}
$this
->
ensureFilesIndex
();
$this
->
ensureChunksIndex
();
$this
->
ensuredIndexes
=
true
;
}
private
function
isFilesCollectionEmpty
()
private
function
isFilesCollectionEmpty
()
{
{
return
null
===
$this
->
filesCollection
->
findOne
([],
[
return
null
===
$this
->
filesCollection
->
findOne
([],
[
...
...
src/GridFS/GridF
s
Download.php
→
src/GridFS/GridF
S
Download.php
View file @
f2666e19
<?php
<?php
namespace
MongoDB\GridFS
;
namespace
MongoDB\GridFS
;
use
MongoDB\
Collec
tion
;
use
MongoDB\
Driver\Exception\Excep
tion
;
use
\
MongoDB\Exception\GridFSCorruptFileException
;
use
MongoDB\Exception\GridFSCorruptFileException
;
use
\MongoDB\Exception\InvalidArgumentTypeException
;
use
stdClass
;
/**
/**
* GridFSDownload abstracts the process of reading a GridFS file.
*
* @internal
* @internal
* GridFSDownload abstracts the processes of downloading from a GridFSBucket
*/
*/
class
GridF
s
Download
class
GridF
S
Download
{
{
private
$buffer
;
private
$bufferEmpty
=
true
;
private
$bufferFresh
=
true
;
private
$bytesSeen
=
0
;
private
$chunkOffset
=
0
;
private
$chunksIterator
;
private
$chunksIterator
;
private
$bytesSeen
=
0
;
private
$numChunks
;
private
$iteratorEmpty
=
false
;
private
$firstCheck
=
true
;
private
$bufferFresh
=
true
;
private
$bufferEmpty
=
true
;
private
$collectionsWrapper
;
private
$collectionsWrapper
;
private
$chunkOffset
=
0
;
private
$buffer
;
private
$file
;
private
$file
;
private
$firstCheck
=
true
;
private
$iteratorEmpty
=
false
;
private
$numChunks
;
/**
/**
* Constructs a GridFS download stream
* Constructs a GridFS download stream.
*
*
*
* @param GridFSCollectionsWrapper $collectionsWrapper
File options
* @param GridFSCollectionsWrapper $collectionsWrapper
GridFS collections wrapper
* @param
\stdClass $file GridFS file to use
* @param
stdClass $file GridFS file document
* @throws GridFSCorruptFileException
, InvalidArgumentTypeException
* @throws GridFSCorruptFileException
*/
*/
public
function
__construct
(
public
function
__construct
(
GridFSCollectionsWrapper
$collectionsWrapper
,
stdClass
$file
)
GridFSCollectionsWrapper
$collectionsWrapper
,
$file
)
{
{
if
(
!
(
$file
instanceof
\stdClass
)){
throw
new
\MongoDB\Exception\InvalidArgumentTypeException
(
'"file"'
,
$file
,
'stdClass'
);
}
$this
->
collectionsWrapper
=
$collectionsWrapper
;
$this
->
collectionsWrapper
=
$collectionsWrapper
;
$this
->
file
=
$file
;
$this
->
file
=
$file
;
try
{
$cursor
=
$this
->
collectionsWrapper
->
getChunksCollection
()
->
find
([
'files_id'
=>
$this
->
file
->
_id
],
[
'sort'
=>
[
'n'
=>
1
]]);
try
{
}
catch
(
\MongoDB\Exception
$e
){
$cursor
=
$this
->
collectionsWrapper
->
getChunksCollection
()
->
find
(
throw
new
\MongoDB\Exception\GridFSCorruptFileException
();
[
'files_id'
=>
$this
->
file
->
_id
],
[
'sort'
=>
[
'n'
=>
1
]]
);
}
catch
(
Exception
$e
)
{
// TODO: Why do we replace a driver exception with GridFSCorruptFileException here?
throw
new
GridFSCorruptFileException
();
}
}
$this
->
chunksIterator
=
new
\IteratorIterator
(
$cursor
);
$this
->
chunksIterator
=
new
\IteratorIterator
(
$cursor
);
if
(
$this
->
file
->
length
>=
0
)
{
$this
->
numChunks
=
(
$file
->
length
>=
0
)
?
ceil
(
$file
->
length
/
$file
->
chunkSize
)
:
0
;
$this
->
numChunks
=
ceil
(
$this
->
file
->
length
/
$this
->
file
->
chunkSize
);
}
else
{
$this
->
numChunks
=
0
;
}
$this
->
buffer
=
fopen
(
'php://temp'
,
'w+'
);
$this
->
buffer
=
fopen
(
'php://temp'
,
'w+'
);
}
}
public
function
downloadToStream
(
$destination
)
public
function
close
()
{
{
while
(
$this
->
advanceChunks
())
{
fclose
(
$this
->
buffer
);
fwrite
(
$destination
,
$this
->
chunksIterator
->
current
()
->
data
->
getData
());
}
}
}
public
function
downloadNumBytes
(
$numToRead
)
{
public
function
downloadNumBytes
(
$numToRead
)
{
$output
=
""
;
$output
=
""
;
if
(
$this
->
bufferFresh
)
{
if
(
$this
->
bufferFresh
)
{
rewind
(
$this
->
buffer
);
rewind
(
$this
->
buffer
);
$this
->
bufferFresh
=
false
;
$this
->
bufferFresh
=
false
;
}
}
// TODO: Should we be checking for fread errors here?
$output
=
fread
(
$this
->
buffer
,
$numToRead
);
$output
=
fread
(
$this
->
buffer
,
$numToRead
);
if
(
strlen
(
$output
)
==
$numToRead
)
{
if
(
strlen
(
$output
)
==
$numToRead
)
{
return
$output
;
return
$output
;
}
}
fclose
(
$this
->
buffer
);
fclose
(
$this
->
buffer
);
$this
->
buffer
=
fopen
(
"php://temp"
,
"w+"
);
$this
->
buffer
=
fopen
(
"php://temp"
,
"w+"
);
$this
->
bufferFresh
=
true
;
$this
->
bufferFresh
=
true
;
$this
->
bufferEmpty
=
true
;
$this
->
bufferEmpty
=
true
;
$bytesLeft
=
$numToRead
-
strlen
(
$output
);
$bytesLeft
=
$numToRead
-
strlen
(
$output
);
while
(
strlen
(
$output
)
<
$numToRead
&&
$this
->
advanceChunks
())
{
while
(
strlen
(
$output
)
<
$numToRead
&&
$this
->
advanceChunks
())
{
$bytesLeft
=
$numToRead
-
strlen
(
$output
);
$bytesLeft
=
$numToRead
-
strlen
(
$output
);
$output
.=
substr
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
(),
0
,
$bytesLeft
);
$output
.=
substr
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
(),
0
,
$bytesLeft
);
}
}
if
(
!
$this
->
iteratorEmpty
&&
$this
->
file
->
length
>
0
&&
$bytesLeft
<
strlen
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
()))
{
if
(
!
$this
->
iteratorEmpty
&&
$this
->
file
->
length
>
0
&&
$bytesLeft
<
strlen
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
()))
{
fwrite
(
$this
->
buffer
,
substr
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
(),
$bytesLeft
));
fwrite
(
$this
->
buffer
,
substr
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
(),
$bytesLeft
));
$this
->
bufferEmpty
=
false
;
$this
->
bufferEmpty
=
false
;
}
}
return
$output
;
return
$output
;
}
}
public
function
getSize
()
public
function
downloadToStream
(
$destination
)
{
{
return
$this
->
file
->
length
;
while
(
$this
->
advanceChunks
())
{
// TODO: Should we be checking for fwrite errors here?
fwrite
(
$destination
,
$this
->
chunksIterator
->
current
()
->
data
->
getData
());
}
}
}
public
function
getFile
()
{
return
$this
->
file
;
}
public
function
getId
()
public
function
getId
()
{
{
return
$this
->
file
->
_id
;
return
$this
->
file
->
_id
;
}
}
public
function
getFile
()
public
function
getSize
()
{
{
return
$this
->
file
;
return
$this
->
file
->
length
;
}
public
function
isEOF
()
{
return
(
$this
->
iteratorEmpty
&&
$this
->
bufferEmpty
);
}
}
private
function
advanceChunks
()
private
function
advanceChunks
()
{
{
if
(
$this
->
chunkOffset
>=
$this
->
numChunks
)
{
if
(
$this
->
chunkOffset
>=
$this
->
numChunks
)
{
$this
->
iteratorEmpty
=
true
;
$this
->
iteratorEmpty
=
true
;
return
false
;
return
false
;
}
}
if
(
$this
->
firstCheck
)
{
if
(
$this
->
firstCheck
)
{
$this
->
chunksIterator
->
rewind
();
$this
->
chunksIterator
->
rewind
();
$this
->
firstCheck
=
false
;
$this
->
firstCheck
=
false
;
}
else
{
}
else
{
$this
->
chunksIterator
->
next
();
$this
->
chunksIterator
->
next
();
}
}
if
(
!
$this
->
chunksIterator
->
valid
())
{
throw
new
\MongoDB\Exception\GridFSCorruptFileException
();
if
(
!
$this
->
chunksIterator
->
valid
())
{
throw
new
GridFSCorruptFileException
();
}
}
if
(
$this
->
chunksIterator
->
current
()
->
n
!=
$this
->
chunkOffset
)
{
if
(
$this
->
chunksIterator
->
current
()
->
n
!=
$this
->
chunkOffset
)
{
throw
new
\MongoDB\Exception\
GridFSCorruptFileException
();
throw
new
GridFSCorruptFileException
();
}
}
$chunkSizeIs
=
strlen
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
());
if
(
$this
->
chunkOffset
==
$this
->
numChunks
-
1
)
{
$actualChunkSize
=
strlen
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
());
$chunkSizeShouldBe
=
$this
->
file
->
length
-
$this
->
bytesSeen
;
if
(
$chunkSizeShouldBe
!=
$chunkSizeIs
)
{
$expectedChunkSize
=
(
$this
->
chunkOffset
==
$this
->
numChunks
-
1
)
throw
new
\MongoDB\Exception\GridFSCorruptFileException
();
?
(
$this
->
file
->
length
-
$this
->
bytesSeen
)
}
:
$this
->
file
->
chunkSize
;
}
else
if
(
$this
->
chunkOffset
<
$this
->
numChunks
-
1
)
{
if
(
$chunkSizeIs
!=
$this
->
file
->
chunkSize
)
{
if
(
$actualChunkSize
!=
$expectedChunkSize
)
{
throw
new
\MongoDB\Exception\GridFSCorruptFileException
();
throw
new
GridFSCorruptFileException
();
}
}
}
$this
->
bytesSeen
+=
$chunkSizeIs
;
$this
->
bytesSeen
+=
$actualChunkSize
;
$this
->
chunkOffset
++
;
$this
->
chunkOffset
++
;
return
true
;
}
public
function
close
()
{
fclose
(
$this
->
buffer
);
}
public
function
isEOF
()
return
true
;
{
$eof
=
$this
->
iteratorEmpty
&&
$this
->
bufferEmpty
;
return
$eof
;
}
}
}
}
src/GridFS/GridF
s
Upload.php
→
src/GridFS/GridF
S
Upload.php
View file @
f2666e19
<?php
<?php
namespace
MongoDB\GridFS
;
namespace
MongoDB\GridFS
;
use
MongoDB\Collection
;
use
MongoDB\BSON\Binary
;
use
MongoDB\BSON\ObjectId
;
use
MongoDB\BSON\UTCDateTime
;
use
MongoDB\Driver\Exception\Exception
;
use
MongoDB\Exception\InvalidArgumentTypeException
;
use
MongoDB\Exception\InvalidArgumentTypeException
;
use
MongoDB\BSON
;
/**
/**
* GridFSUpload abstracts the process of writing a GridFS file.
*
* @internal
* @internal
* GridFsupload abstracts the processes of inserting into a GridFSBucket
*/
*/
class
GridF
s
Upload
class
GridF
S
Upload
{
{
private
$
ctx
;
private
$
buffer
;
private
$bufferLength
=
0
;
private
$bufferLength
=
0
;
private
$indexChecker
;
private
$length
=
0
;
private
$collectionsWrapper
;
private
$chunkOffset
=
0
;
private
$chunkOffset
=
0
;
private
$chunkSize
;
private
$chunkSize
;
private
$buffer
;
private
$collectionsWrapper
;
private
$ctx
;
private
$file
;
private
$file
;
private
$indexChecker
;
private
$isClosed
=
false
;
private
$isClosed
=
false
;
private
$length
=
0
;
/**
/**
* Constructs a GridFS upload stream
* Constructs a GridFS upload stream
.
*
*
* Supported options:
* Supported options:
*
*
* * contentType (string): DEPRECATED content type to be stored with the file.
* * aliases (array of strings): DEPRECATED An array of aliases.
* This information should now be added to the metadata
* Applications wishing to store aliases should add an aliases field to
* the metadata document instead.
*
*
* * aliases (array of strings): DEPRECATED An array of aliases.
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to
* Applications wishing to store aliases should add an aliases field to the
* 261120 (i.e. 255 KiB).
* metadata document instead.
*
* * metadata (array or object): User data for the 'metadata' field of the files
* collection document.
*
*
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
* * contentType (string): DEPRECATED content type to be stored with the
* file. This information should now be added to the metadata.
*
*
* * chunkSizeBytes: size of each chunk
* * metadata (document): User data for the "metadata" field of the files
* collection document.
*
*
* @param GridFSCollectionsWrapper $collectionsWrapper
Files Collection
* @param GridFSCollectionsWrapper $collectionsWrapper
GridFS collections wrapper
* @param string $filename
Filename to insert
* @param string $filename
File name
* @param array $options
File
options
* @param array $options
Upload
options
* @throws InvalidArgumentTypeException
* @throws InvalidArgumentTypeException
*/
*/
public
function
__construct
(
public
function
__construct
(
GridFSCollectionsWrapper
$collectionsWrapper
,
$filename
,
array
$options
=
[])
GridFsCollectionsWrapper
$collectionsWrapper
,
$filename
,
array
$options
=
[]
)
{
{
$this
->
ctx
=
hash_init
(
'md5'
);
$options
+=
[
'chunkSizeBytes'
=>
261120
];
$this
->
collectionsWrapper
=
$collectionsWrapper
;
$this
->
buffer
=
fopen
(
'php://temp'
,
'w+'
);
$options
+=
[
'chunkSizeBytes'
=>
261120
];
if
(
isset
(
$options
[
'aliases'
])
&&
!
\MongoDB\is_string_array
(
$options
[
'aliases'
]))
{
$this
->
chunkSize
=
$options
[
'chunkSizeBytes'
];
throw
new
InvalidArgumentTypeException
(
'"aliases" option'
,
$options
[
'aliases'
],
'array of strings'
);
$time
=
$this
->
millitime
();
$uploadDate
=
new
\MongoDB\BSON\UTCDateTime
(
$time
);
$objectId
=
new
\MongoDB\BSON\ObjectId
();
$main_file
=
[
"chunkSize"
=>
$this
->
chunkSize
,
"filename"
=>
$filename
,
"uploadDate"
=>
$uploadDate
,
"_id"
=>
$objectId
];
$fileOptions
=
[];
if
(
isset
(
$options
[
'contentType'
]))
{
if
(
is_string
(
$options
[
'contentType'
]))
{
$fileOptions
[
'contentType'
]
=
$options
[
'contentType'
];
}
else
{
throw
new
\MongoDB\Exception\InvalidArgumentTypeException
(
'"contentType" option'
,
$options
[
'contentType'
],
'string'
);
}
}
if
(
isset
(
$options
[
'aliases'
]))
{
if
(
\MongoDB\is_string_array
(
$options
[
'aliases'
]))
{
$fileOptions
[
'aliases'
]
=
$options
[
'aliases'
];
}
else
{
throw
new
\MongoDB\Exception\InvalidArgumentTypeException
(
'"aliases" option'
,
$options
[
'aliases'
],
'array of strings'
);
}
}
}
if
(
isset
(
$options
[
'metadata'
]))
{
if
(
isset
(
$options
[
'contentType'
])
&&
!
is_string
(
$options
[
'contentType'
]))
{
if
(
is_array
(
$options
[
'metadata'
])
||
is_object
(
$options
[
'metadata'
]))
{
throw
new
InvalidArgumentTypeException
(
'"contentType" option'
,
$options
[
'contentType'
],
'string'
);
$fileOptions
[
'metadata'
]
=
$options
[
'metadata'
];
}
else
{
throw
new
\MongoDB\Exception\InvalidArgumentTypeException
(
'"metadata" option'
,
$options
[
'metadata'
],
'object or array'
);
}
}
}
$this
->
file
=
array_merge
(
$main_file
,
$fileOptions
);
}
if
(
isset
(
$options
[
'metadata'
])
&&
!
is_array
(
$options
[
'metadata'
])
&&
!
is_object
(
$options
[
'metadata'
]))
{
/**
throw
new
InvalidArgumentTypeException
(
'"metadata" option'
,
$options
[
'metadata'
],
'array or object'
);
* Reads data from a stream into GridFS
*
* @param Stream $source Source Stream
* @return ObjectId
*/
public
function
uploadFromStream
(
$source
)
{
if
(
!
is_resource
(
$source
)
||
get_resource_type
(
$source
)
!=
"stream"
)
{
throw
new
UnexpectedTypeException
(
'stream'
,
$source
);
}
else
{
$streamMetadata
=
stream_get_meta_data
(
$source
);
}
while
(
$data
=
$this
->
readChunk
(
$source
))
{
$this
->
insertChunk
(
$data
);
}
return
$this
->
fileCollectionInsert
();
}
/**
* Insert a chunks into GridFS from a string
*
* @param string $toWrite String to upload
* @return int
*/
public
function
insertChunks
(
$toWrite
)
{
if
(
$this
->
isClosed
){
return
;
}
}
$readBytes
=
0
;
while
(
$readBytes
!=
strlen
(
$toWrite
))
{
$this
->
chunkSize
=
$options
[
'chunkSizeBytes'
];
$addToBuffer
=
substr
(
$toWrite
,
$readBytes
,
$this
->
chunkSize
-
$this
->
bufferLength
);
$this
->
collectionsWrapper
=
$collectionsWrapper
;
fwrite
(
$this
->
buffer
,
$addToBuffer
);
$this
->
buffer
=
fopen
(
'php://temp'
,
'w+'
);
$readBytes
+=
strlen
(
$addToBuffer
);
$this
->
ctx
=
hash_init
(
'md5'
);
$this
->
bufferLength
+=
strlen
(
$addToBuffer
);
if
(
$this
->
bufferLength
==
$this
->
chunkSize
)
{
$this
->
file
=
[
rewind
(
$this
->
buffer
);
'_id'
=>
new
ObjectId
(),
$this
->
insertChunk
(
stream_get_contents
(
$this
->
buffer
));
'chunkSize'
=>
$this
->
chunkSize
,
ftruncate
(
$this
->
buffer
,
0
);
'filename'
=>
(
string
)
$filename
,
$this
->
bufferLength
=
0
;
'uploadDate'
=>
$this
->
createUploadDate
(),
}
]
+
array_intersect_key
(
$options
,
[
'aliases'
=>
1
,
'contentType'
=>
1
,
'metadata'
=>
1
]);
}
return
$readBytes
;
}
}
/**
/**
* Close an active stream, pushes all buffered data to GridFS
* Closes an active stream and flushes all buffered data to GridFS.
*
*/
*/
public
function
close
()
public
function
close
()
{
{
if
(
$this
->
isClosed
){
if
(
$this
->
isClosed
)
{
// TODO: Should this be an error condition? e.g. BadMethodCallException
return
;
return
;
}
}
rewind
(
$this
->
buffer
);
rewind
(
$this
->
buffer
);
$cached
=
stream_get_contents
(
$this
->
buffer
);
$cached
=
stream_get_contents
(
$this
->
buffer
);
if
(
strlen
(
$cached
)
>
0
)
{
if
(
strlen
(
$cached
)
>
0
)
{
$this
->
insertChunk
(
$cached
);
$this
->
insertChunk
(
$cached
);
}
}
fclose
(
$this
->
buffer
);
fclose
(
$this
->
buffer
);
$this
->
fileCollectionInsert
();
$this
->
fileCollectionInsert
();
$this
->
isClosed
=
true
;
$this
->
isClosed
=
true
;
}
}
public
function
getSize
()
public
function
getChunkSize
()
{
{
return
$this
->
length
;
return
$this
->
chunkSize
;
}
}
public
function
getFile
()
{
return
$this
->
file
;
}
public
function
getId
()
public
function
getId
()
{
{
return
$this
->
file
[
"_id"
];
return
$this
->
file
[
'_id'
];
}
}
public
function
getLength
()
public
function
getLength
()
{
{
return
$this
->
length
;
return
$this
->
length
;
}
}
public
function
getChunkSize
()
public
function
getSize
()
{
{
return
$this
->
chunkSize
;
return
$this
->
length
;
}
}
public
function
getFile
()
/**
* Inserts binary data into GridFS via chunks.
*
* Data will be buffered internally until chunkSizeBytes are accumulated, at
* which point a chunk's worth of data will be inserted and the buffer
* reset.
*
* @param string $toWrite Binary data to write
* @return int
*/
public
function
insertChunks
(
$toWrite
)
{
{
return
$this
->
file
;
if
(
$this
->
isClosed
)
{
// TODO: Should this be an error condition? e.g. BadMethodCallException
return
;
}
$readBytes
=
0
;
while
(
$readBytes
!=
strlen
(
$toWrite
))
{
$addToBuffer
=
substr
(
$toWrite
,
$readBytes
,
$this
->
chunkSize
-
$this
->
bufferLength
);
fwrite
(
$this
->
buffer
,
$addToBuffer
);
$readBytes
+=
strlen
(
$addToBuffer
);
$this
->
bufferLength
+=
strlen
(
$addToBuffer
);
if
(
$this
->
bufferLength
==
$this
->
chunkSize
)
{
rewind
(
$this
->
buffer
);
$this
->
insertChunk
(
stream_get_contents
(
$this
->
buffer
));
ftruncate
(
$this
->
buffer
,
0
);
$this
->
bufferLength
=
0
;
}
}
return
$readBytes
;
}
}
public
function
isEOF
()
public
function
isEOF
()
{
{
return
$this
->
isClosed
;
return
$this
->
isClosed
;
}
}
/**
* Writes the contents of a readable stream to a GridFS file.
*
* @param resource $source Readable stream
* @return ObjectId
*/
public
function
uploadFromStream
(
$source
)
{
if
(
!
is_resource
(
$source
)
||
get_resource_type
(
$source
)
!=
"stream"
)
{
throw
new
InvalidArgumentTypeException
(
'$stream'
,
$source
,
'resource'
);
}
$streamMetadata
=
stream_get_meta_data
(
$source
);
while
(
$data
=
$this
->
readChunk
(
$source
))
{
$this
->
insertChunk
(
$data
);
}
return
$this
->
fileCollectionInsert
();
}
private
function
abort
()
private
function
abort
()
{
{
$this
->
collectionsWrapper
->
getChunksCollection
()
->
deleteMany
([
"files_id"
=>
$this
->
file
[
"_id"
]]);
$this
->
collectionsWrapper
->
getChunksCollection
()
->
deleteMany
([
'files_id'
=>
$this
->
file
[
'_id'
]]);
$this
->
collectionsWrapper
->
getFilesCollection
()
->
deleteOne
([
"_id"
=>
$this
->
file
[
'_id'
]]);
$this
->
collectionsWrapper
->
getFilesCollection
()
->
deleteOne
([
'_id'
=>
$this
->
file
[
'_id'
]]);
$this
->
isClosed
=
true
;
$this
->
isClosed
=
true
;
}
}
private
function
insertChunk
(
$data
)
// From: http://stackoverflow.com/questions/3656713/how-to-get-current-time-in-milliseconds-in-php
private
function
createUploadDate
()
{
{
if
(
$this
->
isClosed
){
$parts
=
explode
(
' '
,
microtime
());
return
;
$milliseconds
=
sprintf
(
'%d%03d'
,
$parts
[
1
],
$parts
[
0
]
*
1000
);
}
$toUpload
=
[
"files_id"
=>
$this
->
file
[
'_id'
],
"n"
=>
$this
->
chunkOffset
,
"data"
=>
new
\MongoDB\BSON\Binary
(
$data
,
\MongoDB\BSON\Binary
::
TYPE_GENERIC
)];
return
new
UTCDateTime
(
$milliseconds
);
hash_update
(
$this
->
ctx
,
$data
);
$this
->
collectionsWrapper
->
chunkInsert
(
$toUpload
);
$this
->
length
+=
strlen
(
$data
);
$this
->
chunkOffset
++
;
}
}
private
function
fileCollectionInsert
()
private
function
fileCollectionInsert
()
{
{
if
(
$this
->
isClosed
){
if
(
$this
->
isClosed
)
{
// TODO: Should this be an error condition? e.g. BadMethodCallException
return
;
return
;
}
}
$md5
=
hash_final
(
$this
->
ctx
);
$md5
=
hash_final
(
$this
->
ctx
);
$this
->
file
=
array_merge
(
$this
->
file
,
[
'length'
=>
$this
->
length
,
'md5'
=>
$md5
]);
$this
->
collectionsWrapper
->
fileInsert
(
$this
->
file
);
$this
->
file
[
'length'
]
=
$this
->
length
;
$this
->
file
[
'md5'
]
=
$md5
;
$this
->
collectionsWrapper
->
insertFile
(
$this
->
file
);
return
$this
->
file
[
'_id'
];
return
$this
->
file
[
'_id'
];
}
}
//from: http://stackoverflow.com/questions/3656713/how-to-get-current-time-in-milliseconds-in-php
private
function
millitime
()
{
private
function
insertChunk
(
$data
)
$microtime
=
microtime
();
{
$comps
=
explode
(
' '
,
$microtime
);
if
(
$this
->
isClosed
)
{
return
sprintf
(
'%d%03d'
,
$comps
[
1
],
$comps
[
0
]
*
1000
);
// TODO: Should this be an error condition? e.g. BadMethodCallException
return
;
}
$toUpload
=
[
'files_id'
=>
$this
->
file
[
'_id'
],
'n'
=>
$this
->
chunkOffset
,
'data'
=>
new
Binary
(
$data
,
Binary
::
TYPE_GENERIC
),
];
hash_update
(
$this
->
ctx
,
$data
);
$this
->
collectionsWrapper
->
insertChunk
(
$toUpload
);
$this
->
length
+=
strlen
(
$data
);
$this
->
chunkOffset
++
;
}
}
private
function
readChunk
(
$source
)
private
function
readChunk
(
$source
)
{
{
$data
;
try
{
try
{
$data
=
fread
(
$source
,
$this
->
chunkSize
);
$data
=
fread
(
$source
,
$this
->
chunkSize
);
}
catch
(
Exception
$e
)
{
}
catch
(
Exception
$e
)
{
$this
->
abort
();
$this
->
abort
();
throw
$e
;
throw
$e
;
}
}
return
$data
;
return
$data
;
}
}
}
}
src/GridFS/StreamWrapper.php
View file @
f2666e19
<?php
<?php
namespace
MongoDB\GridFS
;
use
MongoDB\Collection
;
namespace
MongoDB\GridFS
;
/**
/**
* Stream wrapper for reading and writing a GridFS file.
* Stream wrapper for reading and writing a GridFS file.
*
*
* @internal
* @internal
* @see MongoDB\GridFS\Bucket::openUploadStream(), MongoDB\GridFS\Bucket::openDownloadStream()
* @see Bucket::openUploadStream()
* @see Bucket::openDownloadStream()
*/
*/
class
StreamWrapper
class
StreamWrapper
{
{
public
$context
;
public
$context
;
private
$filename
;
private
$protocol
=
'gridfs'
;
private
$mode
;
private
$gridFsStream
;
private
$collectionsWrapper
;
public
$id
;
public
$id
;
private
$collectionsWrapper
;
private
$gridFSStream
;
private
$mode
;
public
function
openReadStream
()
{
$context
=
stream_context_get_options
(
$this
->
context
);
$this
->
gridFSStream
=
new
GridFSDownload
(
$this
->
collectionsWrapper
,
$context
[
'gridfs'
][
'file'
]);
$this
->
id
=
$this
->
gridFSStream
->
getId
();
return
true
;
}
public
function
openWriteStream
()
{
$context
=
stream_context_get_options
(
$this
->
context
);
$options
=
$context
[
'gridfs'
][
'uploadOptions'
];
$this
->
gridFSStream
=
new
GridFSUpload
(
$this
->
collectionsWrapper
,
$this
->
identifier
,
$options
);
$this
->
id
=
$this
->
gridFSStream
->
getId
();
return
true
;
}
/**
/**
* Register the GridFS stream wrapper.
* Register the GridFS stream wrapper.
*/
*/
...
@@ -27,63 +45,59 @@ class StreamWrapper
...
@@ -27,63 +45,59 @@ class StreamWrapper
if
(
in_array
(
'gridfs'
,
stream_get_wrappers
()))
{
if
(
in_array
(
'gridfs'
,
stream_get_wrappers
()))
{
stream_wrapper_unregister
(
'gridfs'
);
stream_wrapper_unregister
(
'gridfs'
);
}
}
stream_wrapper_register
(
'gridfs'
,
get_called_class
(),
STREAM_IS_URL
);
}
stream_wrapper_register
(
'gridfs'
,
get_called_class
(),
\STREAM_IS_URL
);
public
function
stream_write
(
$data
)
{
$this
->
gridFsStream
->
insertChunks
(
$data
);
return
strlen
(
$data
);
}
public
function
stream_read
(
$count
)
{
return
$this
->
gridFsStream
->
downloadNumBytes
(
$count
);
}
public
function
stream_eof
()
{
return
$this
->
gridFsStream
->
isEOF
();
}
}
public
function
stream_close
()
public
function
stream_close
()
{
{
$this
->
gridF
s
Stream
->
close
();
$this
->
gridF
S
Stream
->
close
();
}
}
public
function
stream_stat
()
public
function
stream_eof
()
{
{
$stat
=
$this
->
getStatTemplate
();
return
$this
->
gridFSStream
->
isEOF
();
$stat
[
7
]
=
$stat
[
'size'
]
=
$this
->
gridFsStream
->
getSize
();
return
$stat
;
}
}
public
function
stream_open
(
$path
,
$mode
,
$options
,
&
$openedPath
)
public
function
stream_open
(
$path
,
$mode
,
$options
,
&
$openedPath
)
{
{
$this
->
initProtocol
(
$path
);
$this
->
initProtocol
(
$path
);
$context
=
stream_context_get_options
(
$this
->
context
);
$context
=
stream_context_get_options
(
$this
->
context
);
$this
->
collectionsWrapper
=
$context
[
'gridfs'
][
'collectionsWrapper'
];
$this
->
collectionsWrapper
=
$context
[
'gridfs'
][
'collectionsWrapper'
];
$this
->
mode
=
$mode
;
$this
->
mode
=
$mode
;
switch
(
$this
->
mode
)
{
switch
(
$this
->
mode
)
{
case
'
w'
:
return
$this
->
openWrite
Stream
();
case
'
r'
:
return
$this
->
openRead
Stream
();
case
'
r'
:
return
$this
->
openRead
Stream
();
case
'
w'
:
return
$this
->
openWrite
Stream
();
default
:
return
false
;
default
:
return
false
;
}
}
}
}
public
function
openWriteStream
()
{
$context
=
stream_context_get_options
(
$this
->
context
);
public
function
stream_read
(
$count
)
$options
=
$context
[
'gridfs'
][
'uploadOptions'
];
{
$this
->
gridFsStream
=
new
GridFsUpload
(
$this
->
collectionsWrapper
,
$this
->
identifier
,
$options
);
return
$this
->
gridFSStream
->
downloadNumBytes
(
$count
);
$this
->
id
=
$this
->
gridFsStream
->
getId
();
return
true
;
}
}
public
function
openReadStream
()
{
public
function
stream_stat
()
$context
=
stream_context_get_options
(
$this
->
context
);
{
$this
->
gridFsStream
=
new
GridFsDownload
(
$this
->
collectionsWrapper
,
$context
[
'gridfs'
][
'file'
]);
$stat
=
$this
->
getStatTemplate
();
$this
->
id
=
$this
->
gridFsStream
->
getId
();
$stat
[
7
]
=
$stat
[
'size'
]
=
$this
->
gridFSStream
->
getSize
();
return
true
;
return
$stat
;
}
public
function
stream_write
(
$data
)
{
$this
->
gridFSStream
->
insertChunks
(
$data
);
return
strlen
(
$data
);
}
}
/**
/**
* Gets a URL stat template with default values
* Gets a URL stat template with default values
* from https://github.com/aws/aws-sdk-php/blob/master/src/S3/StreamWrapper.php
* from https://github.com/aws/aws-sdk-php/blob/master/src/S3/StreamWrapper.php
* @return array
* @return array
*/
*/
private
function
getStatTemplate
()
private
function
getStatTemplate
()
{
{
return
[
return
[
...
@@ -102,10 +116,10 @@ class StreamWrapper
...
@@ -102,10 +116,10 @@ class StreamWrapper
12
=>
-
1
,
'blocks'
=>
-
1
,
12
=>
-
1
,
'blocks'
=>
-
1
,
];
];
}
}
private
function
initProtocol
(
$path
)
private
function
initProtocol
(
$path
)
{
{
$parsed_path
=
parse_url
(
$path
);
$parsed_path
=
parse_url
(
$path
);
$this
->
databaseName
=
$parsed_path
[
"host"
];
$this
->
identifier
=
substr
(
$parsed_path
[
'path'
],
1
);
$this
->
identifier
=
substr
(
$parsed_path
[
"path"
],
1
);
}
}
}
}
tests/GridFS/BucketFunctionalTest.php
View file @
f2666e19
...
@@ -176,25 +176,25 @@ class BucketFunctionalTest extends FunctionalTestCase
...
@@ -176,25 +176,25 @@ class BucketFunctionalTest extends FunctionalTestCase
$this
->
bucket
->
uploadFromStream
(
"test"
,
$this
->
generateStream
(
"bar"
));
$this
->
bucket
->
uploadFromStream
(
"test"
,
$this
->
generateStream
(
"bar"
));
$this
->
bucket
->
uploadFromStream
(
"test"
,
$this
->
generateStream
(
"baz"
));
$this
->
bucket
->
uploadFromStream
(
"test"
,
$this
->
generateStream
(
"baz"
));
$this
->
assertEquals
(
"foo"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
0
)));
$this
->
assertEquals
(
"foo"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
0
]
)));
$this
->
assertEquals
(
"bar"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
1
)));
$this
->
assertEquals
(
"bar"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
1
]
)));
$this
->
assertEquals
(
"baz"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
2
)));
$this
->
assertEquals
(
"baz"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
2
]
)));
$this
->
assertEquals
(
"baz"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
-
1
)));
$this
->
assertEquals
(
"baz"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
-
1
]
)));
$this
->
assertEquals
(
"bar"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
-
2
)));
$this
->
assertEquals
(
"bar"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
-
2
]
)));
$this
->
assertEquals
(
"foo"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
-
3
)));
$this
->
assertEquals
(
"foo"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
-
3
]
)));
$fileNotFound
=
'\MongoDB\Exception\GridFSFileNotFoundException'
;
$fileNotFound
=
'\MongoDB\Exception\GridFSFileNotFoundException'
;
$error
=
null
;
$error
=
null
;
try
{
try
{
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
3
);
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
3
]
);
}
catch
(
\MongoDB\Exception\Exception
$e
)
{
}
catch
(
\MongoDB\Exception\Exception
$e
)
{
$error
=
$e
;
$error
=
$e
;
}
}
$this
->
assertTrue
(
$error
instanceof
$fileNotFound
);
$this
->
assertTrue
(
$error
instanceof
$fileNotFound
);
$error
=
null
;
$error
=
null
;
try
{
try
{
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
-
4
);
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
-
4
]
);
}
catch
(
\MongoDB\Exception\Exception
$e
)
{
}
catch
(
\MongoDB\Exception\Exception
$e
)
{
$error
=
$e
;
$error
=
$e
;
}
}
...
...
tests/GridFS/GridF
s
StreamTest.php
→
tests/GridFS/GridF
S
StreamTest.php
View file @
f2666e19
...
@@ -7,12 +7,12 @@ use MongoDB\GridFS;
...
@@ -7,12 +7,12 @@ use MongoDB\GridFS;
/**
/**
* Functional tests for the Bucket class.
* Functional tests for the Bucket class.
*/
*/
class
GridF
s
StreamTest
extends
FunctionalTestCase
class
GridF
S
StreamTest
extends
FunctionalTestCase
{
{
public
function
testBasic
()
public
function
testBasic
()
{
{
$upload
=
new
\MongoDB\GridFS\GridF
s
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$upload
=
new
\MongoDB\GridFS\GridF
S
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$upload
->
insertChunks
(
"hello world"
);
$upload
->
insertChunks
(
"hello world"
);
$id
=
$upload
->
getId
();
$id
=
$upload
->
getId
();
$upload
->
close
();
$upload
->
close
();
...
@@ -22,7 +22,7 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -22,7 +22,7 @@ class GridFsStreamTest extends FunctionalTestCase
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
"_id"
=>
$id
]);
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
"_id"
=>
$id
]);
$download
=
new
\MongoDB\GridFS\GridF
s
Download
(
$this
->
collectionsWrapper
,
$file
);
$download
=
new
\MongoDB\GridFS\GridF
S
Download
(
$this
->
collectionsWrapper
,
$file
);
$stream
=
fopen
(
'php://temp'
,
'w+'
);
$stream
=
fopen
(
'php://temp'
,
'w+'
);
$download
->
downloadToStream
(
$stream
);
$download
->
downloadToStream
(
$stream
);
rewind
(
$stream
);
rewind
(
$stream
);
...
@@ -31,7 +31,7 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -31,7 +31,7 @@ class GridFsStreamTest extends FunctionalTestCase
fclose
(
$stream
);
fclose
(
$stream
);
#make sure it's still there!
#make sure it's still there!
$download
=
new
\MongoDB\GridFS\GridF
s
Download
(
$this
->
collectionsWrapper
,
$file
);
$download
=
new
\MongoDB\GridFS\GridF
S
Download
(
$this
->
collectionsWrapper
,
$file
);
$stream
=
fopen
(
'php://temp'
,
'w+'
);
$stream
=
fopen
(
'php://temp'
,
'w+'
);
$download
->
downloadToStream
(
$stream
);
$download
->
downloadToStream
(
$stream
);
rewind
(
$stream
);
rewind
(
$stream
);
...
@@ -39,7 +39,7 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -39,7 +39,7 @@ class GridFsStreamTest extends FunctionalTestCase
$this
->
assertEquals
(
"hello world"
,
$contents
);
$this
->
assertEquals
(
"hello world"
,
$contents
);
fclose
(
$stream
);
fclose
(
$stream
);
$upload
=
new
\MongoDB\GridFS\GridF
s
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$upload
=
new
\MongoDB\GridFS\GridF
S
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$id
=
$upload
->
getId
();
$id
=
$upload
->
getId
();
$upload
->
close
();
$upload
->
close
();
...
@@ -47,7 +47,7 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -47,7 +47,7 @@ class GridFsStreamTest extends FunctionalTestCase
$this
->
assertEquals
(
1
,
$this
->
collectionsWrapper
->
getChunksCollection
()
->
count
());
$this
->
assertEquals
(
1
,
$this
->
collectionsWrapper
->
getChunksCollection
()
->
count
());
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
"_id"
=>
$id
]);
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
"_id"
=>
$id
]);
$download
=
new
\MongoDB\GridFS\GridF
s
Download
(
$this
->
collectionsWrapper
,
$file
);
$download
=
new
\MongoDB\GridFS\GridF
S
Download
(
$this
->
collectionsWrapper
,
$file
);
$stream
=
fopen
(
'php://temp'
,
'w+'
);
$stream
=
fopen
(
'php://temp'
,
'w+'
);
$download
->
downloadToStream
(
$stream
);
$download
->
downloadToStream
(
$stream
);
rewind
(
$stream
);
rewind
(
$stream
);
...
@@ -58,7 +58,7 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -58,7 +58,7 @@ class GridFsStreamTest extends FunctionalTestCase
public
function
testMd5
()
public
function
testMd5
()
{
{
$upload
=
new
\MongoDB\GridFS\GridF
s
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$upload
=
new
\MongoDB\GridFS\GridF
S
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$upload
->
insertChunks
(
"hello world
\n
"
);
$upload
->
insertChunks
(
"hello world
\n
"
);
$id
=
$upload
->
getId
();
$id
=
$upload
->
getId
();
$upload
->
close
();
$upload
->
close
();
...
@@ -68,7 +68,7 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -68,7 +68,7 @@ class GridFsStreamTest extends FunctionalTestCase
}
}
public
function
testUploadDefaultOpts
()
public
function
testUploadDefaultOpts
()
{
{
$upload
=
new
\MongoDB\GridFS\GridF
s
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$upload
=
new
\MongoDB\GridFS\GridF
S
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$this
->
assertTrue
(
$upload
->
getId
()
instanceof
\MongoDB\BSON\ObjectId
);
$this
->
assertTrue
(
$upload
->
getId
()
instanceof
\MongoDB\BSON\ObjectId
);
$this
->
assertTrue
(
$upload
->
getFile
()[
"uploadDate"
]
instanceof
\MongoDB\BSON\UTCDateTime
);
$this
->
assertTrue
(
$upload
->
getFile
()[
"uploadDate"
]
instanceof
\MongoDB\BSON\UTCDateTime
);
...
@@ -89,7 +89,7 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -89,7 +89,7 @@ class GridFsStreamTest extends FunctionalTestCase
"aliases"
=>
[
"foo"
,
"bar"
],
"aliases"
=>
[
"foo"
,
"bar"
],
"metadata"
=>
[
"foo"
=>
1
,
"bar"
=>
2
]
"metadata"
=>
[
"foo"
=>
1
,
"bar"
=>
2
]
];
];
$upload
=
new
\MongoDB\GridFS\GridF
s
Upload
(
$this
->
collectionsWrapper
,
"test"
,
$options
);
$upload
=
new
\MongoDB\GridFS\GridF
S
Upload
(
$this
->
collectionsWrapper
,
"test"
,
$options
);
$this
->
assertEquals
(
$upload
->
getChunkSize
(),
1
);
$this
->
assertEquals
(
$upload
->
getChunkSize
(),
1
);
$this
->
assertEquals
(
$upload
->
getFile
()[
"contentType"
],
"text/html"
);
$this
->
assertEquals
(
$upload
->
getFile
()[
"contentType"
],
"text/html"
);
$this
->
assertEquals
(
$upload
->
getFile
()[
"aliases"
],
[
"foo"
,
"bar"
]);
$this
->
assertEquals
(
$upload
->
getFile
()[
"aliases"
],
[
"foo"
,
"bar"
]);
...
@@ -97,11 +97,11 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -97,11 +97,11 @@ class GridFsStreamTest extends FunctionalTestCase
}
}
public
function
testDownloadDefaultOpts
()
public
function
testDownloadDefaultOpts
()
{
{
$upload
=
new
\MongoDB\GridFS\GridF
s
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$upload
=
new
\MongoDB\GridFS\GridF
S
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$upload
->
close
();
$upload
->
close
();
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
"_id"
=>
$upload
->
getId
()]);
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
"_id"
=>
$upload
->
getId
()]);
$download
=
new
\MongoDB\GridFS\GridF
s
Download
(
$this
->
collectionsWrapper
,
$file
);
$download
=
new
\MongoDB\GridFS\GridF
S
Download
(
$this
->
collectionsWrapper
,
$file
);
$download
->
close
();
$download
->
close
();
$this
->
assertEquals
(
$upload
->
getId
(),
$download
->
getId
());
$this
->
assertEquals
(
$upload
->
getId
(),
$download
->
getId
());
...
@@ -120,12 +120,12 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -120,12 +120,12 @@ class GridFsStreamTest extends FunctionalTestCase
"aliases"
=>
[
"foo"
,
"bar"
],
"aliases"
=>
[
"foo"
,
"bar"
],
"metadata"
=>
[
"foo"
=>
1
,
"bar"
=>
2
]
"metadata"
=>
[
"foo"
=>
1
,
"bar"
=>
2
]
];
];
$upload
=
new
\MongoDB\GridFS\GridF
s
Upload
(
$this
->
collectionsWrapper
,
"test"
,
$options
);
$upload
=
new
\MongoDB\GridFS\GridF
S
Upload
(
$this
->
collectionsWrapper
,
"test"
,
$options
);
$upload
->
insertChunks
(
"hello world"
);
$upload
->
insertChunks
(
"hello world"
);
$upload
->
close
();
$upload
->
close
();
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
"_id"
=>
$upload
->
getId
()]);
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
"_id"
=>
$upload
->
getId
()]);
$download
=
new
\MongoDB\GridFS\GridF
s
Download
(
$this
->
collectionsWrapper
,
$file
);
$download
=
new
\MongoDB\GridFS\GridF
S
Download
(
$this
->
collectionsWrapper
,
$file
);
$this
->
assertEquals
(
"test"
,
$download
->
getFile
()
->
filename
);
$this
->
assertEquals
(
"test"
,
$download
->
getFile
()
->
filename
);
$this
->
assertEquals
(
$upload
->
getId
(),
$download
->
getId
());
$this
->
assertEquals
(
$upload
->
getId
(),
$download
->
getId
());
...
@@ -141,7 +141,7 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -141,7 +141,7 @@ class GridFsStreamTest extends FunctionalTestCase
*/
*/
public
function
testInsertChunks
(
$data
)
public
function
testInsertChunks
(
$data
)
{
{
$upload
=
new
\MongoDB\GridFS\GridF
s
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$upload
=
new
\MongoDB\GridFS\GridF
S
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$upload
->
insertChunks
(
$data
);
$upload
->
insertChunks
(
$data
);
$upload
->
close
();
$upload
->
close
();
$stream
=
$this
->
bucket
->
openDownloadStream
(
$upload
->
getId
());
$stream
=
$this
->
bucket
->
openDownloadStream
(
$upload
->
getId
());
...
@@ -154,7 +154,7 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -154,7 +154,7 @@ class GridFsStreamTest extends FunctionalTestCase
for
(
$i
=
0
;
$i
<
255
*
1024
+
1000
;
$i
++
){
for
(
$i
=
0
;
$i
<
255
*
1024
+
1000
;
$i
++
){
$toUpload
.=
"a"
;
$toUpload
.=
"a"
;
}
}
$upload
=
new
\MongoDB\GridFS\GridF
s
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$upload
=
new
\MongoDB\GridFS\GridF
S
Upload
(
$this
->
collectionsWrapper
,
"test"
);
$upload
->
insertChunks
(
$toUpload
);
$upload
->
insertChunks
(
$toUpload
);
$upload
->
close
();
$upload
->
close
();
...
@@ -170,7 +170,7 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -170,7 +170,7 @@ class GridFsStreamTest extends FunctionalTestCase
public
function
testSmallChunks
(
$data
)
public
function
testSmallChunks
(
$data
)
{
{
$options
=
[
"chunkSizeBytes"
=>
1
];
$options
=
[
"chunkSizeBytes"
=>
1
];
$upload
=
new
\MongoDB\GridFS\GridF
s
Upload
(
$this
->
collectionsWrapper
,
"test"
,
$options
);
$upload
=
new
\MongoDB\GridFS\GridF
S
Upload
(
$this
->
collectionsWrapper
,
"test"
,
$options
);
$upload
->
insertChunks
(
$data
);
$upload
->
insertChunks
(
$data
);
$upload
->
close
();
$upload
->
close
();
...
@@ -182,11 +182,11 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -182,11 +182,11 @@ class GridFsStreamTest extends FunctionalTestCase
}
}
public
function
testMultipleReads
()
public
function
testMultipleReads
()
{
{
$upload
=
new
\MongoDB\GridFS\GridF
s
Upload
(
$this
->
collectionsWrapper
,
"test"
,
[
"chunkSizeBytes"
=>
3
]);
$upload
=
new
\MongoDB\GridFS\GridF
S
Upload
(
$this
->
collectionsWrapper
,
"test"
,
[
"chunkSizeBytes"
=>
3
]);
$upload
->
insertChunks
(
"hello world"
);
$upload
->
insertChunks
(
"hello world"
);
$upload
->
close
();
$upload
->
close
();
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
"_id"
=>
$upload
->
getId
()]);
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
"_id"
=>
$upload
->
getId
()]);
$download
=
new
\MongoDB\GridFS\GridF
s
Download
(
$this
->
collectionsWrapper
,
$file
);
$download
=
new
\MongoDB\GridFS\GridF
S
Download
(
$this
->
collectionsWrapper
,
$file
);
$this
->
assertEquals
(
"he"
,
$download
->
downloadNumBytes
(
2
));
$this
->
assertEquals
(
"he"
,
$download
->
downloadNumBytes
(
2
));
$this
->
assertEquals
(
"ll"
,
$download
->
downloadNumBytes
(
2
));
$this
->
assertEquals
(
"ll"
,
$download
->
downloadNumBytes
(
2
));
$this
->
assertEquals
(
"o "
,
$download
->
downloadNumBytes
(
2
));
$this
->
assertEquals
(
"o "
,
$download
->
downloadNumBytes
(
2
));
...
@@ -202,11 +202,11 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -202,11 +202,11 @@ class GridFsStreamTest extends FunctionalTestCase
*/
*/
public
function
testProvidedMultipleReads
(
$data
)
public
function
testProvidedMultipleReads
(
$data
)
{
{
$upload
=
new
\MongoDB\GridFS\GridF
s
Upload
(
$this
->
collectionsWrapper
,
"test"
,
[
"chunkSizeBytes"
=>
rand
(
1
,
5
)]);
$upload
=
new
\MongoDB\GridFS\GridF
S
Upload
(
$this
->
collectionsWrapper
,
"test"
,
[
"chunkSizeBytes"
=>
rand
(
1
,
5
)]);
$upload
->
insertChunks
(
$data
);
$upload
->
insertChunks
(
$data
);
$upload
->
close
();
$upload
->
close
();
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
"_id"
=>
$upload
->
getId
()]);
$file
=
$this
->
collectionsWrapper
->
getFilesCollection
()
->
findOne
([
"_id"
=>
$upload
->
getId
()]);
$download
=
new
\MongoDB\GridFS\GridF
s
Download
(
$this
->
collectionsWrapper
,
$file
);
$download
=
new
\MongoDB\GridFS\GridF
S
Download
(
$this
->
collectionsWrapper
,
$file
);
$readPos
=
0
;
$readPos
=
0
;
while
(
$readPos
<
strlen
(
$data
)){
while
(
$readPos
<
strlen
(
$data
)){
...
@@ -227,7 +227,7 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -227,7 +227,7 @@ class GridFsStreamTest extends FunctionalTestCase
*/
*/
public
function
testUploadConstructorOptionTypeChecks
(
array
$options
)
public
function
testUploadConstructorOptionTypeChecks
(
array
$options
)
{
{
new
\MongoDB\GridFS\GridF
s
Upload
(
$this
->
collectionsWrapper
,
"test"
,
$options
);
new
\MongoDB\GridFS\GridF
S
Upload
(
$this
->
collectionsWrapper
,
"test"
,
$options
);
}
}
public
function
provideInvalidUploadConstructorOptions
()
public
function
provideInvalidUploadConstructorOptions
()
...
@@ -248,22 +248,4 @@ class GridFsStreamTest extends FunctionalTestCase
...
@@ -248,22 +248,4 @@ class GridFsStreamTest extends FunctionalTestCase
}
}
return
$options
;
return
$options
;
}
}
/**
* @expectedException \MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDownloadConstructorFile
*/
public
function
testDownloadConstructorFileCheck
(
$file
)
{
$download
=
new
\MongoDB\GridFS\GridFsDownload
(
$this
->
collectionsWrapper
,
$file
);
}
public
function
provideInvalidDownloadConstructorFile
()
{
$files
=
[];
$invalidFiles
=
[
123
,
3.14
,
true
,
[]];
foreach
(
$invalidFiles
as
$value
)
{
$files
[][]
=
$value
;
}
return
$files
;
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment