Skip to content
Open
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
1 change: 1 addition & 0 deletions tarantool-spring-data/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<module>tarantool-spring-data-33</module>
<module>tarantool-spring-data-34</module>
<module>tarantool-spring-data-35</module>
<module>tarantool-spring-data-40</module>
</modules>

<properties>
Expand Down
36 changes: 36 additions & 0 deletions tarantool-spring-data/tarantool-spring-data-40/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<name>tarantool-spring-data-40</name>
<description>Minimalistic java connector for Tarantool versions 2.11+ based on Netty framework</description>
<url>https://tarantool.io</url>

<parent>
<groupId>io.tarantool</groupId>
<artifactId>tarantool-spring-data</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>

<artifactId>tarantool-spring-data-40</artifactId>
<packaging>jar</packaging>

<properties>
<!--Рекомендованная версия JAVA == 25, минимальная - 17-->
<maven.compiler.release>17</maven.compiler.release>
<spring.boot.version>4.0.4</spring.boot.version>
<shared.dir>${project.parent.parent.basedir}/tarantool-shared-resources/</shared.dir>
<license.header.file>${project.parent.parent.basedir}/LICENSE_HEADER.txt</license.header.file>
<!-- Spring framework 7.x перешел на 6 версию -->
<junit.version>6.0.3</junit.version>
</properties>

<dependencies>
<dependency>
<groupId>io.tarantool</groupId>
<artifactId>tarantool-spring-data-core</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2025 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY
* All Rights Reserved.
*/

package io.tarantool.spring.data40;

import java.util.Map;

import org.jspecify.annotations.NonNull;
import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter;
import org.springframework.data.util.CloseableIterator;

import io.tarantool.client.box.TarantoolBoxClient;
import io.tarantool.spring.data.ProxyTarantoolBoxKeyValueAdapter;

