Skip to content

Commit a48e981

Browse files
authored
Merge pull request #345 from fmachado/added-support-map-queryresult-groupby
Added support map queryresult groupby
2 parents 8f601cc + eff316f commit a48e981

File tree

2 files changed

+106
-7
lines changed

2 files changed

+106
-7
lines changed

src/main/java/org/influxdb/impl/InfluxDBResultMapper.java

+18-6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.LinkedList;
2929
import java.util.List;
3030
import java.util.Objects;
31+
import java.util.Map.Entry;
3132
import java.util.concurrent.ConcurrentHashMap;
3233
import java.util.concurrent.ConcurrentMap;
3334
import java.util.concurrent.TimeUnit;
@@ -147,19 +148,32 @@ String getMeasurementName(final Class<?> clazz) {
147148

148149
<T> List<T> parseSeriesAs(final QueryResult.Series series, final Class<T> clazz, final List<T> result) {
149150
int columnSize = series.getColumns().size();
151+
ConcurrentMap<String, Field> colNameAndFieldMap = CLASS_FIELD_CACHE.get(clazz.getName());
150152
try {
151153
T object = null;
152154
for (List<Object> row : series.getValues()) {
153155
for (int i = 0; i < columnSize; i++) {
154-
String resultColumnName = series.getColumns().get(i);
155-
Field correspondingField = CLASS_FIELD_CACHE.get(clazz.getName()).get(resultColumnName);
156+
Field correspondingField = colNameAndFieldMap.get(series.getColumns().get(i)/*InfluxDB columnName*/);
156157
if (correspondingField != null) {
157158
if (object == null) {
158159
object = clazz.newInstance();
159160
}
160161
setFieldValue(object, correspondingField, row.get(i));
161162
}
162163
}
164+
// When the "GROUP BY" clause is used, "tags" are returned as Map<String,String> and
165+
// accordingly with InfluxDB documentation
166+
// https://docs.influxdata.com/influxdb/v1.2/concepts/glossary/#tag-value
167+
// "tag" values are always String.
168+
if (series.getTags() != null && !series.getTags().isEmpty()) {
169+
for (Entry<String, String> entry : series.getTags().entrySet()) {
170+
Field correspondingField = colNameAndFieldMap.get(entry.getKey()/*InfluxDB columnName*/);
171+
if (correspondingField != null) {
172+
// I don't think it is possible to reach here without a valid "object"
173+
setFieldValue(object, correspondingField, entry.getValue());
174+
}
175+
}
176+
}
163177
if (object != null) {
164178
result.add(object);
165179
object = null;
@@ -233,8 +247,7 @@ <T> boolean fieldValueModified(final Class<?> fieldType, final Field field, fina
233247
}
234248

235249
<T> boolean fieldValueForPrimitivesModified(final Class<?> fieldType, final Field field, final T object,
236-
final Object value)
237-
throws IllegalArgumentException, IllegalAccessException {
250+
final Object value) throws IllegalArgumentException, IllegalAccessException {
238251
if (double.class.isAssignableFrom(fieldType)) {
239252
field.setDouble(object, ((Double) value).doubleValue());
240253
return true;
@@ -255,8 +268,7 @@ <T> boolean fieldValueForPrimitivesModified(final Class<?> fieldType, final Fiel
255268
}
256269

257270
<T> boolean fieldValueForPrimitiveWrappersModified(final Class<?> fieldType, final Field field, final T object,
258-
final Object value)
259-
throws IllegalArgumentException, IllegalAccessException {
271+
final Object value) throws IllegalArgumentException, IllegalAccessException {
260272
if (Double.class.isAssignableFrom(fieldType)) {
261273
field.set(object, value);
262274
return true;

src/test/java/org/influxdb/impl/InfluxDBResultMapperTest.java

+88-1
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
import java.time.Instant;
2727
import java.util.Arrays;
2828
import java.util.Date;
29+
import java.util.HashMap;
2930
import java.util.LinkedList;
3031
import java.util.List;
32+
import java.util.Map;
3133
import java.util.Random;
3234
import java.util.UUID;
3335

@@ -243,7 +245,61 @@ public void testToPOJO_SeriesFromQueryResultIsNull() {
243245
// Then...
244246
assertTrue("there must NO entry in the result list", myList.isEmpty());
245247
}
246-
248+
249+
@Test
250+
public void testToPOJO_QueryResultCreatedByGroupByClause() {
251+
// Given...
252+
mapper.cacheMeasurementClass(GroupByCarrierDeviceOS.class);
253+
254+
List<String> columnList = Arrays.asList("time", "median", "min", "max");
255+
256+
// InfluxDB client returns the time representation as Double.
257+
Double now = Long.valueOf(System.currentTimeMillis()).doubleValue();
258+
259+
List<Object> firstSeriesResult = Arrays.asList(now, new Double("233.8"), new Double("0.0"),
260+
new Double("3090744.0"));
261+
// When the "GROUP BY" clause is used, "tags" are returned as Map<String,String>
262+
Map<String, String> firstSeriesTagMap = new HashMap<>();
263+
firstSeriesTagMap.put("CARRIER", "000/00");
264+
firstSeriesTagMap.put("DEVICE_OS_VERSION", "4.4.2");
265+
266+
List<Object> secondSeriesResult = Arrays.asList(now, new Double("552.0"), new Double("135.0"),
267+
new Double("267705.0"));
268+
Map<String, String> secondSeriesTagMap = new HashMap<>();
269+
secondSeriesTagMap.put("CARRIER", "000/01");
270+
secondSeriesTagMap.put("DEVICE_OS_VERSION", "9.3.5");
271+
272+
QueryResult.Series firstSeries = new QueryResult.Series();
273+
firstSeries.setColumns(columnList);
274+
firstSeries.setValues(Arrays.asList(firstSeriesResult));
275+
firstSeries.setTags(firstSeriesTagMap);
276+
firstSeries.setName("tb_network");
277+
278+
QueryResult.Series secondSeries = new QueryResult.Series();
279+
secondSeries.setColumns(columnList);
280+
secondSeries.setValues(Arrays.asList(secondSeriesResult));
281+
secondSeries.setTags(secondSeriesTagMap);
282+
secondSeries.setName("tb_network");
283+
284+
QueryResult.Result internalResult = new QueryResult.Result();
285+
internalResult.setSeries(Arrays.asList(firstSeries, secondSeries));
286+
287+
QueryResult queryResult = new QueryResult();
288+
queryResult.setResults(Arrays.asList(internalResult));
289+
290+
// When...
291+
List<GroupByCarrierDeviceOS> myList = mapper.toPOJO(queryResult, GroupByCarrierDeviceOS.class);
292+
293+
// Then...
294+
GroupByCarrierDeviceOS firstGroupByEntry = myList.get(0);
295+
assertEquals("field 'carrier' does not match", "000/00", firstGroupByEntry.carrier);
296+
assertEquals("field 'deviceOsVersion' does not match", "4.4.2", firstGroupByEntry.deviceOsVersion);
297+
298+
GroupByCarrierDeviceOS secondGroupByEntry = myList.get(1);
299+
assertEquals("field 'carrier' does not match", "000/01", secondGroupByEntry.carrier);
300+
assertEquals("field 'deviceOsVersion' does not match", "9.3.5", secondGroupByEntry.deviceOsVersion);
301+
}
302+
247303
@Measurement(name = "CustomMeasurement")
248304
static class MyCustomMeasurement {
249305

@@ -297,4 +353,35 @@ static class MyPojoWithUnsupportedField {
297353
@Column(name = "bar")
298354
private Date myDate;
299355
}
356+
357+
/**
358+
* Class created based on example from https://github.com/influxdata/influxdb-java/issues/343
359+
*/
360+
@Measurement(name = "tb_network")
361+
static class GroupByCarrierDeviceOS {
362+
363+
@Column(name = "time")
364+
private Instant time;
365+
366+
@Column(name = "CARRIER", tag = true)
367+
private String carrier;
368+
369+
@Column(name = "DEVICE_OS_VERSION", tag = true)
370+
private String deviceOsVersion;
371+
372+
@Column(name = "median")
373+
private Double median;
374+
375+
@Column(name = "min")
376+
private Double min;
377+
378+
@Column(name = "max")
379+
private Double max;
380+
381+
@Override
382+
public String toString() {
383+
return "GroupByCarrierDeviceOS [time=" + time + ", carrier=" + carrier + ", deviceOsVersion=" + deviceOsVersion
384+
+ ", median=" + median + ", min=" + min + ", max=" + max + "]";
385+
}
386+
}
300387
}

0 commit comments

Comments
 (0)