Skip to content

Commit d39b171

Browse files
committed
Version with mappers
1 parent 4f8c028 commit d39b171

24 files changed

Lines changed: 538 additions & 167 deletions

src/main/java/io/tarantool/driver/core/MultiValueCallResultImpl.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.tarantool.driver.api.MultiValueCallResult;
44
import io.tarantool.driver.exceptions.TarantoolFunctionCallException;
55
import io.tarantool.driver.exceptions.errors.TarantoolErrorsParser;
6+
import io.tarantool.driver.mappers.MessagePackValueMapper;
67
import io.tarantool.driver.mappers.converters.ValueConverter;
78
import org.msgpack.value.ArrayValue;
89
import org.msgpack.value.Value;
@@ -14,12 +15,13 @@
1415
* {@code null}, the second is treated as a formatted error or an error message.
1516
*
1617
* @author Alexey Kuzin
18+
* @author Artyom Dubinin
1719
*/
1820
public class MultiValueCallResultImpl<T, R extends List<T>> implements MultiValueCallResult<T, R> {
1921

2022
private final R value;
2123

22-
public MultiValueCallResultImpl(Value result, ValueConverter<Value, R> valueConverter) {
24+
public MultiValueCallResultImpl(Value result, ValueConverter<ArrayValue, R> valueConverter) {
2325
if (result == null) {
2426
throw new TarantoolFunctionCallException("Function call result is null");
2527
}
@@ -36,6 +38,23 @@ public MultiValueCallResultImpl(Value result, ValueConverter<Value, R> valueConv
3638
}
3739
}
3840

41+
public MultiValueCallResultImpl(Value result, MessagePackValueMapper valueMapper) {
42+
if (result == null) {
43+
throw new TarantoolFunctionCallException("Function call result is null");
44+
}
45+
if (!result.isArrayValue()) {
46+
throw new TarantoolFunctionCallException("Function call result is not a MessagePack array");
47+
}
48+
ArrayValue resultArray = result.asArrayValue();
49+
if (resultArray.size() == 2 && (resultArray.get(0).isNilValue() && !resultArray.get(1).isNilValue())) {
50+
// [nil, "Error msg..."] or [nil, {str="Error msg...", stack="..."}]
51+
throw TarantoolErrorsParser.parse(resultArray.get(1));
52+
} else {
53+
// result
54+
this.value = valueMapper.fromValue(result.asArrayValue());
55+
}
56+
}
57+
3958
@Override
4059
public R value() {
4160
return value;

src/main/java/io/tarantool/driver/core/SingleValueCallResultImpl.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.tarantool.driver.api.SingleValueCallResult;
44
import io.tarantool.driver.exceptions.TarantoolFunctionCallException;
55
import io.tarantool.driver.exceptions.errors.TarantoolErrorsParser;
6+
import io.tarantool.driver.mappers.MessagePackValueMapper;
67
import io.tarantool.driver.mappers.converters.ValueConverter;
78
import org.msgpack.value.ArrayValue;
89
import org.msgpack.value.Value;
@@ -12,6 +13,7 @@
1213
* {@code null}, the second is treated as a formatted error or an error message.
1314
*
1415
* @author Alexey Kuzin
16+
* @author Artyom Dubinin
1517
*/
1618
public class SingleValueCallResultImpl<T> implements SingleValueCallResult<T> {
1719

@@ -33,6 +35,22 @@ public SingleValueCallResultImpl(ArrayValue result, ValueConverter<Value, T> val
3335
}
3436
}
3537

38+
public SingleValueCallResultImpl(ArrayValue result, MessagePackValueMapper valueMapper) {
39+
if (result == null) {
40+
throw new TarantoolFunctionCallException("Function call result is null");
41+
}
42+
if (result.size() == 0 || result.size() == 1 && result.get(0).isNilValue()) {
43+
// [nil] or []
44+
value = null;
45+
} else if (result.size() == 2 && (result.get(0).isNilValue() && !result.get(1).isNilValue())) {
46+
// [nil, "Error msg..."] or [nil, {str="Error msg...", stack="..."}]
47+
throw TarantoolErrorsParser.parse(result.get(1));
48+
} else {
49+
// [result]
50+
value = valueMapper.fromValue(result.get(0));
51+
}
52+
}
53+
3654
@Override
3755
public T value() {
3856
return value;

src/main/java/io/tarantool/driver/core/TarantoolResultImpl.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package io.tarantool.driver.core;
22

33
import io.tarantool.driver.api.TarantoolResult;
4-
import io.tarantool.driver.api.metadata.TarantoolFieldMetadata;
5-
import io.tarantool.driver.api.metadata.TarantoolSpaceMetadata;
6-
import io.tarantool.driver.core.metadata.TarantoolFieldMetadataImpl;
7-
import io.tarantool.driver.core.metadata.TarantoolSpaceMetadataImpl;
84
import io.tarantool.driver.exceptions.TarantoolClientException;
95
import io.tarantool.driver.exceptions.TarantoolTupleConversionException;
106
import io.tarantool.driver.mappers.converters.ValueConverter;
@@ -17,7 +13,6 @@
1713
import java.util.ArrayList;
1814
import java.util.Collection;
1915
import java.util.Iterator;
20-
import java.util.LinkedHashMap;
2116
import java.util.List;
2217
import java.util.ListIterator;
2318
import java.util.Map;
@@ -32,11 +27,8 @@
3227
*/
3328
public class TarantoolResultImpl<T> implements TarantoolResult<T> {
3429

35-
protected static final StringValue RESULT_META = ValueFactory.newString("metadata");
36-
protected static final StringValue RESULT_ROWS = ValueFactory.newString("rows");
37-
38-
protected static final StringValue FORMAT_NAME_KEY = ValueFactory.newString("name");
39-
protected static final StringValue FORMAT_TYPE_KEY = ValueFactory.newString("type");
30+
private static final StringValue RESULT_META = ValueFactory.newString("metadata");
31+
private static final StringValue RESULT_ROWS = ValueFactory.newString("rows");
4032

4133
protected List<T> tuples;
4234

@@ -80,7 +72,7 @@ protected void setTuples(ArrayValue tupleArray, ValueConverter<ArrayValue, T> tu
8072
.collect(Collectors.toList());
8173
}
8274

83-
static boolean hasRowsAndMetadata(Map<Value, Value> valueMap) {
75+
private static boolean hasRowsAndMetadata(Map<Value, Value> valueMap) {
8476
return valueMap.containsKey(RESULT_META) && valueMap.containsKey(RESULT_ROWS);
8577
}
8678

Lines changed: 17 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,41 @@
11
package io.tarantool.driver.core;
22

3-
import io.tarantool.driver.api.metadata.TarantoolFieldMetadata;
43
import io.tarantool.driver.api.metadata.TarantoolSpaceMetadata;
54
import io.tarantool.driver.api.tuple.TarantoolTuple;
6-
import io.tarantool.driver.core.metadata.TarantoolFieldMetadataImpl;
7-
import io.tarantool.driver.core.metadata.TarantoolSpaceMetadataImpl;
8-
import io.tarantool.driver.exceptions.TarantoolClientException;
95
import io.tarantool.driver.exceptions.TarantoolTupleConversionException;
106
import io.tarantool.driver.mappers.converters.value.custom.TarantoolTupleConverter;
117
import org.msgpack.core.MessageTypeCastException;
128
import org.msgpack.value.ArrayValue;
139
import org.msgpack.value.Value;
1410

15-
import java.util.ArrayList;
16-
import java.util.LinkedHashMap;
17-
import java.util.List;
18-
import java.util.Map;
1911
import java.util.stream.Collectors;
2012

2113
/**
22-
* Basic TarantoolResult implementation. Supports two types of the tuple result: a MessagePack array of arrays
23-
* (as in IPROTO) and a map with format {@code {"rows": [[], ...], "metadata": []}} as returned by tarantool/crud module
14+
* Specific TarantoolResult implementation especially for TarantoolTuple input
2415
*
25-
* @author Alexey Kuzin
16+
* @author Artyom Dubinin
2617
*/
2718
public class TarantoolTupleResultImpl extends TarantoolResultImpl<TarantoolTuple> {
2819

29-
public TarantoolTupleResultImpl(Value value, TarantoolTupleConverter tupleConverter) {
30-
if (value.isArrayValue()) {
31-
// [[[],...]]
32-
setTuples(value.asArrayValue(), tupleConverter);
33-
} else if (value.isMapValue()) {
34-
// [{"metadata" : [...], "rows": [...]}]
35-
Map<Value, Value> tupleMap = value.asMapValue().map();
36-
if (!hasRowsAndMetadata(tupleMap)) {
37-
throw new TarantoolClientException("The received tuple map has wrong format, " +
38-
"expected {\"metadata\" : [...], \"rows\": [...]}, got %s", value.toString());
39-
}
40-
Value tupleArray = tupleMap.get(RESULT_ROWS);
41-
if (!tupleArray.isArrayValue()) {
42-
throw new TarantoolClientException("The \"rows\" field must contain a MessagePack array");
43-
}
44-
TarantoolSpaceMetadata responseMetadata = parseCRUDMetadata(tupleMap.get(RESULT_META));
45-
setTuples(tupleArray.asArrayValue(), tupleConverter, responseMetadata);
46-
} else if (value.isNilValue()) {
47-
// [nil]
48-
this.tuples = new ArrayList<>();
49-
} else {
50-
throw new TarantoolClientException("The received result cannot be converted to an array of tuples: %s",
51-
value.toString());
52-
}
20+
public TarantoolTupleResultImpl(ArrayValue rawTuples, TarantoolSpaceMetadata metadata,
21+
TarantoolTupleConverter tupleConverter) {
22+
setTuples(rawTuples, metadata, tupleConverter);
5323
}
5424

55-
private TarantoolSpaceMetadata parseCRUDMetadata(Value metadata) {
56-
if (metadata == null || !metadata.isArrayValue()) {
57-
throw new TarantoolClientException("Unsupported crud metadata format: expected array of maps");
58-
}
59-
60-
List<Value> responseFormat = metadata.asArrayValue().list();
61-
62-
Map<String, TarantoolFieldMetadata> spaceFormatMetadata = new LinkedHashMap<>();
63-
int fieldPosition = 0;
64-
for (Value value : responseFormat) {
65-
if (!value.isMapValue()) {
66-
throw new TarantoolClientException("Unsupported crud metadata format: expected array of maps");
67-
}
68-
Map<Value, Value> fieldMap = value.asMapValue().map();
69-
70-
Value fieldNameValue = fieldMap.get(FORMAT_NAME_KEY);
71-
if (fieldNameValue == null || !fieldNameValue.isStringValue()) {
72-
throw new TarantoolClientException(
73-
"Unsupported space metadata format: key '" + FORMAT_NAME_KEY + "' must have string value," +
74-
" get " + fieldNameValue);
75-
}
76-
String fieldName = fieldNameValue.asStringValue().asString();
77-
78-
Value fieldTypeValue = fieldMap.get(FORMAT_TYPE_KEY);
79-
if (fieldTypeValue == null || !fieldTypeValue.isStringValue()) {
80-
throw new TarantoolClientException(
81-
"Unsupported space metadata format: key '" + FORMAT_TYPE_KEY + "' must have string value," +
82-
" get " + fieldNameValue);
83-
}
84-
String fieldType = fieldTypeValue.asStringValue().asString();
85-
86-
spaceFormatMetadata.put(fieldName,
87-
new TarantoolFieldMetadataImpl(fieldName, fieldType, fieldPosition++));
88-
}
89-
90-
TarantoolSpaceMetadataImpl spaceMetadata = new TarantoolSpaceMetadataImpl();
91-
spaceMetadata.setSpaceFormatMetadata(spaceFormatMetadata);
92-
93-
return spaceMetadata;
25+
public TarantoolTupleResultImpl(Value value, TarantoolTupleConverter tupleConverter) {
26+
setTuples(value.asArrayValue(), tupleConverter);
9427
}
9528

96-
private void setTuples(ArrayValue tupleArray, TarantoolTupleConverter tupleConverter,
97-
TarantoolSpaceMetadata responseMetadata) {
29+
private void setTuples(ArrayValue tupleArray, TarantoolSpaceMetadata responseMetadata,
30+
TarantoolTupleConverter tupleConverter) {
9831
this.tuples = tupleArray.list().stream()
99-
.map(v -> {
100-
try {
101-
return tupleConverter.fromValue(v.asArrayValue(), responseMetadata);
102-
} catch (MessageTypeCastException e) {
103-
throw new TarantoolTupleConversionException(v, e);
104-
}
105-
})
106-
.collect(Collectors.toList());
32+
.map(v -> {
33+
try {
34+
return tupleConverter.fromValue(v.asArrayValue(), responseMetadata);
35+
} catch (MessageTypeCastException e) {
36+
throw new TarantoolTupleConversionException(v, e);
37+
}
38+
})
39+
.collect(Collectors.toList());
10740
}
10841
}

src/main/java/io/tarantool/driver/core/space/TarantoolTupleSpace.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ protected TupleOperations makeOperationsFromTuple(TarantoolTuple tuple) {
5050
@Override
5151
protected MessagePackValueMapper tupleResultMapper() {
5252
return client.getResultMapperFactoryFactory().defaultTupleResultMapperFactory()
53-
.withDefaultTupleValueConverter(config.getMessagePackMapper(), getMetadata());
53+
.withTarantoolTupleResultConverter(config.getMessagePackMapper(), getMetadata());
5454
}
5555

5656
@Override

src/main/java/io/tarantool/driver/mappers/AbstractResultMapperFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.tarantool.driver.exceptions.TarantoolClientException;
44
import io.tarantool.driver.mappers.converters.ValueConverter;
55
import org.msgpack.value.ArrayValue;
6+
import org.msgpack.value.Value;
67

78
/**
89
* Base class for result mapper factories.

src/main/java/io/tarantool/driver/mappers/TupleResultMapperFactory.java renamed to src/main/java/io/tarantool/driver/mappers/ArrayValueToTarantoolResultMapperFactory.java

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
package io.tarantool.driver.mappers;
22

33
import io.tarantool.driver.api.TarantoolResult;
4-
import io.tarantool.driver.mappers.converters.value.custom.TarantoolResultConverter;
4+
import io.tarantool.driver.mappers.converters.value.custom.DefaultArrayValueToTarantoolResultConverter;
55
import io.tarantool.driver.mappers.converters.ValueConverter;
66
import org.msgpack.value.ArrayValue;
77

88
/**
99
* Factory for {@link TarantoolResultMapper} instances used for handling results with tuples of any type
1010
*
1111
* @author Alexey Kuzin
12+
* @author Artyom Dubinin
1213
*/
13-
public class TupleResultMapperFactory<T> extends TarantoolResultMapperFactory<T> {
14+
public class ArrayValueToTarantoolResultMapperFactory<T> extends TarantoolResultMapperFactory<T> {
1415

1516
private final MessagePackMapper messagePackMapper;
1617

1718
/**
1819
* Basic constructor
1920
*/
20-
public TupleResultMapperFactory() {
21+
public ArrayValueToTarantoolResultMapperFactory() {
2122
this(DefaultMessagePackMapperFactory.getInstance().emptyMapper());
2223
}
2324

@@ -26,7 +27,7 @@ public TupleResultMapperFactory() {
2627
*
2728
* @param messagePackMapper MessagePack-to-object mapper for tuple contents
2829
*/
29-
public TupleResultMapperFactory(MessagePackMapper messagePackMapper) {
30+
public ArrayValueToTarantoolResultMapperFactory(MessagePackMapper messagePackMapper) {
3031
super();
3132
this.messagePackMapper = messagePackMapper;
3233
}
@@ -37,8 +38,11 @@ public TupleResultMapperFactory(MessagePackMapper messagePackMapper) {
3738
* @param tupleConverter MessagePack-to-entity converter for tuples
3839
* @return mapper instance
3940
*/
40-
public TarantoolResultMapper<T> withTupleValueConverter(ValueConverter<ArrayValue, T> tupleConverter) {
41-
return withConverter(messagePackMapper.copy(), new TarantoolResultConverter<>(tupleConverter));
41+
public TarantoolResultMapper<T> withTarantoolResultConverter(ValueConverter<ArrayValue, T> tupleConverter) {
42+
return withConverter(
43+
messagePackMapper.copy(),
44+
new DefaultArrayValueToTarantoolResultConverter<T>(tupleConverter)
45+
);
4246
}
4347

4448
/**
@@ -48,9 +52,12 @@ public TarantoolResultMapper<T> withTupleValueConverter(ValueConverter<ArrayValu
4852
* @param tupleConverter MessagePack-to-entity converter for tuples
4953
* @return mapper instance
5054
*/
51-
public TarantoolResultMapper<T> withTupleValueConverter(MessagePackValueMapper valueMapper,
52-
ValueConverter<ArrayValue, T> tupleConverter) {
53-
return withConverter(valueMapper, new TarantoolResultConverter<>(tupleConverter));
55+
public TarantoolResultMapper<T> withTarantoolResultConverter(MessagePackValueMapper valueMapper,
56+
ValueConverter<ArrayValue, T> tupleConverter) {
57+
return withConverter(
58+
valueMapper,
59+
new DefaultArrayValueToTarantoolResultConverter<T>(tupleConverter)
60+
);
5461
}
5562

5663
/**
@@ -63,7 +70,11 @@ public TarantoolResultMapper<T> withTupleValueConverter(MessagePackValueMapper v
6370
*/
6471
public TarantoolResultMapper<T> withTarantoolResultConverter(ValueConverter<ArrayValue, T> tupleConverter,
6572
Class<? extends TarantoolResult<T>> resultClass) {
66-
return withConverter(messagePackMapper.copy(), new TarantoolResultConverter<>(tupleConverter), resultClass);
73+
return withConverter(
74+
messagePackMapper.copy(),
75+
new DefaultArrayValueToTarantoolResultConverter<T>(tupleConverter),
76+
resultClass
77+
);
6778
}
6879

6980
/**
@@ -75,9 +86,13 @@ public TarantoolResultMapper<T> withTarantoolResultConverter(ValueConverter<Arra
7586
* (e.g. lambda)
7687
* @return mapper instance
7788
*/
78-
public TarantoolResultMapper<T> withTupleValueConverter(MessagePackValueMapper valueMapper,
79-
ValueConverter<ArrayValue, T> tupleConverter,
80-
Class<? extends TarantoolResult<T>> resultClass) {
81-
return withConverter(valueMapper, new TarantoolResultConverter<>(tupleConverter), resultClass);
89+
public TarantoolResultMapper<T> withTarantoolResultConverter(MessagePackValueMapper valueMapper,
90+
ValueConverter<ArrayValue, T> tupleConverter,
91+
Class<? extends TarantoolResult<T>> resultClass) {
92+
return withConverter(
93+
valueMapper,
94+
new DefaultArrayValueToTarantoolResultConverter<T>(tupleConverter),
95+
resultClass
96+
);
8297
}
8398
}

0 commit comments

Comments
 (0)