@@ -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