Skip to content

Commit c4bb8ab

Browse files
feat: add getMappedValue function
1 parent 0fdf8e0 commit c4bb8ab

File tree

9 files changed

+243
-222
lines changed

9 files changed

+243
-222
lines changed

src/main/java/com/influxdb/v3/client/PointValues.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -435,17 +435,6 @@ public PointValues setField(@Nonnull final String field, @Nullable final Object
435435
return putField(field, value);
436436
}
437437

438-
/**
439-
* Add a null field.
440-
*
441-
* @param field the field name
442-
* @return this
443-
*/
444-
@Nonnull
445-
public PointValues setNullField(@Nonnull final String field) {
446-
return putField(field, null);
447-
}
448-
449438
/**
450439
* Adds or replaces fields for this point.
451440
*

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ public Stream<PointValues> queryPoints(@Nonnull final String query,
218218
return IntStream
219219
.range(0, vector.getRowCount())
220220
.mapToObj(row ->
221-
VectorSchemaRootConverter.INSTANCE.toPointValues(row, vector, fieldVectors));
221+
VectorSchemaRootConverter.INSTANCE.toPointValues(row, fieldVectors));
222222
});
223223
}
224224

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,23 +150,20 @@ public static BigInteger getTimestampNano(@Nonnull final Object value, @Nonnull
150150
}
151151
long nanoseconds = TimeUnit.NANOSECONDS.convert((Long) value, timeUnit);
152152
Instant instant = Instant.ofEpochSecond(0, nanoseconds);
153-
result = convertInstantToNano(instant, WritePrecision.NS);
153+
result = convertInstantToNano(instant);
154154
} else {
155155
Instant instant = Instant.ofEpochMilli((Long) value);
156-
result = convertInstantToNano(instant, WritePrecision.NS);
156+
result = convertInstantToNano(instant);
157157
}
158158
} else if (value instanceof LocalDateTime) {
159159
Instant instant = ((LocalDateTime) value).toInstant(ZoneOffset.UTC);
160-
result = convertInstantToNano(instant, WritePrecision.NS);
160+
result = convertInstantToNano(instant);
161161
}
162162
return result;
163163
}
164164

165-
private static BigInteger convertInstantToNano(final Instant instant, final WritePrecision precision) {
165+
private static BigInteger convertInstantToNano(final Instant instant) {
166166
var writePrecision = WritePrecision.NS;
167-
if (precision != null) {
168-
writePrecision = precision;
169-
}
170167
BigInteger convertedTime = NanosecondConverter.convert(instant, writePrecision);
171168
return NanosecondConverter.convertToNanos(convertedTime, writePrecision);
172169
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public static double toDoubleValue(@Nonnull final Object value) {
7373
public static String toStringValue(@Nonnull final Object value) {
7474

7575
if (Text.class.isAssignableFrom(value.getClass())) {
76-
return ((Text) value).toString();
76+
return value.toString();
7777
}
7878

7979
return (String) value;

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

Lines changed: 63 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
import org.apache.arrow.vector.FieldVector;
3434
import org.apache.arrow.vector.VectorSchemaRoot;
35+
import org.apache.arrow.vector.types.pojo.Field;
3536
import org.apache.arrow.vector.util.Text;
3637

3738
import com.influxdb.v3.client.PointValues;
@@ -55,39 +56,37 @@ public final class VectorSchemaRootConverter {
5556
* Converts a given row of data from a VectorSchemaRoot object to PointValues.
5657
*
5758
* @param rowNumber the index of the row to be converted
58-
* @param vector the VectorSchemaRoot object containing the data
5959
* @param fieldVectors the list of FieldVector objects representing the data columns
6060
* @return the converted PointValues object
6161
*/
6262
@Nonnull
6363
PointValues toPointValues(final int rowNumber,
64-
@Nonnull final VectorSchemaRoot vector,
6564
@Nonnull final List<FieldVector> fieldVectors) {
6665
PointValues p = new PointValues();
6766
for (FieldVector fieldVector : fieldVectors) {
6867
var field = fieldVector.getField();
6968
var value = fieldVector.getObject(rowNumber);
70-
var name = field.getName();
69+
var fieldName = field.getName();
7170
var metaType = field.getMetadata().get("iox::column::type");
7271

7372
if (value instanceof Text) {
7473
value = value.toString();
7574
}
7675

77-
if ((Objects.equals(name, "measurement")
78-
|| Objects.equals(name, "iox::measurement"))
76+
if ((Objects.equals(fieldName, "measurement")
77+
|| Objects.equals(fieldName, "iox::measurement"))
7978
&& value instanceof String) {
8079
p.setMeasurement((String) value);
8180
continue;
8281
}
8382

8483
if (metaType == null) {
85-
if (Objects.equals(name, "time") && (value instanceof Long || value instanceof LocalDateTime)) {
84+
if (Objects.equals(fieldName, "time") && (value instanceof Long || value instanceof LocalDateTime)) {
8685
var timeNano = NanosecondConverter.getTimestampNano(value, field);
8786
p.setTimestamp(timeNano, WritePrecision.NS);
8887
} else {
8988
// just push as field If you don't know what type is it
90-
p.setField(name, value);
89+
p.setField(fieldName, value);
9190
}
9291

9392
continue;
@@ -97,71 +96,68 @@ PointValues toPointValues(final int rowNumber,
9796
String valueType = parts[2];
9897

9998
if ("field".equals(valueType)) {
100-
setFieldWithMetaType(p, name, value, metaType);
99+
var fieldValue = getMappedValue(valueType, metaType, value, fieldName, field);
100+
p.setField(fieldName, fieldValue);
101101
} else if ("tag".equals(valueType) && value instanceof String) {
102-
p.setTag(name, (String) value);
102+
var tag = (String) getMappedValue(valueType, metaType, value, fieldName, field);
103+
p.setTag(fieldName, tag);
103104
} else if ("timestamp".equals(valueType)) {
104-
var timeNano = NanosecondConverter.getTimestampNano(value, field);
105+
var timeNano = (BigInteger) getMappedValue(valueType, metaType, value, fieldName, field);
105106
p.setTimestamp(timeNano, WritePrecision.NS);
106107
}
107108
}
108109
return p;
109110
}
110111

111-
/**
112-
* Set field value for PointValues base on iox::column::type.
113-
*
114-
* @param p The target PointValues.
115-
* @param fieldName Field name in PointValues
116-
* @param value The value to be set
117-
* @param metaType The iox::column::type column meta type,
118-
* eg: iox::column_type::field::integer, iox::column_type::field::float
119-
*/
120-
public void setFieldWithMetaType(final PointValues p,
121-
final String fieldName,
122-
final Object value,
123-
final String metaType) {
112+
public Object getMappedValue(final String valueType,
113+
final String metaType,
114+
final Object value,
115+
final String fieldName,
116+
final Field field) {
124117
if (value == null) {
125-
return;
118+
return null;
126119
}
127120

128-
switch (metaType) {
129-
case "iox::column_type::field::integer":
130-
case "iox::column_type::field::uinteger":
131-
if (value instanceof Long) {
132-
p.setIntegerField(fieldName, TypeCasting.toLongValue(value));
133-
} else {
134-
p.setNullField(fieldName);
135-
LOG.warning(String.format("Value of %s is not an Integer", fieldName));
136-
}
137-
break;
138-
case "iox::column_type::field::float":
139-
if (value instanceof Double) {
140-
p.setFloatField(fieldName, TypeCasting.toDoubleValue(value));
141-
} else {
142-
p.setNullField(fieldName);
143-
LOG.warning(String.format("Value of %s is not a Double", fieldName));
144-
}
145-
break;
146-
case "iox::column_type::field::string":
147-
if (value instanceof String || value instanceof Text) {
148-
p.setStringField(fieldName, TypeCasting.toStringValue(value));
149-
} else {
150-
p.setNullField(fieldName);
151-
LOG.warning(String.format("Value of %s is not a String", fieldName));
152-
}
153-
break;
154-
case "iox::column_type::field::boolean":
155-
if (value instanceof Boolean) {
156-
p.setBooleanField(fieldName, (Boolean) value);
157-
} else {
158-
p.setNullField(fieldName);
159-
LOG.warning(String.format("Value of %s is not a Boolean", fieldName));
160-
}
161-
break;
162-
default:
163-
p.setField(fieldName, value);
164-
break;
121+
if ("field".equals(valueType)) {
122+
switch (metaType) {
123+
case "iox::column_type::field::integer":
124+
case "iox::column_type::field::uinteger":
125+
if (value instanceof Number) {
126+
return TypeCasting.toLongValue(value);
127+
} else {
128+
LOG.warning(String.format("Value of %s is not an Integer", fieldName));
129+
return value;
130+
}
131+
case "iox::column_type::field::float":
132+
if (value instanceof Number) {
133+
return TypeCasting.toDoubleValue(value);
134+
} else {
135+
LOG.warning(String.format("Value of %s is not a Double", fieldName));
136+
return value;
137+
}
138+
case "iox::column_type::field::string":
139+
if (value instanceof Text || value instanceof String) {
140+
return TypeCasting.toStringValue(value);
141+
} else {
142+
LOG.warning(String.format("Value of %s is not a String", fieldName));
143+
return value;
144+
}
145+
case "iox::column_type::field::boolean":
146+
if (value instanceof Boolean) {
147+
return (Boolean) value;
148+
} else {
149+
LOG.warning(String.format("Value of %s is not a Boolean", fieldName));
150+
return value;
151+
}
152+
default:
153+
return value;
154+
}
155+
} else if ("timestamp".equals(valueType) || Objects.equals(fieldName, "time")) {
156+
return NanosecondConverter.getTimestampNano(value, field);
157+
} else if ("tag".equals(valueType)) {
158+
return TypeCasting.toStringValue(value);
159+
} else {
160+
return value;
165161
}
166162
}
167163

@@ -178,58 +174,13 @@ public Object[] getArrayObjectFromVectorSchemaRoot(final VectorSchemaRoot vector
178174
var field = fieldVector.getField();
179175
var metaType = field.getMetadata().get("iox::column::type");
180176
String valueType = metaType != null ? metaType.split("::")[2] : null;
181-
String fieldName = field.getName();
182177

183-
Object value = fieldVector.getObject(rowNumber);
184-
if (value == null) {
185-
row.add(null);
186-
continue;
187-
}
188-
189-
if ("field".equals(valueType)) {
190-
switch (metaType) {
191-
case "iox::column_type::field::integer":
192-
case "iox::column_type::field::uinteger":
193-
if (value instanceof Long) {
194-
row.add(TypeCasting.toLongValue(value));
195-
} else {
196-
row.add(null);
197-
LOG.warning(String.format("Value of %s is not an Integer", fieldName));
198-
}
199-
break;
200-
case "iox::column_type::field::float":
201-
if (value instanceof Double) {
202-
row.add(TypeCasting.toDoubleValue(value));
203-
} else {
204-
row.add(null);
205-
LOG.warning(String.format("Value of %s is not a Double", fieldName));
206-
}
207-
break;
208-
case "iox::column_type::field::string":
209-
if (value instanceof Text || value instanceof String) {
210-
row.add(TypeCasting.toStringValue(value));
211-
} else {
212-
row.add(null);
213-
LOG.warning(String.format("Value of %s is not a String", fieldName));
214-
}
215-
break;
216-
case "iox::column_type::field::boolean":
217-
if (value instanceof Boolean) {
218-
row.add((Boolean) value);
219-
} else {
220-
row.add(null);
221-
LOG.warning(String.format("Value of %s is not a Boolean", fieldName));
222-
}
223-
break;
224-
default:
225-
}
226-
} else if ("timestamp".equals(valueType)
227-
|| Objects.equals(fieldName, "time")) {
228-
BigInteger time = NanosecondConverter.getTimestampNano(value, field);
229-
row.add(time);
230-
} else {
231-
row.add(value);
232-
}
178+
var value = getMappedValue(valueType,
179+
metaType,
180+
fieldVector.getObject(rowNumber),
181+
field.getName(),
182+
field);
183+
row.add(value);
233184
}
234185

235186
return row.toArray();

src/test/java/com/influxdb/v3/client/InfluxDBClientTest.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,10 @@
2828
import java.util.UUID;
2929
import java.util.stream.Stream;
3030

31-
import org.apache.arrow.vector.VectorSchemaRoot;
3231
import org.assertj.core.api.Assertions;
3332
import org.junit.jupiter.api.Test;
3433
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
3534

36-
import com.influxdb.v3.client.internal.VectorSchemaRootConverter;
37-
import com.influxdb.v3.client.internal.VectorSchemaRootUtils;
3835
import com.influxdb.v3.client.write.WriteOptions;
3936
import com.influxdb.v3.client.write.WritePrecision;
4037

@@ -176,18 +173,4 @@ public void testQuery() throws Exception {
176173
}
177174
}
178175
}
179-
180-
@Test
181-
public void testParseQueryWithInvalidMetaData() {
182-
try (VectorSchemaRoot vector = VectorSchemaRootUtils.generateInvalidVectorSchemaRoot()) {
183-
Object[] objects = VectorSchemaRootConverter.INSTANCE.getArrayObjectFromVectorSchemaRoot(vector, 0);
184-
185-
Assertions.assertThat(objects[0]).isNull();
186-
Assertions.assertThat(objects[1]).isNull();
187-
Assertions.assertThat(objects[2]).isNull();
188-
Assertions.assertThat(objects[3]).isNull();
189-
Assertions.assertThat(objects[4]).isNull();
190-
}
191-
}
192-
193176
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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 org.apache.arrow.vector.util.Text;
25+
import org.junit.jupiter.api.Assertions;
26+
import org.junit.jupiter.api.Test;
27+
28+
public class TypeCastingTest {
29+
30+
@Test
31+
void testToLongValue() {
32+
Assertions.assertEquals(1, TypeCasting.toLongValue(1));
33+
Assertions.assertEquals(1.0, TypeCasting.toLongValue(1.23));
34+
35+
Assertions.assertThrows(ClassCastException.class,
36+
() -> TypeCasting.toLongValue("1"));
37+
}
38+
39+
@Test
40+
void testToDoubleValue() {
41+
Assertions.assertEquals(1.23, TypeCasting.toDoubleValue(1.23));
42+
Assertions.assertEquals(1.0, TypeCasting.toDoubleValue(1));
43+
44+
Assertions.assertThrows(ClassCastException.class,
45+
() -> TypeCasting.toDoubleValue("1.2"));
46+
}
47+
48+
@Test
49+
void testToStringValue() {
50+
Assertions.assertEquals("test", TypeCasting.toStringValue("test"));
51+
Assertions.assertEquals("test",
52+
TypeCasting.toStringValue(new Text("test")));
53+
54+
Assertions.assertThrows(ClassCastException.class,
55+
() -> TypeCasting.toStringValue(1));
56+
}
57+
}

0 commit comments

Comments
 (0)