Skip to content

Commit fdfa7a3

Browse files
committed
Merge remote-tracking branch 'origin/main' into workinprogress
2 parents e06d6cc + e05524e commit fdfa7a3

19 files changed

+446
-180
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.idea/
22
vendor
33
phpunit.xml
4-
test
4+
test
5+
.phpunit.result.cache

.phpunit.result.cache

Lines changed: 0 additions & 1 deletion
This file was deleted.

composer.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
"guzzlehttp/guzzle": "^7.9",
77
"psr/http-client": "^1.0",
88
"ext-json": "*",
9-
"php": "^8.1",
10-
"laudis/neo4j-php-client": "^3.2"
9+
"php": "^8.1"
1110
},
1211
"require-dev": {
1312
"phpunit/phpunit": "^11.0"

composer.lock

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

queryCounters/queryCountersTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class queryCountersTest extends TestCase
77
{
88
public function testGetExistingCounter(): void
99
{
10-
$counters = new queryCounters([
10+
$counters = new \Neo4j\QueryAPI\Objects\ResultCounters([
1111
'nodes_created' => 1,
1212
'relationships_created' => 2,
1313
'properties_set' => 3,

run.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace Neo4j\QueryAPI;
4+
require './vendor/autoload.php'; // Make sure Guzzle is installed (composer require guzzlehttp/guzzle)
5+
6+
use GuzzleHttp\Client;
7+
8+
9+
$neo4j_url = 'https://6f72daa1.databases.neo4j.io/';
10+
$username = 'neo4j';
11+
//$password = 'your_password';
12+
$password = '9lWmptqBgxBOz8NVcTJjgs3cHPyYmsy63ui6Spmw1d0';
13+
14+
$query = 'CREATE (n:Person {name: "Bobby"}) RETURN n';
15+
16+
$auth = base64_encode("$username:$password");
17+
18+
$payload = json_encode([
19+
'statement' => $query,
20+
]);
21+
22+
$headers = [
23+
'Authorization' => 'Basic ' . $auth,
24+
'Content-Type' => 'application/json',
25+
'Accept' => 'application/json',
26+
];
27+
28+
29+
$client = new Client();
30+
31+
$response = $client->post('https://6f72daa1.databases.neo4j.io/db/neo4j/query/v2/tx', [
32+
'headers' => $headers,
33+
'body' => $payload,
34+
]);
35+
$responseData = json_decode($response->getBody(), true);
36+
37+
print_r($responseData);

src/Neo4jQueryAPI.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static function login(string $address, string $username, string $password
2929
'base_uri' => rtrim($address, '/'),
3030
'timeout' => 10.0,
3131
'headers' => [
32-
'Authorization' => '',
32+
'Authorization' => 'Basic ' . base64_encode("$username:$password"),
3333
'Content-Type' => 'application/vnd.neo4j.query',
3434
'Accept'=>'application/vnd.neo4j.query',
3535
],
@@ -45,17 +45,18 @@ public static function login(string $address, string $username, string $password
4545
public function run(string $cypher, array $parameters, string $database = 'neo4j'): ResultSet
4646
{
4747
try {
48-
48+
// Prepare the payload for the request
4949
$payload = [
5050
'statement' => $cypher,
5151
'parameters' => empty($parameters) ? new stdClass() : $parameters,
5252
];
5353

54+
// Execute the request to the Neo4j server
5455
$response = $this->client->post('/db/' . $database . '/query/v2', [
5556
'json' => $payload,
5657
]);
5758

58-
59+
// Decode the response body
5960
$data = json_decode($response->getBody()->getContents(), true);
6061
$ogm = new OGM();
6162

@@ -70,7 +71,7 @@ public function run(string $cypher, array $parameters, string $database = 'neo4j
7071
return new ResultRow($data);
7172
}, $values);
7273

73-
return new ResultSet($ogm, $rows);
74+
return new ResultSet($rows);
7475
} catch (RequestExceptionInterface $e) {
7576
$response = $e->getResponse();
7677
if ($response !== null) {
@@ -84,4 +85,16 @@ public function run(string $cypher, array $parameters, string $database = 'neo4j
8485
}
8586
}
8687

88+
public function beginTransaction(string $database = 'neo4j'): Transaction
89+
{
90+
$response = $this->client->post("/db/neo4j/query/v2/tx");
91+
92+
$clusterAffinity = $response->getHeaderLine('neo4j-cluster-affinity');
93+
$responseData = json_decode($response->getBody(), true);
94+
$transactionId = $responseData['transaction']['id'];
95+
96+
97+
98+
return new Transaction($this->client, $clusterAffinity, $transactionId);
99+
}
87100
}

src/Results/ResultSet.php

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

4+
use ArrayIterator;
5+
use Countable;
46
use IteratorAggregate;
57
use Neo4j\QueryAPI\Objects\ResultCounters;
6-
use Neo4j\QueryAPI\OGM;
7-
use queryCounters;
88
use Traversable;
99

10-
class ResultSet implements IteratorAggregate
10+
class ResultSet implements IteratorAggregate, Countable
1111
{
1212
/**
13-
* @var list<ResultRow>
13+
* @param list<ResultRow> $rows
1414
*/
15-
private array $rows = [];
16-
17-
/**
18-
* @param OGM $ogm
19-
*/
20-
public function __construct(private OGM $ogm, private ResultCounters $counters)
15+
public function __construct(private readonly array $rows,private ResultCounters $counters)
2116
{
2217
}
2318

24-
/**
25-
*
26-
* @param array $keys
27-
* @param array $dataRows
28-
*/
29-
public function initialize(array $dataRows): void
30-
{
31-
foreach ($dataRows as $dataRow) {
32-
$this->rows[] = new ResultRow($this->ogm->map($dataRow));
33-
}
34-
}
35-
3619
public function getIterator(): Traversable
3720
{
38-
return new \ArrayIterator($this->rows);
21+
return new ArrayIterator($this->rows);
3922
}
40-
public function getqueryCounters(): ?QueryCounters
23+
public function getQueryCounters(): ?ResultCounters
4124
{
4225
return $this->counters;
4326
}
27+
28+
public function count(): int
29+
{
30+
return count($this->rows);
31+
}
32+
33+
4434
}

src/Transaction.php

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
namespace Neo4j\QueryAPI;
4+
5+
use GuzzleHttp\Client;
6+
use Neo4j\QueryAPI\Exception\Neo4jException;
7+
use Neo4j\QueryAPI\Results\ResultRow;
8+
use Psr\Http\Client\ClientInterface;
9+
use Psr\Http\Client\RequestExceptionInterface;
10+
use stdClass;
11+
12+
class Transaction
13+
{
14+
15+
public function __construct(private ClientInterface $client, private string $clusterAffinity, private string $transactionId)
16+
{
17+
}
18+
19+
/**
20+
* Create a node in Neo4j with a specified label and properties.
21+
*
22+
* @param string $query The Cypher query to be executed.
23+
* @param $parameters
24+
* @return array The response data from Neo4j.
25+
*/
26+
public function run(string $query, array $parameters): array
27+
{
28+
// Execute the request to the Neo4j server
29+
$response = $this->client->post("/db/neo4j/query/v2/tx", [
30+
'headers' => [
31+
'neo4j-cluster-affinity' => $this->clusterAffinity,
32+
],
33+
'json' => [
34+
35+
'statement' => $query,
36+
'parameters' => empty($parameters) ? new stdClass() : $parameters, // Pass the parameters array here
37+
38+
],
39+
]);
40+
41+
// Decode the response body
42+
$data = json_decode($response->getBody()->getContents(), true);
43+
44+
// Initialize the OGM (Object Graph Mapping) class
45+
$ogm = new OGM();
46+
47+
// Extract keys (field names) and values (actual data)
48+
$keys = $data['results'][0]['columns'];
49+
$values = $data['results'][0]['data'];
50+
51+
// Process each row of the result and map them using OGM
52+
$rows = array_map(function ($resultRow) use ($ogm, $keys) {
53+
$data = [];
54+
foreach ($keys as $index => $key) {
55+
$fieldData = $resultRow['row'][$index] ?? null;
56+
$data[$key] = $ogm->map($fieldData); // Map the field data to the appropriate object format
57+
}
58+
return new ResultRow($data); // Wrap the mapped data in a ResultRow object
59+
}, $values);
60+
61+
return $rows; // Return the processed rows as an array of ResultRow objects
62+
63+
64+
}
65+
66+
67+
68+
public function commit(): void
69+
{
70+
$this->client->post("/db/neo4j/query/v2/tx/{$this->transactionId}/commit", [
71+
'headers' => [
72+
'neo4j-cluster-affinity' => $this->clusterAffinity,
73+
]
74+
]);
75+
}
76+
77+
public function rollback(): void
78+
{
79+
$this->client->delete("/db/neo4j/query/v2/tx/{$this->transactionId}", [
80+
'headers' => [
81+
'neo4j-cluster-affinity' => $this->clusterAffinity,
82+
]
83+
]);
84+
}
85+
}

0 commit comments

Comments
 (0)