Skip to content

Commit 5e2da96

Browse files
committed
Updated login logic
1 parent e3e90c7 commit 5e2da96

File tree

6 files changed

+418
-45
lines changed

6 files changed

+418
-45
lines changed

src/AuthenticateInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Psr\Http\Message\RequestInterface;
66

7-
interface AuthenticateInterface
7+
interface AuthenticateInterface extends RequestInterface
88
{
99
/**
1010
* Authenticates the request by returning a new instance of the request with the authentication information attached.

src/BasicAuthentication.php

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
namespace Neo4j\QueryAPI;
44

5+
use Psr\Http\Message\MessageInterface;
56
use Psr\Http\Message\RequestInterface;
67
use Psr\Http\Message\ResponseInterface;
8+
use Psr\Http\Message\StreamInterface;
9+
use Psr\Http\Message\UriInterface;
710

811
class BasicAuthentication implements AuthenticateInterface
912
{
@@ -16,4 +19,89 @@ public function authenticate(RequestInterface $request): RequestInterface
1619
$authHeader = 'Basic ' . base64_encode($this->username . ':' . $this->password);
1720
return $request->withHeader('Authorization', $authHeader);
1821
}
22+
23+
public function getProtocolVersion(): string
24+
{
25+
// TODO: Implement getProtocolVersion() method.
26+
}
27+
28+
public function withProtocolVersion(string $version): MessageInterface
29+
{
30+
// TODO: Implement withProtocolVersion() method.
31+
}
32+
33+
public function getHeaders(): array
34+
{
35+
// TODO: Implement getHeaders() method.
36+
}
37+
38+
public function hasHeader(string $name): bool
39+
{
40+
// TODO: Implement hasHeader() method.
41+
}
42+
43+
public function getHeader(string $name): array
44+
{
45+
// TODO: Implement getHeader() method.
46+
}
47+
48+
public function getHeaderLine(string $name): string
49+
{
50+
// TODO: Implement getHeaderLine() method.
51+
}
52+
53+
public function withHeader(string $name, $value): MessageInterface
54+
{
55+
// TODO: Implement withHeader() method.
56+
}
57+
58+
public function withAddedHeader(string $name, $value): MessageInterface
59+
{
60+
// TODO: Implement withAddedHeader() method.
61+
}
62+
63+
public function withoutHeader(string $name): MessageInterface
64+
{
65+
// TODO: Implement withoutHeader() method.
66+
}
67+
68+
public function getBody(): StreamInterface
69+
{
70+
// TODO: Implement getBody() method.
71+
}
72+
73+
public function withBody(StreamInterface $body): MessageInterface
74+
{
75+
// TODO: Implement withBody() method.
76+
}
77+
78+
public function getRequestTarget(): string
79+
{
80+
// TODO: Implement getRequestTarget() method.
81+
}
82+
83+
public function withRequestTarget(string $requestTarget): RequestInterface
84+
{
85+
// TODO: Implement withRequestTarget() method.
86+
}
87+
88+
public function getMethod(): string
89+
{
90+
// TODO: Implement getMethod() method.
91+
}
92+
93+
public function withMethod(string $method): RequestInterface
94+
{
95+
// TODO: Implement withMethod() method.
96+
}
97+
98+
public function getUri(): UriInterface
99+
{
100+
// TODO: Implement getUri() method.
101+
}
102+
103+
public function withUri(UriInterface $uri, bool $preserveHost = false): RequestInterface
104+
{
105+
// TODO: Implement withUri() method.
106+
}
19107
}

src/Neo4jQueryAPI.php

Lines changed: 85 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public static function login(string $address, AuthenticateInterface $auth = null
4444
],
4545
]);
4646

47-
return new self($client, $auth ?? Authentication::fromEnvironment());
47+
return new self($client, $auth ?? Authentication::basic());
4848
}
4949

5050
/**
@@ -55,37 +55,59 @@ public static function login(string $address, AuthenticateInterface $auth = null
5555
*/
5656
public function run(string $cypher, array $parameters = [], string $database = 'neo4j', Bookmarks $bookmark = null): ResultSet
5757
{
58-
try {
59-
$payload = [
60-
'statement' => $cypher,
61-
'parameters' => empty($parameters) ? new stdClass() : $parameters,
62-
'includeCounters' => true,
63-
];
64-
65-
if ($bookmark !== null) {
66-
$payload['bookmarks'] = $bookmark->getBookmarks();
67-
}
68-
69-
70-
$request = new Request('POST', '/db/' . $database . '/query/v2');
71-
72-
$request = $this->auth->authenticate($request);
73-
74-
$request = $request->withHeader('Content-Type', 'application/json');
58+
$payload = [
59+
'statement' => $cypher,
60+
'parameters' => empty($parameters) ? new stdClass() : $parameters,
61+
'includeCounters' => true,
62+
];
63+
64+
if ($bookmark !== null) {
65+
$payload['bookmarks'] = $bookmark->getBookmarks();
66+
}
7567

76-
$request = $request->withBody(Utils::streamFor(json_encode($payload)));
68+
$request = new Request('POST', '/db/' . $database . '/query/v2');
69+
$request = $this->auth->authenticate($request);
70+
$request = $request->withHeader('Content-Type', 'application/json');
71+
$request = $request->withBody(Utils::streamFor(json_encode($payload)));
72+
73+
// Send the request to Neo4j
74+
$response = $this->client->sendRequest($request);
75+
76+
// Get the response content
77+
$contents = $response->getBody()->getContents();
78+
$data = json_decode($contents, true, flags: JSON_THROW_ON_ERROR);
79+
80+
// Check for Neo4j errors in the response
81+
if (isset($data['errors']) && count($data['errors']) > 0) {
82+
$error = $data['errors'][0];
83+
$errorCode = $error['code'] ?? '';
84+
$errorMessage = $error['message'] ?? '';
85+
86+
// Handle specific error types
87+
if ($errorCode === 'Neo.ClientError.Schema.EquivalentSchemaRuleAlreadyExists') {
88+
// Provide error details as an array, not a string
89+
$errorDetails = [
90+
'code' => $errorCode,
91+
'message' => $errorMessage,
92+
];
93+
throw new Neo4jException($errorDetails); // Pass error details as an array
94+
}
7795

78-
$response = $this->client->sendRequest($request);
96+
// You can handle other Neo4j-specific errors similarly
97+
if ($errorCode) {
98+
$errorDetails = [
99+
'code' => $errorCode,
100+
'message' => $errorMessage,
101+
];
102+
throw new Neo4jException($errorDetails); // Pass error details as an array
103+
}
104+
}
79105

106+
// If no error, return the result set
107+
return $this->parseResultSet($data);
108+
}
80109

81-
$contents = $response->getBody()->getContents();
82-
$data = json_decode($contents, true, flags: JSON_THROW_ON_ERROR);
83110

84-
return $this->parseResultSet($data);
85-
} catch (RequestExceptionInterface $e) {
86-
$this->handleException($e);
87-
}
88-
}
89111

