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

io.tarantool.driver.metadata.ProxyTarantoolSpaceMetadataConverter 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.metadata;

import io.tarantool.driver.exceptions.TarantoolClientException;
import io.tarantool.driver.mappers.MessagePackValueMapper;
import io.tarantool.driver.mappers.ValueConverter;
import org.msgpack.value.ArrayValue;
import org.msgpack.value.ImmutableStringValue;
import org.msgpack.value.Value;
import org.msgpack.value.impl.ImmutableStringValueImpl;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Maps MessagePack {@link ArrayValue} from proxy schema API function call result into
 * {@link ProxyTarantoolSpaceMetadataContainer}.
 * See https://github.com/tarantool/ddl
 *
 * @author Sergey Volgin
 */
public class ProxyTarantoolSpaceMetadataConverter
        implements ValueConverter {

    private static final int ID_UNKNOWN = -1;

    private static final ImmutableStringValue SPACE_ID_KEY = new ImmutableStringValueImpl("id");
    private static final ImmutableStringValue SPACE_NAME_KEY = new ImmutableStringValueImpl("name");
    private static final ImmutableStringValue SPACE_FORMAT_KEY = new ImmutableStringValueImpl("format");
    private static final ImmutableStringValue SPACE_INDEXES_KEY = new ImmutableStringValueImpl("indexes");

    private static final ImmutableStringValue FORMAT_NAME_KEY = new ImmutableStringValueImpl("name");
    private static final ImmutableStringValue FORMAT_TYPE_KEY = new ImmutableStringValueImpl("type");

    private static final ImmutableStringValue INDEX_ID_KEY = new ImmutableStringValueImpl("id");
    private static final ImmutableStringValue INDEX_NAME_KEY = new ImmutableStringValueImpl("name");
    private static final ImmutableStringValue INDEX_UNIQUE_KEY = new ImmutableStringValueImpl("unique");
    private static final ImmutableStringValue INDEX_TYPE_KEY = new ImmutableStringValueImpl("type");
    private static final ImmutableStringValue INDEX_PARTS_KEY = new ImmutableStringValueImpl("parts");

    private static final ImmutableStringValue INDEX_PARTS_FIELD_NO = new ImmutableStringValueImpl("fieldno");
    private static final ImmutableStringValue INDEX_PARTS_TYPE_KEY = new ImmutableStringValueImpl("type");

    private final MessagePackValueMapper mapper;

    public ProxyTarantoolSpaceMetadataConverter(MessagePackValueMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    public ProxyTarantoolSpaceMetadataContainer fromValue(ArrayValue value) {

        if (value.size() == 0) {
            throw new TarantoolClientException("Empty tuple returned for space metadata");
        }

        if (!value.get(0).isMapValue()) {
            throw new TarantoolClientException("Unsupported space metadata format: expected map");
        }

        Map spacesMap = value.get(0).asMapValue().map();

        Value nameValue = spacesMap.get(SPACE_NAME_KEY);
        if (nameValue == null) {
            throw new TarantoolClientException(
                    "Unsupported space metadata format: key '" + SPACE_NAME_KEY + "' not found");
        }

        Value idValue = spacesMap.get(SPACE_ID_KEY);
        if (idValue == null) {
            throw new TarantoolClientException(
                    "Unsupported space metadata format: key '" + SPACE_ID_KEY + "' not found");
        }

        ProxyTarantoolSpaceMetadataContainer proxyMetadata = new ProxyTarantoolSpaceMetadataContainer();

        TarantoolSpaceMetadata spaceMetadata = new TarantoolSpaceMetadata();
        spaceMetadata.setSpaceId(idValue.asIntegerValue().asInt());
        spaceMetadata.setOwnerId(ID_UNKNOWN);
        spaceMetadata.setSpaceName(nameValue.asStringValue().asString());

        Value formatValue = spacesMap.get(SPACE_FORMAT_KEY);
        if (formatValue == null) {
            throw new TarantoolClientException(
                    "Unsupported space metadata format: key '" + SPACE_FORMAT_KEY + "' not found");
        }
        if (!formatValue.isArrayValue()) {
            throw new TarantoolClientException(
                    "Unsupported space metadata format: key '" + SPACE_FORMAT_KEY + "' value is not a list");
        }

        List spaceFormat = formatValue.asArrayValue().list();
        spaceMetadata.setSpaceFormatMetadata(parseFormat(spaceFormat));

        proxyMetadata.addSpace(spaceMetadata);

        Value indexesValue = spacesMap.get(SPACE_INDEXES_KEY);
        if (indexesValue != null && indexesValue.isArrayValue() && indexesValue.asArrayValue().size() > 0) {
            List indexes = indexesValue.asArrayValue().list();
            proxyMetadata.addIndexes(spaceMetadata.getSpaceName(), parseIndexes(indexes));
        }

        return proxyMetadata;
    }

    private LinkedHashMap parseFormat(List spaceFormat) {
        LinkedHashMap spaceFormatMetadata = new LinkedHashMap<>();

        int fieldPosition = 0;
        for (Value fieldValueMetadata : spaceFormat) {

            if (!fieldValueMetadata.isMapValue()) {
                throw new TarantoolClientException("Unsupported space metadata format: field metadata is not a map");
            }

            Map fieldMap = fieldValueMetadata.asMapValue().map();
            Value fieldNameValue = fieldMap.get(FORMAT_NAME_KEY);
            if (fieldNameValue == null || !fieldNameValue.isStringValue()) {
                throw new TarantoolClientException(
                        "Unsupported space metadata format: key '" + FORMAT_NAME_KEY + "' must have string value");
            }
            String fieldName = fieldNameValue.asStringValue().asString();

            Value fieldTypeValue = fieldMap.get(FORMAT_TYPE_KEY);
            if (fieldTypeValue == null || !fieldTypeValue.isStringValue()) {
                throw new TarantoolClientException(
                        "Unsupported space metadata format: key '" + FORMAT_TYPE_KEY + "' must have string value");
            }
            String fieldType = fieldTypeValue.asStringValue().asString();

            spaceFormatMetadata.put(fieldName, new TarantoolFieldMetadata(fieldName, fieldType, fieldPosition++));
        }

        return spaceFormatMetadata;
    }

    private Map parseIndexes(List indexes) {
        Map indexMetadataMap = new HashMap<>();

        for (Value indexValueMetadata : indexes) {

            if (!indexValueMetadata.isMapValue()) {
                throw new TarantoolClientException("Unsupported index metadata format: index metadata is not a map");
            }

            Map indexMap = indexValueMetadata.asMapValue().map();
            Value indexIdValue = indexMap.get(INDEX_ID_KEY);
            if (indexIdValue == null || !indexIdValue.isIntegerValue()) {
                throw new TarantoolClientException(
                        "Unsupported index metadata format: key '" + INDEX_ID_KEY + "' must have int value");
            }
            int indexId = indexIdValue.asIntegerValue().asInt();

            Value indexNameValue = indexMap.get(INDEX_NAME_KEY);
            if (indexNameValue == null || !indexNameValue.isStringValue()) {
                throw new TarantoolClientException(
                        "Unsupported index metadata format: key '" + INDEX_NAME_KEY + "' must have string value");
            }
            String indexName = indexNameValue.asStringValue().asString();

            Value indexTypeValue = indexMap.get(INDEX_TYPE_KEY);
            if (indexTypeValue == null || !indexTypeValue.isStringValue()) {
                throw new TarantoolClientException(
                        "Unsupported index metadata format: key '" + INDEX_TYPE_KEY + "' must have string value");
            }
            String indexType = indexTypeValue.asStringValue().asString();

            Value indexUniqueValue = indexMap.get(INDEX_UNIQUE_KEY);
            if (indexUniqueValue == null || !indexUniqueValue.isBooleanValue()) {
                throw new TarantoolClientException(
                        "Unsupported index metadata format: key '" + INDEX_UNIQUE_KEY + "' must have boolean value");
            }
            boolean isUnique = indexUniqueValue.asBooleanValue().getBoolean();

            TarantoolIndexOptions indexOptions = new TarantoolIndexOptions();
            indexOptions.setUnique(isUnique);

            TarantoolIndexMetadata indexMetadata = new TarantoolIndexMetadata();
            indexMetadata.setSpaceId(ID_UNKNOWN);
            indexMetadata.setIndexId(indexId);
            indexMetadata.setIndexType(TarantoolIndexType.fromString(indexType));
            indexMetadata.setIndexName(indexName);
            indexMetadata.setIndexOptions(indexOptions);

            Value indexPartsValue = indexMap.get(INDEX_PARTS_KEY);
            if (indexPartsValue == null) {
                throw new TarantoolClientException(
                        "Unsupported index metadata format: key '" + INDEX_PARTS_KEY + "' not found");
            }
            if (!indexPartsValue.isArrayValue()) {
                throw new TarantoolClientException(
                        "Unsupported index metadata format: key '" + INDEX_PARTS_KEY + "' value is not a list");
            }

            List indexParts = indexPartsValue.asArrayValue().list();
            List indexPartMetadata = indexParts.stream()
                    .map(parts -> {
                        if (!parts.isMapValue()) {
                            throw new TarantoolClientException(
                                "Unsupported index metadata format: index part metadata is not a map");
                        }

                        Map partsMap = parts.asMapValue().map();
                        Value fieldPositionValue = partsMap.get(INDEX_PARTS_FIELD_NO);
                        if (fieldPositionValue == null || !fieldPositionValue.isIntegerValue()) {
                            throw new TarantoolClientException("Unsupported index metadata format: key '" +
                                    INDEX_PARTS_FIELD_NO + "' must have int value");
                        }
                        int fieldNumber = fieldPositionValue.asIntegerValue().asInt();

                        Value fieldTypeValue = partsMap.get(INDEX_PARTS_TYPE_KEY);
                        if (fieldTypeValue == null || !fieldTypeValue.isStringValue()) {
                            throw new TarantoolClientException("Unsupported index metadata format: key '" +
                                    INDEX_PARTS_TYPE_KEY + "' must have string value");
                        }
                        String fieldType = fieldTypeValue.asStringValue().asString();

                        return new TarantoolIndexPartMetadata(fieldNumber - 1, fieldType);
                    })
                    .collect(Collectors.toList());

            indexMetadata.setIndexParts(indexPartMetadata);

            indexMetadataMap.put(indexName, indexMetadata);
        }

        return indexMetadataMap;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy