Skip to content

Commit d8b62a0

Browse files
committed
winp
1 parent 0aa93ed commit d8b62a0

9 files changed

+419
-126
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ test
1111

1212
#PHP-CS-FIXER
1313
.php-cs-fixer.php
14-
14+
.php-cs-fixer.cache

.php-cs-fixer.cache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"php":"8.3.6","version":"3.68.0:v3.68.0#73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"at_least_single_space"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_empty_anonymous_classes":true},"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_parentheses":true,"no_blank_lines_after_class_opening":true,"no_extra_blank_lines":{"tokens":["use"]},"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"none"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","const_import","do","else","elseif","final","finally","for","foreach","function","function_import","if","insteadof","interface","namespace","new","private","protected","public","static","switch","trait","try","use","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":{"only_dec_inc":true},"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"attribute_placement":"ignore","on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"strict_param":true},"hashes":{"tests\/Unit\/Neo4jExceptionUnitTest.php":"0d7842780eeb9729d501831ee55df0d8","tests\/Unit\/ResultRowTest.php":"f5ee9f21d2439793a290e8ab946a7f32","tests\/Integration\/Neo4jOGMTest.php":"73136b2d28fbb4fa298467d1ab3e18c8","src\/OGM.php":"93aae9c7afc8dbfd5aa00bc1d264ad19","src\/Results\/ResultRow.php":"ad55ec1bd999a8f6ad6b18874c4017b5","src\/Results\/ResultSet.php":"5f7748a356bf0fb30403e3c5a411bd24","src\/Exception\/Neo4jException.php":"dfb0f6933b9d3913c5495ba6d801d5f1","src\/Objects\/Path.php":"88c95962a6316ba7aa2fa3f0f6e31627","src\/Objects\/Node.php":"4a8ab7b8bd1981ee4d35d8c52b81c7c3","src\/Objects\/ProfiledQueryPlanArguments.php":"1be7b230a034a72c13349a5670a34a2f","src\/Objects\/Person.php":"f2f469937660f5454761e4f31154e081","src\/Objects\/Point.php":"169715b2157e08482e420374e6ca4cc3","src\/Objects\/Bookmarks.php":"50f89ca88b2df817433ce8237ccc0f18","src\/Objects\/ResultCounters.php":"a9372c98fe7bede10cb004af30ea502f","src\/Objects\/Relationship.php":"f6347c0260780d4f5d2dc407dc97e25e","src\/Objects\/ProfiledQueryPlan.php":"d9ba608f3177426ea34d73276d75f20b","src\/Objects\/php your-script.php":"63c3a9abbf4774d1da8c5f3c9f8f455e","src\/Objects\/ResultSet.php":"f126eac07a2190797052d123971933be","tests\/resources\/expected\/complex-query-profile.php":"10f481c27e83c1478b5c0e3ad509ab26","src\/Transaction.php":"3e57e12e463749f8e3aabece091c91fc","tests\/Unit\/Neo4jQueryAPIUnitTest.php":"2d0183e377b28f6381e3a065592118c4","tests\/Unit\/Neo4jRequestFactoryTest.php":"8fdcf16ec45f05a923bf36ee94583df7","tests\/Unit\/AuthenticationTest.php":"58e41cacacf5f521fef5abc25ad4bc9f","tests\/Integration\/Neo4jQueryAPIIntegrationTest.php":"975c579bb20d1f5a2f2dfbef7af2af61","src\/Neo4jQueryAPI.php":"c145914ee1458602691bab00d1822e77","src\/BearerAuthentication.php":"0c6a9ba4adc3b762a586f8d1d58e62dc","src\/NoAuth.php":"80e445bfbd33cc7b60036db9461e0706","src\/AuthenticateInterface.php":"36290631a54b09926af0d78af8fc7282","src\/BasicAuthentication.php":"efaae7442bf25f033548765fd06b70dd","src\/Neo4jRequestFactory.php":"2c1b08e8547ff90fee8826ad02e7c65c","src\/Objects\/Authentication.php":"de564835b80cf54171f42c3f5fccda28","src\/requestFactory.php":"23cff999060edda7bd1f19b7122d4b49"}}
1+
{"php":"8.3.6","version":"3.68.0:v3.68.0#73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"at_least_single_space"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_empty_anonymous_classes":true},"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_parentheses":true,"no_blank_lines_after_class_opening":true,"no_extra_blank_lines":{"tokens":["use"]},"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"none"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","const_import","do","else","elseif","final","finally","for","foreach","function","function_import","if","insteadof","interface","namespace","new","private","protected","public","static","switch","trait","try","use","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":{"only_dec_inc":true},"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"attribute_placement":"ignore","on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"strict_param":true},"hashes":{"tests\/Unit\/Neo4jExceptionUnitTest.php":"0d7842780eeb9729d501831ee55df0d8","tests\/Unit\/ResultRowTest.php":"f5ee9f21d2439793a290e8ab946a7f32","tests\/Integration\/Neo4jOGMTest.php":"73136b2d28fbb4fa298467d1ab3e18c8","src\/OGM.php":"93aae9c7afc8dbfd5aa00bc1d264ad19","src\/Results\/ResultRow.php":"ad55ec1bd999a8f6ad6b18874c4017b5","src\/Results\/ResultSet.php":"5f7748a356bf0fb30403e3c5a411bd24","src\/Exception\/Neo4jException.php":"dfb0f6933b9d3913c5495ba6d801d5f1","src\/Objects\/Path.php":"88c95962a6316ba7aa2fa3f0f6e31627","src\/Objects\/Node.php":"4a8ab7b8bd1981ee4d35d8c52b81c7c3","src\/Objects\/ProfiledQueryPlanArguments.php":"1be7b230a034a72c13349a5670a34a2f","src\/Objects\/Person.php":"f2f469937660f5454761e4f31154e081","src\/Objects\/Point.php":"169715b2157e08482e420374e6ca4cc3","src\/Objects\/Bookmarks.php":"50f89ca88b2df817433ce8237ccc0f18","src\/Objects\/ResultCounters.php":"a9372c98fe7bede10cb004af30ea502f","src\/Objects\/Relationship.php":"f6347c0260780d4f5d2dc407dc97e25e","src\/Objects\/ProfiledQueryPlan.php":"d9ba608f3177426ea34d73276d75f20b","src\/Objects\/php your-script.php":"63c3a9abbf4774d1da8c5f3c9f8f455e","src\/Objects\/ResultSet.php":"f126eac07a2190797052d123971933be","tests\/resources\/expected\/complex-query-profile.php":"10f481c27e83c1478b5c0e3ad509ab26","src\/Transaction.php":"3e57e12e463749f8e3aabece091c91fc","tests\/Unit\/Neo4jQueryAPIUnitTest.php":"2d0183e377b28f6381e3a065592118c4","tests\/Unit\/AuthenticationTest.php":"58e41cacacf5f521fef5abc25ad4bc9f","src\/BearerAuthentication.php":"0c6a9ba4adc3b762a586f8d1d58e62dc","src\/NoAuth.php":"80e445bfbd33cc7b60036db9461e0706","src\/AuthenticateInterface.php":"36290631a54b09926af0d78af8fc7282","src\/BasicAuthentication.php":"efaae7442bf25f033548765fd06b70dd","src\/Objects\/Authentication.php":"de564835b80cf54171f42c3f5fccda28","src\/Neo4jPhp.php":"79006f2c26015a1a1335559a5f8fc73d","src\/transaction_Script.php":"411ce81fd25cd49a8ec18ec817e56b50","tests\/Unit\/Neo4jRequestFactoryTest.php":"29f3446c8a8e7d202d7f403a5e261019","tests\/Integration\/Neo4jQueryAPIIntegrationTest.php":"5fb6a97821b94444748ad41ce67f4cac","src\/Neo4jQueryAPI.php":"a07a7ae10a29f8ce8b4c997e9359cdfd","src\/Neo4jRequestFactory.php":"5349daa39d67fff3de4c750cbaaa8d66","src\/requestFactory.php":"6a11cd1e82952867c137949dadf99126"}}

src/Neo4jPhp.php

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
require __DIR__.'/../vendor/autoload.php'; // Assuming you have Composer installed and dependencies loaded
4+
5+
use Neo4j\QueryAPI\Neo4jQueryAPI;
6+
use Neo4j\QueryAPI\Objects\Authentication;
7+
use Neo4j\QueryAPI\Objects\Bookmarks;
8+
use GuzzleHttp\Client;
9+
use GuzzleHttp\Exception\RequestException;
10+
use stdClass;
11+
12+
try {
13+
// Step 1: Initialize the connection to Neo4j with login credentials (authentication)
14+
$neo4jAddress = 'https://6f72daa1.databases.neo4j.io'; // Replace with your Neo4j database address
15+
$username = 'neo4j';
16+
$password = '9lWmptqBgxBOz8NVcTJjgs3cHPyYmsy63ui6Spmw1d0';
17+
18+
// Base64 encode the username and password for Basic Authentication
19+
$credentials = base64_encode("$username:$password");
20+
21+
// Set up the authentication header with base64-encoded credentials
22+
$headers = [
23+
'Authorization' => 'Basic ' . $credentials,
24+
'Content-Type' => 'application/json',
25+
];
26+
27+
// Initialize the client with the authorization header
28+
$client = new \GuzzleHttp\Client([
29+
'base_uri' => rtrim($neo4jAddress, '/'),
30+
'timeout' => 10.0,
31+
'headers' => $headers,
32+
]);
33+
34+
// Step 2: Create the Cypher query
35+
$cypherQuery = 'MATCH (n) RETURN n LIMIT 10';
36+
$parameters = []; // No parameters in this query
37+
$database = 'neo4j'; // Default Neo4j database
38+
39+
echo "Running Cypher Query: $cypherQuery\n";
40+
41+
// Prepare the payload for the Cypher query
42+
$payload = [
43+
'statement' => $cypherQuery,
44+
'parameters' => new stdClass(), // No parameters
45+
'includeCounters' => true,
46+
];
47+
48+
// Step 3: Send the request to Neo4j
49+
$response = $client->post("/db/{$database}/query/v2", [
50+
'json' => $payload,
51+
]);
52+
53+
// Parse the response body as JSON
54+
$responseData = json_decode($response->getBody()->getContents(), true);
55+
56+
// Check for errors in the response
57+
if (isset($responseData['errors']) && count($responseData['errors']) > 0) {
58+
echo "Error: " . $responseData['errors'][0]['message'] . "\n";
59+
} else {
60+
// Step 4: Output the result of the query
61+
echo "Query Results:\n";
62+
foreach ($responseData['data'] as $row) {
63+
print_r($row); // Print each row's data
64+
}
65+
}
66+
67+
// Step 5: Begin a new transaction
68+
$transactionResponse = $client->post("/db/neo4j/query/v2/tx");
69+
$transactionData = json_decode($transactionResponse->getBody()->getContents(), true);
70+
$transactionId = $transactionData['transaction']['id']; // Retrieve the transaction ID
71+
72+
echo "Transaction started successfully.\n";
73+
echo "Transaction ID: $transactionId\n";
74+
75+
// You can also fetch additional transaction details if available in the response
76+
// Example: transaction metadata or counters
77+
if (isset($transactionData['transaction']['metadata'])) {
78+
echo "Transaction Metadata: \n";
79+
print_r($transactionData['transaction']['metadata']);
80+
}
81+
82+
// Step 6: Execute a query within the transaction
83+
$cypherTransactionQuery = 'MATCH (n) SET n.modified = true RETURN n LIMIT 5';
84+
$transactionPayload = [
85+
'statement' => $cypherTransactionQuery,
86+
'parameters' => new stdClass(), // No parameters
87+
];
88+
89+
// Execute the transaction query
90+
$transactionQueryResponse = $client->post("/db/neo4j/query/v2/tx/{$transactionId}/commit", [
91+
'json' => $transactionPayload,
92+
]);
93+
94+
$transactionQueryData = json_decode($transactionQueryResponse->getBody()->getContents(), true);
95+
96+
// Check for any errors in the transaction query
97+
if (isset($transactionQueryData['errors']) && count($transactionQueryData['errors']) > 0) {
98+
echo "Transaction Error: " . $transactionQueryData['errors'][0]['message'] . "\n";
99+
} else {
100+
echo "Transaction Query Results:\n";
101+
print_r($transactionQueryData['data']); // Print transaction results
102+
}
103+
104+
} catch (RequestException $e) {
105+
echo "Request Error: " . $e->getMessage() . "\n";
106+
} catch (Exception $e) {
107+
echo "Error: " . $e->getMessage() . "\n";
108+
}

