From ddf50b0cfcfbf5b25a952a09451751cf68b468aa Mon Sep 17 00:00:00 2001 From: MCubs <> Date: Mon, 22 Jun 2020 12:44:35 +0300 Subject: [PATCH 1/4] Update code for mongodb 3.6-4.0 work properly --- src/Collection.php | 17 ++++++++++ tests/AggregatePipelineTest.php | 58 ++++++++++++++++++++++++-------- tests/DocumentValidationTest.php | 2 +- 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/Collection.php b/src/Collection.php index ea1d42b..c44e394 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -232,6 +232,11 @@ public function delete() { $status = $this->getMongoCollection()->drop(); + if ($status === array()) { + $writeConcern = $this->getWriteConcern(); + $status['ok'] = ($writeConcern['w'] === 0 ? 1:0); + } + if ($status['ok'] != 1) { // check if collection exists if ('ns not found' !== $status['errmsg']) { @@ -1038,6 +1043,18 @@ public function aggregate( } else { throw new FeatureNotSupportedException('Aggregate cursor supported from driver version 1.5'); } + } else { + if ( + empty($options['explain']) && + version_compare(\MongoClient::VERSION, '1.5.0', '>=') && + version_compare($this->database->getClient()->getDbVersion(), '2.6', '>=') + ) { + try { + return iterator_to_array($this->getMongoCollection()->aggregateCursor($pipeline, $options), false); + } catch (\Exception $e) { + throw new Exception('Aggregate error: ' . $e->getMessage()); + } + } } // prepare command diff --git a/tests/AggregatePipelineTest.php b/tests/AggregatePipelineTest.php index d797ca1..a813813 100644 --- a/tests/AggregatePipelineTest.php +++ b/tests/AggregatePipelineTest.php @@ -361,21 +361,51 @@ public function testAggregate_ServerSideError() )) ->getMock(); - $mongoDatabaseMock - ->expects($this->once()) - ->method('command') - ->will($this->returnValue(array( - 'ok' => (double) 0, - 'errmsg' => 'some_error', - 'code' => 1785342, - ))); - $database = new Database($this->collection->getDatabase()->getClient(), $mongoDatabaseMock); - $database - ->getCollection('phpmongo_test_collection') - ->aggregate(array( - array('$match' => array('field' => 'value')) - )); + + $pipeline = array( + array('$match' => array('field' => 'value')) + ); + + if ( + version_compare(\MongoClient::VERSION, '1.5.0', '>=') && + version_compare($database->getClient()->getDbVersion(), '2.6', '>=') + ) { + $mongoCollectionMock = $this->getMockBuilder('\MongoCollection') + ->setMethods(['aggregateCursor']) + ->setConstructorArgs([$mongoDatabaseMock, 'phpmongo_test_collection']) + ->getMock() + ; + $mongoCollectionMock + ->method('aggregateCursor') + ->willThrowException(new \Exception('some_error')) + ; + + $collectionMock = $this->getMockBuilder('Sokil\Mongo\Collection') + ->setMethods(['getMongoCollection']) + ->setConstructorArgs([$database, 'phpmongo_test_collection']) + ->getMock() + ; + $collectionMock + ->method('getMongoCollection') + ->willReturn($mongoCollectionMock) + ; + + $collectionMock->aggregate($pipeline); + } else { + $mongoDatabaseMock + ->expects($this->once()) + ->method('command') + ->willReturn(array( + 'ok' => (double)0, + 'errmsg' => 'some_error', + 'code' => 1785342, + )); + + $database + ->getCollection('phpmongo_test_collection') + ->aggregate($pipeline); + } } public function testAggregate_ExplainOption() diff --git a/tests/DocumentValidationTest.php b/tests/DocumentValidationTest.php index b2f2691..e5d5216 100644 --- a/tests/DocumentValidationTest.php +++ b/tests/DocumentValidationTest.php @@ -778,7 +778,7 @@ public function testIsValid_FieldEmail() try { // additional MX check on wrong email - $document->set('some-field-name-mx', 'user@example.com'); + $document->set('some-field-name-mx', 'user@example'); $this->assertFalse($document->isValid()); // additional MX check on valid email From 7e5318e91036ab4a5ca8e8b01cc4245a495f0e60 Mon Sep 17 00:00:00 2001 From: MCubs Date: Tue, 23 Jun 2020 13:45:41 +0300 Subject: [PATCH 2/4] Add tests on delete collection --- src/Collection.php | 3 ++- tests/CollectionTest.php | 54 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/Collection.php b/src/Collection.php index c44e394..d90c00a 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -232,9 +232,10 @@ public function delete() { $status = $this->getMongoCollection()->drop(); + // Drop function in mongodb >= 3.6 with unacknowledged write concern return empty result if ($status === array()) { $writeConcern = $this->getWriteConcern(); - $status['ok'] = ($writeConcern['w'] === 0 ? 1:0); + $status = ($writeConcern['w'] === 0 ? array('ok' => 1):array('ok' => 0, 'errmsg' => 'unknown error')); } if ($status['ok'] != 1) { diff --git a/tests/CollectionTest.php b/tests/CollectionTest.php index 14b816c..46a508d 100644 --- a/tests/CollectionTest.php +++ b/tests/CollectionTest.php @@ -533,6 +533,60 @@ public function testDeleteCollection_ExceptionOnCollectionDeleteError() $collection->delete(); } + public function testDeleteCollection_WithUnacknowledgedWriteConcernAndEmptyResultStatus() + { + $this->collectionMock = $this + ->getMockBuilder('\MongoCollection') + ->setMethods(array('drop','getWriteConcern')) + ->setConstructorArgs(array( + $this->database->getMongoDB(), + 'phpmongo_test_collection', + )) + ->getMock(); + + $this->collectionMock + ->expects($this->once()) + ->method('drop') + ->willReturn(array()); + + $this->collectionMock + ->expects($this->once()) + ->method('getWriteConcern') + ->willReturn(array('w' => 0)); + + $collection = new Collection($this->database, $this->collectionMock); + $collection->delete(); + } + + /** + * @expectedException \Sokil\Mongo\Exception + * @expectedExceptionMessage Error deleting collection phpmongo_test_collection: unknown error + */ + public function testDeleteCollection_WithAcknowledgedWriteConcernAndEmptyResultStatus() + { + $this->collectionMock = $this + ->getMockBuilder('\MongoCollection') + ->setMethods(array('drop','getWriteConcern')) + ->setConstructorArgs(array( + $this->database->getMongoDB(), + 'phpmongo_test_collection', + )) + ->getMock(); + + $this->collectionMock + ->expects($this->once()) + ->method('drop') + ->willReturn(array()); + + $this->collectionMock + ->expects($this->once()) + ->method('getWriteConcern') + ->willReturn(array('w' => 1)); + + $collection = new Collection($this->database, $this->collectionMock); + $collection->delete(); + } + public function testDeleteDocuments_ExpressionAsArray() { // add From 50d05d68ae33a00b006d8525869953ef0cfb8d04 Mon Sep 17 00:00:00 2001 From: MCubs Date: Tue, 23 Jun 2020 14:57:58 +0300 Subject: [PATCH 3/4] Set mongodb ini settings in php 5.x --- docker/php/init.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker/php/init.sh b/docker/php/init.sh index c0a5218..c6fe330 100644 --- a/docker/php/init.sh +++ b/docker/php/init.sh @@ -63,6 +63,8 @@ then # last version of xdebug with support PHP < 7.0 is 2.5.5 if [[ ${PHP_VERSION:0:2} == "5." ]]; then pecl install xdebug-2.5.5; + echo "mongo.native_long=0" >> /usr/local/etc/php/conf.d/mongo.ini + echo "mongo.long_as_object=1" >> /usr/local/etc/php/conf.d/mongo.ini elif [[ ${PHP_VERSION:0:3} == "7.3" ]]; then pecl install xdebug-2.7.0beta1; else From a6dc52a668c8ef20be32cbd05d2aeab2987b2eab Mon Sep 17 00:00:00 2001 From: MCubs Date: Thu, 25 Jun 2020 09:10:22 +0300 Subject: [PATCH 4/4] Fix error: 'sort' parameter must be an object, found array, when is empty array in Cursor::findAndUpdate --- src/Cursor.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Cursor.php b/src/Cursor.php index bce9250..f7c9f3c 100644 --- a/src/Cursor.php +++ b/src/Cursor.php @@ -765,17 +765,20 @@ public function findAndRemove() */ public function findAndUpdate(Operator $operator, $upsert = false, $returnUpdated = true) { + $options = array( + 'new' => $returnUpdated, + 'upsert' => $upsert, + ); + if ($this->sort) { + $options['sort'] = $this->sort; + } $mongoDocument = $this->collection ->getMongoCollection() ->findAndModify( $this->expression->toArray(), $operator ? $operator->toArray() : null, $this->projection, - array( - 'new' => $returnUpdated, - 'sort' => $this->sort, - 'upsert' => $upsert, - ) + $options ); if (empty($mongoDocument)) {