diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f6b78fd..78c085f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## 3.1.0 [unreleased] +### Features +1. [#131](https://github.com/influxdata/influxdb-client-php/pull/131): Added `FluxRecord.row` which stores response data in a array + + ## 3.0.0 [2022-09-30] :warning: This release drops strong couple to [Guzzle HTTP client](https://github.com/guzzle/guzzle). diff --git a/examples/README.md b/examples/README.md index 9c567789..2b910d51 100644 --- a/examples/README.md +++ b/examples/README.md @@ -19,4 +19,6 @@ ## Others - [InfluxDB_18_Example.php](InfluxDB_18_Example.php) - How to use forward compatibility APIs from InfluxDB 1.8 - [DeleteDataExample.php](DeleteDataExample.php) - How to delete data from InfluxDB by client -- [InvokableScripts.php](InvokableScripts.php) - How to use Invokable scripts Cloud API to create custom endpoints that query data \ No newline at end of file +- [InvokableScripts.php](InvokableScripts.php) - How to use Invokable scripts Cloud API to create custom endpoints that query data +- [RecordRowExample.php](RecordRowExample.php) - How to use `FluxRecord.row` instead of `FluxRecord.values`, + in case of duplicity column names \ No newline at end of file diff --git a/examples/RecordRowExample.php b/examples/RecordRowExample.php new file mode 100644 index 00000000..916deee4 --- /dev/null +++ b/examples/RecordRowExample.php @@ -0,0 +1,66 @@ + "http://localhost:8086", + "token" => $token, + "bucket" => $bucket, + "org" => $org, + "precision" => InfluxDB2\Model\WritePrecision::S +]); + +// +// Write test data into InfluxDB +// +$writeApi = $client->createWriteApi(); + +foreach (range(1, 5) as $i) { + $writeApi->write("point,table=my-table result=$i", InfluxDB2\Model\WritePrecision::MS, $bucket, $org); +} + +$writeApi->close(); + +// +// Query data with pivot +// +$queryApi = $client->createQueryApi(); + +$result = $queryApi->query( + "from(bucket: \"$bucket\") |> range(start: -1m) |> filter(fn: (r) => (r[\"_measurement\"] == \"point\")) +|> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")" +); + +// +// Write data to output +// +printf("\n--------------------------------------- FluxRecord.values ----------------------------------------\n"); +foreach ($result as $table) { + foreach ($table->records as $record) { + $values = implode(", ", $record->values); + print "$values\n"; + } +} + +printf("\n----------------------------------------- FluxRecord.row -----------------------------------------\n"); +foreach ($result as $table) { + foreach ($table->records as $record) { + $row = implode(", ", $record->row); + print "$row\n"; + } +} + +$client->close(); diff --git a/src/InfluxDB2/FluxCsvParser.php b/src/InfluxDB2/FluxCsvParser.php index cda72fb8..cafc085e 100644 --- a/src/InfluxDB2/FluxCsvParser.php +++ b/src/InfluxDB2/FluxCsvParser.php @@ -147,7 +147,9 @@ private function parseRecord(int $tableIndex, FluxTable $table, array $csv) foreach ($table->columns as $fluxColumn) { $columnName = $fluxColumn->label; $strVal = $csv[$fluxColumn->index + 1]; - $record->values[$columnName] = $this->toValue($strVal, $fluxColumn); + $value = $this->toValue($strVal, $fluxColumn); + $record->values[$columnName] = $value; + $record->row[] = $value; } return $record; } @@ -183,10 +185,24 @@ private function addDefaultEmptyValues(FluxTable $table, $defaultValues) private function addColumnNamesAndTags(FluxTable $table, array $csv) { $i = 1; - foreach ($table->columns as &$column) { + + foreach ($table->columns as $column) { $column->label = $csv[$i]; $i++; } + + $duplicates = array(); + foreach (array_count_values($csv) as $label => $count) { + if ($count > 1) { + $duplicates[] = $label; + } + } + + if (count($duplicates) > 0) { + $duplicatesStr = implode(", ", $duplicates); + print "The response contains columns with duplicated names: {$duplicatesStr}\n"; + print "You should use the 'FluxRecord.row' to access your data instead of 'FluxRecord.values'."; + } } diff --git a/src/InfluxDB2/FluxRecord.php b/src/InfluxDB2/FluxRecord.php index 483f7437..b5be323c 100644 --- a/src/InfluxDB2/FluxRecord.php +++ b/src/InfluxDB2/FluxRecord.php @@ -15,16 +15,18 @@ class FluxRecord implements ArrayAccess { public $table; public $values; + public $row; /** * FluxRecord constructor. * @param $table int table index * @param $values array array with record values, key is the column name */ - public function __construct($table, $values=null) + public function __construct($table, $values = null, $row = null) { $this->table = $table; $this->values = $values; + $this->row = $row; } /** @@ -70,7 +72,7 @@ public function getField() /** * @return mixed record value for column named '_measurement' */ - public function getMeasurement():string + public function getMeasurement(): string { return $this->getRecordValue('_measurement'); } diff --git a/tests/FluxCsvParserTest.php b/tests/FluxCsvParserTest.php index 1c4a5a23..338ffb4e 100644 --- a/tests/FluxCsvParserTest.php +++ b/tests/FluxCsvParserTest.php @@ -442,6 +442,28 @@ public function testParseInfinity() $this->assertEquals(-INF, $tables[0]->records[11]->values['le']); } + public function testParseDuplicateColumnNames() + { + $data = "#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,string,string,double +#group,false,false,true,true,false,true,true,false +#default,_result,,,,,,, + ,result,table,_start,_stop,_time,_measurement,location,result +,,0,2022-09-13T06:14:40.469404272Z,2022-09-13T06:24:40.469404272Z,2022-09-13T06:24:33.746Z,my_measurement,Prague,25.3 +,,0,2022-09-13T06:14:40.469404272Z,2022-09-13T06:24:40.469404272Z,2022-09-13T06:24:39.299Z,my_measurement,Prague,25.3 +,,0,2022-09-13T06:14:40.469404272Z,2022-09-13T06:24:40.469404272Z,2022-09-13T06:24:40.454Z,my_measurement,Prague,25.3 +"; + + $parser = new FluxCsvParser($data); + $tables = $parser->parse()->tables; + + $this->assertEquals(1, sizeof($tables)); + $this->assertEquals(3, sizeof($tables[0]->records)); + $this->assertEquals(8, sizeof($tables[0]->columns)); + $this->assertEquals(7, sizeof($tables[0]->records[0]->values)); + $this->assertEquals(8, sizeof($tables[0]->records[0]->row)); + $this->assertEquals(25.3, $tables[0]->records[0]->row[7]); + } + private function assertColumns(array $columnHeaders, array $values) { $i = 0;