90112
private function parseResultSet(array $data): ResultSet
91113
{
@@ -147,15 +169,46 @@ private function handleException(RequestExceptionInterface $e): void
147169

148170
public function beginTransaction(string $database = 'neo4j'): Transaction
149171
{
150-
$response = $this->client->sendRequest(new Request('POST', '/db/neo4j/query/v2/tx'));
172+
// Create the request to begin a transaction
173+
$request = new Request('POST', '/db/' . $database . '/query/v2/tx');
151174

152-
$clusterAffinity = $response->getHeaderLine('neo4j-cluster-affinity');
153-
$responseData = json_decode($response->getBody(), true);
154-
$transactionId = $responseData['transaction']['id'];
175+
// Authenticate the request by adding necessary headers (e.g., Authorization)
176+
$request = $this->auth->authenticate($request);
155177

156-
return new Transaction($this->client, $clusterAffinity, $transactionId);
178+
try {
179+
// Send the request
180+
$response = $this->client->sendRequest($request);
181+
182+
// Check for a successful response (status code 200 or 202)
183+
if ($response->getStatusCode() !== 200 && $response->getStatusCode() !== 202) {
184+
throw new \RuntimeException('Failed to begin transaction: ' . $response->getReasonPhrase());
185+
}
186+
187+
// Extract the necessary information from the response
188+
$clusterAffinity = $response->getHeaderLine('neo4j-cluster-affinity');
189+
$responseData = json_decode($response->getBody(), true);
190+
191+
// Ensure that the transaction ID exists and is not empty
192+
if (!isset($responseData['transaction']['id']) || empty($responseData['transaction']['id'])) {
193+
throw new \Exception('Transaction ID is missing or empty in the response.');
194+
}
195+
196+
// Get the transaction ID
197+
$transactionId = $responseData['transaction']['id'];
198+
199+
// Return the Transaction object with the necessary details
200+
return new Transaction($this->client, $clusterAffinity, $transactionId);
201+
202+
} catch (\Exception $e) {
203+
// Handle any exceptions (e.g., network, authentication issues, etc.)
204+
// Optionally log the error or rethrow a more specific exception
205+
throw new \RuntimeException('Error initiating transaction: ' . $e->getMessage(), 0, $e);
206+
}
157207
}
158208

209+
210+
211+
159212
private function createProfileData(array $data): ProfiledQueryPlan
160213
{
161214
$ogm = new OGM();

0 commit comments

Comments
 (0)