All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.tarantool.driver.core.space.ProxyTarantoolSpace Maven / Gradle / Ivy

Go to download

Tarantool Cartridge driver for Tarantool versions 1.10+ based on Netty framework

There is a newer version: 0.14.0
Show newest version
package io.tarantool.driver.core.space;

import io.tarantool.driver.api.SingleValueCallResult;
import io.tarantool.driver.api.TarantoolCallOperations;
import io.tarantool.driver.api.TarantoolClientConfig;
import io.tarantool.driver.api.conditions.Conditions;
import io.tarantool.driver.api.metadata.TarantoolMetadataOperations;
import io.tarantool.driver.api.metadata.TarantoolSpaceMetadata;
import io.tarantool.driver.api.proxy.ProxyOperationsMappingConfig;
import io.tarantool.driver.api.space.TarantoolSpaceOperations;
import io.tarantool.driver.api.space.options.DeleteOptions;
import io.tarantool.driver.api.space.options.InsertManyOptions;
import io.tarantool.driver.api.space.options.InsertOptions;
import io.tarantool.driver.api.space.options.ReplaceManyOptions;
import io.tarantool.driver.api.space.options.ReplaceOptions;
import io.tarantool.driver.api.space.options.SelectOptions;
import io.tarantool.driver.api.space.options.UpdateOptions;
import io.tarantool.driver.api.space.options.UpsertOptions;
import io.tarantool.driver.api.space.options.proxy.ProxyDeleteOptions;
import io.tarantool.driver.api.space.options.proxy.ProxyInsertManyOptions;
import io.tarantool.driver.api.space.options.proxy.ProxyInsertOptions;
import io.tarantool.driver.api.space.options.proxy.ProxyReplaceManyOptions;
import io.tarantool.driver.api.space.options.proxy.ProxyReplaceOptions;
import io.tarantool.driver.api.space.options.proxy.ProxySelectOptions;
import io.tarantool.driver.api.space.options.proxy.ProxyTruncateOptions;
import io.tarantool.driver.api.space.options.proxy.ProxyUpdateOptions;
import io.tarantool.driver.api.space.options.proxy.ProxyUpsertOptions;
import io.tarantool.driver.api.tuple.operations.TupleOperations;
import io.tarantool.driver.core.proxy.DeleteProxyOperation;
import io.tarantool.driver.core.proxy.InsertManyProxyOperation;
import io.tarantool.driver.core.proxy.InsertProxyOperation;
import io.tarantool.driver.core.proxy.ProxyOperation;
import io.tarantool.driver.core.proxy.ReplaceManyProxyOperation;
import io.tarantool.driver.core.proxy.ReplaceProxyOperation;
import io.tarantool.driver.core.proxy.SelectProxyOperation;
import io.tarantool.driver.core.proxy.TruncateProxyOperation;
import io.tarantool.driver.core.proxy.UpdateProxyOperation;
import io.tarantool.driver.core.proxy.UpsertProxyOperation;
import io.tarantool.driver.exceptions.TarantoolClientException;
import io.tarantool.driver.mappers.CallResultMapper;
import io.tarantool.driver.protocol.Packable;
import io.tarantool.driver.protocol.TarantoolIndexQuery;
import org.msgpack.value.ArrayValue;

import java.util.Collection;
import java.util.concurrent.CompletableFuture;

/**
 * Basic proxy {@link TarantoolSpaceOperations} implementation, which uses calls to API functions defined in
 * Tarantool instance for performing CRUD operations on a space
 *
 * @author Sergey Volgin
 * @author Alexey Kuzin
 */
