Skip to content
This repository was archived by the owner on Nov 15, 2022. It is now read-only.

Commit 4a1efb4

Browse files
authored
Merge pull request #111 from aldas/resultset_series
Resultset improvements for multiquery results
2 parents d918501 + 584dc01 commit 4a1efb4

File tree

5 files changed

+198
-30
lines changed

5 files changed

+198
-30
lines changed

src/InfluxDB/Driver/Guzzle.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,17 @@ public function query()
9494

9595
$raw = (string) $response->getBody();
9696

97-
return new ResultSet($raw);
97+
return $this->asResultSet($raw);
98+
}
9899

100+
/**
101+
* @param $raw
102+
* @return ResultSet
103+
* @throws \InfluxDB\Client\Exception
104+
*/
105+
protected function asResultSet($raw)
106+
{
107+
return new ResultSet($raw);
99108
}
100109

101110
/**

src/InfluxDB/ResultSet.php

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,20 @@ class ResultSet
3030
public function __construct($raw)
3131
{
3232
$this->rawResults = $raw;
33-
$this->parsedResults = json_decode((string) $raw, true);
33+
$this->parsedResults = json_decode((string)$raw, true);
3434

3535
if (json_last_error() !== JSON_ERROR_NONE) {
3636
throw new \InvalidArgumentException('Invalid JSON');
3737
}
3838

39+
$this->validate();
40+
}
41+
42+
/**
43+
* @throws ClientException
44+
*/
45+
protected function validate()
46+
{
3947
// There was an error in the query thrown by influxdb
4048
if (isset($this->parsedResults['error'])) {
4149
throw new ClientException($this->parsedResults['error']);
@@ -50,8 +58,9 @@ public function __construct($raw)
5058
/**
5159
* @return string
5260
*/
53-
public function getRaw() {
54-
return $this->rawResults;
61+
public function getRaw()
62+
{
63+
return $this->rawResults;
5564
}
5665

5766
/**
@@ -86,31 +95,60 @@ public function getPoints($metricName = '', array $tags = [])
8695
* results is an array of objects, one for each query,
8796
* each containing the keys for a series
8897
*
89-
* @throws Exception
98+
* @param int $queryIndex which Nth query result to return. Use null as value if you want all result of multi query results
9099
* @return array $series
100+
* @throws ClientException
91101
*/
92-
public function getSeries()
102+
public function getSeries($queryIndex = 0)
93103
{
94-
$series = array_map(
95-
function ($object) {
96-
if (isset($object['error'])) {
97-
throw new ClientException($object['error']);
98-
}
104+
$results = $this->parsedResults['results'];
105+
106+
if ($queryIndex !== null && !array_key_exists($queryIndex, $results)) {
107+
throw new \InvalidArgumentException('Invalid statement index provided');
108+
}
99109

100-
return isset($object['series']) ? $object['series'] : [];
101-
},
102-
$this->parsedResults['results']
103-
);
110+
$queryResults = [];
111+
foreach ($results as $index => $query) {
112+
/**
113+
* 'statement_id' was introduced in 1.2+ version so for backwards compatibility use array index for query index
114+
* See difference:
115+
* 1.2 -> https://docs.influxdata.com/influxdb/v1.2/guides/querying_data/
116+
* 1.1 -> https://docs.influxdata.com/influxdb/v1.1/guides/querying_data/
117+
*/
118+
$statementId = isset($query['statement_id']) ? $query['statement_id'] : $index;
119+
120+
if ($queryIndex === $statementId) {
121+
return $this->extractQuery($query);
122+
}
123+
124+
if ($queryIndex === null) {
125+
$queryResults[$statementId] = $this->extractQuery($query);
126+
}
127+
}
104128

105-
return array_shift($series);
129+
return $queryResults;
130+
}
131+
132+
private function extractQuery($statementSeries)
133+
{
134+
if (isset($statementSeries['error'])) {
135+
throw new ClientException($statementSeries['error']);
136+
}
137+
138+
return isset($statementSeries['series']) ? $statementSeries['series'] : [];
106139
}
107140

108141
/**
142+
* @param int $queryIndex which Nth query result to return. Defaults to first query.
109143
* @return mixed
144+
* @throws ClientException
110145
*/
111-
public function getColumns()
146+
public function getColumns($queryIndex = 0)
112147
{
113-
return $this->getSeries()[0]['columns'];
148+
if ($queryIndex === null) {
149+
$queryIndex = 0;
150+
}
151+
return $this->getSeries($queryIndex)[0]['columns'];
114152
}
115153

116154
/**

tests/unit/ResultSetTest.php

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
<?php
2+
23
namespace InfluxDB\Test\unit;
34

45
use InfluxDB\ResultSet;
56
use PHPUnit\Framework\TestCase;
67

78
class ResultSetTest extends TestCase
89
{
9-
/** @var ResultSet $resultSet*/
10+
/** @var ResultSet $resultSet */
1011
protected $resultSet;
1112

13+
/** @var ResultSet $resultSet */
14+
protected $multiQueryResultSet;
15+
1216
public function setUp()
1317
{
1418
$resultJsonExample = file_get_contents(__DIR__ . '/json/result.example.json');
1519
$this->resultSet = new ResultSet($resultJsonExample);
20+
$this->multiQueryResultSet = new ResultSet(file_get_contents(__DIR__ . '/json/result-multi-query.example.json'));
1621
}
1722

1823
/**
@@ -47,18 +52,15 @@ public function testThrowsInfluxDBException()
4752
*/
4853
public function testThrowsInfluxDBExceptionIfAnyErrorInSeries()
4954
{
55+
new ResultSet(file_get_contents(__DIR__ . '/json/result-error.example.json'));
56+
}
5057

51-
$errorResult = <<<EOD
52-
{
53-
"results": [
54-
{
55-
"series": [],
56-
"error": "There was an error after querying"
57-
}
58-
]
59-
}
60-
EOD;
61-
new ResultSet($errorResult);
58+
public function testGetRaw()
59+
{
60+
$resultJsonExample = file_get_contents(__DIR__ . '/json/result.example.json');
61+
$resultSet = new ResultSet($resultJsonExample);
62+
63+
$this->assertEquals($resultJsonExample, $resultSet->getRaw());
6264
}
6365

6466
/**
@@ -101,6 +103,13 @@ public function testGetSeries()
101103
$this->assertEquals(['time', 'value'], $this->resultSet->getColumns());
102104
}
103105

106+
public function testGetSeriesFromMultiQuery()
107+
{
108+
$this->assertEquals(['time', 'value'], $this->multiQueryResultSet->getColumns(0));
109+
$this->assertEquals(['time', 'value'], $this->multiQueryResultSet->getColumns(null));
110+
$this->assertEquals(['time', 'count'], $this->multiQueryResultSet->getColumns(1));
111+
}
112+
104113
/**
105114
* We can get points from measurement
106115
*/
@@ -144,4 +153,60 @@ public function testGetPointsFromNameAndTags()
144153
$this->assertTrue(is_array($points));
145154
$this->assertCount($expectedNumberOfPoints, $points);
146155
}
156+
157+
public function testGetDefaultResultFromMultiStatementQuery()
158+
{
159+
$series = $this->multiQueryResultSet->getSeries();
160+
161+
$this->assertTrue(is_array($series));
162+
$this->assertCount(1, $series);
163+
$this->assertEquals('cpu_load_short', $series[0]['name']);
164+
}
165+
166+
public function testGetNthResultFromMultiStatementQuery()
167+
{
168+
$series = $this->multiQueryResultSet->getSeries(1);
169+
170+
$this->assertTrue(is_array($series));
171+
$this->assertCount(1, $series);
172+
$this->assertEquals('cpu_load_long', $series[0]['name']);
173+
}
174+
175+
public function testGetAllResultsFromMultiStatementQuery()
176+
{
177+
$series = $this->multiQueryResultSet->getSeries(null);
178+
179+
$this->assertTrue(is_array($series));
180+
$this->assertCount(2, $series);
181+
$this->assertEquals('cpu_load_short', $series[0][0]['name']);
182+
$this->assertEquals('cpu_load_long', $series[1][0]['name']);
183+
}
184+
185+
/**
186+
* Throws Exception if invalid query index is given
187+
*
188+
* @expectedException \InvalidArgumentException
189+
* @expectedExceptionMessage Invalid statement index provided
190+
*/
191+
public function testGetInvalidResultFromMultiStatementQuery()
192+
{
193+
$this->multiQueryResultSet->getSeries(2);
194+
}
195+
196+
/**
197+
* Throws Exception if Nth query resulted an error
198+
*
199+
* @expectedException \InfluxDB\Client\Exception
200+
* @expectedExceptionMessage should trigger error
201+
*/
202+
public function testGetErrorFromMultiStatementQuery()
203+
{
204+
$raw = json_decode(file_get_contents(__DIR__ . '/json/result-multi-query.example.json'), true);
205+
unset($raw['results'][1]['series']);
206+
$raw['results'][1]['error'] = 'should trigger error';
207+
208+
$resultSet = new ResultSet(json_encode($raw));
209+
210+
$resultSet->getSeries(1);
211+
}
147212
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"results": [
3+
{
4+
"statement_id": 0,
5+
"error": "not executed"
6+
}
7+
]
8+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"results": [
3+
{
4+
"statement_id": 0,
5+
"series": [
6+
{
7+
"name": "cpu_load_short",
8+
"columns": [
9+
"time",
10+
"value"
11+
],
12+
"values": [
13+
[
14+
"2015-01-29T21:55:43.702900257Z",
15+
2
16+
],
17+
[
18+
"2015-01-29T21:55:43.702900257Z",
19+
0.55
20+
],
21+
[
22+
"2015-06-11T20:46:02Z",
23+
0.64
24+
]
25+
]
26+
}
27+
]
28+
},
29+
{
30+
"statement_id": 1,
31+
"series": [
32+
{
33+
"name": "cpu_load_long",
34+
"columns": [
35+
"time",
36+
"count"
37+
],
38+
"values": [
39+
[
40+
"1970-01-01T00:00:00Z",
41+
3
42+
]
43+
]
44+
}
45+
]
46+
}
47+
]
48+
}

0 commit comments

Comments
 (0)