6
6
use GuzzleHttp \Client ;
7
7
use GuzzleHttp \Exception \GuzzleException ;
8
8
use GuzzleHttp \Exception \RequestException ;
9
+ use Neo4j \QueryAPI \Objects \ChildQueryPlan ;
10
+ use Neo4j \QueryAPI \Objects \QueryArguments ;
9
11
use Neo4j \QueryAPI \Objects \ResultCounters ;
12
+ use Neo4j \QueryAPI \Objects \ProfiledQueryPlan ;
10
13
use Neo4j \QueryAPI \Results \ResultRow ;
11
14
use Neo4j \QueryAPI \Results \ResultSet ;
12
15
use Neo4j \QueryAPI \Exception \Neo4jException ;
@@ -37,7 +40,7 @@ public static function login(string $address, string $username, string $password
37
40
'headers ' => [
38
41
'Authorization ' => 'Basic ' . base64_encode ("$ username: $ password " ),
39
42
'Content-Type ' => 'application/vnd.neo4j.query ' ,
40
- 'Accept ' => 'application/vnd.neo4j.query ' ,
43
+ 'Accept ' => 'application/vnd.neo4j.query ' ,
41
44
],
42
45
]);
43
46
@@ -80,6 +83,10 @@ public function run(string $cypher, array $parameters = [], string $database = '
80
83
return new ResultRow ($ data );
81
84
}, $ values );
82
85
86
+ if (isset ($ data ['profiledQueryPlan ' ])) {
87
+ $ profile = $ this ->createProfileData ($ data ['profiledQueryPlan ' ]);
88
+ }
89
+
83
90
$ resultCounters = new ResultCounters (
84
91
containsUpdates: $ data ['counters ' ]['containsUpdates ' ] ?? false ,
85
92
nodesCreated: $ data ['counters ' ]['nodesCreated ' ] ?? 0 ,
@@ -97,22 +104,79 @@ public function run(string $cypher, array $parameters = [], string $database = '
97
104
systemUpdates: $ data ['counters ' ]['systemUpdates ' ] ?? 0
98
105
);
99
106
100
- $ resultSet = new ResultSet ($ rows , $ resultCounters , new Bookmarks ( $ data [ ' bookmarks ' ] ?? []));
101
-
102
-
103
- return $ resultSet ;
104
-
105
- } catch ( RequestException $ e ) {
106
- {
107
- $ response = $ e ->getResponse ();
108
- if ($ response !== null ) {
109
- $ contents = $ response ->getBody ()->getContents ();
110
- $ errorResponse = json_decode ($ contents , true );
107
+ return new ResultSet (
108
+ $ rows ,
109
+ $ resultCounters ,
110
+ new Bookmarks ( $ data [ ' bookmarks ' ] ?? []),
111
+ $ profile
112
+ );
113
+ } catch ( RequestExceptionInterface $ e ) {
114
+ $ response = $ e ->getResponse ();
115
+ if ($ response !== null ) {
116
+ $ contents = $ response ->getBody ()->getContents ();
117
+ $ errorResponse = json_decode ($ contents , true );
111
118
112
119
throw Neo4jException::fromNeo4jResponse ($ errorResponse , $ e );
113
120
}
114
121
}
115
122
throw new RuntimeException ('Error executing query: ' . $ e ->getMessage (), 0 , $ e );
116
123
}
124
+
125
+
126
+ public function beginTransaction (string $ database = 'neo4j ' ): Transaction
127
+ {
128
+ $ response = $ this ->client ->post ("/db/neo4j/query/v2/tx " );
129
+
130
+ $ clusterAffinity = $ response ->getHeaderLine ('neo4j-cluster-affinity ' );
131
+ $ responseData = json_decode ($ response ->getBody (), true );
132
+ $ transactionId = $ responseData ['transaction ' ]['id ' ];
133
+
134
+ return new Transaction ($ this ->client , $ clusterAffinity , $ transactionId );
135
+ }
136
+
137
+ private function createProfileData (array $ data ): ProfiledQueryPlan
138
+ {
139
+ $ arguments = $ data ['arguments ' ];
140
+
141
+ $ queryArguments = new QueryArguments (
142
+ $ arguments ['globalMemory ' ] ?? 0 ,
143
+ $ arguments ['plannerImpl ' ] ?? '' ,
144
+ $ arguments ['memory ' ] ?? 0 ,
145
+ $ arguments ['stringRepresentation ' ] ?? '' ,
146
+ is_string ($ arguments ['runtime ' ] ?? '' ) ? $ arguments ['runtime ' ] : json_encode ($ arguments ['runtime ' ]),
147
+ $ arguments ['runtimeImpl ' ] ?? '' ,
148
+ $ arguments ['dbHits ' ] ?? 0 ,
149
+ $ arguments ['batchSize ' ] ?? 0 ,
150
+ $ arguments ['details ' ] ?? '' ,
151
+ $ arguments ['plannerVersion ' ] ?? '' ,
152
+ $ arguments ['pipelineInfo ' ] ?? '' ,
153
+ $ arguments ['runtimeVersion ' ] ?? '' ,
154
+ $ arguments ['id ' ] ?? 0 ,
155
+ $ arguments ['estimatedRows ' ] ?? 0.0 ,
156
+ is_string ($ arguments ['planner ' ] ?? '' ) ? $ arguments ['planner ' ] : json_encode ($ arguments ['planner ' ]),
157
+ $ arguments ['rows ' ] ?? 0
158
+ );
159
+
160
+ $ profiledQueryPlan = new ProfiledQueryPlan (
161
+ $ data ['dbHits ' ],
162
+ $ data ['records ' ],
163
+ $ data ['hasPageCacheStats ' ],
164
+ $ data ['pageCacheHits ' ],
165
+ $ data ['pageCacheMisses ' ],
166
+ $ data ['pageCacheHitRatio ' ],
167
+ $ data ['time ' ],
168
+ $ data ['operatorType ' ],
169
+ $ queryArguments
170
+ );
171
+
172
+ foreach ($ data ['children ' ] as $ child ) {
173
+ $ childQueryPlan = $ this ->createProfileData ($ child );
174
+
175
+ $ profiledQueryPlan ->addChild ($ childQueryPlan );
176
+ }
177
+
178
+ return $ profiledQueryPlan ;
117
179
}
180
+
181
+
118
182
}
0 commit comments