public abstract class ProxyTarantoolSpace>
    implements TarantoolSpaceOperations {

    private final String spaceName;
    private final TarantoolClientConfig config;
    private final TarantoolCallOperations client;
    private final TarantoolMetadataOperations metadataOperations;
    private final ProxyOperationsMappingConfig operationsMapping;
    private final TarantoolSpaceMetadata spaceMetadata;

    public ProxyTarantoolSpace(
        TarantoolClientConfig config,
        TarantoolCallOperations client,
        ProxyOperationsMappingConfig operationsMapping,
        TarantoolMetadataOperations metadata,
        TarantoolSpaceMetadata spaceMetadata) {
        this.config = config;
        this.client = client;
        this.operationsMapping = operationsMapping;
        this.metadataOperations = metadata;
        this.spaceMetadata = spaceMetadata;
        this.spaceName = spaceMetadata.getSpaceName();
    }

    @Override
    public CompletableFuture delete(Conditions conditions) throws TarantoolClientException {
        return delete(conditions, rowsMetadataTupleResultMapper(), ProxyDeleteOptions.create());
    }

    @Override
    public CompletableFuture delete(Conditions conditions, DeleteOptions options) throws TarantoolClientException {
        if (options == null) {
            throw new IllegalArgumentException("Options should not be null");
        }
        return delete(conditions, rowsMetadataTupleResultMapper(), options);
    }

    private CompletableFuture delete(
        Conditions conditions,
        CallResultMapper> resultMapper,
        DeleteOptions options)
        throws TarantoolClientException {
        TarantoolIndexQuery indexQuery = conditions.toIndexQuery(metadataOperations, spaceMetadata);

        DeleteProxyOperation operation = new DeleteProxyOperation.Builder()
            .withClient(client)
            .withSpaceName(spaceName)
            .withFunctionName(operationsMapping.getDeleteFunctionName())
            .withIndexQuery(indexQuery)
            .withArgumentsMapper(config.getMessagePackMapper())
            .withResultMapper(resultMapper)
            .withOptions(options)
            .build();

        return executeOperation(operation);
    }

    @Override
    public CompletableFuture insert(T tuple) throws TarantoolClientException {
        return insert(tuple, rowsMetadataTupleResultMapper(), ProxyInsertOptions.create());
    }

    @Override
    public CompletableFuture insert(T tuple, InsertOptions options) throws TarantoolClientException {
        if (options == null) {
            throw new IllegalArgumentException("Options should not be null");
        }
        return insert(tuple, rowsMetadataTupleResultMapper(), options);
    }

    private CompletableFuture insert(
        T tuple,
        CallResultMapper> resultMapper,
        InsertOptions options)
        throws TarantoolClientException {
        InsertProxyOperation operation = new InsertProxyOperation.Builder()
            .withClient(client)
            .withSpaceName(spaceName)
            .withFunctionName(operationsMapping.getInsertFunctionName())
            .withTuple(tuple)
            .withArgumentsMapper(config.getMessagePackMapper())
            .withResultMapper(resultMapper)
            .withOptions(options)
            .build();

        return executeOperation(operation);
    }

    @Override
    public CompletableFuture insertMany(Collection tuples) {
        return insertMany(tuples, rowsMetadataTupleResultMapper(), ProxyInsertManyOptions.create()
            .withStopOnError(true)
            .withRollbackOnError(true)
        );
    }

    @Override
    public CompletableFuture insertMany(Collection tuples, InsertManyOptions options)
        throws TarantoolClientException {
        if (options == null) {
            throw new IllegalArgumentException("Options should not be null");
        }
        return insertMany(tuples, rowsMetadataTupleResultMapper(), options);
    }

    private CompletableFuture insertMany(
        Collection tuples,
        CallResultMapper> resultMapper,
        InsertManyOptions options)
        throws TarantoolClientException {
        InsertManyProxyOperation operation = new InsertManyProxyOperation.Builder()
            .withClient(client)
            .withSpaceName(spaceName)
            .withFunctionName(operationsMapping.getInsertManyFunctionName())
            .withTuples(tuples)
            .withArgumentsMapper(config.getMessagePackMapper())
            .withResultMapper(resultMapper)
            .withOptions(options)
            .build();

        return executeOperation(operation);
    }

    @Override
    public CompletableFuture replace(T tuple) throws TarantoolClientException {
        return replace(tuple, rowsMetadataTupleResultMapper(), ProxyReplaceOptions.create());
    }

    @Override
    public CompletableFuture replace(T tuple, ReplaceOptions options) throws TarantoolClientException {
        if (options == null) {
            throw new IllegalArgumentException("Options should not be null");
        }
        return replace(tuple, rowsMetadataTupleResultMapper(), options);
    }

    private CompletableFuture replace(
        T tuple,
        CallResultMapper> resultMapper,
        ReplaceOptions options)
        throws TarantoolClientException {
        ReplaceProxyOperation operation = new ReplaceProxyOperation.Builder()
            .withClient(client)
            .withSpaceName(spaceName)
            .withFunctionName(operationsMapping.getReplaceFunctionName())
            .withTuple(tuple)
            .withArgumentsMapper(config.getMessagePackMapper())
            .withResultMapper(resultMapper)
            .withOptions(options)
            .build();

        return executeOperation(operation);
    }

    @Override
    public CompletableFuture replaceMany(Collection tuples) throws TarantoolClientException {
        return replaceMany(tuples, rowsMetadataTupleResultMapper(), ProxyReplaceManyOptions.create()
            .withStopOnError(true)
            .withRollbackOnError(true)
        );
    }

    @Override
    public CompletableFuture replaceMany(Collection tuples, ReplaceManyOptions options) {
        if (options == null) {
            throw new IllegalArgumentException("Options should not be null");
        }
        return replaceMany(tuples, rowsMetadataTupleResultMapper(), options);
    }

    private CompletableFuture replaceMany(
        Collection tuples,
        CallResultMapper> resultMapper,
        ReplaceManyOptions options)
        throws TarantoolClientException {
        ReplaceManyProxyOperation operation = new ReplaceManyProxyOperation.Builder()
            .withClient(client)
            .withSpaceName(spaceName)
            .withFunctionName(operationsMapping.getReplaceManyFunctionName())
            .withTuples(tuples)
            .withArgumentsMapper(config.getMessagePackMapper())
            .withResultMapper(resultMapper)
            .withOptions(options)
            .build();

        return executeOperation(operation);
    }

    @Override
    public CompletableFuture select(Conditions conditions) throws TarantoolClientException {
        return select(conditions, rowsMetadataTupleResultMapper(), ProxySelectOptions.create());
    }

    @Override
    public CompletableFuture select(
        Conditions conditions,
        SelectOptions options) throws TarantoolClientException {
        if (options == null) {
            throw new IllegalArgumentException("Options should not be null");
        }
        return select(conditions, rowsMetadataTupleResultMapper(), options);
    }

    private CompletableFuture select(
        Conditions conditions,
        CallResultMapper> resultMapper,
        SelectOptions options)
        throws TarantoolClientException {
        SelectProxyOperation operation = new SelectProxyOperation.Builder(metadataOperations, spaceMetadata)
            .withClient(client)
            .withSpaceName(spaceName)
            .withFunctionName(operationsMapping.getSelectFunctionName())
            .withConditions(conditions)
            .withArgumentsMapper(config.getMessagePackMapper())
            .withResultMapper(resultMapper)
            .withOptions(options)
            .build();

        return executeOperation(operation);
    }

    @Override
    public CompletableFuture update(Conditions conditions, T tuple) {
        return update(conditions, makeOperationsFromTuple(tuple), rowsMetadataTupleResultMapper(),
            ProxyUpdateOptions.create()
        );
    }

    @Override
    public CompletableFuture update(Conditions conditions, T tuple, UpdateOptions options) {
        if (options == null) {
            throw new IllegalArgumentException("Options should not be null");
        }
        return update(conditions, makeOperationsFromTuple(tuple), rowsMetadataTupleResultMapper(), options);
    }

    /**
     * Create a {@link TupleOperations} instance from the given tuple of type {@code T}
     *
     * @param tuple tuple of the specified type
     * @return new {@link TupleOperations} instance
     */
    protected abstract TupleOperations makeOperationsFromTuple(T tuple);

    @Override
    public CompletableFuture update(Conditions conditions, TupleOperations operations) {
        return update(conditions, operations, rowsMetadataTupleResultMapper(), ProxyUpdateOptions.create());
    }

    @Override
    public CompletableFuture update(Conditions conditions, TupleOperations operations, UpdateOptions options) {
        if (options == null) {
            throw new IllegalArgumentException("Options should not be null");
        }
        return update(conditions, operations, rowsMetadataTupleResultMapper(), options);
    }

    private CompletableFuture update(
        Conditions conditions,
        TupleOperations operations,
        CallResultMapper> resultMapper,
        UpdateOptions options) {
        TarantoolIndexQuery indexQuery = conditions.toIndexQuery(metadataOperations, spaceMetadata);

        UpdateProxyOperation operation = new UpdateProxyOperation.Builder()
            .withClient(client)
            .withSpaceName(spaceName)
            .withFunctionName(operationsMapping.getUpdateFunctionName())
            .withIndexQuery(indexQuery)
            .withTupleOperation(operations)
            .withArgumentsMapper(config.getMessagePackMapper())
            .withResultMapper(resultMapper)
            .withOptions(options)
            .build();

        return executeOperation(operation);
    }

    @Override
    public CompletableFuture upsert(Conditions conditions, T tuple, TupleOperations operations) {
        return upsert(conditions, tuple, operations, rowsMetadataTupleResultMapper(), ProxyUpsertOptions.create());
    }

    @Override
    public CompletableFuture upsert(
        Conditions conditions, T tuple, TupleOperations operations,
        UpsertOptions options) {
        if (options == null) {
            throw new IllegalArgumentException("Options should not be null");
        }
        return upsert(conditions, tuple, operations, rowsMetadataTupleResultMapper(), options);
    }

    private CompletableFuture upsert(
        Conditions conditions,
        T tuple,
        TupleOperations operations,
        CallResultMapper> resultMapper,
        UpsertOptions options) {

        UpsertProxyOperation operation = new UpsertProxyOperation.Builder()
            .withClient(client)
            .withSpaceName(spaceName)
            .withFunctionName(operationsMapping.getUpsertFunctionName())
            .withTuple(tuple)
            .withTupleOperation(operations)
            .withArgumentsMapper(config.getMessagePackMapper())
            .withResultMapper(resultMapper)
            .withOptions(options)
            .build();

        return executeOperation(operation);
    }

    @Override
    public CompletableFuture truncate() throws TarantoolClientException {
        try {
            return executeVoidOperation(TruncateProxyOperation.builder()
                .withClient(client)
                .withSpaceName(spaceName)
                .withFunctionName(operationsMapping.getTruncateFunctionName())
                .withOptions(ProxyTruncateOptions.create())
                .build()
            );
        } catch (TarantoolClientException e) {
            throw new TarantoolClientException(e);
        }
    }

    /**
     * MessagePack value mapper configured with an ArrayValue to tuple converter corresponding to the selected
     * tuple type
     *
     * @return configured mapper with {@link ArrayValue} to {@code T} converter
     */
    protected abstract CallResultMapper> rowsMetadataTupleResultMapper();

    private CompletableFuture executeOperation(ProxyOperation operation) {
        return operation.execute();
    }

    private CompletableFuture executeVoidOperation(ProxyOperation operation) {
        return operation.execute();
    }

    @Override
    public TarantoolSpaceMetadata getMetadata() {
        return spaceMetadata;
    }

    @Override
    public String toString() {
        return String.format("ProxyTarantoolSpace [%s]", spaceName);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy