// Path: src/main/java/ru/shadam/tarantool/core/convert/TarantoolConverter.java
// public interface TarantoolConverter
//         extends EntityConverter<TarantoolPersistentEntity<?>, TarantoolPersistentProperty, Object, TarantoolData> {
// 
//     void removePrimaryKey(Object source, TarantoolData sink);
// }
// 
// Path: src/main/java/ru/shadam/tarantool/core/convert/TarantoolData.java
// public class TarantoolData {
//     private Object id;
// 
//     private Tuple tuple;
// 
//     public TarantoolData() {
//         this.tuple = new Tuple();
//     }
// 
//     public TarantoolData(Tuple tuple) {
//         this.tuple = tuple;
//     }
// 
//     public Object getId() {
//         return id;
//     }
// 
//     public void setId(Object id) {
//         this.id = id;
//     }
// 
// 
//     @Override
//     public String toString() {
//         return "TarantoolData{" +
//                 ", id=" + id +
//                 ", tuple=" + tuple +
//                 '}';
//     }
// 
//     public Tuple getTuple() {
//         return tuple;
//     }
// }
// 
// Path: src/main/java/ru/shadam/tarantool/core/mapping/TarantoolMappingContext.java
// public class TarantoolMappingContext extends AbstractMappingContext<TarantoolPersistentEntity<?>, TarantoolPersistentProperty> {
//     private KeySpaceResolver fallbackKeySpaceResolver;
// 
//     public void setFallbackKeySpaceResolver(KeySpaceResolver fallbackKeySpaceResolver) {
//         this.fallbackKeySpaceResolver = fallbackKeySpaceResolver;
//     }
// 
//     @Override
//     public TarantoolPersistentEntity<?> getPersistentEntity(Class<?> type) {
//         return super.getPersistentEntity(type);
//     }
// 
//     @Override
//     public TarantoolPersistentEntity<?> getPersistentEntity(TypeInformation<?> type) {
//         return super.getPersistentEntity(type);
// 
//     }
// 
//     @Override
//     protected <T> TarantoolPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
//         return new BasicTarantoolPersistentEntity<>(typeInformation, fallbackKeySpaceResolver);
//     }
// 
//     @Override
//     protected TarantoolPersistentPropertyImpl createPersistentProperty(Field field,
//                                                                        PropertyDescriptor descriptor,
//                                                                        TarantoolPersistentEntity<?> owner,
//                                                                        SimpleTypeHolder simpleTypeHolder) {
//         return new TarantoolPersistentPropertyImpl(field, descriptor, owner, simpleTypeHolder);
//     }
// }
// 
// Path: src/main/java/ru/shadam/tarantool/core/mapping/TarantoolPersistentEntity.java
// public interface TarantoolPersistentEntity<T>  extends MutablePersistentEntity<T, TarantoolPersistentProperty> {
//     String getSpaceName();
// }
// 
// Path: src/main/java/ru/shadam/tarantool/core/mapping/TarantoolPersistentProperty.java
// public interface TarantoolPersistentProperty extends PersistentProperty<TarantoolPersistentProperty> {
//     OptionalInt getTupleIndex();
// 
//     Optional<String> getSpaceIndexName();
// }
// 
// Path: src/main/java/ru/shadam/tarantool/repository/query/TarantoolQuery.java
// public class TarantoolQuery {
//     private String key;
//     private Object value;
// 
//     public TarantoolQuery(String key, Object value) {
//         this.key = key;
//         this.value = value;
//     }
// 
//     public String getKey() {
//         return key;
//     }
// 
//     public Object getValue() {
//         return value;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         final TarantoolQuery that = (TarantoolQuery) o;
// 
//         if (key != null ? !key.equals(that.key) : that.key != null) return false;
//         return value != null ? value.equals(that.value) : that.value == null;
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = key != null ? key.hashCode() : 0;
//         result = 31 * result + (value != null ? value.hashCode() : 0);
//         return result;
//     }
// 
// 
//     @Override
//     public String toString() {
//         return "TarantoolQuery{" +
//                 "key='" + key + '\'' +
//                 ", value=" + value +
//                 '}';
//     }
// }


import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Sort;
import org.springframework.data.keyvalue.core.KeyValueCallback;
import org.springframework.data.keyvalue.core.KeyValueOperations;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import ru.shadam.tarantool.core.convert.TarantoolConverter;
import ru.shadam.tarantool.core.convert.TarantoolData;
import ru.shadam.tarantool.core.mapping.TarantoolMappingContext;
import ru.shadam.tarantool.core.mapping.TarantoolPersistentEntity;
import ru.shadam.tarantool.core.mapping.TarantoolPersistentProperty;
import ru.shadam.tarantool.repository.query.TarantoolQuery;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
package ru.shadam.tarantool.core;



/**
 * @author sala
 */
public class TarantoolKeyValueTemplate implements KeyValueOperations {
    // for exception translation
    private final TarantoolOps tarantoolOps;
    private final TarantoolMappingContext mappingContext;
    private final TarantoolConverter converter;
//    private final QueryEngine<? extends KeyValueAdapter, ?, ?> engine;

    public TarantoolKeyValueTemplate(TarantoolOps tarantoolOps, TarantoolMappingContext mappingContext, TarantoolConverter converter) {
        this.tarantoolOps = tarantoolOps;
        this.mappingContext = mappingContext;
        this.converter = converter;
    }