src/Neo4jQueryAPI.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
use Neo4j\QueryAPI\Results\ResultRow;
1616
use Psr\Http\Client\ClientInterface;
1717
use Psr\Http\Client\RequestExceptionInterface;
18-
use Psr\Http\Message\RequestInterface;
1918
use RuntimeException;
2019
use stdClass;
2120

src/Neo4jRequestFactory.php

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,36 @@
22

33
namespace Neo4j\QueryAPI;
44

5+
use Psr\Http\Message\RequestFactoryInterface;
6+
use Psr\Http\Message\StreamFactoryInterface;
7+
use Psr\Http\Message\RequestInterface;
8+
59
class Neo4jRequestFactory
610
{
711
private string $baseUri;
812
private ?string $authHeader = null;
9-
10-
public function __construct(string $baseUri, ?string $authHeader = null)
11-
{
13+
private RequestFactoryInterface $psr17Factory;
14+
private StreamFactoryInterface $streamFactory;
15+
16+
public function __construct(
17+
RequestFactoryInterface $psr17Factory,
18+
StreamFactoryInterface $streamFactory,
19+
string $baseUri,
20+
?string $authHeader = null
21+
) {
22+
$this->psr17Factory = $psr17Factory;
23+
$this->streamFactory = $streamFactory;
1224
$this->baseUri = $baseUri;
1325
$this->authHeader = $authHeader;
1426
}
1527

16-
/**
17-
* Builds a request for running a Cypher query.
18-
*/
1928
public function buildRunQueryRequest(
2029
string $database,
2130
string $cypher,
22-
array $parameters = [],
23-
bool $includeCounters = true,
31+
array $parameters = [],
32+
bool $includeCounters = true,
2433
?array $bookmarks = null
25-
): array {
34+
): RequestInterface {
2635
$payload = [
2736
'statement' => $cypher,
2837
'parameters' => empty($parameters) ? new \stdClass() : $parameters,
@@ -38,41 +47,28 @@ public function buildRunQueryRequest(
3847
return $this->createRequest('POST', $uri, json_encode($payload));
3948
}
4049

41-
/**
42-
* Builds a request for starting a new transaction.
43-
*/
44-
public function buildBeginTransactionRequest(string $database): array
50+
public function buildBeginTransactionRequest(string $database): RequestInterface
4551
{
4652
$uri = rtrim($this->baseUri, '/') . "/db/{$database}/query/v2/tx";
47-
4853
return $this->createRequest('POST', $uri);
4954
}
5055

51-
/**
52-
* Builds a request for committing a transaction.
53-
*/
54-
public function buildCommitRequest(string $database, string $transactionId): array
56+
public function buildCommitRequest(string $database, string $transactionId): RequestInterface
5557
{
5658
$uri = rtrim($this->baseUri, '/') . "/db/{$database}/query/v2/tx/{$transactionId}/commit";
57-
5859
return $this->createRequest('POST', $uri);
5960
}
6061

61-
/**
62-
* Builds a request for rolling back a transaction.
63-
*/
64-
public function buildRollbackRequest(string $database, string $transactionId): array
62+
public function buildRollbackRequest(string $database, string $transactionId): RequestInterface
6563
{
6664
$uri = rtrim($this->baseUri, '/') . "/db/{$database}/query/v2/tx/{$transactionId}/rollback";
67-
6865
return $this->createRequest('POST', $uri);
6966
}
7067

71-
/**
72-
* Helper method to create a request manually.
73-
*/
74-
private function createRequest(string $method, string $uri, ?string $body = null): array
68+
private function createRequest(string $method, string $uri, ?string $body = null): RequestInterface
7569
{
70+
$request = $this->psr17Factory->createRequest($method, $uri);
71+
7672
$headers = [
7773
'Content-Type' => 'application/json',
7874
'Accept' => 'application/json',
@@ -82,11 +78,15 @@ private function createRequest(string $method, string $uri, ?string $body = null
8278
$headers['Authorization'] = $this->authHeader;
8379
}
8480

85-
return [
86-
'method' => $method,
87-
'uri' => $uri,
88-
'headers' => $headers,
89-
'body' => $body,
90-
];
81+
foreach ($headers as $name => $value) {
82+
$request = $request->withHeader($name, $value);
83+
}
84+
85+
if ($body !== null) {
86+
$stream = $this->streamFactory->createStream($body);
87+
$request = $request->withBody($stream);
88+
}
89+
90+
return $request;
9191
}
9292
}

0 commit comments

Comments
 (0)