Skip to content

Commit 7fd6c42

Browse files
feat: respect iox::column_type::field metadata when mapping query (#200)
1 parent 86adf7e commit 7fd6c42

File tree

11 files changed

+836
-96
lines changed

11 files changed

+836
-96
lines changed

CHANGELOG.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
## 0.10.0 [unreleased]
1+
## 1.0.0 [unreleased]
2+
3+
### Features
4+
5+
1. [#200](https://github.com/InfluxCommunity/influxdb3-java/pull/200): Respect iox::column_type::field metadata when
6+
mapping query results into values.
7+
- iox::column_type::field::integer: => Long
8+
- iox::column_type::field::uinteger: => Long
9+
- iox::column_type::field::float: => Double
10+
- iox::column_type::field::string: => String
11+
- iox::column_type::field::boolean: => Boolean
212

313
### Dependencies
414

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<groupId>com.influxdb</groupId>
3030
<artifactId>influxdb3-java</artifactId>
3131
<packaging>jar</packaging>
32-
<version>0.10.0-SNAPSHOT</version>
32+
<version>1.0.0-SNAPSHOT</version>
3333

3434
<name>InfluxDB 3 Java Client</name>
3535
<description>

src/main/java/com/influxdb/v3/client/internal/InfluxDBClientImpl.java

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import java.io.ByteArrayOutputStream;
2525
import java.io.IOException;
2626
import java.nio.charset.StandardCharsets;
27-
import java.util.ArrayList;
2827
import java.util.Collections;
2928
import java.util.HashMap;
3029
import java.util.List;
@@ -181,19 +180,13 @@ public Stream<Object[]> query(@Nonnull final String query,
181180
@Nonnull final Map<String, Object> parameters,
182181
@Nonnull final QueryOptions options) {
183182
return queryData(query, parameters, options)
184-
.flatMap(vector -> {
185-
List<FieldVector> fieldVectors = vector.getFieldVectors();
186-
return IntStream
187-
.range(0, vector.getRowCount())
188-
.mapToObj(rowNumber -> {
189-
190-
ArrayList<Object> row = new ArrayList<>();
191-
for (FieldVector fieldVector : fieldVectors) {
192-
row.add(fieldVector.getObject(rowNumber));
193-
}
194-
return row.toArray();
195-
});
196-
});
183+
.flatMap(vector -> IntStream.range(0, vector.getRowCount())
184+
.mapToObj(rowNumber ->
185+
VectorSchemaRootConverter.INSTANCE
186+
.getArrayObjectFromVectorSchemaRoot(
187+
vector,
188+
rowNumber
189+
)));
197190
}
198191

199192
@Nonnull
@@ -225,7 +218,7 @@ public Stream<PointValues> queryPoints(@Nonnull final String query,
225218
return IntStream
226219
.range(0, vector.getRowCount())
227220
.mapToObj(row ->
228-
VectorSchemaRootConverter.INSTANCE.toPointValues(row, vector, fieldVectors));
221+
VectorSchemaRootConverter.INSTANCE.toPointValues(row, fieldVectors));
229222
});
230223
}
231224

src/main/java/com/influxdb/v3/client/internal/NanosecondConverter.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,18 @@
2424
import java.math.BigDecimal;
2525
import java.math.BigInteger;
2626
import java.time.Instant;
27+
import java.time.LocalDateTime;
28+
import java.time.ZoneOffset;
2729
import java.util.HashMap;
2830
import java.util.Map;
31+
import java.util.concurrent.TimeUnit;
2932
import java.util.function.Function;
33+
import javax.annotation.Nonnull;
3034
import javax.annotation.Nullable;
3135

36+
import org.apache.arrow.vector.types.pojo.ArrowType;
37+
import org.apache.arrow.vector.types.pojo.Field;
38+
3239
import com.influxdb.v3.client.write.WritePrecision;
3340

