Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
## [Unreleased]

- Use netty part dependencies instead of netty-all ([#295](https://github.com/tarantool/cartridge-java/issues/295))
- Refactor mappers and split `TarantoolResultConverter` ([#301](https://github.com/tarantool/cartridge-java/pull/301))
- **[breaking change]** `TarantoolResultConverter` was removed, use `DefaultArrayValueToTarantoolResultConverter` or `DefaultMapValueToTarantoolTupleResultConverter` instead ([#301](https://github.com/tarantool/cartridge-java/pull/301))
- **[breaking change]** `ConverterWrapper` was moved to converters package ([#301](https://github.com/tarantool/cartridge-java/pull/301))
- **[breaking change]** `*MapperFactory` classes were moved to separate package ([#301](https://github.com/tarantool/cartridge-java/pull/301))
- **[breaking change]** `TarantoolTupleMultiResult` was renamed to `MultiValueTarantoolTupleResult` ([#301](https://github.com/tarantool/cartridge-java/pull/301))
- **[breaking change]** `TarantoolTupleSingleResult` was renamed to `SingleValueTarantoolTupleResult` ([#301](https://github.com/tarantool/cartridge-java/pull/301))
- **[breaking change]** `*MapperFactory` methods were renamed ([#301](https://github.com/tarantool/cartridge-java/pull/301))
- **[breaking change]** `*DefaultConverter` converters moved into `mappers.converters.value.defaults` package ([#301](https://github.com/tarantool/cartridge-java/pull/301))
- **[breaking change]** All converters from `mappers.converters.value.custom` moved into `mappers.converters.value` package ([#301](https://github.com/tarantool/cartridge-java/pull/301))

## [0.9.2] - 2022-11-15

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import io.tarantool.driver.mappers.CallResultMapper;
import io.tarantool.driver.mappers.MessagePackMapper;
import io.tarantool.driver.mappers.MessagePackObjectMapper;
import io.tarantool.driver.mappers.ResultMapperFactoryFactory;
import io.tarantool.driver.mappers.converters.ValueConverter;
import io.tarantool.driver.mappers.factories.ResultMapperFactoryFactory;
import org.msgpack.value.Value;

import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import io.tarantool.driver.auth.TarantoolCredentials;
import io.tarantool.driver.mappers.DefaultMessagePackMapper;
import io.tarantool.driver.mappers.MessagePackMapper;
import io.tarantool.driver.mappers.factories.DefaultMessagePackMapperFactory;

import java.net.InetSocketAddress;
import java.util.List;
Expand Down Expand Up @@ -112,7 +113,7 @@ public interface TarantoolClientBuilder extends TarantoolClientConfigurator<Tara
* <p>
* This method takes a lambda as an argument, where the mapperBuilder is {@link DefaultMessagePackMapper.Builder}.
* </p>
* see {@link io.tarantool.driver.mappers.DefaultMessagePackMapperFactory}.
* see {@link DefaultMessagePackMapperFactory}.
*
* @param mapperBuilder builder provider instance, e.g. a lambda function taking the builder
* for {@link MessagePackMapper} instance
Expand All @@ -127,7 +128,7 @@ public interface TarantoolClientBuilder extends TarantoolClientConfigurator<Tara
* The mapper contains converters for simple and complex tuple field types and for the entire tuples into custom
* Java objects. This mapper is used by default if a custom mapper is not passed to a specific operation.
* You may build and pass here your custom mapper or add some converters to a default one,
* see {@link io.tarantool.driver.mappers.DefaultMessagePackMapperFactory}.
* see {@link DefaultMessagePackMapperFactory}.
*
* @param mapper configured {@link MessagePackMapper} instance
* @return this instance of builder {@link TarantoolClientBuilder}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import io.tarantool.driver.api.connection.TarantoolConnectionSelectionStrategies;
import io.tarantool.driver.auth.SimpleTarantoolCredentials;
import io.tarantool.driver.auth.TarantoolCredentials;
import io.tarantool.driver.mappers.DefaultMessagePackMapperFactory;
import io.tarantool.driver.mappers.MessagePackMapper;
import io.tarantool.driver.mappers.factories.DefaultMessagePackMapperFactory;
import io.tarantool.driver.utils.Assert;

import java.util.concurrent.atomic.AtomicBoolean;
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/io/tarantool/driver/api/TarantoolResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import java.util.List;

/**
* Basic interface for Tarantool operations result -- an array of tuples
* Basic interface for Tarantool operations result.
* It can be multiple return values from Lua, tuple(s) from IProto, and other things in different structures
*
* @param <T> target tuple type
* @author Alexey Kuzin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
* @author Alexey Kuzin
* @see TarantoolTupleResult
*/
public interface TarantoolTupleMultiResult
public interface MultiValueTarantoolTupleResult
extends MultiValueCallResult<TarantoolTuple, TarantoolResult<TarantoolTuple>> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
* @author Alexey Kuzin
* @see TarantoolTupleResult
*/
public interface TarantoolTupleSingleResult extends SingleValueCallResult<TarantoolResult<TarantoolTuple>> {
public interface SingleValueTarantoolTupleResult extends SingleValueCallResult<TarantoolResult<TarantoolTuple>> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
import io.tarantool.driver.exceptions.TarantoolClientException;
import io.tarantool.driver.exceptions.TarantoolSpaceNotFoundException;
import io.tarantool.driver.mappers.CallResultMapper;
import io.tarantool.driver.mappers.DefaultResultMapperFactoryFactory;
import io.tarantool.driver.mappers.MessagePackMapper;
import io.tarantool.driver.mappers.MessagePackObjectMapper;
import io.tarantool.driver.mappers.MessagePackValueMapper;
import io.tarantool.driver.mappers.ResultMapperFactoryFactory;
import io.tarantool.driver.mappers.converters.ValueConverter;
import io.tarantool.driver.mappers.factories.ResultMapperFactoryFactoryImpl;
import io.tarantool.driver.mappers.factories.ResultMapperFactoryFactory;
import io.tarantool.driver.protocol.Packable;
import io.tarantool.driver.protocol.TarantoolProtocolException;
import io.tarantool.driver.protocol.requests.TarantoolCallRequest;
Expand Down Expand Up @@ -66,7 +66,7 @@ public abstract class AbstractTarantoolClient<T extends Packable, R extends Coll
private final TarantoolConnectionFactory connectionFactory;
private final TarantoolConnectionListeners listeners;
private final AtomicReference<TarantoolMetadata> metadataHolder = new AtomicReference<>();
private final DefaultResultMapperFactoryFactory mapperFactoryFactory;
private final ResultMapperFactoryFactoryImpl mapperFactoryFactory;
private final SpacesMetadataProvider metadataProvider;
private final ScheduledExecutorService timeoutScheduler;
private TarantoolConnectionManager connectionManager;
Expand Down Expand Up @@ -110,7 +110,7 @@ public AbstractTarantoolClient(TarantoolClientConfig config, TarantoolConnection
Assert.notNull(listeners, "Tarantool connection listeners must not be null");

this.config = config;
this.mapperFactoryFactory = new DefaultResultMapperFactoryFactory();
this.mapperFactoryFactory = new ResultMapperFactoryFactoryImpl();
this.eventLoopGroup = new NioEventLoopGroup(config.getEventLoopThreadsNumber());
this.bootstrap = new Bootstrap()
.group(eventLoopGroup)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.tarantool.driver.api.MultiValueCallResult;
import io.tarantool.driver.exceptions.TarantoolFunctionCallException;
import io.tarantool.driver.exceptions.errors.TarantoolErrorsParser;
import io.tarantool.driver.mappers.MessagePackValueMapper;
import io.tarantool.driver.mappers.converters.ValueConverter;
import org.msgpack.value.ArrayValue;
import org.msgpack.value.Value;
Expand All @@ -14,6 +15,7 @@
* {@code null}, the second is treated as a formatted error or an error message.
*
* @author Alexey Kuzin
* @author Artyom Dubinin
*/
public class MultiValueCallResultImpl<T, R extends List<T>> implements MultiValueCallResult<T, R> {

Expand All @@ -36,6 +38,23 @@ public MultiValueCallResultImpl(Value result, ValueConverter<ArrayValue, R> valu
}
}

public MultiValueCallResultImpl(Value result, MessagePackValueMapper valueMapper) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need the existing method once we have this new one? We need either to remove the former one or to refactor them in a way that eliminates the copy-paste.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need it when we pass only one converter to parsing. We parse callForMultiResult with one converter on the top of stack

if (result == null) {
throw new TarantoolFunctionCallException("Function call result is null");
}
if (!result.isArrayValue()) {
throw new TarantoolFunctionCallException("Function call result is not a MessagePack array");
}
ArrayValue resultArray = result.asArrayValue();
if (resultArray.size() == 2 && (resultArray.get(0).isNilValue() && !resultArray.get(1).isNilValue())) {
// [nil, "Error msg..."] or [nil, {str="Error msg...", stack="..."}]
throw TarantoolErrorsParser.parse(resultArray.get(1));
} else {
// result
this.value = valueMapper.fromValue(result.asArrayValue());
}
}

@Override
public R value() {
return value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
import io.tarantool.driver.mappers.MessagePackMapper;
import io.tarantool.driver.mappers.MessagePackObjectMapper;
import io.tarantool.driver.mappers.MessagePackValueMapper;
import io.tarantool.driver.mappers.ResultMapperFactoryFactory;
import io.tarantool.driver.mappers.converters.ValueConverter;
import io.tarantool.driver.mappers.factories.ResultMapperFactoryFactory;
import io.tarantool.driver.protocol.Packable;
import io.tarantool.driver.utils.Assert;
import org.msgpack.value.Value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
import io.tarantool.driver.mappers.MessagePackMapper;
import io.tarantool.driver.mappers.MessagePackObjectMapper;
import io.tarantool.driver.mappers.MessagePackValueMapper;
import io.tarantool.driver.mappers.ResultMapperFactoryFactory;
import io.tarantool.driver.mappers.converters.ValueConverter;
import io.tarantool.driver.mappers.factories.ResultMapperFactoryFactory;
import io.tarantool.driver.protocol.Packable;
import org.msgpack.value.Value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.tarantool.driver.api.SingleValueCallResult;
import io.tarantool.driver.exceptions.TarantoolFunctionCallException;
import io.tarantool.driver.exceptions.errors.TarantoolErrorsParser;
import io.tarantool.driver.mappers.MessagePackValueMapper;
import io.tarantool.driver.mappers.converters.ValueConverter;
import org.msgpack.value.ArrayValue;
import org.msgpack.value.Value;
Expand All @@ -12,6 +13,7 @@
* {@code null}, the second is treated as a formatted error or an error message.
*
* @author Alexey Kuzin
* @author Artyom Dubinin
*/
public class SingleValueCallResultImpl<T> implements SingleValueCallResult<T> {

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

public SingleValueCallResultImpl(ArrayValue result, MessagePackValueMapper valueMapper) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same question as for the multi result implementation, we need to either remove the constructor with converter or make them both reusing the same code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need it when we pass only one converter to parsing. For example, we parse callForSingleiResult with one converter on the top of stack

if (result == null) {
throw new TarantoolFunctionCallException("Function call result is null");
}
if (result.size() == 0 || result.size() == 1 && result.get(0).isNilValue()) {
// [nil] or []
value = null;
} else if (result.size() == 2 && (result.get(0).isNilValue() && !result.get(1).isNilValue())) {
// [nil, "Error msg..."] or [nil, {str="Error msg...", stack="..."}]
throw TarantoolErrorsParser.parse(result.get(1));
} else {
// [result]
value = valueMapper.fromValue(result.get(0));
}
}

@Override
public T value() {
return value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import io.tarantool.driver.handlers.TarantoolAuthenticationResponseHandler;
import io.tarantool.driver.handlers.TarantoolRequestHandler;
import io.tarantool.driver.handlers.TarantoolResponseHandler;
import io.tarantool.driver.mappers.DefaultMessagePackMapperFactory;
import io.tarantool.driver.mappers.factories.DefaultMessagePackMapperFactory;

import java.util.concurrent.CompletableFuture;

Expand Down
63 changes: 17 additions & 46 deletions src/main/java/io/tarantool/driver/core/TarantoolResultImpl.java
Original file line number Diff line number Diff line change
@@ -1,78 +1,49 @@
package io.tarantool.driver.core;

import io.tarantool.driver.api.TarantoolResult;
import io.tarantool.driver.exceptions.TarantoolClientException;
import io.tarantool.driver.exceptions.TarantoolTupleConversionException;
import io.tarantool.driver.mappers.converters.ValueConverter;
import org.msgpack.core.MessageTypeCastException;
import org.msgpack.value.ArrayValue;
import org.msgpack.value.StringValue;
import org.msgpack.value.Value;
import org.msgpack.value.ValueFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.stream.Collectors;

/**
* Basic TarantoolResult implementation. Supports two types of the tuple result: a MessagePack array of arrays
* (as in IPROTO) and a map with format {@code {"rows": [[], ...], "metadata": []}} as returned by tarantool/crud module
* Basic TarantoolResult implementation
*
* @param <T> target result tuple type
* @author Alexey Kuzin
* @author Artyom Dubinin
*/
public class TarantoolResultImpl<T> implements TarantoolResult<T> {

private static final StringValue RESULT_META = ValueFactory.newString("metadata");
private static final StringValue RESULT_ROWS = ValueFactory.newString("rows");

private List<T> tuples;

public TarantoolResultImpl(Value value, ValueConverter<ArrayValue, T> tupleConverter) {
if (value.isArrayValue()) {
// [[[],...]]
setTuples(value.asArrayValue(), tupleConverter);
} else if (value.isMapValue()) {
// [{"metadata" : [...], "rows": [...]}]
Map<Value, Value> tupleMap = value.asMapValue().map();
if (!hasRowsAndMetadata(tupleMap)) {
throw new TarantoolClientException("The received tuple map has wrong format, " +
"expected {\"metadata\" : [...], \"rows\": [...]}, got %s", value.toString());
}
Value tupleArray = tupleMap.get(RESULT_ROWS);
if (!tupleArray.isArrayValue()) {
throw new TarantoolClientException("The \"rows\" field must contain a MessagePack array");
}
setTuples(tupleArray.asArrayValue(), tupleConverter);
} else if (value.isNilValue()) {
// [nil]
this.tuples = new ArrayList<>();
} else {
throw new TarantoolClientException("The received result cannot be converted to an array of tuples: %s",
value.toString());
}
}

private void setTuples(ArrayValue tupleArray, ValueConverter<ArrayValue, T> tupleConverter) {
this.tuples = tupleArray.list().stream()
protected List<T> tuples;

protected TarantoolResultImpl() {
}

public TarantoolResultImpl(ArrayValue value, ValueConverter<ArrayValue, T> valueConverter) {
// [[[],...]]
setItems(value, valueConverter);
}

protected void setItems(ArrayValue itemsArray, ValueConverter<ArrayValue, T> valueConverter) {
this.tuples = itemsArray.list().stream()
.map(v -> {
try {
return tupleConverter.fromValue(v.asArrayValue());
return valueConverter.fromValue(v.asArrayValue());
} catch (MessageTypeCastException e) {
throw new TarantoolTupleConversionException(v, e);
}
})
.collect(Collectors.toList());
}

private static boolean hasRowsAndMetadata(Map<Value, Value> valueMap) {
return valueMap.containsKey(RESULT_META) && valueMap.containsKey(RESULT_ROWS);
}

@Override
public int size() {
return this.tuples.size();
Expand Down Expand Up @@ -115,7 +86,7 @@ public boolean remove(Object o) {

@Override
public boolean containsAll(Collection<?> c) {
return this.tuples.containsAll(c);
return new HashSet<>(this.tuples).containsAll(c);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private <T> CompletableFuture<TarantoolResult<T>> select(
throws TarantoolClientException {
CallResultMapper<TarantoolResult<T>, SingleValueCallResult<TarantoolResult<T>>> resultMapper =
client.getResultMapperFactoryFactory().<T>singleValueTarantoolResultMapperFactory()
.withTarantoolResultConverter(resultConverter, resultClass);
.withSingleValueArrayTarantoolResultConverter(resultConverter, resultClass);
return client.call(selectCmd, resultMapper);
}
}
Loading