From 6dc41c409f51f52f0e58522a7c46dbf5194e3cc2 Mon Sep 17 00:00:00 2001 From: Jeremy Mikola Date: Mon, 21 Nov 2016 13:39:23 -0500 Subject: [PATCH] PHPC-676: Do not allow BulkWrite objects to be executed multiple times --- php_phongo.c | 12 +-- tests/bulk/bulkwrite_error-002.phpt | 27 ++++++ tests/bulk/write-0003.phpt | 85 ------------------- .../manager-executeBulkWrite_error-007.phpt | 11 +-- .../replicaset/manager-selectserver-001.phpt | 5 ++ 5 files changed, 41 insertions(+), 99 deletions(-) create mode 100644 tests/bulk/bulkwrite_error-002.phpt delete mode 100644 tests/bulk/write-0003.phpt diff --git a/php_phongo.c b/php_phongo.c index ece495bfb..a0378d7b8 100644 --- a/php_phongo.c +++ b/php_phongo.c @@ -489,15 +489,9 @@ bool phongo_execute_write(zval *manager, const char *namespace, php_phongo_bulkw client = Z_MANAGER_OBJ_P(manager)->client; - /* Since BulkWrite objects can currently be executed multiple times, ensure - * that the database and collection name are freed before we overwrite them. - * This may be removed once PHPC-676 is implemented. */ - if (bulk_write->database) { - efree(bulk_write->database); - } - - if (bulk_write->collection) { - efree(bulk_write->collection); + if (bulk_write->executed) { + phongo_throw_exception(PHONGO_ERROR_WRITE_FAILED TSRMLS_CC, "BulkWrite objects may only be executed once and this instance has already been executed"); + return false; } if (!phongo_split_namespace(namespace, &bulk_write->database, &bulk_write->collection)) { diff --git a/tests/bulk/bulkwrite_error-002.phpt b/tests/bulk/bulkwrite_error-002.phpt new file mode 100644 index 000000000..bbef30f15 --- /dev/null +++ b/tests/bulk/bulkwrite_error-002.phpt @@ -0,0 +1,27 @@ +--TEST-- +MongoDB\Driver\BulkWrite cannot be executed multiple times +--SKIPIF-- + +--FILE-- +insert(['x' => 1]); +$result = $manager->executeBulkWrite(NS, $bulk); +printf("Inserted %d document(s)\n", $result->getInsertedCount()); + +echo throws(function() use ($manager, $bulk) { + $result = $manager->executeBulkWrite(NS, $bulk); +}, 'MongoDB\Driver\Exception\BulkWriteException'), "\n"; + +?> +===DONE=== + +--EXPECTF-- +Inserted 1 document(s) +OK: Got MongoDB\Driver\Exception\BulkWriteException +BulkWrite objects may only be executed once and this instance has already been executed +===DONE=== diff --git a/tests/bulk/write-0003.phpt b/tests/bulk/write-0003.phpt deleted file mode 100644 index 0084588a6..000000000 --- a/tests/bulk/write-0003.phpt +++ /dev/null @@ -1,85 +0,0 @@ ---TEST-- -MongoDB\Driver\BulkWrite: #003 executed multiple times ---SKIPIF-- - ---FILE-- -insert(['x' => 1]); -$result = $manager->executeBulkWrite(NS, $insertBulk); -printf("Inserted %d document(s)\n", $result->getInsertedCount()); - -$insertBulk = new MongoDB\Driver\BulkWrite; -$insertBulk->insert(['x' => 1]); -$result = $manager->executeBulkWrite(NS, $insertBulk); -printf("Inserted %d document(s)\n", $result->getInsertedCount()); - -try { - $result = $manager->executeBulkWrite(NS, $insertBulk); - printf("Inserted %d document(s)\n", $result->getInsertedCount()); -} catch (MongoDB\Driver\Exception\BulkWriteException $e) { - printf("Write error: %s\n", $e->getWriteResult()->getWriteErrors()[0]->getMessage()); -} - -$updateBulk = new MongoDB\Driver\BulkWrite; -$updateBulk->update([], ['$inc' => ['x' => 1]]); -$result = $manager->executeBulkWrite(NS, $updateBulk); -printf("Updated %d document(s)\n", $result->getModifiedCount()); - -$result = $manager->executeBulkWrite(NS, $updateBulk); -printf("Updated %d document(s)\n", $result->getModifiedCount()); - -$cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); -var_dump($cursor->toArray()); - -$deleteBulk = new MongoDB\Driver\BulkWrite; -$deleteBulk->delete([], ['limit' => 1]); -$result = $manager->executeBulkWrite(NS, $deleteBulk); -printf("Deleted %d document(s)\n", $result->getDeletedCount()); - -$result = $manager->executeBulkWrite(NS, $deleteBulk); -printf("Deleted %d document(s)\n", $result->getDeletedCount()); - -$cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); -var_dump($cursor->toArray()); - -?> -===DONE=== - ---EXPECTF-- -Inserted 1 document(s) -Inserted 1 document(s) -Write error: E11000 duplicate key error%s -Updated 1 document(s) -Updated 1 document(s) -array(2) { - [0]=> - object(stdClass)#%d (%d) { - ["_id"]=> - object(MongoDB\BSON\ObjectID)#%d (%d) { - ["oid"]=> - string(24) "%x" - } - ["x"]=> - int(3) - } - [1]=> - object(stdClass)#%d (%d) { - ["_id"]=> - object(MongoDB\BSON\ObjectID)#%d (%d) { - ["oid"]=> - string(24) "%x" - } - ["x"]=> - int(1) - } -} -Deleted 1 document(s) -Deleted 1 document(s) -array(0) { -} -===DONE=== diff --git a/tests/manager/manager-executeBulkWrite_error-007.phpt b/tests/manager/manager-executeBulkWrite_error-007.phpt index 1d1dad98d..cc3631a94 100644 --- a/tests/manager/manager-executeBulkWrite_error-007.phpt +++ b/tests/manager/manager-executeBulkWrite_error-007.phpt @@ -6,20 +6,21 @@ MongoDB\Driver\Manager::executeBulkWrite() should not issue warning before excep insert(['x' => 1]); - // Invalid host cannot be resolved $manager = new MongoDB\Driver\Manager('mongodb://invalid.host:27017', ['serverSelectionTimeoutMS' => 1]); -echo throws(function() use ($manager, $bulk) { +echo throws(function() use ($manager) { + $bulk = new MongoDB\Driver\BulkWrite; + $bulk->insert(['x' => 1]); $manager->executeBulkWrite(NS, $bulk); }, 'MongoDB\Driver\Exception\ConnectionTimeoutException'), "\n"; // Valid host refuses connection $manager = new MongoDB\Driver\Manager('mongodb://localhost:54321', ['serverSelectionTimeoutMS' => 1]); -echo throws(function() use ($manager, $bulk) { +echo throws(function() use ($manager) { + $bulk = new MongoDB\Driver\BulkWrite; + $bulk->insert(['x' => 1]); $manager->executeBulkWrite(NS, $bulk); }, 'MongoDB\Driver\Exception\ConnectionTimeoutException'), "\n"; diff --git a/tests/replicaset/manager-selectserver-001.phpt b/tests/replicaset/manager-selectserver-001.phpt index 20be6f084..65affb385 100644 --- a/tests/replicaset/manager-selectserver-001.phpt +++ b/tests/replicaset/manager-selectserver-001.phpt @@ -41,6 +41,11 @@ $bulk->insert(array('_id' => 3, 'x' => 4, 'y' => 5)); throws(function() use($server2, $bulk) { $server2->executeBulkWrite(NS, $bulk); }, "MongoDB\Driver\Exception\BulkWriteException"); + +$bulk = new \MongoDB\Driver\BulkWrite(); +$bulk->insert(array('_id' => 1, 'x' => 2, 'y' => 3)); +$bulk->insert(array('_id' => 2, 'x' => 3, 'y' => 4)); +$bulk->insert(array('_id' => 3, 'x' => 4, 'y' => 5)); $result = $server2->executeBulkWrite("local.example", $bulk); var_dump($result->getInsertedCount()); ?>