Skip to content

Commit 0ca519a

Browse files
committed
added extra material for pratiksha to understand the query api use case and implementation
1 parent 21ec7b1 commit 0ca519a

File tree

6 files changed

+135
-2
lines changed

6 files changed

+135
-2
lines changed

docker-compose.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
version: '3.8'
2+
3+
services:
4+
neo4j:
5+
image: neo4j:5
6+
container_name: neo4j
7+
environment:
8+
# Change the password here as desired
9+
NEO4J_AUTH: "neo4j/your_password"
10+
ports:
11+
- "7474:7474" # HTTP
12+
- "7687:7687" # Bolt

src/Neo4jQueryAPI.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,9 @@ public function run(string $cypher, array $parameters, string $database = 'neo4j
8585
}
8686
}
8787

88+
public function beginTransaction(string $cypher = null, array $parameters = [], string $database = 'neo4j'): Transaction
89+
{
90+
91+
}
92+
8893
}

src/Results/ResultSet.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
<?php
22
namespace Neo4j\QueryAPI\Results;
33

4+
use ArrayIterator;
5+
use Countable;
46
use InvalidArgumentException;
57
use IteratorAggregate;
68
use Neo4j\QueryAPI\OGM;
79
use Traversable;
810

9-
class ResultSet implements IteratorAggregate
11+
class ResultSet implements IteratorAggregate, Countable
1012
{
1113
/**
1214
* @param list<ResultRow> $rows
@@ -17,6 +19,11 @@ public function __construct(private readonly array $rows)
1719

1820
public function getIterator(): Traversable
1921
{
20-
return new \ArrayIterator($this->rows);
22+
return new ArrayIterator($this->rows);
23+
}
24+
25+
public function count(): int
26+
{
27+
return count($this->rows);
2128
}
2229
}

src/Transaction.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Neo4j\QueryAPI;
4+
5+
use Neo4j\QueryAPI\Results\ResultSet;
6+
7+
class Transaction
8+
{
9+
public function run(string $statement, array $params = []): ResultSet
10+
{
11+
12+
}
13+
14+
public function commit(string $statement = null, array $parameters = []): null|ResultSet
15+
{
16+
17+
}
18+
19+
public function rollback(): void
20+
{
21+
22+
}
23+
}

test.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
require 'vendor/autoload.php'; // Make sure Guzzle is installed (composer require guzzlehttp/guzzle)
4+
5+
use GuzzleHttp\Client;
6+
7+
//$neo4j_url = 'https://6f72daa1.databases.neo4j.io/db/neo4j/query/v2/tx';
8+
//$neo4j_url = 'http://localhost:7474/db/neo4j/query/v2/tx';
9+
$username = 'neo4j';
10+
$password = 'your_password';
11+
//$password = '9lWmptqBgxBOz8NVcTJjgs3cHPyYmsy63ui6Spmw1d0';
12+
13+
$query = 'CREATE (n:Person) RETURN n';
14+
15+
$auth = base64_encode("$username:$password");
16+
17+
$payload = json_encode([
18+
'statement' => $query,
19+
]);
20+
21+
$headers = [
22+
'Authorization' => 'Basic ' . $auth,
23+
'Content-Type' => 'application/json',
24+
'Accept' => 'application/json',
25+
];
26+
27+
28+
$client = new Client();
29+
30+
$response = $client->post('http://localhost:7474/db/neo4j/query/v2/tx', [
31+
'headers' => $headers,
32+
'body' => $payload,
33+
]);
34+
$clusterAffinity = $response->getHeaderLine('neo4j-cluster-affinity');
35+
$responseData = json_decode($response->getBody(), true);
36+
$headers['neo4j-cluster-affinity'] = $clusterAffinity;
37+
38+
$transactionId = $responseData['transaction']['id'];
39+
40+
$response = $client->delete('http://localhost:7474/db/neo4j/query/v2/tx/' . $transactionId, [
41+
'headers' => $headers,
42+
'body' => $payload,
43+
]);
44+
$responseData = json_decode($response->getBody(), true);
45+
46+
47+
//$commitUrl = 'https://6f72daa1.databases.neo4j.io/db/neo4j/tx/' . $responseData['transaction']['id'] . '/query/v2/commit';
48+
$response = $client->post('http://localhost:7474/db/neo4j/query/v2/tx/' . $transactionId . '/commit', [
49+
'headers' => $headers,
50+
'body' => $payload,
51+
]);
52+
$responseData = json_decode($response->getBody(), true);
53+
print_r($responseData);
54+

tests/Integration/Neo4jQueryAPIIntegrationTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,38 @@ private function initializeApi(): Neo4jQueryAPI
3535
);
3636
}
3737

38+
public function testTransactionCommit(): void
39+
{
40+
// This test validates if a transaction exists in its own world until we commit it.
41+
// by create a node in our transaction we validate if it exists within the transaction,
42+
// but not the database.
43+
// After we commit our transaction we are able to validate if our created node exists in the database.
44+
45+
$tsx = $this->api->beginTransaction();
46+
47+
// we create a human with a random name and remember our randomly generated name so
48+
// we can query its existence.
49+
// by creating it in a transaction it should not exist in the real database yet.
50+
$name = mt_rand(1, 100000);
51+
$tsx->run('CREATE (x:Human {name: $name})', ['name' => $name]);
52+
53+
54+
// we simply validate if the human with the random name does not exist in the database, because we
55+
// haven't commited our transaction yet.
56+
$results = $this->api->run('MATCH (x:Human {name: $name}) RETURN x', ['name' => $name]);
57+
$this->assertCount(0, $results);
58+
59+
// The human should of course only exist in the transaction, so we expect a count of 1 here.
60+
$results = $tsx->run('MATCH (x:Human {name: $name}) RETURN x', ['name' => $name]);
61+
$this->assertCount(1, $results);
62+
63+
$tsx->commit();
64+
65+
// Now that we have commited our transaction, the human should of course exist in our database
66+
$results = $this->api->run('MATCH (x:Human {name: $name}) RETURN x', ['name' => $name]);
67+
$this->assertCount(1, $results);
68+
}
69+
3870
/**
3971
* @throws GuzzleException
4072
*/

0 commit comments

Comments
 (0)