    @Override
    public <T> T insert(T objectToInsert) {
        Assert.notNull(objectToInsert, "Object to be inserted must not be null!");

        Class<?> objectClass = objectToInsert.getClass();
        String keyspace = resolveKeySpace(objectClass);

// Path: src/main/java/ru/shadam/tarantool/core/convert/TarantoolConverter.java
// public interface TarantoolConverter
//         extends EntityConverter<TarantoolPersistentEntity<?>, TarantoolPersistentProperty, Object, TarantoolData> {
// 
//     void removePrimaryKey(Object source, TarantoolData sink);
// }
// 
// Path: src/main/java/ru/shadam/tarantool/core/convert/TarantoolData.java
// public class TarantoolData {
//     private Object id;
// 
//     private Tuple tuple;
// 
//     public TarantoolData() {
//         this.tuple = new Tuple();
//     }
// 
//     public TarantoolData(Tuple tuple) {
//         this.tuple = tuple;
//     }
// 
//     public Object getId() {
//         return id;
//     }
// 
//     public void setId(Object id) {
//         this.id = id;
//     }
// 
// 
//     @Override
//     public String toString() {
//         return "TarantoolData{" +
//                 ", id=" + id +
//                 ", tuple=" + tuple +
//                 '}';
//     }
// 
//     public Tuple getTuple() {
//         return tuple;
//     }
// }
// 
// Path: src/main/java/ru/shadam/tarantool/core/mapping/TarantoolMappingContext.java
// public class TarantoolMappingContext extends AbstractMappingContext<TarantoolPersistentEntity<?>, TarantoolPersistentProperty> {
//     private KeySpaceResolver fallbackKeySpaceResolver;
// 
//     public void setFallbackKeySpaceResolver(KeySpaceResolver fallbackKeySpaceResolver) {
//         this.fallbackKeySpaceResolver = fallbackKeySpaceResolver;
//     }
// 
//     @Override
//     public TarantoolPersistentEntity<?> getPersistentEntity(Class<?> type) {
//         return super.getPersistentEntity(type);
//     }
// 
//     @Override
//     public TarantoolPersistentEntity<?> getPersistentEntity(TypeInformation<?> type) {
//         return super.getPersistentEntity(type);
// 
//     }
// 
//     @Override
//     protected <T> TarantoolPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
//         return new BasicTarantoolPersistentEntity<>(typeInformation, fallbackKeySpaceResolver);
//     }
// 
//     @Override
//     protected TarantoolPersistentPropertyImpl createPersistentProperty(Field field,
//                                                                        PropertyDescriptor descriptor,
//                                                                        TarantoolPersistentEntity<?> owner,
//                                                                        SimpleTypeHolder simpleTypeHolder) {
//         return new TarantoolPersistentPropertyImpl(field, descriptor, owner, simpleTypeHolder);
//     }
// }
// 
// Path: src/main/java/ru/shadam/tarantool/core/mapping/TarantoolPersistentEntity.java
// public interface TarantoolPersistentEntity<T>  extends MutablePersistentEntity<T, TarantoolPersistentProperty> {
//     String getSpaceName();
// }
// 
// Path: src/main/java/ru/shadam/tarantool/core/mapping/TarantoolPersistentProperty.java
// public interface TarantoolPersistentProperty extends PersistentProperty<TarantoolPersistentProperty> {
//     OptionalInt getTupleIndex();
// 
//     Optional<String> getSpaceIndexName();
// }
// 
// Path: src/main/java/ru/shadam/tarantool/repository/query/TarantoolQuery.java
// public class TarantoolQuery {
//     private String key;
//     private Object value;
// 
//     public TarantoolQuery(String key, Object value) {
//         this.key = key;
//         this.value = value;
//     }
// 
//     public String getKey() {
//         return key;
//     }
// 
//     public Object getValue() {
//         return value;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         final TarantoolQuery that = (TarantoolQuery) o;
// 
//         if (key != null ? !key.equals(that.key) : that.key != null) return false;
//         return value != null ? value.equals(that.value) : that.value == null;
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = key != null ? key.hashCode() : 0;
//         result = 31 * result + (value != null ? value.hashCode() : 0);
//         return result;
//     }
// 
// 
//     @Override
//     public String toString() {
//         return "TarantoolQuery{" +
//                 "key='" + key + '\'' +
//                 ", value=" + value +
//                 '}';
//     }
// }


// Path: src/main/java/ru/shadam/tarantool/core/TarantoolKeyValueTemplate.java
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Sort;
import org.springframework.data.keyvalue.core.KeyValueCallback;
import org.springframework.data.keyvalue.core.KeyValueOperations;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import ru.shadam.tarantool.core.convert.TarantoolConverter;
import ru.shadam.tarantool.core.convert.TarantoolData;
import ru.shadam.tarantool.core.mapping.TarantoolMappingContext;
import ru.shadam.tarantool.core.mapping.TarantoolPersistentEntity;
import ru.shadam.tarantool.core.mapping.TarantoolPersistentProperty;
import ru.shadam.tarantool.repository.query.TarantoolQuery;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

package ru.shadam.tarantool.core;



/**
 * @author sala
 */
public class TarantoolKeyValueTemplate implements KeyValueOperations {
    // for exception translation
    private final TarantoolOps tarantoolOps;
    private final TarantoolMappingContext mappingContext;
    private final TarantoolConverter converter;
//    private final QueryEngine<? extends KeyValueAdapter, ?, ?> engine;

    public TarantoolKeyValueTemplate(TarantoolOps tarantoolOps, TarantoolMappingContext mappingContext, TarantoolConverter converter) {
        this.tarantoolOps = tarantoolOps;
        this.mappingContext = mappingContext;
        this.converter = converter;
    }

    @Override
    public <T> T insert(T objectToInsert) {
        Assert.notNull(objectToInsert, "Object to be inserted must not be null!");

        Class<?> objectClass = objectToInsert.getClass();
        String keyspace = resolveKeySpace(objectClass);

        TarantoolData tdo = maybeConvert(objectToInsert);