From abdb7dc8ac08bf993f09dec45d238f0a76807334 Mon Sep 17 00:00:00 2001 From: Oliver Mack Date: Sat, 29 Mar 2014 08:26:02 +0100 Subject: [PATCH] Added CollectionHandler::has() checker method which enables checking if a collection exists Added DocumentHandler::has() checker method which enables checking if a document exists Added GraphHandler::hasVertex() checker method which enables checking if a vertex exists Added GraphHandler::hasEdge() checker method which enables checking if an edge exists --- README.md | 22 ++++--- examples/collection.php | 4 ++ examples/document.php | 4 ++ examples/graph.php | 6 ++ lib/triagens/ArangoDb/CollectionHandler.php | 33 ++++++++++- lib/triagens/ArangoDb/DocumentHandler.php | 38 +++++++++++- lib/triagens/ArangoDb/GraphHandler.php | 64 +++++++++++++++++++++ tests/CollectionBasicTest.php | 61 +++++++++++--------- tests/DocumentBasicTest.php | 25 ++++++++ tests/GraphExtendedTest.php | 26 +++++++++ 10 files changed, 246 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 58bb1cfa..6d7d1d18 100644 --- a/README.md +++ b/README.md @@ -216,11 +216,11 @@ In order to use ArangoDB, you need to specify the connection options. We do so b // authorization type to use (currently supported: 'Basic') ArangoConnectionOptions::OPTION_AUTH_TYPE => 'Basic', // user for basic authorization - ArangoConnectionOptions::OPTION_AUTH_USER => 'root', + ArangoConnectionOptions::OPTION_AUTH_USER => 'root', // password for basic authorization - ArangoConnectionOptions::OPTION_AUTH_PASSWD => '', + ArangoConnectionOptions::OPTION_AUTH_PASSWD => '', // connection persistence on server. can use either 'Close' (one-time connections) or 'Keep-Alive' (re-used connections) - ArangoConnectionOptions::OPTION_CONNECTION => 'Close', + ArangoConnectionOptions::OPTION_CONNECTION => 'Close', // connect timeout in seconds ArangoConnectionOptions::OPTION_TIMEOUT => 3, // whether or not to reconnect when a keep-alive connection has timed out on server @@ -263,7 +263,7 @@ The below code will first set up the collection locally in a variable name $user $collectionHandler = new CollectionHandler($connection); - // create a new document + // create a new collection $userCollection = new ArangoCollection(); $userCollection->setName('user'); $id = $collectionHandler->add($userCollection); @@ -271,6 +271,10 @@ The below code will first set up the collection locally in a variable name $user // print the collection id created by the server var_dump($id); + // check if the collection exists + $result = $collectionHandler->has('user'); + var_dump($result); + ## Creating a document @@ -298,6 +302,10 @@ The below code will first set up the document locally in a variable name $user, // print the document id created by the server var_dump($id); + // check if a document exists + $result = $handler->has("users", $id); + var_dump($result); + Document properties can be set by using the set() method, or by directly manipulating the document properties. @@ -484,11 +492,11 @@ Here's the full code that combines all the pieces outlined above: // authorization type to use (currently supported: 'Basic') ArangoConnectionOptions::OPTION_AUTH_TYPE => 'Basic', // user for basic authorization - ArangoConnectionOptions::OPTION_AUTH_USER => 'root', + ArangoConnectionOptions::OPTION_AUTH_USER => 'root', // password for basic authorization - ArangoConnectionOptions::OPTION_AUTH_PASSWD => '', + ArangoConnectionOptions::OPTION_AUTH_PASSWD => '', // connection persistence on server. can use either 'Close' (one-time connections) or 'Keep-Alive' (re-used connections) - ArangoConnectionOptions::OPTION_CONNECTION => 'Close', + ArangoConnectionOptions::OPTION_CONNECTION => 'Close', // connect timeout in seconds ArangoConnectionOptions::OPTION_TIMEOUT => 3, // optionally create new collections when inserting documents diff --git a/examples/collection.php b/examples/collection.php index 130b5a68..364aacef 100644 --- a/examples/collection.php +++ b/examples/collection.php @@ -14,6 +14,10 @@ $result = $handler->add($col); var_dump($result); + // check if a collection exists + $result = $handler->has("foobar"); + var_dump($result); + // get an existing collection $result = $handler->get("hihi"); var_dump($result); diff --git a/examples/document.php b/examples/document.php index cb5e2292..fc434a1e 100644 --- a/examples/document.php +++ b/examples/document.php @@ -50,6 +50,10 @@ // delete the document $result = $handler->deleteById("users", $id); var_dump($result); + + // check if a document exists + $result = $handler->has("users", "foobar123"); + var_dump($result); } catch (ConnectException $e) { print $e . PHP_EOL; } catch (ServerException $e) { diff --git a/examples/graph.php b/examples/graph.php index c94c84b6..78197f60 100644 --- a/examples/graph.php +++ b/examples/graph.php @@ -42,9 +42,15 @@ $getResult1 = $graphHandler->getVertex('Graph', 'vertex1'); $getResult2 = $graphHandler->getVertex('Graph', 'vertex2'); + // check if vertex exists + var_dump($graphHandler->hasVertex('Graph', 'vertex1')); + // Save the connecting edge $saveEdgeResult1 = $graphHandler->saveEdge('Graph', 'vertex1', 'vertex2', 'somelabelValue', $edge1); + // check if edge exists + var_dump($graphHandler->hasEdge('Graph', 'edge1')); + // Get the connecting edge $getEdgeResult1 = $graphHandler->getEdge('Graph', 'edge1'); diff --git a/lib/triagens/ArangoDb/CollectionHandler.php b/lib/triagens/ArangoDb/CollectionHandler.php index 20e9fe02..f60d8983 100644 --- a/lib/triagens/ArangoDb/CollectionHandler.php +++ b/lib/triagens/ArangoDb/CollectionHandler.php @@ -247,6 +247,37 @@ public function get($collectionId) } + /** + * Check if a collection exists + * + * This will call self::get() internally and checks if there + * was an exception thrown which represents an 404 request. + * + * @throws Exception When any other error than a 404 occurs + * + * @param mixed $collectionId - collection id as a string or number + * @return boolean + */ + public function has($collectionId) + { + try { + // will throw ServerException if entry could not be retrieved + $result = $this->get($collectionId); + return true; + } catch (ServerException $e) { + // we are expecting a 404 to return boolean false + if (strpos($e->getMessage(), '404') !== false) { + return false; + } + + // just rethrow + throw $e; + } + + return false; + } + + /** * Get properties of a collection * @@ -438,7 +469,7 @@ public function create($collection, $options = array()) if ($collection->getNumberOfShards() !== null) { $params[Collection::ENTRY_NUMBER_OF_SHARDS] = $collection->getNumberOfShards(); } - + if (is_array($collection->getShardKeys())) { $params[Collection::ENTRY_SHARD_KEYS] = $collection->getShardKeys(); } diff --git a/lib/triagens/ArangoDb/DocumentHandler.php b/lib/triagens/ArangoDb/DocumentHandler.php index 7900a387..2f6e1549 100644 --- a/lib/triagens/ArangoDb/DocumentHandler.php +++ b/lib/triagens/ArangoDb/DocumentHandler.php @@ -70,6 +70,38 @@ public function get($collectionId, $documentId, array $options = array()) } + /** + * Check if a document exists + * + * This will call self::get() internally and checks if there + * was an exception thrown which represents an 404 request. + * + * @throws Exception When any other error than a 404 occurs + * + * @param string $collectionId - collection id as a string or number + * @param mixed $documentId - document identifier + * @return boolean + */ + public function has($collectionId, $documentId) + { + try { + // will throw ServerException if entry could not be retrieved + $result = $this->get($collectionId, $documentId); + return true; + } catch (ServerException $e) { + // we are expecting a 404 to return boolean false + if (strpos($e->getMessage(), '404') !== false) { + return false; + } + + // just rethrow + throw $e; + } + + return false; + } + + /** * Get a single document from a collection * @@ -590,8 +622,8 @@ public function replaceById($collectionId, $documentId, Document $document, $opt { return $this->put(Urls::URL_DOCUMENT, $collectionId, $documentId, $document, $options); } - - + + /** * Replace an existing document in a collection (internal method) * @@ -734,7 +766,7 @@ public function removeById($collectionId, $documentId, $revision = null, $option return $this->erase(Urls::URL_DOCUMENT, $collectionId, $documentId, $revision, $options); } - + /** * Remove a document from a collection (internal method) * diff --git a/lib/triagens/ArangoDb/GraphHandler.php b/lib/triagens/ArangoDb/GraphHandler.php index 9d2cb4cf..dabf798c 100644 --- a/lib/triagens/ArangoDb/GraphHandler.php +++ b/lib/triagens/ArangoDb/GraphHandler.php @@ -239,6 +239,38 @@ public function getVertex($graphName, $vertexId, array $options = array()) } + /** + * Check if a vertex exists + * + * This will call self::getVertex() internally and checks if there + * was an exception thrown which represents an 404 request. + * + * @throws Exception When any other error than a 404 occurs + * + * @param mixed $graph - graph name as a string or instance of Graph + * @param mixed $vertexId - the vertex identifier + * @return boolean + */ + public function hasVertex($graph, $vertexId) + { + try { + // will throw ServerException if entry could not be retrieved + $result = $this->getVertex($graph, $vertexId); + return true; + } catch (ServerException $e) { + // we are expecting a 404 to return boolean false + if (strpos($e->getMessage(), '404') !== false) { + return false; + } + + // just rethrow + throw $e; + } + + return false; + } + + /** * Replace an existing vertex in a graph, identified graph name and vertex id * @@ -522,6 +554,38 @@ public function getEdge($graphName, $edgeId, array $options = array()) } + /** + * Check if an edge exists + * + * This will call self::getEdge() internally and checks if there + * was an exception thrown which represents an 404 request. + * + * @throws Exception When any other error than a 404 occurs + * + * @param mixed $graph - graph name as a string or instance of Graph + * @param mixed $edgeId - the vertex identifier + * @return boolean + */ + public function hasEdge($graph, $edgeId) + { + try { + // will throw ServerException if entry could not be retrieved + $result = $this->getEdge($graph, $edgeId); + return true; + } catch (ServerException $e) { + // we are expecting a 404 to return boolean false + if (strpos($e->getMessage(), '404') !== false) { + return false; + } + + // just rethrow + throw $e; + } + + return false; + } + + /** * Replace an existing edge in a graph, identified graph name and edge id * diff --git a/tests/CollectionBasicTest.php b/tests/CollectionBasicTest.php index d38b8c79..b4050c71 100644 --- a/tests/CollectionBasicTest.php +++ b/tests/CollectionBasicTest.php @@ -81,9 +81,9 @@ public function testCreateAndDeleteCollectionPre1_2() $connection = $this->connection; $collection = new Collection(); $collectionHandler = new CollectionHandler($connection); - + $name = 'ArangoDB_PHP_TestSuite_TestCollection_01'; - + try { $collectionHandler->drop($name); } catch (Exception $e) { @@ -117,13 +117,13 @@ public function testCreateCollectionWithKeyOptionsAndVerifyProperties() // don't execute this test in a cluster return; } - + $connection = $this->connection; $collection = new Collection(); $collectionHandler = new CollectionHandler($connection); - + $name = 'ArangoDB_PHP_TestSuite_TestCollection_01'; - + try { $collectionHandler->drop($name); } catch (Exception $e) { @@ -162,7 +162,7 @@ public function testCreateCollectionWithKeyOptionsAndVerifyProperties() ); $collectionHandler->delete($collection); } - + /** * Try to create a collection with keyOptions and then retrieve it to confirm. @@ -173,13 +173,13 @@ public function testCreateCollectionWithKeyOptionsCluster() // don't execute this test in a non-cluster return; } - + $connection = $this->connection; $collection = new Collection(); $collectionHandler = new CollectionHandler($connection); - + $name = 'ArangoDB_PHP_TestSuite_TestCollection_01'; - + try { $collectionHandler->drop($name); } catch (Exception $e) { @@ -196,11 +196,11 @@ public function testCreateCollectionWithKeyOptionsCluster() } catch (\Exception $e) { } - + $this->assertEquals($e->getCode() , 501); } - - + + /** * Try to create a collection with number of shards */ @@ -210,13 +210,13 @@ public function testCreateCollectionWithNumberOfShardsCluster() // don't execute this test in a non-cluster return; } - + $connection = $this->connection; $collection = new Collection(); $collectionHandler = new CollectionHandler($connection); - + $name = 'ArangoDB_PHP_TestSuite_TestCollection_01'; - + try { $collectionHandler->drop($name); } catch (Exception $e) { @@ -234,8 +234,8 @@ public function testCreateCollectionWithNumberOfShardsCluster() $this->assertEquals($properties[Collection::ENTRY_NUMBER_OF_SHARDS], 4, 'Number of shards does not match.'); $this->assertEquals($properties[Collection::ENTRY_SHARD_KEYS], array("_key"), 'Shard keys do not match.'); } - - + + /** * Try to create a collection with specified shard keys */ @@ -245,13 +245,13 @@ public function testCreateCollectionWithShardKeysCluster() // don't execute this test in a non-cluster return; } - + $connection = $this->connection; $collection = new Collection(); $collectionHandler = new CollectionHandler($connection); - + $name = 'ArangoDB_PHP_TestSuite_TestCollection_01'; - + try { $collectionHandler->drop($name); } catch (Exception $e) { @@ -279,9 +279,9 @@ public function testCreateAndDeleteCollection() $connection = $this->connection; $collection = new Collection(); $collectionHandler = new CollectionHandler($connection); - + $name = 'ArangoDB_PHP_TestSuite_TestCollection_01'; - + try { $collectionHandler->drop($name); } catch (Exception $e) { @@ -313,7 +313,7 @@ public function testCreateAndDeleteEdgeCollection() $connection = $this->connection; $collection = new Collection(); $collectionHandler = new CollectionHandler($connection); - + $name = 'ArangoDB_PHP_TestSuite_TestCollection_02'; try { @@ -349,7 +349,7 @@ public function testCreateAndDeleteEdgeCollectionWithoutCreatingObject() $collectionHandler = new CollectionHandler($connection); $name = 'ArangoDB_PHP_TestSuite_TestCollection_02'; - + try { $collectionHandler->drop($name); } catch (Exception $e) { @@ -382,7 +382,7 @@ public function testCreateAndDeleteVolatileCollectionWithoutCreatingObject() $collectionHandler = new CollectionHandler($connection); $name = 'ArangoDB_PHP_TestSuite_TestCollection_02'; - + try { $collectionHandler->drop($name); } catch (Exception $e) { @@ -414,7 +414,7 @@ public function testCreateAndDeleteSystemCollectionWithoutCreatingObject() $collectionHandler = new CollectionHandler($connection); $name = 'ArangoDB_PHP_TestSuite_TestCollection_02'; - + try { $collectionHandler->drop($name); } catch (Exception $e) { @@ -657,6 +657,15 @@ public function testGetIndex() $this->assertEquals(100, $indexInfo[CollectionHandler::OPTION_MIN_LENGTH], 'Min length does not match!'); } + public function testHasCollectionReturnsFalseIfCollectionDoesNotExist() + { + $this->assertFalse($this->collectionHandler->has('just_a_stupid_collection_id_which_does_not_exist')); + } + + public function testHasCollectionReturnsTrueIfCollectionExists() + { + $this->assertTrue($this->collectionHandler->has('ArangoDB_PHP_TestSuite_IndexTestCollection')); + } public function tearDown() { diff --git a/tests/DocumentBasicTest.php b/tests/DocumentBasicTest.php index ed531cf8..694efd9f 100644 --- a/tests/DocumentBasicTest.php +++ b/tests/DocumentBasicTest.php @@ -251,6 +251,31 @@ public function testCreateAndDeleteDocumentUsingDefinedKeyWithArrayAndSaveOnly() } + public function testHasDocumentReturnsFalseIfDocumentDoesNotExist() + { + $connection = $this->connection; + $collection = $this->collection; + $documentHandler = new DocumentHandler($connection); + $this->assertFalse($documentHandler->has($collection->getId(), 'just_a_stupid_document_id_which_does_not_exist')); + } + + + public function testHasDocumentReturnsTrueIfDocumentExists() + { + $connection = $this->connection; + $collection = $this->collection; + $documentHandler = new DocumentHandler($connection); + + // create doc first + $document = new Document(); + $document->someAttribute = 'someValue'; + + $documentId = $documentHandler->add($collection->getId(), $document); + + $this->assertTrue($this->collectionHandler->has($collection->getId(), $documentId)); + } + + public function tearDown() { try { diff --git a/tests/GraphExtendedTest.php b/tests/GraphExtendedTest.php index f45ebf6f..cd8362a6 100644 --- a/tests/GraphExtendedTest.php +++ b/tests/GraphExtendedTest.php @@ -1380,6 +1380,32 @@ public function testCreateGraphAndQueryEdges() } + public function testHasVertexReturnsFalseIfNotExists() + { + $result = $this->graphHandler->hasVertex($this->graphName, 'just_a_stupid_vertex_id_which_does_not_exist'); + $this->assertFalse($result); + } + + public function testHasVertexReturnsTrueIfExists() + { + $this->createGraph(); + $result = $this->graphHandler->hasVertex($this->graphName, $this->vertex1Name); + $this->assertTrue($result); + } + + public function testHasEdgeReturnsFalseIfNotExists() + { + $result = $this->graphHandler->hasEdge($this->graphName, 'just_a_stupid_edge_id_which_does_not_exist'); + $this->assertFalse($result); + } + + public function testHasEdgeReturnsTrueIfExists() + { + $this->createGraph(); + $result = $this->graphHandler->hasEdge($this->graphName, $this->edge1Name); + $this->assertTrue($result); + } + public function tearDown() { try {