3441
import static java.util.function.Function.identity;
@@ -111,4 +118,55 @@ public static BigInteger convert(final Instant instant, final WritePrecision pre
111118

112119
return FROM_NANOS.get(precision).apply(nanos);
113120
}
121+
122+
/**
123+
* Convert Long or LocalDateTime to timestamp nanosecond.
124+
*
125+
* @param value the time in Long or LocalDateTime
126+
* @param field the arrow field metadata
127+
* @return the time in nanosecond
128+
*/
129+
@Nullable
130+
public static BigInteger getTimestampNano(@Nonnull final Object value, @Nonnull final Field field) {
131+
BigInteger result = null;
132+
133+
if (value instanceof Long) {
134+
if (field.getFieldType().getType() instanceof ArrowType.Timestamp) {
135+
ArrowType.Timestamp type = (ArrowType.Timestamp) field.getFieldType().getType();
136+
TimeUnit timeUnit;
137+
switch (type.getUnit()) {
138+
case SECOND:
139+
timeUnit = TimeUnit.SECONDS;
140+
break;
141+
case MILLISECOND:
142+
timeUnit = TimeUnit.MILLISECONDS;
143+
break;
144+
case MICROSECOND:
145+
timeUnit = TimeUnit.MICROSECONDS;
146+
break;
147+
case NANOSECOND:
148+
default:
149+
timeUnit = TimeUnit.NANOSECONDS;
150+
break;
151+
}
152+
long nanoseconds = TimeUnit.NANOSECONDS.convert((Long) value, timeUnit);
153+
Instant instant = Instant.ofEpochSecond(0, nanoseconds);
154+
result = convertInstantToNano(instant);
155+
} else {
156+
Instant instant = Instant.ofEpochMilli((Long) value);
157+
result = convertInstantToNano(instant);
158+
}
159+
} else if (value instanceof LocalDateTime) {
160+
Instant instant = ((LocalDateTime) value).toInstant(ZoneOffset.UTC);
161+
result = convertInstantToNano(instant);
162+
}
163+
return result;
164+
}
165+
166+
@Nullable
167+
private static BigInteger convertInstantToNano(@Nonnull final Instant instant) {
168+
var writePrecision = WritePrecision.NS;
169+
BigInteger convertedTime = NanosecondConverter.convert(instant, writePrecision);
170+
return NanosecondConverter.convertToNanos(convertedTime, writePrecision);
171+
}
114172
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+
* THE SOFTWARE.
21+
*/
22+
package com.influxdb.v3.client.internal;
23+
24+
import javax.annotation.Nonnull;
25+
26+
import org.apache.arrow.vector.util.Text;
27+
28+
/**
29+
* Functions for safe type casting.
30+
*/
31+
public final class TypeCasting {
32+
33+
private TypeCasting() { }
34+
35+
/**
36+
* Safe casting to long value.
37+
*
38+
* @param value object to cast
39+
* @return long value
40+
*/
41+
public static long toLongValue(@Nonnull final Object value) {
42+
43+
if (long.class.isAssignableFrom(value.getClass())
44+
|| Long.class.isAssignableFrom(value.getClass())) {
45+
return (long) value;
46+
}
47+
48+
return ((Number) value).longValue();
49+
}
50+
51+
/**
52+
* Safe casting to double value.
53+
*
54+
* @param value object to cast
55+
* @return double value
56+
*/
57+
public static double toDoubleValue(@Nonnull final Object value) {
58+
59+
if (double.class.isAssignableFrom(value.getClass())
60+
|| Double.class.isAssignableFrom(value.getClass())) {
61+
return (double) value;
62+
}
63+
64+
return ((Number) value).doubleValue();
65+
}
66+
67+
/**
68+
* Safe casting to string value.
69+
*
70+
* @param value object to cast
71+
* @return string value
72+
*/
73+
public static String toStringValue(@Nonnull final Object value) {
74+
75+
if (Text.class.isAssignableFrom(value.getClass())) {
76+
return value.toString();
77+
}
78+
79+
return (String) value;
80+
}
81+
}

0 commit comments

Comments
 (0)