@@ -44,7 +44,7 @@ public static function login(string $address, AuthenticateInterface $auth = null
44
44
],
45
45
]);
46
46
47
- return new self ($ client , $ auth ?? Authentication::fromEnvironment ());
47
+ return new self ($ client , $ auth ?? Authentication::basic ());
48
48
}
49
49
50
50
/**
@@ -55,37 +55,59 @@ public static function login(string $address, AuthenticateInterface $auth = null
55
55
*/
56
56
public function run (string $ cypher , array $ parameters = [], string $ database = 'neo4j ' , Bookmarks $ bookmark = null ): ResultSet
57
57
{
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
+ }
75
67
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
+ }
77
95
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
+ }
79
105
106
+ // If no error, return the result set
107
+ return $ this ->parseResultSet ($ data );
108
+ }
80
109
81
- $ contents = $ response ->getBody ()->getContents ();
82
- $ data = json_decode ($ contents , true , flags: JSON_THROW_ON_ERROR );
83
110
84
- return $ this ->parseResultSet ($ data );
85
- } catch (RequestExceptionInterface $ e ) {
86
- $ this ->handleException ($ e );
87
- }
88
- }
89
111
90
112
private function parseResultSet (array $ data ): ResultSet
91
113
{
@@ -147,15 +169,46 @@ private function handleException(RequestExceptionInterface $e): void
147
169
148
170
public function beginTransaction (string $ database = 'neo4j ' ): Transaction
149
171
{
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 ' );
151
174
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 );
155
177
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
+ }
157
207
}
158
208
209
+
210
+
211
+
159
212
private function createProfileData (array $ data ): ProfiledQueryPlan
160
213
{
161
214
$ ogm = new OGM ();
0 commit comments