Skip to content

Commit

Permalink
Merge pull request #49 from daniel-sc/migrate-mongo-dependency
Browse files Browse the repository at this point in the history
migrate (optional) ext-mongo to mongodb/mongodb + ext-mongodb
  • Loading branch information
AidasK authored Aug 26, 2022
2 parents ab7f6f9 + 78e2453 commit fe8890c
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 42 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ language: php
dist: precise

php:
- 5.3
- 5.4
- 5.5

Expand Down
9 changes: 7 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@
"chunks"
],
"require": {
"php": ">=5.3"
"php": ">=5.4"
},
"require-dev": {
"mikey179/vfsstream": "v1.2.0",
"league/phpunit-coverage-listener": "~1.1",
"fabpot/php-cs-fixer": "~2.2",
"phpunit/phpunit": "4.*"
"phpunit/phpunit": "4.*",
"mongodb/mongodb": "^1.4.0",
"ext-mongodb": "*"
},
"suggest": {
"mongodb/mongodb":"Required to use this package with Mongo DB"
},
"autoload": {
"psr-0": {
Expand Down
7 changes: 4 additions & 3 deletions src/Flow/Mongo/MongoConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Flow\Mongo;

use Flow\Config;
use MongoDB\GridFS\Bucket;

/**
* @codeCoverageIgnore
Expand All @@ -12,17 +13,17 @@ class MongoConfig extends Config implements MongoConfigInterface
private $gridFs;

/**
* @param \MongoGridFS $gridFS storage of the upload (and chunks)
* @param Bucket $gridFS storage of the upload (and chunks)
*/
function __construct(\MongoGridFS $gridFS)
function __construct(Bucket $gridFS)
{
parent::__construct();
$this->gridFs = $gridFS;
}


/**
* @return \MongoGridFS
* @return Bucket
*/
public function getGridFs()
{
Expand Down
3 changes: 2 additions & 1 deletion src/Flow/Mongo/MongoConfigInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Flow\Mongo;

use Flow\ConfigInterface;
use MongoDB\GridFS\Bucket;

/**
* @codeCoverageIgnore
Expand All @@ -11,7 +12,7 @@ interface MongoConfigInterface extends ConfigInterface
{

/**
* @return \MongoGridFS
* @return Bucket
*/
public function getGridFs();

Expand Down
48 changes: 24 additions & 24 deletions src/Flow/Mongo/MongoFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

namespace Flow\Mongo;

use Exception;
use Flow\File;
use Flow\Request;
use Flow\RequestInterface;
use MongoDB\BSON\Binary;
use MongoDB\BSON\ObjectId;
use MongoDB\BSON\UTCDateTime;
use MongoDB\Operation\FindOneAndReplace;


/**
Expand Down Expand Up @@ -42,9 +47,9 @@ protected function getGridFsFile()
if (!$this->uploadGridFsFile) {
$gridFsFileQuery = $this->getGridFsFileQuery();
$changed = $gridFsFileQuery;
$changed['flowUpdated'] = new \MongoDate();
$this->uploadGridFsFile = $this->config->getGridFs()->findAndModify($gridFsFileQuery, $changed, null,
['upsert' => true, 'new' => true]);
$changed['flowUpdated'] = new UTCDateTime();
$this->uploadGridFsFile = $this->config->getGridFs()->getFilesCollection()->findOneAndReplace($gridFsFileQuery, $changed,
['upsert' => true, 'returnDocument' => FindOneAndReplace::RETURN_DOCUMENT_AFTER]);
}

return $this->uploadGridFsFile;
Expand All @@ -56,10 +61,10 @@ protected function getGridFsFile()
*/
public function chunkExists($index)
{
return $this->config->getGridFs()->chunks->find([
return $this->config->getGridFs()->getChunksCollection()->findOne([
'files_id' => $this->getGridFsFile()['_id'],
'n' => (intval($index) - 1)
])->limit(1)->hasNext();
]) !== null;
}

public function checkChunk()
Expand All @@ -71,7 +76,7 @@ public function checkChunk()
* Save chunk
* @param $additionalUpdateOptions array additional options for the mongo update/upsert operation.
* @return bool
* @throws \Exception if upload size is invalid or some other unexpected error occurred.
* @throws Exception if upload size is invalid or some other unexpected error occurred.
*/
public function saveChunk($additionalUpdateOptions = [])
{
Expand All @@ -89,19 +94,19 @@ public function saveChunk($additionalUpdateOptions = [])
($actualChunkSize < $this->request->getDefaultChunkSize() &&
$this->request->getCurrentChunkNumber() != $this->request->getTotalChunks())
) {
throw new \Exception("Invalid upload! (size: {$actualChunkSize})");
throw new Exception("Invalid upload! (size: $actualChunkSize)");
}
$chunk['data'] = new \MongoBinData($data, 0); // \MongoBinData::GENERIC is not defined for older mongo drivers
$this->config->getGridFs()->chunks->update($chunkQuery, $chunk, array_merge(['upsert' => true], $additionalUpdateOptions));
$chunk['data'] = new Binary($data, Binary::TYPE_GENERIC);
$this->config->getGridFs()->getChunksCollection()->replaceOne($chunkQuery, $chunk, array_merge(['upsert' => true], $additionalUpdateOptions));
unlink($file['tmp_name']);

$this->ensureIndices();

return true;
} catch (\Exception $e) {
} catch (Exception $e) {
// try to remove a possibly (partly) stored chunk:
if (isset($chunkQuery)) {
$this->config->getGridFs()->chunks->remove($chunkQuery);
$this->config->getGridFs()->getChunksCollection()->deleteMany($chunkQuery);
}
throw $e;
}
Expand All @@ -113,25 +118,24 @@ public function saveChunk($additionalUpdateOptions = [])
public function validateFile()
{
$totalChunks = intval($this->request->getTotalChunks());
$storedChunks = $this->config->getGridFs()->chunks
->find(['files_id' => $this->getGridFsFile()['_id']])
->count();
$storedChunks = $this->config->getGridFs()->getChunksCollection()
->countDocuments(['files_id' => $this->getGridFsFile()['_id']]);
return $totalChunks === $storedChunks;
}


/**
* Merge all chunks to single file
* @param $metadata array additional metadata for final file
* @return \MongoId|bool of saved file or false if file was already saved
* @throws \Exception
* @return ObjectId|bool of saved file or false if file was already saved
* @throws Exception
*/
public function saveToGridFs($metadata = null)
{
$file = $this->getGridFsFile();
$file['flowStatus'] = 'finished';
$file['metadata'] = $metadata;
$result = $this->config->getGridFs()->findAndModify($this->getGridFsFileQuery(), $file);
$result = $this->config->getGridFs()->getFilesCollection()->findOneAndReplace($this->getGridFsFileQuery(), $file);
// on second invocation no more file can be found, as the flowStatus changed:
if (is_null($result)) {
return false;
Expand All @@ -142,7 +146,7 @@ public function saveToGridFs($metadata = null)

public function save($destination)
{
throw new \Exception("Must not use 'save' on MongoFile - use 'saveToGridFs'!");
throw new Exception("Must not use 'save' on MongoFile - use 'saveToGridFs'!");
}

public function deleteChunks()
Expand All @@ -152,14 +156,10 @@ public function deleteChunks()

public function ensureIndices()
{
$chunksCollection = $this->config->getGridFs()->chunks;
$chunksCollection = $this->config->getGridFs()->getChunksCollection();
$indexKeys = ['files_id' => 1, 'n' => 1];
$indexOptions = ['unique' => true, 'background' => true];
if(method_exists($chunksCollection, 'createIndex')) { // only available for PECL mongo >= 1.5.0
$chunksCollection->createIndex($indexKeys, $indexOptions);
} else {
$chunksCollection->ensureIndex($indexKeys, $indexOptions);
}
$chunksCollection->createIndex($indexKeys, $indexOptions);
}

/**
Expand Down
15 changes: 6 additions & 9 deletions src/Flow/Mongo/MongoUploader.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Flow\Mongo;

use Flow\FileOpenException;
use MongoDB\GridFS\Bucket;

/**
* @codeCoverageIgnore
Expand All @@ -12,20 +12,17 @@ class MongoUploader
/**
* Delete chunks older than expiration time.
*
* @param \MongoGridFS $gridFs
* @param Bucket $gridFs
* @param int $expirationTime seconds
*
* @throws FileOpenException
*/
public static function pruneChunks($gridFs, $expirationTime = 172800)
{
$result = $gridFs->remove([
'flowUpdated' => ['$lt' => new \MongoDate(time() - $expirationTime)],
$result = $gridFs->find([
'flowUpdated' => ['$lt' => new \MongoDB\BSON\UTCDateTime(time() - $expirationTime)],
'flowStatus' => 'uploading'
]);

if (!$result) {
throw new FileOpenException("Could not remove chunks!");
foreach ($result as $file) {
$gridFs->delete($file['_id']);
}
}
}
4 changes: 2 additions & 2 deletions src/Flow/Mongo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Usage

* Must use 'forceChunkSize=true' on client side.
* Chunk preprocessor not supported.
* One should ensure indices on the gridfs collection on the property 'flowIdentifier'.
* One should ensure indices on the gridfs files collection on the property 'flowIdentifier'.

Besides the points above, the usage is analogous to the 'normal' flow-php:

Expand Down Expand Up @@ -41,7 +41,7 @@ if ($file->validateFile()) {
Delete unfinished files
-----------------------

For this you should setup cron, which would check each chunk upload time.
For this you should set up cron, which would check each chunk upload time.
If chunk is uploaded long time ago, then chunk should be deleted.

Helper method for checking this:
Expand Down

0 comments on commit fe8890c

Please sign in to comment.