public class TarantoolBoxKeyValueAdapter extends AbstractKeyValueAdapter {

private final ProxyTarantoolBoxKeyValueAdapter adapter;

public TarantoolBoxKeyValueAdapter(@NonNull TarantoolBoxClient tarantoolBoxClient) {
adapter = new ProxyTarantoolBoxKeyValueAdapter(tarantoolBoxClient);
}

@Override
public Object put(@NonNull Object id, @NonNull Object item, @NonNull String keyspace) {
return adapter.put(id, item, keyspace);
}

@Override
public boolean contains(@NonNull Object id, @NonNull String keyspace) {
return adapter.contains(id, keyspace);
}

@Override
public Object get(@NonNull Object id, @NonNull String keyspace) {
return adapter.get(id, keyspace);
}

@Override
public Object delete(@NonNull Object id, @NonNull String keyspace) {
return adapter.delete(id, keyspace);
}

@Override
@NonNull
public Iterable<Object> getAllOf(@NonNull String keyspace) {
return adapter.getAllOf(keyspace);
}

@Override
public void deleteAllOf(@NonNull String keyspace) {
adapter.deleteAllOf(keyspace);
}

@Override
public void clear() {
adapter.clear();
}

@Override
public long count(@NonNull String keyspace) {
return adapter.count(keyspace);
}

@Override
public void destroy() throws Exception {
adapter.destroy();
}

@Override
@NonNull
public CloseableIterator<Map.Entry<Object, Object>> entries(@NonNull String keyspace) {
throw new UnsupportedOperationException("Not implemented yet");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright (c) 2025 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY
* All Rights Reserved.
*/

package io.tarantool.spring.data40;

import java.util.Collections;
import java.util.Map.Entry;

import com.fasterxml.jackson.annotation.JsonFormat;
import org.jspecify.annotations.NonNull;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter;
import org.springframework.data.util.CloseableIterator;

import io.tarantool.client.crud.TarantoolCrudClient;
import io.tarantool.spring.data.ProxyTarantoolCrudKeyValueAdapter;
import io.tarantool.spring.data.mapping.model.CompositeKey;

public class TarantoolCrudKeyValueAdapter extends AbstractKeyValueAdapter {

private final ProxyTarantoolCrudKeyValueAdapter adapter;

public TarantoolCrudKeyValueAdapter(@NonNull TarantoolCrudClient client) {
super(new TarantoolQueryEngine(client));
this.adapter = new ProxyTarantoolCrudKeyValueAdapter(client);
}

@Override
public Object put(@NonNull Object id, @NonNull Object item, @NonNull String keyspace) {
return adapter.put(convertId(id), item, keyspace);
}

@Override
public boolean contains(@NonNull Object id, @NonNull String keyspace) {
return adapter.contains(convertId(id), keyspace);
}

@Override
public Object get(@NonNull Object id, @NonNull String keyspace) {
return adapter.get(convertId(id), keyspace);
}

@Override
public <T> T get(@NonNull Object id, @NonNull String keyspace, @NonNull Class<T> type) {
return adapter.get(convertId(id), keyspace, type);
}

@Override
public Object delete(@NonNull Object id, @NonNull String keyspace) {
return adapter.delete(convertId(id), keyspace);
}

@Override
public <T> T delete(@NonNull Object id, @NonNull String keyspace, @NonNull Class<T> type) {
return adapter.delete(convertId(id), keyspace, type);
}

@Override
@NonNull
public Iterable<Object> getAllOf(@NonNull String keyspace) {
return adapter.getAllOf(keyspace);
}

@Override
public void deleteAllOf(String keyspace) {
adapter.deleteAllOf(keyspace);
}

@Override
public void clear() {
adapter.clear();
}

@Override
public void destroy() throws Exception {
adapter.destroy();
}

@Override
public long count(String keyspace) {
return adapter.count(keyspace);
}

@Override
public CloseableIterator<Entry<Object, Object>> entries(String keyspace) {
throw new UnsupportedOperationException("Not implemented yet");
}

/**
* Convert the identifier to the form required by the tarantool-java-sdk driver.
*
* @param id identifier object
* @return identifier in the required form
*/
private Object convertId(Object id) {
if (id instanceof CompositeKey || hasJsonFormatArrayAnnotation(id)) {
return id;
}
return Collections.singletonList(id);
}

/**
* Determine whether the identifier type is annotated with the {@link JsonFormat} annotation.
*
* @param id identifier object
* @return return true if the annotation is present, false otherwise
*/
private boolean hasJsonFormatArrayAnnotation(Object id) {
final JsonFormat jsonFormatAnnotation =
AnnotatedElementUtils.findMergedAnnotation(id.getClass(), JsonFormat.class);

return jsonFormatAnnotation != null
&& JsonFormat.Shape.ARRAY.equals(jsonFormatAnnotation.shape());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2025 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY
* All Rights Reserved.
*/

package io.tarantool.spring.data40;

import java.util.Collection;
import java.util.Comparator;
import java.util.Map.Entry;

import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.springframework.data.keyvalue.core.QueryEngine;

import io.tarantool.client.crud.TarantoolCrudClient;
import io.tarantool.spring.data.ProxyTarantoolQueryEngine;
import io.tarantool.spring.data.query.TarantoolCriteria;
import io.tarantool.spring.data40.query.TarantoolCriteriaAccessor;
import io.tarantool.spring.data40.query.TarantoolSortAccessor;

/**
* Implementation of {@code findBy*()} and {@code countBy*{}} queries.
*
* @author Artyom Dubinin
*/
public class TarantoolQueryEngine
extends QueryEngine<TarantoolCrudKeyValueAdapter, TarantoolCriteria, Comparator<Entry<?, ?>>> {

private final ProxyTarantoolQueryEngine engine;

public TarantoolQueryEngine(TarantoolCrudClient client) {
super(new TarantoolCriteriaAccessor(), new TarantoolSortAccessor());
this.engine = new ProxyTarantoolQueryEngine(client);
}

@Override
@NonNull
public Collection<?> execute(
@Nullable final TarantoolCriteria criteria,
@Nullable final Comparator<Entry<?, ?>> sort,
final long offset,
final int rows,
@NonNull final String keyspace) {
return engine.execute(criteria, sort, offset, rows, keyspace);
}

/**
* Construct the final query predicate for Tarantool to execute, from the base query plus any
* paging and sorting.
*
* <p>Variations here allow the base query predicate to be omitted, sorting to be omitted, and
* paging to be omitted.
*
* @param criteria Search criteria, null means match everything
* @param sort Possibly null collation
* @param offset Start point of returned page, -1 if not used
* @param rows Size of page, -1 if not used
* @param keyspace The map name
* @return Results from Tarantool
*/
@Override
@NonNull
public <T> Collection<T> execute(
@Nullable final TarantoolCriteria criteria,
@Nullable final Comparator<Entry<?, ?>> sort,
final long offset,
final int rows,
@NonNull final String keyspace,
@NonNull Class<T> type) {
return engine.execute(criteria, sort, offset, rows, keyspace, type);
}

/**
* Execute {@code countBy*()} queries against a Tarantool space.
*
* @param criteria Predicate to use, not null
* @param keyspace The map name
* @return Results from Tarantool
*/
@Override
public long count(@Nullable final TarantoolCriteria criteria, @NonNull final String keyspace) {
return engine.count(criteria, keyspace);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2025 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY
* All Rights Reserved.
*/

package io.tarantool.spring.data40.config;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_BOX_CLIENT_BEAN_REF;
import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_BOX_KEY_VALUE_ADAPTER_REF;
import io.tarantool.client.box.TarantoolBoxClient;
import io.tarantool.client.factory.TarantoolBoxClientBuilder;
import io.tarantool.spring.data.config.BaseTarantoolBoxConfiguration;
import io.tarantool.spring.data40.TarantoolBoxKeyValueAdapter;
import io.tarantool.spring.data40.config.properties.TarantoolProperties;

@Configuration(proxyBeanMethods = false)
public class TarantoolBoxConfiguration extends BaseTarantoolBoxConfiguration {

public TarantoolBoxConfiguration(
ObjectProvider<TarantoolProperties> properties,
ObjectProvider<TarantoolBoxClientBuilder> tarantoolBoxClientBuilder) {
super(properties.getIfAvailable(), tarantoolBoxClientBuilder.getIfAvailable());
}

@Bean(name = DEFAULT_TARANTOOL_BOX_KEY_VALUE_ADAPTER_REF)
@ConditionalOnMissingBean(TarantoolBoxKeyValueAdapter.class)
public TarantoolBoxKeyValueAdapter tarantoolCrudKeyValueAdapter(
TarantoolBoxClient tarantoolBoxClient) {
return new TarantoolBoxKeyValueAdapter(tarantoolBoxClient);
}

@Bean(name = DEFAULT_TARANTOOL_BOX_CLIENT_BEAN_REF)
@ConditionalOnMissingBean(TarantoolBoxClient.class)
public TarantoolBoxClient tarantoolBoxClient() throws Exception {
return super.tarantoolBoxClient();
}

@Override
public TarantoolBoxClientBuilder getClientBuilder() {
return super.getClientBuilder();
}
}
Loading