diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d90e1bdf..3b16a233 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -63,6 +63,31 @@ jobs: # path: "**/jacoco-unit.exec" # retention-days: 1 + tests-spring-data-41: + runs-on: ubuntu-22.04 + timeout-minutes: 40 + steps: + - uses: actions/checkout@v6 + + - name: Set up JDK 17 + uses: actions/setup-java@v5 + with: + distribution: 'temurin' + java-version: '17' + cache: 'maven' + + # the reactor installs testcontainers-autogen before the testcontainers module + # loads it as a jsonschema2pojo plugin dependency + - name: Build dependencies + run: > + ./mvnw -B -pl tarantool-spring-data/tarantool-spring-data-4 -am install -DskipTests + -Dspring.boot.version=4.1.2 -Dspring-data-keyvalue.version=4.1.2 + + - name: Run Spring Data tests against Spring Boot 4.1.x + run: > + ./mvnw -B -pl tarantool-spring-data/tarantool-spring-data-4 test + -Dspring.boot.version=4.1.2 -Dspring-data-keyvalue.version=4.1.2 + tests-box-integration: runs-on: ubuntu-22.04 strategy: diff --git a/CHANGELOG.md b/CHANGELOG.md index 716d7705..7c872229 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,16 @@ exit code, stdout and stderr are logged and included in the error. Before, the error carried only the empty stdout ("Failed to change the app topology via cartridge CLI: "). +### Spring Data + +- **Breaking:** only Spring Boot 4.x is supported. The `tarantool-spring-data-27`, + `tarantool-spring-data-31`, `-32`, `-33`, `-34` and `-35` modules are removed. + `tarantool-spring-data-40` is renamed to `tarantool-spring-data-4`, now the single artifact. +- **Breaking:** packages are renamed from `io.tarantool.spring.data40.*` to + `io.tarantool.spring4.data.*`. Update imports after upgrading. +- `tarantool-spring-data-4` is built against Spring Boot 4.0.x and unit-tested with 4.0.x and 4.1.x. +- Users staying on Spring Boot 2.7.x or 3.x should keep using tarantool-spring-data 1.7.x. + ## [1.7.3] - 2026-10-30 ### Pool diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md index 9956fe6b..bf779433 100644 --- a/CONTRIBUTE.md +++ b/CONTRIBUTE.md @@ -79,10 +79,8 @@ tarantool-java-sdk (parent POM) ├── tarantool-balancer ├── tarantool-schema ├── tarantool-spring-data - ├── tarantool-spring-data-core - ├── tarantool-spring-data-27 - ├── ... - ├── tarantool-spring-data-35 + ├── tarantool-spring-data-core + └── tarantool-spring-data-4 ├── testcontainers └── jacoco-coverage-aggregate-report ``` diff --git a/documentation/doc-src/pages/spring-data/configuration.en.md b/documentation/doc-src/pages/spring-data/configuration.en.md index c982dec8..f8ec616c 100644 --- a/documentation/doc-src/pages/spring-data/configuration.en.md +++ b/documentation/doc-src/pages/spring-data/configuration.en.md @@ -20,7 +20,7 @@ necessary settings: ```java import io.tarantool.client.factory.TarantoolCrudClientBuilder; import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.spring.data.repository.config.EnableTarantoolRepositories; +import io.tarantool.spring4.data.repository.config.EnableTarantoolRepositories; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -53,7 +53,7 @@ To configure the client through a configuration file (for example, via ```java - import io.tarantool.spring.data.repository.config.EnableTarantoolRepositories; + import io.tarantool.spring4.data.repository.config.EnableTarantoolRepositories; import org.springframework.context.annotation.Configuration; @Configuration diff --git a/documentation/doc-src/pages/spring-data/configuration.md b/documentation/doc-src/pages/spring-data/configuration.md index 8b9df428..b241b73d 100644 --- a/documentation/doc-src/pages/spring-data/configuration.md +++ b/documentation/doc-src/pages/spring-data/configuration.md @@ -20,7 +20,7 @@ title: Конфигурация клиентов ```java import io.tarantool.client.factory.TarantoolCrudClientBuilder; import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.spring.data.repository.config.EnableTarantoolRepositories; +import io.tarantool.spring4.data.repository.config.EnableTarantoolRepositories; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -53,7 +53,7 @@ public class Config { ```java - import io.tarantool.spring.data.repository.config.EnableTarantoolRepositories; + import io.tarantool.spring4.data.repository.config.EnableTarantoolRepositories; import org.springframework.context.annotation.Configuration; @Configuration diff --git a/documentation/doc-src/pages/spring-data/index.en.md b/documentation/doc-src/pages/spring-data/index.en.md index 58206855..ee2c753e 100644 --- a/documentation/doc-src/pages/spring-data/index.en.md +++ b/documentation/doc-src/pages/spring-data/index.en.md @@ -28,20 +28,15 @@ using [Tarantool](https://www.tarantool.io) as a data store. | 1.5.x | 1.5.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.11 | | 1.6.x | 1.6.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.13 / 3.5.8 | | 1.7.x | 1.7.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.13 / 3.5.16 / 4.0.9 | +| 2.0.x | 2.0.x | 4.0.x / 4.1.x | -Choose the module by the Spring Boot minor line of your application. The table above lists the -Spring Boot versions each module is built and tested with; other patch versions of the same line are -not tested in CI, and newer minor lines are not tested at all. +The `tarantool-spring-data-4` module supports Spring Boot 4.x. CI builds it against 4.0.x and +runs unit tests with 4.0.x and 4.1.x. Its packages carry the Spring major version +(`io.tarantool.spring4.data`), so future Spring Data majors can be supported alongside. -| Spring Boot line | Module | -|:----------------:|:---------------------------:| -| 2.7.x | `tarantool-spring-data-27` | -| 3.1.x | `tarantool-spring-data-31` | -| 3.2.x | `tarantool-spring-data-32` | -| 3.3.x | `tarantool-spring-data-33` | -| 3.4.x | `tarantool-spring-data-34` | -| 3.5.x | `tarantool-spring-data-35` | -| 4.0.x | `tarantool-spring-data-40` | +| Spring Boot line | Module | +|:----------------:|:--------------------------:| +| 4.0.x / 4.1.x | `tarantool-spring-data-4` | ### Tarantool Version and Supported Client Modules @@ -119,7 +114,7 @@ Include the module in your project as follows: io.tarantool - tarantool-spring-data-40 + tarantool-spring-data-4 ${tarantool-spring-data.version} diff --git a/documentation/doc-src/pages/spring-data/index.md b/documentation/doc-src/pages/spring-data/index.md index a05016d6..64119ced 100644 --- a/documentation/doc-src/pages/spring-data/index.md +++ b/documentation/doc-src/pages/spring-data/index.md @@ -28,20 +28,16 @@ hide: | 1.5.x | 1.5.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.11 | | 1.6.x | 1.6.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.13 / 3.5.8 | | 1.7.x | 1.7.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.13 / 3.5.16 / 4.0.9 | +| 2.0.x | 2.0.x | 4.0.x / 4.1.x | -Модуль выбирается по минорной линии Spring Boot приложения. В таблице выше — версии Spring Boot, с -которыми модули собраны и протестированы; другие патч-версии той же линии в CI не проверяются, более -новые минорные линии не проверяются вовсе. +Модуль `tarantool-spring-data-4` поддерживает Spring Boot 4.x. В CI он собирается против 4.0.x и +прогоняет unit-тесты с 4.0.x и 4.1.x. Пакеты содержат мажорную версию Spring +(`io.tarantool.spring4.data`), поэтому будущие мажорные версии Spring Data можно поддерживать +параллельно. | Линия Spring Boot | Модуль | |:-----------------:|:---------------------------:| -| 2.7.x | `tarantool-spring-data-27` | -| 3.1.x | `tarantool-spring-data-31` | -| 3.2.x | `tarantool-spring-data-32` | -| 3.3.x | `tarantool-spring-data-33` | -| 3.4.x | `tarantool-spring-data-34` | -| 3.5.x | `tarantool-spring-data-35` | -| 4.0.x | `tarantool-spring-data-40` | +| 4.0.x / 4.1.x | `tarantool-spring-data-4` | ### Версия Tarantool и поддерживаемые модули-клиенты @@ -119,7 +115,7 @@ Tarantool можно найти io.tarantool - tarantool-spring-data-40 + tarantool-spring-data-4 ${tarantool-spring-data.version} diff --git a/tarantool-java-sdk-bom/pom.xml b/tarantool-java-sdk-bom/pom.xml index 171f1827..4bd7e1db 100644 --- a/tarantool-java-sdk-bom/pom.xml +++ b/tarantool-java-sdk-bom/pom.xml @@ -117,6 +117,11 @@ tarantool-spring-data-core ${project.version} + + io.tarantool + tarantool-spring-data-4 + ${project.version} + io.tarantool testcontainers diff --git a/tarantool-spring-data/README.md b/tarantool-spring-data/README.md index 50842bf3..68895a78 100644 --- a/tarantool-spring-data/README.md +++ b/tarantool-spring-data/README.md @@ -30,20 +30,13 @@ data storage. | 1.5.x | 1.5.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.11 | | 1.6.x | 1.6.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.13 / 3.5.8 | | 1.7.x | 1.7.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.13 / 3.5.16 / 4.0.9 | +| 2.0.x | 2.0.x | 4.0.x / 4.1.x | -Choose the module by the Spring Boot minor line of your application. The table above lists the -Spring Boot versions each module is built and tested with; other patch versions of the same line are -not tested in CI, and newer minor lines are not tested at all. +The `tarantool-spring-data-4` module supports Spring Boot 4.x. -| Spring Boot line | Module | -|:----------------:|:---------------------------:| -| 2.7.x | `tarantool-spring-data-27` | -| 3.1.x | `tarantool-spring-data-31` | -| 3.2.x | `tarantool-spring-data-32` | -| 3.3.x | `tarantool-spring-data-33` | -| 3.4.x | `tarantool-spring-data-34` | -| 3.5.x | `tarantool-spring-data-35` | -| 4.0.x | `tarantool-spring-data-40` | +| Spring Boot line | Module | +|:----------------:|:--------------------------:| +| 4.0.x / 4.1.x | `tarantool-spring-data-4` | ### Tarantool Version and Supported Client Modules @@ -96,11 +89,12 @@ CRUD operations of the > which are not available in TDG. Using a `Repository` with a TDG connection fails with > `BoxError{code=33, message='Procedure 'crud.select' is not defined'}`. -> [!IMPORTANT] -> #### Spring Data 3.4.x -> Verified operation of -> [repository fragments SPI](https://github.com/spring-projects/spring-data-commons/wiki/Spring-Data-2024.1-Release-Notes#repository-fragments-spi). -> Additional information [here](https://github.com/spring-projects/spring-data-commons/pull/3093). +> [!IMPORTANT] +> #### Repository fragments +> The +> [repository fragments SPI](https://github.com/spring-projects/spring-data-commons/wiki/Spring-Data-2024.1-Release-Notes#repository-fragments-spi) +> is supported. Additional information +> [here](https://github.com/spring-projects/spring-data-commons/pull/3093). ## Getting Started with Spring Data Tarantool diff --git a/tarantool-spring-data/pom.xml b/tarantool-spring-data/pom.xml index e7aee152..f76a19ba 100644 --- a/tarantool-spring-data/pom.xml +++ b/tarantool-spring-data/pom.xml @@ -18,13 +18,7 @@ tarantool-spring-data-core - tarantool-spring-data-27 - tarantool-spring-data-31 - tarantool-spring-data-32 - tarantool-spring-data-33 - tarantool-spring-data-34 - tarantool-spring-data-35 - tarantool-spring-data-40 + tarantool-spring-data-4 @@ -32,8 +26,10 @@ 2.0.20 1.5.32 5.14.4 - - 2.7.18 + + 4.0.9 + 4.0.8 ${project.parent.basedir}/LICENSE_HEADER.txt @@ -74,7 +70,7 @@ org.springframework.data spring-data-keyvalue - ${spring.boot.version} + ${spring-data-keyvalue.version} diff --git a/tarantool-spring-data/tarantool-spring-data-27/pom.xml b/tarantool-spring-data/tarantool-spring-data-27/pom.xml deleted file mode 100644 index 2f4dfd8b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/pom.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - 4.0.0 - - tarantool-spring-data-27 - Minimalistic java connector for Tarantool versions 2.11+ based on Netty framework - https://tarantool.io - - - io.tarantool - tarantool-spring-data - 2.0.0-SNAPSHOT - - - tarantool-spring-data-27 - 2.0.0-SNAPSHOT - jar - - - ${project.parent.parent.basedir}/tarantool-shared-resources/ - ${project.parent.parent.basedir}/LICENSE_HEADER.txt - 2.7.18 - - 1.2.13 - - 1.7.36 - - - - - - org.slf4j - slf4j-api - ${slf4j.api.version} - - - ch.qos.logback - logback-classic - ${logback.version} - test - - - io.tarantool - tarantool-spring-data-core - - - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - 2.13.5 - test - - - diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/TarantoolBoxKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/TarantoolBoxKeyValueAdapter.java deleted file mode 100644 index a4814582..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/TarantoolBoxKeyValueAdapter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27; - -import java.util.Map; - -import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.NonNull; - -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(Object id, Object item, String keyspace) { - return adapter.put(id, item, keyspace); - } - - @Override - public boolean contains(Object id, String keyspace) { - return adapter.contains(id, keyspace); - } - - @Override - public Object get(Object id, String keyspace) { - return adapter.get(id, keyspace); - } - - @Override - public Object delete(Object id, String keyspace) { - return adapter.delete(id, keyspace); - } - - @Override - public Iterable getAllOf(String keyspace) { - return adapter.getAllOf(keyspace); - } - - @Override - public void deleteAllOf(String keyspace) { - adapter.deleteAllOf(keyspace); - } - - @Override - public void clear() { - adapter.clear(); - } - - @Override - public long count(String keyspace) { - return adapter.count(keyspace); - } - - @Override - public void destroy() throws Exception { - adapter.destroy(); - } - - @Override - public CloseableIterator> entries(String keyspace) { - throw new UnsupportedOperationException("Not implemented yet"); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/TarantoolCrudKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/TarantoolCrudKeyValueAdapter.java deleted file mode 100644 index 827cba40..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/TarantoolCrudKeyValueAdapter.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27; - -import java.util.Collections; -import java.util.Map.Entry; - -import com.fasterxml.jackson.annotation.JsonFormat; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.NonNull; - -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(Object id, Object item, String keyspace) { - return adapter.put(convertId(id), item, keyspace); - } - - @Override - public boolean contains(Object id, String keyspace) { - return adapter.contains(convertId(id), keyspace); - } - - @Override - public Object get(Object id, String keyspace) { - return adapter.get(convertId(id), keyspace); - } - - @Override - public T get(Object id, String keyspace, Class type) { - return adapter.get(convertId(id), keyspace, type); - } - - @Override - public Object delete(Object id, String keyspace) { - return adapter.delete(convertId(id), keyspace); - } - - @Override - public T delete(Object id, String keyspace, Class type) { - return adapter.delete(convertId(id), keyspace, type); - } - - @Override - public Iterable getAllOf(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> 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()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/TarantoolQueryEngine.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/TarantoolQueryEngine.java deleted file mode 100644 index 7f68bce3..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/TarantoolQueryEngine.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27; - -import java.util.Collection; -import java.util.Comparator; -import java.util.Map.Entry; - -import org.springframework.data.keyvalue.core.QueryEngine; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.ProxyTarantoolQueryEngine; -import io.tarantool.spring.data.query.TarantoolCriteria; -import io.tarantool.spring.data27.query.TarantoolCriteriaAccessor; -import io.tarantool.spring.data27.query.TarantoolSortAccessor; - -/** - * Implementation of {@code findBy*()} and {@code countBy*{}} queries. - * - * @author Artyom Dubinin - */ -public class TarantoolQueryEngine - extends QueryEngine>> { - - 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> 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. - * - *

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 Collection execute( - @Nullable final TarantoolCriteria criteria, - @Nullable final Comparator> sort, - final long offset, - final int rows, - @NonNull final String keyspace, - @NonNull Class 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); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/config/TarantoolCrudConfiguration.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/config/TarantoolCrudConfiguration.java deleted file mode 100644 index b285c0fa..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/config/TarantoolCrudConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.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_CRUD_CLIENT_BEAN_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.spring.data.config.BaseTarantoolCrudConfiguration; -import io.tarantool.spring.data27.TarantoolCrudKeyValueAdapter; -import io.tarantool.spring.data27.config.properties.TarantoolProperties; - -@Configuration(proxyBeanMethods = false) -public class TarantoolCrudConfiguration extends BaseTarantoolCrudConfiguration { - - public TarantoolCrudConfiguration( - ObjectProvider properties, - ObjectProvider tarantoolClientConfiguration) { - super(properties.getIfAvailable(), tarantoolClientConfiguration.getIfAvailable()); - } - - @Bean(name = DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF) - @ConditionalOnMissingBean(TarantoolCrudKeyValueAdapter.class) - public TarantoolCrudKeyValueAdapter tarantoolCrudKeyValueAdapter( - TarantoolCrudClient tarantoolCrudClient) { - return new TarantoolCrudKeyValueAdapter(tarantoolCrudClient); - } - - @Bean(name = DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF) - @ConditionalOnMissingBean(TarantoolCrudClient.class) - public TarantoolCrudClient tarantoolCrudClient() throws Exception { - return super.tarantoolCrudClient(); - } - - public TarantoolCrudClientBuilder getClientBuilder() { - return super.getClientBuilder(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/config/package-info.java deleted file mode 100644 index a3414471..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/config/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Config package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data27.config; diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/TarantoolTemplate.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/TarantoolTemplate.java deleted file mode 100644 index 1e196048..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/TarantoolTemplate.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.core; - -import org.springframework.data.keyvalue.core.IdentifierGenerator; -import org.springframework.data.keyvalue.core.KeyValueAdapter; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.util.ClassUtils; - -import io.tarantool.spring.data27.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data27.core.mapping.TarantoolMappingContext; - -public class TarantoolTemplate extends KeyValueTemplate { - - public TarantoolTemplate(KeyValueAdapter adapter) { - super(adapter, new TarantoolMappingContext<>()); - } - - public TarantoolTemplate( - KeyValueAdapter adapter, - MappingContext< - ? extends KeyValuePersistentEntity, ? extends KeyValuePersistentProperty> - mappingContext) { - super(adapter, mappingContext); - } - - public TarantoolTemplate( - KeyValueAdapter adapter, - MappingContext< - ? extends KeyValuePersistentEntity, ? extends KeyValuePersistentProperty> - mappingContext, - IdentifierGenerator identifierGenerator) { - super(adapter, mappingContext, identifierGenerator); - } - - @Override - public T insert(T objectToInsert) { - if (DefaultIdClassResolver.INSTANCE.resolveIdClassType(objectToInsert.getClass()) == null) { - return super.insert(objectToInsert); - } - - PersistentEntity entity = - getMappingContext().getRequiredPersistentEntity(ClassUtils.getUserClass(objectToInsert)); - - IdentifierAccessor identifierAccessor = entity.getIdentifierAccessor(objectToInsert); - Object id = identifierAccessor.getRequiredIdentifier(); - return insert(id, objectToInsert); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/annotation/DefaultIdClassResolver.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/annotation/DefaultIdClassResolver.java deleted file mode 100644 index 69aaf7d1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/annotation/DefaultIdClassResolver.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.core.annotation; - -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.core.annotation.IdClassResolver; - -/** Default implementation of {@link IdClassResolver}. */ -public enum DefaultIdClassResolver implements IdClassResolver { - INSTANCE; - - public static final String ANNOTATION_TYPE_EXCEPTION = - "The class of a composite identifier specified in the @IdClass annotation cannot be" - + " annotation!"; - - @Nullable - @Override - public Class resolveIdClassType(Class type) { - Assert.notNull(type, "Type for IdClass must be not null!"); - - IdClass idClassTypeAnnotation = AnnotatedElementUtils.findMergedAnnotation(type, IdClass.class); - - if (idClassTypeAnnotation == null) { - return null; - } - - Class idClassTypeValue = idClassTypeAnnotation.value(); - Assert.isTrue(!idClassTypeValue.isAnnotation(), ANNOTATION_TYPE_EXCEPTION); - - return idClassTypeValue; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/annotation/package-info.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/annotation/package-info.java deleted file mode 100644 index e49b1a90..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/annotation/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Core annotations of data mapping. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data27.core.annotation; diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/BasicKeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/BasicKeyValueCompositePersistentEntity.java deleted file mode 100644 index 2e44c76b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/BasicKeyValueCompositePersistentEntity.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.core.mapping; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.data.domain.Persistable; -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.support.IsNewStrategy; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.mapping.model.CompositeKey; -import io.tarantool.spring.data27.core.mapping.model.CompositeIdPropertyAccessor; -import io.tarantool.spring.data27.core.mapping.model.PersistentCompositeIdIsNewStrategy; - -public class BasicKeyValueCompositePersistentEntity> - extends BasicKeyValuePersistentEntity implements KeyValueCompositePersistentEntity { - - public static final String TYPE_MISMATCH = - "Target bean of type %s is not of type of the persistent entity (%s)"; - - private final Class idClassTypeValue; - private @Nullable P idProperty; - - private Map entityIdClassFields; - - /** - * @param information must not be {@literal null}. - * @param fallbackKeySpaceResolver can be {@literal null}. - * @param idClassTypeValue class that specified in {@link IdClass} - */ - public BasicKeyValueCompositePersistentEntity( - TypeInformation information, - @Nullable KeySpaceResolver fallbackKeySpaceResolver, - Class idClassTypeValue) { - super(information, fallbackKeySpaceResolver); - - Assert.notNull(idClassTypeValue, "idClassTypeValue must be not null for this class!"); - this.idClassTypeValue = idClassTypeValue; - } - - @Override - public IdentifierAccessor getIdentifierAccessor(Object bean) { - verifyBeanType(bean); - - if (Persistable.class.isAssignableFrom(getType())) { - throw new IllegalArgumentException( - "Persistable override is not currently supported for entities with a composite key."); - } - - return hasIdProperty() - ? new CompositeIdPropertyAccessor(bean, this.entityIdClassFields, getIdClassType()) - : new AbsentIdentifierAccessor(); - } - - @Override - public Class getIdClassType() { - return this.idClassTypeValue; - } - - @Override - public void verify() { - super.verify(); - - if (this.idProperty != null) { - this.entityIdClassFields = KeyPartTypeChecker.getFieldMapIfTypesValid(this, this.idProperty); - } - } - - @Override - protected IsNewStrategy getFallbackIsNewStrategy() { - return PersistentCompositeIdIsNewStrategy.of(this); - } - - @Override - protected P returnPropertyIfBetterIdPropertyCandidateOrNull(P property) { - Assert.isInstanceOf(Identifier.class, property, "property must be Identifier for this class"); - - if (!property.isIdProperty()) { - return null; - } - - if (this.idProperty == null) { - this.idProperty = property; - return this.idProperty; - } - - this.idProperty.addPart(property); - - return this.idProperty; - } - - /** - * Verifies the given bean type to no be {@literal null} and of the type of the current {@link - * PersistentEntity}. - * - * @param bean must not be {@literal null}. - */ - private void verifyBeanType(Object bean) { - - Assert.notNull(bean, "Target bean must not be null"); - Assert.isInstanceOf( - getType(), - bean, - () -> String.format(TYPE_MISMATCH, bean.getClass().getName(), getType().getName())); - } - - /** - * A null-object implementation of {@link IdentifierAccessor} to be able to return an accessor for - * entities that do not have an identifier property. - */ - private static class AbsentIdentifierAccessor implements IdentifierAccessor { - - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.IdentifierAccessor#getIdentifier() - */ - @Override - @Nullable - public Object getIdentifier() { - return null; - } - } - - /** - * A class that checks the types of fields of a composite key. In addition, the correspondence - * between types and field names marked with {@code @Id}. - */ - public static class KeyPartTypeChecker { - - public static final String COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION = - "Number of fields specified in domain class and composite class the key is different!"; - - public static final String COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION = - "Domain class fields marked with @Id differ from fields specified in the composite key" - + " class"; - - /** - * Check the number and types of entity fields, annotated {@code @Id} and fields {@link - * CompositeKey} and if the types and quantities match return the id part fields mapping. - * - * @param persistentEntity persistent entity - * @param idProperty id property - * @return mapping between fields of composite key class and fields annotated {@code @Id} in - * entity. - */ - public static Map getFieldMapIfTypesValid( - KeyValueCompositePersistentEntity persistentEntity, Identifier idProperty) { - Map entityIdClassFields = new HashMap<>(); - - List compositeKeyFields = persistentEntity.getIdClassTypeFields(); - - Field[] entityFields = idProperty.getFields(); - - if (compositeKeyFields.size() != entityFields.length) { - throw new IllegalArgumentException(COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION); - } - - for (int i = 0; i < compositeKeyFields.size(); i++) { - Field compositeKeyField = compositeKeyFields.get(i); - Field entityField = entityFields[i]; - - if (!equalFields(compositeKeyField, entityField)) { - throw new IllegalArgumentException(COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION); - } - - entityIdClassFields.put(entityField, compositeKeyField); - } - return entityIdClassFields; - } - - /** - * Compares two class fields by name and type. - * - * @param firstField first field - * @param secondField second field - * @return true if fields are equal - */ - private static boolean equalFields(Field firstField, Field secondField) { - return firstField.getName().equals(secondField.getName()) - && firstField.getType().equals(secondField.getType()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/Identifier.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/Identifier.java deleted file mode 100644 index 96660102..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/Identifier.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.core.mapping; - -import java.lang.reflect.Field; -import java.util.Collection; - -import org.springframework.data.mapping.PersistentProperty; - -/** The interface of the identifier class that will contain information about the composite key. */ -public interface Identifier

> { - - /** - * Add a {@link PersistentProperty} tagged with {@code Id}. Don't add the current property. - * - * @param property {@link PersistentProperty} tagged {@code Id} - */ - void addPart(P property); - - /** - * Return the parts of a composite key that are {@link PersistentProperty}. - * - * @return parts of a composite key - */ - Collection

getParts(); - - /** - * Return a list {@link Field} of fields that are annotated {@code @Id}. Unlike method {@link - * #getParts()} this method returns an array {@link Field}, where {@link Field} is taken from each - * element of the collection returned by the {@link #getParts()} method. Necessary in order not to - * write polluting code. - * - * @return fields of a composite key - */ - Field[] getFields(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/KeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/KeyValueCompositePersistentEntity.java deleted file mode 100644 index d31d1ef9..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/KeyValueCompositePersistentEntity.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.core.mapping; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.model.MutablePersistentEntity; - -import io.tarantool.spring.data.core.annotation.IdClass; - -/** - * An interface to enable {@link PersistentEntity}-specific operations with a composite key. - * - * @param domain class type - * @param

{@link PersistentProperty} type - */ -public interface KeyValueCompositePersistentEntity> - extends MutablePersistentEntity { - - /** - * Returns the fields of the class specified in the {@link IdClass} annotation. - * - * @return all fields that are in composite key class - */ - default List getIdClassTypeFields() { - List fields = new ArrayList<>(); - - for (Field field : getIdClassType().getDeclaredFields()) { - if (!field.isSynthetic()) { - fields.add(field); - } - } - return fields; - } - - /** - * Returns the type of the class specified in the {@link IdClass} annotation. - * - * @return class that specified in {@link IdClass} - */ - Class getIdClassType(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/KeyValueCompositeProperty.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/KeyValueCompositeProperty.java deleted file mode 100644 index 2e32d2d2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/KeyValueCompositeProperty.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.core.mapping; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; - -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.util.Assert; - -public class KeyValueCompositeProperty

> - extends KeyValuePersistentProperty

implements Identifier

{ - - private final List

identifierPartsWithoutFirst; - - public KeyValueCompositeProperty( - Property property, PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - super(property, owner, simpleTypeHolder); - this.identifierPartsWithoutFirst = new ArrayList<>(); - } - - @Override - public void addPart(P property) { - Assert.notNull(property, "property must be not null"); - - if (equals(property) || this.identifierPartsWithoutFirst.contains(property)) { - return; - } - this.identifierPartsWithoutFirst.add(property); - } - - @Override - @SuppressWarnings("unchecked") - public Collection

getParts() { - List

resultList = new ArrayList<>(this.identifierPartsWithoutFirst); - resultList.add(0, (P) this); - - return resultList; - } - - @Override - public Field[] getFields() { - int totalSize = this.identifierPartsWithoutFirst.size() + 1; - - final Field[] fields = new Field[totalSize]; - fields[0] = getField(); - - for (int i = 1; i < totalSize; i++) { - fields[i] = this.identifierPartsWithoutFirst.get(i - 1).getField(); - } - return fields; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - KeyValueCompositeProperty other = (KeyValueCompositeProperty) o; - - if (this.identifierPartsWithoutFirst.isEmpty() && other.identifierPartsWithoutFirst.isEmpty()) { - return super.equals(o); - } - - if (this.identifierPartsWithoutFirst.size() != other.identifierPartsWithoutFirst.size() - || !other.getProperty().equals(getProperty())) { - return false; - } - - for (int i = 0; i < this.identifierPartsWithoutFirst.size(); i++) { - // take Property from both parts - Property thisKeyPartProperty = - ((KeyValueCompositeProperty) this.identifierPartsWithoutFirst.get(i)).getProperty(); - Property otherKeyPartProperty = - ((KeyValueCompositeProperty) other.identifierPartsWithoutFirst.get(i)).getProperty(); - - if (!thisKeyPartProperty.equals(otherKeyPartProperty)) { - return false; - } - } - return true; - } - - @Override - public int hashCode() { - int hashCode = super.hashCode(); - - if (this.identifierPartsWithoutFirst.isEmpty()) { - return hashCode; - } - - // sublist to avoid endless recursion - return Objects.hash(hashCode, this.identifierPartsWithoutFirst); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/TarantoolMappingContext.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/TarantoolMappingContext.java deleted file mode 100644 index e08a4e97..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/TarantoolMappingContext.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.core.mapping; - -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; - -import io.tarantool.spring.data.core.annotation.IdClassResolver; -import io.tarantool.spring.data27.core.annotation.DefaultIdClassResolver; - -public class TarantoolMappingContext< - E extends KeyValuePersistentEntity, P extends KeyValuePersistentProperty

> - extends KeyValueMappingContext { - - private final IdClassResolver idClassResolver; - - private @Nullable KeySpaceResolver fallbackKeySpaceResolver; - - public TarantoolMappingContext() { - super(); - this.idClassResolver = DefaultIdClassResolver.INSTANCE; - } - - /** - * Configures the {@link KeySpaceResolver} to be used if not explicit key space is annotated to - * the domain type. - * - * @param fallbackKeySpaceResolver can be {@literal null}. - */ - @Override - public void setFallbackKeySpaceResolver(KeySpaceResolver fallbackKeySpaceResolver) { - super.setFallbackKeySpaceResolver(fallbackKeySpaceResolver); - this.fallbackKeySpaceResolver = fallbackKeySpaceResolver; - } - - @SuppressWarnings("unchecked") - @Override - public E createPersistentEntity(TypeInformation typeInformation) { - final Class idClassTypeValue = - this.idClassResolver.resolveIdClassType(typeInformation.getType()); - if (idClassTypeValue == null) { - return (E) - new BasicKeyValuePersistentEntity(typeInformation, this.fallbackKeySpaceResolver); - } - return (E) - new BasicKeyValueCompositePersistentEntity<>( - typeInformation, this.fallbackKeySpaceResolver, idClassTypeValue); - } - - @SuppressWarnings("unchecked") - @Override - public P createPersistentProperty(Property property, E owner, SimpleTypeHolder simpleTypeHolder) { - if (KeyValueCompositePersistentEntity.class.isAssignableFrom(owner.getClass())) { - return (P) new KeyValueCompositeProperty<>(property, owner, simpleTypeHolder); - } - return (P) new KeyValuePersistentProperty<>(property, owner, simpleTypeHolder); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/model/CompositeIdPropertyAccessor.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/model/CompositeIdPropertyAccessor.java deleted file mode 100644 index af6cb4d7..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/model/CompositeIdPropertyAccessor.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.core.mapping.model; - -import java.lang.reflect.Field; -import java.util.Map; - -import org.springframework.data.mapping.TargetAwareIdentifierAccessor; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -/** Class that allows to convert {@code @Id} annotated fields in an entity into a composite key. */ -public class CompositeIdPropertyAccessor extends TargetAwareIdentifierAccessor { - - private final Map entityIdClassFields; - - private final Class idClassType; - - private final Object target; - - public CompositeIdPropertyAccessor( - Object target, @NonNull Map entityIdClassFields, Class idClassType) { - - super(target); - this.target = target; - this.entityIdClassFields = entityIdClassFields; - this.idClassType = idClassType; - } - - @Nullable - public Object getIdentifier() { - try { - return generateIdentifier(); - } catch (InstantiationException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - /** - * Generates a composite identifier from those marked with the {@code @Id} annotation in a domain - * class based on fields, specified in the composite key class. - * - * @return identifier - * @throws IllegalAccessException if the class or its nullary constructor is not accessible. - * @throws InstantiationException if this {@code Class} represents an abstract class, an - * interface, an array class, a primitive type, or void; or if the class has no nullary - * constructor; or if the instantiation fails for some other reason. - */ - private Object generateIdentifier() throws InstantiationException, IllegalAccessException { - Assert.notNull(this.target, "target object must be not null!"); - Object compositeKey = idClassType.newInstance(); - for (Map.Entry fieldPair : this.entityIdClassFields.entrySet()) { - writeValuesFromEntityId(compositeKey, fieldPair.getKey(), fieldPair.getValue()); - } - return compositeKey; - } - - /** - * Write the composite primary key fields provided in the entity to the class which implements - * {@link CompositeKey}. - * - * @param compositeKey object of the composite key into which the values are written. - * @param entityField field from the represented entity. - * @param compositeKeyField field from the composite key class. - */ - private void writeValuesFromEntityId( - Object compositeKey, Field entityField, Field compositeKeyField) { - ReflectionUtils.makeAccessible(entityField); - ReflectionUtils.makeAccessible(compositeKeyField); - - Object value = ReflectionUtils.getField(entityField, this.target); - ReflectionUtils.setField(compositeKeyField, compositeKey, value); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/model/PersistentCompositeIdIsNewStrategy.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/model/PersistentCompositeIdIsNewStrategy.java deleted file mode 100644 index b7fc8ec6..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/model/PersistentCompositeIdIsNewStrategy.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.core.mapping.model; - -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.support.IsNewStrategy; -import org.springframework.util.Assert; - -/** - * Strategy class for entity with composite key to determine whether a given entity is to be - * considered new. - */ -public class PersistentCompositeIdIsNewStrategy implements IsNewStrategy { - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} for the given entity. - * - * @param entity must not be {@literal null}. - * @param idOnly check only id to determine - */ - private PersistentCompositeIdIsNewStrategy(PersistentEntity entity, boolean idOnly) { - // TODO сделать реализацию версионирования - // TODO add idOnly support - Assert.notNull(entity, "PersistentEntity must not be null"); - } - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} to only consider the identifier of the - * given entity. - * - * @param entity must not be {@literal null}. - * @return strategy to determine whether entity is new or not - */ - public static PersistentCompositeIdIsNewStrategy forIdOnly(PersistentEntity entity) { - return new PersistentCompositeIdIsNewStrategy(entity, true); - } - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} to consider version properties before - * falling back to the identifier. - * - * @param entity must not be {@literal null}. - * @return strategy to determine whether entity is new or not - */ - public static PersistentCompositeIdIsNewStrategy of(PersistentEntity entity) { - return new PersistentCompositeIdIsNewStrategy(entity, false); - } - - /** - * Determine whether the current domain entity type object is new. Currently stub and always - * returns false. - * - * @param entity must not be {@literal null}. - * @return result of the question of entity is new or not - */ - @Override - public boolean isNew(Object entity) { - return false; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/model/package-info.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/model/package-info.java deleted file mode 100644 index 8d4898d2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/model/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Core implementation of the mapping subsystem's model. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data27.core.mapping.model; diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/package-info.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/package-info.java deleted file mode 100644 index 1f1d7174..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/mapping/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Base package for the mapping subsystem. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data27.core.mapping; diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/package-info.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/package-info.java deleted file mode 100644 index c6acdd7b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/core/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Core package for integrating Tarantool with Spring - * concepts. - */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data27.core; diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/Field.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/Field.java deleted file mode 100644 index 5ab2a6b0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/Field.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.core.annotation.AliasFor; - -/** - * Allows adding some metadata to the class fields relevant for storing them in the Tarantool space - * - * @author Artyom Dubinin - */ -@Inherited -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) -public @interface Field { - - /** - * The target Tarantool space field for storing the marked class field. Alias for {@link #name()}. - * - * @return the name of a field in space - */ - @AliasFor("name") - String value() default ""; - - /** - * The target Tarantool space field for storing the marked class field. Alias for {@link - * #value()}. - * - * @return the name of a field in space - */ - @AliasFor("value") - String name() default ""; - - /** - * The order in which fields shall be stored in the tuple. Has to be a positive integer. - * - * @return the order the field shall have in the tuple or -1 if undefined. - */ - int order() default -1; -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/PaginationUtils.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/PaginationUtils.java deleted file mode 100644 index fc37636d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/PaginationUtils.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.keyvalue.core.IterableConverter; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class PaginationUtils { - - private static final String CRITERIA_NULL_EXC_MSG = "TarantoolCriteria must be not null"; - - /** - * Returns {@link TarantoolPageable} cast from {@link Pageable} with type checking. - * - * @param sliceParams pageable - * @return {@link TarantoolPageable} - */ - public static TarantoolPageable castToTarantoolPageable(Pageable sliceParams) { - Assert.isInstanceOf(TarantoolPageable.class, sliceParams, "Pageable must be TarantoolPageable"); - return (TarantoolPageable) sliceParams; - } - - /** - * A general method for retrieving data for paginated queries. - * - * @param query query - * @param pageRequest {@link TarantoolPageable} - * @param pageSize page size - * @return selection result. - */ - public static List doPaginationQuery( - final KeyValueQuery query, - TarantoolPageable pageRequest, - int pageSize, - KeyValueOperations keyValueOperations, - Class targetType) { - - TarantoolCriteria criteria = (TarantoolCriteria) query.getCriteria(); - PaginationDirection paginationDirection = pageRequest.getPaginationDirection(); - - Assert.notNull(criteria, CRITERIA_NULL_EXC_MSG); - criteria.withAfter(pageRequest.getTupleCursor()); - - query.setRows(pageSize * paginationDirection.getMultiplier()); - - return IterableConverter.toList(keyValueOperations.find(query, targetType)); - } - - public static Page doPageQuery( - Pageable pageable, - KeyValueQuery query, - KeyValueOperations keyValueOperations, - Class targetType) { - if (pageable.isUnpaged()) { - return new TarantoolPageImpl<>(); - } - TarantoolPageable resultSliceParams = castToTarantoolPageable(pageable); - - int pageSize = resultSliceParams.getPageSize(); - - // non transactional calls - List content = - doPaginationQuery(query, resultSliceParams, pageSize, keyValueOperations, targetType); - - if (content.isEmpty()) { - return new TarantoolPageImpl<>(); - } - - long totalElements = keyValueOperations.count(query, targetType); - return new TarantoolPageImpl<>(content, resultSliceParams, totalElements); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolChunk.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolChunk.java deleted file mode 100644 index a1e852e4..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolChunk.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -/** - * A chunk of data restricted by the configured {@link Pageable} for Tarantool. - * - * @author Nikolay Belonogov - */ -abstract class TarantoolChunk implements Slice, Serializable { - - private static final long serialVersionUID = 867755909294344406L; - - private final List content = new ArrayList<>(); - - private final Pageable pageable; - - /** - * Creates a new {@link TarantoolChunk} with the given content and the given governing {@link - * TarantoolPageable}. - * - * @param content must not be {@literal null}. - * @param pageable must not be {@literal null}. - */ - public TarantoolChunk(List content, Pageable pageable) { - - Assert.notNull(content, "Content must not be null"); - Assert.notNull(pageable, "Pageable must not be null"); - - if (pageable.isPaged() && !(pageable instanceof TarantoolPageable)) { - throw new IllegalArgumentException("Pageable must be TarantoolPageable or Unpaged type"); - } - - this.content.addAll(content); - this.pageable = pageable; - } - - @Override - public boolean isFirst() { - return !hasPrevious(); - } - - @Override - public boolean isLast() { - return !hasNext(); - } - - @Override - public boolean hasPrevious() { - return getNumber() > 0 && hasContent(); - } - - @Override - public boolean hasContent() { - return !content.isEmpty(); - } - - /** - * Returns the {@link Pageable} to request the next {@link Slice}. Can be {@link - * Pageable#unpaged()} in case the current {@link Slice} is already the last one or when data - * content is empty. Clients should check {@link #hasNext()} and {@link #hasContent()} before - * calling this method. - * - * @see #nextOrLastPageable() - */ - @NonNull - @Override - @SuppressWarnings("unchecked") - public Pageable nextPageable() { - if (hasNext() && pageable.isPaged()) { - return ((TarantoolPageable) pageable).next(content.get(content.size() - 1)); - } - return Pageable.unpaged(); - } - - /** - * Returns the {@link Pageable} to request the previous {@link Slice}. Can be {@link - * Pageable#unpaged()} in case the current {@link Slice} is already the first one or data content - * is empty. Clients should check {@link #hasPrevious()} and {@link #hasContent()} before calling - * this method. - * - * @see #previousOrFirstPageable() - */ - @NonNull - @Override - @SuppressWarnings("unchecked") - public Pageable previousPageable() { - if (hasPrevious() && pageable.isPaged()) { - return ((TarantoolPageable) pageable).previousOrFirst(content.get(0)); - } - return Pageable.unpaged(); - } - - @Override - public Iterator iterator() { - return content.iterator(); - } - - @NonNull - @Override - public List getContent() { - return Collections.unmodifiableList(content); - } - - @NonNull - @Override - public Pageable getPageable() { - return pageable; - } - - @NonNull - @Override - public Sort getSort() { - return pageable.getSort(); - } - - @Override - public int getNumber() { - if (pageable.isPaged()) { - return pageable.getPageNumber(); - } - return 0; - } - - @Override - public int getSize() { - if (pageable.isPaged()) { - return pageable.getPageSize(); - } - return content.size(); - } - - @Override - public int getNumberOfElements() { - return content.size(); - } - - /** - * Applies the given {@link Function} to the content of the {@link TarantoolChunk}. - * - * @param converter must not be {@literal null}. - */ - protected List getConvertedContent(Function converter) { - - Assert.notNull(converter, "Function must not be null"); - - return this.stream().map(converter).collect(Collectors.toList()); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolChunk)) { - return false; - } - TarantoolChunk that = (TarantoolChunk) o; - return content.equals(that.content) && pageable.equals(that.pageable); - } - - @Override - public int hashCode() { - return Objects.hash(content, pageable); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolCriteriaAccessor.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolCriteriaAccessor.java deleted file mode 100644 index 00f1143e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolCriteriaAccessor.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import org.springframework.data.keyvalue.core.CriteriaAccessor; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -import io.tarantool.spring.data.query.TarantoolCriteria; - -/** - * Provide a mechanism to convert the abstract query into the direct implementation in Tarantool. - * - * @author Artyom Dubinin - */ -public class TarantoolCriteriaAccessor implements CriteriaAccessor { - - /** - * @param query in Spring form - * @return The same in Tarantool form - */ - public TarantoolCriteria resolve(KeyValueQuery query) { - return (TarantoolCriteria) query.getCriteria(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolPageImpl.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolPageImpl.java deleted file mode 100644 index 3f72b54f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolPageImpl.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.lang.NonNull; - -/** - * Basic {@code Page} implementation for Tarantool. - * - * @param domain class type. - * @author Nikolay Belonogov - */ -class TarantoolPageImpl extends TarantoolChunk implements Page { - - private static final long serialVersionUID = 867755909294344406L; - - private final long total; - - /** - * Creates a new {@link TarantoolPageImpl} with empty content. This will result in the created - * {@link Page} being identical to the entire {@link List}. - */ - public TarantoolPageImpl() { - this(Collections.emptyList(), Pageable.unpaged(), 0L); - } - - /** - * Creates a new {@link TarantoolPageImpl} with the given content. This will result in the created - * {@link Page} being identical to the entire {@link List}. - * - * @param content must not be {@literal null}. - */ - public TarantoolPageImpl(List content) { - this(content, Pageable.unpaged(), content == null ? 0L : content.size()); - } - - /** - * Constructor of {@link TarantoolPageImpl}. - * - * @param content the content of this page, must not be {@literal null}. - * @param pageable the paging information, must not be {@literal null}. - * @param total the total amount of items available. The total might be adapted considering the - * length of the content given, if it is going to be the content of the last page. This is in - * place to mitigate inconsistencies. - */ - public TarantoolPageImpl(List content, Pageable pageable, long total) { - - super(content, pageable); - - this.total = - pageable - .toOptional() - .filter(it -> !content.isEmpty()) - .filter(it -> it.getOffset() + it.getPageSize() > total) - .map(it -> it.getOffset() + content.size()) - .orElse(total); - } - - @Override - public int getTotalPages() { - return getSize() == 0 ? 1 : (int) Math.ceil((double) total / (double) getSize()); - } - - @Override - public long getTotalElements() { - return total; - } - - @Override - public boolean hasNext() { - return getNumber() + 1 < getTotalPages() && hasContent(); - } - - @Override - public boolean isLast() { - return !hasNext(); - } - - @Override - @NonNull - public Page map(@NonNull Function converter) { - return new PageImpl<>(getConvertedContent(converter), getPageable(), total); - } - - @Override - public String toString() { - - List content = getContent(); - boolean canGetContentType = !content.isEmpty() && content.get(0) != null; - - String contentType = canGetContentType ? content.get(0).getClass().getName() : "UNKNOWN"; - - return String.format( - "Page %s of %d containing %s instances", getNumber() + 1, getTotalPages(), contentType); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolPageImpl)) { - return false; - } - if (!super.equals(o)) { - return false; - } - TarantoolPageImpl that = (TarantoolPageImpl) o; - return total == that.total; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), total); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolPageRequest.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolPageRequest.java deleted file mode 100644 index 918af34a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolPageRequest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.util.Objects; - -import org.springframework.data.domain.AbstractPageRequest; -import org.springframework.data.domain.Sort; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; - -/** - * Basic implementation of {@link TarantoolPageable} for Tarantool. - * - *

Important: When specifying a cursor tuple, you must adhere to the following - * rules: - * - *

1. To specify a page starting from the beginning of {@code space} (the first element of the - * page is the first element found in {@code space}), use {@code tupleCursor == null}. - * - *

2. To specify an arbitrary page (the first element of the page is the next/previous one from - * the given one tuple cursor depending on the methods used and page number), use {@code tupleCursor - * == someTupleCursor} . - * - * @param domain entity type - */ -public final class TarantoolPageRequest extends AbstractPageRequest - implements TarantoolPageable { - - private static final long serialVersionUID = -4541509938956089562L; - - private final Sort sort; - - private final T tupleCursor; - - private final PaginationDirection paginationDirection; - - /** - * Creates a new unsorted {@link TarantoolPageRequest} from begin of {@code space}. - * - * @param pageSize the size of the page to be returned, must be greater than 0. - */ - public TarantoolPageRequest(int pageSize) { - this(0, pageSize, null); - } - - /** - * Creates a new unsorted {@link TarantoolPageRequest}. - * - *

Important: Use this method with caution! It is important to know the exact - * match of number pages and the tuple after (before) which the page goes (without including this - * tuple in the page itself). A mistake in compliance results in the appearance of blank pages - * with unpaged pageable even when using methods {@link - * TarantoolPageImpl#previousOrFirstPageable()} / {@link TarantoolPageImpl#nextOrLastPageable()} - * and {@link TarantoolSliceImpl#previousOrFirstPageable()} / {@link - * TarantoolSliceImpl#nextOrLastPageable()}. - * - * @param page zero-based page index (virtual), must not be negative. - * @param size the size of the page to be returned, must be greater than 0. - * @param tupleCursor tuple cursor from which the page count begins. More: {@link - * TarantoolPageRequest}. - */ - public TarantoolPageRequest(int page, int size, T tupleCursor) { - this(page, size, Sort.unsorted(), tupleCursor, FORWARD); - } - - /** - * Private constructor to create an instance with a specific {@link PaginationDirection}. - * - * @param page zero-based page index, must not be negative. - * @param size the size of the page to be returned, must be greater than 0. - * @param sort must not be {@literal null}, use {@link Sort#unsorted()} instead. - * @param tupleCursor tuple cursor from which the page count begins. More: {@link - * TarantoolPageRequest}. - * @param direction direction of pagination. - */ - TarantoolPageRequest( - int page, int size, Sort sort, T tupleCursor, @NonNull PaginationDirection direction) { - super(page, size); - Assert.notNull(sort, "Sort must not be null"); - Assert.notNull(direction, "PaginationDirection must not be null"); - - this.sort = sort; - this.tupleCursor = tupleCursor; - this.paginationDirection = direction; - } - - /** Non supported for Tarantool. */ - @Override - @NonNull - public TarantoolPageRequest withPage(int pageNumber) throws UnsupportedOperationException { - throw new UnsupportedOperationException("method \"withPage(int pageNumber)\" unsupported"); - } - - @Override - @NonNull - public TarantoolPageable first() { - return new TarantoolPageRequest<>(getPageSize()); - } - - /** Non supported for Tarantool. Use {@link #next(Object)}. */ - @Override - @NonNull - public TarantoolPageRequest next() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"next()\" unsupported, use next(T nextTupleCursor)"); - } - - @Override - public TarantoolPageRequest next(T tupleCursor) { - return new TarantoolPageRequest<>( - getPageNumber() + 1, getPageSize(), getSort(), tupleCursor, FORWARD); - } - - /** Non supported for Tarantool. Use {@link #previous(Object)}. */ - @Override - @NonNull - public TarantoolPageRequest previous() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"previous()\" unsupported, use previous(T prevTupleCursor)"); - } - - private TarantoolPageRequest previous(T tupleCursor) { - if (hasPrevious()) { - return new TarantoolPageRequest<>( - getPageNumber() - 1, getPageSize(), getSort(), tupleCursor, BACKWARD); - } - return this; - } - - /** Non supported for Tarantool. Use {@link #previousOrFirst(Object)}. */ - @Override - @NonNull - public TarantoolPageable previousOrFirst() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"previousOrFirst()\" unsupported, use previousOrFirst(T prevTupleCursor)"); - } - - @Override - public TarantoolPageable previousOrFirst(T tupleCursor) { - if (hasPrevious()) { - return previous(tupleCursor); - } - return new TarantoolPageRequest<>(0, getPageSize(), getSort(), null, BACKWARD); - } - - @Override - public PaginationDirection getPaginationDirection() { - return this.paginationDirection; - } - - @Override - @NonNull - public Sort getSort() { - return this.sort; - } - - @Override - public T getTupleCursor() { - return this.tupleCursor; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolPageRequest)) { - return false; - } - if (!super.equals(o)) { - return false; - } - TarantoolPageRequest that = (TarantoolPageRequest) o; - return sort.equals(that.sort) - && Objects.equals(tupleCursor, that.tupleCursor) - && paginationDirection == that.paginationDirection; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), sort, tupleCursor, paginationDirection); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolPageable.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolPageable.java deleted file mode 100644 index e4bd60f5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolPageable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import org.springframework.data.domain.Pageable; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; - -import io.tarantool.spring.data.query.PaginationDirection; - -/** - * Abstract interface for pagination information in Tarantool. - * - * @param domain class type. - * @author Nikolay Belonogov - */ -public interface TarantoolPageable extends Pageable { - - /** - * Returns tuple cursor of domain type. Can be {@code null}. If the cursor is {@code null} then - * the page is counted from the first tuple in Tarantool. - * - * @return tuple cursor of domain type. - */ - @Nullable - T getTupleCursor(); - - /** - * Returns the {@link TarantoolPageable} for previous page or the {@link TarantoolPageable} for - * first page if the current one already is the first one. Important: this method - * always returns {@link TarantoolPageable} c {@link PaginationDirection#BACKWARD}. - * - * @param tupleCursor tuple cursor of domain type for previous page. - * @return {@link TarantoolPageable} instance. - */ - TarantoolPageable previousOrFirst(T tupleCursor); - - /** - * Returns the {@link TarantoolPageable} requesting the next {@link - * org.springframework.data.domain.Page}. - * - *

Important: method always creates a new {@link TarantoolPageable} with the - * same parameters Sort and page size. Pagination direction is {@link - * PaginationDirection#FORWARD}, the page number always has value {@code n+1}, n is the current - * page number. - * - * @param tupleCursor tuple cursor of domain type for next page. - * @return {@link TarantoolPageable} object - */ - TarantoolPageable next(T tupleCursor); - - /** - * Returns pagination direction by {@link PaginationDirection} enumeration. - * - * @return {@link PaginationDirection}. - */ - PaginationDirection getPaginationDirection(); - - /** - * Returns a {@link TarantoolPageable} that points to the first page with {@link - * PaginationDirection#FORWARD} pagination direction. - * - * @return {@link TarantoolPageable} which has {@code cursor == null}, page number is 0, the rest - * parameters are equivalent to the parameters of the current {@link TarantoolPageable}. - */ - @NonNull - TarantoolPageable first(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolPartTreeQuery.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolPartTreeQuery.java deleted file mode 100644 index 32952852..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolPartTreeQuery.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery; -import org.springframework.data.repository.query.Parameter; -import org.springframework.data.repository.query.Parameters; -import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.data.util.StreamUtils; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data27.query.PaginationUtils.castToTarantoolPageable; -import static io.tarantool.spring.data27.query.PaginationUtils.doPageQuery; -import static io.tarantool.spring.data27.query.PaginationUtils.doPaginationQuery; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.spring.data.query.PaginationDirection; - -/** - * There is one instance for each query method defined for a repository, providing a query from the - * bind parameters. - * - * @author Artyom Dubinin - */ -public class TarantoolPartTreeQuery extends KeyValuePartTreeQuery { - - public static final String ILLEGAL_RETURN_TYPE_FOR_DELETE = - "Illegal returned type: %s. The operation 'deleteBy' accepts only 'long' and 'Collection' as" - + " the returned object type"; - public static final String QUERY_METHOD_S_NOT_SUPPORTED = "Query method '%s' not supported."; - private final QueryMethod queryMethod; - private final KeyValueOperations keyValueOperations; - private final PartTree tree; - - private final boolean isCount; - private final boolean isDelete; - private final boolean isDistinct; - private final boolean isExists; - private final Class targetType; - private final Class returnType; - - private boolean isRearrangeKnown; - private boolean isRearrangeRequired; - private int[] rearrangeIndex; - - /** - * Create a {@link RepositoryQuery} implementation for each query method defined in a tarantool - * repository. - * - * @param queryMethod Method defined in Tarantool Repositories - * @param evaluationContextProvider Not used - * @param keyValueOperations Interface to Tarantool - * @param queryCreator Not used - */ - public TarantoolPartTreeQuery( - QueryMethod queryMethod, - QueryMethodEvaluationContextProvider evaluationContextProvider, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - super(queryMethod, evaluationContextProvider, keyValueOperations, queryCreator); - this.queryMethod = queryMethod; - this.keyValueOperations = keyValueOperations; - this.isRearrangeKnown = false; - this.targetType = queryMethod.getEntityInformation().getJavaType(); - this.returnType = queryMethod.getReturnedObjectType(); - this.tree = new PartTree(getQueryMethod().getName(), targetType); - if (queryMethod.getParameters().getNumberOfParameters() > 0) { - this.isCount = tree.isCountProjection(); - this.isDelete = tree.isDelete(); - this.isDistinct = tree.isDistinct(); - this.isExists = tree.isExistsProjection(); - } else { - this.isCount = false; - this.isDelete = false; - this.isDistinct = false; - this.isExists = false; - } - } - - /** - * Execute this query instance, using any invocation parameters. - * - *

Expecting {@code findBy...()}, {@code countBy...()} or {@code deleteBy...()} - * - * @param parameters Any parameters - * @return Query result - */ - @Override - public Object execute(@NonNull Object[] parameters) { - ParametersParameterAccessor accessor = this.prepareAccessor(parameters, tree); - - KeyValueQuery query = prepareQuery(accessor); - - if (this.isCount) { - if (this.isDistinct) { - final Iterable iterable = this.keyValueOperations.find(query, targetType); - return StreamUtils.createStreamFromIterator(iterable.iterator()).distinct().count(); - } - return this.keyValueOperations.count(query, targetType); - } - - if (this.isDelete) { - return this.executeDeleteQuery(query); - } - - if (this.isExists) { - query.setOffset(0); - query.setRows(1); - final Iterable result = this.keyValueOperations.find(query, targetType); - return result.iterator().hasNext(); - } - - if (queryMethod.isPageQuery()) { - return this.executePageQuery(query, accessor); - } - - if (queryMethod.isSliceQuery()) { - return this.executeSliceQuery(query, accessor); - } - - if (queryMethod.isCollectionQuery() - || queryMethod.isQueryForEntity() - || queryMethod.isStreamQuery()) { - return this.executeFindQuery(query); - } - - throw new UnsupportedOperationException( - String.format(QUERY_METHOD_S_NOT_SUPPORTED, queryMethod.getName())); - } - - /** - * Execute a "delete" query, not really a query more of an operation. - * - *

- * - * @param query The query to run - * @return Collection of deleted objects or the number of deleted objects - */ - private Object executeDeleteQuery(final KeyValueQuery query) { - - Iterable resultSet = this.keyValueOperations.find(query, targetType); - Iterator iterator = resultSet.iterator(); - - List result = new ArrayList<>(); - while (iterator.hasNext()) { - result.add(this.keyValueOperations.delete(iterator.next())); - } - - if (queryMethod.isCollectionQuery()) { - return result; - } - if (long.class.equals(returnType) || Long.class.equals(returnType)) { - return result.size(); - } - throw new UnsupportedOperationException( - String.format(ILLEGAL_RETURN_TYPE_FOR_DELETE, returnType)); - } - - /** - * Execute a retrieval query. The query engine will return this in an iterator, which may need - * conversion to a single domain entity or a stream. - * - * @param query The query to run - * @return Query result - */ - private Object executeFindQuery(final KeyValueQuery query) { - - Iterable resultSet = this.keyValueOperations.find(query, targetType); - - if (!queryMethod.isCollectionQuery() - && !queryMethod.isPageQuery() - && !queryMethod.isSliceQuery() - && !queryMethod.isStreamQuery()) { - // Singleton result - return resultSet.iterator().hasNext() ? resultSet.iterator().next() : null; - } - - Stream stream = StreamUtils.createStreamFromIterator(resultSet.iterator()); - if (this.isDistinct) { - stream = stream.distinct(); - } - - if (queryMethod.isStreamQuery()) { - return stream; - } - - // optimization: - // we can omit if condition - // but this will recreate result even if it's not distinct and isn't stream query - if (this.isDistinct) { - return stream.collect(Collectors.toList()); - } - - return resultSet; - } - - /** - * Execute the slice request. - * - * @param query query - * @param accessor accessor - * @return slice selection result. - */ - private Object executePageQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - - Pageable pageParams = accessor.getPageable(); - return doPageQuery(pageParams, query, this.keyValueOperations, targetType); - } - - private Object executeSliceQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - - Pageable sliceParams = accessor.getPageable(); - - if (sliceParams.isUnpaged()) { - return new TarantoolSliceImpl<>(); - } - - TarantoolPageable resultSliceParams = castToTarantoolPageable(sliceParams); - - int pageSize = resultSliceParams.getPageSize(); - - List content = - doPaginationQuery( - query, resultSliceParams, pageSize + 1, this.keyValueOperations, targetType); - - if (content.isEmpty()) { - return new TarantoolSliceImpl<>(); - } - - boolean hasNext = content.size() > resultSliceParams.getPageSize(); - PaginationDirection paginationDirection = resultSliceParams.getPaginationDirection(); - - List result = content; - if (hasNext) { - switch (paginationDirection) { - case FORWARD: - { - result = content.subList(0, pageSize); - break; - } - case BACKWARD: - { - result = content.subList(1, content.size()); - break; - } - } - } - return new TarantoolSliceImpl<>(result, resultSliceParams, hasNext); - } - - /** - * Create the query from the bind parameters. - * - * @return A ready-to-use query - */ - @NonNull - protected KeyValueQuery prepareQuery(ParametersParameterAccessor accessor) { - KeyValueQuery query = createQuery(accessor); - - /* - If there is no limitation in the name of the method, we always put a - limit so that don't think about this in the engine, especially when distinguishing between a regular query and a - paginated query. - */ - if (!tree.isLimiting()) { - query.setRows(SelectOptions.DEFAULT_LIMIT); - } - - if (accessor.getSort() != Sort.unsorted()) { - query.setSort(accessor.getSort()); - } - - return query; - } - - /** - * Handle {@code @Param}. - * - *
    - *
  1. Without {@code @Param} - *

    Arguments to the call are assumed to follow the same sequence as cited in the method - * name.
    - * Eg. - *

    -   *     findByOneAndTwo(String one, String two);
    -   *     
    - *
  2. With {@code @Param} - *

    Arguments to the call are use the {@code @Param} to match them against the fields. - *

    Eg. - *

    -   *   findByOneAndTwo(@Param("two") String two, @Param("one") String one);
    -   *   
    - *
- * - * @param originalParameters Possibly empty - * @param partTree Query tree to traverse - * @return Parameters in correct order - */ - private ParametersParameterAccessor prepareAccessor( - final Object[] originalParameters, final PartTree partTree) { - - if (!this.isRearrangeKnown) { - this.prepareRearrange(partTree, this.queryMethod.getParameters().getBindableParameters()); - this.isRearrangeKnown = true; - } - - Object[] parameters = originalParameters; - Assert.notNull(parameters, "Parameters must not be null."); - - if (this.isRearrangeRequired) { - parameters = new Object[originalParameters.length]; - - for (int i = 0; i < parameters.length; i++) { - int index = (i < rearrangeIndex.length) ? rearrangeIndex[i] : i; - parameters[i] = originalParameters[index]; - } - } - - return new ParametersParameterAccessor(this.queryMethod.getParameters(), parameters); - } - - /** - * Determine if the arguments to the method need reordered. - * - *

For searches such as {@code findBySomethingNotNull} there may be more parts than parameters - * needed to be bound to them. - * - * @param partTree Query parts - * @param bindableParameters Parameters expected - */ - @SuppressWarnings("unchecked") - private void prepareRearrange( - final PartTree partTree, final Parameters bindableParameters) { - - this.isRearrangeRequired = false; - if (partTree == null || bindableParameters == null) { - return; - } - - List queryParams = new ArrayList<>(); - List methodParams = new ArrayList<>(); - - for (Part part : partTree.getParts()) { - queryParams.add(part.getProperty().getSegment()); - } - - Iterator bindableParameterIterator = - (Iterator) bindableParameters.iterator(); - while (bindableParameterIterator.hasNext()) { - Parameter parameter = bindableParameterIterator.next(); - parameter.getName().ifPresent(methodParams::add); - } - - this.rearrangeIndex = new int[queryParams.size()]; - - String[] paramsExpected = queryParams.toArray(new String[0]); - String[] paramsProvided = methodParams.toArray(new String[0]); - - for (int i = 0; i < this.rearrangeIndex.length; i++) { - this.rearrangeIndex[i] = i; - - for (int j = 0; j < paramsProvided.length; j++) { - if (paramsProvided[j] != null && paramsProvided[j].equals(paramsExpected[i])) { - this.rearrangeIndex[i] = j; - this.isRearrangeRequired = true; - } - } - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolQueryCreator.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolQueryCreator.java deleted file mode 100644 index 661a3669..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolQueryCreator.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.mapping.PropertyPath; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -import static io.tarantool.client.crud.ConditionOperator.EQ; -import static io.tarantool.client.crud.ConditionOperator.GREATER; -import static io.tarantool.client.crud.ConditionOperator.GREATER_EQ; -import static io.tarantool.client.crud.ConditionOperator.LESS; -import static io.tarantool.client.crud.ConditionOperator.LESS_EQ; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.ConditionOperator; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolQueryCreator - extends AbstractQueryCreator, TarantoolCriteria> { - - private final Map cache = new ConcurrentHashMap<>(); - - public static final String INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE = - "Logic error for '%s' in query. "; - - public TarantoolQueryCreator(PartTree tree, ParameterAccessor parameters) { - super(tree, parameters); - } - - private String getFieldName(Part part) { - PropertyPath property = part.getProperty(); - String segment = property.toDotPath(); - Class domainType = property.getOwningType().getType(); - java.lang.reflect.Field field = ReflectionUtils.findField(domainType, segment); - - if (field == null) { - throw new IllegalArgumentException("No such field: " + segment + " in " + domainType); - } - Field annotationField = field.getAnnotation(Field.class); - - if (annotationField != null) { - String value = annotationField.value(); - if (StringUtils.hasText(value)) { - return value; - } - String name = annotationField.name(); - if (StringUtils.hasText(name)) { - return name; - } - } - - return segment; - } - - @Override - @NonNull - protected TarantoolCriteria create(Part part, @NonNull Iterator iterator) { - final TarantoolCriteria tarantoolCriteria = new TarantoolCriteria(); - - Part.Type type = part.getType(); - if (isIgnoreCase(part)) { - throw new InvalidDataAccessApiUsageException( - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "IgnoreCase isn't supported yet", - type)); - } - String property = cache.computeIfAbsent(part, this::getFieldName); - - switch (type) { - case SIMPLE_PROPERTY: - generateConditions(tarantoolCriteria, type, property, iterator, EQ); - break; - case LESS_THAN: - case BEFORE: - generateConditions(tarantoolCriteria, type, property, iterator, LESS); - break; - case LESS_THAN_EQUAL: - generateConditions(tarantoolCriteria, type, property, iterator, LESS_EQ); - break; - case GREATER_THAN: - case AFTER: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER); - break; - case GREATER_THAN_EQUAL: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER_EQ); - break; - case BETWEEN: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER, LESS); - break; - case TRUE: - tarantoolCriteria.addCondition(Condition.create(EQ, property, true)); - break; - case FALSE: - tarantoolCriteria.addCondition(Condition.create(EQ, property, false)); - break; - case IS_EMPTY: - tarantoolCriteria.addCondition(Condition.create(EQ, property, "")); - break; - case IS_NULL: - tarantoolCriteria.addCondition(Condition.create(EQ, property, null)); - break; - default: - throw new InvalidDataAccessApiUsageException(String.format("Unsupported type '%s'", type)); - } - - return tarantoolCriteria; - } - - private void generateConditions( - TarantoolCriteria tarantoolCriteria, - Part.Type type, - String property, - Iterator iterator, - ConditionOperator... operators) { - for (int i = 0; i < type.getNumberOfArguments(); i++) { - if (!iterator.hasNext()) { - throw new InvalidDataAccessApiUsageException( - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "Transmitted not enough arguments (%d of %d)", - type, - i, - type.getNumberOfArguments())); - } - tarantoolCriteria.addCondition(Condition.create(operators[i], property, iterator.next())); - } - } - - private boolean isIgnoreCase(Part part) { - switch (part.shouldIgnoreCase()) { - case ALWAYS: - Assert.state( - canUpperCase(part.getProperty()), - String.format( - "Unable to ignore case of %s types, the property '%s' must reference a String", - part.getProperty().getType().getName(), part.getProperty().getSegment())); - return true; - case WHEN_POSSIBLE: - return canUpperCase(part.getProperty()); - case NEVER: - default: - return false; - } - } - - private boolean canUpperCase(PropertyPath path) { - return String.class.equals(path.getType()); - } - - @Override - @NonNull - protected TarantoolCriteria and( - @NonNull Part part, @NonNull TarantoolCriteria base, @NonNull Iterator iterator) { - throw new UnsupportedOperationException(); - } - - @Override - @NonNull - protected TarantoolCriteria or( - @NonNull TarantoolCriteria base, @NonNull TarantoolCriteria criteria) { - throw new UnsupportedOperationException(); - } - - @Override - @NonNull - protected KeyValueQuery complete( - @Nullable final TarantoolCriteria criteria, @NonNull Sort sort) { - return new KeyValueQuery<>(criteria); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolQueryMethodImpl.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolQueryMethodImpl.java deleted file mode 100644 index 97a41bdf..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolQueryMethodImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.lang.reflect.Method; - -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryMethod; - -import io.tarantool.spring.data.query.Query; -import io.tarantool.spring.data.query.TarantoolQueryMethod; - -/** Tarantool {@link QueryMethod} Implementation */ -public class TarantoolQueryMethodImpl extends QueryMethod implements TarantoolQueryMethod { - - private final Method method; - - public TarantoolQueryMethodImpl( - Method method, RepositoryMetadata metadata, ProjectionFactory factory) { - super(method, metadata, factory); - this.method = method; - } - - public boolean hasAnnotatedQuery() { - return getQuery() != null; - } - - public String getQueryValue(Query query) { - return (String) AnnotationUtils.getValue(query); - } - - public Query getQuery() { - return method.getAnnotation(Query.class); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolRepositoryQuery.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolRepositoryQuery.java deleted file mode 100644 index e5c81b02..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolRepositoryQuery.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.RepositoryQuery; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.query.ProxyTarantoolRepositoryQuery; - -/** {@link RepositoryQuery} using String based function name to call function in Tarantool. */ -public class TarantoolRepositoryQuery implements RepositoryQuery { - - private final ProxyTarantoolRepositoryQuery proxy; - private final TarantoolQueryMethodImpl queryMethod; - - public TarantoolRepositoryQuery( - TarantoolCrudClient client, TarantoolQueryMethodImpl queryMethod) { - this.queryMethod = queryMethod; - this.proxy = new ProxyTarantoolRepositoryQuery(client, queryMethod); - } - - @Override - public Object execute(Object[] parameters) { - return proxy.execute(parameters); - } - - @Override - public QueryMethod getQueryMethod() { - return queryMethod; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolSliceImpl.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolSliceImpl.java deleted file mode 100644 index ebf1f1bb..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolSliceImpl.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.lang.NonNull; - -/** - * Default implementation of {@link Slice} for Tarantool. - * - * @author Nikolay Belonogov - */ -class TarantoolSliceImpl extends TarantoolChunk { - - private static final long serialVersionUID = 867755909294344406L; - - private final boolean hasNext; - - private final Pageable pageable; - - /** - * Creates a new {@link TarantoolSliceImpl} with the empty content. This will result in the - * created {@link Slice} being identical to the entire {@link List}. - */ - public TarantoolSliceImpl() { - this(Collections.emptyList(), Pageable.unpaged(), false); - } - - /** - * Creates a new {@link TarantoolSliceImpl} with the given content. This will result in the - * created {@link Slice} being identical to the entire {@link List}. - * - * @param content must not be {@literal null}. - */ - public TarantoolSliceImpl(List content) { - this(content, Pageable.unpaged(), false); - } - - /** - * Creates a new {@link TarantoolSliceImpl} with the given content and {@link Pageable}. - * - * @param content the content of this {@link Slice}, must not be {@literal null}. - * @param pageable the paging information, must not be {@literal null}. - * @param hasNext whether there's another slice following the current one. - */ - public TarantoolSliceImpl(List content, Pageable pageable, boolean hasNext) { - super(content, pageable); - - this.hasNext = hasContent() && hasNext; - this.pageable = pageable; - } - - /** - * Returns true if there is a next data slice. No data content means that the next slice does not - * exist and method will return false. - * - * @return Returns true if there is a next data slice. No data content means that the next slice - * does not exist and method will return false. - */ - @Override - public boolean hasNext() { - return hasNext && hasContent(); - } - - @Override - @NonNull - public Slice map(@NonNull Function converter) { - return new TarantoolSliceImpl<>(getConvertedContent(converter), pageable, hasNext); - } - - @Override - public String toString() { - - String contentType = "UNKNOWN"; - List content = getContent(); - - if (content.size() > 0) { - contentType = content.get(0).getClass().getName(); - } - - return String.format("Slice %d containing %s instances", getNumber(), contentType); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolSliceImpl)) { - return false; - } - if (!super.equals(o)) { - return false; - } - TarantoolSliceImpl that = (TarantoolSliceImpl) o; - return hasNext == that.hasNext && pageable.equals(that.pageable); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), hasNext, pageable); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolSortAccessor.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolSortAccessor.java deleted file mode 100644 index 50acf247..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/query/TarantoolSortAccessor.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.util.Comparator; -import java.util.Map.Entry; - -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Sort.Order; -import org.springframework.data.keyvalue.core.SortAccessor; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -/** - * Implements sorting for Tarantool repository queries. - * - * @author Artyom Dubinin - */ -public class TarantoolSortAccessor implements SortAccessor>> { - - /** - * Sort on a sequence of fields, possibly none. - * - * @param query If not null, will contain one of more {@link Order} objects. - * @return A sequence of comparators or {@code null} - */ - public Comparator> resolve(KeyValueQuery query) { - if (query == null || query.getSort() == Sort.unsorted()) { - return null; - } - - throw new UnsupportedOperationException(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/TarantoolRepositoryFactory.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/TarantoolRepositoryFactory.java deleted file mode 100644 index 5b1357e4..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/TarantoolRepositoryFactory.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.repository; - -import java.util.Optional; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.SpelQueryCreator; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data27.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data27.repository.config.TarantoolQueryLookupStrategy; -import io.tarantool.spring.data27.repository.support.TarantoolSimpleRepository; - -/** - * Tarantool version of {@link KeyValueRepositoryFactory}, a factory to build tarantool repository - * instances. - * - *

The purpose of extending is to ensure that the {@link #getQueryLookupStrategy} method returns - * a {@link TarantoolQueryLookupStrategy} rather than the default. - * - *

The end goal of this bean is for {@link TarantoolPartTreeQuery} to be used for query - * preparation. - * - * @author Artyom Dubinin - */ -public class TarantoolRepositoryFactory extends KeyValueRepositoryFactory { - - private static final Class DEFAULT_QUERY_CREATOR = SpelQueryCreator.class; - - private final KeyValueOperations keyValueOperations; - private final Class> queryCreator; - private final TarantoolCrudClient client; - - /* Mirror functionality of super, to ensure private - * fields are set. - */ - public TarantoolRepositoryFactory( - TarantoolCrudClient client, KeyValueOperations keyValueOperations) { - this(client, keyValueOperations, DEFAULT_QUERY_CREATOR); - } - - /* Capture KeyValueOperations and QueryCreator objects after passing to super. - */ - public TarantoolRepositoryFactory( - TarantoolCrudClient client, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - - super(keyValueOperations, queryCreator); - - this.client = client; - this.keyValueOperations = keyValueOperations; - this.queryCreator = queryCreator; - } - - /** - * Ensure the mechanism for query evaluation is Tarantool specific, as the original {@code - * KeyValueQueryLookupStrategy} does not function correctly for Tarantool. - */ - @Override - protected Optional getQueryLookupStrategy( - QueryLookupStrategy.Key key, QueryMethodEvaluationContextProvider evaluationContextProvider) { - return Optional.of( - new TarantoolQueryLookupStrategy( - client, key, evaluationContextProvider, keyValueOperations, queryCreator)); - } - - @Override - protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { - return TarantoolSimpleRepository.class; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/TarantoolQueryLookupStrategy.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/TarantoolQueryLookupStrategy.java deleted file mode 100644 index 1a97bc59..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/TarantoolQueryLookupStrategy.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.repository.config; - -import java.lang.reflect.Method; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery; -import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.repository.core.NamedQueries; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.util.Assert; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data27.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data27.query.TarantoolQueryMethodImpl; -import io.tarantool.spring.data27.query.TarantoolRepositoryQuery; - -/** - * Ensures {@link TarantoolPartTreeQuery} is used for query preparation rather than {@link - * KeyValuePartTreeQuery} or other alternatives. - * - * @author Artyom Dubinin - */ -public class TarantoolQueryLookupStrategy implements QueryLookupStrategy { - - private final QueryMethodEvaluationContextProvider evaluationContextProvider; - private final KeyValueOperations keyValueOperations; - private final Class> queryCreator; - private final TarantoolCrudClient client; - - /** - * Required constructor, capturing arguments for use in {@link #resolveQuery}. - * - * @param client tarantool crud client - * @param key Not used - * @param evaluationContextProvider For evaluation of query expressions - * @param keyValueOperations Bean to use for Key/Value operations on Tarantool repos - * @param queryCreator Query creator - */ - public TarantoolQueryLookupStrategy( - TarantoolCrudClient client, - Key key, - QueryMethodEvaluationContextProvider evaluationContextProvider, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - - Assert.notNull(evaluationContextProvider, "EvaluationContextProvider must not be null!"); - Assert.notNull(keyValueOperations, "KeyValueOperations must not be null!"); - Assert.notNull(queryCreator, "Query creator type must not be null!"); - - this.client = client; - this.evaluationContextProvider = evaluationContextProvider; - this.keyValueOperations = keyValueOperations; - this.queryCreator = queryCreator; - } - - /** - * Use {@link TarantoolPartTreeQuery} for resolving queries against Tarantool repositories. - * - * @param method, the query method - * @param metadata, not used - * @param projectionFactory, not used - * @param namedQueries, not used - * @return A mechanism for querying Tarantool repositories - */ - public RepositoryQuery resolveQuery( - Method method, - RepositoryMetadata metadata, - ProjectionFactory projectionFactory, - NamedQueries namedQueries) { - - TarantoolQueryMethodImpl queryMethod = - new TarantoolQueryMethodImpl(method, metadata, projectionFactory); - - if (queryMethod.hasAnnotatedQuery()) { - return new TarantoolRepositoryQuery(client, queryMethod); - } - - return new TarantoolPartTreeQuery( - queryMethod, evaluationContextProvider, this.keyValueOperations, this.queryCreator); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/TarantoolRepositoriesRegistrar.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/TarantoolRepositoriesRegistrar.java deleted file mode 100644 index b5c941fb..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/TarantoolRepositoriesRegistrar.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.repository.config; - -import java.lang.annotation.Annotation; - -import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport; -import org.springframework.data.repository.config.RepositoryConfigurationExtension; - -class TarantoolRepositoriesRegistrar extends RepositoryBeanDefinitionRegistrarSupport { - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoriesRegistrar#getAnnotation() - */ - @Override - protected Class getAnnotation() { - return EnableTarantoolRepositories.class; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport#getExtension() - */ - @Override - protected RepositoryConfigurationExtension getExtension() { - return new TarantoolRepositoryConfigurationExtension(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/TarantoolRepositoryConfigurationExtension.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/TarantoolRepositoryConfigurationExtension.java deleted file mode 100644 index 1e00f327..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/TarantoolRepositoryConfigurationExtension.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.repository.config; - -import org.springframework.beans.factory.config.ConstructorArgumentValues; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension; -import org.springframework.data.repository.config.RepositoryConfigurationSource; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.spring.data27.config.TarantoolCrudConfiguration; -import io.tarantool.spring.data27.core.TarantoolTemplate; -import io.tarantool.spring.data27.core.mapping.TarantoolMappingContext; - -public class TarantoolRepositoryConfigurationExtension - extends KeyValueRepositoryConfigurationExtension { - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getModuleName() - */ - @Override - public String getModuleName() { - return "Tarantool"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getModulePrefix() - */ - @Override - public String getModulePrefix() { - return "tarantool"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getDefaultKeyValueTemplateRef() - */ - @Override - public String getDefaultKeyValueTemplateRef() { - return DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #registerBeansForRoot() - */ - @Override - public void registerBeansForRoot( - BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) { - // register a default set of beans based on the passed annotation attributes. - final ClientType clientTypeAttribute = - configurationSource.getRequiredAttribute("clientType", ClientType.class); - - if (clientTypeAttribute == ClientType.CRUD) { - final String defaultCrudConfigurationBeanName = - TarantoolCrudConfiguration.class.getCanonicalName(); - registerIfNotAlreadyRegistered( - () -> new RootBeanDefinition(TarantoolCrudConfiguration.class), - registry, - defaultCrudConfigurationBeanName, - configurationSource); - } else { - throw new IllegalArgumentException("The Box client is not yet supported."); - } - super.registerBeansForRoot(registry, configurationSource); - - // remove KeyValueMappingContext to add TarantoolMappingContext - registry.removeBeanDefinition(getMappingContextBeanRef()); - registerIfNotAlreadyRegistered( - () -> { - RootBeanDefinition definition = new RootBeanDefinition(TarantoolMappingContext.class); - definition.setSource(configurationSource.getSource()); - - return definition; - }, - registry, - getMappingContextBeanRef(), - configurationSource); - } - - @Override - protected AbstractBeanDefinition getDefaultKeyValueTemplateBeanDefinition( - RepositoryConfigurationSource configurationSource) { - final RootBeanDefinition keyValueTemplateBeanDefinition = - new RootBeanDefinition(TarantoolTemplate.class); - - final ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); - constructorArgumentValues.addIndexedArgumentValue( - 0, new RuntimeBeanReference(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF)); - constructorArgumentValues.addIndexedArgumentValue( - 1, new RuntimeBeanReference(getMappingContextBeanRef())); - - keyValueTemplateBeanDefinition.setConstructorArgumentValues(constructorArgumentValues); - keyValueTemplateBeanDefinition.setSource(configurationSource); - keyValueTemplateBeanDefinition.setDependsOn(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF); - keyValueTemplateBeanDefinition.setDependsOn(getMappingContextBeanRef()); - - return keyValueTemplateBeanDefinition; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/package-info.java deleted file mode 100644 index 7ce62de7..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository config package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data27.repository.config; diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/package-info.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/package-info.java deleted file mode 100644 index 99dbe8ac..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data27.repository; diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/support/TarantoolRepositoryFactoryBean.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/support/TarantoolRepositoryFactoryBean.java deleted file mode 100644 index 63a15979..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/support/TarantoolRepositoryFactoryBean.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.repository.support; - -import java.io.Serializable; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean; -import org.springframework.data.repository.Repository; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data27.repository.TarantoolRepositoryFactory; - -public class TarantoolRepositoryFactoryBean, S, ID extends Serializable> - extends KeyValueRepositoryFactoryBean { - - @Autowired private TarantoolCrudClient client; - - public TarantoolRepositoryFactoryBean(Class repositoryInterface) { - super(repositoryInterface); - } - - /** - * Return a {@link TarantoolRepositoryFactory}. - * - *

{@code super} would return {@link KeyValueRepositoryFactory} which in turn builds {@code - * KeyValueRepository} instances, and these have a private method that implement querying in a - * manner that does not fit with Tarantool. More details are in {@link - * TarantoolRepositoryFactory}. - * - * @param operations operations - * @param queryCreator creator - * @param repositoryQueryType, not used - * @return A {@link TarantoolRepositoryFactory} that creates tarantool repository instances. - */ - @Override - protected KeyValueRepositoryFactory createRepositoryFactory( - KeyValueOperations operations, - Class> queryCreator, - Class repositoryQueryType) { - return new TarantoolRepositoryFactory(client, operations, queryCreator); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/support/TarantoolSimpleRepository.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/support/TarantoolSimpleRepository.java deleted file mode 100644 index c108f2b7..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/support/TarantoolSimpleRepository.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.repository.support; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository; -import org.springframework.data.repository.core.EntityInformation; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data27.query.PaginationUtils.doPageQuery; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolSimpleRepository extends SimpleKeyValueRepository { - - private static final String FIND_ALL_EXC_MSG = - "This method is not supported to avoid sampling huge data massive. " - + "Please use derived methods with scrolling or pagination to select all data."; - - private static final String FIND_ALL_SORT_EXC_MSG = - "This method is not supported because sorting is not supported " - + "in Tarantool. Organize sorting of results using Java tools."; - - private static final String PAGEABLE_NULL_EXC_MSG = "Pageable must be not null"; - - private final KeyValueOperations operations; - private final EntityInformation entityInformation; - - /** - * Creates a new {@link SimpleKeyValueRepository} for the given {@link EntityInformation} and - * {@link KeyValueOperations}. - * - * @param metadata must not be {@literal null}. - * @param operations must not be {@literal null}. - */ - public TarantoolSimpleRepository( - EntityInformation metadata, KeyValueOperations operations) { - super(metadata, operations); - this.entityInformation = metadata; - this.operations = operations; - } - - @Override - public List findAll() { - throw new UnsupportedOperationException(FIND_ALL_EXC_MSG); - } - - @Override - public Iterable findAll(Sort sort) { - throw new UnsupportedOperationException(FIND_ALL_SORT_EXC_MSG); - } - - @Override - @SuppressWarnings("unchecked") - public Page findAll(Pageable pageable) { - Assert.notNull(pageable, PAGEABLE_NULL_EXC_MSG); - - KeyValueQuery query = new KeyValueQuery<>(new TarantoolCriteria()); - return (Page) - doPageQuery(pageable, query, this.operations, this.entityInformation.getJavaType()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/support/package-info.java b/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/support/package-info.java deleted file mode 100644 index 7e24aca2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/support/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository support package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data27.repository.support; diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/GenericTarantoolConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/GenericTarantoolConfigurationTest.java deleted file mode 100644 index 638e122e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/GenericTarantoolConfigurationTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.config; - -import java.io.IOException; -import java.nio.file.Files; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.test.context.TestPropertySource; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.spring.data27.config.properties.TarantoolProperties; - -@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -public abstract class GenericTarantoolConfigurationTest implements ApplicationContextAware { - - protected static TarantoolProperties testProperties; - - protected ApplicationContext applicationContext; - - @Autowired protected TarantoolProperties properties; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - @BeforeAll - static void beforeAll() throws IOException { - testProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists(DEFAULT_TEST_PROPERTY_DIR.resolve(DEFAULT_PROPERTY_FILE_NAME)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/TarantoolBoxConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/TarantoolBoxConfigurationTest.java deleted file mode 100644 index cda79d3a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/TarantoolBoxConfigurationTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.config; - -import java.io.IOException; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.RepeatedTest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.client.box.TarantoolBoxClient; -import io.tarantool.client.factory.TarantoolBoxClientBuilder; -import io.tarantool.pool.HeartbeatOpts; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data27.config.properties.TarantoolProperties; - -@SpringBootTest(classes = {TarantoolBoxConfigurationTest.Config.class}) -public class TarantoolBoxConfigurationTest extends GenericTarantoolConfigurationTest { - - @MockBean TarantoolBoxClient client; - - @Autowired private TarantoolBoxConfiguration tarantoolBoxConfiguration; - - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testGetBoxClientBuilder() throws IOException { - assertEquals(properties, tarantoolBoxConfiguration.getProperties()); - - final TarantoolBoxClientBuilder boxClientBuilder = tarantoolBoxConfiguration.getClientBuilder(); - - if (properties.getConnectionGroups() == null) { - assertNull(boxClientBuilder.getGroups()); - } else { - assertEquals(properties.getConnectionGroups().size(), boxClientBuilder.getGroups().size()); - List connectionGroupsFromBuilder = boxClientBuilder.getGroups(); - List connectionGroupsFromProperty = - properties.getInstanceConnectionGroups(); - - assertNotNull(connectionGroupsFromBuilder); - assertNotNull(connectionGroupsFromProperty); - for (int i = 0; i < connectionGroupsFromBuilder.size(); i++) { - InstanceConnectionGroup groupFromBuilder = connectionGroupsFromBuilder.get(i); - InstanceConnectionGroup groupFromProperty = connectionGroupsFromProperty.get(i); - - assertEquals(groupFromProperty.getAuthType(), groupFromBuilder.getAuthType()); - assertEquals(groupFromProperty.getTag(), groupFromBuilder.getTag()); - assertEquals(groupFromProperty.getSize(), groupFromBuilder.getSize()); - assertEquals(groupFromProperty.getUser(), groupFromBuilder.getUser()); - assertEquals(groupFromProperty.getPassword(), groupFromBuilder.getPassword()); - assertEquals(groupFromProperty.getPort(), groupFromBuilder.getPort()); - assertEquals(groupFromProperty.getHost(), groupFromBuilder.getHost()); - } - } - - final HeartbeatOpts propertiesHeartbeatOpts = properties.getHeartbeatOpts(); - if (propertiesHeartbeatOpts == null) { - assertNull(boxClientBuilder.getHeartbeatOpts()); - } else { - HeartbeatOpts builderHeartbeatOpts = boxClientBuilder.getHeartbeatOpts(); - assertEquals( - propertiesHeartbeatOpts.getPingInterval(), builderHeartbeatOpts.getPingInterval()); - assertEquals( - propertiesHeartbeatOpts.getDeathThreshold(), builderHeartbeatOpts.getDeathThreshold()); - assertEquals( - propertiesHeartbeatOpts.getInvalidationThreshold(), - builderHeartbeatOpts.getInvalidationThreshold()); - assertEquals(propertiesHeartbeatOpts.getWindowSize(), builderHeartbeatOpts.getWindowSize()); - } - - assertEquals(properties.getUserName(), boxClientBuilder.getUser()); - assertEquals(properties.getPort(), boxClientBuilder.getPort()); - assertEquals(properties.getEventLoopThreadsCount(), boxClientBuilder.getnThreads()); - assertEquals(properties.getBalancerClass(), boxClientBuilder.getBalancerClass()); - assertEquals(properties.isGracefulShutdownEnabled(), boxClientBuilder.isGracefulShutdown()); - assertEquals(properties.getConnectTimeout(), boxClientBuilder.getConnectTimeout()); - assertEquals(properties.getReconnectAfter(), boxClientBuilder.getReconnectAfter()); - assertEquals(properties.getHost(), boxClientBuilder.getHost()); - assertEquals(properties.getPassword(), boxClientBuilder.getPassword()); - assertEquals(properties.isFetchSchema(), boxClientBuilder.isFetchSchema()); - assertEquals( - properties.isIgnoreOldSchemaVersion(), boxClientBuilder.isIgnoreOldSchemaVersion()); - - testProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @Configuration - @EnableConfigurationProperties(TarantoolProperties.class) - @Import(TarantoolBoxConfiguration.class) - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/TarantoolCrudConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/TarantoolCrudConfigurationTest.java deleted file mode 100644 index 21dc5a50..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/TarantoolCrudConfigurationTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.config; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.test.annotation.DirtiesContext; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.pool.HeartbeatOpts; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyHeartbeatOpts; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.spring.data27.repository.config.EnableTarantoolRepositories; - -@SpringBootTest(classes = {TarantoolCrudConfigurationTest.Config.class}) -public class TarantoolCrudConfigurationTest extends GenericTarantoolConfigurationTest { - - @MockBean TarantoolCrudClient client; - - @Autowired private TarantoolCrudConfiguration tarantoolCrudConfiguration; - - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testGetCrudClientBuilder() throws IOException { - assertEquals(properties, tarantoolCrudConfiguration.getProperties()); - - final TarantoolCrudClientBuilder crudClientBuilder = - tarantoolCrudConfiguration.getClientBuilder(); - - if (properties.getConnectionGroups() == null) { - assertNull(crudClientBuilder.getGroups()); - } else { - assertEquals(properties.getConnectionGroups().size(), crudClientBuilder.getGroups().size()); - List connectionGroupsFromBuilder = crudClientBuilder.getGroups(); - List connectionGroupsFromProperty = - properties.getConnectionGroups(); - assertNotNull(connectionGroupsFromBuilder); - assertNotNull(connectionGroupsFromProperty); - for (int i = 0; i < connectionGroupsFromBuilder.size(); i++) { - InstanceConnectionGroup groupFromBuilder = connectionGroupsFromBuilder.get(i); - PropertyInstanceConnectionGroup groupFromProperty = connectionGroupsFromProperty.get(i); - - assertEquals(groupFromProperty.getAuthType(), groupFromBuilder.getAuthType()); - assertEquals(groupFromProperty.getTag(), groupFromBuilder.getTag()); - assertEquals(groupFromProperty.getConnectionGroupSize(), groupFromBuilder.getSize()); - assertEquals(groupFromProperty.getUserName(), groupFromBuilder.getUser()); - assertEquals(groupFromProperty.getPassword(), groupFromBuilder.getPassword()); - assertEquals(groupFromProperty.getPort(), groupFromBuilder.getPort()); - assertEquals(groupFromProperty.getHost(), groupFromBuilder.getHost()); - } - } - - final PropertyHeartbeatOpts propertiesHeartbeatOpts = properties.getHeartbeat(); - if (propertiesHeartbeatOpts == null) { - assertNull(crudClientBuilder.getHeartbeatOpts()); - } else { - HeartbeatOpts builderHeartbeatOpts = crudClientBuilder.getHeartbeatOpts(); - - assertEquals( - propertiesHeartbeatOpts.getPingInterval(), builderHeartbeatOpts.getPingInterval()); - assertEquals( - propertiesHeartbeatOpts.getDeathThreshold(), builderHeartbeatOpts.getDeathThreshold()); - assertEquals( - propertiesHeartbeatOpts.getInvalidationThreshold(), - builderHeartbeatOpts.getInvalidationThreshold()); - assertEquals(propertiesHeartbeatOpts.getWindowSize(), builderHeartbeatOpts.getWindowSize()); - } - - assertEquals(properties.getUserName(), crudClientBuilder.getUser()); - assertEquals(properties.getPort(), crudClientBuilder.getPort()); - assertEquals(properties.getEventLoopThreadsCount(), crudClientBuilder.getnThreads()); - assertEquals(properties.getBalancerClass(), crudClientBuilder.getBalancerClass()); - assertEquals(properties.isGracefulShutdownEnabled(), crudClientBuilder.isGracefulShutdown()); - assertEquals(properties.getConnectTimeout(), crudClientBuilder.getConnectTimeout()); - assertEquals(properties.getReconnectAfter(), crudClientBuilder.getReconnectAfter()); - assertEquals(properties.getHost(), crudClientBuilder.getHost()); - assertEquals(properties.getPassword(), crudClientBuilder.getPassword()); - - testProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @Test - void testKeyValueTemplate() { - final List beanDefinitions = Arrays.asList(applicationContext.getBeanDefinitionNames()); - assertTrue(beanDefinitions.contains(DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF)); - - final KeyValueTemplate keyValueTemplate = - applicationContext.getBean( - DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF, KeyValueTemplate.class); - assertNotNull(keyValueTemplate); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/TarantoolEmptyPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/TarantoolEmptyPropertiesTest.java deleted file mode 100644 index 2310f507..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/TarantoolEmptyPropertiesTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.config; - -import java.io.IOException; -import java.nio.file.Files; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.TestPropertySource; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; -import io.tarantool.spring.data27.config.properties.TarantoolProperties; -import io.tarantool.spring.data27.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data27.utils.TarantoolTestSupport; - -/** - * @see TarantoolPropertiesTest - */ -@SpringBootTest(classes = {TarantoolEmptyPropertiesTest.Config.class}) -@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -@Timeout(5) -public class TarantoolEmptyPropertiesTest { - - @Autowired private TarantoolProperties springParsedProperties; - - @BeforeAll - static void beforeAll() throws IOException { - TarantoolTestSupport.writeTestEmptyPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - /* - * The test checks that if property processing is enabled via the @EnableConfigurationProperties annotation, then - * TarantoolProperty always exists and has default values. - */ - @Test - void testParseEmptyProperties() { - assertNotNull(springParsedProperties); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists(DEFAULT_TEST_PROPERTY_DIR.resolve(DEFAULT_PROPERTY_FILE_NAME)); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/TarantoolPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/TarantoolPropertiesTest.java deleted file mode 100644 index 1cda4611..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/config/TarantoolPropertiesTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.config; - -import java.io.IOException; -import java.nio.file.Files; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Timeout; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.TestPropertySource; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data27.config.properties.TarantoolProperties; -import io.tarantool.spring.data27.repository.config.EnableTarantoolRepositories; - -/** - * The test checks whether the Spring framework parses a file with the specified properties - * correctly. Before creating the test class, a random file with properties is written to the - * classpath:properties-test.yaml file. Next, when creating a test class the Spring context is - * raised and parses the file with properties. A test is launched to check the uniqueness of the - * current properties and properties that were specified in the previous iteration. It is checked - * that the generated Spring class TarantoolProperty is equal to the class written to the file. - * Next, the next entry to the file occurs, after which there is a forced reload of the Spring - * context -> the file with properties is parsed again and everything happens according to circle. - */ -@SpringBootTest(classes = {TarantoolPropertiesTest.Config.class}) -@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -@Timeout(5) -public class TarantoolPropertiesTest { - - private static TarantoolProperties writtenToFileProperties; - private static TarantoolProperties prevSpringParsedProperties; - private static TarantoolProperties prevWrittenToFileProperties; - @Autowired private TarantoolProperties springParsedProperties; - - @MockBean private TarantoolCrudClient client; - - @BeforeAll - static void beforeAll() throws IOException { - writtenToFileProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists(DEFAULT_TEST_PROPERTY_DIR.resolve(DEFAULT_PROPERTY_FILE_NAME)); - } - - /** - * The annotation allows you to tell Spring that the context is dirty and needs to be reloaded - * after the test. - */ - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testParseProperty() throws IOException { - assertNotEquals(prevWrittenToFileProperties, writtenToFileProperties); - assertNotEquals(prevSpringParsedProperties, springParsedProperties); - assertEquals(writtenToFileProperties, springParsedProperties); - - prevWrittenToFileProperties = writtenToFileProperties; - prevSpringParsedProperties = springParsedProperties; - - // Write the Properties class that will be parsed by Spring in the next iteration. - writtenToFileProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/annotation/IdClassResolverTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/annotation/IdClassResolverTest.java deleted file mode 100644 index 7dc746fa..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/annotation/IdClassResolverTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.core.annotation; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import io.tarantool.spring.data27.utils.entity.ComplexPerson; -import io.tarantool.spring.data27.utils.entity.CompositePersonKey; -import io.tarantool.spring.data27.utils.entity.EntityWithAnnotationAsIdClass; -import io.tarantool.spring.data27.utils.entity.Person; - -@Timeout(5) -class IdClassResolverTest { - - public static final DefaultIdClassResolver ID_CLASS_RESOLVER = DefaultIdClassResolver.INSTANCE; - - @Test - void testResolveIdClassTypeWithNullEntity() { - - final IllegalArgumentException throwable = - assertThrows( - IllegalArgumentException.class, () -> ID_CLASS_RESOLVER.resolveIdClassType(null)); - final String EXCEPTION_MESSAGE = "Type for IdClass must be not null!"; - assertEquals(EXCEPTION_MESSAGE, throwable.getMessage()); - } - - @Test - void testResolveIdClassTypeWithEntityWithoutAnnotation() { - assertNull(ID_CLASS_RESOLVER.resolveIdClassType(Person.class)); - } - - @Test - void testResolveIdClassTypeWithEntityWithAnnotation() { - assertEquals( - ID_CLASS_RESOLVER.resolveIdClassType(ComplexPerson.class), CompositePersonKey.class); - } - - @Test - void testResolveIdClassTypeWithCrossAnnotation() { - final IllegalArgumentException throwable = - assertThrows( - IllegalArgumentException.class, - () -> ID_CLASS_RESOLVER.resolveIdClassType(EntityWithAnnotationAsIdClass.class)); - - assertEquals(DefaultIdClassResolver.ANNOTATION_TYPE_EXCEPTION, throwable.getMessage()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/mapping/KeyValueCompositePropertyTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/mapping/KeyValueCompositePropertyTest.java deleted file mode 100644 index 753a6c1e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/mapping/KeyValueCompositePropertyTest.java +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.core.mapping; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import lombok.Getter; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.ClassTypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.ReflectionUtils; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class KeyValueCompositePropertyTest

> { - - private @Nullable Identifier

identifier; - - @BeforeEach - public void setUp() { - this.identifier = null; - } - - /** Check methods for adding and retrieving parts of a composite key. */ - @Test - public void testAddAndGetParts() { - Class entityClass = TestEntity.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(ClassTypeInformation.from(TestEntity.class), null); - - ReflectionUtils.FieldFilter isIdFieldFiler = field -> field.isAnnotationPresent(Id.class); - ReflectionUtils.doWithFields(entityClass, field -> addPart(field, owner), isIdFieldFiler); - - assertNotNull(identifier); - List identifierFieldsFromProperties = - this.identifier.getParts().stream() - .map(PersistentProperty::getField) - .collect(Collectors.toList()); - - compareFieldCollection(identifierFieldsFromProperties, getExpectedIdFields(entityClass)); - } - - /** Check methods for adding and retrieving parts of a composite key. */ - @Test - public void testAddAndGetFields() { - Class entityClass = TestEntity.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(ClassTypeInformation.from(TestEntity.class), null); - - ReflectionUtils.FieldFilter idFieldFiler = field -> field.isAnnotationPresent(Id.class); - ReflectionUtils.doWithFields(entityClass, field -> addPart(field, owner), idFieldFiler); - - assertNotNull(identifier); - List fieldsFromIdentifier = Arrays.asList(identifier.getFields()); - - compareFieldCollection(fieldsFromIdentifier, getExpectedIdFields(entityClass)); - } - - /** - * Check methods for adding and getting parts of a composite key for an object without - * {@code @Id}. - */ - @Test - public void testAddAndGetPartsWithEntityWithoutId() { - Class entityClass = TestEntityWithoutId.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(ClassTypeInformation.from(TestEntity.class), null); - ReflectionUtils.doWithFields( - entityClass, field -> addPart(field, owner), field -> field.isAnnotationPresent(Id.class)); - - assertNull(identifier); - } - - @Test - @SuppressWarnings("unchecked") - void testAddWithRepeatedProperty() { - Class entityClass = TestEntity.class; - - final List exceptedFields = getExpectedIdFields(entityClass); - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(ClassTypeInformation.from(entityClass), null); - - ReflectionUtils.doWithFields( - entityClass, field -> addPart(field, owner), field -> field.isAnnotationPresent(Id.class)); - - // repeat - assertNotNull(identifier); - identifier.addPart((P) ((List) identifier.getParts()).get(0)); - - assertNotNull(identifier); - final List addedFields = Arrays.asList(identifier.getFields()); - - compareFieldCollection(exceptedFields, addedFields); - } - - private Stream dataForTestEquals() { - final Function, List>> doCreateEntityAndGetProperties = - (entityType) -> { - final PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(ClassTypeInformation.from(entityType), null); - - ReflectionUtils.doWithFields( - entityType, - field -> addPart(field, owner), - field -> field.isAnnotationPresent(Id.class)); - - assertNotNull(identifier); - - return new ArrayList<>(identifier.getParts()); - }; - - return Stream.of( - Arguments.of( - doCreateEntityAndGetProperties, - TestEntity.class, - SecondTestEntity.class, - TestEntityWithOneId.class)); - } - - @ParameterizedTest - @MethodSource("dataForTestEquals") - void testEquals( - Function, List>> generatePropertiesFunction, - Class entityType, - Class sameEntityWithOtherClass, - Class entityWithOneId) { - // first set - List> firstPropertiesList = - generatePropertiesFunction.apply(entityType); - Identifier

firstIdentifier = identifier; - - identifier = null; - - // second set - List> secondPropertiesList = - generatePropertiesFunction.apply(entityType); - Identifier

secondIdentifier = identifier; - - identifier = null; - - // third set - List> thirdPropertiesList = - generatePropertiesFunction.apply(entityType); - Identifier

thirdIdentifier = identifier; - - identifier = null; - - // same set but with other class - List> samePropertiesListWithOtherClass = - generatePropertiesFunction.apply(sameEntityWithOtherClass); - Identifier

sameIdentifierWithOtherClass = identifier; - - identifier = null; - - // extra set - List> oneIdPropertiesList = - generatePropertiesFunction.apply(entityWithOneId); - Identifier

oneIdIdentifier = identifier; - - identifier = null; - - // always false - assertNotEquals(firstIdentifier, null); - assertNotEquals(null, firstIdentifier); - - // transitive - for (int i = 0; i < firstPropertiesList.size(); i++) { - assertEquals(firstPropertiesList.get(i), secondPropertiesList.get(i)); - assertEquals(firstPropertiesList.get(i), thirdPropertiesList.get(i)); - assertEquals(secondPropertiesList.get(i), thirdPropertiesList.get(i)); - - assertNotEquals(firstPropertiesList.get(i), samePropertiesListWithOtherClass.get(i)); - assertNotEquals(secondPropertiesList.get(i), samePropertiesListWithOtherClass.get(i)); - assertNotEquals(thirdPropertiesList.get(i), samePropertiesListWithOtherClass.get(i)); - } - - for (int i = 0; i < oneIdPropertiesList.size(); i++) { - assertNotEquals(firstPropertiesList.get(i), oneIdPropertiesList.get(i)); - assertNotEquals(secondPropertiesList.get(i), oneIdPropertiesList.get(i)); - assertNotEquals(thirdPropertiesList.get(i), oneIdPropertiesList.get(i)); - } - - // simple compare complex property - for (int i = 1; i < firstPropertiesList.size(); i++) { - assertNotEquals(firstPropertiesList.get(i), firstIdentifier); - assertNotEquals(firstIdentifier, firstPropertiesList.get(i)); - } - - // compare itself - assertEquals(firstIdentifier, firstIdentifier); - assertEquals(firstIdentifier, secondIdentifier); - assertEquals(secondIdentifier, thirdIdentifier); - - // compare complex same identifier but other class - assertNotEquals(firstIdentifier, sameIdentifierWithOtherClass); - assertNotEquals(secondIdentifier, sameIdentifierWithOtherClass); - assertNotEquals(thirdIdentifier, sameIdentifierWithOtherClass); - - // compare complex identifier with one id - assertNotEquals(firstIdentifier, oneIdIdentifier); - assertNotEquals(secondIdentifier, oneIdIdentifier); - assertNotEquals(thirdIdentifier, oneIdIdentifier); - } - - @Test - void testHashCode() { - Class entityClass = TestEntity.class; - - // first set - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(ClassTypeInformation.from(entityClass), null); - ReflectionUtils.doWithFields( - entityClass, field -> addPart(field, owner), field -> field.isAnnotationPresent(Id.class)); - - assertNotNull(identifier); - List> properties = new ArrayList<>(identifier.getParts()); - - Set> propertiesSet = new HashSet<>(properties); - - assertTrue(propertiesSet.containsAll(properties)); - } - - @Getter - static class TestEntity { - - @Id private long id; - - @Id private int secondId; - - private int age; - } - - @Getter - static class SecondTestEntity { - - @Id private long id; - - @Id private int secondId; - - private int age; - } - - @Getter - static class TestEntityWithOneId { - - @Id private long id; - - private int secondId; - - private int age; - } - - static class TestEntityWithoutId { - - private long id; - - @Nullable private String name; - - private int secondId; - } - - /** Create a PersistentProperty and add to first id property. */ - @SuppressWarnings("unchecked") - private void addPart(Field field, PersistentEntity owner) { - Property property = Property.of(owner.getTypeInformation(), field); - Identifier

persistentProperty = - new KeyValueCompositeProperty<>(property, owner, SimpleTypeHolder.DEFAULT); - - if (this.identifier == null) { - this.identifier = persistentProperty; - return; - } - this.identifier.addPart((P) persistentProperty); - } - - /** Compare fields by name and type. */ - private void compareFieldCollection(List first, List second) { - assertEquals(first.size(), second.size()); - - first.sort(Comparator.comparing(Field::getName)); - second.sort(Comparator.comparing(Field::getName)); - - for (int i = 0; i < first.size(); i++) { - assertEquals(first.get(i).getName(), second.get(i).getName()); - assertEquals(first.get(i).getType(), second.get(i).getType()); - } - } - - /** Get the expected fields marked with the {@code @Id} annotation. */ - private List getExpectedIdFields(Class entityClass) { - return Arrays.stream(entityClass.getDeclaredFields()) - .filter(field -> field.isAnnotationPresent(Id.class)) - .collect(Collectors.toList()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/mapping/TarantoolMappingContextTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/mapping/TarantoolMappingContextTest.java deleted file mode 100644 index 3fd1aeb0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/mapping/TarantoolMappingContextTest.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.core.mapping; - -import java.lang.reflect.Field; -import java.util.HashSet; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Test; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.ClassTypeInformation; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; - -import static io.tarantool.spring.data27.core.mapping.BasicKeyValueCompositePersistentEntity.KeyPartTypeChecker.COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION; -import static io.tarantool.spring.data27.core.mapping.BasicKeyValueCompositePersistentEntity.KeyPartTypeChecker.COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION; -import io.tarantool.spring.data27.core.mapping.BasicKeyValueCompositePersistentEntity.KeyPartTypeChecker; -import io.tarantool.spring.data27.utils.entity.ComplexPerson; -import io.tarantool.spring.data27.utils.entity.EntityWithInvalidKeyFieldsOrder; -import io.tarantool.spring.data27.utils.entity.EntityWithWrongCompositeKeyPartsCount; -import io.tarantool.spring.data27.utils.entity.EntityWithWrongFieldTypes; -import io.tarantool.spring.data27.utils.entity.Person; - -class TarantoolMappingContextTest { - - @Test - void testSetFallbackKeySpaceResolver() throws NoSuchFieldException { - final KeySpaceResolver RESOLVER = TestResolver.INSTANCE; - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - mappingContext.setFallbackKeySpaceResolver(RESOLVER); - - final Field field = TarantoolMappingContext.class.getDeclaredField("fallbackKeySpaceResolver"); - ReflectionUtils.makeAccessible(field); - - final Object resolverFieldValue = ReflectionUtils.getField(field, mappingContext); - - assertEquals(RESOLVER, resolverFieldValue); - } - - @Test - void testCreatePersistentEntity() { - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - final TypeInformation informationForSimpleClass = - ClassTypeInformation.from(Person.class); - - final TypeInformation informationForIdentifierClass = - ClassTypeInformation.from(ComplexPerson.class); - - assertInstanceOf( - KeyValueCompositePersistentEntity.class, createEntityForClass(ComplexPerson.class)); - - assertInstanceOf(KeyValuePersistentEntity.class, createEntityForClass(ComplexPerson.class)); - } - - @Test - void testCreatePersistentProperty() { - ReflectionUtils.FieldFilter idFilter = field -> field.isAnnotationPresent(Id.class); - - PersistentProperty simpleIdProperty = createProperty(Person.class, idFilter); - assertInstanceOf(KeyValuePersistentProperty.class, simpleIdProperty); - - PersistentProperty compositeIdProperty = createProperty(ComplexPerson.class, idFilter); - assertInstanceOf(KeyValueCompositeProperty.class, compositeIdProperty); - } - - @Test - void testCreateEntityWithWrongCompositeKeyPartTypes() { - Set> initialSet = - new HashSet>() { - { - add(EntityWithWrongFieldTypes.class); - } - }; - IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> initEntities(initialSet)); - - assertEquals(COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION, exception.getMessage()); - } - - @Test - void testCreateEntityWithWrongCompositeKeyPartCount() { - Set> initialSet = - new HashSet>() { - { - add(EntityWithWrongCompositeKeyPartsCount.class); - } - }; - IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> initEntities(initialSet)); - - assertEquals(COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION, exception.getMessage()); - } - - @Test - void testCreateEntityWithCompositeKeyFieldsInvalidOrder() { - Set> initialSet = - new HashSet>() { - { - add(EntityWithInvalidKeyFieldsOrder.class); - } - }; - IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> initEntities(initialSet)); - - assertEquals( - KeyPartTypeChecker.COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION, exception.getMessage()); - } - - /** - * Create a mappingContext from the passed domain classes. After initialize - create for them - * PersistentEntities and add PersistentProperties to them. - * - * @param entitySet - * @return - */ - private MappingContext initEntities(Set> entitySet) { - TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - mappingContext.setInitialEntitySet(entitySet); - mappingContext.initialize(); - return mappingContext; - } - - private enum TestResolver implements KeySpaceResolver { - INSTANCE; - - @Override - @Nullable - public String resolveKeySpace(Class type) { - - Assert.notNull(type, "Type for keyspace for null!"); - - Class userClass = ClassUtils.getUserClass(type); - Object keySpace = getKeySpace(userClass); - - return keySpace != null ? keySpace.toString() : null; - } - - @Nullable - private static Object getKeySpace(Class type) { - - KeySpace keyspace = AnnotatedElementUtils.findMergedAnnotation(type, KeySpace.class); - - if (keyspace != null) { - return AnnotationUtils.getValue(keyspace); - } - - return null; - } - } - - private PersistentEntity createEntityForClass(Class entityClass) { - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - final TypeInformation informationForClass = ClassTypeInformation.from(entityClass); - return mappingContext.createPersistentEntity(informationForClass); - } - - private

> PersistentProperty createProperty( - Class classType, ReflectionUtils.FieldFilter fieldFilter) { - - final TarantoolMappingContext, P> context = - new TarantoolMappingContext<>(); - KeyValuePersistentEntity entity = - context.createPersistentEntity(ClassTypeInformation.from(classType)); - Field field = org.springframework.data.util.ReflectionUtils.findField(classType, fieldFilter); - assertNotNull(field); - - return context.createPersistentProperty( - Property.of(entity.getTypeInformation(), field), entity, SimpleTypeHolder.DEFAULT); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java deleted file mode 100644 index d4817dde..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.core.mapping.model; - -import java.lang.reflect.Field; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.Test; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.ClassTypeInformation; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data27.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data27.core.mapping.BasicKeyValueCompositePersistentEntity; -import io.tarantool.spring.data27.core.mapping.KeyValueCompositeProperty; -import io.tarantool.spring.data27.utils.entity.ComplexPerson; - -public class PersistentCompositeIdIsNewStrategyTest

> { - - /** Check the strategy creation method and check whether the domain entity is new. */ - @Test - public void testForIdOnly() { - - // Currently identical like of 'of' method (version doesn't support) - PersistentCompositeIdIsNewStrategy strategy = - PersistentCompositeIdIsNewStrategy.forIdOnly(createPersistentEntity(ComplexPerson.class)); - - // Now is stub - always is false - ComplexPerson emptyEntity = new ComplexPerson(); - assertFalse(strategy.isNew(emptyEntity)); - } - - /** Check the strategy creation method and check whether the domain entity is new. */ - @Test - public void testIsNew() { - PersistentCompositeIdIsNewStrategy strategy = - PersistentCompositeIdIsNewStrategy.of(createPersistentEntity(ComplexPerson.class)); - - // Now is stub - always is false - ComplexPerson emptyEntity = new ComplexPerson(); - assertFalse(strategy.isNew(emptyEntity)); - } - - private BasicKeyValueCompositePersistentEntity createPersistentEntity(Class entityType) { - Class compositeKeyType = DefaultIdClassResolver.INSTANCE.resolveIdClassType(entityType); - assertNotNull(compositeKeyType); - - BasicKeyValueCompositePersistentEntity persistentEntity = - new BasicKeyValueCompositePersistentEntity<>( - ClassTypeInformation.from(entityType), null, compositeKeyType); - ReflectionUtils.doWithFields(entityType, field -> addProperty(field, persistentEntity)); - return persistentEntity; - } - - /** Add Persistent property into PersistentEntity. */ - @SuppressWarnings("unchecked") - private void addProperty(Field field, BasicKeyValueCompositePersistentEntity owner) { - Property property = Property.of(owner.getTypeInformation(), field); - P persistentProperty = - (P) new KeyValueCompositeProperty<>(property, owner, SimpleTypeHolder.DEFAULT); - owner.addPersistentProperty(persistentProperty); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/BaseIntegrationTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/BaseIntegrationTest.java deleted file mode 100644 index 5ad4a389..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/BaseIntegrationTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.integration; - -import java.io.IOException; -import java.nio.file.Files; -import java.time.Duration; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Timeout; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.cluster.ClusterContainer; -import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer; -import org.testcontainers.containers.cluster.vshard.VshardClusterContainer; -import org.testcontainers.containers.output.Slf4jLogConsumer; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.spring.data27.config.properties.TarantoolProperties; - -@Timeout(60) -public abstract class BaseIntegrationTest { - - protected static ClusterContainer clusterContainer; - - private static final String dockerRegistry = - System.getenv().getOrDefault("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", ""); - - @BeforeAll - protected static void beforeAll() throws IOException { - configureContainer(); - writeConfigurationFile(); - } - - private static void configureContainer() { - if (!isCartridgeAvailable()) { - VshardClusterContainer vshardClusterContainer = - new VshardClusterContainer( - "vshard_cluster/Dockerfile", - dockerRegistry + "vshard-cluster-java", - "vshard_cluster/instances.yaml", - "vshard_cluster/config.yaml", - "tarantool/tarantool"); - - if (!vshardClusterContainer.isRunning()) { - vshardClusterContainer.withPrivilegedMode(true); - vshardClusterContainer.start(); - } - clusterContainer = vshardClusterContainer; - } else { - CartridgeClusterContainer cartridgeContainer = - new CartridgeClusterContainer( - "cartridge/Dockerfile", - dockerRegistry + "cartridge", - "cartridge/instances.yml", - "cartridge/replicasets.yml", - org.testcontainers.containers.Arguments.get("tarantool/tarantool")) - .withStartupTimeout(Duration.ofMinutes(5)) - .withLogConsumer( - new Slf4jLogConsumer(LoggerFactory.getLogger(BaseIntegrationTest.class))); - - if (!cartridgeContainer.isRunning()) { - cartridgeContainer.start(); - } - clusterContainer = cartridgeContainer; - } - } - - private static void writeConfigurationFile() throws IOException { - final TarantoolProperties properties = new TarantoolProperties(); - properties.setHost(clusterContainer.getHost()); - properties.setPort(clusterContainer.getPort()); - properties.setUserName(clusterContainer.getUsername()); - properties.setPassword(clusterContainer.getPassword()); - - writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME, properties); - } - - @AfterAll - protected static void afterAll() throws IOException { - Files.deleteIfExists(DEFAULT_TEST_PROPERTY_DIR.resolve(DEFAULT_PROPERTY_FILE_NAME)); - } - - protected static String getHost() { - return clusterContainer.getHost(); - } - - protected static int getPort() { - return clusterContainer.getPort(); - } - - protected static String getUsername() { - return clusterContainer.getUsername(); - } - - protected static String getPassword() { - return clusterContainer.getPassword(); - } - - protected static boolean isCartridgeAvailable() { - return System.getenv().getOrDefault("TARANTOOL_VERSION", "").matches("2.*"); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/CrudConfigurations.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/CrudConfigurations.java deleted file mode 100644 index b3d4d624..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/CrudConfigurations.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.integration.crud; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.TestPropertySource; - -import static io.tarantool.client.TarantoolClient.DEFAULT_TAG; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.PERSON_SPACE; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data27.integration.BaseIntegrationTest; -import io.tarantool.spring.data27.repository.config.EnableTarantoolRepositories; - -@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -abstract class CrudConfigurations extends BaseIntegrationTest { - - @Autowired protected TarantoolCrudClient client; - - private static InstanceConnectionGroup groupFromJavaConfig; - - private static final String PACKAGE_PATH = "io.tarantool.spring.data27.utils.core"; - - @BeforeAll - protected static void beforeAll() throws IOException { - BaseIntegrationTest.beforeAll(); - groupFromJavaConfig = - InstanceConnectionGroup.builder() - .withHost(clusterContainer.getHost()) - .withPort(clusterContainer.getPort()) - .withUser(getUsername()) - .withPassword(getPassword()) - .withTag(DEFAULT_TAG) - .withSize(4) - .build(); - } - - @BeforeEach - public void truncateSpaces() { - client.space(PERSON_SPACE).truncate().join(); - client.space(COMPLEX_PERSON_SPACE).truncate().join(); - } - - @EnableTarantoolRepositories(basePackages = {PACKAGE_PATH}) - @Configuration - static class JavaConfigConfiguration { - - @Bean - TarantoolCrudClientBuilder crudClientBuilder() { - return TarantoolFactory.crud().withGroups(Collections.singletonList(groupFromJavaConfig)); - } - } - - @EnableTarantoolRepositories(basePackages = {PACKAGE_PATH}) - @Configuration - static class ViaPropertyFileConfiguration {} - - @Test - void testSimpleClient() { - TarantoolCrudSpace space = client.space(PERSON_SPACE); - - assertEquals(0, space.select().join().size()); - - List tuple = Arrays.asList(0, true, "petya"); - List insertTuple = space.insert(tuple).join().get(); - - assertEquals(tuple, insertTuple.subList(0, insertTuple.size() - 1)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/GenericRepositoryTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/GenericRepositoryTest.java deleted file mode 100644 index abff0c85..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/GenericRepositoryTest.java +++ /dev/null @@ -1,1649 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.integration.crud; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.util.Streamable; - -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data27.query.TarantoolQueryCreator.INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.UNKNOWN_PERSON; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.generateAndInsertPersons; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.mapping.Tuple; -import io.tarantool.spring.data.query.Conditions; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data27.query.TarantoolPageRequest; -import io.tarantool.spring.data27.utils.TarantoolTestSupport; -import io.tarantool.spring.data27.utils.core.ComplexPersonRepository; -import io.tarantool.spring.data27.utils.core.GenericPaginationMethods; -import io.tarantool.spring.data27.utils.core.PersonRepository; -import io.tarantool.spring.data27.utils.entity.ComplexPerson; -import io.tarantool.spring.data27.utils.entity.Person; - -abstract class GenericRepositoryTest extends CrudConfigurations { - - @Autowired protected ApplicationContext context; - - protected static BiFunction> - complexPersonGenerateAndInsertFunction = - (context, personCount) -> - generateAndInsertComplexPersons( - personCount, context.getBean(TarantoolCrudClient.class)); - - protected static BiFunction> - personGenerateAndInsertFunction = - (context, personCount) -> - generateAndInsertPersons(personCount, context.getBean(TarantoolCrudClient.class)); - - protected static Function> complexPersonGenerateFunction = - TarantoolTestSupport::generateComplexPersons; - - protected static Function> personGenerateFunction = - TarantoolTestSupport::generatePersons; - - protected static Stream dataForTestRepositoryWithFindByIs() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByIs") - , ID> void testRepositoryWithFindByIs( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - List foundPersons = repository.findByName(person.getName()); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(1, foundPersons.size()); - assertEquals(person, foundPersons.get(0)); - } - - protected static Stream dataForTestRepositoryWithFindById() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindById") - , ID> void testRepositoryWithFindById( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - Optional foundPerson = repository.findById(person.generateFullKey()); - - assertTrue(foundPerson.isPresent()); - assertEquals(person, foundPerson.get()); - } - - protected static Stream dataForTestRepositoryWithFindAllById() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllById") - , ID> void testRepositoryWithFindAllById( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - Iterable foundPersons = - repository.findAllById( - persons.stream().map(PERSON::generateFullKey).collect(Collectors.toList())); - List foundPersonsAsList = - StreamSupport.stream(foundPersons.spliterator(), false) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(persons, foundPersonsAsList); - } - - protected static Stream dataForTestRepositoryWithCount() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithCount") - , ID> void testRepositoryWithCount( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - assertEquals(PERSONS_COUNT, context.getBean(repositoryClass).count()); - } - - protected static Stream dataForTestRepositoryWithCountBy() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithCountBy") - , ID> void testRepositoryWithCountBy( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - assertEquals(1, repository.countByName(person.getName())); - } - - protected static Stream dataForTestRepositoryWithDelete() { - return Stream.of( - Arguments.of( - personGenerateFunction, - PersonRepository.class, - PERSON_SPACE, - (BiFunction>) - (space, key) -> { - Tuple tuple = - space.get(Collections.singletonList(key), Person.class).join(); - if (tuple != null) { - return tuple.get(); - } - return null; - }), - Arguments.of( - complexPersonGenerateFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (BiFunction>) - (space, key) -> { - Tuple tuple = space.get(key, ComplexPerson.class).join(); - if (tuple != null) { - return tuple.get(); - } - return null; - })); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithDelete") - , ID> void testRepositoryWithDelete( - Function> generateFunction, - Class> repositoryClass, - String spaceName, - BiFunction spaceGetFunction) { - - final List persons = generateFunction.apply(PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - space.insertMany(persons).join(); - - final PERSON deletingPerson = persons.get(0); - - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - // by object - repository.delete(deletingPerson); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - space.insert(deletingPerson).join(); - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - // by id - repository.deleteById(deletingPerson.generateFullKey()); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - space.insert(deletingPerson).join(); - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - // by name - repository.deleteByName(deletingPerson.getName()); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - } - - protected static Stream dataForTestRepositoryWithExistId() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiConsumer) - (space, key) -> space.delete(Collections.singletonList(key)).join(), - PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - (BiConsumer) (space, key) -> space.delete(key).join(), - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithExistId") - , ID> void testRepositoryWithExistId( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - BiConsumer deleteConsumer, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final PERSON person = persons.get(0); - - assertTrue(repository.existsById(person.generateFullKey())); - deleteConsumer.accept(space, person.generateFullKey()); - assertFalse(repository.existsById(person.generateFullKey())); - } - - protected static Stream dataForTestQueryAnnotationAsCall() { - return Stream.of( - Arguments.of(PersonRepository.class), Arguments.of(ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsCall") - , ID> void testQueryAnnotationAsCall( - Class> repositoryClass) { - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - assertEquals(Arrays.asList(1, "hi", false), repository.getStatic().get()); - } - - protected static Stream dataForTestQueryAnnotationAsCallWithArgs() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsCallWithArgs") - , ID> void testQueryAnnotationAsCallWithArgs( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals(Arrays.asList("hello", true, 13), repository.echo("hello", true, 13).get()); - } - - protected static Stream dataForTestQueryAnnotationAsEval() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsEval") - , ID> void testQueryAnnotationAsEval( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals(Arrays.asList("hello", 123, true), repository.evalGetStatic().get()); - } - - protected static Stream dataForTestQueryAnnotationAsEvalWithArgs() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsEvalWithArgs") - , ID> void testQueryAnnotationAsEvalWithArgs( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals( - Arrays.asList("hello", true, 13), repository.evalWithArgs("hello", true, 13).get()); - } - - protected static Stream dataForTestRepositoryWithExistName() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiConsumer) - (space, key) -> space.delete(Collections.singletonList(key)).join(), - PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - (BiConsumer) (space, key) -> space.delete(key).join(), - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithExistName") - , ID> void testRepositoryWithExistName( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - BiConsumer deleteConsumer, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final PERSON person = persons.get(0); - - assertTrue(repository.existsByName(person.getName())); - deleteConsumer.accept(space, person.generateFullKey()); - assertFalse(repository.existsByName(person.getName())); - } - - protected static Stream dataForTestRepositoryWithFindByLessThan() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByLessThan") - , ID> void testRepositoryWithFindByLessThan( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 10; - final List foundPersons = repository.findAllByIdIsLessThan(findLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(findLimiter, foundPersons.size()); - assertEquals(persons.subList(0, findLimiter), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsTrue() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsTrue") - , ID> void testRepositoryWithFindAllByIsMarriedIsTrue( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsTrue(); - assertEquals(PERSONS_COUNT / 3, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(GenericPerson::getIsMarried)); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsFalse() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsFalse") - , ID> void testRepositoryWithFindAllByIsMarriedIsFalse( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsFalse(); - assertEquals(PERSONS_COUNT / 3, foundPersons.size()); - assertTrue(foundPersons.stream().noneMatch(GenericPerson::getIsMarried)); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsNull() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsNull") - , ID> void testRepositoryWithFindAllByIsMarriedIsNull( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsNull(); - assertEquals(PERSONS_COUNT / 3 + 1, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(p -> p.getIsMarried() == null)); - } - - protected static Stream dataForTestRepositoryWithFindAllByNameIsEmpty() { - return Stream.of( - Arguments.of(personGenerateFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByNameIsEmpty") - , ID> void testRepositoryWithFindAllByNameIsEmpty( - Function> generateFunction, - Class> repositoryClass) { - - List persons = generateFunction.apply(PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - PERSON person = persons.get(0); - person.setName(""); - persons.set(0, person); - - repository.saveAll(persons); - - final List foundPersons = repository.findAllByNameIsEmpty(); - assertEquals(1, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(p -> p.getName().isEmpty())); - } - - protected static Stream dataForTestRepositoryWithFindByLessThanEqual() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByLessThanEqual") - , ID> void testRepositoryWithFindByLessThanEqual( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 10; - final List foundPersonsWithEqual = repository.findAllByIdLessThanEqual(findLimiter); - - foundPersonsWithEqual.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(findLimiter + 1, foundPersonsWithEqual.size()); - assertEquals(persons.subList(0, findLimiter + 1), foundPersonsWithEqual); - } - - protected static Stream dataForTestRepositoryWithFindByGreaterThan() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByGreaterThan") - , ID> void testRepositoryWithFindByGreaterThan( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 90; - final List foundPersons = repository.findAllByIdIsGreaterThan(findLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(PERSONS_COUNT - findLimiter - 1, foundPersons.size()); - assertEquals(persons.subList(findLimiter + 1, PERSONS_COUNT), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindByGreaterThanEqual() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByGreaterThanEqual") - , ID> void testRepositoryWithFindByGreaterThanEqual( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 90; - final List foundPersonsWithEqual = repository.findAllByIdGreaterThanEqual(findLimiter); - - foundPersonsWithEqual.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(PERSONS_COUNT - findLimiter, foundPersonsWithEqual.size()); - assertEquals(persons.subList(findLimiter, PERSONS_COUNT), foundPersonsWithEqual); - } - - protected static Stream dataForTestRepositoryWithFindByBetween() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByBetween") - , ID> void testRepositoryWithFindByBetween( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int startFindLimiter = 50; - final int endFindLimiter = 90; - final List foundPersons = - repository.findAllByIdBetween(startFindLimiter, endFindLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - final int foundPersonsCount = endFindLimiter - startFindLimiter - 1; - assertEquals(foundPersonsCount, foundPersons.size()); - assertEquals(persons.subList(startFindLimiter + 1, endFindLimiter), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindByBetweenNegativeInts() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByBetweenNegativeInts") - , ID> void testRepositoryWithFindByBetweenNegativeInts( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int startFindLimiter = -1; - final int endFindLimiter = -10; - final List foundPersons = - repository.findAllByIdBetween(startFindLimiter, endFindLimiter); - assertTrue(foundPersons.isEmpty()); - } - - protected static Stream dataForTestRepositoryIgnoreCase() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryIgnoreCase") - , ID> void testRepositoryIgnoreCase( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - final String name = persons.get(0).getName(); - - final InvalidDataAccessApiUsageException exception = - assertThrows( - InvalidDataAccessApiUsageException.class, () -> repository.findByNameIgnoreCase(name)); - final String EXCEPTION_MESSAGE = - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "IgnoreCase isn't supported yet", - Part.Type.SIMPLE_PROPERTY); - assertEquals(EXCEPTION_MESSAGE, exception.getMessage()); - } - - protected static Stream dataForTestRepositoryWithTarantoolNamingNotation() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithTarantoolNamingNotation") - , ID> void testRepositoryWithTarantoolNamingNotation( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List marriedPersons = repository.findByIsMarried(true); - final List nonMarriedPersons = repository.findByIsMarried(false); - final int expectedCount = PERSONS_COUNT / 3; - assertEquals(expectedCount, marriedPersons.size()); - assertEquals(expectedCount, nonMarriedPersons.size()); - } - - protected static Stream dataForTestRepositoryNotEnoughArguments() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryNotEnoughArguments") - , ID> void testRepositoryNotEnoughArguments( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertThrows(InvalidDataAccessApiUsageException.class, repository::findById); - } - - protected static Stream dataForTestRepositorySave() { - return dataForTestRepositoryWithDelete(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySave") - , ID> void testRepositorySave( - Function> generateFunction, - Class> repositoryClass, - String spaceName, - BiFunction getFunction) { - - List persons = generateFunction.apply(PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - TarantoolCrudSpace space = client.space(spaceName); - final PERSON person = persons.get(0); - - repository.save(person); - - PERSON gotPerson = getFunction.apply(space, person.generateFullKey()); - assertEquals(person, gotPerson); - } - - protected static Stream dataForTestRepositorySaveAll() { - Conditions conditions = new Conditions(); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - PERSON_SPACE, - (Function>) - (space) -> unwrapTuples(space.select(conditions, Person.class).join())), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (Function>) - (space) -> unwrapTuples(space.select(conditions, ComplexPerson.class).join()))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySaveAll") - , ID> void testRepositorySaveAll( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - Function> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - repository.saveAll(persons); - - List selectedPersons = selectFunction.apply(space); - selectedPersons.sort(Comparator.comparing(GenericPerson::getId)); - - assertEquals(persons, selectedPersons); - } - - protected static Stream dataForTestDeleteAll() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class, PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteAll") - , ID> void testDeleteAll( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow(() -> repository.deleteAll()); - assertEquals(0, space.count(new Conditions()).join()); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow(() -> repository.deleteAll(persons)); - assertEquals(0, space.count(new Conditions()).join()); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow( - () -> - repository.deleteAllById( - persons.stream().map(PERSON::generateFullKey).collect(Collectors.toList()))); - assertEquals(0, space.count(new Conditions()).join()); - } - - protected static Stream dataForTestRepositoryFindByAfter() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByAfter") - , ID> void testRepositoryFindByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - final List selectedPersons = repository.findByNameAfter(person.getName()); - selectedPersons.sort(Comparator.comparing(PERSON::getName)); - - final List expectedList = - persons.stream() - .filter(p -> p.getName().compareTo(person.getName()) > 0) - .limit(SelectOptions.DEFAULT_LIMIT) - .sorted(Comparator.comparing(PERSON::getName)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - } - - protected static Stream dataForTestRepositoryFindByAfterWithLimit() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByAfterWithLimit") - , ID> void testRepositoryFindByAfterWithLimit( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int LIMIT = 5; - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findFirst5ByIdAfter(person.getId()); - selectedPersons.sort(Comparator.comparing(PERSON::getId)); - - final List selectedPersonsWithTopKeyword = repository.findTop5ByIdAfter(person.getId()); - selectedPersonsWithTopKeyword.sort(Comparator.comparing(PERSON::getId)); - - final List expectedList = - persons.stream() - .filter(p -> p.getId().compareTo(person.getId()) > 0) - .limit(LIMIT) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - - assertEquals(expectedList.size(), selectedPersonsWithTopKeyword.size()); - assertEquals(expectedList, selectedPersonsWithTopKeyword); - } - - protected static Stream dataForTestRepositoryFindByBefore() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByBefore") - , ID> void testRepositoryFindByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findByNameBefore(person.getName()); - selectedPersons.sort(Comparator.comparing(PERSON::getName)); - - final List expectedList = - persons.stream() - .filter(p -> p.getName().compareTo(person.getName()) < 0) - .limit(SelectOptions.DEFAULT_LIMIT) - .sorted(Comparator.comparing(PERSON::getName)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - } - - protected static Stream dataForTestRepositoryFindByBeforeWithLimit() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByBeforeWithLimit") - , ID> void testRepositoryFindByBeforeWithLimit( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int LIMIT = 5; - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findFirst5ByIdBefore(person.getId()); - selectedPersons.sort(Comparator.comparing(PERSON::getId)); - - final List selectedPersonsWithTopKeyword = - repository.findTop5ByIdBefore(person.getId()); - selectedPersonsWithTopKeyword.sort(Comparator.comparing(PERSON::getId)); - - // Because id (not fullscan) - persons.sort(Comparator.comparing(PERSON::getId, (o1, o2) -> Integer.compare(o2, o1))); - - final List expectedList = - persons.stream() - .filter(p -> p.getId().compareTo(person.getId()) < 0) - .limit(LIMIT) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - - assertEquals(expectedList.size(), selectedPersonsWithTopKeyword.size()); - assertEquals(expectedList, selectedPersonsWithTopKeyword); - } - - protected static Stream dataForTestDeleteByAfter() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - PERSON_SPACE, - (BiFunction>) - (space, options) -> - unwrapTuples( - space.select(Collections.emptyList(), options, Person.class).join())), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (BiFunction>) - (space, options) -> - unwrapTuples( - space - .select(Collections.emptyList(), options, ComplexPerson.class) - .join()))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteByAfter") - , ID> void testDeleteByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - BiFunction> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - persons.sort(Comparator.comparing(PERSON::getName)); - - final int RANDOM_INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final SelectOptions options = SelectOptions.builder().withFirst(PERSONS_COUNT).build(); - final PERSON deletingAfterPerson = persons.get(RANDOM_INDEX); - - final List deletedPersons = repository.deleteByNameAfter(deletingAfterPerson.getName()); - - List allPersonsInBaseAfterDeleted = selectFunction.apply(space, options); - assertEquals(PERSONS_COUNT - deletedPersons.size(), allPersonsInBaseAfterDeleted.size()); - - persons.removeAll(deletedPersons); - allPersonsInBaseAfterDeleted.sort(Comparator.comparing(PERSON::getId)); - persons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(persons, allPersonsInBaseAfterDeleted); - } - - protected static Stream dataForTestDeleteByBefore() { - return dataForTestDeleteByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteByBefore") - , ID> void testDeleteByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - BiFunction> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final SelectOptions options = SelectOptions.builder().withFirst(PERSONS_COUNT).build(); - final int RANDOM_INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - - final PERSON deletingBeforePerson = persons.get(RANDOM_INDEX); - final List deletedPersons = - repository.deleteByNameBefore(deletingBeforePerson.getName()); - - List allPersonsInBaseAfterDeleted = selectFunction.apply(space, options); - - assertEquals(PERSONS_COUNT - deletedPersons.size(), allPersonsInBaseAfterDeleted.size()); - - persons.removeAll(deletedPersons); - allPersonsInBaseAfterDeleted.sort(Comparator.comparing(PERSON::getId)); - persons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(persons, allPersonsInBaseAfterDeleted); - } - - protected static Stream dataForTestCountByAfter() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestCountByAfter") - , ID> void testCountByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final int ID_AFTER = persons.get(INDEX).getId(); - - final long count = repository.countByIdAfter(ID_AFTER); - - final int EXPECTED_COUNT = PERSONS_COUNT - ID_AFTER - 1; - assertEquals(EXPECTED_COUNT, count); - } - - protected static Stream dataForTestCountByBefore() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestCountByBefore") - , ID> void testCountByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - persons.sort(Comparator.comparing(PERSON::getName)); - - final int indexBefore = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final String name = persons.get(indexBefore).getName(); - final long count = repository.countByNameBefore(name); - - assertEquals(indexBefore, count); - - final long unknownNameCount = repository.countByNameBefore(UNKNOWN_PERSON.getName()); - assertEquals(0, unknownNameCount); - } - - protected static < - REPO extends GenericPaginationMethods, PERSON extends GenericPerson, ID> - Stream dataForTestRepositorySlicePagePageableEqual() { - final int PAGE_SIZE = ThreadLocalRandom.current().nextInt(1, PERSONS_COUNT / 3 - 1); - final String NAME = "name"; - final Pageable beginPageable = new TarantoolPageRequest>(PAGE_SIZE); - - BiFunction> generatePersonAndInsertFunction = - (context, size) -> - generateAndInsertPersons( - size, context.getBean(TarantoolCrudClient.class), (person) -> person.setName(NAME)); - - BiFunction> - generateComplexPersonAndInsertFunction = - (context, size) -> - generateAndInsertComplexPersons( - size, - context.getBean(TarantoolCrudClient.class), - (person) -> person.setName(NAME)); - - Function personRepositoryFunc = - (context) -> context.getBean(PersonRepository.class); - - Function complexPersonRepositoryFunc = - (context) -> context.getBean(ComplexPersonRepository.class); - - BiFunction> executionForFindAllByName = - (repo, pageable) -> repo.findAllByName(NAME, pageable); - - Function, List> expectedListForFindAllByNameFunc = - (persons) -> - persons.stream() - .filter(person -> NAME.equals(person.getName())) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()) - .subList(0, PAGE_SIZE); - - BiFunction> executionForFindByName = - (repo, pageable) -> repo.findPersonByName(NAME, pageable); - - List> generateFunctionPairs = - Arrays.asList( - Arrays.asList(generatePersonAndInsertFunction, personRepositoryFunc), - Arrays.asList(generateComplexPersonAndInsertFunction, complexPersonRepositoryFunc)); - - List executionFunctions = Arrays.asList(executionForFindAllByName, executionForFindByName); - - // add arguments set - List arguments = new ArrayList<>(); - for (List generateFunctionPair : generateFunctionPairs) { - for (Object executionFunction : executionFunctions) { - arguments.add( - Arguments.of( - generateFunctionPair.get(0), - executionFunction, - generateFunctionPair.get(1), - expectedListForFindAllByNameFunc, - beginPageable)); - } - } - - return arguments.stream(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySlicePagePageableEqual") - , PERSON extends GenericPerson, ID> - void testRepositorySlicePagePageableEqual( - BiFunction> generateAndInsertFunction, - BiFunction> executingRepositoryMethod, - Function giveRepositoryFunction, - Function, List> expectedSlicePageContent, - Pageable beginPageable) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - Slice slicePage = - executingRepositoryMethod.apply(giveRepositoryFunction.apply(context), beginPageable); - - assertEquals(beginPageable, slicePage.getPageable()); - assertEquals(expectedSlicePageContent.apply(persons), slicePage.getContent()); - } - - protected static Stream dataForTestRepositorySliceMethodWithoutPageable() { - final String NAME = "name"; - return Stream.of( - Arguments.of(PersonRepository.class, NAME), - Arguments.of(ComplexPersonRepository.class, NAME)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySliceMethodWithoutPageable") - , ID> void testRepositorySliceMethodWithoutPageable( - Class> repositoryClass, String name) { - GenericPaginationMethods repository = context.getBean(repositoryClass); - - assertEquals(Pageable.unpaged(), repository.findAllByName(name).getPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).nextPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).nextOrLastPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).previousPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).previousOrFirstPageable()); - } - - @SuppressWarnings("unchecked") - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Stream dataForTestRepositorySliceWithDifferentFields() { - final int PAGE_SIZE = 10; - - Function, Pageable> nextPageableFunc = Slice::nextPageable; - Function, Pageable> prevPageableFunc = Slice::previousPageable; - Function, Pageable> nextOrLastPageableFunc = Slice::nextOrLastPageable; - Function, Pageable> prevOrFirstPageableFunc = Slice::previousOrFirstPageable; - BiFunction predicateForNextPageableFunc = - (currentPageable, nextPageable) -> nextPageable.isPaged(); - - BiFunction predicateForNextOrPageableFunc = - (currentPageable, nextPageable) -> !currentPageable.equals(nextPageable); - - Function personRepositoryFunc = - (context) -> context.getBean(PersonRepository.class); - - Function complexPersonRepositoryFunc = - (context) -> context.getBean(ComplexPersonRepository.class); - - Pageable beginPageable = new TarantoolPageRequest<>(PAGE_SIZE); - - BiFunction, Integer, Integer> idExtractionFunction = - (args, index) -> { - List persons = (List) args.get(0); - return persons.get(index).getId(); - }; - - BiFunction, Integer, String> nameExtractionFunction = - (args, index) -> { - List persons = (List) args.get(0); - return persons.get(index).getName(); - }; - - BiFunction, Slice> executionForFindAllByIdLessThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, PERSONS_COUNT - 1); - return repo.findAllByIdLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByIdLessThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, PERSONS_COUNT - 1); - return repo.findPersonByIdLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByIdGreaterThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, 0); - return repo.findAllByIdGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByIdGreaterThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, 0); - return repo.findPersonByIdGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByIsMarriedLessThanEqual = - (repo, arguments) -> - repo.findAllByIsMarriedLessThanEqual(false, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindPersonByIsMarriedLessThanEqual = - (repo, arguments) -> - repo.findPersonByIsMarriedLessThanEqual(false, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindAllByIsMarriedGreaterThanEqual = - (repo, arguments) -> - repo.findAllByIsMarriedGreaterThanEqual(null, (Pageable) arguments.get(1)); - - BiFunction, Slice> - executionForFindPersonByIsMarriedGreaterThanEqual = - (repo, arguments) -> - repo.findPersonByIsMarriedGreaterThanEqual(null, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindAllByNameLessThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findAllByNameLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByNameLessThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findPersonByNameLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByNameGreaterThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findAllByNameGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByNameGreaterThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findPersonByNameGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAll = - (repo, arguments) -> repo.findAll((Pageable) arguments.get(1)); - - Function, List> expectedListForFindAllByIdLessThanEqualFunc = - (persons) -> - persons.stream() - .sorted(Comparator.comparing(PERSON::getId).reversed()) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByIdGreaterThanEqualFunc = - (persons) -> persons; - - Function, List> expectedListForFindAllByIsMarriedGreaterThanEqual = - (persons) -> - persons.stream() - .sorted( - Comparator.comparing( - PERSON::getIsMarried, Comparator.nullsFirst(Comparator.naturalOrder()))) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByIsMarriedLessThanEqual = - (persons) -> - persons.stream() - .filter(person -> person.getIsMarried() == null || !person.getIsMarried()) - .sorted( - Comparator.comparing( - PERSON::getIsMarried, Comparator.nullsLast(Comparator.naturalOrder())) - .thenComparing(Comparator.comparing(PERSON::getId).reversed())) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByNameLessThanEqual = - (persons) -> { - String name = persons.get(persons.size() / 2).getName(); - return persons.stream() - .filter(person -> person.getName().compareTo(name) <= 0) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - }; - - Function, List> expectedListForFindAllByNameGreaterThanEqual = - (persons) -> { - String name = persons.get(persons.size() / 2).getName(); - return persons.stream() - .filter(person -> person.getName().compareTo(name) >= 0) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - }; - - Function, List> expectedListForFindAll = (persons) -> persons; - - List> getNextPageableMethodFunctionPairs = - Arrays.asList( - Arrays.asList(nextPageableFunc, prevPageableFunc, predicateForNextPageableFunc), - Arrays.asList( - nextOrLastPageableFunc, prevOrFirstPageableFunc, predicateForNextOrPageableFunc)); - - List> generateFunctions = - Arrays.asList( - Arrays.asList(personGenerateAndInsertFunction, personRepositoryFunc), - Arrays.asList(complexPersonGenerateAndInsertFunction, complexPersonRepositoryFunc)); - - List> executeExpectedFunctionPairs = - Arrays.asList( - Arrays.asList( - executionForFindAllByIdLessThanEqualFunc, - expectedListForFindAllByIdLessThanEqualFunc), - Arrays.asList( - executionForFindAllByIdGreaterThanEqualFunc, - expectedListForFindAllByIdGreaterThanEqualFunc), - Arrays.asList( - executionForFindAllByIsMarriedGreaterThanEqual, - expectedListForFindAllByIsMarriedGreaterThanEqual), - Arrays.asList( - executionForFindAllByIsMarriedLessThanEqual, - expectedListForFindAllByIsMarriedLessThanEqual), - Arrays.asList( - executionForFindAllByNameLessThanEqual, expectedListForFindAllByNameLessThanEqual), - Arrays.asList( - executionForFindAllByNameGreaterThanEqual, - expectedListForFindAllByNameGreaterThanEqual), - Arrays.asList( - executionForFindPersonByIdLessThanEqualFunc, - expectedListForFindAllByIdLessThanEqualFunc), - Arrays.asList( - executionForFindPersonByIdGreaterThanEqualFunc, - expectedListForFindAllByIdGreaterThanEqualFunc), - Arrays.asList( - executionForFindPersonByIsMarriedGreaterThanEqual, - expectedListForFindAllByIsMarriedGreaterThanEqual), - Arrays.asList( - executionForFindPersonByIsMarriedLessThanEqual, - expectedListForFindAllByIsMarriedLessThanEqual), - Arrays.asList( - executionForFindPersonByNameLessThanEqual, - expectedListForFindAllByNameLessThanEqual), - Arrays.asList( - executionForFindPersonByNameGreaterThanEqual, - expectedListForFindAllByNameGreaterThanEqual), - Arrays.asList(executionForFindAll, expectedListForFindAll)); - - // add arguments set - List arguments = new ArrayList<>(); - for (List generateFunctionPair : generateFunctions) { - for (List getNextPrevPageableFuncTriple : getNextPageableMethodFunctionPairs) { - for (List executeExpectedFunctionPair : executeExpectedFunctionPairs) { - arguments.add( - Arguments.of( - generateFunctionPair.get(0), - generateFunctionPair.get(1), - executeExpectedFunctionPair.get(0), - getNextPrevPageableFuncTriple.get(0), - getNextPrevPageableFuncTriple.get(1), - getNextPrevPageableFuncTriple.get(2), - executeExpectedFunctionPair.get(1), - beginPageable)); - } - } - } - return arguments.stream(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySliceWithDifferentFields") - , ID> void testRepositorySliceWithDifferentFields( - BiFunction> generateAndInsertFunction, - Function> giveRepositoryFunction, - BiFunction, List, Slice> - executingRepositoryMethod, - Function, Pageable> nextPageableMethod, - Function, Pageable> prevPageableMethod, - BiFunction stopPaginationPredicateFunction, - Function, List> expectedResultListMovingFunction, - Pageable beginPageable) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - - // moving forward - Pageable nextPageable = beginPageable; - List> forwardSlices = new ArrayList<>(); - Slice slice; - do { - slice = - executingRepositoryMethod.apply( - giveRepositoryFunction.apply(context), Arrays.asList(persons, nextPageable)); - forwardSlices.add(slice); - nextPageable = nextPageableMethod.apply(slice); - } while (stopPaginationPredicateFunction.apply(slice.getPageable(), nextPageable)); - - List forwardMovingResultList = - forwardSlices.stream().flatMap(Streamable::stream).collect(Collectors.toList()); - assertEquals(expectedResultListMovingFunction.apply(persons), forwardMovingResultList); - - // moving backward - List> reverseSlices = new ArrayList<>(); - nextPageable = forwardSlices.get(forwardSlices.size() - 1).getPageable(); - do { - slice = - executingRepositoryMethod.apply( - giveRepositoryFunction.apply(context), Arrays.asList(persons, nextPageable)); - reverseSlices.add(slice); - nextPageable = prevPageableMethod.apply(slice); - } while (stopPaginationPredicateFunction.apply(slice.getPageable(), nextPageable)); - - List backwardMovingResultList = - reverseSlices.stream() - .sorted(Comparator.comparing(Slice::getNumber)) - .flatMap(Streamable::stream) - .collect(Collectors.toList()); - - assertEquals(expectedResultListMovingFunction.apply(persons), backwardMovingResultList); - } - - protected static Stream dataForTestUnsupportedRepositoryMethods() { - return Stream.of(PersonRepository.class, ComplexPersonRepository.class); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestUnsupportedRepositoryMethods") - , ID, REPO extends GenericPaginationMethods> - void testUnsupportedRepositoryMethods(Class repositoryClass) { - final REPO repository = context.getBean(repositoryClass); - - assertThrows(UnsupportedOperationException.class, repository::findAll); - assertThrows(UnsupportedOperationException.class, () -> repository.findAll(Sort.unsorted())); - } - - protected static Stream dataForTestPageableWithTrueCursorAndPageNumber() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(PAGE_SIZE), - PAGES_COUNT, - PAGES_COUNT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(1, PAGE_SIZE, new Person(9, null, "User-9")), - PAGES_COUNT - 1, - PAGES_COUNT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(2, PAGE_SIZE, new Person(19, null, "User-19")), - PAGES_COUNT - 2, - PAGES_COUNT)); - } - - private static void doTestPageableWithCursorAndPageNumber( - Pageable pageable, - BiFunction> repositoryFunction, - BiConsumer>, List>> assertionAction) { - List> forwardPages = new ArrayList<>(); - - Slice page = repositoryFunction.apply(0, pageable); - - forwardPages.add(page); - - while (page.hasNext()) { - page = repositoryFunction.apply(0, page.nextOrLastPageable()); - forwardPages.add(page); - } - - List> backwardPages = new ArrayList<>(); - for (int i = forwardPages.size() - 1; i >= 0; i--) { - Slice currentPage = forwardPages.get(i); - if (currentPage.getPageable().isPaged()) { - page = currentPage; - break; - } - } - backwardPages.add(page); - - page = repositoryFunction.apply(0, page.previousOrFirstPageable()); - backwardPages.add(page); - - while (page.hasPrevious()) { - page = repositoryFunction.apply(0, page.previousOrFirstPageable()); - backwardPages.add(page); - } - - assertionAction.accept(forwardPages, backwardPages); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageableWithTrueCursorAndPageNumber") - , ID, REPO extends GenericPaginationMethods> - void testPageableWithTrueCursorAndPageNumber( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCount, - int expectedBackwardPageCount) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - backwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestPageablePageNumberLessCursor() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // fourth page - new TarantoolPageRequest<>(0, PAGE_SIZE, new Person(29, null, "User-29")), - PAGES_COUNT - 2, - PAGES_COUNT - 3, - PAGES_COUNT - 3), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // third page - new TarantoolPageRequest<>(0, PAGE_SIZE, new Person(19, null, "User-19")), - PAGES_COUNT - 1, - PAGES_COUNT - 2, - PAGES_COUNT - 2)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageablePageNumberLessCursor") - , ID, REPO extends GenericPaginationMethods> - void testPageablePageNumberLessCursor( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCountForPage, - int expectedForwardPageCountForSlice, - int expectedBackwardPageCount) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - int expectedForwardPageCount = expectedForwardPageCountForSlice; - Slice firstPageable = forwardSlice.get(0); - if (firstPageable instanceof Page) { - expectedForwardPageCount = expectedForwardPageCountForPage; - } - - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - if (firstPageable instanceof Page) { - assertTrue(forwardSlice.get(forwardSlice.size() - 1).getPageable().isUnpaged()); - forwardSlice - .subList(0, forwardSlice.size() - 1) - .forEach(p -> assertTrue(p.getPageable().isPaged())); - } else { - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - } - backwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestPageablePageNumberGreaterCursor() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // second page - new TarantoolPageRequest<>(1, PAGE_SIZE, null), - PAGES_COUNT - 1, - PAGES_COUNT, - PAGES_COUNT, - PAGES_COUNT + 1), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // fourth page - new TarantoolPageRequest<>(3, PAGE_SIZE, new Person(9, null, "User-9")), - PAGES_COUNT - 3, - PAGES_COUNT - 1, - PAGES_COUNT - 1, - PAGES_COUNT + 1)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageablePageNumberGreaterCursor") - , ID, REPO extends GenericPaginationMethods> - void testPageablePageNumberGreaterCursor( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCountForPage, - int expectedForwardPageCountForSlice, - int expectedBackwardPageCountForPage, - int expectedBackwardPageCountForSlice) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - int expectedForwardPageCount = expectedForwardPageCountForPage; - int expectedBackwardPageCount = expectedBackwardPageCountForPage; - - Slice firstPageable = forwardSlice.get(0); - if (!(firstPageable instanceof Page)) { - expectedForwardPageCount = expectedForwardPageCountForSlice; - expectedBackwardPageCount = expectedBackwardPageCountForSlice; - } - - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - assertTrue(backwardSlice.get(backwardSlice.size() - 1).getPageable().isUnpaged()); - backwardSlice - .subList(0, backwardSlice.size() - 1) - .forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - @Test - void testConcurrentDerivedMethods() { - - final byte threadCount = 3; - final ExecutorService executor = Executors.newFixedThreadPool(threadCount); - final List>> futures = new ArrayList<>(threadCount); - final PersonRepository repository = context.getBean(PersonRepository.class); - - final List insertedPersons = - personGenerateAndInsertFunction.apply(context, (int) threadCount); - final Person firstPerson = insertedPersons.get(0); - final Person secondPerson = insertedPersons.get(1); - final Person thirdPerson = insertedPersons.get(2); - - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findPersonById(firstPerson.getId()), executor)); - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findByIsMarried(secondPerson.getIsMarried()), executor)); - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findByName(thirdPerson.getName()), executor)); - - CompletableFuture.allOf(futures.toArray(new CompletableFuture[] {})).join(); - - assertEquals(firstPerson, futures.get(0).join().get(0)); - assertEquals(secondPerson, futures.get(1).join().get(0)); - assertEquals(thirdPerson, futures.get(2).join().get(0)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/GenericTarantoolTemplateTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/GenericTarantoolTemplateTest.java deleted file mode 100644 index fed9ea79..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/GenericTarantoolTemplateTest.java +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.integration.crud; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.core.UncategorizedKeyValueException; - -import static io.tarantool.spring.data.ProxyTarantoolCrudKeyValueAdapter.POTENTIAL_PERFORMANCE_ISSUES_EXCEPTION_MESSAGE; -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.generateAndInsertPersons; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.generateComplexPersons; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.mapping.crud.CrudException; -import io.tarantool.spring.data27.core.TarantoolTemplate; -import io.tarantool.spring.data27.utils.entity.ComplexPerson; -import io.tarantool.spring.data27.utils.entity.ComplexPersonWithIncorrectPK; -import io.tarantool.spring.data27.utils.entity.ComplexPersonWithJsonFormatVariantPK; -import io.tarantool.spring.data27.utils.entity.CompositePersonKey; -import io.tarantool.spring.data27.utils.entity.CompositePersonKeyWithJsonFormat; -import io.tarantool.spring.data27.utils.entity.Person; - -abstract class GenericTarantoolTemplateTest extends CrudConfigurations { - - @Autowired protected TarantoolTemplate tarantoolTemplate; - - @Test - void testGetAllOf() { - final Throwable throwable = - assertThrows( - UncategorizedKeyValueException.class, () -> tarantoolTemplate.findAll(Person.class)) - .getCause(); - - assertEquals(UnsupportedOperationException.class, throwable.getClass()); - assertEquals(POTENTIAL_PERFORMANCE_ISSUES_EXCEPTION_MESSAGE, throwable.getMessage()); - } - - static Stream dataForInsert() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - return Stream.of( - Arguments.of( - simpleKeyPerson, - (Function) (kv) -> kv.insert(simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - compositeKeyPerson, - (Function) (kv) -> kv.insert(compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForInsert") - void testKVTemplateInsert( - Object result, - Function callingMethod, - Function> selectAction) { - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForInsertById() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - return Stream.of( - Arguments.of( - simpleKeyPerson, - (Function) (kv) -> kv.insert(simpleKey, simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - compositeKeyPerson, - (Function) - (kv) -> kv.insert(compositeKey, compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForInsertById") - void testKVTemplateInsertById( - Object result, - Function callingMethod, - Function> selectAction) { - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForUpdate() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - Consumer prepareActionForSimpleKeyPerson = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer prepareActionForCompositeKeyPerson = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - return Stream.of( - Arguments.of( - prepareActionForSimpleKeyPerson, - simpleKeyPerson, - (Function) (kv) -> kv.update(simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - prepareActionForCompositeKeyPerson, - compositeKeyPerson, - (Function) (kv) -> kv.update(compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForUpdate") - void testKVTemplateUpdate( - Consumer prepareAction, - Object result, - Function callingMethod, - Function> selectAction) { - prepareAction.accept(client); - - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForUpdateById() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - Consumer prepareActionForSimpleKeyPerson = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer prepareActionForCompositeKeyPerson = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - return Stream.of( - Arguments.of( - prepareActionForSimpleKeyPerson, - simpleKeyPerson, - (Function) (kv) -> kv.update(simpleKey, simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - prepareActionForCompositeKeyPerson, - compositeKeyPerson, - (Function) - (kv) -> kv.update(compositeKey, compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForUpdateById") - void testKVTemplateUpdateById( - Consumer prepareAction, - Object result, - Function callingMethod, - Function> selectAction) { - prepareAction.accept(client); - - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForDelete() { - - Runnable simpleKeyPrepareAction = () -> generatePersons(PERSONS_COUNT); - Runnable compositeKeyPrepareAction = () -> generateComplexPersons(PERSONS_COUNT); - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(Person.class), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(ComplexPerson.class), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDelete") - void testKVTemplateDelete( - Runnable prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.run(); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForDeleteEntities() { - - Person simpleKeyPerson = new Person(0, true, "0"); - ComplexPerson compositeKeyPerson = new ComplexPerson(0, UUID.randomUUID(), true, "0"); - - Consumer simpleKeyPrepareAction = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer compositeKeyPrepareAction = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(simpleKeyPerson), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(compositeKeyPerson), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDeleteEntities") - void testKVTemplateDeleteEntities( - Consumer prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.accept(client); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForDeleteEntitiesById() { - - Person simpleKeyPerson = new Person(0, true, "0"); - ComplexPerson compositeKeyPerson = new ComplexPerson(0, UUID.randomUUID(), true, "0"); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Consumer simpleKeyPrepareAction = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer compositeKeyPrepareAction = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(simpleKey, Person.class), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(compositeKey, ComplexPerson.class), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDeleteEntitiesById") - void testKVTemplateDeleteEntitiesById( - Consumer prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.accept(client); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForCount() { - - Consumer simpleKeyPrepareAction = - (client) -> generateAndInsertPersons(PERSONS_COUNT, client); - - Consumer compositeKeyPrepareAction = - (client) -> generateAndInsertComplexPersons(PERSONS_COUNT, client); - - return Stream.of( - Arguments.of( - PERSONS_COUNT, - simpleKeyPrepareAction, - (Function) (kv) -> kv.count(Person.class)), - Arguments.of( - PERSONS_COUNT, - compositeKeyPrepareAction, - (Function) (kv) -> kv.count(ComplexPerson.class))); - } - - @ParameterizedTest - @MethodSource("dataForCount") - void testCount( - long expectedCount, - Consumer prepareAction, - Function callingMethod) { - prepareAction.accept(client); - assertEquals(expectedCount, callingMethod.apply(tarantoolTemplate)); - } - - @Test - void testCompositeKeyWithJsonFormat() { - ComplexPersonWithJsonFormatVariantPK complexPersonWithJsonFormatVariantPK = - new ComplexPersonWithJsonFormatVariantPK(0, UUID.randomUUID(), null, "0"); - - assertEquals( - complexPersonWithJsonFormatVariantPK, - tarantoolTemplate.insert(complexPersonWithJsonFormatVariantPK)); - - CompositePersonKeyWithJsonFormat key = - new CompositePersonKeyWithJsonFormat( - complexPersonWithJsonFormatVariantPK.getId(), - complexPersonWithJsonFormatVariantPK.getSecondId()); - Optional foundPerson = - tarantoolTemplate.findById(key, ComplexPersonWithJsonFormatVariantPK.class); - assertTrue(foundPerson.isPresent()); - assertEquals(complexPersonWithJsonFormatVariantPK, foundPerson.get()); - } - - @Test - void testCompositeKeyWithoutJsonFormat() { - ComplexPersonWithIncorrectPK complexPersonWithIncorrectPK = - new ComplexPersonWithIncorrectPK(0, UUID.randomUUID(), null, "0"); - - Throwable exception = - assertThrows( - UncategorizedKeyValueException.class, - () -> tarantoolTemplate.insert(complexPersonWithIncorrectPK)) - .getRootCause(); - assertInstanceOf(CrudException.class, exception); - } - - public static Stream dataForTestCompositeKeyWithConcurrency() { - final List threadsCount = Arrays.asList(1, 2, 3); - final List tuplesCount = Arrays.asList(20, 120, 360, 1200, 3000); - final List totalArguments = new ArrayList<>(); - - for (final Integer threadCount : threadsCount) { - for (final Integer tupleCount : tuplesCount) { - totalArguments.add(Arguments.of(threadCount, tupleCount)); - } - } - - return totalArguments.stream(); - } - - @DisplayName("Checking the insertion of an entity with a composite key") - @ParameterizedTest(autoCloseArguments = false, name = "thread count: {0}, tuples count: {1}") - @MethodSource("dataForTestCompositeKeyWithConcurrency") - void testCompositeKeyWithConcurrency(int threadsCount, int tuplesCount) { - final ExecutorService executor = Executors.newFixedThreadPool(threadsCount); - final List> futures = new ArrayList<>(); - final List tuples = generateComplexPersons(tuplesCount); - - for (final ComplexPerson tuple : tuples) { - futures.add( - CompletableFuture.supplyAsync(() -> this.tarantoolTemplate.insert(tuple), executor)); - } - - CompletableFuture.allOf(futures.toArray(new CompletableFuture[] {})).join(); - - for (int i = 0; i < tuplesCount; i++) { - assertEquals(tuples.get(i), futures.get(i).join()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/RepositoryConfigurationExtensionTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/RepositoryConfigurationExtensionTest.java deleted file mode 100644 index 4259557f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/RepositoryConfigurationExtensionTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.integration.crud; - -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.client.factory.TarantoolBoxClientBuilder; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.spring.data27.integration.BaseIntegrationTest; -import io.tarantool.spring.data27.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data27.repository.config.TarantoolRepositoryConfigurationExtension; - -class RepositoryConfigurationExtensionTest extends BaseIntegrationTest { - - private static TarantoolRepositoryConfigurationExtension defaultExtension; - - @BeforeAll - static void setUp() throws IOException { - BaseIntegrationTest.beforeAll(); - defaultExtension = new TarantoolRepositoryConfigurationExtension(); - } - - @Test - void testGetModuleName() { - assertEquals("Tarantool", defaultExtension.getModuleName()); - } - - @Test - void testGetModulePrefix() { - assertEquals("tarantool", defaultExtension.getModulePrefix()); - } - - @Test - void testGetDefaultKeyValueTemplateRef() { - assertEquals( - DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF, defaultExtension.getDefaultKeyValueTemplateRef()); - } - - @Test - void testRegisterBeansForRootWithDefaultConfig() { - final ApplicationContext context = new AnnotationConfigApplicationContext(DefaultConfig.class); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF)); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF)); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF)); - } - - @Test - void testRegisterBeansForRootWithCustomClientConfigShouldThrows() { - final Throwable throwable = - assertThrows( - IllegalArgumentException.class, - () -> new AnnotationConfigApplicationContext(BoxNonSupportConfig.class)); - - final String exceptionMessage = "The Box client is not yet supported."; - assertEquals(exceptionMessage, throwable.getMessage()); - } - - private static TarantoolCrudClientBuilder getCrudClientSettings() { - return TarantoolFactory.crud() - .withHost(getHost()) - .withPort(getPort()) - .withUser(getUsername()) - .withPassword(getPassword()); - } - - private static TarantoolBoxClientBuilder getBoxClientSettings() { - return TarantoolFactory.box().withHost(getHost()).withPort(getPort()); - } - - @EnableTarantoolRepositories - static class DefaultConfig { - - @Bean - public TarantoolCrudClientBuilder clientSettings() { - return getCrudClientSettings(); - } - } - - @EnableTarantoolRepositories(clientType = ClientType.BOX) - static class BoxNonSupportConfig { - - @Bean - public TarantoolBoxClientBuilder clientSettings() { - return getBoxClientSettings(); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/RepositoryViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/RepositoryViaJavaConfigTest.java deleted file mode 100644 index 7dd2896b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/RepositoryViaJavaConfigTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data27.integration.crud.CrudConfigurations.JavaConfigConfiguration; - -@SpringBootTest(classes = {JavaConfigConfiguration.class}) -class RepositoryViaJavaConfigTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/RepositoryViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/RepositoryViaPropertiesTest.java deleted file mode 100644 index 8aa1fd36..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/RepositoryViaPropertiesTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data27.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; - -@SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) -class RepositoryViaPropertiesTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/TarantoolTemplateViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/TarantoolTemplateViaJavaConfigTest.java deleted file mode 100644 index 175bafda..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/TarantoolTemplateViaJavaConfigTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data27.integration.crud.CrudConfigurations.JavaConfigConfiguration; - -@SpringBootTest(classes = {JavaConfigConfiguration.class}) -class TarantoolTemplateViaJavaConfigTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/query/TarantoolCriteriaTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/query/TarantoolCriteriaTest.java deleted file mode 100644 index a056295d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/query/TarantoolCriteriaTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.util.Arrays; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; - -import static io.tarantool.client.crud.ConditionOperator.EQ; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.spring.data.query.Conditions; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolCriteriaTest { - - @Test - void testAddAndGetConditions() { - final TarantoolCriteria tarantoolCriteria = new TarantoolCriteria(); - final String identifier = "name"; - final Object value = "value"; - final String operator = "=="; - - final Condition condition = Condition.create(operator, identifier, value); - assertEquals(operator, condition.getOperator()); - assertEquals(identifier, condition.getFieldIdentifier()); - assertEquals(value, condition.getValue()); - - final Condition conditionConstructor = new Condition(operator, identifier, value); - assertEquals(operator, conditionConstructor.getOperator()); - assertEquals(identifier, conditionConstructor.getFieldIdentifier()); - assertEquals(value, conditionConstructor.getValue()); - - final Condition conditionFromBuilder = - Condition.builder() - .withOperator(operator) - .withValue(value) - .withFieldIdentifier(identifier) - .build(); - assertEquals(operator, conditionFromBuilder.getOperator()); - assertEquals(identifier, conditionFromBuilder.getFieldIdentifier()); - assertEquals(value, conditionFromBuilder.getValue()); - - final Condition conditionWithEnum = Condition.create(EQ, identifier, value); - assertEquals(operator, conditionWithEnum.getOperator()); - assertEquals(identifier, conditionWithEnum.getFieldIdentifier()); - assertEquals(value, conditionWithEnum.getValue()); - - final Condition conditionConstructorWithEnum = new Condition(EQ, identifier, value); - assertEquals(operator, conditionConstructorWithEnum.getOperator()); - assertEquals(identifier, conditionConstructorWithEnum.getFieldIdentifier()); - assertEquals(value, conditionConstructorWithEnum.getValue()); - - final Condition conditionFromBuilderWithEnum = - Condition.builder() - .withOperator(EQ) - .withValue(value) - .withFieldIdentifier(identifier) - .build(); - assertEquals(operator, conditionFromBuilderWithEnum.getOperator()); - assertEquals(identifier, conditionFromBuilderWithEnum.getFieldIdentifier()); - assertEquals(value, conditionFromBuilderWithEnum.getValue()); - - tarantoolCriteria.addCondition(condition); - tarantoolCriteria.addCondition(conditionConstructor); - tarantoolCriteria.addCondition(conditionFromBuilder); - - tarantoolCriteria.addCondition(conditionWithEnum); - tarantoolCriteria.addCondition(conditionConstructorWithEnum); - tarantoolCriteria.addCondition(conditionFromBuilderWithEnum); - - final Conditions expectedConditions = new Conditions(); - expectedConditions.addAll( - Arrays.asList( - condition, - conditionConstructor, - conditionFromBuilder, - conditionWithEnum, - conditionConstructorWithEnum, - conditionFromBuilderWithEnum)); - - assertEquals(expectedConditions, tarantoolCriteria.getConditions()); - } - - @Test - void testFirst() { - final TarantoolCriteria criteria = new TarantoolCriteria(); - criteria.withFirst(1); - - final String key = "first"; - SelectOptions options = criteria.getOptions(); - assertEquals(1, options.getOptions().get(key)); - - criteria.clear(); - criteria.withFirst(-1); - options = criteria.getOptions(); - assertEquals(-1, options.getOptions().get(key)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/query/TarantoolPageImplTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/query/TarantoolPageImplTest.java deleted file mode 100644 index e1a2480a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/query/TarantoolPageImplTest.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data27.utils.entity.Person; - -class TarantoolPageImplTest { - - private static final List PERSONS = generatePersons(PERSONS_COUNT); - - private static final int DEFAULT_PAGE_SIZE_PER_TEST_CLASS = 10; - - private static final int DEFAULT_PAGE_NUMBER_PER_TEST_CLASS = 0; - - private static final Pageable FIRST_PAGE_PAGEABLE_PER_TEST_CLASS = - new TarantoolPageRequest<>( - DEFAULT_PAGE_NUMBER_PER_TEST_CLASS, DEFAULT_PAGE_SIZE_PER_TEST_CLASS, null); - - private static final long MULTIPLIER = 2L; - - private static final BiFunction GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE = - (pageSize, operator) -> { - switch (operator) { - // pageSize > totalPageCount - case ">": - { - return pageSize / MULTIPLIER; - } - // pageSize < totalPageCount - case "<": - { - return MULTIPLIER * pageSize; - } - // pageSize == totalPageCount - case "==": - { - return Long.valueOf(pageSize); - } - default: - throw new IllegalArgumentException("The passed option isn't supported"); - } - }; - - private static final List EMPTY_CONTENT = Collections.emptyList(); - - protected static Stream dataForTestConstructors() { - TarantoolPageable> pageable = - new TarantoolPageRequest<>(0, DEFAULT_PAGE_SIZE_PER_TEST_CLASS, null); - - long personsSize = PERSONS.size(); - - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>(PERSONS, pageable, personsSize), - PERSONS.size() / DEFAULT_PAGE_SIZE_PER_TEST_CLASS, - personsSize), - Arguments.of(new TarantoolPageImpl<>(PERSONS), 1, personsSize), - Arguments.of(new TarantoolPageImpl<>(), 1, 0L)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructors") - void testConstructors(Page> page, int totalPages, long totalElements) { - assertEquals(totalPages, page.getTotalPages()); - assertEquals(totalElements, page.getTotalElements()); - } - - static Stream dataForTestGetTotalPages() { - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, ">")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "<")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - PERSONS.size() / FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, ">")), - 0), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "<")), - 0), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "==")), - 0)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTotalPages") - void testGetTotalPages(Page page, long totalPagesCount) { - assertEquals(totalPagesCount, page.getTotalPages()); - } - - static Stream dataForTestConstructorsThrowsIllegalArgumentException() { - final class DummyTarantoolPageRequest implements Pageable { - - @Override - public int getPageNumber() { - return 0; - } - - @Override - public int getPageSize() { - return 0; - } - - @Override - public long getOffset() { - return 0L; - } - - @Override - public Sort getSort() { - return null; - } - - @Override - public Pageable next() { - return null; - } - - @Override - public Pageable previousOrFirst() { - return null; - } - - @Override - public Pageable first() { - return null; - } - - @Override - public Pageable withPage(int pageNumber) { - return null; - } - - @Override - public boolean hasPrevious() { - return false; - } - } - - Pageable dummyPageable = new DummyTarantoolPageRequest(); - - return Stream.of( - Arguments.of(null, null, "Content must not be null"), - Arguments.of(Collections.emptyList(), null, "Pageable must not be null"), - Arguments.of( - Collections.emptyList(), - dummyPageable, - "Pageable must be TarantoolPageable or Unpaged type")); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructorsThrowsIllegalArgumentException") - void testConstructors_throws_IllegalArgumentException( - List content, Pageable pageable, String errorMsg) { - assertThrows( - IllegalArgumentException.class, - () -> new TarantoolPageImpl<>(content, pageable, 0L), - errorMsg); - } - - static Stream dataForTestGetTotalElements() { - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() / MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() * MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - PERSONS.size()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() * MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTotalElements") - void testGetTotalElements(Page page, long totalElementCount) { - assertEquals(totalElementCount, page.getTotalElements()); - } - - static Stream dataForTestHasNext() { - return Stream.of( - Arguments.of( - false, - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())), - Arguments.of( - true, - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - MULTIPLIER * FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())), - Arguments.of( - false, - new TarantoolPageImpl<>( - PERSONS, - Pageable.unpaged(), - MULTIPLIER * FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()))); - } - - @ParameterizedTest - @MethodSource("dataForTestHasNext") - void testHasNext(boolean exceptedBool, Page page) { - assertEquals(exceptedBool, page.hasNext()); - } - - @ParameterizedTest - @MethodSource("dataForTestHasNext") - void testIsLast(boolean notEqualBool, Page page) { - assertNotEquals(notEqualBool, page.isLast()); - } - - static Stream dataForTestMap() { - List exceptedNames = PERSONS.stream().map(Person::getName).collect(Collectors.toList()); - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - exceptedNames, - (Function) Person::getName)); - } - - @ParameterizedTest - @MethodSource("dataForTestMap") - void testMap(Page page, List exceptedNames, Function mapFunction) { - List names = page.map(mapFunction).toList(); - assertEquals(exceptedNames, names); - } - - static Stream dataForTestEqualsAndHashCode() { - List> equalPages = - Arrays.asList( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())); - - final int ITERATION_COUNT = 100; - - return Stream.of( - Arguments.of( - equalPages, - new TarantoolPageImpl<>(EMPTY_CONTENT, Pageable.unpaged(), 150), - ITERATION_COUNT), - Arguments.of(equalPages, null, ITERATION_COUNT)); - } - - @ParameterizedTest - @MethodSource("dataForTestEqualsAndHashCode") - void testEqualsAndHashCode(List> pages, Page notEqualPage, int iterationCount) { - for (int i = 0; i < iterationCount; i++) { - for (Page page : pages) { - for (Page otherPage : pages) { - assertEquals(page, otherPage); - assertEquals(page.hashCode(), otherPage.hashCode()); - } - assertNotEquals(page, notEqualPage); - if (notEqualPage != null) { - assertNotEquals(page.hashCode(), notEqualPage.hashCode()); - } - } - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/query/TarantoolPageRequestTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/query/TarantoolPageRequestTest.java deleted file mode 100644 index d25d0a96..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/query/TarantoolPageRequestTest.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.util.Arrays; -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.AbstractPageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data27.utils.entity.Person; - -class TarantoolPageRequestTest { - - private static final int PAGE_SIZE = 10; - - private static final Person CURSOR = new Person(0, true, "0"); - - private static final int PAGE_NUMBER = 0; - - protected static Stream dataForTestConstructors() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - null, - FORWARD), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - CURSOR, - FORWARD), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, null), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - null, - FORWARD)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructors") - void testConstructors( - Supplier>> constructorGenerator, - int pageNumber, - int size, - Sort sort, - GenericPerson cursor, - PaginationDirection direction) { - TarantoolPageable> pageable = constructorGenerator.get(); - - assertEquals(size, pageable.getPageSize()); - assertEquals(pageNumber, pageable.getPageNumber()); - assertEquals(sort, pageable.getSort()); - assertEquals(cursor, pageable.getTupleCursor()); - assertEquals(direction, pageable.getPaginationDirection()); - } - - protected static Stream dataTestGetSort() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - Sort.unsorted()), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - Sort.unsorted())); - } - - @ParameterizedTest - @MethodSource("dataTestGetSort") - void testGetSort(Supplier>> constructorGenerator, Sort sort) { - Pageable pageable = constructorGenerator.get(); - assertEquals(sort, pageable.getSort()); - } - - protected static Stream dataForTestGetTupleCursor() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - null), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTupleCursor") - void testGetTupleCursor( - Supplier>> constructorGenerator, GenericPerson person) { - TarantoolPageable> pageable = constructorGenerator.get(); - assertEquals(person, pageable.getTupleCursor()); - } - - protected static Stream dataForTestNext() { - final Person NEXT_CURSOR = - new Person(CURSOR.getId() + PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), CURSOR, NEXT_CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataForTestNext") - void testNext( - TarantoolPageable> pageable, - GenericPerson cursor, - GenericPerson nextCursor) { - assertEquals(cursor, pageable.getTupleCursor()); - - TarantoolPageable> nextPageable = pageable.next(nextCursor); - assertEquals(nextCursor, nextPageable.getTupleCursor()); - - assertEquals(pageable.getPageSize(), nextPageable.getPageSize()); - assertEquals(pageable.getPageNumber() + 1, nextPageable.getPageNumber()); - assertEquals(pageable.getSort(), nextPageable.getSort()); - assertEquals(pageable.getOffset() + PAGE_SIZE, nextPageable.getOffset()); - } - - @Test - void testNextUnsupported() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::next); - } - - protected static Stream dataTestGetPaginationDirection() { - final Person PREV_CURSOR = new Person(CURSOR.getId(), CURSOR.getIsMarried(), CURSOR.getName()); - final Person NEXT_CURSOR = - new Person(PREV_CURSOR.getId() + PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, NEXT_CURSOR), NEXT_CURSOR, PREV_CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataTestGetPaginationDirection") - void testGetPaginationDirection( - TarantoolPageable> pageable, - GenericPerson nextCursor, - GenericPerson prevCursor) { - - assertEquals(FORWARD, pageable.getPaginationDirection()); - - TarantoolPageable> prevPageable = pageable.previousOrFirst(prevCursor); - assertEquals(PaginationDirection.BACKWARD, prevPageable.getPaginationDirection()); - - TarantoolPageable> nextPageable = prevPageable.next(nextCursor); - assertEquals(FORWARD, nextPageable.getPaginationDirection()); - assertEquals(pageable, nextPageable); - } - - protected static Stream dataTestFirst() { - final Person CURSOR = new Person(2 * PAGE_SIZE, true, "name"); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(0, PAGE_SIZE, null))); - } - - @ParameterizedTest - @MethodSource("dataTestFirst") - void testFirst( - TarantoolPageable> pageable, - TarantoolPageable> exceptedFirstPageable) { - assertEquals(exceptedFirstPageable, pageable.first()); - } - - @Test - void testWithPage() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, () -> pageable.withPage(100)); - } - - protected static Stream dataTestPreviousOrFirst() { - final Person CURSOR = new Person(PAGE_SIZE, true, "name"); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, CURSOR), - new Person(CURSOR.getId() - PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()))); - } - - @ParameterizedTest - @MethodSource("dataTestPreviousOrFirst") - void testPreviousOrFirst( - TarantoolPageable> pageable, GenericPerson prevCursor) { - - TarantoolPageable> prevPageable = pageable.previousOrFirst(prevCursor); - - assertNotEquals(pageable, prevPageable); - assertEquals(pageable.getPageSize(), prevPageable.getPageSize()); - assertEquals(pageable.getOffset() - PAGE_SIZE, prevPageable.getOffset()); - assertEquals(pageable.getSort(), prevPageable.getSort()); - assertEquals(pageable.getPageNumber() - 1, prevPageable.getPageNumber()); - - // here will be first with null cursor - TarantoolPageable> firstPageable = prevPageable.previousOrFirst(prevCursor); - assertNull(firstPageable.getTupleCursor()); - } - - @Test - void testPreviousOrFirstUnsupported() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::previousOrFirst); - } - - @Test - void testPreviousUnsupported() { - AbstractPageRequest pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::previous); - } - - protected static Stream dataForTestEquals() { - return Stream.of( - Arguments.of( - Arrays.asList( - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR)), - new TarantoolPageRequest<>(PAGE_SIZE))); - } - - @ParameterizedTest - @MethodSource("dataForTestEquals") - void testEquals( - List>> equalPageableList, - TarantoolPageable> notEqualPageable) { - - assertTrue(equalPageableList.size() > 0); - final int COUNT = 10; - - for (int i = 0; i < COUNT; i++) { - for (TarantoolPageable> pageable : equalPageableList) { - for (TarantoolPageable> secondPageable : equalPageableList) { - assertEquals(pageable, secondPageable); - } - assertNotEquals(pageable, null); - assertNotEquals(pageable, notEqualPageable); - } - } - } - - @ParameterizedTest - @MethodSource("dataForTestEquals") - void testHashCode( - List>> equalPageableList, - TarantoolPageable> notEqualPageable) { - - for (TarantoolPageable> pageable : equalPageableList) { - for (TarantoolPageable> secondPageable : equalPageableList) { - assertEquals(pageable.hashCode(), secondPageable.hashCode()); - } - assertNotEquals(pageable.hashCode(), notEqualPageable.hashCode()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/query/TarantoolSliceTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/query/TarantoolSliceTest.java deleted file mode 100644 index b25af51d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/query/TarantoolSliceTest.java +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.function.Executable; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data27.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.spring.data27.utils.entity.Person; - -public class TarantoolSliceTest { - - private static final int PAGE_SIZE = 10; - - private static final int PAGE_NUMBER = 0; - - private static final Person SOME_CURSOR = new Person(0, true, "0"); - - private static List PERSONS; - - private static final Pageable SOME_PAGEABLE = - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR); - - @BeforeAll - static void setUp() { - PERSONS = generatePersons(PERSONS_COUNT); - } - - static Stream dataForTestConstructorsShouldThrow() { - Pageable tarantoolPageable = new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR); - Pageable notTarantoolPageable = Pageable.ofSize(PAGE_SIZE); - return Stream.of( - Arguments.of(null, tarantoolPageable, false), - Arguments.of(null, tarantoolPageable, true), - Arguments.of(PERSONS, null, false), - Arguments.of(PERSONS, null, true), - Arguments.of(PERSONS, notTarantoolPageable, false), - Arguments.of(PERSONS, notTarantoolPageable, true)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructorsShouldThrow") - public void testConstructorsShouldThrow(List content, Pageable pageable, boolean hasNext) { - assertThrows( - IllegalArgumentException.class, () -> new TarantoolSliceImpl<>(content, pageable, hasNext)); - } - - static Stream dataForTestConstructorsDoesntThrow() { - return Stream.of( - () -> new TarantoolSliceImpl<>(PERSONS), - () -> new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - () -> new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestConstructorsDoesntThrow") - public void testConstructorsDoesntThrow(Executable runTestCase) { - assertDoesNotThrow(runTestCase); - } - - static Stream dataForTestGetNumber() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getPageNumber()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetNumber") - public void testGetNumber(Slice slice, int expectedPageNumber) { - assertEquals(expectedPageNumber, slice.getNumber()); - } - - static Stream dataForTestGetSize() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getPageSize()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS.size()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), - SOME_PAGEABLE.getPageSize()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetSize") - public void testGetSize(Slice slice, int expectedSize) { - assertEquals(expectedSize, slice.getSize()); - } - - static Stream dataForTestGetNumberOfElements() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), PERSONS.size()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS.size()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), 0), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetNumberOfElements") - public void testGetNumberOfElements(Slice slice, int expectedNumberOfElements) { - assertEquals(expectedNumberOfElements, slice.getNumberOfElements()); - } - - static Stream dataForTestGetContent() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), PERSONS), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), - Collections.emptyList()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Collections.emptyList())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetContent") - public void testGetContent(Slice slice, List expectedContent) { - assertEquals(expectedContent, slice.getContent()); - } - - static Stream dataForTestHasContent() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), true), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), false), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasContent") - void testHasContent(Slice slice, boolean expectedHasContent) { - assertEquals(expectedHasContent, slice.hasContent()); - } - - static Stream dataForTestGetSort() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getSort()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Sort.unsorted())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetSort") - void testGetSort(Slice slice, Sort expectedSort) { - assertEquals(expectedSort, slice.getSort()); - } - - static Stream dataForTestIsFirst() { - final int MIDDLE_PAGE_NUMBER = 2; - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), true), - true), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), true), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - true), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), true)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestIsFirst") - void testIsFirst(Slice slice, boolean expectedIsFirst) { - assertEquals(expectedIsFirst, slice.isFirst()); - } - - static Stream dataForTestIsLast() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), false), - // last imitation - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, false), true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), true), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), true), - // last imitation - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, false), true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), true)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestIsLast") - void testIsLast(Slice slice, boolean expectedIsLast) { - assertEquals(expectedIsLast, slice.isLast()); - } - - static Stream dataForTestHasNext() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, new TarantoolPageRequest<>(PAGE_SIZE), true), true), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, new TarantoolPageRequest<>(PAGE_SIZE), false), false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), new TarantoolPageRequest<>(PAGE_SIZE), true), - false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), new TarantoolPageRequest<>(PAGE_SIZE), false), - false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasNext") - void testHasNext(Slice slice, boolean expectedHasNext) { - assertEquals(expectedHasNext, slice.hasNext()); - } - - static Stream dataForTestHasPrevious() { - final int MIDDLE_PAGE_NUMBER = 2; - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), false), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - false), - true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), false), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - false), - false), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), false), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasPrevious") - void testHasPrevious(Slice slice, boolean expectedHasPrevious) { - assertEquals(expectedHasPrevious, slice.hasPrevious()); - } - - static Stream dataForTestGetPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, pageable, true), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), pageable), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, pageable, false), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), pageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), - Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetPageable") - void testGetPageable(Slice slice, Pageable expectedPageable) { - assertEquals(expectedPageable, slice.getPageable()); - } - - static Stream dataForTestNextPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, true), - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - new TarantoolPageRequest<>(5, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestNextPageable") - void testNextPageable(Slice slice, Pageable expectedNextPageable) { - assertEquals(expectedNextPageable, slice.nextPageable()); - } - - static Stream dataForTestPreviousPageable() { - Pageable firstPagePageable = new TarantoolPageRequest<>(PAGE_SIZE); - Pageable secondPagePageable = - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)); - - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, false), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(4, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(0)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPreviousPageable") - void testPreviousPageable(Slice slice, Pageable expectedPrevPageable) { - assertEquals(expectedPrevPageable, slice.previousPageable()); - } - - static Stream dataForTestNextOrLastPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, true), - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), pageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, false), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), pageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - new TarantoolPageRequest<>(5, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - false), - new TarantoolPageRequest<>(4, PAGE_SIZE, null))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestNextOrLastPageable") - void testNextOrLastPageable(Slice slice, Pageable expectedNextOrLastPageable) { - assertEquals(expectedNextOrLastPageable, slice.nextOrLastPageable()); - } - - static Stream dataForTestPreviousOrFirstPageable() { - Pageable firstPagePageable = new TarantoolPageRequest<>(PAGE_SIZE); - Pageable secondPagePageable = - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)); - - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, true), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, true), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, false), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, false), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, true), - secondPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, false), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, false), - secondPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(4, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(0)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPreviousOrFirstPageable") - void testPreviousOrFirstPageable(Slice slice, Pageable expectedPrevOrFirstPageable) { - assertEquals(expectedPrevOrFirstPageable, slice.previousOrFirstPageable()); - } - - static Stream dataForTestMap() { - - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - List expectedNames = PERSONS.stream().map(Person::getName).collect(Collectors.toList()); - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, pageable, true), - (Function) Person::getName, - expectedNames, - new TarantoolSliceImpl<>(expectedNames, pageable, true))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestMap") - void testMap( - Slice slice, - Function mapper, - List expectedMappedList, - Slice expectedMappedSlice) { - assertEquals(expectedMappedSlice, slice.map(mapper)); - assertEquals(expectedMappedList, slice.map(mapper).getContent()); - } - - protected static Stream dataForTestEquals() { - - return Stream.of( - Arguments.of( - Arrays.asList( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true)), - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestEquals") - void testEquals(List> equalPageableList, Slice notEqualPageable) { - - assertFalse(equalPageableList.isEmpty()); - final int COUNT = 10; - - for (int i = 0; i < COUNT; i++) { - for (Slice pageable : equalPageableList) { - for (Slice secondPageable : equalPageableList) { - assertEquals(pageable, secondPageable); - } - assertNotEquals(pageable, null); - assertNotEquals(pageable, notEqualPageable); - } - } - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestEquals") - void testHashCode(List> equalPageableList, Slice notEqualPageable) { - for (Slice pageable : equalPageableList) { - for (Slice secondPageable : equalPageableList) { - assertEquals(pageable.hashCode(), secondPageable.hashCode()); - } - assertNotEquals(pageable.hashCode(), notEqualPageable.hashCode()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/TarantoolTestSupport.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/TarantoolTestSupport.java deleted file mode 100644 index d3f08163..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/TarantoolTestSupport.java +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.utils; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.UUID; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.Consumer; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.introspector.Property; -import org.yaml.snakeyaml.nodes.NodeTuple; -import org.yaml.snakeyaml.nodes.Tag; -import org.yaml.snakeyaml.representer.Representer; - -import static io.tarantool.balancer.BalancerMode.DEFAULT_BALANCER_MODE; -import static io.tarantool.client.TarantoolClient.DEFAULT_TAG; -import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_PASSWORD; -import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_USERNAME; -import static io.tarantool.core.protocol.requests.IProtoAuth.DEFAULT_AUTH_TYPE; -import static io.tarantool.pool.InstanceConnectionGroup.DEFAULT_HOST; -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data27.config.properties.TarantoolProperties.PropertyFlushConsolidationHandler; -import static io.tarantool.spring.data27.config.properties.TarantoolProperties.PropertyHeartbeatOpts; -import static io.tarantool.spring.data27.config.properties.TarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.balancer.BalancerMode; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.core.protocol.requests.IProtoAuth; -import io.tarantool.mapping.Tuple; -import io.tarantool.spring.data27.config.properties.TarantoolProperties; -import io.tarantool.spring.data27.utils.entity.ComplexPerson; -import io.tarantool.spring.data27.utils.entity.Person; - -public class TarantoolTestSupport { - - private static final ThreadLocalRandom random = ThreadLocalRandom.current(); - private static final Map firstInternalMap = new HashMap<>(); - private static final Map secondInternalMap = new HashMap<>(); - private static final Map externalMap = new HashMap<>(); - private static final Representer representer; - public static final String PERSON_SPACE = "person"; - public static final String COMPLEX_PERSON_SPACE = "complex_person"; - public static final int PERSONS_COUNT = 100; - public static final Random RANDOMIZER = new Random(); - public static final Person UNKNOWN_PERSON = new Person(-1, true, "Alien"); - public static final ComplexPerson UNKNOWN_COMPLEX_PERSON = - new ComplexPerson(-1, new UUID(0, 0), true, "Alien"); - - public static final Path DEFAULT_TEST_PROPERTY_DIR = Paths.get("target", "test-classes"); - private static final Yaml yaml; - - static { - representer = - new Representer() { - @Override - @Nullable - protected NodeTuple representJavaBeanProperty( - Object javaBean, Property property, @Nullable Object propertyValue, Tag customTag) { - if (propertyValue == null) { - return null; - } else { - return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag); - } - } - }; - representer.addClassTag(TarantoolProperties.class, Tag.MAP); - yaml = new Yaml(representer); - } - - public static TarantoolProperties writeTestPropertiesYaml(@NonNull final String fileName) - throws IOException { - return writeTestPropertiesYaml(fileName, createRandomProperty()); - } - - public static TarantoolProperties writeTestPropertiesYaml( - final String fileName, final TarantoolProperties properties) throws IOException { - final File FILE = DEFAULT_TEST_PROPERTY_DIR.resolve(fileName).toFile().getAbsoluteFile(); - - try (Writer writer = new FileWriter(FILE)) { - firstInternalMap.put("tarantool", properties); - secondInternalMap.put("data", firstInternalMap); - externalMap.put("spring", secondInternalMap); - - yaml.dump(externalMap, writer); - replaceNullToDefault(properties); - return properties; - } - } - - public static void writeTestEmptyPropertiesYaml(@NonNull final String fileName) - throws IOException { - final File FILE = DEFAULT_TEST_PROPERTY_DIR.resolve(fileName).toFile().getAbsoluteFile(); - try (Writer writer = new FileWriter(FILE)) { - yaml.dump(Collections.emptyMap(), writer); - } - } - - private static void replaceNullToDefault(final TarantoolProperties result) { - - if (result.getHost() == null) { - result.setHost(DEFAULT_HOST); - } - - if (result.getUserName() == null) { - result.setUserName(DEFAULT_CRUD_USERNAME); - } - - if (result.getBalancerMode() == null) { - result.setBalancerMode(DEFAULT_BALANCER_MODE); - } - - if (result.getPassword() == null) { - result.setPassword(DEFAULT_CRUD_PASSWORD); - } - - if (result.getConnectionGroups() != null) { - for (PropertyInstanceConnectionGroup propertyInstanceConnectionGroup : - result.getConnectionGroups()) { - if (propertyInstanceConnectionGroup.getAuthType() == null) { - propertyInstanceConnectionGroup.setAuthType(DEFAULT_AUTH_TYPE); - } - - if (propertyInstanceConnectionGroup.getHost() == null) { - propertyInstanceConnectionGroup.setHost(DEFAULT_HOST); - } - - if (propertyInstanceConnectionGroup.getTag() == null) { - propertyInstanceConnectionGroup.setTag(DEFAULT_TAG); - } - - if (propertyInstanceConnectionGroup.getUserName() == null) { - propertyInstanceConnectionGroup.setUserName(DEFAULT_CRUD_USERNAME); - } - - if (propertyInstanceConnectionGroup.getUserName() == null) { - propertyInstanceConnectionGroup.setPassword(DEFAULT_CRUD_PASSWORD); - } - } - } - } - - private static TarantoolProperties createRandomProperty() { - final int intVar = 999; - final long longVar = 9999L; - final List booleanVar = Arrays.asList(true, false); - - PropertyHeartbeatOpts propertyHeartbeatOpts = - heartbeat( - choiceOrNull(longVar), - choiceOrNull(intVar), - choiceOrNull(intVar), - choiceOrNull(intVar)); - - PropertyFlushConsolidationHandler propertyFlushConsolidationHandler = - choiceOrNull(flushConsolidation(choiceOrNull(intVar), choiceOrNull(booleanVar))); - - PropertyInstanceConnectionGroup propertyInstanceConnectionGroup = - choiceOrNull( - connectionGroup( - choiceOrNull("host"), - "password", - choiceOrNull(intVar), - choiceOrNull(intVar), - choiceOrNull("tag"), - "user", - choiceOrNull(Arrays.asList(IProtoAuth.AuthType.values())), - propertyFlushConsolidationHandler)); - List propertyInstanceConnectionGroups = null; - if (propertyInstanceConnectionGroup != null) { - propertyInstanceConnectionGroups = new ArrayList<>(); - propertyInstanceConnectionGroups.add(propertyInstanceConnectionGroup); - } - - return tarantoolProperties( - choiceOrNull("host"), - choiceOrNull("password"), - choiceOrNull(intVar), - choiceOrNull("user"), - propertyInstanceConnectionGroups, - choiceOrNull(intVar), - choiceOrNull(booleanVar), - choiceOrNull(propertyHeartbeatOpts), - choiceOrNull(longVar), - choiceOrNull(longVar), - choiceOrNull(booleanVar), - choiceOrNull(booleanVar), - choiceOrNull(Arrays.asList(BalancerMode.values()))); - } - - @Nullable - public static T choiceOrNull(@Nullable T element) { - int rnd = random.nextInt(2); - if (rnd == 0 || element == null) { - return null; - } - return element; - } - - public static PropertyHeartbeatOpts heartbeat( - @Nullable Long pingInterval, - @Nullable Integer invalidationThreshold, - @Nullable Integer windowSize, - @Nullable Integer deathThreshold) { - - PropertyHeartbeatOpts propertyHeartbeatOpts = new PropertyHeartbeatOpts(); - if (invalidationThreshold != null) { - propertyHeartbeatOpts.setInvalidationThreshold(invalidationThreshold); - } - if (pingInterval != null) { - propertyHeartbeatOpts.setPingInterval(pingInterval); - } - if (deathThreshold != null) { - propertyHeartbeatOpts.setDeathThreshold(deathThreshold); - } - if (windowSize != null) { - propertyHeartbeatOpts.setWindowSize(windowSize); - } - - return propertyHeartbeatOpts; - } - - public static PropertyFlushConsolidationHandler flushConsolidation( - @Nullable Integer explicitFlushAfterFlushes, - @Nullable Boolean consolidateWhenNoReadInProgress) { - - PropertyFlushConsolidationHandler propertyFlushConsolidationHandler = - new PropertyFlushConsolidationHandler(); - if (explicitFlushAfterFlushes != null) { - propertyFlushConsolidationHandler.setExplicitFlushAfterFlushes(explicitFlushAfterFlushes); - } - - if (consolidateWhenNoReadInProgress != null) { - propertyFlushConsolidationHandler.setConsolidateWhenNoReadInProgress( - consolidateWhenNoReadInProgress); - } - return propertyFlushConsolidationHandler; - } - - @Nullable - public static T choiceOrNull(@Nullable List list) { - if (list == null || list.isEmpty()) { - return null; - } - int rnd = random.nextInt(list.size() + 1); - - if (rnd == list.size()) { - return null; - } - return list.get(rnd); - } - - @NonNull - public static PropertyInstanceConnectionGroup connectionGroup( - @Nullable String host, - @Nullable String password, - @Nullable Integer port, - @Nullable Integer connectionNumber, - @Nullable String tag, - @Nullable String user, - @Nullable IProtoAuth.AuthType type, - @Nullable PropertyFlushConsolidationHandler propertyFlushConsolidationHandler) { - - PropertyInstanceConnectionGroup propertyInstanceConnectionGroup = - new PropertyInstanceConnectionGroup(); - propertyInstanceConnectionGroup.setHost(host); - if (connectionNumber != null) { - propertyInstanceConnectionGroup.setConnectionGroupSize(connectionNumber); - } - propertyInstanceConnectionGroup.setAuthType(type); - propertyInstanceConnectionGroup.setPassword(password); - if (port != null) { - propertyInstanceConnectionGroup.setPort(port); - } - propertyInstanceConnectionGroup.setTag(tag); - propertyInstanceConnectionGroup.setUserName(user); - - propertyInstanceConnectionGroup.setFlushConsolidationHandler(propertyFlushConsolidationHandler); - return propertyInstanceConnectionGroup; - } - - @NonNull - public static TarantoolProperties tarantoolProperties( - @Nullable String host, - @Nullable String password, - @Nullable Integer port, - @Nullable String user, - @Nullable List propertyInstanceConnectionGroups, - @Nullable Integer eventLoopThreadsCount, - @Nullable Boolean enableGracefulShutdown, - @Nullable PropertyHeartbeatOpts propertyHeartbeatOptsOpts, - @Nullable Long connectTimeout, - @Nullable Long reconnectAfter, - @Nullable Boolean fetchSchema, - @Nullable Boolean ignoreOldSchemaVersion, - @Nullable BalancerMode balancerClass) { - - TarantoolProperties prop = new TarantoolProperties(); - prop.setHost(host); - prop.setPassword(password); - if (port != null) { - prop.setPort(port); - } - prop.setUserName(user); - prop.setConnectionGroups(propertyInstanceConnectionGroups); - if (eventLoopThreadsCount != null) { - prop.setEventLoopThreadsCount(eventLoopThreadsCount); - } - - if (enableGracefulShutdown != null) { - prop.setGracefulShutdownEnabled(enableGracefulShutdown); - } - prop.setHeartbeat(propertyHeartbeatOptsOpts); - if (connectTimeout != null) { - prop.setConnectTimeout(connectTimeout); - } - if (reconnectAfter != null) { - prop.setReconnectAfter(reconnectAfter); - } - if (fetchSchema != null) { - prop.setFetchSchema(fetchSchema); - } - if (ignoreOldSchemaVersion != null) { - prop.setIgnoreOldSchemaVersion(ignoreOldSchemaVersion); - } - prop.setBalancerMode(balancerClass); - return prop; - } - - public static List generatePersons(int count) { - List persons = new ArrayList<>(); - for (int i = 0; i < count; i++) { - persons.add(new Person(i, i % 3 == 0 ? null : i % 2 == 0, "User-" + i)); - } - return persons; - } - - public static List generatePersons(int count, Consumer actionAtPerson) { - List persons = generatePersons(count); - persons.forEach(actionAtPerson); - return persons; - } - - public static List generateComplexPersons(int count) { - List persons = new ArrayList<>(); - for (int i = 0; i < count; i++) { - persons.add( - new ComplexPerson(i, UUID.randomUUID(), i % 3 == 0 ? null : i % 2 == 0, "User-" + i)); - } - return persons; - } - - public static List generateComplexPersons( - int count, Consumer actionAtPerson) { - List persons = generateComplexPersons(count); - persons.forEach(actionAtPerson); - return persons; - } - - public static List generateAndInsertPersons(int count, TarantoolCrudClient client) { - final List persons = generatePersons(count); - final TarantoolCrudSpace space = client.space(PERSON_SPACE); - - List> insertedPersons = space.insertMany(persons, Person.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertPersons( - int count, TarantoolCrudClient client, Consumer action) { - final List persons = generatePersons(count, action); - final TarantoolCrudSpace space = client.space(PERSON_SPACE); - - List> insertedPersons = space.insertMany(persons, Person.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertComplexPersons( - int count, TarantoolCrudClient client) { - final List persons = generateComplexPersons(count); - final TarantoolCrudSpace space = client.space(COMPLEX_PERSON_SPACE); - - List> insertedPersons = - space.insertMany(persons, ComplexPerson.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertComplexPersons( - int count, TarantoolCrudClient client, Consumer action) { - - final List persons = generateComplexPersons(count, action); - final TarantoolCrudSpace space = client.space(COMPLEX_PERSON_SPACE); - - List> insertedPersons = - space.insertMany(persons, ComplexPerson.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/core/GenericPaginationMethods.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/core/GenericPaginationMethods.java deleted file mode 100644 index b4fbc9c1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/core/GenericPaginationMethods.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.utils.core; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; - -public interface GenericPaginationMethods { - - Slice findAllByName(String name); - - Slice findAllByName(String name, Pageable pageable); - - Slice findAllByNameGreaterThanEqual(String name, Pageable pageable); - - Slice findAllByNameLessThanEqual(String name, Pageable pageable); - - Slice findAllByIdLessThanEqual(int id, Pageable pageable); - - Slice findAllByIdGreaterThanEqual(int id, Pageable pageable); - - Slice findAllByIsMarriedLessThanEqual(Boolean id, Pageable pageable); - - Slice findAllByIsMarriedGreaterThanEqual(Boolean id, Pageable pageable); - - Page findPersonByName(String name, Pageable pageable); - - Page findPersonByNameGreaterThanEqual(String name, Pageable pageable); - - Page findPersonByNameLessThanEqual(String name, Pageable pageable); - - Page findPersonByIdLessThanEqual(int id, Pageable pageable); - - Page findPersonByIdGreaterThanEqual(int id, Pageable pageable); - - Page findPersonByIsMarriedLessThanEqual(Boolean id, Pageable pageable); - - Page findPersonByIsMarriedGreaterThanEqual(Boolean id, Pageable pageable); - - Iterable findAll(Sort sort); - - Page findAll(Pageable pageable); - - Iterable findAll(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/core/PersonRepository.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/core/PersonRepository.java deleted file mode 100644 index 0bd5ab73..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/core/PersonRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.utils.core; - -import org.springframework.data.repository.PagingAndSortingRepository; - -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data27.utils.entity.Person; - -public interface PersonRepository - extends PagingAndSortingRepository, - GenericRepositoryMethods, - GenericPaginationMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/ComplexPerson.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/ComplexPerson.java deleted file mode 100644 index e5927c81..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/ComplexPerson.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data27.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKey.class) -public class ComplexPerson implements GenericPerson { - - @Id - @Field("id") - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - protected Boolean isMarried; - - @Field("name") - @JsonProperty("name") - String name; - - @Override - public CompositePersonKey generateFullKey() { - return new CompositePersonKey(id, secondId); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/ComplexPersonWithIncorrectPK.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/ComplexPersonWithIncorrectPK.java deleted file mode 100644 index 207f14f0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/ComplexPersonWithIncorrectPK.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data27.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKeyWithoutJsonFormat.class) -public class ComplexPersonWithIncorrectPK { - - @Id - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/ComplexPersonWithJsonFormatVariantPK.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/ComplexPersonWithJsonFormatVariantPK.java deleted file mode 100644 index dc9b10e3..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/ComplexPersonWithJsonFormatVariantPK.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data27.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKeyWithJsonFormat.class) -public class ComplexPersonWithJsonFormatVariantPK { - - @Id - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositeKeyWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositeKeyWithWrongFieldTypes.java deleted file mode 100644 index fc99e784..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositeKeyWithWrongFieldTypes.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositeKeyWithWrongFieldTypes implements CompositeKey { - - @JsonProperty("id") - private long id; - - @JsonProperty("secondId") - private String secondId; - - @JsonProperty("thirdId") - private boolean thirdId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositePersonKey.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositePersonKey.java deleted file mode 100644 index fca1e9d2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositePersonKey.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositePersonKey implements CompositeKey { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositePersonKeyWithJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositePersonKeyWithJsonFormat.java deleted file mode 100644 index cebba73a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositePersonKeyWithJsonFormat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -public class CompositePersonKeyWithJsonFormat { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/EntityWithAnnotationAsIdClass.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/EntityWithAnnotationAsIdClass.java deleted file mode 100644 index be1b0a13..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/EntityWithAnnotationAsIdClass.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.utils.entity; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@IdClass(IdClass.class) -public class EntityWithAnnotationAsIdClass {} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/EntityWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/EntityWithWrongFieldTypes.java deleted file mode 100644 index 33866e7f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/EntityWithWrongFieldTypes.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@IdClass(CompositeKeyWithWrongFieldTypes.class) -public class EntityWithWrongFieldTypes { - - @Id - @JsonProperty("id") - private long id; - - @Id - @JsonProperty("secondId") - private String secondId; - - @Id - @JsonProperty("thirdId") - private int thirdId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/Person.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/Person.java deleted file mode 100644 index cc4778bb..00000000 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/Person.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data27.utils.entity; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data27.query.Field; - -/** - * @author Artyom Dubinin - */ -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("person") -public class Person implements GenericPerson { - - @Id - @Field("id") - @JsonProperty("id") - public Integer id; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; - - @Override - public Integer generateFullKey() { - return id; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/pom.xml b/tarantool-spring-data/tarantool-spring-data-31/pom.xml deleted file mode 100644 index d1536f30..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - 4.0.0 - - tarantool-spring-data-31 - Minimalistic java connector for Tarantool versions 2.11+ based on Netty framework - https://tarantool.io - - - io.tarantool - tarantool-spring-data - 2.0.0-SNAPSHOT - - - tarantool-spring-data-31 - 2.0.0-SNAPSHOT - jar - - - 17 - 17 - 3.1.12 - ${project.parent.parent.basedir}/tarantool-shared-resources/ - ${project.parent.parent.basedir}/LICENSE_HEADER.txt - - - - io.tarantool - tarantool-spring-data-core - - - diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/TarantoolBoxKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/TarantoolBoxKeyValueAdapter.java deleted file mode 100644 index 017c2647..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/TarantoolBoxKeyValueAdapter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31; - -import java.util.Map; - -import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.NonNull; - -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(Object id, Object item, String keyspace) { - return adapter.put(id, item, keyspace); - } - - @Override - public boolean contains(Object id, String keyspace) { - return adapter.contains(id, keyspace); - } - - @Override - public Object get(Object id, String keyspace) { - return adapter.get(id, keyspace); - } - - @Override - public Object delete(Object id, String keyspace) { - return adapter.delete(id, keyspace); - } - - @Override - public Iterable getAllOf(String keyspace) { - return adapter.getAllOf(keyspace); - } - - @Override - public void deleteAllOf(String keyspace) { - adapter.deleteAllOf(keyspace); - } - - @Override - public void clear() { - adapter.clear(); - } - - @Override - public long count(String keyspace) { - return adapter.count(keyspace); - } - - @Override - public void destroy() throws Exception { - adapter.destroy(); - } - - @Override - public CloseableIterator> entries(String keyspace) { - throw new UnsupportedOperationException("Not implemented yet"); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/TarantoolCrudKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/TarantoolCrudKeyValueAdapter.java deleted file mode 100644 index ead7d38e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/TarantoolCrudKeyValueAdapter.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31; - -import java.util.Collections; -import java.util.Map.Entry; - -import com.fasterxml.jackson.annotation.JsonFormat; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.NonNull; - -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(Object id, Object item, String keyspace) { - return adapter.put(convertId(id), item, keyspace); - } - - @Override - public boolean contains(Object id, String keyspace) { - return adapter.contains(convertId(id), keyspace); - } - - @Override - public Object get(Object id, String keyspace) { - return adapter.get(convertId(id), keyspace); - } - - @Override - public T get(Object id, String keyspace, Class type) { - return adapter.get(convertId(id), keyspace, type); - } - - @Override - public Object delete(Object id, String keyspace) { - return adapter.delete(convertId(id), keyspace); - } - - @Override - public T delete(Object id, String keyspace, Class type) { - return adapter.delete(convertId(id), keyspace, type); - } - - @Override - public Iterable getAllOf(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> 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()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/TarantoolQueryEngine.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/TarantoolQueryEngine.java deleted file mode 100644 index 022d0615..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/TarantoolQueryEngine.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31; - -import java.util.Collection; -import java.util.Comparator; -import java.util.Map.Entry; - -import org.springframework.data.keyvalue.core.QueryEngine; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.ProxyTarantoolQueryEngine; -import io.tarantool.spring.data.query.TarantoolCriteria; -import io.tarantool.spring.data31.query.TarantoolCriteriaAccessor; -import io.tarantool.spring.data31.query.TarantoolSortAccessor; - -/** - * Implementation of {@code findBy*()} and {@code countBy*{}} queries. - * - * @author Artyom Dubinin - */ -public class TarantoolQueryEngine - extends QueryEngine>> { - - 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> 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. - * - *

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 Collection execute( - @Nullable final TarantoolCriteria criteria, - @Nullable final Comparator> sort, - final long offset, - final int rows, - @NonNull final String keyspace, - @NonNull Class 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); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/config/TarantoolBoxConfiguration.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/config/TarantoolBoxConfiguration.java deleted file mode 100644 index ab5f20bb..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/config/TarantoolBoxConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.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.data31.TarantoolBoxKeyValueAdapter; -import io.tarantool.spring.data31.config.properties.TarantoolProperties; - -@Configuration(proxyBeanMethods = false) -public class TarantoolBoxConfiguration extends BaseTarantoolBoxConfiguration { - - public TarantoolBoxConfiguration( - ObjectProvider properties, - ObjectProvider 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(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/config/TarantoolCrudConfiguration.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/config/TarantoolCrudConfiguration.java deleted file mode 100644 index 036fc70c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/config/TarantoolCrudConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.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_CRUD_CLIENT_BEAN_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.spring.data.config.BaseTarantoolCrudConfiguration; -import io.tarantool.spring.data31.TarantoolCrudKeyValueAdapter; -import io.tarantool.spring.data31.config.properties.TarantoolProperties; - -@Configuration(proxyBeanMethods = false) -public class TarantoolCrudConfiguration extends BaseTarantoolCrudConfiguration { - - public TarantoolCrudConfiguration( - ObjectProvider properties, - ObjectProvider tarantoolClientConfiguration) { - super(properties.getIfAvailable(), tarantoolClientConfiguration.getIfAvailable()); - } - - @Bean(name = DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF) - @ConditionalOnMissingBean(TarantoolCrudKeyValueAdapter.class) - public TarantoolCrudKeyValueAdapter tarantoolCrudKeyValueAdapter( - TarantoolCrudClient tarantoolCrudClient) { - return new TarantoolCrudKeyValueAdapter(tarantoolCrudClient); - } - - @Bean(name = DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF) - @ConditionalOnMissingBean(TarantoolCrudClient.class) - public TarantoolCrudClient tarantoolCrudClient() throws Exception { - return super.tarantoolCrudClient(); - } - - public TarantoolCrudClientBuilder getClientBuilder() { - return super.getClientBuilder(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/config/package-info.java deleted file mode 100644 index 1c8390ce..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/config/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Config package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data31.config; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/config/properties/TarantoolProperties.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/config/properties/TarantoolProperties.java deleted file mode 100644 index 8f4dbc90..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/config/properties/TarantoolProperties.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.config.properties; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties; - -/** - * Configuration properties for Tarantool. - * - * @author Nikolay Belonogov - */ -@ConfigurationProperties(prefix = "spring.data.tarantool") -public class TarantoolProperties extends BaseTarantoolProperties {} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/annotation/DefaultIdClassResolver.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/annotation/DefaultIdClassResolver.java deleted file mode 100644 index ecc3d75c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/annotation/DefaultIdClassResolver.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.core.annotation; - -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.core.annotation.IdClassResolver; - -/** Default implementation of {@link IdClassResolver}. */ -public enum DefaultIdClassResolver implements IdClassResolver { - INSTANCE; - - public static final String ANNOTATION_TYPE_EXCEPTION = - "The class of a composite identifier specified in the @IdClass annotation cannot be" - + " annotation!"; - - @Nullable - @Override - public Class resolveIdClassType(Class type) { - Assert.notNull(type, "Type for IdClass must be not null!"); - - IdClass idClassTypeAnnotation = AnnotatedElementUtils.findMergedAnnotation(type, IdClass.class); - - if (idClassTypeAnnotation == null) { - return null; - } - - Class idClassTypeValue = idClassTypeAnnotation.value(); - Assert.isTrue(!idClassTypeValue.isAnnotation(), ANNOTATION_TYPE_EXCEPTION); - - return idClassTypeValue; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/annotation/package-info.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/annotation/package-info.java deleted file mode 100644 index 6e6823f6..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/annotation/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Core annotations of data mapping. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data31.core.annotation; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/BasicKeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/BasicKeyValueCompositePersistentEntity.java deleted file mode 100644 index cdf03bb0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/BasicKeyValueCompositePersistentEntity.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.core.mapping; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.data.domain.Persistable; -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.support.IsNewStrategy; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.mapping.model.CompositeKey; -import io.tarantool.spring.data31.core.mapping.model.CompositeIdPropertyAccessor; -import io.tarantool.spring.data31.core.mapping.model.PersistentCompositeIdIsNewStrategy; - -public class BasicKeyValueCompositePersistentEntity> - extends BasicKeyValuePersistentEntity implements KeyValueCompositePersistentEntity { - - public static final String TYPE_MISMATCH = - "Target bean of type %s is not of type of the persistent entity (%s)"; - - private final Class idClassTypeValue; - private @Nullable P idProperty; - - private Map entityIdClassFields; - - /** - * @param information must not be {@literal null}. - * @param fallbackKeySpaceResolver can be {@literal null}. - * @param idClassTypeValue class that specified in {@link IdClass} - */ - public BasicKeyValueCompositePersistentEntity( - TypeInformation information, - @Nullable KeySpaceResolver fallbackKeySpaceResolver, - Class idClassTypeValue) { - super(information, fallbackKeySpaceResolver); - - Assert.notNull(idClassTypeValue, "idClassTypeValue must be not null for this class!"); - this.idClassTypeValue = idClassTypeValue; - } - - @Override - public IdentifierAccessor getIdentifierAccessor(Object bean) { - verifyBeanType(bean); - - if (Persistable.class.isAssignableFrom(getType())) { - throw new IllegalArgumentException( - "Persistable override is not currently supported for entities with a composite key."); - } - - return hasIdProperty() - ? new CompositeIdPropertyAccessor(bean, this.entityIdClassFields, getIdClassType()) - : new AbsentIdentifierAccessor(); - } - - @Override - public Class getIdClassType() { - return this.idClassTypeValue; - } - - @Override - public void verify() { - super.verify(); - - if (this.idProperty != null) { - this.entityIdClassFields = KeyPartTypeChecker.getFieldMapIfTypesValid(this, this.idProperty); - } - } - - @Override - protected IsNewStrategy getFallbackIsNewStrategy() { - return PersistentCompositeIdIsNewStrategy.of(this); - } - - @Override - protected P returnPropertyIfBetterIdPropertyCandidateOrNull(P property) { - Assert.isInstanceOf(Identifier.class, property, "property must be Identifier for this class"); - - if (!property.isIdProperty()) { - return null; - } - - if (this.idProperty == null) { - this.idProperty = property; - return this.idProperty; - } - - this.idProperty.addPart(property); - - return this.idProperty; - } - - /** - * Verifies the given bean type to no be {@literal null} and of the type of the current {@link - * PersistentEntity}. - * - * @param bean must not be {@literal null}. - */ - private void verifyBeanType(Object bean) { - - Assert.notNull(bean, "Target bean must not be null"); - Assert.isInstanceOf( - getType(), - bean, - () -> String.format(TYPE_MISMATCH, bean.getClass().getName(), getType().getName())); - } - - /** - * A null-object implementation of {@link IdentifierAccessor} to be able to return an accessor for - * entities that do not have an identifier property. - */ - private static class AbsentIdentifierAccessor implements IdentifierAccessor { - - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.IdentifierAccessor#getIdentifier() - */ - @Override - @Nullable - public Object getIdentifier() { - return null; - } - } - - /** - * A class that checks the types of fields of a composite key. In addition, the correspondence - * between types and field names marked with {@code @Id}. - */ - public static class KeyPartTypeChecker { - - public static final String COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION = - "Number of fields specified in domain class and composite class the key is different!"; - - public static final String COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION = - "Domain class fields marked with @Id differ from fields specified in the composite key" - + " class"; - - /** - * Check the number and types of entity fields, annotated {@code @Id} and fields {@link - * CompositeKey} and if the types and quantities match return the id part fields mapping. - * - * @param persistentEntity persistent entity - * @param idProperty id property - * @return mapping between fields of composite key class and fields annotated {@code @Id} in - * entity. - */ - public static Map getFieldMapIfTypesValid( - KeyValueCompositePersistentEntity persistentEntity, Identifier idProperty) { - Map entityIdClassFields = new HashMap<>(); - - List compositeKeyFields = persistentEntity.getIdClassTypeFields(); - - Field[] entityFields = idProperty.getFields(); - - if (compositeKeyFields.size() != entityFields.length) { - throw new IllegalArgumentException(COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION); - } - - for (int i = 0; i < compositeKeyFields.size(); i++) { - Field compositeKeyField = compositeKeyFields.get(i); - Field entityField = entityFields[i]; - - if (!equalFields(compositeKeyField, entityField)) { - throw new IllegalArgumentException(COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION); - } - - entityIdClassFields.put(entityField, compositeKeyField); - } - return entityIdClassFields; - } - - /** - * Compares two class fields by name and type. - * - * @param firstField first field - * @param secondField second field - * @return true if fields are equal - */ - private static boolean equalFields(Field firstField, Field secondField) { - return firstField.getName().equals(secondField.getName()) - && firstField.getType().equals(secondField.getType()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/KeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/KeyValueCompositePersistentEntity.java deleted file mode 100644 index 34d8ac67..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/KeyValueCompositePersistentEntity.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.core.mapping; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.model.MutablePersistentEntity; - -import io.tarantool.spring.data.core.annotation.IdClass; - -/** - * An interface to enable {@link PersistentEntity}-specific operations with a composite key. - * - * @param domain class type - * @param

{@link PersistentProperty} type - */ -public interface KeyValueCompositePersistentEntity> - extends MutablePersistentEntity { - - /** - * Returns the fields of the class specified in the {@link IdClass} annotation. - * - * @return all fields that are in composite key class - */ - default List getIdClassTypeFields() { - List fields = new ArrayList<>(); - - for (Field field : getIdClassType().getDeclaredFields()) { - if (!field.isSynthetic()) { - fields.add(field); - } - } - return fields; - } - - /** - * Returns the type of the class specified in the {@link IdClass} annotation. - * - * @return class that specified in {@link IdClass} - */ - Class getIdClassType(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/TarantoolMappingContext.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/TarantoolMappingContext.java deleted file mode 100644 index 6974ca0d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/TarantoolMappingContext.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.core.mapping; - -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; - -import io.tarantool.spring.data.core.annotation.IdClassResolver; -import io.tarantool.spring.data31.core.annotation.DefaultIdClassResolver; - -public class TarantoolMappingContext< - E extends KeyValuePersistentEntity, P extends KeyValuePersistentProperty

> - extends KeyValueMappingContext { - - private final IdClassResolver idClassResolver; - - private @Nullable KeySpaceResolver keySpaceResolver; - - public TarantoolMappingContext() { - super(); - this.idClassResolver = DefaultIdClassResolver.INSTANCE; - } - - @Override - public void setKeySpaceResolver(KeySpaceResolver keySpaceResolver) { - super.setKeySpaceResolver(keySpaceResolver); - this.keySpaceResolver = keySpaceResolver; - } - - @SuppressWarnings("unchecked") - @Override - protected E createPersistentEntity(TypeInformation typeInformation) { - final Class idClassTypeValue = - this.idClassResolver.resolveIdClassType(typeInformation.getType()); - if (idClassTypeValue == null) { - return (E) new BasicKeyValuePersistentEntity(typeInformation, this.keySpaceResolver); - } - return (E) - new BasicKeyValueCompositePersistentEntity<>( - typeInformation, this.keySpaceResolver, idClassTypeValue); - } - - @SuppressWarnings("unchecked") - @Override - protected P createPersistentProperty( - Property property, E owner, SimpleTypeHolder simpleTypeHolder) { - if (KeyValueCompositePersistentEntity.class.isAssignableFrom(owner.getClass())) { - return (P) new KeyValueCompositeProperty<>(property, owner, simpleTypeHolder); - } - return (P) new KeyValuePersistentProperty<>(property, owner, simpleTypeHolder); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/model/CompositeIdPropertyAccessor.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/model/CompositeIdPropertyAccessor.java deleted file mode 100644 index 49d227c1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/model/CompositeIdPropertyAccessor.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.core.mapping.model; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.util.Map; - -import org.springframework.data.mapping.TargetAwareIdentifierAccessor; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -/** Class that allows to convert {@code @Id} annotated fields in an entity into a composite key. */ -public class CompositeIdPropertyAccessor extends TargetAwareIdentifierAccessor { - - private final Map entityIdClassFields; - - private final Class idClassType; - - private final Object target; - - public CompositeIdPropertyAccessor( - Object target, @NonNull Map entityIdClassFields, Class idClassType) { - - super(target); - this.target = target; - this.entityIdClassFields = entityIdClassFields; - this.idClassType = idClassType; - } - - @Nullable - public Object getIdentifier() { - try { - return generateIdentifier(); - } catch (InstantiationException - | IllegalAccessException - | NoSuchMethodException - | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - /** - * Generates a composite identifier from those marked with the {@code @Id} annotation in a domain - * class based on fields, specified in the composite key class. - * - * @return identifier - * @throws IllegalAccessException if the class or its nullary constructor is not accessible. - * @throws InstantiationException if this {@code Class} represents an abstract class, an - * interface, an array class, a primitive type, or void; or if the class has no nullary - * constructor; or if the instantiation fails for some other reason. - */ - private Object generateIdentifier() - throws InstantiationException, - IllegalAccessException, - NoSuchMethodException, - InvocationTargetException { - Assert.notNull(this.target, "target object must be not null!"); - Object compositeKey = idClassType.getDeclaredConstructor().newInstance(); - for (Map.Entry fieldPair : this.entityIdClassFields.entrySet()) { - writeValuesFromEntityId(compositeKey, fieldPair.getKey(), fieldPair.getValue()); - } - return compositeKey; - } - - /** - * Write the composite primary key fields provided in the entity to the class which implements - * {@link CompositeKey}. - * - * @param compositeKey object of the composite key into which the values are written. - * @param entityField field from the represented entity. - * @param compositeKeyField field from the composite key class. - */ - private void writeValuesFromEntityId( - Object compositeKey, Field entityField, Field compositeKeyField) { - ReflectionUtils.makeAccessible(entityField); - ReflectionUtils.makeAccessible(compositeKeyField); - - Object value = ReflectionUtils.getField(entityField, this.target); - ReflectionUtils.setField(compositeKeyField, compositeKey, value); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/model/PersistentCompositeIdIsNewStrategy.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/model/PersistentCompositeIdIsNewStrategy.java deleted file mode 100644 index 627f2edb..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/model/PersistentCompositeIdIsNewStrategy.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.core.mapping.model; - -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.support.IsNewStrategy; -import org.springframework.util.Assert; - -/** - * Strategy class for entity with composite key to determine whether a given entity is to be - * considered new. - */ -public class PersistentCompositeIdIsNewStrategy implements IsNewStrategy { - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} for the given entity. - * - * @param entity must not be {@literal null}. - * @param idOnly check only id to determine - */ - private PersistentCompositeIdIsNewStrategy(PersistentEntity entity, boolean idOnly) { - // TODO сделать реализацию версионирования - // TODO add idOnly support - Assert.notNull(entity, "PersistentEntity must not be null"); - } - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} to only consider the identifier of the - * given entity. - * - * @param entity must not be {@literal null}. - * @return strategy to determine whether entity is new or not - */ - public static PersistentCompositeIdIsNewStrategy forIdOnly(PersistentEntity entity) { - return new PersistentCompositeIdIsNewStrategy(entity, true); - } - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} to consider version properties before - * falling back to the identifier. - * - * @param entity must not be {@literal null}. - * @return strategy to determine whether entity is new or not - */ - public static PersistentCompositeIdIsNewStrategy of(PersistentEntity entity) { - return new PersistentCompositeIdIsNewStrategy(entity, false); - } - - /** - * Determine whether the current domain entity type object is new. Currently stub and always - * returns false. - * - * @param entity must not be {@literal null}. - * @return result of the question of entity is new or not - */ - @Override - public boolean isNew(Object entity) { - return false; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/model/package-info.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/model/package-info.java deleted file mode 100644 index afe48f06..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/model/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Core implementation of the mapping subsystem's model. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data31.core.mapping.model; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/package-info.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/package-info.java deleted file mode 100644 index 93e97517..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Base package for the mapping subsystem. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data31.core.mapping; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/package-info.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/package-info.java deleted file mode 100644 index d952e8c2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Core package for integrating Tarantool with Spring - * concepts. - */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data31.core; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolChunk.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolChunk.java deleted file mode 100644 index bea67af8..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolChunk.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -/** - * A chunk of data restricted by the configured {@link Pageable} for Tarantool. - * - * @author Nikolay Belonogov - */ -abstract class TarantoolChunk implements Slice, Serializable { - - private static final long serialVersionUID = 867755909294344406L; - - private final List content = new ArrayList<>(); - - private final Pageable pageable; - - /** - * Creates a new {@link TarantoolChunk} with the given content and the given governing {@link - * TarantoolPageable}. - * - * @param content must not be {@literal null}. - * @param pageable must not be {@literal null}. - */ - public TarantoolChunk(List content, Pageable pageable) { - - Assert.notNull(content, "Content must not be null"); - Assert.notNull(pageable, "Pageable must not be null"); - - if (pageable.isPaged() && !(pageable instanceof TarantoolPageable)) { - throw new IllegalArgumentException("Pageable must be TarantoolPageable or Unpaged type"); - } - - this.content.addAll(content); - this.pageable = pageable; - } - - @Override - public boolean isFirst() { - return !hasPrevious(); - } - - @Override - public boolean isLast() { - return !hasNext(); - } - - @Override - public boolean hasPrevious() { - return getNumber() > 0 && hasContent(); - } - - @Override - public boolean hasContent() { - return !content.isEmpty(); - } - - /** - * Returns the {@link Pageable} to request the next {@link Slice}. Can be {@link - * Pageable#unpaged()} in case the current {@link Slice} is already the last one or when data - * content is empty. Clients should check {@link #hasNext()} and {@link #hasContent()} before - * calling this method. - * - * @see #nextOrLastPageable() - */ - @NonNull - @Override - @SuppressWarnings("unchecked") - public Pageable nextPageable() { - if (hasNext() && pageable.isPaged()) { - return ((TarantoolPageable) pageable).next(content.get(content.size() - 1)); - } - return Pageable.unpaged(); - } - - /** - * Returns the {@link Pageable} to request the previous {@link Slice}. Can be {@link - * Pageable#unpaged()} in case the current {@link Slice} is already the first one or data content - * is empty. Clients should check {@link #hasPrevious()} and {@link #hasContent()} before calling - * this method. - * - * @see #previousOrFirstPageable() - */ - @NonNull - @Override - @SuppressWarnings("unchecked") - public Pageable previousPageable() { - if (hasPrevious() && pageable.isPaged()) { - return ((TarantoolPageable) pageable).previousOrFirst(content.get(0)); - } - return Pageable.unpaged(); - } - - @Override - public Iterator iterator() { - return content.iterator(); - } - - @NonNull - @Override - public List getContent() { - return Collections.unmodifiableList(content); - } - - @NonNull - @Override - public Pageable getPageable() { - return pageable; - } - - @NonNull - @Override - public Sort getSort() { - return pageable.getSort(); - } - - @Override - public int getNumber() { - if (pageable.isPaged()) { - return pageable.getPageNumber(); - } - return 0; - } - - @Override - public int getSize() { - if (pageable.isPaged()) { - return pageable.getPageSize(); - } - return content.size(); - } - - @Override - public int getNumberOfElements() { - return content.size(); - } - - /** - * Applies the given {@link Function} to the content of the {@link TarantoolChunk}. - * - * @param converter must not be {@literal null}. - */ - protected List getConvertedContent(Function converter) { - - Assert.notNull(converter, "Function must not be null"); - - return this.stream().map(converter).collect(Collectors.toList()); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolChunk)) { - return false; - } - TarantoolChunk that = (TarantoolChunk) o; - return content.equals(that.content) && pageable.equals(that.pageable); - } - - @Override - public int hashCode() { - return Objects.hash(content, pageable); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolKeysetScrollPosition.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolKeysetScrollPosition.java deleted file mode 100644 index f475a208..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolKeysetScrollPosition.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.util.List; -import java.util.Objects; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.Pair; - -final class TarantoolKeysetScrollPosition implements TarantoolScrollPosition { - - private final Pair indexKey; - - private final PaginationDirection direction; - - private final Object cursor; - - TarantoolKeysetScrollPosition( - Pair indexKey, PaginationDirection direction, @Nullable Object cursor) { - - Assert.notNull(direction, "PaginationDirection must not be null"); - Assert.notNull(indexKey, "indexKey must not be null"); - - this.indexKey = indexKey; - this.direction = direction; - this.cursor = cursor; - } - - /** - * Creates a new {@link TarantoolKeysetScrollPosition} from a key set and {@link - * PaginationDirection}. - * - * @param indexKey must not be {@literal null}. - * @return will never be {@literal null}. - */ - static TarantoolScrollPosition forward(Pair indexKey) { - return new TarantoolKeysetScrollPosition(indexKey, FORWARD, null); - } - - static TarantoolScrollPosition backward(Pair indexKey) { - return new TarantoolKeysetScrollPosition(indexKey, BACKWARD, null); - } - - /** - * Returns whether the current scroll position is the initial one (from begin or from end) (see - * {@link PaginationDirection}). - * - * @return {@link Boolean} object. - */ - @Override - public boolean isInitial() { - if (indexKey.getSecond() instanceof List startingList) { - return startingList.isEmpty() && cursor == null; - } - return false; - } - - @Override - public TarantoolScrollPosition reverse() { - Pair newIndexKey = Pair.of(indexKey.getFirst(), indexKey.getSecond()); - return new TarantoolKeysetScrollPosition(newIndexKey, direction.reverse(), cursor); - } - - @Override - public boolean isScrollsBackward() { - return direction.equals(BACKWARD); - } - - /** - * Return the cursor relative to which the data is being found. - * - * @return returns cursor - */ - Object getCursor() { - return cursor; - } - - /** - * @return the scroll direction. - */ - PaginationDirection getDirection() { - return direction; - } - - /** - * @return the indexKey. - */ - Pair getIndexKey() { - return indexKey; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolKeysetScrollPosition that)) { - return false; - } - return indexKey.equals(that.indexKey) - && direction == that.direction - && Objects.equals(cursor, that.cursor); - } - - @Override - public int hashCode() { - return Objects.hash(indexKey, direction, cursor); - } - - @Override - public String toString() { - return String.format("TarantoolKeysetScrollPosition [%s, %s, %s]", direction, indexKey, cursor); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolPageImpl.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolPageImpl.java deleted file mode 100644 index e5c5738b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolPageImpl.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.io.Serial; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.lang.NonNull; - -/** - * Basic {@code Page} implementation for Tarantool. - * - * @param domain class type. - * @author Nikolay Belonogov - */ -class TarantoolPageImpl extends TarantoolChunk implements Page { - - @Serial private static final long serialVersionUID = 867755909294344406L; - - private final long total; - - /** - * Creates a new {@link TarantoolPageImpl} with empty content. This will result in the created - * {@link Page} being identical to the entire {@link List}. - */ - public TarantoolPageImpl() { - this(Collections.emptyList(), Pageable.unpaged(), 0L); - } - - /** - * Creates a new {@link TarantoolPageImpl} with the given content. This will result in the created - * {@link Page} being identical to the entire {@link List}. - * - * @param content must not be {@literal null}. - */ - public TarantoolPageImpl(List content) { - this(content, Pageable.unpaged(), content == null ? 0L : content.size()); - } - - /** - * Constructor of {@link TarantoolPageImpl}. - * - * @param content the content of this page, must not be {@literal null}. - * @param pageable the paging information, must not be {@literal null}. - * @param total the total amount of items available. The total might be adapted considering the - * length of the content given, if it is going to be the content of the last page. This is in - * place to mitigate inconsistencies. - */ - public TarantoolPageImpl(List content, Pageable pageable, long total) { - - super(content, pageable); - - this.total = - pageable - .toOptional() - .filter(it -> !content.isEmpty()) - .filter(it -> it.getOffset() + it.getPageSize() > total) - .map(it -> it.getOffset() + content.size()) - .orElse(total); - } - - @Override - public int getTotalPages() { - return getSize() == 0 ? 1 : (int) Math.ceil((double) total / (double) getSize()); - } - - @Override - public long getTotalElements() { - return total; - } - - @Override - public boolean hasNext() { - return getNumber() + 1 < getTotalPages() && hasContent(); - } - - @Override - public boolean isLast() { - return !hasNext(); - } - - @Override - @NonNull - public Page map(@NonNull Function converter) { - return new PageImpl<>(getConvertedContent(converter), getPageable(), total); - } - - @Override - public String toString() { - - List content = getContent(); - boolean canGetContentType = !content.isEmpty() && content.get(0) != null; - - String contentType = canGetContentType ? content.get(0).getClass().getName() : "UNKNOWN"; - - return String.format( - "Page %s of %d containing %s instances", getNumber() + 1, getTotalPages(), contentType); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolPageImpl that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return total == that.total; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), total); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolPageRequest.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolPageRequest.java deleted file mode 100644 index f9633d1a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolPageRequest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.io.Serial; -import java.util.Objects; - -import org.springframework.data.domain.AbstractPageRequest; -import org.springframework.data.domain.Sort; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; - -/** - * Basic implementation of {@link TarantoolPageable} for Tarantool. - * - *

Important: When specifying a cursor tuple, you must adhere to the following - * rules: - * - *

1. To specify a page starting from the beginning of {@code space} (the first element of the - * page is the first element found in {@code space}), use {@code tupleCursor == null}. - * - *

2. To specify an arbitrary page (the first element of the page is the next/previous one from - * the given one tuple cursor depending on the methods used and page number), use {@code tupleCursor - * == someTupleCursor} . - * - * @param domain entity type - */ -public final class TarantoolPageRequest extends AbstractPageRequest - implements TarantoolPageable { - - @Serial private static final long serialVersionUID = -4541509938956089562L; - - private final Sort sort; - - private final T tupleCursor; - - private final PaginationDirection paginationDirection; - - /** - * Creates a new unsorted {@link TarantoolPageRequest} from begin of {@code space}. - * - * @param pageSize the size of the page to be returned, must be greater than 0. - */ - public TarantoolPageRequest(int pageSize) { - this(0, pageSize, null); - } - - /** - * Creates a new unsorted {@link TarantoolPageRequest}. - * - *

Important: Use this method with caution! It is important to know the exact - * match of number pages and the tuple after (before) which the page goes (without including this - * tuple in the page itself). A mistake in compliance results in the appearance of blank pages - * with unpaged pageable even when using methods {@link - * TarantoolPageImpl#previousOrFirstPageable()} / {@link TarantoolPageImpl#nextOrLastPageable()} - * and {@link TarantoolSliceImpl#previousOrFirstPageable()} / {@link - * TarantoolSliceImpl#nextOrLastPageable()}. - * - * @param page zero-based page index (virtual), must not be negative. - * @param size the size of the page to be returned, must be greater than 0. - * @param tupleCursor tuple cursor from which the page count begins. More: {@link - * TarantoolPageRequest}. - */ - public TarantoolPageRequest(int page, int size, T tupleCursor) { - this(page, size, Sort.unsorted(), tupleCursor, FORWARD); - } - - /** - * Private constructor to create an instance with a specific {@link PaginationDirection}. - * - * @param page zero-based page index, must not be negative. - * @param size the size of the page to be returned, must be greater than 0. - * @param sort must not be {@literal null}, use {@link Sort#unsorted()} instead. - * @param tupleCursor tuple cursor from which the page count begins. More: {@link - * TarantoolPageRequest}. - * @param direction direction of pagination. - */ - TarantoolPageRequest( - int page, int size, Sort sort, T tupleCursor, @NonNull PaginationDirection direction) { - super(page, size); - Assert.notNull(sort, "Sort must not be null"); - Assert.notNull(direction, "PaginationDirection must not be null"); - - this.sort = sort; - this.tupleCursor = tupleCursor; - this.paginationDirection = direction; - } - - /** Non supported for Tarantool. */ - @Override - @NonNull - public TarantoolPageRequest withPage(int pageNumber) throws UnsupportedOperationException { - throw new UnsupportedOperationException("method \"withPage(int pageNumber)\" unsupported"); - } - - @Override - @NonNull - public TarantoolPageable first() { - return new TarantoolPageRequest<>(getPageSize()); - } - - /** Non supported for Tarantool. Use {@link #next(Object)}. */ - @Override - @NonNull - public TarantoolPageRequest next() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"next()\" unsupported, use next(T nextTupleCursor)"); - } - - @Override - public TarantoolPageRequest next(T tupleCursor) { - return new TarantoolPageRequest<>( - getPageNumber() + 1, getPageSize(), getSort(), tupleCursor, FORWARD); - } - - /** Non supported for Tarantool. Use {@link #previous(Object)}. */ - @Override - @NonNull - public TarantoolPageRequest previous() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"previous()\" unsupported, use previous(T prevTupleCursor)"); - } - - private TarantoolPageRequest previous(T tupleCursor) { - if (hasPrevious()) { - return new TarantoolPageRequest<>( - getPageNumber() - 1, getPageSize(), getSort(), tupleCursor, BACKWARD); - } - return this; - } - - /** Non supported for Tarantool. Use {@link #previousOrFirst(Object)}. */ - @Override - @NonNull - public TarantoolPageable previousOrFirst() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"previousOrFirst()\" unsupported, use previousOrFirst(T prevTupleCursor)"); - } - - @Override - public TarantoolPageable previousOrFirst(T tupleCursor) { - if (hasPrevious()) { - return previous(tupleCursor); - } - return new TarantoolPageRequest<>(0, getPageSize(), getSort(), null, BACKWARD); - } - - @Override - public PaginationDirection getPaginationDirection() { - return this.paginationDirection; - } - - @Override - @NonNull - public Sort getSort() { - return this.sort; - } - - @Override - public T getTupleCursor() { - return this.tupleCursor; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolPageRequest that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return sort.equals(that.sort) - && Objects.equals(tupleCursor, that.tupleCursor) - && paginationDirection == that.paginationDirection; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), sort, tupleCursor, paginationDirection); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolPageable.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolPageable.java deleted file mode 100644 index 3868a7d8..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolPageable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import org.springframework.data.domain.Pageable; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; - -import io.tarantool.spring.data.query.PaginationDirection; - -/** - * Abstract interface for pagination information in Tarantool. - * - * @param domain class type. - * @author Nikolay Belonogov - */ -public interface TarantoolPageable extends Pageable { - - /** - * Returns tuple cursor of domain type. Can be {@code null}. If the cursor is {@code null} then - * the page is counted from the first tuple in Tarantool. - * - * @return tuple cursor of domain type. - */ - @Nullable - T getTupleCursor(); - - /** - * Returns the {@link TarantoolPageable} for previous page or the {@link TarantoolPageable} for - * first page if the current one already is the first one. Important: this method - * always returns {@link TarantoolPageable} c {@link PaginationDirection#BACKWARD}. - * - * @param tupleCursor tuple cursor of domain type for previous page. - * @return {@link TarantoolPageable} instance. - */ - TarantoolPageable previousOrFirst(T tupleCursor); - - /** - * Returns the {@link TarantoolPageable} requesting the next {@link - * org.springframework.data.domain.Page}. - * - *

Important: method always creates a new {@link TarantoolPageable} with the - * same parameters Sort and page size. Pagination direction is {@link - * PaginationDirection#FORWARD}, the page number always has value {@code n+1}, n is the current - * page number. - * - * @param tupleCursor tuple cursor of domain type for next page. - * @return {@link TarantoolPageable} object - */ - TarantoolPageable next(T tupleCursor); - - /** - * Returns pagination direction by {@link PaginationDirection} enumeration. - * - * @return {@link PaginationDirection}. - */ - PaginationDirection getPaginationDirection(); - - /** - * Returns a {@link TarantoolPageable} that points to the first page with {@link - * PaginationDirection#FORWARD} pagination direction. - * - * @return {@link TarantoolPageable} which has {@code cursor == null}, page number is 0, the rest - * parameters are equivalent to the parameters of the current {@link TarantoolPageable}. - */ - @NonNull - TarantoolPageable first(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolPartTreeQuery.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolPartTreeQuery.java deleted file mode 100644 index 433b76e2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolPartTreeQuery.java +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; -import org.springframework.data.keyvalue.core.IterableConverter; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery; -import org.springframework.data.repository.query.Parameter; -import org.springframework.data.repository.query.Parameters; -import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.data.util.StreamUtils; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -import static io.tarantool.client.crud.ConditionOperator.GREATER_EQ; -import static io.tarantool.client.crud.ConditionOperator.LESS_EQ; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import static io.tarantool.spring.data31.query.PaginationUtils.doPageQuery; -import static io.tarantool.spring.data31.query.PaginationUtils.doPaginationQuery; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.query.TarantoolCriteria; -import io.tarantool.spring.data.utils.Pair; - -/** - * There is one instance for each query method defined for a repository, providing a query from the - * bind parameters. - * - * @author Artyom Dubinin - */ -public class TarantoolPartTreeQuery extends KeyValuePartTreeQuery { - - public static final String ILLEGAL_RETURN_TYPE_FOR_DELETE = - "Illegal returned type: %s. The operation 'deleteBy' accepts only 'long' and 'Collection' as" - + " the returned object type"; - public static final String QUERY_METHOD_S_NOT_SUPPORTED = "Query method '%s' not supported."; - private final QueryMethod queryMethod; - private final KeyValueOperations keyValueOperations; - private final PartTree tree; - - private final boolean isCount; - private final boolean isDelete; - private final boolean isDistinct; - private final boolean isExists; - private final Class targetType; - private final Class returnType; - - private boolean isRearrangeKnown; - private boolean isRearrangeRequired; - private int[] rearrangeIndex; - - private final List EMPTY_KEY = Collections.emptyList(); - - /** - * Create a {@link RepositoryQuery} implementation for each query method defined in a tarantool - * repository. - * - * @param queryMethod Method defined in Tarantool Repositories - * @param evaluationContextProvider Not used - * @param keyValueOperations Interface to Tarantool - * @param queryCreator Not used - */ - public TarantoolPartTreeQuery( - QueryMethod queryMethod, - QueryMethodEvaluationContextProvider evaluationContextProvider, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - super(queryMethod, evaluationContextProvider, keyValueOperations, queryCreator); - this.queryMethod = queryMethod; - this.keyValueOperations = keyValueOperations; - this.isRearrangeKnown = false; - this.targetType = queryMethod.getEntityInformation().getJavaType(); - this.returnType = queryMethod.getReturnedObjectType(); - this.tree = new PartTree(getQueryMethod().getName(), targetType); - if (queryMethod.getParameters().getNumberOfParameters() > 0) { - this.isCount = tree.isCountProjection(); - this.isDelete = tree.isDelete(); - this.isDistinct = tree.isDistinct(); - this.isExists = tree.isExistsProjection(); - } else { - this.isCount = false; - this.isDelete = false; - this.isDistinct = false; - this.isExists = false; - } - } - - /** - * Execute this query instance, using any invocation parameters. - * - *

Expecting {@code findBy...()}, {@code countBy...()} or {@code deleteBy...()} - * - * @param parameters Any parameters - * @return Query result - */ - @Override - public Object execute(@NonNull Object[] parameters) { - ParametersParameterAccessor accessor = this.prepareAccessor(parameters, tree); - - KeyValueQuery query = prepareQuery(accessor); - - if (this.isCount) { - if (this.isDistinct) { - final Iterable iterable = this.keyValueOperations.find(query, targetType); - return StreamUtils.createStreamFromIterator(iterable.iterator()).distinct().count(); - } - return this.keyValueOperations.count(query, targetType); - } - - if (this.isDelete) { - return this.executeDeleteQuery(query); - } - - if (this.isExists) { - query.setOffset(0); - query.setRows(1); - final Iterable result = this.keyValueOperations.find(query, targetType); - return result.iterator().hasNext(); - } - - if (queryMethod.isPageQuery()) { - return this.executePageQuery(query, accessor); - } - - if (queryMethod.isSliceQuery()) { - return this.executeSliceQuery(query, accessor); - } - - if (queryMethod.isScrollQuery()) { - return this.executeScrollQuery(query, accessor); - } - - if (queryMethod.isCollectionQuery() - || queryMethod.isQueryForEntity() - || queryMethod.isStreamQuery()) { - return this.executeFindQuery(query); - } - - throw new UnsupportedOperationException( - String.format(QUERY_METHOD_S_NOT_SUPPORTED, queryMethod.getName())); - } - - /** - * Execute a "delete" query, not really a query more of an operation. - * - *

- * - * @param query The query to run - * @return Collection of deleted objects or the number of deleted objects - */ - private Object executeDeleteQuery(final KeyValueQuery query) { - - Iterable resultSet = this.keyValueOperations.find(query, targetType); - Iterator iterator = resultSet.iterator(); - - List result = new ArrayList<>(); - while (iterator.hasNext()) { - result.add(this.keyValueOperations.delete(iterator.next())); - } - - if (queryMethod.isCollectionQuery()) { - return result; - } - if (long.class.equals(returnType) || Long.class.equals(returnType)) { - return result.size(); - } - throw new UnsupportedOperationException( - String.format(ILLEGAL_RETURN_TYPE_FOR_DELETE, returnType)); - } - - /** - * Execute a retrieval query. The query engine will return this in an iterator, which may need - * conversion to a single domain entity or a stream. - * - * @param query The query to run - * @return Query result - */ - private Object executeFindQuery(final KeyValueQuery query) { - - Iterable resultSet = this.keyValueOperations.find(query, targetType); - - if (!queryMethod.isCollectionQuery() - && !queryMethod.isPageQuery() - && !queryMethod.isSliceQuery() - && !queryMethod.isStreamQuery()) { - // Singleton result - return resultSet.iterator().hasNext() ? resultSet.iterator().next() : null; - } - - Stream stream = StreamUtils.createStreamFromIterator(resultSet.iterator()); - if (this.isDistinct) { - stream = stream.distinct(); - } - - if (queryMethod.isStreamQuery()) { - return stream; - } - - // optimization: - // we can omit if condition - // but this will recreate result even if it's not distinct and isn't stream query - if (this.isDistinct) { - return stream.collect(Collectors.toList()); - } - - return resultSet; - } - - private Object executeScrollQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - ScrollPosition scrollPosition = accessor.getScrollPosition(); - - Assert.notNull( - scrollPosition, - "The ScrollPosition parameter must be specified. Method: " + queryMethod.getName()); - - if (!(scrollPosition instanceof TarantoolKeysetScrollPosition keysetScrollPosition)) { - throw new IllegalArgumentException( - "ScrollPosition must be an instance of TarantoolKeysetScrollPosition. Method: " - + queryMethod.getName()); - } - - int pageSize = query.getRows(); - List content = doScrollQuery(query, keysetScrollPosition, pageSize + 1); - - boolean hasNext = content.size() > pageSize; - - final List finalResult = getPaginationSubResult(content, pageSize, FORWARD, hasNext); - return Window.from( - finalResult, - value -> - new TarantoolKeysetScrollPosition( - keysetScrollPosition.getIndexKey(), - keysetScrollPosition.getDirection(), - finalResult.get(value)), - hasNext); - } - - private List doScrollQuery( - final KeyValueQuery query, TarantoolKeysetScrollPosition scrollPosition, int pageSize) { - TarantoolCriteria criteria = castToTarantoolCriteria(query.getCriteria()); - PaginationDirection paginationDirection = scrollPosition.getDirection(); - - Object cursor = scrollPosition.getCursor(); - Pair indexKey = scrollPosition.getIndexKey(); - - Object second = EMPTY_KEY; - if (cursor == null) { - second = indexKey.getSecond(); - } - - switch (paginationDirection) { - case FORWARD -> - criteria.addCondition(0, Condition.create(GREATER_EQ, indexKey.getFirst(), second)); - case BACKWARD -> - criteria.addCondition(0, Condition.create(LESS_EQ, indexKey.getFirst(), second)); - } - - criteria.withAfter(cursor); - query.setRows(pageSize); - return IterableConverter.toList(this.keyValueOperations.find(query, targetType)); - } - - /** - * Execute the slice request. - * - * @param query query - * @param accessor accessor - * @return slice selection result. - */ - private Object executePageQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - - Pageable pageParams = accessor.getPageable(); - - return doPageQuery(pageParams, query, this.keyValueOperations, targetType); - } - - private Object executeSliceQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - - Pageable sliceParams = accessor.getPageable(); - - if (sliceParams.isUnpaged()) { - return new TarantoolSliceImpl<>(Collections.emptyList()); - } - - TarantoolPageable resultSliceParams = castToTarantoolPageable(sliceParams); - - int pageSize = resultSliceParams.getPageSize(); - - List content = - doPaginationQuery( - query, resultSliceParams, pageSize + 1, this.keyValueOperations, targetType); - - if (content.isEmpty()) { - return new TarantoolSliceImpl<>(); - } - - boolean hasNext = content.size() > resultSliceParams.getPageSize(); - PaginationDirection paginationDirection = resultSliceParams.getPaginationDirection(); - - List result = getPaginationSubResult(content, pageSize, paginationDirection, hasNext); - return new TarantoolSliceImpl<>(result, resultSliceParams, hasNext); - } - - /** - * Returns {@link TarantoolPageable} cast from {@link Pageable} with type checking. - * - * @param sliceParams pageable - * @return {@link TarantoolPageable} - */ - private TarantoolPageable castToTarantoolPageable(Pageable sliceParams) { - Assert.isInstanceOf(TarantoolPageable.class, sliceParams, "Pageable must be TarantoolPageable"); - return (TarantoolPageable) sliceParams; - } - - /** - * The method allows you to get {@link TarantoolCriteria} even when pagination is used through - * methods the base repository (not via derived methods). - * - * @param criteria criteria object - * @return An instance of {@link TarantoolCriteria}, or creates a new one if null. - */ - private TarantoolCriteria castToTarantoolCriteria(Object criteria) { - if (criteria == null) { - return new TarantoolCriteria(); - } - - if (!(criteria instanceof TarantoolCriteria)) { - throw new IllegalArgumentException("criteria must be instance of TarantoolCriteria"); - } - return (TarantoolCriteria) criteria; - } - - private List getPaginationSubResult( - List content, int pageSize, PaginationDirection direction, boolean hasNext) { - if (hasNext) { - switch (direction) { - case FORWARD -> { - return content.subList(0, pageSize); - } - case BACKWARD -> { - return content.subList(1, content.size()); - } - } - } - return content; - } - - /** - * Create the query from the bind parameters. - * - * @return A ready-to-use query - */ - @NonNull - protected KeyValueQuery prepareQuery(ParametersParameterAccessor accessor) { - KeyValueQuery query = createQuery(accessor); - - /* - If there is no limitation in the name of the method, we always put a - limit so that don't think about this in the engine, especially when distinguishing between a regular query and a - paginated query. - */ - if (!tree.isLimiting()) { - query.setRows(SelectOptions.DEFAULT_LIMIT); - } - - if (accessor.getSort() != Sort.unsorted()) { - query.setSort(accessor.getSort()); - } - - return query; - } - - /** - * Handle {@code @Param}. - * - *
    - *
  1. Without {@code @Param} - *

    Arguments to the call are assumed to follow the same sequence as cited in the method - * name.
    - * Eg. - *

    -   *     findByOneAndTwo(String one, String two);
    -   *     
    - *
  2. With {@code @Param} - *

    Arguments to the call are use the {@code @Param} to match them against the fields. - *

    Eg. - *

    -   *   findByOneAndTwo(@Param("two") String two, @Param("one") String one);
    -   *   
    - *
- * - * @param originalParameters Possibly empty - * @param partTree Query tree to traverse - * @return Parameters in correct order - */ - private ParametersParameterAccessor prepareAccessor( - final Object[] originalParameters, final PartTree partTree) { - - if (!this.isRearrangeKnown) { - this.prepareRearrange(partTree, this.queryMethod.getParameters().getBindableParameters()); - this.isRearrangeKnown = true; - } - - Object[] parameters = originalParameters; - Assert.notNull(parameters, "Parameters must not be null."); - - if (this.isRearrangeRequired) { - parameters = new Object[originalParameters.length]; - - for (int i = 0; i < parameters.length; i++) { - int index = (i < rearrangeIndex.length) ? rearrangeIndex[i] : i; - parameters[i] = originalParameters[index]; - } - } - - return new ParametersParameterAccessor(this.queryMethod.getParameters(), parameters); - } - - /** - * Determine if the arguments to the method need reordered. - * - *

For searches such as {@code findBySomethingNotNull} there may be more parts than parameters - * needed to be bound to them. - * - * @param partTree Query parts - * @param bindableParameters Parameters expected - */ - @SuppressWarnings("unchecked") - private void prepareRearrange( - final PartTree partTree, final Parameters bindableParameters) { - - this.isRearrangeRequired = false; - if (partTree == null || bindableParameters == null) { - return; - } - - List queryParams = new ArrayList<>(); - List methodParams = new ArrayList<>(); - - for (Part part : partTree.getParts()) { - queryParams.add(part.getProperty().getSegment()); - } - - Iterator bindableParameterIterator = - (Iterator) bindableParameters.iterator(); - while (bindableParameterIterator.hasNext()) { - Parameter parameter = bindableParameterIterator.next(); - parameter.getName().ifPresent(methodParams::add); - } - - this.rearrangeIndex = new int[queryParams.size()]; - - String[] paramsExpected = queryParams.toArray(new String[0]); - String[] paramsProvided = methodParams.toArray(new String[0]); - - for (int i = 0; i < this.rearrangeIndex.length; i++) { - this.rearrangeIndex[i] = i; - - for (int j = 0; j < paramsProvided.length; j++) { - if (paramsProvided[j] != null && paramsProvided[j].equals(paramsExpected[i])) { - this.rearrangeIndex[i] = j; - this.isRearrangeRequired = true; - } - } - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolQueryCreator.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolQueryCreator.java deleted file mode 100644 index 4abbf2af..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolQueryCreator.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.mapping.PropertyPath; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -import static io.tarantool.client.crud.ConditionOperator.EQ; -import static io.tarantool.client.crud.ConditionOperator.GREATER; -import static io.tarantool.client.crud.ConditionOperator.GREATER_EQ; -import static io.tarantool.client.crud.ConditionOperator.LESS; -import static io.tarantool.client.crud.ConditionOperator.LESS_EQ; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.ConditionOperator; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolQueryCreator - extends AbstractQueryCreator, TarantoolCriteria> { - - private final Map cache = new ConcurrentHashMap<>(); - - public static final String INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE = - "Logic error for '%s' in query. "; - - public TarantoolQueryCreator(PartTree tree, ParameterAccessor parameters) { - super(tree, parameters); - } - - private String getFieldName(Part part) { - PropertyPath property = part.getProperty(); - String segment = property.toDotPath(); - Class domainType = property.getOwningType().getType(); - java.lang.reflect.Field field = ReflectionUtils.findField(domainType, segment); - - if (field == null) { - throw new IllegalArgumentException("No such field: " + segment + " in " + domainType); - } - Field annotationField = field.getAnnotation(Field.class); - - if (annotationField != null) { - String value = annotationField.value(); - if (StringUtils.hasText(value)) { - return value; - } - String name = annotationField.name(); - if (StringUtils.hasText(name)) { - return name; - } - } - - return segment; - } - - @Override - @NonNull - protected TarantoolCriteria create(Part part, @NonNull Iterator iterator) { - final TarantoolCriteria tarantoolCriteria = new TarantoolCriteria(); - - Part.Type type = part.getType(); - if (isIgnoreCase(part)) { - throw new InvalidDataAccessApiUsageException( - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "IgnoreCase isn't supported yet", - type)); - } - String property = cache.computeIfAbsent(part, this::getFieldName); - - switch (type) { - case SIMPLE_PROPERTY: - generateConditions(tarantoolCriteria, type, property, iterator, EQ); - break; - case LESS_THAN: - case BEFORE: - generateConditions(tarantoolCriteria, type, property, iterator, LESS); - break; - case LESS_THAN_EQUAL: - generateConditions(tarantoolCriteria, type, property, iterator, LESS_EQ); - break; - case GREATER_THAN: - case AFTER: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER); - break; - case GREATER_THAN_EQUAL: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER_EQ); - break; - case BETWEEN: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER, LESS); - break; - case TRUE: - tarantoolCriteria.addCondition(Condition.create(EQ, property, true)); - break; - case FALSE: - tarantoolCriteria.addCondition(Condition.create(EQ, property, false)); - break; - case IS_EMPTY: - tarantoolCriteria.addCondition(Condition.create(EQ, property, "")); - break; - case IS_NULL: - tarantoolCriteria.addCondition(Condition.create(EQ, property, null)); - break; - default: - throw new InvalidDataAccessApiUsageException(String.format("Unsupported type '%s'", type)); - } - - return tarantoolCriteria; - } - - private void generateConditions( - TarantoolCriteria tarantoolCriteria, - Part.Type type, - String property, - Iterator iterator, - ConditionOperator... operators) { - for (int i = 0; i < type.getNumberOfArguments(); i++) { - if (!iterator.hasNext()) { - throw new InvalidDataAccessApiUsageException( - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "Transmitted not enough arguments (%d of %d)", - type, - i, - type.getNumberOfArguments())); - } - tarantoolCriteria.addCondition(Condition.create(operators[i], property, iterator.next())); - } - } - - private boolean isIgnoreCase(Part part) { - switch (part.shouldIgnoreCase()) { - case ALWAYS: - Assert.state( - canUpperCase(part.getProperty()), - String.format( - "Unable to ignore case of %s types, the property '%s' must reference a String", - part.getProperty().getType().getName(), part.getProperty().getSegment())); - return true; - case WHEN_POSSIBLE: - return canUpperCase(part.getProperty()); - case NEVER: - default: - return false; - } - } - - private boolean canUpperCase(PropertyPath path) { - return String.class.equals(path.getType()); - } - - @Override - @NonNull - protected TarantoolCriteria and( - @NonNull Part part, @NonNull TarantoolCriteria base, @NonNull Iterator iterator) { - throw new UnsupportedOperationException(); - } - - @Override - @NonNull - protected TarantoolCriteria or( - @NonNull TarantoolCriteria base, @NonNull TarantoolCriteria criteria) { - throw new UnsupportedOperationException(); - } - - @Override - @NonNull - protected KeyValueQuery complete( - @Nullable final TarantoolCriteria criteria, @NonNull Sort sort) { - return new KeyValueQuery<>(criteria); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolQueryMethodImpl.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolQueryMethodImpl.java deleted file mode 100644 index 1be3ec99..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolQueryMethodImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.lang.reflect.Method; - -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryMethod; - -import io.tarantool.spring.data.query.Query; -import io.tarantool.spring.data.query.TarantoolQueryMethod; - -/** Tarantool {@link QueryMethod} Implementation */ -public class TarantoolQueryMethodImpl extends QueryMethod implements TarantoolQueryMethod { - - private final Method method; - - public TarantoolQueryMethodImpl( - Method method, RepositoryMetadata metadata, ProjectionFactory factory) { - super(method, metadata, factory); - this.method = method; - } - - public boolean hasAnnotatedQuery() { - return getQuery() != null; - } - - public String getQueryValue(Query query) { - return (String) AnnotationUtils.getValue(query); - } - - public Query getQuery() { - return method.getAnnotation(Query.class); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolRepositoryQuery.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolRepositoryQuery.java deleted file mode 100644 index 0543ec5b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolRepositoryQuery.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.RepositoryQuery; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.query.ProxyTarantoolRepositoryQuery; - -/** {@link RepositoryQuery} using String based function name to call function in Tarantool. */ -public class TarantoolRepositoryQuery implements RepositoryQuery { - - private final ProxyTarantoolRepositoryQuery proxy; - private final TarantoolQueryMethodImpl queryMethod; - - public TarantoolRepositoryQuery( - TarantoolCrudClient client, TarantoolQueryMethodImpl queryMethod) { - this.queryMethod = queryMethod; - this.proxy = new ProxyTarantoolRepositoryQuery(client, queryMethod); - } - - @Override - public Object execute(Object[] parameters) { - return proxy.execute(parameters); - } - - @Override - public QueryMethod getQueryMethod() { - return queryMethod; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolScrollPosition.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolScrollPosition.java deleted file mode 100644 index 8430d5b1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolScrollPosition.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import org.springframework.data.domain.ScrollPosition; - -import io.tarantool.spring.data.utils.Pair; - -/** - * Use keyset pagination adapted for Tarantool crud module.. - * - * @author Nikolay Belonogov - * @see #forward(Pair) - * @see #backward(Pair) - * @see #reverse() - */ -public sealed interface TarantoolScrollPosition extends ScrollPosition - permits TarantoolKeysetScrollPosition { - - /** - * Creates a new {@link ScrollPosition} based on the key index scrolling forward. - * - * @param indexKey pair, where the first element is the name of the index on which you want to - * perform pagination. Second element is the value of the indexed field from which you want to - * paginate (exclusive). To perform pagination from the beginning of the index, pass an empty - * list as the second element of the pair. indexKey must be not {@code null}. - * @return new {@link TarantoolScrollPosition} instance. - */ - static TarantoolScrollPosition forward(Pair indexKey) { - return TarantoolKeysetScrollPosition.forward(indexKey); - } - - /** - * Creates a new {@link ScrollPosition} based on the key index scrolling backward. - * - * @param indexKey pair, where the first element is the name of the index on which you want to - * perform pagination. Second element is the value of the indexed field from which you want to - * paginate (exclusive). To perform pagination from the end of the index, pass an empty list - * as the second element of the pair. indexKey must be not {@code null}. - * @return new {@link TarantoolScrollPosition} instance. - */ - static TarantoolScrollPosition backward(Pair indexKey) { - return TarantoolKeysetScrollPosition.backward(indexKey); - } - - /** - * Return {@link TarantoolScrollPosition} with the same parameters, but with the opposite - * pagination direction. If the current {@link TarantoolScrollPosition} was set from the beginning - * of the index, the method will return the {@link TarantoolScrollPosition} set from the end of - * the index. Returns the {@link TarantoolScrollPosition} set from the beginning of the index if - * the current {@link TarantoolScrollPosition} is set from the end of the index. - * - *

Important: when this method is called, the condition specified by the index in - * the current {@link TarantoolScrollPosition} is overridden to unconditional (i.e. it will be - * searched to the end or beginning of the index) - * - * @return {@link TarantoolScrollPosition} instance. - */ - TarantoolScrollPosition reverse(); - - /** - * Return {@code true} if scrolling has backward motion. This means that the current {@link - * TarantoolScrollPosition} has the direction of movement {@link - * io.tarantool.spring.data.query.PaginationDirection#BACKWARD}. Return {@code false} if scrolling - * has forward motion ({@link io.tarantool.spring.data.query.PaginationDirection#FORWARD}). - * - * @return {@link Boolean} primitive. - */ - boolean isScrollsBackward(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolSliceImpl.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolSliceImpl.java deleted file mode 100644 index b9f80476..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolSliceImpl.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.io.Serial; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.lang.NonNull; - -/** - * Default implementation of {@link Slice} for Tarantool. - * - * @author Nikolay Belonogov - */ -class TarantoolSliceImpl extends TarantoolChunk { - - @Serial private static final long serialVersionUID = 867755909294344406L; - - private final boolean hasNext; - - private final Pageable pageable; - - /** - * Creates a new {@link TarantoolSliceImpl} with the empty content. This will result in the - * created {@link Slice} being identical to the entire {@link List}. - */ - public TarantoolSliceImpl() { - this(Collections.emptyList(), Pageable.unpaged(), false); - } - - /** - * Creates a new {@link TarantoolSliceImpl} with the given content. This will result in the - * created {@link Slice} being identical to the entire {@link List}. - * - * @param content must not be {@literal null}. - */ - public TarantoolSliceImpl(List content) { - this(content, Pageable.unpaged(), false); - } - - /** - * Creates a new {@link TarantoolSliceImpl} with the given content and {@link Pageable}. - * - * @param content the content of this {@link Slice}, must not be {@literal null}. - * @param pageable the paging information, must not be {@literal null}. - * @param hasNext whether there's another slice following the current one. - */ - public TarantoolSliceImpl(List content, Pageable pageable, boolean hasNext) { - super(content, pageable); - - this.hasNext = hasContent() && hasNext; - this.pageable = pageable; - } - - /** - * Returns true if there is a next data slice. No data content means that the next slice does not - * exist and method will return false. - * - * @return Returns true if there is a next data slice. No data content means that the next slice - * does not exist and method will return false. - */ - @Override - public boolean hasNext() { - return hasNext && hasContent(); - } - - @Override - @NonNull - public Slice map(@NonNull Function converter) { - return new TarantoolSliceImpl<>(getConvertedContent(converter), pageable, hasNext); - } - - @Override - public String toString() { - - String contentType = "UNKNOWN"; - List content = getContent(); - - if (content.size() > 0) { - contentType = content.get(0).getClass().getName(); - } - - return String.format("Slice %d containing %s instances", getNumber(), contentType); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolSliceImpl that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return hasNext == that.hasNext && pageable.equals(that.pageable); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), hasNext, pageable); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolSortAccessor.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolSortAccessor.java deleted file mode 100644 index 06af92da..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolSortAccessor.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.util.Comparator; -import java.util.Map.Entry; - -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Sort.Order; -import org.springframework.data.keyvalue.core.SortAccessor; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -/** - * Implements sorting for Tarantool repository queries. - * - * @author Artyom Dubinin - */ -public class TarantoolSortAccessor implements SortAccessor>> { - - /** - * Sort on a sequence of fields, possibly none. - * - * @param query If not null, will contain one of more {@link Order} objects. - * @return A sequence of comparators or {@code null} - */ - public Comparator> resolve(KeyValueQuery query) { - if (query == null || query.getSort() == Sort.unsorted()) { - return null; - } - - throw new UnsupportedOperationException(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolWindowIterator.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolWindowIterator.java deleted file mode 100644 index cd4e46bc..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolWindowIterator.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.function.Function; - -import org.springframework.data.domain.Window; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * The class is a complete analogue of {@link org.springframework.data.support.WindowIterator} for - * Tarantool. - * - *

Example of usage: - * - *

- * - *
{@code
- * TarantoolScrollPosition initialScrollPosition =
- *     TarantoolScrollPosition.forward(Pair.of("pk", Collections.emptyList()));
- *
- * TarantoolWindowIterator personIterator =
- *     TarantoolWindowIterator.of(scrollPosition -> repository.findFirst10ByAge(10, scrollPosition))
- *         .startingAt(initialScrollPosition);
- *
- * List result = new ArrayList<>();
- *
- * while (personIterator.hasNext()) {
- *   result.add(personIterator.next());
- * }
- * }
- * - *
- * - * @param domain class type. - */ -public class TarantoolWindowIterator implements Iterator { - - private final Function> windowFunction; - - private TarantoolScrollPosition currentPosition; - - private @Nullable Window currentWindow; - - private @Nullable Iterator currentIterator; - - /** - * Entrypoint to create a new {@link TarantoolWindowIterator} for the given windowFunction. - * - * @param windowFunction must not be {@literal null}. - * @param domain class type. - * @return new instance of {@link TarantoolWindowIteratorBuilder}. - */ - public static TarantoolWindowIteratorBuilder of( - Function> windowFunction) { - return new TarantoolWindowIteratorBuilder<>(windowFunction); - } - - TarantoolWindowIterator( - Function> windowFunction, - TarantoolScrollPosition position) { - - this.windowFunction = windowFunction; - this.currentPosition = position; - } - - @Override - public boolean hasNext() { - - // use while loop instead of recursion to fetch the next window. - do { - if (currentWindow == null) { - currentWindow = windowFunction.apply(currentPosition); - } - - if (currentIterator == null) { - if (currentWindow != null) { - currentIterator = currentWindow.iterator(); - } - } - - if (currentIterator != null) { - - if (currentIterator.hasNext()) { - return true; - } - - if (currentWindow != null && currentWindow.hasNext()) { - - currentPosition = getNextPosition(currentWindow); - currentIterator = null; - currentWindow = null; - continue; - } - } - - return false; - } while (true); - } - - @Override - public T next() { - - if (!hasNext()) { - throw new NoSuchElementException(); - } - - return currentIterator.next(); - } - - private static TarantoolScrollPosition getNextPosition(Window window) { - return (TarantoolScrollPosition) window.positionAt(window.size() - 1); - } - - /** Builder API to construct a {@link TarantoolWindowIterator}. */ - public static class TarantoolWindowIteratorBuilder { - - private final Function> windowFunction; - - TarantoolWindowIteratorBuilder(Function> windowFunction) { - - Assert.notNull(windowFunction, "WindowFunction must not be null"); - - this.windowFunction = windowFunction; - } - - /** - * Create a {@link TarantoolWindowIterator} given {@link TarantoolScrollPosition}. - * - * @param position {@link TarantoolScrollPosition} instance. Must be not null. - * @return {@link TarantoolWindowIterator} instance. - */ - public TarantoolWindowIterator startingAt(TarantoolScrollPosition position) { - - Assert.notNull(position, "TarantoolScrollPosition must not be null"); - - return new TarantoolWindowIterator<>(windowFunction, position); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/TarantoolRepositoryFactory.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/TarantoolRepositoryFactory.java deleted file mode 100644 index 8316d9b5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/TarantoolRepositoryFactory.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.repository; - -import java.util.Optional; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.SpelQueryCreator; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data31.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data31.repository.config.TarantoolQueryLookupStrategy; -import io.tarantool.spring.data31.repository.support.TarantoolSimpleRepository; - -/** - * Tarantool version of {@link KeyValueRepositoryFactory}, a factory to build tarantool repository - * instances. - * - *

The purpose of extending is to ensure that the {@link #getQueryLookupStrategy} method returns - * a {@link TarantoolQueryLookupStrategy} rather than the default. - * - *

The end goal of this bean is for {@link TarantoolPartTreeQuery} to be used for query - * preparation. - * - * @author Artyom Dubinin - */ -public class TarantoolRepositoryFactory extends KeyValueRepositoryFactory { - - private static final Class DEFAULT_QUERY_CREATOR = SpelQueryCreator.class; - - private final KeyValueOperations keyValueOperations; - private final Class> queryCreator; - private final TarantoolCrudClient client; - - /* Mirror functionality of super, to ensure private - * fields are set. - */ - public TarantoolRepositoryFactory( - TarantoolCrudClient client, KeyValueOperations keyValueOperations) { - this(client, keyValueOperations, DEFAULT_QUERY_CREATOR); - } - - /* Capture KeyValueOperations and QueryCreator objects after passing to super. - */ - public TarantoolRepositoryFactory( - TarantoolCrudClient client, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - - super(keyValueOperations, queryCreator); - - this.client = client; - this.keyValueOperations = keyValueOperations; - this.queryCreator = queryCreator; - } - - /** - * Ensure the mechanism for query evaluation is Tarantool specific, as the original {@code - * KeyValueQueryLookupStrategy} does not function correctly for Tarantool. - */ - @Override - protected Optional getQueryLookupStrategy( - QueryLookupStrategy.Key key, QueryMethodEvaluationContextProvider evaluationContextProvider) { - return Optional.of( - new TarantoolQueryLookupStrategy( - client, key, evaluationContextProvider, keyValueOperations, queryCreator)); - } - - @Override - protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { - return TarantoolSimpleRepository.class; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/EnableTarantoolRepositories.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/EnableTarantoolRepositories.java deleted file mode 100644 index 6661ff4f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/EnableTarantoolRepositories.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.repository.config; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.ComponentScan.Filter; -import org.springframework.context.annotation.Import; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.config.QueryCreatorType; -import org.springframework.data.repository.config.DefaultRepositoryBaseClass; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryLookupStrategy.Key; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.spring.data31.config.properties.TarantoolProperties; -import io.tarantool.spring.data31.query.TarantoolQueryCreator; -import io.tarantool.spring.data31.repository.support.TarantoolRepositoryFactoryBean; - -@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@Import(TarantoolRepositoriesRegistrar.class) -@EnableConfigurationProperties(TarantoolProperties.class) -@QueryCreatorType(TarantoolQueryCreator.class) -public @interface EnableTarantoolRepositories { - - /** - * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation - * declarations e.g.: {@code @EnableJpaRepositories("org.my.pkg")} instead of - * {@code @EnableJpaRepositories(basePackages="org.my.pkg")}. - * - * @return value - */ - String[] value() default {}; - - /** - * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually - * exclusive with) this attribute. Use {@link #basePackageClasses()} for a type-safe alternative - * to String-based package names. - * - * @return base packages - */ - String[] basePackages() default {}; - - /** - * Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for - * annotated components. The package of each class specified will be scanned. Consider creating a - * special no-op marker class or interface in each package that serves no purpose other than being - * referenced by this attribute. - * - * @return classes - */ - Class[] basePackageClasses() default {}; - - /** - * Specifies which types are not eligible for component scanning. - * - * @return filters - */ - Filter[] excludeFilters() default {}; - - /** - * Specifies which types are eligible for component scanning. Further, narrows the set of - * candidate components from everything in {@link #basePackages()} to everything in the base - * packages that matches the given filter or filters. - * - * @return filters - */ - Filter[] includeFilters() default {}; - - /** - * Returns the postfix to be used when looking up custom repository implementations. Defaults to - * {@literal Impl}. So for a repository named {@code PersonRepository} the corresponding - * implementation class will be looked up scanning for {@code PersonRepositoryImpl}. - * - * @return postfix - */ - String repositoryImplementationPostfix() default "Impl"; - - /** - * Configures the location of where to find the Spring Data named queries properties file. - * - * @return location - */ - String namedQueriesLocation() default ""; - - /** - * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query - * methods. Defaults to {@link Key#CREATE_IF_NOT_FOUND}. - * - * @return strategy - */ - Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND; - - Class repositoryFactoryBeanClass() default TarantoolRepositoryFactoryBean.class; - - /** - * Allow custom base classes, for generic behavior shared amongst selected repositories. - * - * @return base class - */ - Class repositoryBaseClass() default DefaultRepositoryBaseClass.class; - - /** - * Configures the name of the {@link KeyValueOperations} bean to be used with the repositories - * detected. - * - * @return reference to {@link KeyValueOperations} bean. - */ - String keyValueTemplateRef() default DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; - - /** - * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be - * discovered by the repositories' infrastructure. - * - * @return result of consideration - */ - boolean considerNestedRepositories() default false; - - /** - * Configures the {@link ClientType} to be used as driver client type to connection to Tarantool. - * Must match the referenced type in {@link #keyValueTemplateRef()}} if these values differ from - * the default ones. - * - * @return the type of client through which communication with Tarantool will be made. - */ - ClientType clientType() default ClientType.CRUD; -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/TarantoolQueryLookupStrategy.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/TarantoolQueryLookupStrategy.java deleted file mode 100644 index 0dfd3739..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/TarantoolQueryLookupStrategy.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.repository.config; - -import java.lang.reflect.Method; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery; -import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.repository.core.NamedQueries; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.util.Assert; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data31.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data31.query.TarantoolQueryMethodImpl; -import io.tarantool.spring.data31.query.TarantoolRepositoryQuery; - -/** - * Ensures {@link TarantoolPartTreeQuery} is used for query preparation rather than {@link - * KeyValuePartTreeQuery} or other alternatives. - * - * @author Artyom Dubinin - */ -public class TarantoolQueryLookupStrategy implements QueryLookupStrategy { - - private final QueryMethodEvaluationContextProvider evaluationContextProvider; - private final KeyValueOperations keyValueOperations; - private final Class> queryCreator; - private final TarantoolCrudClient client; - - /** - * Required constructor, capturing arguments for use in {@link #resolveQuery}. - * - * @param client tarantool crud client - * @param key Not used - * @param evaluationContextProvider For evaluation of query expressions - * @param keyValueOperations Bean to use for Key/Value operations on Tarantool repos - * @param queryCreator Query creator - */ - public TarantoolQueryLookupStrategy( - TarantoolCrudClient client, - Key key, - QueryMethodEvaluationContextProvider evaluationContextProvider, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - - Assert.notNull(evaluationContextProvider, "EvaluationContextProvider must not be null!"); - Assert.notNull(keyValueOperations, "KeyValueOperations must not be null!"); - Assert.notNull(queryCreator, "Query creator type must not be null!"); - - this.client = client; - this.evaluationContextProvider = evaluationContextProvider; - this.keyValueOperations = keyValueOperations; - this.queryCreator = queryCreator; - } - - /** - * Use {@link TarantoolPartTreeQuery} for resolving queries against Tarantool repositories. - * - * @param method, the query method - * @param metadata, not used - * @param projectionFactory, not used - * @param namedQueries, not used - * @return A mechanism for querying Tarantool repositories - */ - public RepositoryQuery resolveQuery( - Method method, - RepositoryMetadata metadata, - ProjectionFactory projectionFactory, - NamedQueries namedQueries) { - - TarantoolQueryMethodImpl queryMethod = - new TarantoolQueryMethodImpl(method, metadata, projectionFactory); - - if (queryMethod.hasAnnotatedQuery()) { - return new TarantoolRepositoryQuery(client, queryMethod); - } - - return new TarantoolPartTreeQuery( - queryMethod, evaluationContextProvider, this.keyValueOperations, this.queryCreator); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/TarantoolRepositoriesRegistrar.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/TarantoolRepositoriesRegistrar.java deleted file mode 100644 index bedee8e4..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/TarantoolRepositoriesRegistrar.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.repository.config; - -import java.lang.annotation.Annotation; - -import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport; -import org.springframework.data.repository.config.RepositoryConfigurationExtension; - -class TarantoolRepositoriesRegistrar extends RepositoryBeanDefinitionRegistrarSupport { - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoriesRegistrar#getAnnotation() - */ - @Override - protected Class getAnnotation() { - return EnableTarantoolRepositories.class; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport#getExtension() - */ - @Override - protected RepositoryConfigurationExtension getExtension() { - return new TarantoolRepositoryConfigurationExtension(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/TarantoolRepositoryConfigurationExtension.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/TarantoolRepositoryConfigurationExtension.java deleted file mode 100644 index d05f3062..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/TarantoolRepositoryConfigurationExtension.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.repository.config; - -import org.springframework.beans.factory.config.ConstructorArgumentValues; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension; -import org.springframework.data.repository.config.RepositoryConfigurationSource; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.spring.data31.config.TarantoolCrudConfiguration; -import io.tarantool.spring.data31.core.TarantoolTemplate; -import io.tarantool.spring.data31.core.mapping.TarantoolMappingContext; - -public class TarantoolRepositoryConfigurationExtension - extends KeyValueRepositoryConfigurationExtension { - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getModuleName() - */ - @Override - public String getModuleName() { - return "Tarantool"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getModulePrefix() - */ - @Override - public String getModulePrefix() { - return "tarantool"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getDefaultKeyValueTemplateRef() - */ - @Override - public String getDefaultKeyValueTemplateRef() { - return DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #registerBeansForRoot() - */ - @Override - public void registerBeansForRoot( - BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) { - // register a default set of beans based on the passed annotation attributes. - final ClientType clientTypeAttribute = - configurationSource.getRequiredAttribute("clientType", ClientType.class); - - if (clientTypeAttribute == ClientType.CRUD) { - final String defaultCrudConfigurationBeanName = - TarantoolCrudConfiguration.class.getCanonicalName(); - registerIfNotAlreadyRegistered( - () -> new RootBeanDefinition(TarantoolCrudConfiguration.class), - registry, - defaultCrudConfigurationBeanName, - configurationSource); - } else { - throw new IllegalArgumentException("The Box client is not yet supported."); - } - super.registerBeansForRoot(registry, configurationSource); - - // remove KeyValueMappingContext to add TarantoolMappingContext - registry.removeBeanDefinition(getMappingContextBeanRef()); - registerIfNotAlreadyRegistered( - () -> { - RootBeanDefinition definition = new RootBeanDefinition(TarantoolMappingContext.class); - definition.setSource(configurationSource.getSource()); - - return definition; - }, - registry, - getMappingContextBeanRef(), - configurationSource); - } - - @Override - protected AbstractBeanDefinition getDefaultKeyValueTemplateBeanDefinition( - RepositoryConfigurationSource configurationSource) { - final RootBeanDefinition keyValueTemplateBeanDefinition = - new RootBeanDefinition(TarantoolTemplate.class); - - final ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); - constructorArgumentValues.addIndexedArgumentValue( - 0, new RuntimeBeanReference(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF)); - constructorArgumentValues.addIndexedArgumentValue( - 1, new RuntimeBeanReference(getMappingContextBeanRef())); - - keyValueTemplateBeanDefinition.setConstructorArgumentValues(constructorArgumentValues); - keyValueTemplateBeanDefinition.setSource(configurationSource); - keyValueTemplateBeanDefinition.setDependsOn(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF); - keyValueTemplateBeanDefinition.setDependsOn(getMappingContextBeanRef()); - - return keyValueTemplateBeanDefinition; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/package-info.java deleted file mode 100644 index 8f4d81a7..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/config/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository config package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data31.repository.config; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/package-info.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/package-info.java deleted file mode 100644 index 87e63094..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data31.repository; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/support/TarantoolRepositoryFactoryBean.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/support/TarantoolRepositoryFactoryBean.java deleted file mode 100644 index a4b2e6b6..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/support/TarantoolRepositoryFactoryBean.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.repository.support; - -import java.io.Serializable; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean; -import org.springframework.data.repository.Repository; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data31.repository.TarantoolRepositoryFactory; - -public class TarantoolRepositoryFactoryBean, S, ID extends Serializable> - extends KeyValueRepositoryFactoryBean { - - @Autowired private TarantoolCrudClient client; - - public TarantoolRepositoryFactoryBean(Class repositoryInterface) { - super(repositoryInterface); - } - - /** - * Return a {@link TarantoolRepositoryFactory}. - * - *

{@code super} would return {@link KeyValueRepositoryFactory} which in turn builds {@code - * KeyValueRepository} instances, and these have a private method that implement querying in a - * manner that does not fit with Tarantool. More details are in {@link - * TarantoolRepositoryFactory}. - * - * @param operations operations - * @param queryCreator creator - * @param repositoryQueryType, not used - * @return A {@link TarantoolRepositoryFactory} that creates tarantool repository instances. - */ - @Override - protected KeyValueRepositoryFactory createRepositoryFactory( - KeyValueOperations operations, - Class> queryCreator, - Class repositoryQueryType) { - return new TarantoolRepositoryFactory(client, operations, queryCreator); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/support/TarantoolSimpleRepository.java b/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/support/TarantoolSimpleRepository.java deleted file mode 100644 index 68511526..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/support/TarantoolSimpleRepository.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.repository.support; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository; -import org.springframework.data.repository.core.EntityInformation; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data31.query.PaginationUtils.doPageQuery; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolSimpleRepository extends SimpleKeyValueRepository { - - private static final String FIND_ALL_EXC_MSG = - "This method is not supported to avoid sampling huge data massive. " - + "Please use derived methods with scrolling or pagination to select all data."; - - private static final String FIND_ALL_SORT_EXC_MSG = - "This method is not supported because sorting is not supported " - + "in Tarantool. Organize sorting of results using Java tools."; - - private static final String PAGEABLE_NULL_EXC_MSG = "Pageable must be not null"; - - private final KeyValueOperations operations; - private final EntityInformation entityInformation; - - /** - * Creates a new {@link SimpleKeyValueRepository} for the given {@link EntityInformation} and - * {@link KeyValueOperations}. - * - * @param metadata must not be {@literal null}. - * @param operations must not be {@literal null}. - */ - public TarantoolSimpleRepository( - EntityInformation metadata, KeyValueOperations operations) { - super(metadata, operations); - this.entityInformation = metadata; - this.operations = operations; - } - - @Override - public List findAll() { - throw new UnsupportedOperationException(FIND_ALL_EXC_MSG); - } - - @Override - public List findAll(Sort sort) { - throw new UnsupportedOperationException(FIND_ALL_SORT_EXC_MSG); - } - - @Override - @SuppressWarnings("unchecked") - public Page findAll(Pageable pageable) { - Assert.notNull(pageable, PAGEABLE_NULL_EXC_MSG); - - KeyValueQuery query = new KeyValueQuery<>(new TarantoolCriteria()); - return (Page) - doPageQuery(pageable, query, this.operations, this.entityInformation.getJavaType()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/GenericTarantoolConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/GenericTarantoolConfigurationTest.java deleted file mode 100644 index 4c0cdc86..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/GenericTarantoolConfigurationTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.config; - -import java.io.IOException; -import java.nio.file.Files; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.test.context.TestPropertySource; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.spring.data31.config.properties.TarantoolProperties; - -@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -public abstract class GenericTarantoolConfigurationTest implements ApplicationContextAware { - - protected static TarantoolProperties testProperties; - - protected ApplicationContext applicationContext; - - @Autowired protected TarantoolProperties properties; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - @BeforeAll - static void beforeAll() throws IOException { - testProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists(DEFAULT_TEST_PROPERTY_DIR.resolve(DEFAULT_PROPERTY_FILE_NAME)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/TarantoolBoxConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/TarantoolBoxConfigurationTest.java deleted file mode 100644 index 71b84a75..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/TarantoolBoxConfigurationTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.config; - -import java.io.IOException; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.RepeatedTest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.client.box.TarantoolBoxClient; -import io.tarantool.client.factory.TarantoolBoxClientBuilder; -import io.tarantool.pool.HeartbeatOpts; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data31.config.properties.TarantoolProperties; - -@SpringBootTest(classes = {TarantoolBoxConfigurationTest.Config.class}) -public class TarantoolBoxConfigurationTest extends GenericTarantoolConfigurationTest { - - @MockBean TarantoolBoxClient client; - - @Autowired private TarantoolBoxConfiguration tarantoolBoxConfiguration; - - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testGetBoxClientBuilder() throws IOException { - assertEquals(properties, tarantoolBoxConfiguration.getProperties()); - - final TarantoolBoxClientBuilder boxClientBuilder = tarantoolBoxConfiguration.getClientBuilder(); - - if (properties.getConnectionGroups() == null) { - assertNull(boxClientBuilder.getGroups()); - } else { - Assertions.assertEquals( - properties.getConnectionGroups().size(), boxClientBuilder.getGroups().size()); - List connectionGroupsFromBuilder = boxClientBuilder.getGroups(); - List connectionGroupsFromProperty = - properties.getInstanceConnectionGroups(); - - assertNotNull(connectionGroupsFromBuilder); - assertNotNull(connectionGroupsFromProperty); - for (int i = 0; i < connectionGroupsFromBuilder.size(); i++) { - InstanceConnectionGroup groupFromBuilder = connectionGroupsFromBuilder.get(i); - InstanceConnectionGroup groupFromProperty = connectionGroupsFromProperty.get(i); - - assertEquals(groupFromProperty.getAuthType(), groupFromBuilder.getAuthType()); - assertEquals(groupFromProperty.getTag(), groupFromBuilder.getTag()); - assertEquals(groupFromProperty.getSize(), groupFromBuilder.getSize()); - assertEquals(groupFromProperty.getUser(), groupFromBuilder.getUser()); - assertEquals(groupFromProperty.getPassword(), groupFromBuilder.getPassword()); - assertEquals(groupFromProperty.getPort(), groupFromBuilder.getPort()); - assertEquals(groupFromProperty.getHost(), groupFromBuilder.getHost()); - } - } - - final HeartbeatOpts propertiesHeartbeatOpts = properties.getHeartbeatOpts(); - if (propertiesHeartbeatOpts == null) { - assertNull(boxClientBuilder.getHeartbeatOpts()); - } else { - HeartbeatOpts builderHeartbeatOpts = boxClientBuilder.getHeartbeatOpts(); - assertEquals( - propertiesHeartbeatOpts.getPingInterval(), builderHeartbeatOpts.getPingInterval()); - assertEquals( - propertiesHeartbeatOpts.getDeathThreshold(), builderHeartbeatOpts.getDeathThreshold()); - assertEquals( - propertiesHeartbeatOpts.getInvalidationThreshold(), - builderHeartbeatOpts.getInvalidationThreshold()); - assertEquals(propertiesHeartbeatOpts.getWindowSize(), builderHeartbeatOpts.getWindowSize()); - } - - Assertions.assertEquals(properties.getUserName(), boxClientBuilder.getUser()); - Assertions.assertEquals(properties.getPort(), boxClientBuilder.getPort()); - Assertions.assertEquals(properties.getEventLoopThreadsCount(), boxClientBuilder.getnThreads()); - Assertions.assertEquals(properties.getBalancerClass(), boxClientBuilder.getBalancerClass()); - Assertions.assertEquals( - properties.isGracefulShutdownEnabled(), boxClientBuilder.isGracefulShutdown()); - Assertions.assertEquals(properties.getConnectTimeout(), boxClientBuilder.getConnectTimeout()); - Assertions.assertEquals(properties.getReconnectAfter(), boxClientBuilder.getReconnectAfter()); - Assertions.assertEquals(properties.getHost(), boxClientBuilder.getHost()); - Assertions.assertEquals(properties.getPassword(), boxClientBuilder.getPassword()); - Assertions.assertEquals(properties.isFetchSchema(), boxClientBuilder.isFetchSchema()); - Assertions.assertEquals( - properties.isIgnoreOldSchemaVersion(), boxClientBuilder.isIgnoreOldSchemaVersion()); - - testProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @Configuration - @EnableConfigurationProperties(TarantoolProperties.class) - @Import(TarantoolBoxConfiguration.class) - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/TarantoolCrudConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/TarantoolCrudConfigurationTest.java deleted file mode 100644 index dd61a114..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/TarantoolCrudConfigurationTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.config; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.test.annotation.DirtiesContext; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.pool.HeartbeatOpts; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyHeartbeatOpts; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.spring.data31.repository.config.EnableTarantoolRepositories; - -@SpringBootTest(classes = {TarantoolCrudConfigurationTest.Config.class}) -public class TarantoolCrudConfigurationTest extends GenericTarantoolConfigurationTest { - - @MockBean TarantoolCrudClient client; - - @Autowired private TarantoolCrudConfiguration tarantoolCrudConfiguration; - - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testGetCrudClientBuilder() throws IOException { - assertEquals(properties, tarantoolCrudConfiguration.getProperties()); - - final TarantoolCrudClientBuilder crudClientBuilder = - tarantoolCrudConfiguration.getClientBuilder(); - - if (properties.getConnectionGroups() == null) { - assertNull(crudClientBuilder.getGroups()); - } else { - assertEquals(properties.getConnectionGroups().size(), crudClientBuilder.getGroups().size()); - List connectionGroupsFromBuilder = crudClientBuilder.getGroups(); - List connectionGroupsFromProperty = - properties.getConnectionGroups(); - assertNotNull(connectionGroupsFromBuilder); - assertNotNull(connectionGroupsFromProperty); - for (int i = 0; i < connectionGroupsFromBuilder.size(); i++) { - InstanceConnectionGroup groupFromBuilder = connectionGroupsFromBuilder.get(i); - PropertyInstanceConnectionGroup groupFromProperty = connectionGroupsFromProperty.get(i); - - assertEquals(groupFromProperty.getAuthType(), groupFromBuilder.getAuthType()); - assertEquals(groupFromProperty.getTag(), groupFromBuilder.getTag()); - assertEquals(groupFromProperty.getConnectionGroupSize(), groupFromBuilder.getSize()); - assertEquals(groupFromProperty.getUserName(), groupFromBuilder.getUser()); - assertEquals(groupFromProperty.getPassword(), groupFromBuilder.getPassword()); - assertEquals(groupFromProperty.getPort(), groupFromBuilder.getPort()); - assertEquals(groupFromProperty.getHost(), groupFromBuilder.getHost()); - } - } - - final PropertyHeartbeatOpts propertiesHeartbeatOpts = properties.getHeartbeat(); - if (propertiesHeartbeatOpts == null) { - assertNull(crudClientBuilder.getHeartbeatOpts()); - } else { - HeartbeatOpts builderHeartbeatOpts = crudClientBuilder.getHeartbeatOpts(); - - assertEquals( - propertiesHeartbeatOpts.getPingInterval(), builderHeartbeatOpts.getPingInterval()); - assertEquals( - propertiesHeartbeatOpts.getDeathThreshold(), builderHeartbeatOpts.getDeathThreshold()); - assertEquals( - propertiesHeartbeatOpts.getInvalidationThreshold(), - builderHeartbeatOpts.getInvalidationThreshold()); - assertEquals(propertiesHeartbeatOpts.getWindowSize(), builderHeartbeatOpts.getWindowSize()); - } - - assertEquals(properties.getUserName(), crudClientBuilder.getUser()); - assertEquals(properties.getPort(), crudClientBuilder.getPort()); - assertEquals(properties.getEventLoopThreadsCount(), crudClientBuilder.getnThreads()); - assertEquals(properties.getBalancerClass(), crudClientBuilder.getBalancerClass()); - assertEquals(properties.isGracefulShutdownEnabled(), crudClientBuilder.isGracefulShutdown()); - assertEquals(properties.getConnectTimeout(), crudClientBuilder.getConnectTimeout()); - assertEquals(properties.getReconnectAfter(), crudClientBuilder.getReconnectAfter()); - assertEquals(properties.getHost(), crudClientBuilder.getHost()); - assertEquals(properties.getPassword(), crudClientBuilder.getPassword()); - - testProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @Test - void testKeyValueTemplate() { - final List beanDefinitions = Arrays.asList(applicationContext.getBeanDefinitionNames()); - assertTrue(beanDefinitions.contains(DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF)); - - final KeyValueTemplate keyValueTemplate = - applicationContext.getBean( - DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF, KeyValueTemplate.class); - assertNotNull(keyValueTemplate); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/TarantoolEmptyPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/TarantoolEmptyPropertiesTest.java deleted file mode 100644 index 5c304fd6..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/TarantoolEmptyPropertiesTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.config; - -import java.io.IOException; -import java.nio.file.Files; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.TestPropertySource; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; -import io.tarantool.spring.data31.config.properties.TarantoolProperties; -import io.tarantool.spring.data31.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data31.utils.TarantoolTestSupport; - -/** - * @see TarantoolPropertiesTest - */ -@SpringBootTest(classes = {TarantoolEmptyPropertiesTest.Config.class}) -@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -@Timeout(5) -public class TarantoolEmptyPropertiesTest { - - @Autowired private TarantoolProperties springParsedProperties; - - @BeforeAll - static void beforeAll() throws IOException { - TarantoolTestSupport.writeTestEmptyPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - /* - * The test checks that if property processing is enabled via the @EnableConfigurationProperties annotation, then - * TarantoolProperty always exists and has default values. - */ - @Test - void testParseEmptyProperties() { - assertNotNull(springParsedProperties); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists(DEFAULT_TEST_PROPERTY_DIR.resolve(DEFAULT_PROPERTY_FILE_NAME)); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/TarantoolPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/TarantoolPropertiesTest.java deleted file mode 100644 index f118ba6a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/config/TarantoolPropertiesTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.config; - -import java.io.IOException; -import java.nio.file.Files; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Timeout; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.TestPropertySource; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data31.config.properties.TarantoolProperties; -import io.tarantool.spring.data31.repository.config.EnableTarantoolRepositories; - -/** - * The test checks whether the Spring framework parses a file with the specified properties - * correctly. Before creating the test class, a random file with properties is written to the - * classpath:properties-test.yaml file. Next, when creating a test class the Spring context is - * raised and parses the file with properties. A test is launched to check the uniqueness of the - * current properties and properties that were specified in the previous iteration. It is checked - * that the generated Spring class TarantoolProperty is equal to the class written to the file. - * Next, the next entry to the file occurs, after which there is a forced reload of the Spring - * context -> the file with properties is parsed again and everything happens according to circle. - */ -@SpringBootTest(classes = {TarantoolPropertiesTest.Config.class}) -@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -@Timeout(5) -public class TarantoolPropertiesTest { - - private static TarantoolProperties writtenToFileProperties; - private static TarantoolProperties prevSpringParsedProperties; - private static TarantoolProperties prevWrittenToFileProperties; - @Autowired private TarantoolProperties springParsedProperties; - - @MockBean private TarantoolCrudClient client; - - @BeforeAll - static void beforeAll() throws IOException { - writtenToFileProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists(DEFAULT_TEST_PROPERTY_DIR.resolve(DEFAULT_PROPERTY_FILE_NAME)); - } - - /** - * The annotation allows you to tell Spring that the context is dirty and needs to be reloaded - * after the test. - */ - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testParseProperty() throws IOException { - assertNotEquals(prevWrittenToFileProperties, writtenToFileProperties); - assertNotEquals(prevSpringParsedProperties, springParsedProperties); - assertEquals(writtenToFileProperties, springParsedProperties); - - prevWrittenToFileProperties = writtenToFileProperties; - prevSpringParsedProperties = springParsedProperties; - - // Write the Properties class that will be parsed by Spring in the next iteration. - writtenToFileProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/core/annotation/IdClassResolverTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/core/annotation/IdClassResolverTest.java deleted file mode 100644 index e6a7431b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/core/annotation/IdClassResolverTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.core.annotation; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import io.tarantool.spring.data31.utils.entity.ComplexPerson; -import io.tarantool.spring.data31.utils.entity.CompositePersonKey; -import io.tarantool.spring.data31.utils.entity.EntityWithAnnotationAsIdClass; -import io.tarantool.spring.data31.utils.entity.Person; - -@Timeout(5) -class IdClassResolverTest { - - public static final DefaultIdClassResolver ID_CLASS_RESOLVER = DefaultIdClassResolver.INSTANCE; - - @Test - void testResolveIdClassTypeWithNullEntity() { - - final IllegalArgumentException throwable = - assertThrows( - IllegalArgumentException.class, () -> ID_CLASS_RESOLVER.resolveIdClassType(null)); - final String EXCEPTION_MESSAGE = "Type for IdClass must be not null!"; - assertEquals(EXCEPTION_MESSAGE, throwable.getMessage()); - } - - @Test - void testResolveIdClassTypeWithEntityWithoutAnnotation() { - assertNull(ID_CLASS_RESOLVER.resolveIdClassType(Person.class)); - } - - @Test - void testResolveIdClassTypeWithEntityWithAnnotation() { - assertEquals( - ID_CLASS_RESOLVER.resolveIdClassType(ComplexPerson.class), CompositePersonKey.class); - } - - @Test - void testResolveIdClassTypeWithCrossAnnotation() { - final IllegalArgumentException throwable = - assertThrows( - IllegalArgumentException.class, - () -> ID_CLASS_RESOLVER.resolveIdClassType(EntityWithAnnotationAsIdClass.class)); - - assertEquals(DefaultIdClassResolver.ANNOTATION_TYPE_EXCEPTION, throwable.getMessage()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/core/mapping/KeyValueCompositePropertyTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/core/mapping/KeyValueCompositePropertyTest.java deleted file mode 100644 index 21a70c88..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/core/mapping/KeyValueCompositePropertyTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.core.mapping; - -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.ReflectionUtils; - -public class KeyValueCompositePropertyTest

> { - - private @Nullable Identifier

identifier; - - @BeforeEach - public void setUp() { - this.identifier = null; - } - - /** Check methods for adding and retrieving parts of a composite key. */ - @Test - public void testAddAndGetParts() { - Class entityClass = TestEntity.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - - ReflectionUtils.FieldFilter isIdFieldFiler = field -> field.isAnnotationPresent(Id.class); - ReflectionUtils.doWithFields(entityClass, field -> addPart(field, owner), isIdFieldFiler); - - assertNotNull(identifier); - List identifierFieldsFromProperties = - this.identifier.getParts().stream() - .map(PersistentProperty::getField) - .collect(Collectors.toList()); - - compareFieldCollection(identifierFieldsFromProperties, getExpectedIdFields(entityClass)); - } - - /** Check methods for adding and retrieving parts of a composite key. */ - @Test - public void testAddAndGetFields() { - Class entityClass = TestEntity.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - - ReflectionUtils.FieldFilter isIdFieldFiler = field -> field.isAnnotationPresent(Id.class); - ReflectionUtils.doWithFields(entityClass, field -> addPart(field, owner), isIdFieldFiler); - - assertNotNull(identifier); - List fieldsFromIdentifier = Arrays.asList(identifier.getFields()); - - compareFieldCollection(fieldsFromIdentifier, getExpectedIdFields(entityClass)); - } - - /** - * Check methods for adding and getting parts of a composite key for an object without - * {@code @Id}. - */ - @Test - public void testAddAndGetPartsWithEntityWithoutId() { - Class entityClass = TestEntityWithoutId.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - ReflectionUtils.doWithFields( - entityClass, field -> addPart(field, owner), field -> field.isAnnotationPresent(Id.class)); - - assertNull(identifier); - } - - static class TestEntity { - - @Id private long id; - - @Id private int secondId; - } - - static class TestEntityWithoutId { - - private long id; - - @Nullable private String name; - - private int secondId; - } - - /** Create a PersistentProperty and add to first id property. */ - @SuppressWarnings("unchecked") - private void addPart(Field field, PersistentEntity owner) { - Property property = Property.of(owner.getTypeInformation(), field); - Identifier

persistentProperty = - new KeyValueCompositeProperty<>(property, owner, SimpleTypeHolder.DEFAULT); - - if (this.identifier == null) { - this.identifier = persistentProperty; - } - this.identifier.addPart((P) persistentProperty); - } - - /** Compare fields by name and type. */ - private void compareFieldCollection(List first, List second) { - assertEquals(first.size(), second.size()); - - first.sort(Comparator.comparing(Field::getName)); - second.sort(Comparator.comparing(Field::getName)); - - for (int i = 0; i < first.size(); i++) { - assertEquals(first.get(i).getName(), second.get(i).getName()); - assertEquals(first.get(i).getType(), second.get(i).getType()); - } - } - - /** Get the expected fields marked with the {@code @Id} annotation. */ - private List getExpectedIdFields(Class entityClass) { - return Arrays.stream(entityClass.getDeclaredFields()) - .filter(field -> field.isAnnotationPresent(Id.class)) - .collect(Collectors.toList()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/core/mapping/TarantoolMappingContextTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/core/mapping/TarantoolMappingContextTest.java deleted file mode 100644 index 3d196a06..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/core/mapping/TarantoolMappingContextTest.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.core.mapping; - -import java.lang.reflect.Field; -import java.util.HashSet; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data31.core.mapping.BasicKeyValueCompositePersistentEntity.KeyPartTypeChecker; -import io.tarantool.spring.data31.utils.entity.ComplexPerson; -import io.tarantool.spring.data31.utils.entity.EntityWithWrongCompositeKeyPartsCount; -import io.tarantool.spring.data31.utils.entity.EntityWithWrongFieldTypes; -import io.tarantool.spring.data31.utils.entity.Person; - -class TarantoolMappingContextTest { - - @Test - void testSetKeySpaceResolver() throws NoSuchFieldException { - final KeySpaceResolver RESOLVER = TestResolver.INSTANCE; - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - mappingContext.setKeySpaceResolver(RESOLVER); - - final Field field = TarantoolMappingContext.class.getDeclaredField("keySpaceResolver"); - ReflectionUtils.makeAccessible(field); - - final Object resolverFieldValue = ReflectionUtils.getField(field, mappingContext); - - assertEquals(RESOLVER, resolverFieldValue); - } - - @Test - void testCreatePersistentEntity() { - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - final TypeInformation informationForSimpleClass = TypeInformation.of(Person.class); - - final TypeInformation informationForIdentifierClass = - TypeInformation.of(ComplexPerson.class); - - assertInstanceOf( - KeyValueCompositePersistentEntity.class, createEntityForClass(ComplexPerson.class)); - - assertInstanceOf(KeyValuePersistentEntity.class, createEntityForClass(ComplexPerson.class)); - } - - @Test - void testCreatePersistentProperty() { - ReflectionUtils.FieldFilter idFilter = field -> field.isAnnotationPresent(Id.class); - - PersistentProperty simpleIdProperty = createProperty(Person.class, idFilter); - assertInstanceOf(KeyValuePersistentProperty.class, simpleIdProperty); - - PersistentProperty compositeIdProperty = createProperty(ComplexPerson.class, idFilter); - assertInstanceOf(KeyValueCompositeProperty.class, compositeIdProperty); - } - - @Test - void testCreateEntityWithWrongCompositeKeyPartTypes() { - Set> initialSet = - new HashSet>() { - { - add(EntityWithWrongFieldTypes.class); - } - }; - IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> initEntities(initialSet)); - - Assertions.assertEquals( - KeyPartTypeChecker.COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION, exception.getMessage()); - } - - @Test - void testCreateEntityWithWrongCompositeKeyPartCount() { - Set> initialSet = - new HashSet>() { - { - add(EntityWithWrongCompositeKeyPartsCount.class); - } - }; - IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> initEntities(initialSet)); - - assertEquals(KeyPartTypeChecker.COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION, exception.getMessage()); - } - - /** - * Create a mappingContext from the passed domain classes. After initialize - create for them - * PersistentEntities and add PersistentProperties to them. - * - * @param entitySet - * @return - */ - private MappingContext initEntities(Set> entitySet) { - TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - mappingContext.setInitialEntitySet(entitySet); - mappingContext.initialize(); - return mappingContext; - } - - private enum TestResolver implements KeySpaceResolver { - INSTANCE; - - @Override - @Nullable - public String resolveKeySpace(Class type) { - - Assert.notNull(type, "Type for keyspace for null!"); - - Class userClass = ClassUtils.getUserClass(type); - Object keySpace = getKeySpace(userClass); - - return keySpace != null ? keySpace.toString() : null; - } - - @Nullable - private static Object getKeySpace(Class type) { - - KeySpace keyspace = AnnotatedElementUtils.findMergedAnnotation(type, KeySpace.class); - - if (keyspace != null) { - return AnnotationUtils.getValue(keyspace); - } - - return null; - } - } - - private PersistentEntity createEntityForClass(Class entityClass) { - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - final TypeInformation informationForClass = TypeInformation.of(entityClass); - return mappingContext.createPersistentEntity(informationForClass); - } - - private

> PersistentProperty createProperty( - Class classType, ReflectionUtils.FieldFilter fieldFilter) { - - final TarantoolMappingContext, P> context = - new TarantoolMappingContext<>(); - KeyValuePersistentEntity entity = - context.createPersistentEntity(TypeInformation.of(classType)); - Field field = org.springframework.data.util.ReflectionUtils.findField(classType, fieldFilter); - assertNotNull(field); - - return context.createPersistentProperty( - Property.of(entity.getTypeInformation(), field), entity, SimpleTypeHolder.DEFAULT); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java deleted file mode 100644 index b6e96490..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.core.mapping.model; - -import java.lang.reflect.Field; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.Test; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data31.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data31.core.mapping.BasicKeyValueCompositePersistentEntity; -import io.tarantool.spring.data31.core.mapping.KeyValueCompositeProperty; -import io.tarantool.spring.data31.utils.entity.ComplexPerson; - -public class PersistentCompositeIdIsNewStrategyTest

> { - - /** Check the strategy creation method and check whether the domain entity is new. */ - @Test - public void testForIdOnly() { - - // Currently identical like of 'of' method (version doesn't support) - PersistentCompositeIdIsNewStrategy strategy = - PersistentCompositeIdIsNewStrategy.forIdOnly(createPersistentEntity(ComplexPerson.class)); - - // Now is stub - always is false - ComplexPerson emptyEntity = new ComplexPerson(); - assertFalse(strategy.isNew(emptyEntity)); - } - - /** Check the strategy creation method and check whether the domain entity is new. */ - @Test - public void testIsNew() { - PersistentCompositeIdIsNewStrategy strategy = - PersistentCompositeIdIsNewStrategy.of(createPersistentEntity(ComplexPerson.class)); - - // Now is stub - always is false - ComplexPerson emptyEntity = new ComplexPerson(); - assertFalse(strategy.isNew(emptyEntity)); - } - - private BasicKeyValueCompositePersistentEntity createPersistentEntity(Class entityType) { - Class compositeKeyType = DefaultIdClassResolver.INSTANCE.resolveIdClassType(entityType); - assertNotNull(compositeKeyType); - - BasicKeyValueCompositePersistentEntity persistentEntity = - new BasicKeyValueCompositePersistentEntity<>( - TypeInformation.of(entityType), null, compositeKeyType); - ReflectionUtils.doWithFields(entityType, field -> addProperty(field, persistentEntity)); - return persistentEntity; - } - - /** Add Persistent property into PersistentEntity. */ - @SuppressWarnings("unchecked") - private void addProperty(Field field, BasicKeyValueCompositePersistentEntity owner) { - Property property = Property.of(owner.getTypeInformation(), field); - P persistentProperty = - (P) new KeyValueCompositeProperty<>(property, owner, SimpleTypeHolder.DEFAULT); - owner.addPersistentProperty(persistentProperty); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/BaseIntegrationTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/BaseIntegrationTest.java deleted file mode 100644 index a758fb6e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/BaseIntegrationTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.integration; - -import java.io.IOException; -import java.nio.file.Files; -import java.time.Duration; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Timeout; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.cluster.ClusterContainer; -import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer; -import org.testcontainers.containers.cluster.vshard.VshardClusterContainer; -import org.testcontainers.containers.output.Slf4jLogConsumer; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.spring.data31.config.properties.TarantoolProperties; - -@Timeout(60) -public abstract class BaseIntegrationTest { - - protected static ClusterContainer clusterContainer; - - private static final String dockerRegistry = - System.getenv().getOrDefault("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", ""); - - @BeforeAll - protected static void beforeAll() throws IOException { - configureContainer(); - writeConfigurationFile(); - } - - private static void configureContainer() { - if (!isCartridgeAvailable()) { - VshardClusterContainer vshardClusterContainer = - new VshardClusterContainer( - "vshard_cluster/Dockerfile", - dockerRegistry + "vshard-cluster-java", - "vshard_cluster/instances.yaml", - "vshard_cluster/config.yaml", - "tarantool/tarantool"); - - if (!vshardClusterContainer.isRunning()) { - vshardClusterContainer.withPrivilegedMode(true); - vshardClusterContainer.start(); - } - clusterContainer = vshardClusterContainer; - } else { - CartridgeClusterContainer cartridgeContainer = - new CartridgeClusterContainer( - "cartridge/Dockerfile", - dockerRegistry + "cartridge", - "cartridge/instances.yml", - "cartridge/replicasets.yml", - org.testcontainers.containers.Arguments.get("tarantool/tarantool")) - .withStartupTimeout(Duration.ofMinutes(5)) - .withLogConsumer( - new Slf4jLogConsumer(LoggerFactory.getLogger(BaseIntegrationTest.class))); - - if (!cartridgeContainer.isRunning()) { - cartridgeContainer.start(); - } - clusterContainer = cartridgeContainer; - } - } - - private static void writeConfigurationFile() throws IOException { - final TarantoolProperties properties = new TarantoolProperties(); - properties.setHost(clusterContainer.getHost()); - properties.setPort(clusterContainer.getPort()); - properties.setUserName(clusterContainer.getUsername()); - properties.setPassword(clusterContainer.getPassword()); - - writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME, properties); - } - - @AfterAll - protected static void afterAll() throws IOException { - Files.deleteIfExists(DEFAULT_TEST_PROPERTY_DIR.resolve(DEFAULT_PROPERTY_FILE_NAME)); - } - - protected static String getHost() { - return clusterContainer.getHost(); - } - - protected static int getPort() { - return clusterContainer.getPort(); - } - - protected static String getUsername() { - return clusterContainer.getUsername(); - } - - protected static String getPassword() { - return clusterContainer.getPassword(); - } - - protected static boolean isCartridgeAvailable() { - return System.getenv().getOrDefault("TARANTOOL_VERSION", "").matches("2.*"); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/GenericRepositoryTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/GenericRepositoryTest.java deleted file mode 100644 index 2db2ebbf..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/GenericRepositoryTest.java +++ /dev/null @@ -1,1967 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.integration.crud; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.util.Streamable; - -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data31.query.TarantoolQueryCreator.INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.UNKNOWN_PERSON; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.generateAndInsertPersons; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.mapping.Tuple; -import io.tarantool.spring.data.query.Conditions; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data.utils.Pair; -import io.tarantool.spring.data31.query.TarantoolPageRequest; -import io.tarantool.spring.data31.query.TarantoolScrollPosition; -import io.tarantool.spring.data31.query.TarantoolWindowIterator; -import io.tarantool.spring.data31.utils.TarantoolTestSupport; -import io.tarantool.spring.data31.utils.core.ComplexPersonRepository; -import io.tarantool.spring.data31.utils.core.GenericPaginationMethods; -import io.tarantool.spring.data31.utils.core.PersonRepository; -import io.tarantool.spring.data31.utils.entity.ComplexPerson; -import io.tarantool.spring.data31.utils.entity.Person; - -abstract class GenericRepositoryTest extends CrudConfigurations { - - @Autowired protected ApplicationContext context; - - protected static BiFunction> - complexPersonGenerateAndInsertFunction = - (context, personCount) -> - generateAndInsertComplexPersons( - personCount, context.getBean(TarantoolCrudClient.class)); - - protected static BiFunction> - personGenerateAndInsertFunction = - (context, personCount) -> - generateAndInsertPersons(personCount, context.getBean(TarantoolCrudClient.class)); - - protected static Function> complexPersonGenerateFunction = - TarantoolTestSupport::generateComplexPersons; - - protected static Function> personGenerateFunction = - TarantoolTestSupport::generatePersons; - - protected static final int INDEX_ID_VALUE = 50; - - protected static final Pair PERSON_INDEX_KEY = Pair.of("pk", INDEX_ID_VALUE); - - protected static final Pair PERSON_INITIAL_INDEX_KEY = - Pair.of("pk", Collections.emptyList()); - - protected static Stream dataForTestRepositoryWithFindByIs() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByIs") - , ID> void testRepositoryWithFindByIs( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - List foundPersons = repository.findByName(person.getName()); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(1, foundPersons.size()); - assertEquals(person, foundPersons.get(0)); - } - - protected static Stream dataForTestRepositoryWithFindById() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindById") - , ID> void testRepositoryWithFindById( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - Optional foundPerson = repository.findById(person.generateFullKey()); - - assertTrue(foundPerson.isPresent()); - assertEquals(person, foundPerson.get()); - } - - protected static Stream dataForTestRepositoryWithFindAllById() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllById") - , ID> void testRepositoryWithFindAllById( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - Iterable foundPersons = - repository.findAllById( - persons.stream().map(PERSON::generateFullKey).collect(Collectors.toList())); - List foundPersonsAsList = - StreamSupport.stream(foundPersons.spliterator(), false) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(persons, foundPersonsAsList); - } - - protected static Stream dataForTestRepositoryWithCount() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithCount") - , ID> void testRepositoryWithCount( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - assertEquals(PERSONS_COUNT, context.getBean(repositoryClass).count()); - } - - protected static Stream dataForTestRepositoryWithCountBy() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithCountBy") - , ID> void testRepositoryWithCountBy( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - assertEquals(1, repository.countByName(person.getName())); - } - - protected static Stream dataForTestRepositoryWithDelete() { - return Stream.of( - Arguments.of( - personGenerateFunction, - PersonRepository.class, - PERSON_SPACE, - (BiFunction>) - (space, key) -> { - Tuple tuple = - space.get(Collections.singletonList(key), Person.class).join(); - if (tuple != null) { - return tuple.get(); - } - return null; - }), - Arguments.of( - complexPersonGenerateFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (BiFunction>) - (space, key) -> { - Tuple tuple = space.get(key, ComplexPerson.class).join(); - if (tuple != null) { - return tuple.get(); - } - return null; - })); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithDelete") - , ID> void testRepositoryWithDelete( - Function> generateFunction, - Class> repositoryClass, - String spaceName, - BiFunction spaceGetFunction) { - - final List persons = generateFunction.apply(PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - space.insertMany(persons).join(); - - final PERSON deletingPerson = persons.get(0); - - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - // by object - repository.delete(deletingPerson); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - space.insert(deletingPerson).join(); - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - // by id - repository.deleteById(deletingPerson.generateFullKey()); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - space.insert(deletingPerson).join(); - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - // by name - repository.deleteByName(deletingPerson.getName()); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - } - - protected static Stream dataForTestRepositoryWithExistId() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiConsumer) - (space, key) -> space.delete(Collections.singletonList(key)).join(), - PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - (BiConsumer) (space, key) -> space.delete(key).join(), - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithExistId") - , ID> void testRepositoryWithExistId( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - BiConsumer deleteConsumer, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final PERSON person = persons.get(0); - - assertTrue(repository.existsById(person.generateFullKey())); - deleteConsumer.accept(space, person.generateFullKey()); - assertFalse(repository.existsById(person.generateFullKey())); - } - - protected static Stream dataForTestQueryAnnotationAsCall() { - return Stream.of( - Arguments.of(PersonRepository.class), Arguments.of(ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsCall") - , ID> void testQueryAnnotationAsCall( - Class> repositoryClass) { - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - assertEquals(Arrays.asList(1, "hi", false), repository.getStatic().get()); - } - - protected static Stream dataForTestQueryAnnotationAsCallWithArgs() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsCallWithArgs") - , ID> void testQueryAnnotationAsCallWithArgs( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals(Arrays.asList("hello", true, 13), repository.echo("hello", true, 13).get()); - } - - protected static Stream dataForTestQueryAnnotationAsEval() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsEval") - , ID> void testQueryAnnotationAsEval( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals(Arrays.asList("hello", 123, true), repository.evalGetStatic().get()); - } - - protected static Stream dataForTestQueryAnnotationAsEvalWithArgs() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsEvalWithArgs") - , ID> void testQueryAnnotationAsEvalWithArgs( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals( - Arrays.asList("hello", true, 13), repository.evalWithArgs("hello", true, 13).get()); - } - - protected static Stream dataForTestRepositoryWithExistName() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiConsumer) - (space, key) -> space.delete(Collections.singletonList(key)).join(), - PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - (BiConsumer) (space, key) -> space.delete(key).join(), - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithExistName") - , ID> void testRepositoryWithExistName( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - BiConsumer deleteConsumer, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final PERSON person = persons.get(0); - - assertTrue(repository.existsByName(person.getName())); - deleteConsumer.accept(space, person.generateFullKey()); - assertFalse(repository.existsByName(person.getName())); - } - - protected static Stream dataForTestRepositoryWithFindByLessThan() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByLessThan") - , ID> void testRepositoryWithFindByLessThan( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 10; - final List foundPersons = repository.findAllByIdIsLessThan(findLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(findLimiter, foundPersons.size()); - assertEquals(persons.subList(0, findLimiter), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsTrue() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsTrue") - , ID> void testRepositoryWithFindAllByIsMarriedIsTrue( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsTrue(); - assertEquals(PERSONS_COUNT / 3, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(GenericPerson::getIsMarried)); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsFalse() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsFalse") - , ID> void testRepositoryWithFindAllByIsMarriedIsFalse( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsFalse(); - assertEquals(PERSONS_COUNT / 3, foundPersons.size()); - assertTrue(foundPersons.stream().noneMatch(GenericPerson::getIsMarried)); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsNull() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsNull") - , ID> void testRepositoryWithFindAllByIsMarriedIsNull( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsNull(); - assertEquals(PERSONS_COUNT / 3 + 1, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(p -> p.getIsMarried() == null)); - } - - protected static Stream dataForTestRepositoryWithFindAllByNameIsEmpty() { - return Stream.of( - Arguments.of(personGenerateFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByNameIsEmpty") - , ID> void testRepositoryWithFindAllByNameIsEmpty( - Function> generateFunction, - Class> repositoryClass) { - - List persons = generateFunction.apply(PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - PERSON person = persons.get(0); - person.setName(""); - persons.set(0, person); - - repository.saveAll(persons); - - final List foundPersons = repository.findAllByNameIsEmpty(); - assertEquals(1, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(p -> p.getName().isEmpty())); - } - - protected static Stream dataForTestRepositoryWithFindByLessThanEqual() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByLessThanEqual") - , ID> void testRepositoryWithFindByLessThanEqual( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 10; - final List foundPersonsWithEqual = repository.findAllByIdLessThanEqual(findLimiter); - - foundPersonsWithEqual.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(findLimiter + 1, foundPersonsWithEqual.size()); - assertEquals(persons.subList(0, findLimiter + 1), foundPersonsWithEqual); - } - - protected static Stream dataForTestRepositoryWithFindByGreaterThan() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByGreaterThan") - , ID> void testRepositoryWithFindByGreaterThan( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 90; - final List foundPersons = repository.findAllByIdIsGreaterThan(findLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(PERSONS_COUNT - findLimiter - 1, foundPersons.size()); - assertEquals(persons.subList(findLimiter + 1, PERSONS_COUNT), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindByGreaterThanEqual() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByGreaterThanEqual") - , ID> void testRepositoryWithFindByGreaterThanEqual( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 90; - final List foundPersonsWithEqual = repository.findAllByIdGreaterThanEqual(findLimiter); - - foundPersonsWithEqual.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(PERSONS_COUNT - findLimiter, foundPersonsWithEqual.size()); - assertEquals(persons.subList(findLimiter, PERSONS_COUNT), foundPersonsWithEqual); - } - - protected static Stream dataForTestRepositoryWithFindByBetween() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByBetween") - , ID> void testRepositoryWithFindByBetween( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int startFindLimiter = 50; - final int endFindLimiter = 90; - final List foundPersons = - repository.findAllByIdBetween(startFindLimiter, endFindLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - final int foundPersonsCount = endFindLimiter - startFindLimiter - 1; - assertEquals(foundPersonsCount, foundPersons.size()); - assertEquals(persons.subList(startFindLimiter + 1, endFindLimiter), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindByBetweenNegativeInts() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByBetweenNegativeInts") - , ID> void testRepositoryWithFindByBetweenNegativeInts( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int startFindLimiter = -1; - final int endFindLimiter = -10; - final List foundPersons = - repository.findAllByIdBetween(startFindLimiter, endFindLimiter); - assertTrue(foundPersons.isEmpty()); - } - - protected static Stream dataForTestRepositoryIgnoreCase() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryIgnoreCase") - , ID> void testRepositoryIgnoreCase( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - final String name = persons.get(0).getName(); - - final InvalidDataAccessApiUsageException exception = - assertThrows( - InvalidDataAccessApiUsageException.class, () -> repository.findByNameIgnoreCase(name)); - final String EXCEPTION_MESSAGE = - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "IgnoreCase isn't supported yet", - Part.Type.SIMPLE_PROPERTY); - assertEquals(EXCEPTION_MESSAGE, exception.getMessage()); - } - - protected static Stream dataForTestRepositoryWithTarantoolNamingNotation() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithTarantoolNamingNotation") - , ID> void testRepositoryWithTarantoolNamingNotation( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List marriedPersons = repository.findByIsMarried(true); - final List nonMarriedPersons = repository.findByIsMarried(false); - final int expectedCount = PERSONS_COUNT / 3; - assertEquals(expectedCount, marriedPersons.size()); - assertEquals(expectedCount, nonMarriedPersons.size()); - } - - protected static Stream dataForTestRepositoryNotEnoughArguments() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryNotEnoughArguments") - , ID> void testRepositoryNotEnoughArguments( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertThrows(InvalidDataAccessApiUsageException.class, repository::findById); - } - - protected static Stream dataForTestRepositorySave() { - return dataForTestRepositoryWithDelete(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySave") - , ID> void testRepositorySave( - Function> generateFunction, - Class> repositoryClass, - String spaceName, - BiFunction getFunction) { - - List persons = generateFunction.apply(PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - TarantoolCrudSpace space = client.space(spaceName); - final PERSON person = persons.get(0); - - repository.save(person); - - PERSON gotPerson = getFunction.apply(space, person.generateFullKey()); - assertEquals(person, gotPerson); - } - - protected static Stream dataForTestRepositorySaveAll() { - Conditions conditions = new Conditions(); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - PERSON_SPACE, - (Function>) - (space) -> unwrapTuples(space.select(conditions, Person.class).join())), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (Function>) - (space) -> unwrapTuples(space.select(conditions, ComplexPerson.class).join()))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySaveAll") - , ID> void testRepositorySaveAll( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - Function> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - repository.saveAll(persons); - - List selectedPersons = selectFunction.apply(space); - selectedPersons.sort(Comparator.comparing(GenericPerson::getId)); - - assertEquals(persons, selectedPersons); - } - - protected static Stream dataForTestDeleteAll() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class, PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteAll") - , ID> void testDeleteAll( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow(() -> repository.deleteAll()); - assertEquals(0, space.count(new Conditions()).join()); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow(() -> repository.deleteAll(persons)); - assertEquals(0, space.count(new Conditions()).join()); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow( - () -> - repository.deleteAllById( - persons.stream().map(PERSON::generateFullKey).collect(Collectors.toList()))); - assertEquals(0, space.count(new Conditions()).join()); - } - - protected static Stream dataForTestRepositoryFindByAfter() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByAfter") - , ID> void testRepositoryFindByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - final List selectedPersons = repository.findByNameAfter(person.getName()); - selectedPersons.sort(Comparator.comparing(PERSON::getName)); - - final List expectedList = - persons.stream() - .filter(p -> p.getName().compareTo(person.getName()) > 0) - .limit(SelectOptions.DEFAULT_LIMIT) - .sorted(Comparator.comparing(PERSON::getName)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - } - - protected static Stream dataForTestRepositoryFindByAfterWithLimit() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByAfterWithLimit") - , ID> void testRepositoryFindByAfterWithLimit( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int LIMIT = 5; - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findFirst5ByIdAfter(person.getId()); - selectedPersons.sort(Comparator.comparing(PERSON::getId)); - - final List selectedPersonsWithTopKeyword = repository.findTop5ByIdAfter(person.getId()); - selectedPersonsWithTopKeyword.sort(Comparator.comparing(PERSON::getId)); - - final List expectedList = - persons.stream() - .filter(p -> p.getId().compareTo(person.getId()) > 0) - .limit(LIMIT) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - - assertEquals(expectedList.size(), selectedPersonsWithTopKeyword.size()); - assertEquals(expectedList, selectedPersonsWithTopKeyword); - } - - protected static Stream dataForTestRepositoryFindByBefore() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByBefore") - , ID> void testRepositoryFindByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findByNameBefore(person.getName()); - selectedPersons.sort(Comparator.comparing(PERSON::getName)); - - final List expectedList = - persons.stream() - .filter(p -> p.getName().compareTo(person.getName()) < 0) - .limit(SelectOptions.DEFAULT_LIMIT) - .sorted(Comparator.comparing(PERSON::getName)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - } - - protected static Stream dataForTestRepositoryFindByBeforeWithLimit() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByBeforeWithLimit") - , ID> void testRepositoryFindByBeforeWithLimit( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int LIMIT = 5; - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findFirst5ByIdBefore(person.getId()); - selectedPersons.sort(Comparator.comparing(PERSON::getId)); - - final List selectedPersonsWithTopKeyword = - repository.findTop5ByIdBefore(person.getId()); - selectedPersonsWithTopKeyword.sort(Comparator.comparing(PERSON::getId)); - - // Because id (not fullscan) - persons.sort(Comparator.comparing(PERSON::getId, (o1, o2) -> Integer.compare(o2, o1))); - - final List expectedList = - persons.stream() - .filter(p -> p.getId().compareTo(person.getId()) < 0) - .limit(LIMIT) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - - assertEquals(expectedList.size(), selectedPersonsWithTopKeyword.size()); - assertEquals(expectedList, selectedPersonsWithTopKeyword); - } - - protected static Stream dataForTestDeleteByAfter() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - PERSON_SPACE, - (BiFunction>) - (space, options) -> - unwrapTuples( - space.select(Collections.emptyList(), options, Person.class).join())), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (BiFunction>) - (space, options) -> - unwrapTuples( - space - .select(Collections.emptyList(), options, ComplexPerson.class) - .join()))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteByAfter") - , ID> void testDeleteByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - BiFunction> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - persons.sort(Comparator.comparing(PERSON::getName)); - - final int RANDOM_INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final SelectOptions options = SelectOptions.builder().withFirst(PERSONS_COUNT).build(); - final PERSON deletingAfterPerson = persons.get(RANDOM_INDEX); - - final List deletedPersons = repository.deleteByNameAfter(deletingAfterPerson.getName()); - - List allPersonsInBaseAfterDeleted = selectFunction.apply(space, options); - assertEquals(PERSONS_COUNT - deletedPersons.size(), allPersonsInBaseAfterDeleted.size()); - - persons.removeAll(deletedPersons); - allPersonsInBaseAfterDeleted.sort(Comparator.comparing(PERSON::getId)); - persons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(persons, allPersonsInBaseAfterDeleted); - } - - protected static Stream dataForTestDeleteByBefore() { - return dataForTestDeleteByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteByBefore") - , ID> void testDeleteByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - BiFunction> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final SelectOptions options = SelectOptions.builder().withFirst(PERSONS_COUNT).build(); - final int RANDOM_INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - - final PERSON deletingBeforePerson = persons.get(RANDOM_INDEX); - final List deletedPersons = - repository.deleteByNameBefore(deletingBeforePerson.getName()); - - List allPersonsInBaseAfterDeleted = selectFunction.apply(space, options); - - assertEquals(PERSONS_COUNT - deletedPersons.size(), allPersonsInBaseAfterDeleted.size()); - - persons.removeAll(deletedPersons); - allPersonsInBaseAfterDeleted.sort(Comparator.comparing(PERSON::getId)); - persons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(persons, allPersonsInBaseAfterDeleted); - } - - protected static Stream dataForTestCountByAfter() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestCountByAfter") - , ID> void testCountByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final int ID_AFTER = persons.get(INDEX).getId(); - - final long count = repository.countByIdAfter(ID_AFTER); - - final int EXPECTED_COUNT = PERSONS_COUNT - ID_AFTER - 1; - assertEquals(EXPECTED_COUNT, count); - } - - protected static Stream dataForTestCountByBefore() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestCountByBefore") - , ID> void testCountByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - persons.sort(Comparator.comparing(PERSON::getName)); - - final int indexBefore = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final String name = persons.get(indexBefore).getName(); - final long count = repository.countByNameBefore(name); - - assertEquals(indexBefore, count); - - final long unknownNameCount = repository.countByNameBefore(UNKNOWN_PERSON.getName()); - assertEquals(0, unknownNameCount); - } - - protected static < - REPO extends GenericPaginationMethods, PERSON extends GenericPerson, ID> - Stream dataForTestRepositorySlicePagePageableEqual() { - final int PAGE_SIZE = ThreadLocalRandom.current().nextInt(1, PERSONS_COUNT / 3 - 1); - final String NAME = "name"; - final Pageable beginPageable = new TarantoolPageRequest>(PAGE_SIZE); - - BiFunction> generatePersonAndInsertFunction = - (context, size) -> - generateAndInsertPersons( - size, context.getBean(TarantoolCrudClient.class), (person) -> person.setName(NAME)); - - BiFunction> - generateComplexPersonAndInsertFunction = - (context, size) -> - generateAndInsertComplexPersons( - size, - context.getBean(TarantoolCrudClient.class), - (person) -> person.setName(NAME)); - - Function personRepositoryFunc = - (context) -> context.getBean(PersonRepository.class); - - Function complexPersonRepositoryFunc = - (context) -> context.getBean(ComplexPersonRepository.class); - - BiFunction> executionForFindAllByName = - (repo, pageable) -> repo.findAllByName(NAME, pageable); - - Function, List> expectedListForFindAllByNameFunc = - (persons) -> - persons.stream() - .filter(person -> NAME.equals(person.getName())) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()) - .subList(0, PAGE_SIZE); - - BiFunction> executionForFindByName = - (repo, pageable) -> repo.findPersonByName(NAME, pageable); - - List> generateFunctionPairs = - Arrays.asList( - Arrays.asList(generatePersonAndInsertFunction, personRepositoryFunc), - Arrays.asList(generateComplexPersonAndInsertFunction, complexPersonRepositoryFunc)); - - List executionFunctions = Arrays.asList(executionForFindAllByName, executionForFindByName); - - // add arguments set - List arguments = new ArrayList<>(); - for (List generateFunctionPair : generateFunctionPairs) { - for (Object executionFunction : executionFunctions) { - arguments.add( - Arguments.of( - generateFunctionPair.get(0), - executionFunction, - generateFunctionPair.get(1), - expectedListForFindAllByNameFunc, - beginPageable)); - } - } - - return arguments.stream(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySlicePagePageableEqual") - , PERSON extends GenericPerson, ID> - void testRepositorySlicePagePageableEqual( - BiFunction> generateAndInsertFunction, - BiFunction> executingRepositoryMethod, - Function giveRepositoryFunction, - Function, List> expectedSlicePageContent, - Pageable beginPageable) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - Slice slicePage = - executingRepositoryMethod.apply(giveRepositoryFunction.apply(context), beginPageable); - - assertEquals(beginPageable, slicePage.getPageable()); - assertEquals(expectedSlicePageContent.apply(persons), slicePage.getContent()); - } - - protected static Stream dataForTestRepositorySliceMethodWithoutPageable() { - final String NAME = "name"; - return Stream.of( - Arguments.of(PersonRepository.class, NAME), - Arguments.of(ComplexPersonRepository.class, NAME)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySliceMethodWithoutPageable") - , ID> void testRepositorySliceMethodWithoutPageable( - Class> repositoryClass, String name) { - GenericPaginationMethods repository = context.getBean(repositoryClass); - - assertEquals(Pageable.unpaged(), repository.findAllByName(name).getPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).nextPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).nextOrLastPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).previousPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).previousOrFirstPageable()); - } - - @SuppressWarnings("unchecked") - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Stream dataForTestRepositorySliceWithDifferentFields() { - final int PAGE_SIZE = 10; - - Function, Pageable> nextPageableFunc = Slice::nextPageable; - Function, Pageable> prevPageableFunc = Slice::previousPageable; - Function, Pageable> nextOrLastPageableFunc = Slice::nextOrLastPageable; - Function, Pageable> prevOrFirstPageableFunc = Slice::previousOrFirstPageable; - BiFunction predicateForNextPageableFunc = - (currentPageable, nextPageable) -> nextPageable.isPaged(); - - BiFunction predicateForNextOrPageableFunc = - (currentPageable, nextPageable) -> !currentPageable.equals(nextPageable); - - Function personRepositoryFunc = - (context) -> context.getBean(PersonRepository.class); - - Function complexPersonRepositoryFunc = - (context) -> context.getBean(ComplexPersonRepository.class); - - Pageable beginPageable = new TarantoolPageRequest<>(PAGE_SIZE); - - BiFunction, Integer, Integer> idExtractionFunction = - (args, index) -> { - List persons = (List) args.get(0); - return persons.get(index).getId(); - }; - - BiFunction, Integer, String> nameExtractionFunction = - (args, index) -> { - List persons = (List) args.get(0); - return persons.get(index).getName(); - }; - - BiFunction, Slice> executionForFindAllByIdLessThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, PERSONS_COUNT - 1); - return repo.findAllByIdLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByIdLessThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, PERSONS_COUNT - 1); - return repo.findPersonByIdLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByIdGreaterThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, 0); - return repo.findAllByIdGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByIdGreaterThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, 0); - return repo.findPersonByIdGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByIsMarriedLessThanEqual = - (repo, arguments) -> - repo.findAllByIsMarriedLessThanEqual(false, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindPersonByIsMarriedLessThanEqual = - (repo, arguments) -> - repo.findPersonByIsMarriedLessThanEqual(false, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindAllByIsMarriedGreaterThanEqual = - (repo, arguments) -> - repo.findAllByIsMarriedGreaterThanEqual(null, (Pageable) arguments.get(1)); - - BiFunction, Slice> - executionForFindPersonByIsMarriedGreaterThanEqual = - (repo, arguments) -> - repo.findPersonByIsMarriedGreaterThanEqual(null, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindAllByNameLessThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findAllByNameLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByNameLessThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findPersonByNameLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByNameGreaterThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findAllByNameGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByNameGreaterThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findPersonByNameGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAll = - (repo, arguments) -> repo.findAll((Pageable) arguments.get(1)); - - Function, List> expectedListForFindAllByIdLessThanEqualFunc = - (persons) -> - persons.stream() - .sorted(Comparator.comparing(PERSON::getId).reversed()) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByIdGreaterThanEqualFunc = - (persons) -> persons; - - Function, List> expectedListForFindAllByIsMarriedGreaterThanEqual = - (persons) -> - persons.stream() - .sorted( - Comparator.comparing( - PERSON::getIsMarried, Comparator.nullsFirst(Comparator.naturalOrder()))) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByIsMarriedLessThanEqual = - (persons) -> - persons.stream() - .filter(person -> person.getIsMarried() == null || !person.getIsMarried()) - .sorted( - Comparator.comparing( - PERSON::getIsMarried, Comparator.nullsLast(Comparator.naturalOrder())) - .thenComparing(Comparator.comparing(PERSON::getId).reversed())) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByNameLessThanEqual = - (persons) -> { - String name = persons.get(persons.size() / 2).getName(); - return persons.stream() - .filter(person -> person.getName().compareTo(name) <= 0) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - }; - - Function, List> expectedListForFindAllByNameGreaterThanEqual = - (persons) -> { - String name = persons.get(persons.size() / 2).getName(); - return persons.stream() - .filter(person -> person.getName().compareTo(name) >= 0) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - }; - - Function, List> expectedListForFindAll = (persons) -> persons; - - List> getNextPageableMethodFunctionPairs = - Arrays.asList( - Arrays.asList(nextPageableFunc, prevPageableFunc, predicateForNextPageableFunc), - Arrays.asList( - nextOrLastPageableFunc, prevOrFirstPageableFunc, predicateForNextOrPageableFunc)); - - List> generateFunctions = - Arrays.asList( - Arrays.asList(personGenerateAndInsertFunction, personRepositoryFunc), - Arrays.asList(complexPersonGenerateAndInsertFunction, complexPersonRepositoryFunc)); - - List> executeExpectedFunctionPairs = - Arrays.asList( - Arrays.asList( - executionForFindAllByIdLessThanEqualFunc, - expectedListForFindAllByIdLessThanEqualFunc), - Arrays.asList( - executionForFindAllByIdGreaterThanEqualFunc, - expectedListForFindAllByIdGreaterThanEqualFunc), - Arrays.asList( - executionForFindAllByIsMarriedGreaterThanEqual, - expectedListForFindAllByIsMarriedGreaterThanEqual), - Arrays.asList( - executionForFindAllByIsMarriedLessThanEqual, - expectedListForFindAllByIsMarriedLessThanEqual), - Arrays.asList( - executionForFindAllByNameLessThanEqual, expectedListForFindAllByNameLessThanEqual), - Arrays.asList( - executionForFindAllByNameGreaterThanEqual, - expectedListForFindAllByNameGreaterThanEqual), - Arrays.asList( - executionForFindPersonByIdLessThanEqualFunc, - expectedListForFindAllByIdLessThanEqualFunc), - Arrays.asList( - executionForFindPersonByIdGreaterThanEqualFunc, - expectedListForFindAllByIdGreaterThanEqualFunc), - Arrays.asList( - executionForFindPersonByIsMarriedGreaterThanEqual, - expectedListForFindAllByIsMarriedGreaterThanEqual), - Arrays.asList( - executionForFindPersonByIsMarriedLessThanEqual, - expectedListForFindAllByIsMarriedLessThanEqual), - Arrays.asList( - executionForFindPersonByNameLessThanEqual, - expectedListForFindAllByNameLessThanEqual), - Arrays.asList( - executionForFindPersonByNameGreaterThanEqual, - expectedListForFindAllByNameGreaterThanEqual), - Arrays.asList(executionForFindAll, expectedListForFindAll)); - - // add arguments set - List arguments = new ArrayList<>(); - for (List generateFunctionPair : generateFunctions) { - for (List getNextPrevPageableFuncTriple : getNextPageableMethodFunctionPairs) { - for (List executeExpectedFunctionPair : executeExpectedFunctionPairs) { - arguments.add( - Arguments.of( - generateFunctionPair.get(0), - generateFunctionPair.get(1), - executeExpectedFunctionPair.get(0), - getNextPrevPageableFuncTriple.get(0), - getNextPrevPageableFuncTriple.get(1), - getNextPrevPageableFuncTriple.get(2), - executeExpectedFunctionPair.get(1), - beginPageable)); - } - } - } - return arguments.stream(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySliceWithDifferentFields") - , ID> void testRepositorySliceWithDifferentFields( - BiFunction> generateAndInsertFunction, - Function> giveRepositoryFunction, - BiFunction, List, Slice> - executingRepositoryMethod, - Function, Pageable> nextPageableMethod, - Function, Pageable> prevPageableMethod, - BiFunction stopPaginationPredicateFunction, - Function, List> expectedResultListMovingFunction, - Pageable beginPageable) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - - // moving forward - Pageable nextPageable = beginPageable; - List> forwardSlices = new ArrayList<>(); - Slice slice; - do { - slice = - executingRepositoryMethod.apply( - giveRepositoryFunction.apply(context), Arrays.asList(persons, nextPageable)); - forwardSlices.add(slice); - nextPageable = nextPageableMethod.apply(slice); - } while (stopPaginationPredicateFunction.apply(slice.getPageable(), nextPageable)); - - List forwardMovingResultList = - forwardSlices.stream().flatMap(Streamable::stream).collect(Collectors.toList()); - assertEquals(expectedResultListMovingFunction.apply(persons), forwardMovingResultList); - - // moving backward - List> reverseSlices = new ArrayList<>(); - nextPageable = forwardSlices.get(forwardSlices.size() - 1).getPageable(); - do { - slice = - executingRepositoryMethod.apply( - giveRepositoryFunction.apply(context), Arrays.asList(persons, nextPageable)); - reverseSlices.add(slice); - nextPageable = prevPageableMethod.apply(slice); - } while (stopPaginationPredicateFunction.apply(slice.getPageable(), nextPageable)); - - List backwardMovingResultList = - reverseSlices.stream() - .sorted(Comparator.comparing(Slice::getNumber)) - .flatMap(Streamable::stream) - .collect(Collectors.toList()); - - assertEquals(expectedResultListMovingFunction.apply(persons), backwardMovingResultList); - } - - protected static , ID> - List expectedForwardFuncForFindFirst5ByIsMarriedInitial(List persons) { - return persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst5ByIsMarriedInitial(List persons) { - List result = - new ArrayList<>(expectedForwardFuncForFindFirst5ByIsMarriedInitial(persons)); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial( - List persons) { - return persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial( - List persons) { - List result = - new ArrayList<>( - expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial(persons)); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst5ByIsMarriedIndexKey(List persons) { - return persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst5ByIsMarriedIndexKey(List persons) { - List result = - new ArrayList<>( - persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .sorted(Comparator.comparing(PERSON::getId)) - .toList()); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey( - List persons) { - return persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey( - List persons) { - List result = - new ArrayList<>( - persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .sorted(Comparator.comparing(PERSON::getId)) - .toList()); - Collections.reverse(result); - return result; - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Window executionFunctionForFindFirst5ByIsMarried(REPO repository, List args) { - ScrollPosition scrollPosition = (ScrollPosition) args.get(0); - return repository.findFirst5ByIsMarried(false, scrollPosition); - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Window executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual( - REPO repository, List args) { - ScrollPosition scrollPosition = (ScrollPosition) args.get(0); - return repository.findFirst10ByIsMarriedGreaterThanEqual(false, scrollPosition); - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Stream dataForTestRepositoryScrollForwardAndBackwardMoving() { - - ScrollPosition beginScrollPositionInitial = - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY); - ScrollPosition beginScrollPositionIndexKey = TarantoolScrollPosition.forward(PERSON_INDEX_KEY); - - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst5ByIsMarried, - (Function, List>) - GenericRepositoryTest::expectedForwardFuncForFindFirst5ByIsMarriedInitial, - (Function, List>) - GenericRepositoryTest::expectedBackwardFuncForFindFirst5ByIsMarriedInitial, - beginScrollPositionInitial), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst5ByIsMarried, - (Function, List>) - GenericRepositoryTest::expectedForwardFuncForFindFirst5ByIsMarriedIndexKey, - (Function, List>) - GenericRepositoryTest::expectedBackwardFuncForFindFirst5ByIsMarriedIndexKey, - beginScrollPositionIndexKey), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual, - (Function, List>) - GenericRepositoryTest - ::expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial, - (Function, List>) - GenericRepositoryTest - ::expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial, - beginScrollPositionInitial), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual, - (Function, List>) - GenericRepositoryTest - ::expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey, - (Function, List>) - GenericRepositoryTest - ::expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey, - beginScrollPositionIndexKey)); - } - - @ParameterizedTest - @MethodSource("dataForTestRepositoryScrollForwardAndBackwardMoving") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryScrollForwardAndBackwardMoving( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - BiFunction, Window> executingRepositoryMethod, - Function, List> expectedForwardResultFunction, - Function, List> expectedBackwardResultFunction, - ScrollPosition beginScrollPosition) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - Window personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(beginScrollPosition)); - List forwardResult = new ArrayList<>(); - - while (!personWindow.isEmpty() && personWindow.hasNext()) { - personWindow.forEach(forwardResult::add); - ScrollPosition nextPosition = personWindow.positionAt(personWindow.size() - 1); - personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(nextPosition)); - } - personWindow.forEach(forwardResult::add); - - assertEquals(expectedForwardResultFunction.apply(persons), forwardResult); - - TarantoolScrollPosition backwardScrollPosition = - ((TarantoolScrollPosition) personWindow.positionAt(0)).reverse(); - List backwardResult = personWindow.getContent(); - Collections.reverse(backwardResult); - - personWindow = - executingRepositoryMethod.apply( - repository, Collections.singletonList(backwardScrollPosition)); - while (!personWindow.isEmpty() && personWindow.hasNext()) { - personWindow.forEach(backwardResult::add); - ScrollPosition nextPosition = personWindow.positionAt(personWindow.size() - 1); - personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(nextPosition)); - } - personWindow.forEach(backwardResult::add); - - assertEquals(expectedBackwardResultFunction.apply(persons), backwardResult); - } - - protected static > - Stream dataForTestWindowIterator() { - return Stream.of( - Arguments.of( - (BiFunction>) - (context, size) -> Collections.emptyList(), - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY), - (Function, List>) (persons) -> Collections.emptyList(), - (Function, List>) (persons) -> Collections.emptyList()), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY), - (Function, List>) (persons) -> persons, - (Function, List>) - (persons) -> { - Collections.reverse(persons); - return persons; - }), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INDEX_KEY), - (Function, List>) - GenericRepositoryTest::expectedWindowIteratorForwardFromSomeCursor, - (Function, List>) - GenericRepositoryTest::expectedWindowIteratorBackwardFromSomeCursor)); - } - - protected static , ID> - List expectedWindowIteratorForwardFromSomeCursor(List persons) { - return persons.stream() - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .collect(Collectors.toList()); - } - - protected static , ID> - List expectedWindowIteratorBackwardFromSomeCursor(List persons) { - return persons.stream() - .filter(person -> person.getId() <= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId).reversed()) - .collect(Collectors.toList()); - } - - @ParameterizedTest - @MethodSource("dataForTestWindowIterator") - , ID, REPO extends GenericPaginationMethods> - void testWithWindowIteratorMoving( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - TarantoolScrollPosition beginScrollPosition, - Function, List> expectedForwardResultFunction, - Function, List> expectedBackwardResultFunction) { - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - TarantoolWindowIterator personForwardIterator = - TarantoolWindowIterator.of( - scrollPosition -> - repository.findFirst10ByIsMarriedGreaterThanEqual(null, scrollPosition)) - .startingAt(beginScrollPosition); - - List forwardResult = new ArrayList<>(); - - while (personForwardIterator.hasNext()) { - forwardResult.add(personForwardIterator.next()); - } - - forwardResult.sort(Comparator.comparing(PERSON::getId)); - assertEquals(expectedForwardResultFunction.apply(persons), forwardResult); - - // go back - List backwardResult = new ArrayList<>(); - - TarantoolWindowIterator personBackwardIterator = - TarantoolWindowIterator.of( - scrollPosition -> - repository.findFirst10ByIsMarriedGreaterThanEqual(null, scrollPosition)) - .startingAt(beginScrollPosition.reverse()); - - while (personBackwardIterator.hasNext()) { - backwardResult.add(personBackwardIterator.next()); - } - - assertEquals(expectedBackwardResultFunction.apply(persons), backwardResult); - } - - protected static Stream dataForTestUnsupportedRepositoryMethods() { - return Stream.of(PersonRepository.class, ComplexPersonRepository.class); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestUnsupportedRepositoryMethods") - , ID, REPO extends GenericPaginationMethods> - void testUnsupportedRepositoryMethods(Class repositoryClass) { - final REPO repository = context.getBean(repositoryClass); - - assertThrows(UnsupportedOperationException.class, repository::findAll); - assertThrows(UnsupportedOperationException.class, () -> repository.findAll(Sort.unsorted())); - } - - protected static Stream dataForTestPageableWithTrueCursorAndPageNumber() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(PAGE_SIZE), - PAGES_COUNT, - PAGES_COUNT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(1, PAGE_SIZE, new Person(9, null, "User-9")), - PAGES_COUNT - 1, - PAGES_COUNT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(2, PAGE_SIZE, new Person(19, null, "User-19")), - PAGES_COUNT - 2, - PAGES_COUNT)); - } - - private static void doTestPageableWithCursorAndPageNumber( - Pageable pageable, - BiFunction> repositoryFunction, - BiConsumer>, List>> assertionAction) { - List> forwardPages = new ArrayList<>(); - - Slice page = repositoryFunction.apply(0, pageable); - - forwardPages.add(page); - - while (page.hasNext()) { - page = repositoryFunction.apply(0, page.nextOrLastPageable()); - forwardPages.add(page); - } - - List> backwardPages = new ArrayList<>(); - for (int i = forwardPages.size() - 1; i >= 0; i--) { - Slice currentPage = forwardPages.get(i); - if (currentPage.getPageable().isPaged()) { - page = currentPage; - break; - } - } - backwardPages.add(page); - - page = repositoryFunction.apply(0, page.previousOrFirstPageable()); - backwardPages.add(page); - - while (page.hasPrevious()) { - page = repositoryFunction.apply(0, page.previousOrFirstPageable()); - backwardPages.add(page); - } - - assertionAction.accept(forwardPages, backwardPages); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageableWithTrueCursorAndPageNumber") - , ID, REPO extends GenericPaginationMethods> - void testPageableWithTrueCursorAndPageNumber( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCount, - int expectedBackwardPageCount) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - backwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestPageablePageNumberLessCursor() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // fourth page - new TarantoolPageRequest<>(0, PAGE_SIZE, new Person(29, null, "User-29")), - PAGES_COUNT - 2, - PAGES_COUNT - 3, - PAGES_COUNT - 3), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // third page - new TarantoolPageRequest<>(0, PAGE_SIZE, new Person(19, null, "User-19")), - PAGES_COUNT - 1, - PAGES_COUNT - 2, - PAGES_COUNT - 2)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageablePageNumberLessCursor") - , ID, REPO extends GenericPaginationMethods> - void testPageablePageNumberLessCursor( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCountForPage, - int expectedForwardPageCountForSlice, - int expectedBackwardPageCount) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - int expectedForwardPageCount = expectedForwardPageCountForSlice; - Slice firstPageable = forwardSlice.get(0); - if (firstPageable instanceof Page) { - expectedForwardPageCount = expectedForwardPageCountForPage; - } - - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - if (firstPageable instanceof Page) { - assertTrue(forwardSlice.get(forwardSlice.size() - 1).getPageable().isUnpaged()); - forwardSlice - .subList(0, forwardSlice.size() - 1) - .forEach(p -> assertTrue(p.getPageable().isPaged())); - } else { - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - } - backwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestPageablePageNumberGreaterCursor() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // second page - new TarantoolPageRequest<>(1, PAGE_SIZE, null), - PAGES_COUNT - 1, - PAGES_COUNT, - PAGES_COUNT, - PAGES_COUNT + 1), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // fourth page - new TarantoolPageRequest<>(3, PAGE_SIZE, new Person(9, null, "User-9")), - PAGES_COUNT - 3, - PAGES_COUNT - 1, - PAGES_COUNT - 1, - PAGES_COUNT + 1)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageablePageNumberGreaterCursor") - , ID, REPO extends GenericPaginationMethods> - void testPageablePageNumberGreaterCursor( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCountForPage, - int expectedForwardPageCountForSlice, - int expectedBackwardPageCountForPage, - int expectedBackwardPageCountForSlice) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - int expectedForwardPageCount = expectedForwardPageCountForPage; - int expectedBackwardPageCount = expectedBackwardPageCountForPage; - - Slice firstPageable = forwardSlice.get(0); - if (!(firstPageable instanceof Page)) { - expectedForwardPageCount = expectedForwardPageCountForSlice; - expectedBackwardPageCount = expectedBackwardPageCountForSlice; - } - - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - assertTrue(backwardSlice.get(backwardSlice.size() - 1).getPageable().isUnpaged()); - backwardSlice - .subList(0, backwardSlice.size() - 1) - .forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - @Test - void testConcurrentDerivedMethods() { - - final byte threadCount = 3; - final ExecutorService executor = Executors.newFixedThreadPool(threadCount); - final List>> futures = new ArrayList<>(threadCount); - final PersonRepository repository = context.getBean(PersonRepository.class); - - final List insertedPersons = - personGenerateAndInsertFunction.apply(context, (int) threadCount); - final Person firstPerson = insertedPersons.get(0); - final Person secondPerson = insertedPersons.get(1); - final Person thirdPerson = insertedPersons.get(2); - - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findPersonById(firstPerson.getId()), executor)); - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findByIsMarried(secondPerson.getIsMarried()), executor)); - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findByName(thirdPerson.getName()), executor)); - - CompletableFuture.allOf(futures.toArray(new CompletableFuture[] {})).join(); - - assertEquals(firstPerson, futures.get(0).join().get(0)); - assertEquals(secondPerson, futures.get(1).join().get(0)); - assertEquals(thirdPerson, futures.get(2).join().get(0)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/GenericTarantoolTemplateTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/GenericTarantoolTemplateTest.java deleted file mode 100644 index 2913efd9..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/GenericTarantoolTemplateTest.java +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.integration.crud; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.core.UncategorizedKeyValueException; - -import static io.tarantool.spring.data.ProxyTarantoolCrudKeyValueAdapter.POTENTIAL_PERFORMANCE_ISSUES_EXCEPTION_MESSAGE; -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.generateAndInsertPersons; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.generateComplexPersons; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.mapping.crud.CrudException; -import io.tarantool.spring.data31.core.TarantoolTemplate; -import io.tarantool.spring.data31.utils.entity.ComplexPerson; -import io.tarantool.spring.data31.utils.entity.ComplexPersonWithIncorrectPK; -import io.tarantool.spring.data31.utils.entity.ComplexPersonWithJsonFormatVariantPK; -import io.tarantool.spring.data31.utils.entity.CompositePersonKey; -import io.tarantool.spring.data31.utils.entity.CompositePersonKeyWithJsonFormat; -import io.tarantool.spring.data31.utils.entity.Person; - -abstract class GenericTarantoolTemplateTest extends CrudConfigurations { - - @Autowired protected TarantoolTemplate tarantoolTemplate; - - @Test - void testGetAllOf() { - final Throwable throwable = - assertThrows( - UncategorizedKeyValueException.class, () -> tarantoolTemplate.findAll(Person.class)) - .getCause(); - - assertEquals(UnsupportedOperationException.class, throwable.getClass()); - assertEquals(POTENTIAL_PERFORMANCE_ISSUES_EXCEPTION_MESSAGE, throwable.getMessage()); - } - - static Stream dataForInsert() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - return Stream.of( - Arguments.of( - simpleKeyPerson, - (Function) (kv) -> kv.insert(simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - compositeKeyPerson, - (Function) (kv) -> kv.insert(compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForInsert") - void testKVTemplateInsert( - Object result, - Function callingMethod, - Function> selectAction) { - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForInsertById() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - return Stream.of( - Arguments.of( - simpleKeyPerson, - (Function) (kv) -> kv.insert(simpleKey, simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - compositeKeyPerson, - (Function) - (kv) -> kv.insert(compositeKey, compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForInsertById") - void testKVTemplateInsertById( - Object result, - Function callingMethod, - Function> selectAction) { - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForUpdate() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - Consumer prepareActionForSimpleKeyPerson = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer prepareActionForCompositeKeyPerson = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - return Stream.of( - Arguments.of( - prepareActionForSimpleKeyPerson, - simpleKeyPerson, - (Function) (kv) -> kv.update(simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - prepareActionForCompositeKeyPerson, - compositeKeyPerson, - (Function) (kv) -> kv.update(compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForUpdate") - void testKVTemplateUpdate( - Consumer prepareAction, - Object result, - Function callingMethod, - Function> selectAction) { - prepareAction.accept(client); - - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForUpdateById() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - Consumer prepareActionForSimpleKeyPerson = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer prepareActionForCompositeKeyPerson = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - return Stream.of( - Arguments.of( - prepareActionForSimpleKeyPerson, - simpleKeyPerson, - (Function) (kv) -> kv.update(simpleKey, simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - prepareActionForCompositeKeyPerson, - compositeKeyPerson, - (Function) - (kv) -> kv.update(compositeKey, compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForUpdateById") - void testKVTemplateUpdateById( - Consumer prepareAction, - Object result, - Function callingMethod, - Function> selectAction) { - prepareAction.accept(client); - - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForDelete() { - - Runnable simpleKeyPrepareAction = () -> generatePersons(PERSONS_COUNT); - Runnable compositeKeyPrepareAction = () -> generateComplexPersons(PERSONS_COUNT); - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(Person.class), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(ComplexPerson.class), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDelete") - void testKVTemplateDelete( - Runnable prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.run(); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForDeleteEntities() { - - Person simpleKeyPerson = new Person(0, true, "0"); - ComplexPerson compositeKeyPerson = new ComplexPerson(0, UUID.randomUUID(), true, "0"); - - Consumer simpleKeyPrepareAction = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer compositeKeyPrepareAction = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(simpleKeyPerson), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(compositeKeyPerson), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDeleteEntities") - void testKVTemplateDeleteEntities( - Consumer prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.accept(client); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForDeleteEntitiesById() { - - Person simpleKeyPerson = new Person(0, true, "0"); - ComplexPerson compositeKeyPerson = new ComplexPerson(0, UUID.randomUUID(), true, "0"); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Consumer simpleKeyPrepareAction = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer compositeKeyPrepareAction = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(simpleKey, Person.class), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(compositeKey, ComplexPerson.class), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDeleteEntitiesById") - void testKVTemplateDeleteEntitiesById( - Consumer prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.accept(client); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForCount() { - - Consumer simpleKeyPrepareAction = - (client) -> generateAndInsertPersons(PERSONS_COUNT, client); - - Consumer compositeKeyPrepareAction = - (client) -> generateAndInsertComplexPersons(PERSONS_COUNT, client); - - return Stream.of( - Arguments.of( - PERSONS_COUNT, - simpleKeyPrepareAction, - (Function) (kv) -> kv.count(Person.class)), - Arguments.of( - PERSONS_COUNT, - compositeKeyPrepareAction, - (Function) (kv) -> kv.count(ComplexPerson.class))); - } - - @ParameterizedTest - @MethodSource("dataForCount") - void testCount( - long expectedCount, - Consumer prepareAction, - Function callingMethod) { - prepareAction.accept(client); - assertEquals(expectedCount, callingMethod.apply(tarantoolTemplate)); - } - - @Test - void testCompositeKeyWithJsonFormat() { - ComplexPersonWithJsonFormatVariantPK complexPersonWithJsonFormatVariantPK = - new ComplexPersonWithJsonFormatVariantPK(0, UUID.randomUUID(), null, "0"); - - assertEquals( - complexPersonWithJsonFormatVariantPK, - tarantoolTemplate.insert(complexPersonWithJsonFormatVariantPK)); - - CompositePersonKeyWithJsonFormat key = - new CompositePersonKeyWithJsonFormat( - complexPersonWithJsonFormatVariantPK.getId(), - complexPersonWithJsonFormatVariantPK.getSecondId()); - Optional foundPerson = - tarantoolTemplate.findById(key, ComplexPersonWithJsonFormatVariantPK.class); - assertTrue(foundPerson.isPresent()); - assertEquals(complexPersonWithJsonFormatVariantPK, foundPerson.get()); - } - - @Test - void testCompositeKeyWithoutJsonFormat() { - ComplexPersonWithIncorrectPK complexPersonWithIncorrectPK = - new ComplexPersonWithIncorrectPK(0, UUID.randomUUID(), null, "0"); - - Throwable exception = - assertThrows( - UncategorizedKeyValueException.class, - () -> tarantoolTemplate.insert(complexPersonWithIncorrectPK)) - .getRootCause(); - assertInstanceOf(CrudException.class, exception); - } - - public static Stream dataForTestCompositeKeyWithConcurrency() { - final List threadsCount = Arrays.asList(1, 2, 3); - final List tuplesCount = Arrays.asList(20, 120, 360, 1200, 3000); - final List totalArguments = new ArrayList<>(); - - for (final Integer threadCount : threadsCount) { - for (final Integer tupleCount : tuplesCount) { - totalArguments.add(Arguments.of(threadCount, tupleCount)); - } - } - - return totalArguments.stream(); - } - - @DisplayName("Checking the insertion of an entity with a composite key") - @ParameterizedTest(autoCloseArguments = false, name = "thread count: {0}, tuples count: {1}") - @MethodSource("dataForTestCompositeKeyWithConcurrency") - void testCompositeKeyWithConcurrency(int threadsCount, int tuplesCount) { - final ExecutorService executor = Executors.newFixedThreadPool(threadsCount); - final List> futures = new ArrayList<>(); - final List tuples = generateComplexPersons(tuplesCount); - - for (final ComplexPerson tuple : tuples) { - futures.add( - CompletableFuture.supplyAsync(() -> this.tarantoolTemplate.insert(tuple), executor)); - } - - CompletableFuture.allOf(futures.toArray(new CompletableFuture[] {})).join(); - - for (int i = 0; i < tuplesCount; i++) { - assertEquals(tuples.get(i), futures.get(i).join()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/RepositoryConfigurationExtensionTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/RepositoryConfigurationExtensionTest.java deleted file mode 100644 index bc20f88a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/RepositoryConfigurationExtensionTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.integration.crud; - -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.client.factory.TarantoolBoxClientBuilder; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.spring.data31.integration.BaseIntegrationTest; -import io.tarantool.spring.data31.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data31.repository.config.TarantoolRepositoryConfigurationExtension; - -class RepositoryConfigurationExtensionTest extends BaseIntegrationTest { - - private static TarantoolRepositoryConfigurationExtension defaultExtension; - - @BeforeAll - static void setUp() throws IOException { - BaseIntegrationTest.beforeAll(); - defaultExtension = new TarantoolRepositoryConfigurationExtension(); - } - - @Test - void testGetModuleName() { - assertEquals("Tarantool", defaultExtension.getModuleName()); - } - - @Test - void testGetModulePrefix() { - assertEquals("tarantool", defaultExtension.getModulePrefix()); - } - - @Test - void testGetDefaultKeyValueTemplateRef() { - assertEquals( - DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF, defaultExtension.getDefaultKeyValueTemplateRef()); - } - - @Test - void testRegisterBeansForRootWithDefaultConfig() { - final ApplicationContext context = new AnnotationConfigApplicationContext(DefaultConfig.class); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF)); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF)); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF)); - } - - @Test - void testRegisterBeansForRootWithCustomClientConfigShouldThrows() { - final Throwable throwable = - assertThrows( - IllegalArgumentException.class, - () -> new AnnotationConfigApplicationContext(BoxNonSupportConfig.class)); - - final String exceptionMessage = "The Box client is not yet supported."; - assertEquals(exceptionMessage, throwable.getMessage()); - } - - private static TarantoolCrudClientBuilder getCrudClientSettings() { - return TarantoolFactory.crud() - .withHost(getHost()) - .withPort(getPort()) - .withUser(getUsername()) - .withPassword(getPassword()); - } - - private static TarantoolBoxClientBuilder getBoxClientSettings() { - return TarantoolFactory.box().withHost(getHost()).withPort(getPort()); - } - - @EnableTarantoolRepositories - static class DefaultConfig { - - @Bean - public TarantoolCrudClientBuilder clientSettings() { - return getCrudClientSettings(); - } - } - - @EnableTarantoolRepositories(clientType = ClientType.BOX) - static class BoxNonSupportConfig { - - @Bean - public TarantoolBoxClientBuilder clientSettings() { - return getBoxClientSettings(); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/RepositoryViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/RepositoryViaPropertiesTest.java deleted file mode 100644 index f3dd0011..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/RepositoryViaPropertiesTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data31.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; - -@SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) -class RepositoryViaPropertiesTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/TarantoolTemplateViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/TarantoolTemplateViaPropertiesTest.java deleted file mode 100644 index 5505a7b2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/TarantoolTemplateViaPropertiesTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data31.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; - -@SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) -class TarantoolTemplateViaPropertiesTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolCriteriaTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolCriteriaTest.java deleted file mode 100644 index d7bdfebe..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolCriteriaTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.util.Arrays; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; - -import static io.tarantool.client.crud.ConditionOperator.EQ; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.spring.data.query.Conditions; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolCriteriaTest { - - @Test - void testAddAndGetConditions() { - final TarantoolCriteria tarantoolCriteria = new TarantoolCriteria(); - final String identifier = "name"; - final Object value = "value"; - final String operator = "=="; - - final Condition condition = Condition.create(operator, identifier, value); - assertEquals(operator, condition.getOperator()); - assertEquals(identifier, condition.getFieldIdentifier()); - assertEquals(value, condition.getValue()); - - final Condition conditionConstructor = new Condition(operator, identifier, value); - assertEquals(operator, conditionConstructor.getOperator()); - assertEquals(identifier, conditionConstructor.getFieldIdentifier()); - assertEquals(value, conditionConstructor.getValue()); - - final Condition conditionFromBuilder = - Condition.builder() - .withOperator(operator) - .withValue(value) - .withFieldIdentifier(identifier) - .build(); - assertEquals(operator, conditionFromBuilder.getOperator()); - assertEquals(identifier, conditionFromBuilder.getFieldIdentifier()); - assertEquals(value, conditionFromBuilder.getValue()); - - final Condition conditionWithEnum = Condition.create(EQ, identifier, value); - assertEquals(operator, conditionWithEnum.getOperator()); - assertEquals(identifier, conditionWithEnum.getFieldIdentifier()); - assertEquals(value, conditionWithEnum.getValue()); - - final Condition conditionConstructorWithEnum = new Condition(EQ, identifier, value); - assertEquals(operator, conditionConstructorWithEnum.getOperator()); - assertEquals(identifier, conditionConstructorWithEnum.getFieldIdentifier()); - assertEquals(value, conditionConstructorWithEnum.getValue()); - - final Condition conditionFromBuilderWithEnum = - Condition.builder() - .withOperator(EQ) - .withValue(value) - .withFieldIdentifier(identifier) - .build(); - assertEquals(operator, conditionFromBuilderWithEnum.getOperator()); - assertEquals(identifier, conditionFromBuilderWithEnum.getFieldIdentifier()); - assertEquals(value, conditionFromBuilderWithEnum.getValue()); - - tarantoolCriteria.addCondition(condition); - tarantoolCriteria.addCondition(conditionConstructor); - tarantoolCriteria.addCondition(conditionFromBuilder); - - tarantoolCriteria.addCondition(conditionWithEnum); - tarantoolCriteria.addCondition(conditionConstructorWithEnum); - tarantoolCriteria.addCondition(conditionFromBuilderWithEnum); - - final Conditions expectedConditions = new Conditions(); - expectedConditions.addAll( - Arrays.asList( - condition, - conditionConstructor, - conditionFromBuilder, - conditionWithEnum, - conditionConstructorWithEnum, - conditionFromBuilderWithEnum)); - - assertEquals(expectedConditions, tarantoolCriteria.getConditions()); - } - - @Test - void testFirst() { - final TarantoolCriteria criteria = new TarantoolCriteria(); - criteria.withFirst(1); - - final String key = "first"; - SelectOptions options = criteria.getOptions(); - assertEquals(1, options.getOptions().get(key)); - - criteria.clear(); - criteria.withFirst(-1); - options = criteria.getOptions(); - assertEquals(-1, options.getOptions().get(key)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolKeysetScrollPositionTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolKeysetScrollPositionTest.java deleted file mode 100644 index ed07cb5b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolKeysetScrollPositionTest.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.UUID; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.function.Executable; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.ScrollPosition; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.Pair; - -class TarantoolKeysetScrollPositionTest { - - private static final Pair INDEX_KEY = Pair.of("pk", 123); - - private static final Pair INDEX_KEY_WITH_NULL_VALUE = Pair.of("pk", null); - - static Stream dataForTestTarantoolScrollPositionCreateDoesntThrow() { - return Stream.of( - () -> TarantoolScrollPosition.forward(INDEX_KEY), - () -> TarantoolScrollPosition.forward(INDEX_KEY_WITH_NULL_VALUE), - () -> TarantoolScrollPosition.backward(INDEX_KEY), - () -> TarantoolScrollPosition.backward(INDEX_KEY_WITH_NULL_VALUE)); - } - - @ParameterizedTest - @MethodSource("dataForTestTarantoolScrollPositionCreateDoesntThrow") - void testTarantoolScrollPositionCreateDoesntThrow(Executable scrollPositionCreateAction) { - assertDoesNotThrow(scrollPositionCreateAction); - } - - static Stream dataForTestTarantoolScrollPositionCreateThrows() { - return Stream.of( - () -> TarantoolScrollPosition.forward(null), () -> TarantoolScrollPosition.backward(null)); - } - - @ParameterizedTest - @MethodSource("dataForTestTarantoolScrollPositionCreateThrows") - void testTarantoolScrollPositionCreateThrows(Executable scrollPositionCreateAction) { - assertThrows(IllegalArgumentException.class, scrollPositionCreateAction); - } - - static Stream dataForTestEqualsAndHashCode() { - - List equalScrollPositionsWithKey = - Arrays.asList( - TarantoolScrollPosition.forward(INDEX_KEY), TarantoolScrollPosition.forward(INDEX_KEY)); - - TarantoolScrollPosition notEqualScrollPosition = - TarantoolScrollPosition.forward(INDEX_KEY_WITH_NULL_VALUE); - - final int ITERATION_COUNT = 100; - - return Stream.of( - Arguments.of(equalScrollPositionsWithKey, notEqualScrollPosition, ITERATION_COUNT), - Arguments.of(equalScrollPositionsWithKey, null, ITERATION_COUNT)); - } - - @ParameterizedTest - @MethodSource("dataForTestEqualsAndHashCode") - void testEqualsAndHashCode( - List scrollPositions, - ScrollPosition notEqualScrollPosition, - int iterationCount) { - for (int i = 0; i < iterationCount; i++) { - for (ScrollPosition scrollPosition : scrollPositions) { - for (ScrollPosition otherScrollPosition : scrollPositions) { - assertEquals(scrollPosition, otherScrollPosition); - assertEquals(scrollPosition.hashCode(), otherScrollPosition.hashCode()); - } - assertNotEquals(scrollPosition, notEqualScrollPosition); - if (notEqualScrollPosition != null) { - assertNotEquals(scrollPosition.hashCode(), notEqualScrollPosition.hashCode()); - } - } - } - } - - static Stream dataForTestIsInitial() { - var startingIndex = Pair.of("pk", Collections.emptyList()); - var complexIndex = Pair.of("pk", Arrays.asList(1, UUID.randomUUID())); - Object nonNullCursor = Arrays.asList(1, 2, 3, 4); - return Stream.of( - Arguments.of(TarantoolScrollPosition.backward(INDEX_KEY), false), - Arguments.of(TarantoolScrollPosition.forward(INDEX_KEY), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, null), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, nonNullCursor), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, nonNullCursor), false), - Arguments.of(TarantoolScrollPosition.backward(startingIndex), true), - Arguments.of(TarantoolScrollPosition.forward(startingIndex), true), - Arguments.of(new TarantoolKeysetScrollPosition(startingIndex, FORWARD, null), true), - Arguments.of(new TarantoolKeysetScrollPosition(startingIndex, BACKWARD, null), true), - Arguments.of( - new TarantoolKeysetScrollPosition(startingIndex, FORWARD, nonNullCursor), false), - Arguments.of( - new TarantoolKeysetScrollPosition(startingIndex, BACKWARD, nonNullCursor), false), - Arguments.of(TarantoolScrollPosition.backward(complexIndex), false), - Arguments.of(TarantoolScrollPosition.forward(complexIndex), false)); - } - - @ParameterizedTest - @MethodSource("dataForTestIsInitial") - void testIsInitial(ScrollPosition scrollPosition, boolean expectedIsInitial) { - assertEquals(scrollPosition.isInitial(), expectedIsInitial); - } - - static Stream dataForTestGetCursor() { - var cursor = String.valueOf(2); - return Stream.of( - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), null), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, cursor), cursor)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetCursor") - void testGetCursor(TarantoolKeysetScrollPosition scrollPosition, Object expectedCursor) { - assertEquals(expectedCursor, scrollPosition.getCursor()); - } - - static Stream dataForTestGetKeyIndex() { - return Stream.of( - Arguments.of(TarantoolScrollPosition.forward(INDEX_KEY), INDEX_KEY), - Arguments.of(TarantoolScrollPosition.backward(INDEX_KEY), INDEX_KEY)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetKeyIndex") - void testGetKeyIndex( - TarantoolKeysetScrollPosition scrollPosition, Pair expectedIndexKey) { - assertEquals(expectedIndexKey, scrollPosition.getIndexKey()); - } - - static Stream dataForTestGetDirection() { - return Stream.of( - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), FORWARD), - Arguments.of( - new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, String.valueOf(2)), BACKWARD)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetDirection") - void testGetDirection( - TarantoolKeysetScrollPosition scrollPosition, PaginationDirection expectedDirection) { - assertEquals(expectedDirection, scrollPosition.getDirection()); - } - - static Stream dataForTestReverse() { - Object someKey = String.valueOf(1); - var indexKeyAfterReverse = Pair.of(INDEX_KEY.getFirst(), INDEX_KEY.getSecond()); - - return Stream.of( - Arguments.of( - TarantoolScrollPosition.forward(INDEX_KEY), - TarantoolScrollPosition.backward(indexKeyAfterReverse)), - Arguments.of( - new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, someKey), - new TarantoolKeysetScrollPosition(indexKeyAfterReverse, BACKWARD, someKey))); - } - - @ParameterizedTest - @MethodSource("dataForTestReverse") - void testGetReverse( - TarantoolScrollPosition scrollPosition, - TarantoolKeysetScrollPosition expectedReversedPosition) { - assertEquals(expectedReversedPosition, scrollPosition.reverse()); - } - - static Stream dataForTestIsScrollsBackward() { - return Stream.of( - Arguments.of( - TarantoolScrollPosition.forward(Pair.of("pk", Collections.emptyList())), false), - Arguments.of( - TarantoolScrollPosition.backward(Pair.of("pk", Collections.emptyList())), true)); - } - - @ParameterizedTest - @MethodSource("dataForTestIsScrollsBackward") - void testIsScrollsBackward(TarantoolScrollPosition position, boolean expectedIsScrollsBackward) { - assertEquals(expectedIsScrollsBackward, position.isScrollsBackward()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolPageImplTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolPageImplTest.java deleted file mode 100644 index 4b683b35..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolPageImplTest.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data31.utils.entity.Person; - -class TarantoolPageImplTest { - - private static final List PERSONS = generatePersons(PERSONS_COUNT); - - private static final int DEFAULT_PAGE_SIZE_PER_TEST_CLASS = 10; - - private static final int DEFAULT_PAGE_NUMBER_PER_TEST_CLASS = 0; - - private static final Pageable FIRST_PAGE_PAGEABLE_PER_TEST_CLASS = - new TarantoolPageRequest<>( - DEFAULT_PAGE_NUMBER_PER_TEST_CLASS, DEFAULT_PAGE_SIZE_PER_TEST_CLASS, null); - - private static final long MULTIPLIER = 2L; - - private static final BiFunction GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE = - (pageSize, operator) -> { - switch (operator) { - // pageSize > totalPageCount - case ">": - { - return pageSize / MULTIPLIER; - } - // pageSize < totalPageCount - case "<": - { - return MULTIPLIER * pageSize; - } - // pageSize == totalPageCount - case "==": - { - return Long.valueOf(pageSize); - } - default: - throw new IllegalArgumentException("The passed option isn't supported"); - } - }; - - private static final List EMPTY_CONTENT = Collections.emptyList(); - - protected static Stream dataForTestConstructors() { - TarantoolPageable> pageable = - new TarantoolPageRequest<>(0, DEFAULT_PAGE_SIZE_PER_TEST_CLASS, null); - - long personsSize = PERSONS.size(); - - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>(PERSONS, pageable, personsSize), - PERSONS.size() / DEFAULT_PAGE_SIZE_PER_TEST_CLASS, - personsSize), - Arguments.of(new TarantoolPageImpl<>(PERSONS), 1, personsSize), - Arguments.of(new TarantoolPageImpl<>(), 1, 0L)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructors") - void testConstructors(Page> page, int totalPages, long totalElements) { - assertEquals(totalPages, page.getTotalPages()); - assertEquals(totalElements, page.getTotalElements()); - } - - static Stream dataForTestConstructorsThrowsIllegalArgumentException() { - final class DummyTarantoolPageRequest implements Pageable { - - @Override - public int getPageNumber() { - return 0; - } - - @Override - public int getPageSize() { - return 0; - } - - @Override - public long getOffset() { - return 0L; - } - - @Override - public Sort getSort() { - return null; - } - - @Override - public Pageable next() { - return null; - } - - @Override - public Pageable previousOrFirst() { - return null; - } - - @Override - public Pageable first() { - return null; - } - - @Override - public Pageable withPage(int pageNumber) { - return null; - } - - @Override - public boolean hasPrevious() { - return false; - } - } - - Pageable dummyPageable = new DummyTarantoolPageRequest(); - - return Stream.of( - Arguments.of(null, null, "Content must not be null"), - Arguments.of(Collections.emptyList(), null, "Pageable must not be null"), - Arguments.of( - Collections.emptyList(), - dummyPageable, - "Pageable must be TarantoolPageable or Unpaged type")); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructorsThrowsIllegalArgumentException") - void testConstructors_throws_IllegalArgumentException( - List content, Pageable pageable, String errorMsg) { - assertThrows( - IllegalArgumentException.class, - () -> new TarantoolPageImpl<>(content, pageable, 0L), - errorMsg); - } - - static Stream dataForTestGetTotalPages() { - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, ">")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "<")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - PERSONS.size() / FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, ">")), - 0), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "<")), - 0), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "==")), - 0)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTotalPages") - void testGetTotalPages(Page page, long totalPagesCount) { - assertEquals(totalPagesCount, page.getTotalPages()); - } - - static Stream dataForTestGetTotalElements() { - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() / MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() * MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - PERSONS.size()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() * MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTotalElements") - void testGetTotalElements(Page page, long totalElementCount) { - assertEquals(totalElementCount, page.getTotalElements()); - } - - static Stream dataForTestHasNext() { - return Stream.of( - Arguments.of( - false, - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())), - Arguments.of( - true, - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - MULTIPLIER * FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())), - Arguments.of( - false, - new TarantoolPageImpl<>( - PERSONS, - Pageable.unpaged(), - MULTIPLIER * FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()))); - } - - @ParameterizedTest - @MethodSource("dataForTestHasNext") - void testHasNext(boolean exceptedBool, Page page) { - assertEquals(exceptedBool, page.hasNext()); - } - - @ParameterizedTest - @MethodSource("dataForTestHasNext") - void testIsLast(boolean notEqualBool, Page page) { - assertNotEquals(notEqualBool, page.isLast()); - } - - static Stream dataForTestMap() { - List exceptedNames = PERSONS.stream().map(Person::getName).collect(Collectors.toList()); - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - exceptedNames, - (Function) Person::getName)); - } - - @ParameterizedTest - @MethodSource("dataForTestMap") - void testMap(Page page, List exceptedNames, Function mapFunction) { - List names = page.map(mapFunction).toList(); - assertEquals(exceptedNames, names); - } - - static Stream dataForTestEqualsAndHashCode() { - List> equalPages = - Arrays.asList( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())); - - final int ITERATION_COUNT = 100; - - return Stream.of( - Arguments.of( - equalPages, - new TarantoolPageImpl<>(EMPTY_CONTENT, Pageable.unpaged(), 150), - ITERATION_COUNT), - Arguments.of(equalPages, null, ITERATION_COUNT)); - } - - @ParameterizedTest - @MethodSource("dataForTestEqualsAndHashCode") - void testEqualsAndHashCode(List> pages, Page notEqualPage, int iterationCount) { - for (int i = 0; i < iterationCount; i++) { - for (Page page : pages) { - for (Page otherPage : pages) { - assertEquals(page, otherPage); - assertEquals(page.hashCode(), otherPage.hashCode()); - } - assertNotEquals(page, notEqualPage); - if (notEqualPage != null) { - assertNotEquals(page.hashCode(), notEqualPage.hashCode()); - } - } - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolPageRequestTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolPageRequestTest.java deleted file mode 100644 index b190c548..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolPageRequestTest.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.util.Arrays; -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.AbstractPageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data31.utils.entity.Person; - -class TarantoolPageRequestTest { - - private static final int PAGE_SIZE = 10; - - private static final Person CURSOR = new Person(0, true, "0"); - - private static final int PAGE_NUMBER = 0; - - protected static Stream dataForTestConstructors() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - null, - FORWARD), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - CURSOR, - FORWARD), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, null), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - null, - FORWARD)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructors") - void testConstructors( - Supplier>> constructorGenerator, - int pageNumber, - int size, - Sort sort, - GenericPerson cursor, - PaginationDirection direction) { - TarantoolPageable> pageable = constructorGenerator.get(); - - assertEquals(size, pageable.getPageSize()); - assertEquals(pageNumber, pageable.getPageNumber()); - assertEquals(sort, pageable.getSort()); - assertEquals(cursor, pageable.getTupleCursor()); - assertEquals(direction, pageable.getPaginationDirection()); - } - - protected static Stream dataTestGetSort() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - Sort.unsorted()), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - Sort.unsorted())); - } - - @ParameterizedTest - @MethodSource("dataTestGetSort") - void testGetSort(Supplier>> constructorGenerator, Sort sort) { - Pageable pageable = constructorGenerator.get(); - assertEquals(sort, pageable.getSort()); - } - - protected static Stream dataForTestGetTupleCursor() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - null), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTupleCursor") - void testGetTupleCursor( - Supplier>> constructorGenerator, GenericPerson person) { - TarantoolPageable> pageable = constructorGenerator.get(); - assertEquals(person, pageable.getTupleCursor()); - } - - protected static Stream dataForTestNext() { - final Person NEXT_CURSOR = - new Person(CURSOR.getId() + PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), CURSOR, NEXT_CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataForTestNext") - void testNext( - TarantoolPageable> pageable, - GenericPerson cursor, - GenericPerson nextCursor) { - assertEquals(cursor, pageable.getTupleCursor()); - - TarantoolPageable> nextPageable = pageable.next(nextCursor); - assertEquals(nextCursor, nextPageable.getTupleCursor()); - - assertEquals(pageable.getPageSize(), nextPageable.getPageSize()); - assertEquals(pageable.getPageNumber() + 1, nextPageable.getPageNumber()); - assertEquals(pageable.getSort(), nextPageable.getSort()); - assertEquals(pageable.getOffset() + PAGE_SIZE, nextPageable.getOffset()); - } - - @Test - void testNextUnsupported() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::next); - } - - protected static Stream dataTestGetPaginationDirection() { - final Person PREV_CURSOR = new Person(CURSOR.getId(), CURSOR.getIsMarried(), CURSOR.getName()); - final Person NEXT_CURSOR = - new Person(PREV_CURSOR.getId() + PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, NEXT_CURSOR), NEXT_CURSOR, PREV_CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataTestGetPaginationDirection") - void testGetPaginationDirection( - TarantoolPageable> pageable, - GenericPerson nextCursor, - GenericPerson prevCursor) { - - assertEquals(FORWARD, pageable.getPaginationDirection()); - - TarantoolPageable> prevPageable = pageable.previousOrFirst(prevCursor); - assertEquals(PaginationDirection.BACKWARD, prevPageable.getPaginationDirection()); - - TarantoolPageable> nextPageable = prevPageable.next(nextCursor); - assertEquals(FORWARD, nextPageable.getPaginationDirection()); - assertEquals(pageable, nextPageable); - } - - protected static Stream dataTestFirst() { - final Person CURSOR = new Person(2 * PAGE_SIZE, true, "name"); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(0, PAGE_SIZE, null))); - } - - @ParameterizedTest - @MethodSource("dataTestFirst") - void testFirst( - TarantoolPageable> pageable, - TarantoolPageable> exceptedFirstPageable) { - assertEquals(exceptedFirstPageable, pageable.first()); - } - - @Test - void testWithPage() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, () -> pageable.withPage(100)); - } - - protected static Stream dataTestPreviousOrFirst() { - final Person CURSOR = new Person(PAGE_SIZE, true, "name"); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, CURSOR), - new Person(CURSOR.getId() - PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()))); - } - - @ParameterizedTest - @MethodSource("dataTestPreviousOrFirst") - void testPreviousOrFirst( - TarantoolPageable> pageable, GenericPerson prevCursor) { - - TarantoolPageable> prevPageable = pageable.previousOrFirst(prevCursor); - - assertNotEquals(pageable, prevPageable); - assertEquals(pageable.getPageSize(), prevPageable.getPageSize()); - assertEquals(pageable.getOffset() - PAGE_SIZE, prevPageable.getOffset()); - assertEquals(pageable.getSort(), prevPageable.getSort()); - assertEquals(pageable.getPageNumber() - 1, prevPageable.getPageNumber()); - - // here will be first with null cursor - TarantoolPageable> firstPageable = prevPageable.previousOrFirst(prevCursor); - assertNull(firstPageable.getTupleCursor()); - } - - @Test - void testPreviousOrFirstUnsupported() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::previousOrFirst); - } - - @Test - void testPreviousUnsupported() { - AbstractPageRequest pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::previous); - } - - protected static Stream dataForTestEquals() { - return Stream.of( - Arguments.of( - Arrays.asList( - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR)), - new TarantoolPageRequest<>(PAGE_SIZE))); - } - - @ParameterizedTest - @MethodSource("dataForTestEquals") - void testEquals( - List>> equalPageableList, - TarantoolPageable> notEqualPageable) { - - assertTrue(equalPageableList.size() > 0); - final int COUNT = 10; - - for (int i = 0; i < COUNT; i++) { - for (TarantoolPageable> pageable : equalPageableList) { - for (TarantoolPageable> secondPageable : equalPageableList) { - assertEquals(pageable, secondPageable); - } - assertNotEquals(pageable, null); - assertNotEquals(pageable, notEqualPageable); - } - } - } - - @ParameterizedTest - @MethodSource("dataForTestEquals") - void testHashCode( - List>> equalPageableList, - TarantoolPageable> notEqualPageable) { - - for (TarantoolPageable> pageable : equalPageableList) { - for (TarantoolPageable> secondPageable : equalPageableList) { - assertEquals(pageable.hashCode(), secondPageable.hashCode()); - } - assertNotEquals(pageable.hashCode(), notEqualPageable.hashCode()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolSliceTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolSliceTest.java deleted file mode 100644 index 184718f1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/query/TarantoolSliceTest.java +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.function.Executable; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.spring.data31.utils.entity.Person; - -public class TarantoolSliceTest { - - private static final int PAGE_SIZE = 10; - - private static final int PAGE_NUMBER = 0; - - private static final Person SOME_CURSOR = new Person(0, true, "0"); - - private static List PERSONS; - - private static final Pageable SOME_PAGEABLE = - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR); - - @BeforeAll - static void setUp() { - PERSONS = generatePersons(PERSONS_COUNT); - } - - static Stream dataForTestConstructorsShouldThrow() { - Pageable tarantoolPageable = new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR); - Pageable notTarantoolPageable = Pageable.ofSize(PAGE_SIZE); - return Stream.of( - Arguments.of(null, tarantoolPageable, false), - Arguments.of(null, tarantoolPageable, true), - Arguments.of(PERSONS, null, false), - Arguments.of(PERSONS, null, true), - Arguments.of(PERSONS, notTarantoolPageable, false), - Arguments.of(PERSONS, notTarantoolPageable, true)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructorsShouldThrow") - public void testConstructorsShouldThrow(List content, Pageable pageable, boolean hasNext) { - assertThrows( - IllegalArgumentException.class, () -> new TarantoolSliceImpl<>(content, pageable, hasNext)); - } - - static Stream dataForTestConstructorsDoesntThrow() { - return Stream.of( - () -> new TarantoolSliceImpl<>(PERSONS), - () -> new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - () -> new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestConstructorsDoesntThrow") - public void testConstructorsDoesntThrow(Executable runTestCase) { - assertDoesNotThrow(runTestCase); - } - - static Stream dataForTestGetNumber() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getPageNumber()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetNumber") - public void testGetNumber(Slice slice, int expectedPageNumber) { - assertEquals(expectedPageNumber, slice.getNumber()); - } - - static Stream dataForTestGetSize() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getPageSize()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS.size()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), - SOME_PAGEABLE.getPageSize()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetSize") - public void testGetSize(Slice slice, int expectedSize) { - assertEquals(expectedSize, slice.getSize()); - } - - static Stream dataForTestGetNumberOfElements() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), PERSONS.size()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS.size()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), 0), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetNumberOfElements") - public void testGetNumberOfElements(Slice slice, int expectedNumberOfElements) { - assertEquals(expectedNumberOfElements, slice.getNumberOfElements()); - } - - static Stream dataForTestGetContent() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), PERSONS), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), - Collections.emptyList()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Collections.emptyList())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetContent") - public void testGetContent(Slice slice, List expectedContent) { - assertEquals(expectedContent, slice.getContent()); - } - - static Stream dataForTestHasContent() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), true), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), false), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasContent") - void testHasContent(Slice slice, boolean expectedHasContent) { - assertEquals(expectedHasContent, slice.hasContent()); - } - - static Stream dataForTestGetSort() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getSort()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Sort.unsorted())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetSort") - void testGetSort(Slice slice, Sort expectedSort) { - assertEquals(expectedSort, slice.getSort()); - } - - static Stream dataForTestIsFirst() { - final int MIDDLE_PAGE_NUMBER = 2; - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), true), - true), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), true), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - true), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), true)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestIsFirst") - void testIsFirst(Slice slice, boolean expectedIsFirst) { - assertEquals(expectedIsFirst, slice.isFirst()); - } - - static Stream dataForTestIsLast() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), false), - // last imitation - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, false), true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), true), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), true), - // last imitation - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, false), true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), true)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestIsLast") - void testIsLast(Slice slice, boolean expectedIsLast) { - assertEquals(expectedIsLast, slice.isLast()); - } - - static Stream dataForTestHasNext() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, new TarantoolPageRequest<>(PAGE_SIZE), true), true), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, new TarantoolPageRequest<>(PAGE_SIZE), false), false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), new TarantoolPageRequest<>(PAGE_SIZE), true), - false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), new TarantoolPageRequest<>(PAGE_SIZE), false), - false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasNext") - void testHasNext(Slice slice, boolean expectedHasNext) { - assertEquals(expectedHasNext, slice.hasNext()); - } - - static Stream dataForTestHasPrevious() { - final int MIDDLE_PAGE_NUMBER = 2; - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), false), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - false), - true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), false), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - false), - false), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), false), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasPrevious") - void testHasPrevious(Slice slice, boolean expectedHasPrevious) { - assertEquals(expectedHasPrevious, slice.hasPrevious()); - } - - static Stream dataForTestGetPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, pageable, true), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), pageable), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, pageable, false), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), pageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), - Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetPageable") - void testGetPageable(Slice slice, Pageable expectedPageable) { - assertEquals(expectedPageable, slice.getPageable()); - } - - static Stream dataForTestNextPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, true), - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - new TarantoolPageRequest<>(5, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestNextPageable") - void testNextPageable(Slice slice, Pageable expectedNextPageable) { - assertEquals(expectedNextPageable, slice.nextPageable()); - } - - static Stream dataForTestPreviousPageable() { - Pageable firstPagePageable = new TarantoolPageRequest<>(PAGE_SIZE); - Pageable secondPagePageable = - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)); - - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, false), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(4, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(0)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPreviousPageable") - void testPreviousPageable(Slice slice, Pageable expectedPrevPageable) { - assertEquals(expectedPrevPageable, slice.previousPageable()); - } - - static Stream dataForTestNextOrLastPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, true), - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), pageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, false), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), pageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - new TarantoolPageRequest<>(5, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - false), - new TarantoolPageRequest<>(4, PAGE_SIZE, null))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestNextOrLastPageable") - void testNextOrLastPageable(Slice slice, Pageable expectedNextOrLastPageable) { - assertEquals(expectedNextOrLastPageable, slice.nextOrLastPageable()); - } - - static Stream dataForTestPreviousOrFirstPageable() { - Pageable firstPagePageable = new TarantoolPageRequest<>(PAGE_SIZE); - Pageable secondPagePageable = - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)); - - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, true), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, true), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, false), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, false), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, true), - secondPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, false), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, false), - secondPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(4, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(0)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPreviousOrFirstPageable") - void testPreviousOrFirstPageable(Slice slice, Pageable expectedPrevOrFirstPageable) { - assertEquals(expectedPrevOrFirstPageable, slice.previousOrFirstPageable()); - } - - static Stream dataForTestMap() { - - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - List expectedNames = PERSONS.stream().map(Person::getName).collect(Collectors.toList()); - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, pageable, true), - (Function) Person::getName, - expectedNames, - new TarantoolSliceImpl<>(expectedNames, pageable, true))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestMap") - void testMap( - Slice slice, - Function mapper, - List expectedMappedList, - Slice expectedMappedSlice) { - assertEquals(expectedMappedSlice, slice.map(mapper)); - assertEquals(expectedMappedList, slice.map(mapper).getContent()); - } - - protected static Stream dataForTestEquals() { - - return Stream.of( - Arguments.of( - Arrays.asList( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true)), - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestEquals") - void testEquals(List> equalPageableList, Slice notEqualPageable) { - - assertFalse(equalPageableList.isEmpty()); - final int COUNT = 10; - - for (int i = 0; i < COUNT; i++) { - for (Slice pageable : equalPageableList) { - for (Slice secondPageable : equalPageableList) { - assertEquals(pageable, secondPageable); - } - assertNotEquals(pageable, null); - assertNotEquals(pageable, notEqualPageable); - } - } - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestEquals") - void testHashCode(List> equalPageableList, Slice notEqualPageable) { - for (Slice pageable : equalPageableList) { - for (Slice secondPageable : equalPageableList) { - assertEquals(pageable.hashCode(), secondPageable.hashCode()); - } - assertNotEquals(pageable.hashCode(), notEqualPageable.hashCode()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/TarantoolTestSupport.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/TarantoolTestSupport.java deleted file mode 100644 index 77a43c15..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/TarantoolTestSupport.java +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.utils; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.UUID; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.Consumer; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.introspector.Property; -import org.yaml.snakeyaml.nodes.NodeTuple; -import org.yaml.snakeyaml.nodes.Tag; -import org.yaml.snakeyaml.representer.Representer; - -import static io.tarantool.balancer.BalancerMode.DEFAULT_BALANCER_MODE; -import static io.tarantool.client.TarantoolClient.DEFAULT_TAG; -import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_PASSWORD; -import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_USERNAME; -import static io.tarantool.core.protocol.requests.IProtoAuth.DEFAULT_AUTH_TYPE; -import static io.tarantool.pool.InstanceConnectionGroup.DEFAULT_HOST; -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import io.tarantool.balancer.BalancerMode; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.core.protocol.requests.IProtoAuth; -import io.tarantool.mapping.Tuple; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyFlushConsolidationHandler; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyHeartbeatOpts; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.spring.data31.config.properties.TarantoolProperties; -import io.tarantool.spring.data31.utils.entity.ComplexPerson; -import io.tarantool.spring.data31.utils.entity.Person; - -public class TarantoolTestSupport { - - private static final ThreadLocalRandom random = ThreadLocalRandom.current(); - private static final Map firstInternalMap = new HashMap<>(); - private static final Map secondInternalMap = new HashMap<>(); - private static final Map externalMap = new HashMap<>(); - private static final Representer representer; - public static final String PERSON_SPACE = "person"; - public static final String COMPLEX_PERSON_SPACE = "complex_person"; - public static final int PERSONS_COUNT = 100; - public static final Random RANDOMIZER = new Random(); - public static final Person UNKNOWN_PERSON = new Person(-1, true, "Alien"); - public static final ComplexPerson UNKNOWN_COMPLEX_PERSON = - new ComplexPerson(-1, new UUID(0, 0), true, "Alien"); - - public static final Path DEFAULT_TEST_PROPERTY_DIR = Paths.get("target", "test-classes"); - private static final Yaml yaml; - - static { - representer = - new Representer(new DumperOptions()) { - @Override - @Nullable - protected NodeTuple representJavaBeanProperty( - Object javaBean, Property property, @Nullable Object propertyValue, Tag customTag) { - if (propertyValue == null) { - return null; - } else { - return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag); - } - } - }; - representer.addClassTag(TarantoolProperties.class, Tag.MAP); - yaml = new Yaml(representer); - } - - public static TarantoolProperties writeTestPropertiesYaml(@NonNull final String fileName) - throws IOException { - return writeTestPropertiesYaml(fileName, createRandomProperty()); - } - - public static TarantoolProperties writeTestPropertiesYaml( - final String fileName, final TarantoolProperties properties) throws IOException { - final File FILE = DEFAULT_TEST_PROPERTY_DIR.resolve(fileName).toFile().getAbsoluteFile(); - - try (Writer writer = new FileWriter(FILE)) { - firstInternalMap.put("tarantool", properties); - secondInternalMap.put("data", firstInternalMap); - externalMap.put("spring", secondInternalMap); - - yaml.dump(externalMap, writer); - replaceNullToDefault(properties); - return properties; - } - } - - public static void writeTestEmptyPropertiesYaml(@NonNull final String fileName) - throws IOException { - final File FILE = DEFAULT_TEST_PROPERTY_DIR.resolve(fileName).toFile().getAbsoluteFile(); - try (Writer writer = new FileWriter(FILE)) { - yaml.dump(Collections.emptyMap(), writer); - } - } - - private static void replaceNullToDefault(final TarantoolProperties result) { - - if (result.getHost() == null) { - result.setHost(DEFAULT_HOST); - } - - if (result.getUserName() == null) { - result.setUserName(DEFAULT_CRUD_USERNAME); - } - - if (result.getBalancerMode() == null) { - result.setBalancerMode(DEFAULT_BALANCER_MODE); - } - - if (result.getPassword() == null) { - result.setPassword(DEFAULT_CRUD_PASSWORD); - } - - if (result.getConnectionGroups() != null) { - for (PropertyInstanceConnectionGroup propertyInstanceConnectionGroup : - result.getConnectionGroups()) { - if (propertyInstanceConnectionGroup.getAuthType() == null) { - propertyInstanceConnectionGroup.setAuthType(DEFAULT_AUTH_TYPE); - } - - if (propertyInstanceConnectionGroup.getHost() == null) { - propertyInstanceConnectionGroup.setHost(DEFAULT_HOST); - } - - if (propertyInstanceConnectionGroup.getTag() == null) { - propertyInstanceConnectionGroup.setTag(DEFAULT_TAG); - } - - if (propertyInstanceConnectionGroup.getUserName() == null) { - propertyInstanceConnectionGroup.setUserName(DEFAULT_CRUD_USERNAME); - } - - if (propertyInstanceConnectionGroup.getUserName() == null) { - propertyInstanceConnectionGroup.setPassword(DEFAULT_CRUD_PASSWORD); - } - } - } - } - - private static TarantoolProperties createRandomProperty() { - final int intVar = 999; - final long longVar = 9999L; - final List booleanVar = Arrays.asList(true, false); - - PropertyHeartbeatOpts propertyHeartbeatOpts = - heartbeat( - choiceOrNull(longVar), - choiceOrNull(intVar), - choiceOrNull(intVar), - choiceOrNull(intVar)); - - PropertyFlushConsolidationHandler propertyFlushConsolidationHandler = - choiceOrNull(flushConsolidation(choiceOrNull(intVar), choiceOrNull(booleanVar))); - - PropertyInstanceConnectionGroup propertyInstanceConnectionGroup = - choiceOrNull( - connectionGroup( - choiceOrNull("host"), - "password", - choiceOrNull(intVar), - choiceOrNull(intVar), - choiceOrNull("tag"), - "user", - choiceOrNull(Arrays.asList(IProtoAuth.AuthType.values())), - propertyFlushConsolidationHandler)); - List propertyInstanceConnectionGroups = null; - if (propertyInstanceConnectionGroup != null) { - propertyInstanceConnectionGroups = new ArrayList<>(); - propertyInstanceConnectionGroups.add(propertyInstanceConnectionGroup); - } - - return tarantoolProperties( - choiceOrNull("host"), - choiceOrNull("password"), - choiceOrNull(intVar), - choiceOrNull("user"), - propertyInstanceConnectionGroups, - choiceOrNull(intVar), - choiceOrNull(booleanVar), - choiceOrNull(propertyHeartbeatOpts), - choiceOrNull(longVar), - choiceOrNull(longVar), - choiceOrNull(booleanVar), - choiceOrNull(booleanVar), - choiceOrNull(Arrays.asList(BalancerMode.values()))); - } - - @Nullable - public static T choiceOrNull(@Nullable T element) { - int rnd = random.nextInt(2); - if (rnd == 0 || element == null) { - return null; - } - return element; - } - - public static PropertyHeartbeatOpts heartbeat( - @Nullable Long pingInterval, - @Nullable Integer invalidationThreshold, - @Nullable Integer windowSize, - @Nullable Integer deathThreshold) { - - PropertyHeartbeatOpts propertyHeartbeatOpts = new PropertyHeartbeatOpts(); - if (invalidationThreshold != null) { - propertyHeartbeatOpts.setInvalidationThreshold(invalidationThreshold); - } - if (pingInterval != null) { - propertyHeartbeatOpts.setPingInterval(pingInterval); - } - if (deathThreshold != null) { - propertyHeartbeatOpts.setDeathThreshold(deathThreshold); - } - if (windowSize != null) { - propertyHeartbeatOpts.setWindowSize(windowSize); - } - - return propertyHeartbeatOpts; - } - - public static PropertyFlushConsolidationHandler flushConsolidation( - @Nullable Integer explicitFlushAfterFlushes, - @Nullable Boolean consolidateWhenNoReadInProgress) { - - PropertyFlushConsolidationHandler propertyFlushConsolidationHandler = - new PropertyFlushConsolidationHandler(); - if (explicitFlushAfterFlushes != null) { - propertyFlushConsolidationHandler.setExplicitFlushAfterFlushes(explicitFlushAfterFlushes); - } - - if (consolidateWhenNoReadInProgress != null) { - propertyFlushConsolidationHandler.setConsolidateWhenNoReadInProgress( - consolidateWhenNoReadInProgress); - } - return propertyFlushConsolidationHandler; - } - - @Nullable - public static T choiceOrNull(@Nullable List list) { - if (list == null || list.isEmpty()) { - return null; - } - int rnd = random.nextInt(list.size() + 1); - - if (rnd == list.size()) { - return null; - } - return list.get(rnd); - } - - @NonNull - public static PropertyInstanceConnectionGroup connectionGroup( - @Nullable String host, - @Nullable String password, - @Nullable Integer port, - @Nullable Integer connectionNumber, - @Nullable String tag, - @Nullable String user, - @Nullable IProtoAuth.AuthType type, - @Nullable PropertyFlushConsolidationHandler propertyFlushConsolidationHandler) { - - PropertyInstanceConnectionGroup propertyInstanceConnectionGroup = - new PropertyInstanceConnectionGroup(); - propertyInstanceConnectionGroup.setHost(host); - if (connectionNumber != null) { - propertyInstanceConnectionGroup.setConnectionGroupSize(connectionNumber); - } - propertyInstanceConnectionGroup.setAuthType(type); - propertyInstanceConnectionGroup.setPassword(password); - if (port != null) { - propertyInstanceConnectionGroup.setPort(port); - } - propertyInstanceConnectionGroup.setTag(tag); - propertyInstanceConnectionGroup.setUserName(user); - - propertyInstanceConnectionGroup.setFlushConsolidationHandler(propertyFlushConsolidationHandler); - return propertyInstanceConnectionGroup; - } - - @NonNull - public static TarantoolProperties tarantoolProperties( - @Nullable String host, - @Nullable String password, - @Nullable Integer port, - @Nullable String user, - @Nullable List propertyInstanceConnectionGroups, - @Nullable Integer eventLoopThreadsCount, - @Nullable Boolean enableGracefulShutdown, - @Nullable PropertyHeartbeatOpts propertyHeartbeatOptsOpts, - @Nullable Long connectTimeout, - @Nullable Long reconnectAfter, - @Nullable Boolean fetchSchema, - @Nullable Boolean ignoreOldSchemaVersion, - @Nullable BalancerMode balancerClass) { - - TarantoolProperties prop = new TarantoolProperties(); - prop.setHost(host); - prop.setPassword(password); - if (port != null) { - prop.setPort(port); - } - prop.setUserName(user); - prop.setConnectionGroups(propertyInstanceConnectionGroups); - if (eventLoopThreadsCount != null) { - prop.setEventLoopThreadsCount(eventLoopThreadsCount); - } - - if (enableGracefulShutdown != null) { - prop.setGracefulShutdownEnabled(enableGracefulShutdown); - } - prop.setHeartbeat(propertyHeartbeatOptsOpts); - if (connectTimeout != null) { - prop.setConnectTimeout(connectTimeout); - } - if (reconnectAfter != null) { - prop.setReconnectAfter(reconnectAfter); - } - if (fetchSchema != null) { - prop.setFetchSchema(fetchSchema); - } - if (ignoreOldSchemaVersion != null) { - prop.setIgnoreOldSchemaVersion(ignoreOldSchemaVersion); - } - prop.setBalancerMode(balancerClass); - return prop; - } - - public static List generatePersons(int count) { - List persons = new ArrayList<>(); - for (int i = 0; i < count; i++) { - persons.add(new Person(i, i % 3 == 0 ? null : i % 2 == 0, "User-" + i)); - } - return persons; - } - - public static List generatePersons(int count, Consumer actionAtPerson) { - List persons = generatePersons(count); - persons.forEach(actionAtPerson); - return persons; - } - - public static List generateComplexPersons(int count) { - List persons = new ArrayList<>(); - for (int i = 0; i < count; i++) { - persons.add( - new ComplexPerson(i, UUID.randomUUID(), i % 3 == 0 ? null : i % 2 == 0, "User-" + i)); - } - return persons; - } - - public static List generateComplexPersons( - int count, Consumer actionAtPerson) { - List persons = generateComplexPersons(count); - persons.forEach(actionAtPerson); - return persons; - } - - public static List generateAndInsertPersons(int count, TarantoolCrudClient client) { - final List persons = generatePersons(count); - final TarantoolCrudSpace space = client.space(PERSON_SPACE); - - List> insertedPersons = space.insertMany(persons, Person.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertPersons( - int count, TarantoolCrudClient client, Consumer action) { - final List persons = generatePersons(count, action); - final TarantoolCrudSpace space = client.space(PERSON_SPACE); - - List> insertedPersons = space.insertMany(persons, Person.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertComplexPersons( - int count, TarantoolCrudClient client) { - final List persons = generateComplexPersons(count); - final TarantoolCrudSpace space = client.space(COMPLEX_PERSON_SPACE); - - List> insertedPersons = - space.insertMany(persons, ComplexPerson.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertComplexPersons( - int count, TarantoolCrudClient client, Consumer action) { - - final List persons = generateComplexPersons(count, action); - final TarantoolCrudSpace space = client.space(COMPLEX_PERSON_SPACE); - - List> insertedPersons = - space.insertMany(persons, ComplexPerson.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/ComplexPersonRepository.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/ComplexPersonRepository.java deleted file mode 100644 index 511c296c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/ComplexPersonRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.utils.core; - -import org.springframework.data.repository.PagingAndSortingRepository; - -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data31.utils.entity.ComplexPerson; -import io.tarantool.spring.data31.utils.entity.CompositePersonKey; - -public interface ComplexPersonRepository - extends PagingAndSortingRepository, - GenericRepositoryMethods, - GenericPaginationMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/GenericPaginationMethods.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/GenericPaginationMethods.java deleted file mode 100644 index 29db06da..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/GenericPaginationMethods.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.utils.core; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; - -public interface GenericPaginationMethods { - - Slice findAllByName(String name); - - Slice findAllByName(String name, Pageable pageable); - - Slice findAllByNameGreaterThanEqual(String name, Pageable pageable); - - Slice findAllByNameLessThanEqual(String name, Pageable pageable); - - Slice findAllByIdLessThanEqual(int id, Pageable pageable); - - Slice findAllByIdGreaterThanEqual(int id, Pageable pageable); - - Slice findAllByIsMarriedLessThanEqual(Boolean id, Pageable pageable); - - Slice findAllByIsMarriedGreaterThanEqual(Boolean id, Pageable pageable); - - Page findPersonByName(String name, Pageable pageable); - - Page findPersonByNameGreaterThanEqual(String name, Pageable pageable); - - Page findPersonByNameLessThanEqual(String name, Pageable pageable); - - Page findPersonByIdLessThanEqual(int id, Pageable pageable); - - Page findPersonByIdGreaterThanEqual(int id, Pageable pageable); - - Page findPersonByIsMarriedLessThanEqual(Boolean id, Pageable pageable); - - Page findPersonByIsMarriedGreaterThanEqual(Boolean id, Pageable pageable); - - Window findFirst5ByIsMarried(Boolean isMarried, ScrollPosition scrollPosition); - - Window findFirst10ByIsMarriedGreaterThanEqual( - Boolean isMarried, ScrollPosition scrollPosition); - - List findAll(Sort sort); - - Page findAll(Pageable pageable); - - List findAll(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/PersonListRepository.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/PersonListRepository.java deleted file mode 100644 index ad29922b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/PersonListRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.utils.core; - -import org.springframework.data.repository.ListCrudRepository; - -import io.tarantool.spring.data.utils.GenericListRepositoryMethods; -import io.tarantool.spring.data31.utils.entity.Person; - -public interface PersonListRepository - extends ListCrudRepository, GenericListRepositoryMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/PersonRepository.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/PersonRepository.java deleted file mode 100644 index 74c7cc3e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/PersonRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.utils.core; - -import org.springframework.data.repository.PagingAndSortingRepository; - -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data31.utils.entity.Person; - -public interface PersonRepository - extends PagingAndSortingRepository, - GenericRepositoryMethods, - GenericPaginationMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/ComplexPersonWithJsonFormatVariantPK.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/ComplexPersonWithJsonFormatVariantPK.java deleted file mode 100644 index 9c0d03c4..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/ComplexPersonWithJsonFormatVariantPK.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data31.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKeyWithJsonFormat.class) -public class ComplexPersonWithJsonFormatVariantPK { - - @Id - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositeKeyWithWrongFieldCount.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositeKeyWithWrongFieldCount.java deleted file mode 100644 index 09a059b1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositeKeyWithWrongFieldCount.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -public class CompositeKeyWithWrongFieldCount implements CompositeKey { - - @JsonProperty("id") - private long id; -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositePersonKey.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositePersonKey.java deleted file mode 100644 index b5412433..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositePersonKey.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositePersonKey implements CompositeKey { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositePersonKeyWithoutJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositePersonKeyWithoutJsonFormat.java deleted file mode 100644 index c4f811c3..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositePersonKeyWithoutJsonFormat.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositePersonKeyWithoutJsonFormat { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/EntityWithAnnotationAsIdClass.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/EntityWithAnnotationAsIdClass.java deleted file mode 100644 index 6ec894b4..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/EntityWithAnnotationAsIdClass.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.utils.entity; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@IdClass(IdClass.class) -public class EntityWithAnnotationAsIdClass {} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/EntityWithWrongCompositeKeyPartsCount.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/EntityWithWrongCompositeKeyPartsCount.java deleted file mode 100644 index 566d2e79..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/EntityWithWrongCompositeKeyPartsCount.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@IdClass(CompositeKeyWithWrongFieldCount.class) -public class EntityWithWrongCompositeKeyPartsCount { - - @Id - @JsonProperty("id") - private long id; - - @Id - @JsonProperty("secondId") - private long secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/EntityWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/EntityWithWrongFieldTypes.java deleted file mode 100644 index cb862f14..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/EntityWithWrongFieldTypes.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@IdClass(CompositeKeyWithWrongFieldTypes.class) -public class EntityWithWrongFieldTypes { - - @Id - @JsonProperty("id") - private long id; - - @Id - @JsonProperty("secondId") - private String secondId; - - @Id - @JsonProperty("thirdId") - private int thirdId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/Person.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/Person.java deleted file mode 100644 index f5521285..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/Person.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data31.utils.entity; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data31.query.Field; - -/** - * @author Artyom Dubinin - */ -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("person") -public class Person implements GenericPerson { - - @Id - @Field("id") - @JsonProperty("id") - public Integer id; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; - - @Override - public Integer generateFullKey() { - return id; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/resources/application-crud-test.yaml b/tarantool-spring-data/tarantool-spring-data-31/src/test/resources/application-crud-test.yaml deleted file mode 100644 index 9bc8f9b2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/resources/application-crud-test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -spring: - data: - tarantool: - host: localhost - port: 3301 diff --git a/tarantool-spring-data/tarantool-spring-data-32/pom.xml b/tarantool-spring-data/tarantool-spring-data-32/pom.xml deleted file mode 100644 index 043436c2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/pom.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - 4.0.0 - - tarantool-spring-data-32 - Minimalistic java connector for Tarantool versions 2.11+ based on Netty framework - https://tarantool.io - - - io.tarantool - tarantool-spring-data - 2.0.0-SNAPSHOT - - - tarantool-spring-data-32 - 2.0.0-SNAPSHOT - jar - - - 17 - 17 - 3.2.12 - ${project.parent.parent.basedir}/tarantool-shared-resources/ - ${project.parent.parent.basedir}/LICENSE_HEADER.txt - - - - - io.tarantool - tarantool-spring-data-core - - - diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/TarantoolBoxKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/TarantoolBoxKeyValueAdapter.java deleted file mode 100644 index 5c7c6610..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/TarantoolBoxKeyValueAdapter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32; - -import java.util.Map; - -import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.NonNull; - -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(Object id, Object item, String keyspace) { - return adapter.put(id, item, keyspace); - } - - @Override - public boolean contains(Object id, String keyspace) { - return adapter.contains(id, keyspace); - } - - @Override - public Object get(Object id, String keyspace) { - return adapter.get(id, keyspace); - } - - @Override - public Object delete(Object id, String keyspace) { - return adapter.delete(id, keyspace); - } - - @Override - public Iterable getAllOf(String keyspace) { - return adapter.getAllOf(keyspace); - } - - @Override - public void deleteAllOf(String keyspace) { - adapter.deleteAllOf(keyspace); - } - - @Override - public void clear() { - adapter.clear(); - } - - @Override - public long count(String keyspace) { - return adapter.count(keyspace); - } - - @Override - public void destroy() throws Exception { - adapter.destroy(); - } - - @Override - public CloseableIterator> entries(String keyspace) { - throw new UnsupportedOperationException("Not implemented yet"); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/TarantoolCrudKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/TarantoolCrudKeyValueAdapter.java deleted file mode 100644 index 6d545fc9..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/TarantoolCrudKeyValueAdapter.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32; - -import java.util.Collections; -import java.util.Map.Entry; - -import com.fasterxml.jackson.annotation.JsonFormat; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.NonNull; - -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(Object id, Object item, String keyspace) { - return adapter.put(convertId(id), item, keyspace); - } - - @Override - public boolean contains(Object id, String keyspace) { - return adapter.contains(convertId(id), keyspace); - } - - @Override - public Object get(Object id, String keyspace) { - return adapter.get(convertId(id), keyspace); - } - - @Override - public T get(Object id, String keyspace, Class type) { - return adapter.get(convertId(id), keyspace, type); - } - - @Override - public Object delete(Object id, String keyspace) { - return adapter.delete(convertId(id), keyspace); - } - - @Override - public T delete(Object id, String keyspace, Class type) { - return adapter.delete(convertId(id), keyspace, type); - } - - @Override - public Iterable getAllOf(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> 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()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/TarantoolQueryEngine.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/TarantoolQueryEngine.java deleted file mode 100644 index 6800e711..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/TarantoolQueryEngine.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32; - -import java.util.Collection; -import java.util.Comparator; -import java.util.Map.Entry; - -import org.springframework.data.keyvalue.core.QueryEngine; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.ProxyTarantoolQueryEngine; -import io.tarantool.spring.data.query.TarantoolCriteria; -import io.tarantool.spring.data32.query.TarantoolCriteriaAccessor; -import io.tarantool.spring.data32.query.TarantoolSortAccessor; - -/** - * Implementation of {@code findBy*()} and {@code countBy*{}} queries. - * - * @author Artyom Dubinin - */ -public class TarantoolQueryEngine - extends QueryEngine>> { - - 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> 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. - * - *

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 Collection execute( - @Nullable final TarantoolCriteria criteria, - @Nullable final Comparator> sort, - final long offset, - final int rows, - @NonNull final String keyspace, - @NonNull Class 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); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/config/TarantoolBoxConfiguration.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/config/TarantoolBoxConfiguration.java deleted file mode 100644 index 654546a9..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/config/TarantoolBoxConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.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.data32.TarantoolBoxKeyValueAdapter; -import io.tarantool.spring.data32.config.properties.TarantoolProperties; - -@Configuration(proxyBeanMethods = false) -public class TarantoolBoxConfiguration extends BaseTarantoolBoxConfiguration { - - public TarantoolBoxConfiguration( - ObjectProvider properties, - ObjectProvider 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(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/config/package-info.java deleted file mode 100644 index 66705fa3..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/config/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Config package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data32.config; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/config/properties/TarantoolProperties.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/config/properties/TarantoolProperties.java deleted file mode 100644 index 7b1f58d5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/config/properties/TarantoolProperties.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.config.properties; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties; - -/** - * Configuration properties for Tarantool. - * - * @author Nikolay Belonogov - */ -@ConfigurationProperties(prefix = "spring.data.tarantool") -public class TarantoolProperties extends BaseTarantoolProperties {} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/TarantoolTemplate.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/TarantoolTemplate.java deleted file mode 100644 index 5f412bd2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/TarantoolTemplate.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.core; - -import org.springframework.data.keyvalue.core.IdentifierGenerator; -import org.springframework.data.keyvalue.core.KeyValueAdapter; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.util.ClassUtils; - -import io.tarantool.spring.data32.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data32.core.mapping.TarantoolMappingContext; - -public class TarantoolTemplate extends KeyValueTemplate { - - public TarantoolTemplate(KeyValueAdapter adapter) { - super(adapter, new TarantoolMappingContext<>()); - } - - public TarantoolTemplate( - KeyValueAdapter adapter, - MappingContext< - ? extends KeyValuePersistentEntity, ? extends KeyValuePersistentProperty> - mappingContext) { - super(adapter, mappingContext); - } - - public TarantoolTemplate( - KeyValueAdapter adapter, - MappingContext< - ? extends KeyValuePersistentEntity, ? extends KeyValuePersistentProperty> - mappingContext, - IdentifierGenerator identifierGenerator) { - super(adapter, mappingContext, identifierGenerator); - } - - @Override - public T insert(T objectToInsert) { - if (DefaultIdClassResolver.INSTANCE.resolveIdClassType(objectToInsert.getClass()) == null) { - return super.insert(objectToInsert); - } - - PersistentEntity entity = - getMappingContext().getRequiredPersistentEntity(ClassUtils.getUserClass(objectToInsert)); - - IdentifierAccessor identifierAccessor = entity.getIdentifierAccessor(objectToInsert); - Object id = identifierAccessor.getRequiredIdentifier(); - return insert(id, objectToInsert); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/annotation/DefaultIdClassResolver.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/annotation/DefaultIdClassResolver.java deleted file mode 100644 index 35d63477..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/annotation/DefaultIdClassResolver.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.core.annotation; - -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.core.annotation.IdClassResolver; - -/** Default implementation of {@link IdClassResolver}. */ -public enum DefaultIdClassResolver implements IdClassResolver { - INSTANCE; - - public static final String ANNOTATION_TYPE_EXCEPTION = - "The class of a composite identifier specified in the @IdClass annotation cannot be" - + " annotation!"; - - @Nullable - @Override - public Class resolveIdClassType(Class type) { - Assert.notNull(type, "Type for IdClass must be not null!"); - - IdClass idClassTypeAnnotation = AnnotatedElementUtils.findMergedAnnotation(type, IdClass.class); - - if (idClassTypeAnnotation == null) { - return null; - } - - Class idClassTypeValue = idClassTypeAnnotation.value(); - Assert.isTrue(!idClassTypeValue.isAnnotation(), ANNOTATION_TYPE_EXCEPTION); - - return idClassTypeValue; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/annotation/package-info.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/annotation/package-info.java deleted file mode 100644 index 32a70962..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/annotation/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Core annotations of data mapping. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data32.core.annotation; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/BasicKeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/BasicKeyValueCompositePersistentEntity.java deleted file mode 100644 index 1545e38d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/BasicKeyValueCompositePersistentEntity.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.core.mapping; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.data.domain.Persistable; -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.support.IsNewStrategy; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.mapping.model.CompositeKey; -import io.tarantool.spring.data32.core.mapping.model.CompositeIdPropertyAccessor; -import io.tarantool.spring.data32.core.mapping.model.PersistentCompositeIdIsNewStrategy; - -public class BasicKeyValueCompositePersistentEntity> - extends BasicKeyValuePersistentEntity implements KeyValueCompositePersistentEntity { - - public static final String TYPE_MISMATCH = - "Target bean of type %s is not of type of the persistent entity (%s)"; - - private final Class idClassTypeValue; - private @Nullable P idProperty; - - private Map entityIdClassFields; - - /** - * @param information must not be {@literal null}. - * @param fallbackKeySpaceResolver can be {@literal null}. - * @param idClassTypeValue class that specified in {@link IdClass} - */ - public BasicKeyValueCompositePersistentEntity( - TypeInformation information, - @Nullable KeySpaceResolver fallbackKeySpaceResolver, - Class idClassTypeValue) { - super(information, fallbackKeySpaceResolver); - - Assert.notNull(idClassTypeValue, "idClassTypeValue must be not null for this class!"); - this.idClassTypeValue = idClassTypeValue; - } - - @Override - public IdentifierAccessor getIdentifierAccessor(Object bean) { - verifyBeanType(bean); - - if (Persistable.class.isAssignableFrom(getType())) { - throw new IllegalArgumentException( - "Persistable override is not currently supported for entities with a composite key."); - } - - return hasIdProperty() - ? new CompositeIdPropertyAccessor(bean, this.entityIdClassFields, getIdClassType()) - : new AbsentIdentifierAccessor(); - } - - @Override - public Class getIdClassType() { - return this.idClassTypeValue; - } - - @Override - public void verify() { - super.verify(); - - if (this.idProperty != null) { - this.entityIdClassFields = KeyPartTypeChecker.getFieldMapIfTypesValid(this, this.idProperty); - } - } - - @Override - protected IsNewStrategy getFallbackIsNewStrategy() { - return PersistentCompositeIdIsNewStrategy.of(this); - } - - @Override - protected P returnPropertyIfBetterIdPropertyCandidateOrNull(P property) { - Assert.isInstanceOf(Identifier.class, property, "property must be Identifier for this class"); - - if (!property.isIdProperty()) { - return null; - } - - if (this.idProperty == null) { - this.idProperty = property; - return this.idProperty; - } - - this.idProperty.addPart(property); - - return this.idProperty; - } - - /** - * Verifies the given bean type to no be {@literal null} and of the type of the current {@link - * PersistentEntity}. - * - * @param bean must not be {@literal null}. - */ - private void verifyBeanType(Object bean) { - - Assert.notNull(bean, "Target bean must not be null"); - Assert.isInstanceOf( - getType(), - bean, - () -> String.format(TYPE_MISMATCH, bean.getClass().getName(), getType().getName())); - } - - /** - * A null-object implementation of {@link IdentifierAccessor} to be able to return an accessor for - * entities that do not have an identifier property. - */ - private static class AbsentIdentifierAccessor implements IdentifierAccessor { - - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.IdentifierAccessor#getIdentifier() - */ - @Override - @Nullable - public Object getIdentifier() { - return null; - } - } - - /** - * A class that checks the types of fields of a composite key. In addition, the correspondence - * between types and field names marked with {@code @Id}. - */ - public static class KeyPartTypeChecker { - - public static final String COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION = - "Number of fields specified in domain class and composite class the key is different!"; - - public static final String COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION = - "Domain class fields marked with @Id differ from fields specified in the composite key" - + " class"; - - /** - * Check the number and types of entity fields, annotated {@code @Id} and fields {@link - * CompositeKey} and if the types and quantities match return the id part fields mapping. - * - * @param persistentEntity persistent entity - * @param idProperty id property - * @return mapping between fields of composite key class and fields annotated {@code @Id} in - * entity. - */ - public static Map getFieldMapIfTypesValid( - KeyValueCompositePersistentEntity persistentEntity, Identifier idProperty) { - Map entityIdClassFields = new HashMap<>(); - - List compositeKeyFields = persistentEntity.getIdClassTypeFields(); - - Field[] entityFields = idProperty.getFields(); - - if (compositeKeyFields.size() != entityFields.length) { - throw new IllegalArgumentException(COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION); - } - - for (int i = 0; i < compositeKeyFields.size(); i++) { - Field compositeKeyField = compositeKeyFields.get(i); - Field entityField = entityFields[i]; - - if (!equalFields(compositeKeyField, entityField)) { - throw new IllegalArgumentException(COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION); - } - - entityIdClassFields.put(entityField, compositeKeyField); - } - return entityIdClassFields; - } - - /** - * Compares two class fields by name and type. - * - * @param firstField first field - * @param secondField second field - * @return true if fields are equal - */ - private static boolean equalFields(Field firstField, Field secondField) { - return firstField.getName().equals(secondField.getName()) - && firstField.getType().equals(secondField.getType()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/Identifier.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/Identifier.java deleted file mode 100644 index 00ab428a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/Identifier.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.core.mapping; - -import java.lang.reflect.Field; -import java.util.Collection; - -import org.springframework.data.mapping.PersistentProperty; - -/** The interface of the identifier class that will contain information about the composite key. */ -public interface Identifier

> { - - /** - * Add a {@link PersistentProperty} tagged with {@code Id}. - * - * @param property {@link PersistentProperty} tagged {@code Id} - */ - void addPart(P property); - - /** - * Return the parts of a composite key that are {@link PersistentProperty}. - * - * @return parts of a composite key - */ - Collection

getParts(); - - /** - * Return a list {@link Field} of fields that are annotated {@code @Id}. Unlike method {@link - * #getParts()} this method returns an array {@link Field}, where {@link Field} is taken from each - * element of the collection returned by the {@link #getParts()} method. Necessary in order not to - * write polluting code. - * - * @return fields of a composite key - */ - Field[] getFields(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/KeyValueCompositeProperty.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/KeyValueCompositeProperty.java deleted file mode 100644 index 5e722e7a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/KeyValueCompositeProperty.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.core.mapping; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; - -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.util.Assert; - -public class KeyValueCompositeProperty

> - extends KeyValuePersistentProperty

implements Identifier

{ - - private final List

identifierPartsWithoutFirst; - - public KeyValueCompositeProperty( - Property property, PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - super(property, owner, simpleTypeHolder); - this.identifierPartsWithoutFirst = new ArrayList<>(); - } - - @Override - public void addPart(P property) { - Assert.notNull(property, "property must be not null"); - - if (equals(property) || this.identifierPartsWithoutFirst.contains(property)) { - return; - } - this.identifierPartsWithoutFirst.add(property); - } - - @Override - @SuppressWarnings("unchecked") - public Collection

getParts() { - List

resultList = new ArrayList<>(this.identifierPartsWithoutFirst); - resultList.add(0, (P) this); - - return resultList; - } - - @Override - public Field[] getFields() { - int totalSize = this.identifierPartsWithoutFirst.size() + 1; - - final Field[] fields = new Field[totalSize]; - fields[0] = getField(); - - for (int i = 1; i < totalSize; i++) { - fields[i] = this.identifierPartsWithoutFirst.get(i - 1).getField(); - } - return fields; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - KeyValueCompositeProperty other = (KeyValueCompositeProperty) o; - - if (this.identifierPartsWithoutFirst.isEmpty() && other.identifierPartsWithoutFirst.isEmpty()) { - return super.equals(o); - } - - if (this.identifierPartsWithoutFirst.size() != other.identifierPartsWithoutFirst.size() - || !other.getProperty().equals(getProperty())) { - return false; - } - - for (int i = 0; i < this.identifierPartsWithoutFirst.size(); i++) { - // take Property from both parts - Property thisKeyPartProperty = - ((KeyValueCompositeProperty) this.identifierPartsWithoutFirst.get(i)).getProperty(); - Property otherKeyPartProperty = - ((KeyValueCompositeProperty) other.identifierPartsWithoutFirst.get(i)).getProperty(); - - if (!thisKeyPartProperty.equals(otherKeyPartProperty)) { - return false; - } - } - return true; - } - - @Override - public int hashCode() { - int hashCode = super.hashCode(); - - if (this.identifierPartsWithoutFirst.isEmpty()) { - return hashCode; - } - - // sublist to avoid endless recursion - return Objects.hash(hashCode, this.identifierPartsWithoutFirst); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/TarantoolMappingContext.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/TarantoolMappingContext.java deleted file mode 100644 index b95eaee1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/TarantoolMappingContext.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.core.mapping; - -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; - -import io.tarantool.spring.data.core.annotation.IdClassResolver; -import io.tarantool.spring.data32.core.annotation.DefaultIdClassResolver; - -public class TarantoolMappingContext< - E extends KeyValuePersistentEntity, P extends KeyValuePersistentProperty

> - extends KeyValueMappingContext { - - private final IdClassResolver idClassResolver; - - private @Nullable KeySpaceResolver keySpaceResolver; - - public TarantoolMappingContext() { - super(); - this.idClassResolver = DefaultIdClassResolver.INSTANCE; - } - - @Override - public void setKeySpaceResolver(KeySpaceResolver keySpaceResolver) { - super.setKeySpaceResolver(keySpaceResolver); - this.keySpaceResolver = keySpaceResolver; - } - - @SuppressWarnings("unchecked") - @Override - protected E createPersistentEntity(TypeInformation typeInformation) { - final Class idClassTypeValue = - this.idClassResolver.resolveIdClassType(typeInformation.getType()); - if (idClassTypeValue == null) { - return (E) new BasicKeyValuePersistentEntity(typeInformation, this.keySpaceResolver); - } - return (E) - new BasicKeyValueCompositePersistentEntity<>( - typeInformation, this.keySpaceResolver, idClassTypeValue); - } - - @SuppressWarnings("unchecked") - @Override - protected P createPersistentProperty( - Property property, E owner, SimpleTypeHolder simpleTypeHolder) { - if (KeyValueCompositePersistentEntity.class.isAssignableFrom(owner.getClass())) { - return (P) new KeyValueCompositeProperty<>(property, owner, simpleTypeHolder); - } - return (P) new KeyValuePersistentProperty<>(property, owner, simpleTypeHolder); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/model/CompositeIdPropertyAccessor.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/model/CompositeIdPropertyAccessor.java deleted file mode 100644 index d5eed0d8..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/model/CompositeIdPropertyAccessor.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.core.mapping.model; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.util.Map; - -import org.springframework.data.mapping.TargetAwareIdentifierAccessor; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -/** Class that allows to convert {@code @Id} annotated fields in an entity into a composite key. */ -public class CompositeIdPropertyAccessor extends TargetAwareIdentifierAccessor { - - private final Map entityIdClassFields; - - private final Class idClassType; - - private final Object target; - - public CompositeIdPropertyAccessor( - Object target, @NonNull Map entityIdClassFields, Class idClassType) { - - super(target); - this.target = target; - this.entityIdClassFields = entityIdClassFields; - this.idClassType = idClassType; - } - - @Nullable - public Object getIdentifier() { - try { - return generateIdentifier(); - } catch (InstantiationException - | IllegalAccessException - | NoSuchMethodException - | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - /** - * Generates a composite identifier from those marked with the {@code @Id} annotation in a domain - * class based on fields, specified in the composite key class. - * - * @return identifier - * @throws IllegalAccessException if the class or its nullary constructor is not accessible. - * @throws InstantiationException if this {@code Class} represents an abstract class, an - * interface, an array class, a primitive type, or void; or if the class has no nullary - * constructor; or if the instantiation fails for some other reason. - */ - private Object generateIdentifier() - throws InstantiationException, - IllegalAccessException, - NoSuchMethodException, - InvocationTargetException { - Assert.notNull(this.target, "target object must be not null!"); - Object compositeKey = idClassType.getDeclaredConstructor().newInstance(); - for (Map.Entry fieldPair : this.entityIdClassFields.entrySet()) { - writeValuesFromEntityId(compositeKey, fieldPair.getKey(), fieldPair.getValue()); - } - return compositeKey; - } - - /** - * Write the composite primary key fields provided in the entity to the class which implements - * {@link CompositeKey}. - * - * @param compositeKey object of the composite key into which the values are written. - * @param entityField field from the represented entity. - * @param compositeKeyField field from the composite key class. - */ - private void writeValuesFromEntityId( - Object compositeKey, Field entityField, Field compositeKeyField) { - ReflectionUtils.makeAccessible(entityField); - ReflectionUtils.makeAccessible(compositeKeyField); - - Object value = ReflectionUtils.getField(entityField, this.target); - ReflectionUtils.setField(compositeKeyField, compositeKey, value); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/model/package-info.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/model/package-info.java deleted file mode 100644 index 47b91a2a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/model/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Core implementation of the mapping subsystem's model. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data32.core.mapping.model; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/package-info.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/package-info.java deleted file mode 100644 index 5acc8a69..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Base package for the mapping subsystem. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data32.core.mapping; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/package-info.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/package-info.java deleted file mode 100644 index 8822c0a7..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Core package for integrating Tarantool with Spring - * concepts. - */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data32.core; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/Field.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/Field.java deleted file mode 100644 index 48814c20..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/Field.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.core.annotation.AliasFor; - -/** - * Allows adding some metadata to the class fields relevant for storing them in the Tarantool space - * - * @author Artyom Dubinin - */ -@Inherited -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) -public @interface Field { - - /** - * The target Tarantool space field for storing the marked class field. Alias for {@link #name()}. - * - * @return the name of a field in space - */ - @AliasFor("name") - String value() default ""; - - /** - * The target Tarantool space field for storing the marked class field. Alias for {@link - * #value()}. - * - * @return the name of a field in space - */ - @AliasFor("value") - String name() default ""; - - /** - * The order in which fields shall be stored in the tuple. Has to be a positive integer. - * - * @return the order the field shall have in the tuple or -1 if undefined. - */ - int order() default -1; -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/PaginationUtils.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/PaginationUtils.java deleted file mode 100644 index b5f97b34..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/PaginationUtils.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.keyvalue.core.IterableConverter; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class PaginationUtils { - - private static final String CRITERIA_NULL_EXC_MSG = "TarantoolCriteria must be not null"; - - /** - * Returns {@link TarantoolPageable} cast from {@link Pageable} with type checking. - * - * @param sliceParams pageable - * @return {@link TarantoolPageable} - */ - public static TarantoolPageable castToTarantoolPageable(Pageable sliceParams) { - Assert.isInstanceOf(TarantoolPageable.class, sliceParams, "Pageable must be TarantoolPageable"); - return (TarantoolPageable) sliceParams; - } - - /** - * A general method for retrieving data for paginated queries. - * - * @param query query - * @param pageRequest {@link TarantoolPageable} - * @param pageSize page size - * @return selection result. - */ - public static List doPaginationQuery( - final KeyValueQuery query, - TarantoolPageable pageRequest, - int pageSize, - KeyValueOperations keyValueOperations, - Class targetType) { - - TarantoolCriteria criteria = (TarantoolCriteria) query.getCriteria(); - PaginationDirection paginationDirection = pageRequest.getPaginationDirection(); - - Assert.notNull(criteria, CRITERIA_NULL_EXC_MSG); - criteria.withAfter(pageRequest.getTupleCursor()); - - query.setRows(pageSize * paginationDirection.getMultiplier()); - - return IterableConverter.toList(keyValueOperations.find(query, targetType)); - } - - public static Page doPageQuery( - Pageable pageable, - KeyValueQuery query, - KeyValueOperations keyValueOperations, - Class targetType) { - if (pageable.isUnpaged()) { - return new TarantoolPageImpl<>(); - } - TarantoolPageable resultSliceParams = castToTarantoolPageable(pageable); - - int pageSize = resultSliceParams.getPageSize(); - - // non transactional calls - List content = - doPaginationQuery(query, resultSliceParams, pageSize, keyValueOperations, targetType); - - if (content.isEmpty()) { - return new TarantoolPageImpl<>(); - } - - long totalElements = keyValueOperations.count(query, targetType); - return new TarantoolPageImpl<>(content, resultSliceParams, totalElements); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolChunk.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolChunk.java deleted file mode 100644 index db64158e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolChunk.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -/** - * A chunk of data restricted by the configured {@link Pageable} for Tarantool. - * - * @author Nikolay Belonogov - */ -abstract class TarantoolChunk implements Slice, Serializable { - - private static final long serialVersionUID = 867755909294344406L; - - private final List content = new ArrayList<>(); - - private final Pageable pageable; - - /** - * Creates a new {@link TarantoolChunk} with the given content and the given governing {@link - * TarantoolPageable}. - * - * @param content must not be {@literal null}. - * @param pageable must not be {@literal null}. - */ - public TarantoolChunk(List content, Pageable pageable) { - - Assert.notNull(content, "Content must not be null"); - Assert.notNull(pageable, "Pageable must not be null"); - - if (pageable.isPaged() && !(pageable instanceof TarantoolPageable)) { - throw new IllegalArgumentException("Pageable must be TarantoolPageable or Unpaged type"); - } - - this.content.addAll(content); - this.pageable = pageable; - } - - @Override - public boolean isFirst() { - return !hasPrevious(); - } - - @Override - public boolean isLast() { - return !hasNext(); - } - - @Override - public boolean hasPrevious() { - return getNumber() > 0 && hasContent(); - } - - @Override - public boolean hasContent() { - return !content.isEmpty(); - } - - /** - * Returns the {@link Pageable} to request the next {@link Slice}. Can be {@link - * Pageable#unpaged()} in case the current {@link Slice} is already the last one or when data - * content is empty. Clients should check {@link #hasNext()} and {@link #hasContent()} before - * calling this method. - * - * @see #nextOrLastPageable() - */ - @NonNull - @Override - @SuppressWarnings("unchecked") - public Pageable nextPageable() { - if (hasNext() && pageable.isPaged()) { - return ((TarantoolPageable) pageable).next(content.get(content.size() - 1)); - } - return Pageable.unpaged(); - } - - /** - * Returns the {@link Pageable} to request the previous {@link Slice}. Can be {@link - * Pageable#unpaged()} in case the current {@link Slice} is already the first one or data content - * is empty. Clients should check {@link #hasPrevious()} and {@link #hasContent()} before calling - * this method. - * - * @see #previousOrFirstPageable() - */ - @NonNull - @Override - @SuppressWarnings("unchecked") - public Pageable previousPageable() { - if (hasPrevious() && pageable.isPaged()) { - return ((TarantoolPageable) pageable).previousOrFirst(content.get(0)); - } - return Pageable.unpaged(); - } - - @Override - public Iterator iterator() { - return content.iterator(); - } - - @NonNull - @Override - public List getContent() { - return Collections.unmodifiableList(content); - } - - @NonNull - @Override - public Pageable getPageable() { - return pageable; - } - - @NonNull - @Override - public Sort getSort() { - return pageable.getSort(); - } - - @Override - public int getNumber() { - if (pageable.isPaged()) { - return pageable.getPageNumber(); - } - return 0; - } - - @Override - public int getSize() { - if (pageable.isPaged()) { - return pageable.getPageSize(); - } - return content.size(); - } - - @Override - public int getNumberOfElements() { - return content.size(); - } - - /** - * Applies the given {@link Function} to the content of the {@link TarantoolChunk}. - * - * @param converter must not be {@literal null}. - */ - protected List getConvertedContent(Function converter) { - - Assert.notNull(converter, "Function must not be null"); - - return this.stream().map(converter).collect(Collectors.toList()); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolChunk)) { - return false; - } - TarantoolChunk that = (TarantoolChunk) o; - return content.equals(that.content) && pageable.equals(that.pageable); - } - - @Override - public int hashCode() { - return Objects.hash(content, pageable); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolCriteriaAccessor.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolCriteriaAccessor.java deleted file mode 100644 index d1132bd0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolCriteriaAccessor.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import org.springframework.data.keyvalue.core.CriteriaAccessor; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -import io.tarantool.spring.data.query.TarantoolCriteria; - -/** - * Provide a mechanism to convert the abstract query into the direct implementation in Tarantool. - * - * @author Artyom Dubinin - */ -public class TarantoolCriteriaAccessor implements CriteriaAccessor { - - /** - * @param query in Spring form - * @return The same in Tarantool form - */ - public TarantoolCriteria resolve(KeyValueQuery query) { - return (TarantoolCriteria) query.getCriteria(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolKeysetScrollPosition.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolKeysetScrollPosition.java deleted file mode 100644 index 1f0d83a1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolKeysetScrollPosition.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.util.List; -import java.util.Objects; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.Pair; - -final class TarantoolKeysetScrollPosition implements TarantoolScrollPosition { - - private final Pair indexKey; - - private final PaginationDirection direction; - - private final Object cursor; - - TarantoolKeysetScrollPosition( - Pair indexKey, PaginationDirection direction, @Nullable Object cursor) { - - Assert.notNull(direction, "PaginationDirection must not be null"); - Assert.notNull(indexKey, "indexKey must not be null"); - - this.indexKey = indexKey; - this.direction = direction; - this.cursor = cursor; - } - - /** - * Creates a new {@link TarantoolKeysetScrollPosition} from a key set and {@link - * PaginationDirection}. - * - * @param indexKey must not be {@literal null}. - * @return will never be {@literal null}. - */ - static TarantoolScrollPosition forward(Pair indexKey) { - return new TarantoolKeysetScrollPosition(indexKey, FORWARD, null); - } - - static TarantoolScrollPosition backward(Pair indexKey) { - return new TarantoolKeysetScrollPosition(indexKey, BACKWARD, null); - } - - /** - * Returns whether the current scroll position is the initial one (from begin or from end) (see - * {@link PaginationDirection}). - * - * @return {@link Boolean} object. - */ - @Override - public boolean isInitial() { - if (indexKey.getSecond() instanceof List startingList) { - return startingList.isEmpty() && cursor == null; - } - return false; - } - - @Override - public TarantoolScrollPosition reverse() { - Pair newIndexKey = Pair.of(indexKey.getFirst(), indexKey.getSecond()); - return new TarantoolKeysetScrollPosition(newIndexKey, direction.reverse(), cursor); - } - - @Override - public boolean isScrollsBackward() { - return direction.equals(BACKWARD); - } - - /** - * Return the cursor relative to which the data is being found. - * - * @return returns cursor - */ - Object getCursor() { - return cursor; - } - - /** - * @return the scroll direction. - */ - PaginationDirection getDirection() { - return direction; - } - - /** - * @return the indexKey. - */ - Pair getIndexKey() { - return indexKey; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolKeysetScrollPosition that)) { - return false; - } - return indexKey.equals(that.indexKey) - && direction == that.direction - && Objects.equals(cursor, that.cursor); - } - - @Override - public int hashCode() { - return Objects.hash(indexKey, direction, cursor); - } - - @Override - public String toString() { - return String.format("TarantoolKeysetScrollPosition [%s, %s, %s]", direction, indexKey, cursor); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolPageImpl.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolPageImpl.java deleted file mode 100644 index 7a563e62..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolPageImpl.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.io.Serial; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.lang.NonNull; - -/** - * Basic {@code Page} implementation for Tarantool. - * - * @param domain class type. - * @author Nikolay Belonogov - */ -class TarantoolPageImpl extends TarantoolChunk implements Page { - - @Serial private static final long serialVersionUID = 867755909294344406L; - - private final long total; - - /** - * Creates a new {@link TarantoolPageImpl} with empty content. This will result in the created - * {@link Page} being identical to the entire {@link List}. - */ - public TarantoolPageImpl() { - this(Collections.emptyList(), Pageable.unpaged(), 0L); - } - - /** - * Creates a new {@link TarantoolPageImpl} with the given content. This will result in the created - * {@link Page} being identical to the entire {@link List}. - * - * @param content must not be {@literal null}. - */ - public TarantoolPageImpl(List content) { - this(content, Pageable.unpaged(), content == null ? 0L : content.size()); - } - - /** - * Constructor of {@link TarantoolPageImpl}. - * - * @param content the content of this page, must not be {@literal null}. - * @param pageable the paging information, must not be {@literal null}. - * @param total the total amount of items available. The total might be adapted considering the - * length of the content given, if it is going to be the content of the last page. This is in - * place to mitigate inconsistencies. - */ - public TarantoolPageImpl(List content, Pageable pageable, long total) { - - super(content, pageable); - - this.total = - pageable - .toOptional() - .filter(it -> !content.isEmpty()) - .filter(it -> it.getOffset() + it.getPageSize() > total) - .map(it -> it.getOffset() + content.size()) - .orElse(total); - } - - @Override - public int getTotalPages() { - return getSize() == 0 ? 1 : (int) Math.ceil((double) total / (double) getSize()); - } - - @Override - public long getTotalElements() { - return total; - } - - @Override - public boolean hasNext() { - return getNumber() + 1 < getTotalPages() && hasContent(); - } - - @Override - public boolean isLast() { - return !hasNext(); - } - - @Override - @NonNull - public Page map(@NonNull Function converter) { - return new PageImpl<>(getConvertedContent(converter), getPageable(), total); - } - - @Override - public String toString() { - - List content = getContent(); - boolean canGetContentType = !content.isEmpty() && content.get(0) != null; - - String contentType = canGetContentType ? content.get(0).getClass().getName() : "UNKNOWN"; - - return String.format( - "Page %s of %d containing %s instances", getNumber() + 1, getTotalPages(), contentType); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolPageImpl that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return total == that.total; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), total); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolPageRequest.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolPageRequest.java deleted file mode 100644 index 9abe4bcb..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolPageRequest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.io.Serial; -import java.util.Objects; - -import org.springframework.data.domain.AbstractPageRequest; -import org.springframework.data.domain.Sort; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; - -/** - * Basic implementation of {@link TarantoolPageable} for Tarantool. - * - *

Important: When specifying a cursor tuple, you must adhere to the following - * rules: - * - *

1. To specify a page starting from the beginning of {@code space} (the first element of the - * page is the first element found in {@code space}), use {@code tupleCursor == null}. - * - *

2. To specify an arbitrary page (the first element of the page is the next/previous one from - * the given one tuple cursor depending on the methods used and page number), use {@code tupleCursor - * == someTupleCursor} . - * - * @param domain entity type - */ -public final class TarantoolPageRequest extends AbstractPageRequest - implements TarantoolPageable { - - @Serial private static final long serialVersionUID = -4541509938956089562L; - - private final Sort sort; - - private final T tupleCursor; - - private final PaginationDirection paginationDirection; - - /** - * Creates a new unsorted {@link TarantoolPageRequest} from begin of {@code space}. - * - * @param pageSize the size of the page to be returned, must be greater than 0. - */ - public TarantoolPageRequest(int pageSize) { - this(0, pageSize, null); - } - - /** - * Creates a new unsorted {@link TarantoolPageRequest}. - * - *

Important: Use this method with caution! It is important to know the exact - * match of number pages and the tuple after (before) which the page goes (without including this - * tuple in the page itself). A mistake in compliance results in the appearance of blank pages - * with unpaged pageable even when using methods {@link - * TarantoolPageImpl#previousOrFirstPageable()} / {@link TarantoolPageImpl#nextOrLastPageable()} - * and {@link TarantoolSliceImpl#previousOrFirstPageable()} / {@link - * TarantoolSliceImpl#nextOrLastPageable()}. - * - * @param page zero-based page index (virtual), must not be negative. - * @param size the size of the page to be returned, must be greater than 0. - * @param tupleCursor tuple cursor from which the page count begins. More: {@link - * TarantoolPageRequest}. - */ - public TarantoolPageRequest(int page, int size, T tupleCursor) { - this(page, size, Sort.unsorted(), tupleCursor, FORWARD); - } - - /** - * Private constructor to create an instance with a specific {@link PaginationDirection}. - * - * @param page zero-based page index, must not be negative. - * @param size the size of the page to be returned, must be greater than 0. - * @param sort must not be {@literal null}, use {@link Sort#unsorted()} instead. - * @param tupleCursor tuple cursor from which the page count begins. More: {@link - * TarantoolPageRequest}. - * @param direction direction of pagination. - */ - TarantoolPageRequest( - int page, int size, Sort sort, T tupleCursor, @NonNull PaginationDirection direction) { - super(page, size); - Assert.notNull(sort, "Sort must not be null"); - Assert.notNull(direction, "PaginationDirection must not be null"); - - this.sort = sort; - this.tupleCursor = tupleCursor; - this.paginationDirection = direction; - } - - /** Non supported for Tarantool. */ - @Override - @NonNull - public TarantoolPageRequest withPage(int pageNumber) throws UnsupportedOperationException { - throw new UnsupportedOperationException("method \"withPage(int pageNumber)\" unsupported"); - } - - @Override - @NonNull - public TarantoolPageable first() { - return new TarantoolPageRequest<>(getPageSize()); - } - - /** Non supported for Tarantool. Use {@link #next(Object)}. */ - @Override - @NonNull - public TarantoolPageRequest next() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"next()\" unsupported, use next(T nextTupleCursor)"); - } - - @Override - public TarantoolPageRequest next(T tupleCursor) { - return new TarantoolPageRequest<>( - getPageNumber() + 1, getPageSize(), getSort(), tupleCursor, FORWARD); - } - - /** Non supported for Tarantool. Use {@link #previous(Object)}. */ - @Override - @NonNull - public TarantoolPageRequest previous() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"previous()\" unsupported, use previous(T prevTupleCursor)"); - } - - private TarantoolPageRequest previous(T tupleCursor) { - if (hasPrevious()) { - return new TarantoolPageRequest<>( - getPageNumber() - 1, getPageSize(), getSort(), tupleCursor, BACKWARD); - } - return this; - } - - /** Non supported for Tarantool. Use {@link #previousOrFirst(Object)}. */ - @Override - @NonNull - public TarantoolPageable previousOrFirst() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"previousOrFirst()\" unsupported, use previousOrFirst(T prevTupleCursor)"); - } - - @Override - public TarantoolPageable previousOrFirst(T tupleCursor) { - if (hasPrevious()) { - return previous(tupleCursor); - } - return new TarantoolPageRequest<>(0, getPageSize(), getSort(), null, BACKWARD); - } - - @Override - public PaginationDirection getPaginationDirection() { - return this.paginationDirection; - } - - @Override - @NonNull - public Sort getSort() { - return this.sort; - } - - @Override - public T getTupleCursor() { - return this.tupleCursor; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolPageRequest that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return sort.equals(that.sort) - && Objects.equals(tupleCursor, that.tupleCursor) - && paginationDirection == that.paginationDirection; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), sort, tupleCursor, paginationDirection); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolPageable.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolPageable.java deleted file mode 100644 index 2981df5a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolPageable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import org.springframework.data.domain.Pageable; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; - -import io.tarantool.spring.data.query.PaginationDirection; - -/** - * Abstract interface for pagination information in Tarantool. - * - * @param domain class type. - * @author Nikolay Belonogov - */ -public interface TarantoolPageable extends Pageable { - - /** - * Returns tuple cursor of domain type. Can be {@code null}. If the cursor is {@code null} then - * the page is counted from the first tuple in Tarantool. - * - * @return tuple cursor of domain type. - */ - @Nullable - T getTupleCursor(); - - /** - * Returns the {@link TarantoolPageable} for previous page or the {@link TarantoolPageable} for - * first page if the current one already is the first one. Important: this method - * always returns {@link TarantoolPageable} c {@link PaginationDirection#BACKWARD}. - * - * @param tupleCursor tuple cursor of domain type for previous page. - * @return {@link TarantoolPageable} instance. - */ - TarantoolPageable previousOrFirst(T tupleCursor); - - /** - * Returns the {@link TarantoolPageable} requesting the next {@link - * org.springframework.data.domain.Page}. - * - *

Important: method always creates a new {@link TarantoolPageable} with the - * same parameters Sort and page size. Pagination direction is {@link - * PaginationDirection#FORWARD}, the page number always has value {@code n+1}, n is the current - * page number. - * - * @param tupleCursor tuple cursor of domain type for next page. - * @return {@link TarantoolPageable} object - */ - TarantoolPageable next(T tupleCursor); - - /** - * Returns pagination direction by {@link PaginationDirection} enumeration. - * - * @return {@link PaginationDirection}. - */ - PaginationDirection getPaginationDirection(); - - /** - * Returns a {@link TarantoolPageable} that points to the first page with {@link - * PaginationDirection#FORWARD} pagination direction. - * - * @return {@link TarantoolPageable} which has {@code cursor == null}, page number is 0, the rest - * parameters are equivalent to the parameters of the current {@link TarantoolPageable}. - */ - @NonNull - TarantoolPageable first(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolPartTreeQuery.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolPartTreeQuery.java deleted file mode 100644 index 85978665..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolPartTreeQuery.java +++ /dev/null @@ -1,506 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.springframework.data.domain.Limit; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; -import org.springframework.data.keyvalue.core.IterableConverter; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery; -import org.springframework.data.repository.query.Parameter; -import org.springframework.data.repository.query.Parameters; -import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.data.util.StreamUtils; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -import static io.tarantool.client.crud.ConditionOperator.GREATER_EQ; -import static io.tarantool.client.crud.ConditionOperator.LESS_EQ; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import static io.tarantool.spring.data32.query.PaginationUtils.doPageQuery; -import static io.tarantool.spring.data32.query.PaginationUtils.doPaginationQuery; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.query.TarantoolCriteria; -import io.tarantool.spring.data.utils.Pair; - -/** - * There is one instance for each query method defined for a repository, providing a query from the - * bind parameters. - * - * @author Artyom Dubinin - */ -public class TarantoolPartTreeQuery extends KeyValuePartTreeQuery { - - public static final String ILLEGAL_RETURN_TYPE_FOR_DELETE = - "Illegal returned type: %s. The operation 'deleteBy' accepts only 'long' and 'Collection' as" - + " the returned object type"; - public static final String QUERY_METHOD_S_NOT_SUPPORTED = "Query method '%s' not supported."; - private final QueryMethod queryMethod; - private final KeyValueOperations keyValueOperations; - private final PartTree tree; - - private final boolean isCount; - private final boolean isDelete; - private final boolean isDistinct; - private final boolean isExists; - private final Class targetType; - private final Class returnType; - - private boolean isRearrangeKnown; - private boolean isRearrangeRequired; - private int[] rearrangeIndex; - - private final List EMPTY_KEY = Collections.emptyList(); - - /** - * Create a {@link RepositoryQuery} implementation for each query method defined in a tarantool - * repository. - * - * @param queryMethod Method defined in Tarantool Repositories - * @param evaluationContextProvider Not used - * @param keyValueOperations Interface to Tarantool - * @param queryCreator Not used - */ - public TarantoolPartTreeQuery( - QueryMethod queryMethod, - QueryMethodEvaluationContextProvider evaluationContextProvider, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - super(queryMethod, evaluationContextProvider, keyValueOperations, queryCreator); - this.queryMethod = queryMethod; - this.keyValueOperations = keyValueOperations; - this.isRearrangeKnown = false; - this.targetType = queryMethod.getEntityInformation().getJavaType(); - this.returnType = queryMethod.getReturnedObjectType(); - this.tree = new PartTree(getQueryMethod().getName(), targetType); - if (queryMethod.getParameters().getNumberOfParameters() > 0) { - this.isCount = tree.isCountProjection(); - this.isDelete = tree.isDelete(); - this.isDistinct = tree.isDistinct(); - this.isExists = tree.isExistsProjection(); - } else { - this.isCount = false; - this.isDelete = false; - this.isDistinct = false; - this.isExists = false; - } - } - - /** - * Execute this query instance, using any invocation parameters. - * - *

Expecting {@code findBy...()}, {@code countBy...()} or {@code deleteBy...()} - * - * @param parameters Any parameters - * @return Query result - */ - @Override - public Object execute(@NonNull Object[] parameters) { - ParametersParameterAccessor accessor = this.prepareAccessor(parameters, tree); - - KeyValueQuery query = prepareQuery(accessor); - - if (this.isCount) { - if (this.isDistinct) { - final Iterable iterable = this.keyValueOperations.find(query, targetType); - return StreamUtils.createStreamFromIterator(iterable.iterator()).distinct().count(); - } - return this.keyValueOperations.count(query, targetType); - } - - if (this.isDelete) { - return this.executeDeleteQuery(query); - } - - if (this.isExists) { - query.setOffset(0); - query.setRows(1); - final Iterable result = this.keyValueOperations.find(query, targetType); - return result.iterator().hasNext(); - } - - if (queryMethod.isPageQuery()) { - return this.executePageQuery(query, accessor); - } - - if (queryMethod.isSliceQuery()) { - return this.executeSliceQuery(query, accessor); - } - - if (queryMethod.isScrollQuery()) { - return this.executeScrollQuery(query, accessor); - } - - if (queryMethod.isCollectionQuery() - || queryMethod.isQueryForEntity() - || queryMethod.isStreamQuery()) { - return this.executeFindQuery(query); - } - - throw new UnsupportedOperationException( - String.format(QUERY_METHOD_S_NOT_SUPPORTED, queryMethod.getName())); - } - - /** - * Execute a "delete" query, not really a query more of an operation. - * - *

- * - * @param query The query to run - * @return Collection of deleted objects or the number of deleted objects - */ - private Object executeDeleteQuery(final KeyValueQuery query) { - - Iterable resultSet = this.keyValueOperations.find(query, targetType); - Iterator iterator = resultSet.iterator(); - - List result = new ArrayList<>(); - while (iterator.hasNext()) { - result.add(this.keyValueOperations.delete(iterator.next())); - } - - if (queryMethod.isCollectionQuery()) { - return result; - } - if (long.class.equals(returnType) || Long.class.equals(returnType)) { - return result.size(); - } - throw new UnsupportedOperationException( - String.format(ILLEGAL_RETURN_TYPE_FOR_DELETE, returnType)); - } - - /** - * Execute a retrieval query. The query engine will return this in an iterator, which may need - * conversion to a single domain entity or a stream. - * - * @param query The query to run - * @return Query result - */ - private Object executeFindQuery(final KeyValueQuery query) { - - Iterable resultSet = this.keyValueOperations.find(query, targetType); - - if (!queryMethod.isCollectionQuery() - && !queryMethod.isPageQuery() - && !queryMethod.isSliceQuery() - && !queryMethod.isStreamQuery()) { - // Singleton result - return resultSet.iterator().hasNext() ? resultSet.iterator().next() : null; - } - - Stream stream = StreamUtils.createStreamFromIterator(resultSet.iterator()); - if (this.isDistinct) { - stream = stream.distinct(); - } - - if (queryMethod.isStreamQuery()) { - return stream; - } - - // optimization: - // we can omit if condition - // but this will recreate result even if it's not distinct and isn't stream query - if (this.isDistinct) { - return stream.collect(Collectors.toList()); - } - - return resultSet; - } - - private Object executeScrollQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - ScrollPosition scrollPosition = accessor.getScrollPosition(); - - Assert.notNull( - scrollPosition, - "The ScrollPosition parameter must be specified. Method: " + queryMethod.getName()); - - if (!(scrollPosition instanceof TarantoolKeysetScrollPosition keysetScrollPosition)) { - throw new IllegalArgumentException( - "ScrollPosition must be an instance of TarantoolKeysetScrollPosition. Method: " - + queryMethod.getName()); - } - - int pageSize = query.getRows(); - List content = doScrollQuery(query, keysetScrollPosition, pageSize + 1); - - boolean hasNext = content.size() > pageSize; - - final List finalResult = getPaginationSubResult(content, pageSize, FORWARD, hasNext); - return Window.from( - finalResult, - value -> - new TarantoolKeysetScrollPosition( - keysetScrollPosition.getIndexKey(), - keysetScrollPosition.getDirection(), - finalResult.get(value)), - hasNext); - } - - private List doScrollQuery( - final KeyValueQuery query, TarantoolKeysetScrollPosition scrollPosition, int pageSize) { - TarantoolCriteria criteria = castToTarantoolCriteria(query.getCriteria()); - PaginationDirection paginationDirection = scrollPosition.getDirection(); - - Object cursor = scrollPosition.getCursor(); - Pair indexKey = scrollPosition.getIndexKey(); - - Object second = EMPTY_KEY; - if (cursor == null) { - second = indexKey.getSecond(); - } - - switch (paginationDirection) { - case FORWARD -> - criteria.addCondition(0, Condition.create(GREATER_EQ, indexKey.getFirst(), second)); - case BACKWARD -> - criteria.addCondition(0, Condition.create(LESS_EQ, indexKey.getFirst(), second)); - } - - criteria.withAfter(cursor); - query.setRows(pageSize); - return IterableConverter.toList(this.keyValueOperations.find(query, targetType)); - } - - /** - * Execute the slice request. - * - * @param query query - * @param accessor accessor - * @return slice selection result. - */ - private Object executePageQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - - Pageable pageParams = accessor.getPageable(); - - return doPageQuery(pageParams, query, this.keyValueOperations, targetType); - } - - private Object executeSliceQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - - Pageable sliceParams = accessor.getPageable(); - - if (sliceParams.isUnpaged()) { - return new TarantoolSliceImpl<>(Collections.emptyList()); - } - - TarantoolPageable resultSliceParams = castToTarantoolPageable(sliceParams); - - int pageSize = resultSliceParams.getPageSize(); - - List content = - doPaginationQuery( - query, resultSliceParams, pageSize + 1, this.keyValueOperations, targetType); - - if (content.isEmpty()) { - return new TarantoolSliceImpl<>(); - } - - boolean hasNext = content.size() > resultSliceParams.getPageSize(); - PaginationDirection paginationDirection = resultSliceParams.getPaginationDirection(); - - List result = getPaginationSubResult(content, pageSize, paginationDirection, hasNext); - return new TarantoolSliceImpl<>(result, resultSliceParams, hasNext); - } - - /** - * Returns {@link TarantoolPageable} cast from {@link Pageable} with type checking. - * - * @param sliceParams pageable - * @return {@link TarantoolPageable} - */ - private TarantoolPageable castToTarantoolPageable(Pageable sliceParams) { - Assert.isInstanceOf(TarantoolPageable.class, sliceParams, "Pageable must be TarantoolPageable"); - return (TarantoolPageable) sliceParams; - } - - /** - * The method allows you to get {@link TarantoolCriteria} even when pagination is used through - * methods the base repository (not via derived methods). - * - * @param criteria criteria object - * @return An instance of {@link TarantoolCriteria}, or creates a new one if null. - */ - private TarantoolCriteria castToTarantoolCriteria(Object criteria) { - if (criteria == null) { - return new TarantoolCriteria(); - } - - if (!(criteria instanceof TarantoolCriteria)) { - throw new IllegalArgumentException("criteria must be instance of TarantoolCriteria"); - } - return (TarantoolCriteria) criteria; - } - - private List getPaginationSubResult( - List content, int pageSize, PaginationDirection direction, boolean hasNext) { - if (hasNext) { - switch (direction) { - case FORWARD -> { - return content.subList(0, pageSize); - } - case BACKWARD -> { - return content.subList(1, content.size()); - } - } - } - return content; - } - - /** - * Create the query from the bind parameters. - * - * @return A ready-to-use query - */ - @NonNull - protected KeyValueQuery prepareQuery(ParametersParameterAccessor accessor) { - KeyValueQuery query = createQuery(accessor); - - /* - If there is no limitation in the name of the method, we always put a - limit so that don't think about this in the engine, especially when distinguishing between a regular query and a - paginated query. - */ - if (!tree.isLimiting()) { - query.setRows(SelectOptions.DEFAULT_LIMIT); - } - - Limit limit = accessor.getLimit(); - if (limit.isLimited()) { - final int max = limit.max(); - if (max < 0) { - throw new IllegalArgumentException( - "The max number of potential results should be positive! Method: " - + queryMethod - + ". Limit: " - + max); - } - query.setRows(limit.max()); - } - - if (accessor.getSort() != Sort.unsorted()) { - query.setSort(accessor.getSort()); - } - - return query; - } - - /** - * Handle {@code @Param}. - * - *
    - *
  1. Without {@code @Param} - *

    Arguments to the call are assumed to follow the same sequence as cited in the method - * name.
    - * Eg. - *

    -   *     findByOneAndTwo(String one, String two);
    -   *     
    - *
  2. With {@code @Param} - *

    Arguments to the call are use the {@code @Param} to match them against the fields. - *

    Eg. - *

    -   *   findByOneAndTwo(@Param("two") String two, @Param("one") String one);
    -   *   
    - *
- * - * @param originalParameters Possibly empty - * @param partTree Query tree to traverse - * @return Parameters in correct order - */ - private ParametersParameterAccessor prepareAccessor( - final Object[] originalParameters, final PartTree partTree) { - - if (!this.isRearrangeKnown) { - this.prepareRearrange(partTree, this.queryMethod.getParameters().getBindableParameters()); - this.isRearrangeKnown = true; - } - - Object[] parameters = originalParameters; - Assert.notNull(parameters, "Parameters must not be null."); - - if (this.isRearrangeRequired) { - parameters = new Object[originalParameters.length]; - - for (int i = 0; i < parameters.length; i++) { - int index = (i < rearrangeIndex.length) ? rearrangeIndex[i] : i; - parameters[i] = originalParameters[index]; - } - } - - return new ParametersParameterAccessor(this.queryMethod.getParameters(), parameters); - } - - /** - * Determine if the arguments to the method need reordered. - * - *

For searches such as {@code findBySomethingNotNull} there may be more parts than parameters - * needed to be bound to them. - * - * @param partTree Query parts - * @param bindableParameters Parameters expected - */ - @SuppressWarnings("unchecked") - private void prepareRearrange( - final PartTree partTree, final Parameters bindableParameters) { - - this.isRearrangeRequired = false; - if (partTree == null || bindableParameters == null) { - return; - } - - List queryParams = new ArrayList<>(); - List methodParams = new ArrayList<>(); - - for (Part part : partTree.getParts()) { - queryParams.add(part.getProperty().getSegment()); - } - - Iterator bindableParameterIterator = - (Iterator) bindableParameters.iterator(); - while (bindableParameterIterator.hasNext()) { - Parameter parameter = bindableParameterIterator.next(); - parameter.getName().ifPresent(methodParams::add); - } - - this.rearrangeIndex = new int[queryParams.size()]; - - String[] paramsExpected = queryParams.toArray(new String[0]); - String[] paramsProvided = methodParams.toArray(new String[0]); - - for (int i = 0; i < this.rearrangeIndex.length; i++) { - this.rearrangeIndex[i] = i; - - for (int j = 0; j < paramsProvided.length; j++) { - if (paramsProvided[j] != null && paramsProvided[j].equals(paramsExpected[i])) { - this.rearrangeIndex[i] = j; - this.isRearrangeRequired = true; - } - } - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolQueryCreator.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolQueryCreator.java deleted file mode 100644 index d69434b1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolQueryCreator.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.mapping.PropertyPath; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -import static io.tarantool.client.crud.ConditionOperator.EQ; -import static io.tarantool.client.crud.ConditionOperator.GREATER; -import static io.tarantool.client.crud.ConditionOperator.GREATER_EQ; -import static io.tarantool.client.crud.ConditionOperator.LESS; -import static io.tarantool.client.crud.ConditionOperator.LESS_EQ; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.ConditionOperator; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolQueryCreator - extends AbstractQueryCreator, TarantoolCriteria> { - - private final Map cache = new ConcurrentHashMap<>(); - - public static final String INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE = - "Logic error for '%s' in query. "; - - public TarantoolQueryCreator(PartTree tree, ParameterAccessor parameters) { - super(tree, parameters); - } - - private String getFieldName(Part part) { - PropertyPath property = part.getProperty(); - String segment = property.toDotPath(); - Class domainType = property.getOwningType().getType(); - java.lang.reflect.Field field = ReflectionUtils.findField(domainType, segment); - - if (field == null) { - throw new IllegalArgumentException("No such field: " + segment + " in " + domainType); - } - Field annotationField = field.getAnnotation(Field.class); - - if (annotationField != null) { - String value = annotationField.value(); - if (StringUtils.hasText(value)) { - return value; - } - String name = annotationField.name(); - if (StringUtils.hasText(name)) { - return name; - } - } - - return segment; - } - - @Override - @NonNull - protected TarantoolCriteria create(Part part, @NonNull Iterator iterator) { - final TarantoolCriteria tarantoolCriteria = new TarantoolCriteria(); - - Part.Type type = part.getType(); - if (isIgnoreCase(part)) { - throw new InvalidDataAccessApiUsageException( - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "IgnoreCase isn't supported yet", - type)); - } - String property = cache.computeIfAbsent(part, this::getFieldName); - - switch (type) { - case SIMPLE_PROPERTY: - generateConditions(tarantoolCriteria, type, property, iterator, EQ); - break; - case LESS_THAN: - case BEFORE: - generateConditions(tarantoolCriteria, type, property, iterator, LESS); - break; - case LESS_THAN_EQUAL: - generateConditions(tarantoolCriteria, type, property, iterator, LESS_EQ); - break; - case GREATER_THAN: - case AFTER: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER); - break; - case GREATER_THAN_EQUAL: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER_EQ); - break; - case BETWEEN: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER, LESS); - break; - case TRUE: - tarantoolCriteria.addCondition(Condition.create(EQ, property, true)); - break; - case FALSE: - tarantoolCriteria.addCondition(Condition.create(EQ, property, false)); - break; - case IS_EMPTY: - tarantoolCriteria.addCondition(Condition.create(EQ, property, "")); - break; - case IS_NULL: - tarantoolCriteria.addCondition(Condition.create(EQ, property, null)); - break; - default: - throw new InvalidDataAccessApiUsageException(String.format("Unsupported type '%s'", type)); - } - - return tarantoolCriteria; - } - - private void generateConditions( - TarantoolCriteria tarantoolCriteria, - Part.Type type, - String property, - Iterator iterator, - ConditionOperator... operators) { - for (int i = 0; i < type.getNumberOfArguments(); i++) { - if (!iterator.hasNext()) { - throw new InvalidDataAccessApiUsageException( - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "Transmitted not enough arguments (%d of %d)", - type, - i, - type.getNumberOfArguments())); - } - tarantoolCriteria.addCondition(Condition.create(operators[i], property, iterator.next())); - } - } - - private boolean isIgnoreCase(Part part) { - switch (part.shouldIgnoreCase()) { - case ALWAYS: - Assert.state( - canUpperCase(part.getProperty()), - String.format( - "Unable to ignore case of %s types, the property '%s' must reference a String", - part.getProperty().getType().getName(), part.getProperty().getSegment())); - return true; - case WHEN_POSSIBLE: - return canUpperCase(part.getProperty()); - case NEVER: - default: - return false; - } - } - - private boolean canUpperCase(PropertyPath path) { - return String.class.equals(path.getType()); - } - - @Override - @NonNull - protected TarantoolCriteria and( - @NonNull Part part, @NonNull TarantoolCriteria base, @NonNull Iterator iterator) { - throw new UnsupportedOperationException(); - } - - @Override - @NonNull - protected TarantoolCriteria or( - @NonNull TarantoolCriteria base, @NonNull TarantoolCriteria criteria) { - throw new UnsupportedOperationException(); - } - - @Override - @NonNull - protected KeyValueQuery complete( - @Nullable final TarantoolCriteria criteria, @NonNull Sort sort) { - return new KeyValueQuery<>(criteria); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolQueryMethodImpl.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolQueryMethodImpl.java deleted file mode 100644 index 41327488..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolQueryMethodImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.lang.reflect.Method; - -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryMethod; - -import io.tarantool.spring.data.query.Query; -import io.tarantool.spring.data.query.TarantoolQueryMethod; - -/** Tarantool {@link QueryMethod} Implementation */ -public class TarantoolQueryMethodImpl extends QueryMethod implements TarantoolQueryMethod { - - private final Method method; - - public TarantoolQueryMethodImpl( - Method method, RepositoryMetadata metadata, ProjectionFactory factory) { - super(method, metadata, factory); - this.method = method; - } - - public boolean hasAnnotatedQuery() { - return getQuery() != null; - } - - public String getQueryValue(Query query) { - return (String) AnnotationUtils.getValue(query); - } - - public Query getQuery() { - return method.getAnnotation(Query.class); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolRepositoryQuery.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolRepositoryQuery.java deleted file mode 100644 index c75a56df..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolRepositoryQuery.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.RepositoryQuery; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.query.ProxyTarantoolRepositoryQuery; - -/** {@link RepositoryQuery} using String based function name to call function in Tarantool. */ -public class TarantoolRepositoryQuery implements RepositoryQuery { - - private final ProxyTarantoolRepositoryQuery proxy; - private final TarantoolQueryMethodImpl queryMethod; - - public TarantoolRepositoryQuery( - TarantoolCrudClient client, TarantoolQueryMethodImpl queryMethod) { - this.queryMethod = queryMethod; - this.proxy = new ProxyTarantoolRepositoryQuery(client, queryMethod); - } - - @Override - public Object execute(Object[] parameters) { - return proxy.execute(parameters); - } - - @Override - public QueryMethod getQueryMethod() { - return queryMethod; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolScrollPosition.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolScrollPosition.java deleted file mode 100644 index 4afb1f2b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolScrollPosition.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import org.springframework.data.domain.ScrollPosition; - -import io.tarantool.spring.data.utils.Pair; - -/** - * Use keyset pagination adapted for Tarantool crud module.. - * - * @author Nikolay Belonogov - * @see #forward(Pair) - * @see #backward(Pair) - * @see #reverse() - */ -public sealed interface TarantoolScrollPosition extends ScrollPosition - permits TarantoolKeysetScrollPosition { - - /** - * Creates a new {@link ScrollPosition} based on the key index scrolling forward. - * - * @param indexKey pair, where the first element is the name of the index on which you want to - * perform pagination. Second element is the value of the indexed field from which you want to - * paginate (exclusive). To perform pagination from the beginning of the index, pass an empty - * list as the second element of the pair. indexKey must be not {@code null}. - * @return new {@link TarantoolScrollPosition} instance. - */ - static TarantoolScrollPosition forward(Pair indexKey) { - return TarantoolKeysetScrollPosition.forward(indexKey); - } - - /** - * Creates a new {@link ScrollPosition} based on the key index scrolling backward. - * - * @param indexKey pair, where the first element is the name of the index on which you want to - * perform pagination. Second element is the value of the indexed field from which you want to - * paginate (exclusive). To perform pagination from the end of the index, pass an empty list - * as the second element of the pair. indexKey must be not {@code null}. - * @return new {@link TarantoolScrollPosition} instance. - */ - static TarantoolScrollPosition backward(Pair indexKey) { - return TarantoolKeysetScrollPosition.backward(indexKey); - } - - /** - * Return {@link TarantoolScrollPosition} with the same parameters, but with the opposite - * pagination direction. If the current {@link TarantoolScrollPosition} was set from the beginning - * of the index, the method will return the {@link TarantoolScrollPosition} set from the end of - * the index. Returns the {@link TarantoolScrollPosition} set from the beginning of the index if - * the current {@link TarantoolScrollPosition} is set from the end of the index. - * - *

Important: when this method is called, the condition specified by the index in - * the current {@link TarantoolScrollPosition} is overridden to unconditional (i.e. it will be - * searched to the end or beginning of the index) - * - * @return {@link TarantoolScrollPosition} instance. - */ - TarantoolScrollPosition reverse(); - - /** - * Return {@code true} if scrolling has backward motion. This means that the current {@link - * TarantoolScrollPosition} has the direction of movement {@link - * io.tarantool.spring.data.query.PaginationDirection#BACKWARD}. Return {@code false} if scrolling - * has forward motion ({@link io.tarantool.spring.data.query.PaginationDirection#FORWARD}). - * - * @return {@link Boolean} primitive. - */ - boolean isScrollsBackward(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolSliceImpl.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolSliceImpl.java deleted file mode 100644 index eeceb7f0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolSliceImpl.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.io.Serial; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.lang.NonNull; - -/** - * Default implementation of {@link Slice} for Tarantool. - * - * @author Nikolay Belonogov - */ -class TarantoolSliceImpl extends TarantoolChunk { - - @Serial private static final long serialVersionUID = 867755909294344406L; - - private final boolean hasNext; - - private final Pageable pageable; - - /** - * Creates a new {@link TarantoolSliceImpl} with the empty content. This will result in the - * created {@link Slice} being identical to the entire {@link List}. - */ - public TarantoolSliceImpl() { - this(Collections.emptyList(), Pageable.unpaged(), false); - } - - /** - * Creates a new {@link TarantoolSliceImpl} with the given content. This will result in the - * created {@link Slice} being identical to the entire {@link List}. - * - * @param content must not be {@literal null}. - */ - public TarantoolSliceImpl(List content) { - this(content, Pageable.unpaged(), false); - } - - /** - * Creates a new {@link TarantoolSliceImpl} with the given content and {@link Pageable}. - * - * @param content the content of this {@link Slice}, must not be {@literal null}. - * @param pageable the paging information, must not be {@literal null}. - * @param hasNext whether there's another slice following the current one. - */ - public TarantoolSliceImpl(List content, Pageable pageable, boolean hasNext) { - super(content, pageable); - - this.hasNext = hasContent() && hasNext; - this.pageable = pageable; - } - - /** - * Returns true if there is a next data slice. No data content means that the next slice does not - * exist and method will return false. - * - * @return Returns true if there is a next data slice. No data content means that the next slice - * does not exist and method will return false. - */ - @Override - public boolean hasNext() { - return hasNext && hasContent(); - } - - @Override - @NonNull - public Slice map(@NonNull Function converter) { - return new TarantoolSliceImpl<>(getConvertedContent(converter), pageable, hasNext); - } - - @Override - public String toString() { - - String contentType = "UNKNOWN"; - List content = getContent(); - - if (content.size() > 0) { - contentType = content.get(0).getClass().getName(); - } - - return String.format("Slice %d containing %s instances", getNumber(), contentType); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolSliceImpl that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return hasNext == that.hasNext && pageable.equals(that.pageable); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), hasNext, pageable); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolSortAccessor.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolSortAccessor.java deleted file mode 100644 index 11c63bdc..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolSortAccessor.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.util.Comparator; -import java.util.Map.Entry; - -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Sort.Order; -import org.springframework.data.keyvalue.core.SortAccessor; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -/** - * Implements sorting for Tarantool repository queries. - * - * @author Artyom Dubinin - */ -public class TarantoolSortAccessor implements SortAccessor>> { - - /** - * Sort on a sequence of fields, possibly none. - * - * @param query If not null, will contain one of more {@link Order} objects. - * @return A sequence of comparators or {@code null} - */ - public Comparator> resolve(KeyValueQuery query) { - if (query == null || query.getSort() == Sort.unsorted()) { - return null; - } - - throw new UnsupportedOperationException(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolWindowIterator.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolWindowIterator.java deleted file mode 100644 index 718f38ab..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/query/TarantoolWindowIterator.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.function.Function; - -import org.springframework.data.domain.Window; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * The class is a complete analogue of {@link org.springframework.data.support.WindowIterator} for - * Tarantool. - * - *

Example of usage: - * - *

- * - *
{@code
- * TarantoolScrollPosition initialScrollPosition =
- *     TarantoolScrollPosition.forward(Pair.of("pk", Collections.emptyList()));
- *
- * TarantoolWindowIterator personIterator =
- *     TarantoolWindowIterator.of(scrollPosition -> repository.findFirst10ByAge(10, scrollPosition))
- *         .startingAt(initialScrollPosition);
- *
- * List result = new ArrayList<>();
- *
- * while (personIterator.hasNext()) {
- *   result.add(personIterator.next());
- * }
- * }
- * - *
- * - * @param domain class type. - */ -public class TarantoolWindowIterator implements Iterator { - - private final Function> windowFunction; - - private TarantoolScrollPosition currentPosition; - - private @Nullable Window currentWindow; - - private @Nullable Iterator currentIterator; - - /** - * Entrypoint to create a new {@link TarantoolWindowIterator} for the given windowFunction. - * - * @param windowFunction must not be {@literal null}. - * @param domain class type. - * @return new instance of {@link TarantoolWindowIteratorBuilder}. - */ - public static TarantoolWindowIteratorBuilder of( - Function> windowFunction) { - return new TarantoolWindowIteratorBuilder<>(windowFunction); - } - - TarantoolWindowIterator( - Function> windowFunction, - TarantoolScrollPosition position) { - - this.windowFunction = windowFunction; - this.currentPosition = position; - } - - @Override - public boolean hasNext() { - - // use while loop instead of recursion to fetch the next window. - do { - if (currentWindow == null) { - currentWindow = windowFunction.apply(currentPosition); - } - - if (currentIterator == null) { - if (currentWindow != null) { - currentIterator = currentWindow.iterator(); - } - } - - if (currentIterator != null) { - - if (currentIterator.hasNext()) { - return true; - } - - if (currentWindow != null && currentWindow.hasNext()) { - - currentPosition = getNextPosition(currentWindow); - currentIterator = null; - currentWindow = null; - continue; - } - } - - return false; - } while (true); - } - - @Override - public T next() { - - if (!hasNext()) { - throw new NoSuchElementException(); - } - - return currentIterator.next(); - } - - private static TarantoolScrollPosition getNextPosition(Window window) { - return (TarantoolScrollPosition) window.positionAt(window.size() - 1); - } - - /** Builder API to construct a {@link TarantoolWindowIterator}. */ - public static class TarantoolWindowIteratorBuilder { - - private final Function> windowFunction; - - TarantoolWindowIteratorBuilder(Function> windowFunction) { - - Assert.notNull(windowFunction, "WindowFunction must not be null"); - - this.windowFunction = windowFunction; - } - - /** - * Create a {@link TarantoolWindowIterator} given {@link TarantoolScrollPosition}. - * - * @param position {@link TarantoolScrollPosition} instance. Must be not null. - * @return {@link TarantoolWindowIterator} instance. - */ - public TarantoolWindowIterator startingAt(TarantoolScrollPosition position) { - - Assert.notNull(position, "TarantoolScrollPosition must not be null"); - - return new TarantoolWindowIterator<>(windowFunction, position); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/TarantoolRepositoryFactory.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/TarantoolRepositoryFactory.java deleted file mode 100644 index 11c27ea8..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/TarantoolRepositoryFactory.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.repository; - -import java.util.Optional; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.SpelQueryCreator; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data32.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data32.repository.config.TarantoolQueryLookupStrategy; -import io.tarantool.spring.data32.repository.support.TarantoolSimpleRepository; - -/** - * Tarantool version of {@link KeyValueRepositoryFactory}, a factory to build tarantool repository - * instances. - * - *

The purpose of extending is to ensure that the {@link #getQueryLookupStrategy} method returns - * a {@link TarantoolQueryLookupStrategy} rather than the default. - * - *

The end goal of this bean is for {@link TarantoolPartTreeQuery} to be used for query - * preparation. - * - * @author Artyom Dubinin - */ -public class TarantoolRepositoryFactory extends KeyValueRepositoryFactory { - - private static final Class DEFAULT_QUERY_CREATOR = SpelQueryCreator.class; - - private final KeyValueOperations keyValueOperations; - private final Class> queryCreator; - private final TarantoolCrudClient client; - - /* Mirror functionality of super, to ensure private - * fields are set. - */ - public TarantoolRepositoryFactory( - TarantoolCrudClient client, KeyValueOperations keyValueOperations) { - this(client, keyValueOperations, DEFAULT_QUERY_CREATOR); - } - - /* Capture KeyValueOperations and QueryCreator objects after passing to super. - */ - public TarantoolRepositoryFactory( - TarantoolCrudClient client, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - - super(keyValueOperations, queryCreator); - - this.client = client; - this.keyValueOperations = keyValueOperations; - this.queryCreator = queryCreator; - } - - /** - * Ensure the mechanism for query evaluation is Tarantool specific, as the original {@code - * KeyValueQueryLookupStrategy} does not function correctly for Tarantool. - */ - @Override - protected Optional getQueryLookupStrategy( - QueryLookupStrategy.Key key, QueryMethodEvaluationContextProvider evaluationContextProvider) { - return Optional.of( - new TarantoolQueryLookupStrategy( - client, key, evaluationContextProvider, keyValueOperations, queryCreator)); - } - - @Override - protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { - return TarantoolSimpleRepository.class; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/EnableTarantoolRepositories.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/EnableTarantoolRepositories.java deleted file mode 100644 index 5bb9a359..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/EnableTarantoolRepositories.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.repository.config; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.ComponentScan.Filter; -import org.springframework.context.annotation.Import; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.config.QueryCreatorType; -import org.springframework.data.repository.config.DefaultRepositoryBaseClass; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryLookupStrategy.Key; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.spring.data32.config.properties.TarantoolProperties; -import io.tarantool.spring.data32.query.TarantoolQueryCreator; -import io.tarantool.spring.data32.repository.support.TarantoolRepositoryFactoryBean; - -@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@Import(TarantoolRepositoriesRegistrar.class) -@EnableConfigurationProperties(TarantoolProperties.class) -@QueryCreatorType(TarantoolQueryCreator.class) -public @interface EnableTarantoolRepositories { - - /** - * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation - * declarations e.g.: {@code @EnableJpaRepositories("org.my.pkg")} instead of - * {@code @EnableJpaRepositories(basePackages="org.my.pkg")}. - * - * @return value - */ - String[] value() default {}; - - /** - * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually - * exclusive with) this attribute. Use {@link #basePackageClasses()} for a type-safe alternative - * to String-based package names. - * - * @return base packages - */ - String[] basePackages() default {}; - - /** - * Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for - * annotated components. The package of each class specified will be scanned. Consider creating a - * special no-op marker class or interface in each package that serves no purpose other than being - * referenced by this attribute. - * - * @return classes - */ - Class[] basePackageClasses() default {}; - - /** - * Specifies which types are not eligible for component scanning. - * - * @return filters - */ - Filter[] excludeFilters() default {}; - - /** - * Specifies which types are eligible for component scanning. Further, narrows the set of - * candidate components from everything in {@link #basePackages()} to everything in the base - * packages that matches the given filter or filters. - * - * @return filters - */ - Filter[] includeFilters() default {}; - - /** - * Returns the postfix to be used when looking up custom repository implementations. Defaults to - * {@literal Impl}. So for a repository named {@code PersonRepository} the corresponding - * implementation class will be looked up scanning for {@code PersonRepositoryImpl}. - * - * @return postfix - */ - String repositoryImplementationPostfix() default "Impl"; - - /** - * Configures the location of where to find the Spring Data named queries properties file. - * - * @return location - */ - String namedQueriesLocation() default ""; - - /** - * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query - * methods. Defaults to {@link Key#CREATE_IF_NOT_FOUND}. - * - * @return strategy - */ - Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND; - - Class repositoryFactoryBeanClass() default TarantoolRepositoryFactoryBean.class; - - /** - * Allow custom base classes, for generic behavior shared amongst selected repositories. - * - * @return base class - */ - Class repositoryBaseClass() default DefaultRepositoryBaseClass.class; - - /** - * Configures the name of the {@link KeyValueOperations} bean to be used with the repositories - * detected. - * - * @return reference to {@link KeyValueOperations} bean. - */ - String keyValueTemplateRef() default DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; - - /** - * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be - * discovered by the repositories' infrastructure. - * - * @return result of consideration - */ - boolean considerNestedRepositories() default false; - - /** - * Configures the {@link ClientType} to be used as driver client type to connection to Tarantool. - * Must match the referenced type in {@link #keyValueTemplateRef()}} if these values differ from - * the default ones. - * - * @return the type of client through which communication with Tarantool will be made. - */ - ClientType clientType() default ClientType.CRUD; -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/TarantoolQueryLookupStrategy.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/TarantoolQueryLookupStrategy.java deleted file mode 100644 index 2bca8b94..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/TarantoolQueryLookupStrategy.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.repository.config; - -import java.lang.reflect.Method; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery; -import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.repository.core.NamedQueries; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.util.Assert; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data32.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data32.query.TarantoolQueryMethodImpl; -import io.tarantool.spring.data32.query.TarantoolRepositoryQuery; - -/** - * Ensures {@link TarantoolPartTreeQuery} is used for query preparation rather than {@link - * KeyValuePartTreeQuery} or other alternatives. - * - * @author Artyom Dubinin - */ -public class TarantoolQueryLookupStrategy implements QueryLookupStrategy { - - private final QueryMethodEvaluationContextProvider evaluationContextProvider; - private final KeyValueOperations keyValueOperations; - private final Class> queryCreator; - private final TarantoolCrudClient client; - - /** - * Required constructor, capturing arguments for use in {@link #resolveQuery}. - * - * @param client tarantool crud client - * @param key Not used - * @param evaluationContextProvider For evaluation of query expressions - * @param keyValueOperations Bean to use for Key/Value operations on Tarantool repos - * @param queryCreator Query creator - */ - public TarantoolQueryLookupStrategy( - TarantoolCrudClient client, - Key key, - QueryMethodEvaluationContextProvider evaluationContextProvider, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - - Assert.notNull(evaluationContextProvider, "EvaluationContextProvider must not be null!"); - Assert.notNull(keyValueOperations, "KeyValueOperations must not be null!"); - Assert.notNull(queryCreator, "Query creator type must not be null!"); - - this.client = client; - this.evaluationContextProvider = evaluationContextProvider; - this.keyValueOperations = keyValueOperations; - this.queryCreator = queryCreator; - } - - /** - * Use {@link TarantoolPartTreeQuery} for resolving queries against Tarantool repositories. - * - * @param method, the query method - * @param metadata, not used - * @param projectionFactory, not used - * @param namedQueries, not used - * @return A mechanism for querying Tarantool repositories - */ - public RepositoryQuery resolveQuery( - Method method, - RepositoryMetadata metadata, - ProjectionFactory projectionFactory, - NamedQueries namedQueries) { - - TarantoolQueryMethodImpl queryMethod = - new TarantoolQueryMethodImpl(method, metadata, projectionFactory); - - if (queryMethod.hasAnnotatedQuery()) { - return new TarantoolRepositoryQuery(client, queryMethod); - } - - return new TarantoolPartTreeQuery( - queryMethod, evaluationContextProvider, this.keyValueOperations, this.queryCreator); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/package-info.java deleted file mode 100644 index bad0cb98..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository config package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data32.repository.config; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/package-info.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/package-info.java deleted file mode 100644 index a5dc199a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data32.repository; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/support/package-info.java b/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/support/package-info.java deleted file mode 100644 index 7dcb200c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/support/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository support package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data32.repository.support; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/GenericTarantoolConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/GenericTarantoolConfigurationTest.java deleted file mode 100644 index 7cf38126..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/GenericTarantoolConfigurationTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.config; - -import java.io.IOException; -import java.nio.file.Files; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.test.context.TestPropertySource; - -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data32.config.properties.TarantoolProperties; -import io.tarantool.spring.data32.utils.TarantoolTestSupport; - -@TestPropertySource(properties = {Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -public abstract class GenericTarantoolConfigurationTest implements ApplicationContextAware { - - protected static TarantoolProperties testProperties; - - protected ApplicationContext applicationContext; - - @Autowired protected TarantoolProperties properties; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - @BeforeAll - static void beforeAll() throws IOException { - testProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists( - TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR.resolve( - Constants.DEFAULT_PROPERTY_FILE_NAME)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/TarantoolBoxConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/TarantoolBoxConfigurationTest.java deleted file mode 100644 index 63c84ad6..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/TarantoolBoxConfigurationTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.config; - -import java.io.IOException; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.RepeatedTest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; - -import io.tarantool.client.box.TarantoolBoxClient; -import io.tarantool.client.factory.TarantoolBoxClientBuilder; -import io.tarantool.pool.HeartbeatOpts; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data32.config.properties.TarantoolProperties; -import io.tarantool.spring.data32.utils.TarantoolTestSupport; - -@SpringBootTest(classes = {TarantoolBoxConfigurationTest.Config.class}) -public class TarantoolBoxConfigurationTest extends GenericTarantoolConfigurationTest { - - @MockBean TarantoolBoxClient client; - - @Autowired private TarantoolBoxConfiguration tarantoolBoxConfiguration; - - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testGetBoxClientBuilder() throws IOException { - assertEquals(properties, tarantoolBoxConfiguration.getProperties()); - - final TarantoolBoxClientBuilder boxClientBuilder = tarantoolBoxConfiguration.getClientBuilder(); - - if (properties.getConnectionGroups() == null) { - assertNull(boxClientBuilder.getGroups()); - } else { - Assertions.assertEquals( - properties.getConnectionGroups().size(), boxClientBuilder.getGroups().size()); - List connectionGroupsFromBuilder = boxClientBuilder.getGroups(); - List connectionGroupsFromProperty = - properties.getInstanceConnectionGroups(); - - assertNotNull(connectionGroupsFromBuilder); - assertNotNull(connectionGroupsFromProperty); - for (int i = 0; i < connectionGroupsFromBuilder.size(); i++) { - InstanceConnectionGroup groupFromBuilder = connectionGroupsFromBuilder.get(i); - InstanceConnectionGroup groupFromProperty = connectionGroupsFromProperty.get(i); - - assertEquals(groupFromProperty.getAuthType(), groupFromBuilder.getAuthType()); - assertEquals(groupFromProperty.getTag(), groupFromBuilder.getTag()); - assertEquals(groupFromProperty.getSize(), groupFromBuilder.getSize()); - assertEquals(groupFromProperty.getUser(), groupFromBuilder.getUser()); - assertEquals(groupFromProperty.getPassword(), groupFromBuilder.getPassword()); - assertEquals(groupFromProperty.getPort(), groupFromBuilder.getPort()); - assertEquals(groupFromProperty.getHost(), groupFromBuilder.getHost()); - } - } - - final HeartbeatOpts propertiesHeartbeatOpts = properties.getHeartbeatOpts(); - if (propertiesHeartbeatOpts == null) { - assertNull(boxClientBuilder.getHeartbeatOpts()); - } else { - HeartbeatOpts builderHeartbeatOpts = boxClientBuilder.getHeartbeatOpts(); - assertEquals( - propertiesHeartbeatOpts.getPingInterval(), builderHeartbeatOpts.getPingInterval()); - assertEquals( - propertiesHeartbeatOpts.getDeathThreshold(), builderHeartbeatOpts.getDeathThreshold()); - assertEquals( - propertiesHeartbeatOpts.getInvalidationThreshold(), - builderHeartbeatOpts.getInvalidationThreshold()); - assertEquals(propertiesHeartbeatOpts.getWindowSize(), builderHeartbeatOpts.getWindowSize()); - } - - Assertions.assertEquals(properties.getUserName(), boxClientBuilder.getUser()); - Assertions.assertEquals(properties.getPort(), boxClientBuilder.getPort()); - Assertions.assertEquals(properties.getEventLoopThreadsCount(), boxClientBuilder.getnThreads()); - Assertions.assertEquals(properties.getBalancerClass(), boxClientBuilder.getBalancerClass()); - Assertions.assertEquals( - properties.isGracefulShutdownEnabled(), boxClientBuilder.isGracefulShutdown()); - Assertions.assertEquals(properties.getConnectTimeout(), boxClientBuilder.getConnectTimeout()); - Assertions.assertEquals(properties.getReconnectAfter(), boxClientBuilder.getReconnectAfter()); - Assertions.assertEquals(properties.getHost(), boxClientBuilder.getHost()); - Assertions.assertEquals(properties.getPassword(), boxClientBuilder.getPassword()); - Assertions.assertEquals(properties.isFetchSchema(), boxClientBuilder.isFetchSchema()); - Assertions.assertEquals( - properties.isIgnoreOldSchemaVersion(), boxClientBuilder.isIgnoreOldSchemaVersion()); - - testProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @Configuration - @EnableConfigurationProperties(TarantoolProperties.class) - @Import(TarantoolBoxConfiguration.class) - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/TarantoolCrudConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/TarantoolCrudConfigurationTest.java deleted file mode 100644 index 39c60af2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/TarantoolCrudConfigurationTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.config; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.test.annotation.DirtiesContext; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.pool.HeartbeatOpts; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyHeartbeatOpts; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.spring.data32.repository.config.EnableTarantoolRepositories; - -@SpringBootTest(classes = {TarantoolCrudConfigurationTest.Config.class}) -public class TarantoolCrudConfigurationTest extends GenericTarantoolConfigurationTest { - - @MockBean TarantoolCrudClient client; - - @Autowired private TarantoolCrudConfiguration tarantoolCrudConfiguration; - - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testGetCrudClientBuilder() throws IOException { - assertEquals(properties, tarantoolCrudConfiguration.getProperties()); - - final TarantoolCrudClientBuilder crudClientBuilder = - tarantoolCrudConfiguration.getClientBuilder(); - - if (properties.getConnectionGroups() == null) { - assertNull(crudClientBuilder.getGroups()); - } else { - assertEquals(properties.getConnectionGroups().size(), crudClientBuilder.getGroups().size()); - List connectionGroupsFromBuilder = crudClientBuilder.getGroups(); - List connectionGroupsFromProperty = - properties.getConnectionGroups(); - assertNotNull(connectionGroupsFromBuilder); - assertNotNull(connectionGroupsFromProperty); - for (int i = 0; i < connectionGroupsFromBuilder.size(); i++) { - InstanceConnectionGroup groupFromBuilder = connectionGroupsFromBuilder.get(i); - PropertyInstanceConnectionGroup groupFromProperty = connectionGroupsFromProperty.get(i); - - assertEquals(groupFromProperty.getAuthType(), groupFromBuilder.getAuthType()); - assertEquals(groupFromProperty.getTag(), groupFromBuilder.getTag()); - assertEquals(groupFromProperty.getConnectionGroupSize(), groupFromBuilder.getSize()); - assertEquals(groupFromProperty.getUserName(), groupFromBuilder.getUser()); - assertEquals(groupFromProperty.getPassword(), groupFromBuilder.getPassword()); - assertEquals(groupFromProperty.getPort(), groupFromBuilder.getPort()); - assertEquals(groupFromProperty.getHost(), groupFromBuilder.getHost()); - } - } - - final PropertyHeartbeatOpts propertiesHeartbeatOpts = properties.getHeartbeat(); - if (propertiesHeartbeatOpts == null) { - assertNull(crudClientBuilder.getHeartbeatOpts()); - } else { - HeartbeatOpts builderHeartbeatOpts = crudClientBuilder.getHeartbeatOpts(); - - assertEquals( - propertiesHeartbeatOpts.getPingInterval(), builderHeartbeatOpts.getPingInterval()); - assertEquals( - propertiesHeartbeatOpts.getDeathThreshold(), builderHeartbeatOpts.getDeathThreshold()); - assertEquals( - propertiesHeartbeatOpts.getInvalidationThreshold(), - builderHeartbeatOpts.getInvalidationThreshold()); - assertEquals(propertiesHeartbeatOpts.getWindowSize(), builderHeartbeatOpts.getWindowSize()); - } - - assertEquals(properties.getUserName(), crudClientBuilder.getUser()); - assertEquals(properties.getPort(), crudClientBuilder.getPort()); - assertEquals(properties.getEventLoopThreadsCount(), crudClientBuilder.getnThreads()); - assertEquals(properties.getBalancerClass(), crudClientBuilder.getBalancerClass()); - assertEquals(properties.isGracefulShutdownEnabled(), crudClientBuilder.isGracefulShutdown()); - assertEquals(properties.getConnectTimeout(), crudClientBuilder.getConnectTimeout()); - assertEquals(properties.getReconnectAfter(), crudClientBuilder.getReconnectAfter()); - assertEquals(properties.getHost(), crudClientBuilder.getHost()); - assertEquals(properties.getPassword(), crudClientBuilder.getPassword()); - - testProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @Test - void testKeyValueTemplate() { - final List beanDefinitions = Arrays.asList(applicationContext.getBeanDefinitionNames()); - assertTrue(beanDefinitions.contains(DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF)); - - final KeyValueTemplate keyValueTemplate = - applicationContext.getBean( - DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF, KeyValueTemplate.class); - assertNotNull(keyValueTemplate); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/TarantoolEmptyPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/TarantoolEmptyPropertiesTest.java deleted file mode 100644 index 4df85617..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/TarantoolEmptyPropertiesTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.config; - -import java.io.IOException; -import java.nio.file.Files; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.TestPropertySource; - -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data32.config.properties.TarantoolProperties; -import io.tarantool.spring.data32.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data32.utils.TarantoolTestSupport; - -/** - * @see TarantoolPropertiesTest - */ -@SpringBootTest(classes = {TarantoolEmptyPropertiesTest.Config.class}) -@TestPropertySource(properties = {Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -@Timeout(5) -public class TarantoolEmptyPropertiesTest { - - @Autowired private TarantoolProperties springParsedProperties; - - @BeforeAll - static void beforeAll() throws IOException { - TarantoolTestSupport.writeTestEmptyPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - /* - * The test checks that if property processing is enabled via the @EnableConfigurationProperties annotation, then - * TarantoolProperty always exists and has default values. - */ - @Test - void testParseEmptyProperties() { - assertNotNull(springParsedProperties); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists( - TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR.resolve( - Constants.DEFAULT_PROPERTY_FILE_NAME)); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/TarantoolPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/TarantoolPropertiesTest.java deleted file mode 100644 index 135db8ad..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/config/TarantoolPropertiesTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.config; - -import java.io.IOException; -import java.nio.file.Files; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Timeout; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.TestPropertySource; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data32.config.properties.TarantoolProperties; -import io.tarantool.spring.data32.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data32.utils.TarantoolTestSupport; - -/** - * The test checks whether the Spring framework parses a file with the specified properties - * correctly. Before creating the test class, a random file with properties is written to the - * classpath:properties-test.yaml file. Next, when creating a test class the Spring context is - * raised and parses the file with properties. A test is launched to check the uniqueness of the - * current properties and properties that were specified in the previous iteration. It is checked - * that the generated Spring class TarantoolProperty is equal to the class written to the file. - * Next, the next entry to the file occurs, after which there is a forced reload of the Spring - * context -> the file with properties is parsed again and everything happens according to circle. - */ -@SpringBootTest(classes = {TarantoolPropertiesTest.Config.class}) -@TestPropertySource(properties = {Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -@Timeout(5) -public class TarantoolPropertiesTest { - - private static TarantoolProperties writtenToFileProperties; - private static TarantoolProperties prevSpringParsedProperties; - private static TarantoolProperties prevWrittenToFileProperties; - @Autowired private TarantoolProperties springParsedProperties; - - @MockBean private TarantoolCrudClient client; - - @BeforeAll - static void beforeAll() throws IOException { - writtenToFileProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists( - TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR.resolve( - Constants.DEFAULT_PROPERTY_FILE_NAME)); - } - - /** - * The annotation allows you to tell Spring that the context is dirty and needs to be reloaded - * after the test. - */ - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testParseProperty() throws IOException { - assertNotEquals(prevWrittenToFileProperties, writtenToFileProperties); - assertNotEquals(prevSpringParsedProperties, springParsedProperties); - assertEquals(writtenToFileProperties, springParsedProperties); - - prevWrittenToFileProperties = writtenToFileProperties; - prevSpringParsedProperties = springParsedProperties; - - // Write the Properties class that will be parsed by Spring in the next iteration. - writtenToFileProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/core/annotation/IdClassResolverTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/core/annotation/IdClassResolverTest.java deleted file mode 100644 index e384b238..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/core/annotation/IdClassResolverTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.core.annotation; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import io.tarantool.spring.data32.utils.entity.ComplexPerson; -import io.tarantool.spring.data32.utils.entity.CompositePersonKey; -import io.tarantool.spring.data32.utils.entity.EntityWithAnnotationAsIdClass; -import io.tarantool.spring.data32.utils.entity.Person; - -@Timeout(5) -class IdClassResolverTest { - - public static final DefaultIdClassResolver ID_CLASS_RESOLVER = DefaultIdClassResolver.INSTANCE; - - @Test - void testResolveIdClassTypeWithNullEntity() { - - final IllegalArgumentException throwable = - assertThrows( - IllegalArgumentException.class, () -> ID_CLASS_RESOLVER.resolveIdClassType(null)); - final String EXCEPTION_MESSAGE = "Type for IdClass must be not null!"; - assertEquals(EXCEPTION_MESSAGE, throwable.getMessage()); - } - - @Test - void testResolveIdClassTypeWithEntityWithoutAnnotation() { - assertNull(ID_CLASS_RESOLVER.resolveIdClassType(Person.class)); - } - - @Test - void testResolveIdClassTypeWithEntityWithAnnotation() { - assertEquals( - ID_CLASS_RESOLVER.resolveIdClassType(ComplexPerson.class), CompositePersonKey.class); - } - - @Test - void testResolveIdClassTypeWithCrossAnnotation() { - final IllegalArgumentException throwable = - assertThrows( - IllegalArgumentException.class, - () -> ID_CLASS_RESOLVER.resolveIdClassType(EntityWithAnnotationAsIdClass.class)); - - assertEquals(DefaultIdClassResolver.ANNOTATION_TYPE_EXCEPTION, throwable.getMessage()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/core/mapping/KeyValueCompositePropertyTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/core/mapping/KeyValueCompositePropertyTest.java deleted file mode 100644 index e4157cb0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/core/mapping/KeyValueCompositePropertyTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.core.mapping; - -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.ReflectionUtils; - -public class KeyValueCompositePropertyTest

> { - - private @Nullable Identifier

identifier; - - @BeforeEach - public void setUp() { - this.identifier = null; - } - - /** Check methods for adding and retrieving parts of a composite key. */ - @Test - public void testAddAndGetParts() { - Class entityClass = TestEntity.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - - ReflectionUtils.FieldFilter isIdFieldFiler = field -> field.isAnnotationPresent(Id.class); - ReflectionUtils.doWithFields(entityClass, field -> addPart(field, owner), isIdFieldFiler); - - assertNotNull(identifier); - List identifierFieldsFromProperties = - this.identifier.getParts().stream() - .map(PersistentProperty::getField) - .collect(Collectors.toList()); - - compareFieldCollection(identifierFieldsFromProperties, getExpectedIdFields(entityClass)); - } - - /** Check methods for adding and retrieving parts of a composite key. */ - @Test - public void testAddAndGetFields() { - Class entityClass = TestEntity.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - - ReflectionUtils.FieldFilter isIdFieldFiler = field -> field.isAnnotationPresent(Id.class); - ReflectionUtils.doWithFields(entityClass, field -> addPart(field, owner), isIdFieldFiler); - - assertNotNull(identifier); - List fieldsFromIdentifier = Arrays.asList(identifier.getFields()); - - compareFieldCollection(fieldsFromIdentifier, getExpectedIdFields(entityClass)); - } - - /** - * Check methods for adding and getting parts of a composite key for an object without - * {@code @Id}. - */ - @Test - public void testAddAndGetPartsWithEntityWithoutId() { - Class entityClass = TestEntityWithoutId.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - ReflectionUtils.doWithFields( - entityClass, field -> addPart(field, owner), field -> field.isAnnotationPresent(Id.class)); - - assertNull(identifier); - } - - static class TestEntity { - - @Id private long id; - - @Id private int secondId; - } - - static class TestEntityWithoutId { - - private long id; - - @Nullable private String name; - - private int secondId; - } - - /** Create a PersistentProperty and add to first id property. */ - @SuppressWarnings("unchecked") - private void addPart(Field field, PersistentEntity owner) { - Property property = Property.of(owner.getTypeInformation(), field); - Identifier

persistentProperty = - new KeyValueCompositeProperty<>(property, owner, SimpleTypeHolder.DEFAULT); - - if (this.identifier == null) { - this.identifier = persistentProperty; - } - this.identifier.addPart((P) persistentProperty); - } - - /** Compare fields by name and type. */ - private void compareFieldCollection(List first, List second) { - assertEquals(first.size(), second.size()); - - first.sort(Comparator.comparing(Field::getName)); - second.sort(Comparator.comparing(Field::getName)); - - for (int i = 0; i < first.size(); i++) { - assertEquals(first.get(i).getName(), second.get(i).getName()); - assertEquals(first.get(i).getType(), second.get(i).getType()); - } - } - - /** Get the expected fields marked with the {@code @Id} annotation. */ - private List getExpectedIdFields(Class entityClass) { - return Arrays.stream(entityClass.getDeclaredFields()) - .filter(field -> field.isAnnotationPresent(Id.class)) - .collect(Collectors.toList()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/core/mapping/TarantoolMappingContextTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/core/mapping/TarantoolMappingContextTest.java deleted file mode 100644 index b99d7a23..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/core/mapping/TarantoolMappingContextTest.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.core.mapping; - -import java.lang.reflect.Field; -import java.util.HashSet; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data32.core.mapping.BasicKeyValueCompositePersistentEntity.KeyPartTypeChecker; -import io.tarantool.spring.data32.utils.entity.ComplexPerson; -import io.tarantool.spring.data32.utils.entity.EntityWithWrongCompositeKeyPartsCount; -import io.tarantool.spring.data32.utils.entity.EntityWithWrongFieldTypes; -import io.tarantool.spring.data32.utils.entity.Person; - -class TarantoolMappingContextTest { - - @Test - void testSetFallbackKeySpaceResolver() throws NoSuchFieldException { - final KeySpaceResolver RESOLVER = TestResolver.INSTANCE; - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - mappingContext.setKeySpaceResolver(RESOLVER); - - final Field field = TarantoolMappingContext.class.getDeclaredField("keySpaceResolver"); - ReflectionUtils.makeAccessible(field); - - final Object resolverFieldValue = ReflectionUtils.getField(field, mappingContext); - - assertEquals(RESOLVER, resolverFieldValue); - } - - @Test - void testCreatePersistentEntity() { - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - final TypeInformation informationForSimpleClass = TypeInformation.of(Person.class); - - final TypeInformation informationForIdentifierClass = - TypeInformation.of(ComplexPerson.class); - - assertInstanceOf( - KeyValueCompositePersistentEntity.class, createEntityForClass(ComplexPerson.class)); - - assertInstanceOf(KeyValuePersistentEntity.class, createEntityForClass(ComplexPerson.class)); - } - - @Test - void testCreatePersistentProperty() { - ReflectionUtils.FieldFilter idFilter = field -> field.isAnnotationPresent(Id.class); - - PersistentProperty simpleIdProperty = createProperty(Person.class, idFilter); - assertInstanceOf(KeyValuePersistentProperty.class, simpleIdProperty); - - PersistentProperty compositeIdProperty = createProperty(ComplexPerson.class, idFilter); - assertInstanceOf(KeyValueCompositeProperty.class, compositeIdProperty); - } - - @Test - void testCreateEntityWithWrongCompositeKeyPartTypes() { - Set> initialSet = - new HashSet>() { - { - add(EntityWithWrongFieldTypes.class); - } - }; - IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> initEntities(initialSet)); - - Assertions.assertEquals( - KeyPartTypeChecker.COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION, exception.getMessage()); - } - - @Test - void testCreateEntityWithWrongCompositeKeyPartCount() { - Set> initialSet = - new HashSet>() { - { - add(EntityWithWrongCompositeKeyPartsCount.class); - } - }; - IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> initEntities(initialSet)); - - assertEquals(KeyPartTypeChecker.COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION, exception.getMessage()); - } - - /** - * Create a mappingContext from the passed domain classes. After initialize - create for them - * PersistentEntities and add PersistentProperties to them. - * - * @param entitySet - * @return - */ - private MappingContext initEntities(Set> entitySet) { - TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - mappingContext.setInitialEntitySet(entitySet); - mappingContext.initialize(); - return mappingContext; - } - - private enum TestResolver implements KeySpaceResolver { - INSTANCE; - - @Override - @Nullable - public String resolveKeySpace(Class type) { - - Assert.notNull(type, "Type for keyspace for null!"); - - Class userClass = ClassUtils.getUserClass(type); - Object keySpace = getKeySpace(userClass); - - return keySpace != null ? keySpace.toString() : null; - } - - @Nullable - private static Object getKeySpace(Class type) { - - KeySpace keyspace = AnnotatedElementUtils.findMergedAnnotation(type, KeySpace.class); - - if (keyspace != null) { - return AnnotationUtils.getValue(keyspace); - } - - return null; - } - } - - private PersistentEntity createEntityForClass(Class entityClass) { - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - final TypeInformation informationForClass = TypeInformation.of(entityClass); - return mappingContext.createPersistentEntity(informationForClass); - } - - private

> PersistentProperty createProperty( - Class classType, ReflectionUtils.FieldFilter fieldFilter) { - - final TarantoolMappingContext, P> context = - new TarantoolMappingContext<>(); - KeyValuePersistentEntity entity = - context.createPersistentEntity(TypeInformation.of(classType)); - Field field = org.springframework.data.util.ReflectionUtils.findField(classType, fieldFilter); - assertNotNull(field); - - return context.createPersistentProperty( - Property.of(entity.getTypeInformation(), field), entity, SimpleTypeHolder.DEFAULT); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java deleted file mode 100644 index 6926aa56..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.core.mapping.model; - -import java.lang.reflect.Field; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.Test; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data32.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data32.core.mapping.BasicKeyValueCompositePersistentEntity; -import io.tarantool.spring.data32.core.mapping.KeyValueCompositeProperty; -import io.tarantool.spring.data32.utils.entity.ComplexPerson; - -public class PersistentCompositeIdIsNewStrategyTest

> { - - /** Check the strategy creation method and check whether the domain entity is new. */ - @Test - public void testForIdOnly() { - - // Currently identical like of 'of' method (version doesn't support) - PersistentCompositeIdIsNewStrategy strategy = - PersistentCompositeIdIsNewStrategy.forIdOnly(createPersistentEntity(ComplexPerson.class)); - - // Now is stub - always is false - ComplexPerson emptyEntity = new ComplexPerson(); - assertFalse(strategy.isNew(emptyEntity)); - } - - /** Check the strategy creation method and check whether the domain entity is new. */ - @Test - public void testIsNew() { - PersistentCompositeIdIsNewStrategy strategy = - PersistentCompositeIdIsNewStrategy.of(createPersistentEntity(ComplexPerson.class)); - - // Now is stub - always is false - ComplexPerson emptyEntity = new ComplexPerson(); - assertFalse(strategy.isNew(emptyEntity)); - } - - private BasicKeyValueCompositePersistentEntity createPersistentEntity(Class entityType) { - Class compositeKeyType = DefaultIdClassResolver.INSTANCE.resolveIdClassType(entityType); - assertNotNull(compositeKeyType); - - BasicKeyValueCompositePersistentEntity persistentEntity = - new BasicKeyValueCompositePersistentEntity<>( - TypeInformation.of(entityType), null, compositeKeyType); - ReflectionUtils.doWithFields(entityType, field -> addProperty(field, persistentEntity)); - return persistentEntity; - } - - /** Add Persistent property into PersistentEntity. */ - @SuppressWarnings("unchecked") - private void addProperty(Field field, BasicKeyValueCompositePersistentEntity owner) { - Property property = Property.of(owner.getTypeInformation(), field); - P persistentProperty = - (P) new KeyValueCompositeProperty<>(property, owner, SimpleTypeHolder.DEFAULT); - owner.addPersistentProperty(persistentProperty); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/CrudConfigurations.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/CrudConfigurations.java deleted file mode 100644 index 7a7b1b89..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/CrudConfigurations.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.integration.crud; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.TestPropertySource; - -import static io.tarantool.client.TarantoolClient.DEFAULT_TAG; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.PERSON_SPACE; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data32.integration.BaseIntegrationTest; -import io.tarantool.spring.data32.repository.config.EnableTarantoolRepositories; - -@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -abstract class CrudConfigurations extends BaseIntegrationTest { - - @Autowired protected TarantoolCrudClient client; - - private static InstanceConnectionGroup groupFromJavaConfig; - - private static final String PACKAGE_PATH = "io.tarantool.spring.data32.utils.core"; - - @BeforeAll - protected static void beforeAll() throws IOException { - BaseIntegrationTest.beforeAll(); - groupFromJavaConfig = - InstanceConnectionGroup.builder() - .withHost(clusterContainer.getHost()) - .withPort(clusterContainer.getPort()) - .withUser(getUsername()) - .withPassword(getPassword()) - .withTag(DEFAULT_TAG) - .withSize(4) - .build(); - } - - @BeforeEach - public void truncateSpaces() { - client.space(PERSON_SPACE).truncate().join(); - client.space(COMPLEX_PERSON_SPACE).truncate().join(); - } - - @EnableTarantoolRepositories(basePackages = {PACKAGE_PATH}) - @Configuration - static class JavaConfigConfiguration { - - @Bean - TarantoolCrudClientBuilder crudClientBuilder() { - return TarantoolFactory.crud().withGroups(Collections.singletonList(groupFromJavaConfig)); - } - } - - @EnableTarantoolRepositories(basePackages = {PACKAGE_PATH}) - @Configuration - static class ViaPropertyFileConfiguration {} - - @Test - void testSimpleClient() { - TarantoolCrudSpace space = client.space(PERSON_SPACE); - - assertEquals(0, space.select().join().size()); - - List tuple = Arrays.asList(0, true, "petya"); - List insertTuple = space.insert(tuple).join().get(); - - assertEquals(tuple, insertTuple.subList(0, insertTuple.size() - 1)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/GenericRepositoryTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/GenericRepositoryTest.java deleted file mode 100644 index c54d1d8f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/GenericRepositoryTest.java +++ /dev/null @@ -1,2080 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.integration.crud; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Limit; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.util.Streamable; - -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data32.query.TarantoolQueryCreator.INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.UNKNOWN_PERSON; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.generateAndInsertPersons; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.mapping.Tuple; -import io.tarantool.spring.data.query.Conditions; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data.utils.Pair; -import io.tarantool.spring.data32.query.TarantoolPageRequest; -import io.tarantool.spring.data32.query.TarantoolScrollPosition; -import io.tarantool.spring.data32.query.TarantoolWindowIterator; -import io.tarantool.spring.data32.utils.TarantoolTestSupport; -import io.tarantool.spring.data32.utils.core.ComplexPersonRepository; -import io.tarantool.spring.data32.utils.core.GenericPaginationMethods; -import io.tarantool.spring.data32.utils.core.PersonRepository; -import io.tarantool.spring.data32.utils.entity.ComplexPerson; -import io.tarantool.spring.data32.utils.entity.Person; - -abstract class GenericRepositoryTest extends CrudConfigurations { - - @Autowired protected ApplicationContext context; - - protected static BiFunction> - complexPersonGenerateAndInsertFunction = - (context, personCount) -> - generateAndInsertComplexPersons( - personCount, context.getBean(TarantoolCrudClient.class)); - - protected static BiFunction> - personGenerateAndInsertFunction = - (context, personCount) -> - generateAndInsertPersons(personCount, context.getBean(TarantoolCrudClient.class)); - - protected static Function> complexPersonGenerateFunction = - TarantoolTestSupport::generateComplexPersons; - - protected static Function> personGenerateFunction = - TarantoolTestSupport::generatePersons; - - protected static final int INDEX_ID_VALUE = 50; - - protected static final Pair PERSON_INDEX_KEY = Pair.of("pk", INDEX_ID_VALUE); - - protected static final Pair PERSON_INITIAL_INDEX_KEY = - Pair.of("pk", Collections.emptyList()); - - protected static Stream dataForTestRepositoryWithFindByIs() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByIs") - , ID> void testRepositoryWithFindByIs( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - List foundPersons = repository.findByName(person.getName()); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(1, foundPersons.size()); - assertEquals(person, foundPersons.get(0)); - } - - protected static Stream dataForTestRepositoryWithFindById() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindById") - , ID> void testRepositoryWithFindById( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - Optional foundPerson = repository.findById(person.generateFullKey()); - - assertTrue(foundPerson.isPresent()); - assertEquals(person, foundPerson.get()); - } - - protected static Stream dataForTestRepositoryWithFindAllById() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllById") - , ID> void testRepositoryWithFindAllById( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - Iterable foundPersons = - repository.findAllById( - persons.stream().map(PERSON::generateFullKey).collect(Collectors.toList())); - List foundPersonsAsList = - StreamSupport.stream(foundPersons.spliterator(), false) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(persons, foundPersonsAsList); - } - - protected static Stream dataForTestRepositoryWithCount() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithCount") - , ID> void testRepositoryWithCount( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - assertEquals(PERSONS_COUNT, context.getBean(repositoryClass).count()); - } - - protected static Stream dataForTestRepositoryWithCountBy() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithCountBy") - , ID> void testRepositoryWithCountBy( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - assertEquals(1, repository.countByName(person.getName())); - } - - protected static Stream dataForTestRepositoryWithDelete() { - return Stream.of( - Arguments.of( - personGenerateFunction, - PersonRepository.class, - PERSON_SPACE, - (BiFunction>) - (space, key) -> { - Tuple tuple = - space.get(Collections.singletonList(key), Person.class).join(); - if (tuple != null) { - return tuple.get(); - } - return null; - }), - Arguments.of( - complexPersonGenerateFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (BiFunction>) - (space, key) -> { - Tuple tuple = space.get(key, ComplexPerson.class).join(); - if (tuple != null) { - return tuple.get(); - } - return null; - })); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithDelete") - , ID> void testRepositoryWithDelete( - Function> generateFunction, - Class> repositoryClass, - String spaceName, - BiFunction spaceGetFunction) { - - final List persons = generateFunction.apply(PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - space.insertMany(persons).join(); - - final PERSON deletingPerson = persons.get(0); - - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - // by object - repository.delete(deletingPerson); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - space.insert(deletingPerson).join(); - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - // by id - repository.deleteById(deletingPerson.generateFullKey()); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - space.insert(deletingPerson).join(); - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - // by name - repository.deleteByName(deletingPerson.getName()); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - } - - protected static Stream dataForTestRepositoryWithExistId() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiConsumer) - (space, key) -> space.delete(Collections.singletonList(key)).join(), - PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - (BiConsumer) (space, key) -> space.delete(key).join(), - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithExistId") - , ID> void testRepositoryWithExistId( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - BiConsumer deleteConsumer, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final PERSON person = persons.get(0); - - assertTrue(repository.existsById(person.generateFullKey())); - deleteConsumer.accept(space, person.generateFullKey()); - assertFalse(repository.existsById(person.generateFullKey())); - } - - protected static Stream dataForTestQueryAnnotationAsCall() { - return Stream.of( - Arguments.of(PersonRepository.class), Arguments.of(ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsCall") - , ID> void testQueryAnnotationAsCall( - Class> repositoryClass) { - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - assertEquals(Arrays.asList(1, "hi", false), repository.getStatic().get()); - } - - protected static Stream dataForTestQueryAnnotationAsCallWithArgs() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsCallWithArgs") - , ID> void testQueryAnnotationAsCallWithArgs( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals(Arrays.asList("hello", true, 13), repository.echo("hello", true, 13).get()); - } - - protected static Stream dataForTestQueryAnnotationAsEval() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsEval") - , ID> void testQueryAnnotationAsEval( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals(Arrays.asList("hello", 123, true), repository.evalGetStatic().get()); - } - - protected static Stream dataForTestQueryAnnotationAsEvalWithArgs() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsEvalWithArgs") - , ID> void testQueryAnnotationAsEvalWithArgs( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals( - Arrays.asList("hello", true, 13), repository.evalWithArgs("hello", true, 13).get()); - } - - protected static Stream dataForTestRepositoryWithExistName() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiConsumer) - (space, key) -> space.delete(Collections.singletonList(key)).join(), - PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - (BiConsumer) (space, key) -> space.delete(key).join(), - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithExistName") - , ID> void testRepositoryWithExistName( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - BiConsumer deleteConsumer, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final PERSON person = persons.get(0); - - assertTrue(repository.existsByName(person.getName())); - deleteConsumer.accept(space, person.generateFullKey()); - assertFalse(repository.existsByName(person.getName())); - } - - protected static Stream dataForTestRepositoryWithFindByLessThan() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByLessThan") - , ID> void testRepositoryWithFindByLessThan( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 10; - final List foundPersons = repository.findAllByIdIsLessThan(findLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(findLimiter, foundPersons.size()); - assertEquals(persons.subList(0, findLimiter), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsTrue() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsTrue") - , ID> void testRepositoryWithFindAllByIsMarriedIsTrue( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsTrue(); - assertEquals(PERSONS_COUNT / 3, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(GenericPerson::getIsMarried)); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsFalse() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsFalse") - , ID> void testRepositoryWithFindAllByIsMarriedIsFalse( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsFalse(); - assertEquals(PERSONS_COUNT / 3, foundPersons.size()); - assertTrue(foundPersons.stream().noneMatch(GenericPerson::getIsMarried)); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsNull() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsNull") - , ID> void testRepositoryWithFindAllByIsMarriedIsNull( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsNull(); - assertEquals(PERSONS_COUNT / 3 + 1, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(p -> p.getIsMarried() == null)); - } - - protected static Stream dataForTestRepositoryWithFindAllByNameIsEmpty() { - return Stream.of( - Arguments.of(personGenerateFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByNameIsEmpty") - , ID> void testRepositoryWithFindAllByNameIsEmpty( - Function> generateFunction, - Class> repositoryClass) { - - List persons = generateFunction.apply(PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - PERSON person = persons.get(0); - person.setName(""); - persons.set(0, person); - - repository.saveAll(persons); - - final List foundPersons = repository.findAllByNameIsEmpty(); - assertEquals(1, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(p -> p.getName().isEmpty())); - } - - protected static Stream dataForTestRepositoryWithFindByLessThanEqual() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByLessThanEqual") - , ID> void testRepositoryWithFindByLessThanEqual( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 10; - final List foundPersonsWithEqual = repository.findAllByIdLessThanEqual(findLimiter); - - foundPersonsWithEqual.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(findLimiter + 1, foundPersonsWithEqual.size()); - assertEquals(persons.subList(0, findLimiter + 1), foundPersonsWithEqual); - } - - protected static Stream dataForTestRepositoryWithFindByGreaterThan() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByGreaterThan") - , ID> void testRepositoryWithFindByGreaterThan( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 90; - final List foundPersons = repository.findAllByIdIsGreaterThan(findLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(PERSONS_COUNT - findLimiter - 1, foundPersons.size()); - assertEquals(persons.subList(findLimiter + 1, PERSONS_COUNT), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindByGreaterThanEqual() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByGreaterThanEqual") - , ID> void testRepositoryWithFindByGreaterThanEqual( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 90; - final List foundPersonsWithEqual = repository.findAllByIdGreaterThanEqual(findLimiter); - - foundPersonsWithEqual.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(PERSONS_COUNT - findLimiter, foundPersonsWithEqual.size()); - assertEquals(persons.subList(findLimiter, PERSONS_COUNT), foundPersonsWithEqual); - } - - protected static Stream dataForTestRepositoryWithFindByBetween() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByBetween") - , ID> void testRepositoryWithFindByBetween( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int startFindLimiter = 50; - final int endFindLimiter = 90; - final List foundPersons = - repository.findAllByIdBetween(startFindLimiter, endFindLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - final int foundPersonsCount = endFindLimiter - startFindLimiter - 1; - assertEquals(foundPersonsCount, foundPersons.size()); - assertEquals(persons.subList(startFindLimiter + 1, endFindLimiter), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindByBetweenNegativeInts() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByBetweenNegativeInts") - , ID> void testRepositoryWithFindByBetweenNegativeInts( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int startFindLimiter = -1; - final int endFindLimiter = -10; - final List foundPersons = - repository.findAllByIdBetween(startFindLimiter, endFindLimiter); - assertTrue(foundPersons.isEmpty()); - } - - protected static Stream dataForTestRepositoryIgnoreCase() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryIgnoreCase") - , ID> void testRepositoryIgnoreCase( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - final String name = persons.get(0).getName(); - - final InvalidDataAccessApiUsageException exception = - assertThrows( - InvalidDataAccessApiUsageException.class, () -> repository.findByNameIgnoreCase(name)); - final String EXCEPTION_MESSAGE = - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "IgnoreCase isn't supported yet", - Part.Type.SIMPLE_PROPERTY); - assertEquals(EXCEPTION_MESSAGE, exception.getMessage()); - } - - protected static Stream dataForTestRepositoryWithTarantoolNamingNotation() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithTarantoolNamingNotation") - , ID> void testRepositoryWithTarantoolNamingNotation( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List marriedPersons = repository.findByIsMarried(true); - final List nonMarriedPersons = repository.findByIsMarried(false); - final int expectedCount = PERSONS_COUNT / 3; - assertEquals(expectedCount, marriedPersons.size()); - assertEquals(expectedCount, nonMarriedPersons.size()); - } - - protected static Stream dataForTestRepositoryNotEnoughArguments() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryNotEnoughArguments") - , ID> void testRepositoryNotEnoughArguments( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertThrows(InvalidDataAccessApiUsageException.class, repository::findById); - } - - protected static Stream dataForTestRepositorySave() { - return dataForTestRepositoryWithDelete(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySave") - , ID> void testRepositorySave( - Function> generateFunction, - Class> repositoryClass, - String spaceName, - BiFunction getFunction) { - - List persons = generateFunction.apply(PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - TarantoolCrudSpace space = client.space(spaceName); - final PERSON person = persons.get(0); - - repository.save(person); - - PERSON gotPerson = getFunction.apply(space, person.generateFullKey()); - assertEquals(person, gotPerson); - } - - protected static Stream dataForTestRepositorySaveAll() { - Conditions conditions = new Conditions(); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - PERSON_SPACE, - (Function>) - (space) -> unwrapTuples(space.select(conditions, Person.class).join())), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (Function>) - (space) -> unwrapTuples(space.select(conditions, ComplexPerson.class).join()))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySaveAll") - , ID> void testRepositorySaveAll( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - Function> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - repository.saveAll(persons); - - List selectedPersons = selectFunction.apply(space); - selectedPersons.sort(Comparator.comparing(GenericPerson::getId)); - - assertEquals(persons, selectedPersons); - } - - protected static Stream dataForTestDeleteAll() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class, PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteAll") - , ID> void testDeleteAll( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow(() -> repository.deleteAll()); - assertEquals(0, space.count(new Conditions()).join()); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow(() -> repository.deleteAll(persons)); - assertEquals(0, space.count(new Conditions()).join()); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow( - () -> - repository.deleteAllById( - persons.stream().map(PERSON::generateFullKey).collect(Collectors.toList()))); - assertEquals(0, space.count(new Conditions()).join()); - } - - protected static Stream dataForTestRepositoryFindByAfter() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByAfter") - , ID> void testRepositoryFindByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - final List selectedPersons = repository.findByNameAfter(person.getName()); - selectedPersons.sort(Comparator.comparing(PERSON::getName)); - - final List expectedList = - persons.stream() - .filter(p -> p.getName().compareTo(person.getName()) > 0) - .limit(SelectOptions.DEFAULT_LIMIT) - .sorted(Comparator.comparing(PERSON::getName)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - } - - protected static Stream dataForTestRepositoryFindByAfterWithLimit() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByAfterWithLimit") - , ID> void testRepositoryFindByAfterWithLimit( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int LIMIT = 5; - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findFirst5ByIdAfter(person.getId()); - selectedPersons.sort(Comparator.comparing(PERSON::getId)); - - final List selectedPersonsWithTopKeyword = repository.findTop5ByIdAfter(person.getId()); - selectedPersonsWithTopKeyword.sort(Comparator.comparing(PERSON::getId)); - - final List expectedList = - persons.stream() - .filter(p -> p.getId().compareTo(person.getId()) > 0) - .limit(LIMIT) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - - assertEquals(expectedList.size(), selectedPersonsWithTopKeyword.size()); - assertEquals(expectedList, selectedPersonsWithTopKeyword); - } - - protected static Stream dataForTestRepositoryFindByBefore() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByBefore") - , ID> void testRepositoryFindByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findByNameBefore(person.getName()); - selectedPersons.sort(Comparator.comparing(PERSON::getName)); - - final List expectedList = - persons.stream() - .filter(p -> p.getName().compareTo(person.getName()) < 0) - .limit(SelectOptions.DEFAULT_LIMIT) - .sorted(Comparator.comparing(PERSON::getName)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - } - - protected static Stream dataForTestRepositoryFindByBeforeWithLimit() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByBeforeWithLimit") - , ID> void testRepositoryFindByBeforeWithLimit( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int LIMIT = 5; - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findFirst5ByIdBefore(person.getId()); - selectedPersons.sort(Comparator.comparing(PERSON::getId)); - - final List selectedPersonsWithTopKeyword = - repository.findTop5ByIdBefore(person.getId()); - selectedPersonsWithTopKeyword.sort(Comparator.comparing(PERSON::getId)); - - // Because id (not fullscan) - persons.sort(Comparator.comparing(PERSON::getId, (o1, o2) -> Integer.compare(o2, o1))); - - final List expectedList = - persons.stream() - .filter(p -> p.getId().compareTo(person.getId()) < 0) - .limit(LIMIT) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - - assertEquals(expectedList.size(), selectedPersonsWithTopKeyword.size()); - assertEquals(expectedList, selectedPersonsWithTopKeyword); - } - - protected static Stream dataForTestDeleteByAfter() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - PERSON_SPACE, - (BiFunction>) - (space, options) -> - unwrapTuples( - space.select(Collections.emptyList(), options, Person.class).join())), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (BiFunction>) - (space, options) -> - unwrapTuples( - space - .select(Collections.emptyList(), options, ComplexPerson.class) - .join()))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteByAfter") - , ID> void testDeleteByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - BiFunction> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - persons.sort(Comparator.comparing(PERSON::getName)); - - final int RANDOM_INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final SelectOptions options = SelectOptions.builder().withFirst(PERSONS_COUNT).build(); - final PERSON deletingAfterPerson = persons.get(RANDOM_INDEX); - - final List deletedPersons = repository.deleteByNameAfter(deletingAfterPerson.getName()); - - List allPersonsInBaseAfterDeleted = selectFunction.apply(space, options); - assertEquals(PERSONS_COUNT - deletedPersons.size(), allPersonsInBaseAfterDeleted.size()); - - persons.removeAll(deletedPersons); - allPersonsInBaseAfterDeleted.sort(Comparator.comparing(PERSON::getId)); - persons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(persons, allPersonsInBaseAfterDeleted); - } - - protected static Stream dataForTestDeleteByBefore() { - return dataForTestDeleteByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteByBefore") - , ID> void testDeleteByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - BiFunction> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final SelectOptions options = SelectOptions.builder().withFirst(PERSONS_COUNT).build(); - final int RANDOM_INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - - final PERSON deletingBeforePerson = persons.get(RANDOM_INDEX); - final List deletedPersons = - repository.deleteByNameBefore(deletingBeforePerson.getName()); - - List allPersonsInBaseAfterDeleted = selectFunction.apply(space, options); - - assertEquals(PERSONS_COUNT - deletedPersons.size(), allPersonsInBaseAfterDeleted.size()); - - persons.removeAll(deletedPersons); - allPersonsInBaseAfterDeleted.sort(Comparator.comparing(PERSON::getId)); - persons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(persons, allPersonsInBaseAfterDeleted); - } - - protected static Stream dataForTestCountByAfter() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestCountByAfter") - , ID> void testCountByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final int ID_AFTER = persons.get(INDEX).getId(); - - final long count = repository.countByIdAfter(ID_AFTER); - - final int EXPECTED_COUNT = PERSONS_COUNT - ID_AFTER - 1; - assertEquals(EXPECTED_COUNT, count); - } - - protected static Stream dataForTestCountByBefore() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestCountByBefore") - , ID> void testCountByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - persons.sort(Comparator.comparing(PERSON::getName)); - - final int indexBefore = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final String name = persons.get(indexBefore).getName(); - final long count = repository.countByNameBefore(name); - - assertEquals(indexBefore, count); - - final long unknownNameCount = repository.countByNameBefore(UNKNOWN_PERSON.getName()); - assertEquals(0, unknownNameCount); - } - - protected static < - REPO extends GenericPaginationMethods, PERSON extends GenericPerson, ID> - Stream dataForTestRepositorySlicePagePageableEqual() { - final int PAGE_SIZE = ThreadLocalRandom.current().nextInt(1, PERSONS_COUNT / 3 - 1); - final String NAME = "name"; - final Pageable beginPageable = new TarantoolPageRequest>(PAGE_SIZE); - - BiFunction> generatePersonAndInsertFunction = - (context, size) -> - generateAndInsertPersons( - size, context.getBean(TarantoolCrudClient.class), (person) -> person.setName(NAME)); - - BiFunction> - generateComplexPersonAndInsertFunction = - (context, size) -> - generateAndInsertComplexPersons( - size, - context.getBean(TarantoolCrudClient.class), - (person) -> person.setName(NAME)); - - Function personRepositoryFunc = - (context) -> context.getBean(PersonRepository.class); - - Function complexPersonRepositoryFunc = - (context) -> context.getBean(ComplexPersonRepository.class); - - BiFunction> executionForFindAllByName = - (repo, pageable) -> repo.findAllByName(NAME, pageable); - - Function, List> expectedListForFindAllByNameFunc = - (persons) -> - persons.stream() - .filter(person -> NAME.equals(person.getName())) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()) - .subList(0, PAGE_SIZE); - - BiFunction> executionForFindByName = - (repo, pageable) -> repo.findPersonByName(NAME, pageable); - - List> generateFunctionPairs = - Arrays.asList( - Arrays.asList(generatePersonAndInsertFunction, personRepositoryFunc), - Arrays.asList(generateComplexPersonAndInsertFunction, complexPersonRepositoryFunc)); - - List executionFunctions = Arrays.asList(executionForFindAllByName, executionForFindByName); - - // add arguments set - List arguments = new ArrayList<>(); - for (List generateFunctionPair : generateFunctionPairs) { - for (Object executionFunction : executionFunctions) { - arguments.add( - Arguments.of( - generateFunctionPair.get(0), - executionFunction, - generateFunctionPair.get(1), - expectedListForFindAllByNameFunc, - beginPageable)); - } - } - - return arguments.stream(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySlicePagePageableEqual") - , PERSON extends GenericPerson, ID> - void testRepositorySlicePagePageableEqual( - BiFunction> generateAndInsertFunction, - BiFunction> executingRepositoryMethod, - Function giveRepositoryFunction, - Function, List> expectedSlicePageContent, - Pageable beginPageable) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - Slice slicePage = - executingRepositoryMethod.apply(giveRepositoryFunction.apply(context), beginPageable); - - assertEquals(beginPageable, slicePage.getPageable()); - assertEquals(expectedSlicePageContent.apply(persons), slicePage.getContent()); - } - - protected static Stream dataForTestRepositorySliceMethodWithoutPageable() { - final String NAME = "name"; - return Stream.of( - Arguments.of(PersonRepository.class, NAME), - Arguments.of(ComplexPersonRepository.class, NAME)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySliceMethodWithoutPageable") - , ID> void testRepositorySliceMethodWithoutPageable( - Class> repositoryClass, String name) { - GenericPaginationMethods repository = context.getBean(repositoryClass); - - assertEquals(Pageable.unpaged(), repository.findAllByName(name).getPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).nextPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).nextOrLastPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).previousPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).previousOrFirstPageable()); - } - - @SuppressWarnings("unchecked") - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Stream dataForTestRepositorySliceWithDifferentFields() { - final int PAGE_SIZE = 10; - - Function, Pageable> nextPageableFunc = Slice::nextPageable; - Function, Pageable> prevPageableFunc = Slice::previousPageable; - Function, Pageable> nextOrLastPageableFunc = Slice::nextOrLastPageable; - Function, Pageable> prevOrFirstPageableFunc = Slice::previousOrFirstPageable; - BiFunction predicateForNextPageableFunc = - (currentPageable, nextPageable) -> nextPageable.isPaged(); - - BiFunction predicateForNextOrPageableFunc = - (currentPageable, nextPageable) -> !currentPageable.equals(nextPageable); - - Function personRepositoryFunc = - (context) -> context.getBean(PersonRepository.class); - - Function complexPersonRepositoryFunc = - (context) -> context.getBean(ComplexPersonRepository.class); - - Pageable beginPageable = new TarantoolPageRequest<>(PAGE_SIZE); - - BiFunction, Integer, Integer> idExtractionFunction = - (args, index) -> { - List persons = (List) args.get(0); - return persons.get(index).getId(); - }; - - BiFunction, Integer, String> nameExtractionFunction = - (args, index) -> { - List persons = (List) args.get(0); - return persons.get(index).getName(); - }; - - BiFunction, Slice> executionForFindAllByIdLessThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, PERSONS_COUNT - 1); - return repo.findAllByIdLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByIdLessThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, PERSONS_COUNT - 1); - return repo.findPersonByIdLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByIdGreaterThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, 0); - return repo.findAllByIdGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByIdGreaterThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, 0); - return repo.findPersonByIdGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByIsMarriedLessThanEqual = - (repo, arguments) -> - repo.findAllByIsMarriedLessThanEqual(false, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindPersonByIsMarriedLessThanEqual = - (repo, arguments) -> - repo.findPersonByIsMarriedLessThanEqual(false, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindAllByIsMarriedGreaterThanEqual = - (repo, arguments) -> - repo.findAllByIsMarriedGreaterThanEqual(null, (Pageable) arguments.get(1)); - - BiFunction, Slice> - executionForFindPersonByIsMarriedGreaterThanEqual = - (repo, arguments) -> - repo.findPersonByIsMarriedGreaterThanEqual(null, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindAllByNameLessThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findAllByNameLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByNameLessThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findPersonByNameLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByNameGreaterThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findAllByNameGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByNameGreaterThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findPersonByNameGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAll = - (repo, arguments) -> repo.findAll((Pageable) arguments.get(1)); - - Function, List> expectedListForFindAllByIdLessThanEqualFunc = - (persons) -> - persons.stream() - .sorted(Comparator.comparing(PERSON::getId).reversed()) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByIdGreaterThanEqualFunc = - (persons) -> persons; - - Function, List> expectedListForFindAllByIsMarriedGreaterThanEqual = - (persons) -> - persons.stream() - .sorted( - Comparator.comparing( - PERSON::getIsMarried, Comparator.nullsFirst(Comparator.naturalOrder()))) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByIsMarriedLessThanEqual = - (persons) -> - persons.stream() - .filter(person -> person.getIsMarried() == null || !person.getIsMarried()) - .sorted( - Comparator.comparing( - PERSON::getIsMarried, Comparator.nullsLast(Comparator.naturalOrder())) - .thenComparing(Comparator.comparing(PERSON::getId).reversed())) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByNameLessThanEqual = - (persons) -> { - String name = persons.get(persons.size() / 2).getName(); - return persons.stream() - .filter(person -> person.getName().compareTo(name) <= 0) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - }; - - Function, List> expectedListForFindAllByNameGreaterThanEqual = - (persons) -> { - String name = persons.get(persons.size() / 2).getName(); - return persons.stream() - .filter(person -> person.getName().compareTo(name) >= 0) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - }; - - Function, List> expectedListForFindAll = (persons) -> persons; - - List> getNextPageableMethodFunctionPairs = - Arrays.asList( - Arrays.asList(nextPageableFunc, prevPageableFunc, predicateForNextPageableFunc), - Arrays.asList( - nextOrLastPageableFunc, prevOrFirstPageableFunc, predicateForNextOrPageableFunc)); - - List> generateFunctions = - Arrays.asList( - Arrays.asList(personGenerateAndInsertFunction, personRepositoryFunc), - Arrays.asList(complexPersonGenerateAndInsertFunction, complexPersonRepositoryFunc)); - - List> executeExpectedFunctionPairs = - Arrays.asList( - Arrays.asList( - executionForFindAllByIdLessThanEqualFunc, - expectedListForFindAllByIdLessThanEqualFunc), - Arrays.asList( - executionForFindAllByIdGreaterThanEqualFunc, - expectedListForFindAllByIdGreaterThanEqualFunc), - Arrays.asList( - executionForFindAllByIsMarriedGreaterThanEqual, - expectedListForFindAllByIsMarriedGreaterThanEqual), - Arrays.asList( - executionForFindAllByIsMarriedLessThanEqual, - expectedListForFindAllByIsMarriedLessThanEqual), - Arrays.asList( - executionForFindAllByNameLessThanEqual, expectedListForFindAllByNameLessThanEqual), - Arrays.asList( - executionForFindAllByNameGreaterThanEqual, - expectedListForFindAllByNameGreaterThanEqual), - Arrays.asList( - executionForFindPersonByIdLessThanEqualFunc, - expectedListForFindAllByIdLessThanEqualFunc), - Arrays.asList( - executionForFindPersonByIdGreaterThanEqualFunc, - expectedListForFindAllByIdGreaterThanEqualFunc), - Arrays.asList( - executionForFindPersonByIsMarriedGreaterThanEqual, - expectedListForFindAllByIsMarriedGreaterThanEqual), - Arrays.asList( - executionForFindPersonByIsMarriedLessThanEqual, - expectedListForFindAllByIsMarriedLessThanEqual), - Arrays.asList( - executionForFindPersonByNameLessThanEqual, - expectedListForFindAllByNameLessThanEqual), - Arrays.asList( - executionForFindPersonByNameGreaterThanEqual, - expectedListForFindAllByNameGreaterThanEqual), - Arrays.asList(executionForFindAll, expectedListForFindAll)); - - // add arguments set - List arguments = new ArrayList<>(); - for (List generateFunctionPair : generateFunctions) { - for (List getNextPrevPageableFuncTriple : getNextPageableMethodFunctionPairs) { - for (List executeExpectedFunctionPair : executeExpectedFunctionPairs) { - arguments.add( - Arguments.of( - generateFunctionPair.get(0), - generateFunctionPair.get(1), - executeExpectedFunctionPair.get(0), - getNextPrevPageableFuncTriple.get(0), - getNextPrevPageableFuncTriple.get(1), - getNextPrevPageableFuncTriple.get(2), - executeExpectedFunctionPair.get(1), - beginPageable)); - } - } - } - return arguments.stream(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySliceWithDifferentFields") - , ID> void testRepositorySliceWithDifferentFields( - BiFunction> generateAndInsertFunction, - Function> giveRepositoryFunction, - BiFunction, List, Slice> - executingRepositoryMethod, - Function, Pageable> nextPageableMethod, - Function, Pageable> prevPageableMethod, - BiFunction stopPaginationPredicateFunction, - Function, List> expectedResultListMovingFunction, - Pageable beginPageable) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - - // moving forward - Pageable nextPageable = beginPageable; - List> forwardSlices = new ArrayList<>(); - Slice slice; - do { - slice = - executingRepositoryMethod.apply( - giveRepositoryFunction.apply(context), Arrays.asList(persons, nextPageable)); - forwardSlices.add(slice); - nextPageable = nextPageableMethod.apply(slice); - } while (stopPaginationPredicateFunction.apply(slice.getPageable(), nextPageable)); - - List forwardMovingResultList = - forwardSlices.stream().flatMap(Streamable::stream).collect(Collectors.toList()); - assertEquals(expectedResultListMovingFunction.apply(persons), forwardMovingResultList); - - // moving backward - List> reverseSlices = new ArrayList<>(); - nextPageable = forwardSlices.get(forwardSlices.size() - 1).getPageable(); - do { - slice = - executingRepositoryMethod.apply( - giveRepositoryFunction.apply(context), Arrays.asList(persons, nextPageable)); - reverseSlices.add(slice); - nextPageable = prevPageableMethod.apply(slice); - } while (stopPaginationPredicateFunction.apply(slice.getPageable(), nextPageable)); - - List backwardMovingResultList = - reverseSlices.stream() - .sorted(Comparator.comparing(Slice::getNumber)) - .flatMap(Streamable::stream) - .collect(Collectors.toList()); - - assertEquals(expectedResultListMovingFunction.apply(persons), backwardMovingResultList); - } - - protected static , ID> - List expectedForwardFuncForFindFirst5ByIsMarriedInitial(List persons) { - return persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst5ByIsMarriedInitial(List persons) { - List result = - new ArrayList<>(expectedForwardFuncForFindFirst5ByIsMarriedInitial(persons)); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial( - List persons) { - return persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial( - List persons) { - List result = - new ArrayList<>( - expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial(persons)); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst5ByIsMarriedIndexKey(List persons) { - return persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst5ByIsMarriedIndexKey(List persons) { - List result = - new ArrayList<>( - persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .sorted(Comparator.comparing(PERSON::getId)) - .toList()); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey( - List persons) { - return persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey( - List persons) { - List result = - new ArrayList<>( - persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .sorted(Comparator.comparing(PERSON::getId)) - .toList()); - Collections.reverse(result); - return result; - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Window executionFunctionForFindFirst5ByIsMarried(REPO repository, List args) { - ScrollPosition scrollPosition = (ScrollPosition) args.get(0); - return repository.findFirst5ByIsMarried(false, scrollPosition); - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Window executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual( - REPO repository, List args) { - ScrollPosition scrollPosition = (ScrollPosition) args.get(0); - return repository.findFirst10ByIsMarriedGreaterThanEqual(false, scrollPosition); - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Stream dataForTestRepositoryScrollForwardAndBackwardMoving() { - - ScrollPosition beginScrollPositionInitial = - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY); - ScrollPosition beginScrollPositionIndexKey = TarantoolScrollPosition.forward(PERSON_INDEX_KEY); - - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst5ByIsMarried, - (Function, List>) - GenericRepositoryTest::expectedForwardFuncForFindFirst5ByIsMarriedInitial, - (Function, List>) - GenericRepositoryTest::expectedBackwardFuncForFindFirst5ByIsMarriedInitial, - beginScrollPositionInitial), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst5ByIsMarried, - (Function, List>) - GenericRepositoryTest::expectedForwardFuncForFindFirst5ByIsMarriedIndexKey, - (Function, List>) - GenericRepositoryTest::expectedBackwardFuncForFindFirst5ByIsMarriedIndexKey, - beginScrollPositionIndexKey), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual, - (Function, List>) - GenericRepositoryTest - ::expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial, - (Function, List>) - GenericRepositoryTest - ::expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial, - beginScrollPositionInitial), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual, - (Function, List>) - GenericRepositoryTest - ::expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey, - (Function, List>) - GenericRepositoryTest - ::expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey, - beginScrollPositionIndexKey)); - } - - @ParameterizedTest - @MethodSource("dataForTestRepositoryScrollForwardAndBackwardMoving") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryScrollForwardAndBackwardMoving( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - BiFunction, Window> executingRepositoryMethod, - Function, List> expectedForwardResultFunction, - Function, List> expectedBackwardResultFunction, - ScrollPosition beginScrollPosition) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - Window personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(beginScrollPosition)); - List forwardResult = new ArrayList<>(); - - while (!personWindow.isEmpty() && personWindow.hasNext()) { - personWindow.forEach(forwardResult::add); - ScrollPosition nextPosition = personWindow.positionAt(personWindow.size() - 1); - personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(nextPosition)); - } - personWindow.forEach(forwardResult::add); - - assertEquals(expectedForwardResultFunction.apply(persons), forwardResult); - - TarantoolScrollPosition backwardScrollPosition = - ((TarantoolScrollPosition) personWindow.positionAt(0)).reverse(); - List backwardResult = personWindow.getContent(); - Collections.reverse(backwardResult); - - personWindow = - executingRepositoryMethod.apply( - repository, Collections.singletonList(backwardScrollPosition)); - while (!personWindow.isEmpty() && personWindow.hasNext()) { - personWindow.forEach(backwardResult::add); - ScrollPosition nextPosition = personWindow.positionAt(personWindow.size() - 1); - personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(nextPosition)); - } - personWindow.forEach(backwardResult::add); - - assertEquals(expectedBackwardResultFunction.apply(persons), backwardResult); - } - - protected static > - Stream dataForTestWindowIterator() { - return Stream.of( - Arguments.of( - (BiFunction>) - (context, size) -> Collections.emptyList(), - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY), - (Function, List>) (persons) -> Collections.emptyList(), - (Function, List>) (persons) -> Collections.emptyList()), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY), - (Function, List>) (persons) -> persons, - (Function, List>) - (persons) -> { - Collections.reverse(persons); - return persons; - }), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INDEX_KEY), - (Function, List>) - GenericRepositoryTest::expectedWindowIteratorForwardFromSomeCursor, - (Function, List>) - GenericRepositoryTest::expectedWindowIteratorBackwardFromSomeCursor)); - } - - protected static , ID> - List expectedWindowIteratorForwardFromSomeCursor(List persons) { - return persons.stream() - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .collect(Collectors.toList()); - } - - protected static , ID> - List expectedWindowIteratorBackwardFromSomeCursor(List persons) { - return persons.stream() - .filter(person -> person.getId() <= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId).reversed()) - .collect(Collectors.toList()); - } - - @ParameterizedTest - @MethodSource("dataForTestWindowIterator") - , ID, REPO extends GenericPaginationMethods> - void testWithWindowIteratorMoving( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - TarantoolScrollPosition beginScrollPosition, - Function, List> expectedForwardResultFunction, - Function, List> expectedBackwardResultFunction) { - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - TarantoolWindowIterator personForwardIterator = - TarantoolWindowIterator.of( - scrollPosition -> - repository.findFirst10ByIsMarriedGreaterThanEqual(null, scrollPosition)) - .startingAt(beginScrollPosition); - - List forwardResult = new ArrayList<>(); - - while (personForwardIterator.hasNext()) { - forwardResult.add(personForwardIterator.next()); - } - - forwardResult.sort(Comparator.comparing(PERSON::getId)); - assertEquals(expectedForwardResultFunction.apply(persons), forwardResult); - - // go back - List backwardResult = new ArrayList<>(); - - TarantoolWindowIterator personBackwardIterator = - TarantoolWindowIterator.of( - scrollPosition -> - repository.findFirst10ByIsMarriedGreaterThanEqual(null, scrollPosition)) - .startingAt(beginScrollPosition.reverse()); - - while (personBackwardIterator.hasNext()) { - backwardResult.add(personBackwardIterator.next()); - } - - assertEquals(expectedBackwardResultFunction.apply(persons), backwardResult); - } - - protected static Stream dataForTestUnsupportedRepositoryMethods() { - return Stream.of(PersonRepository.class, ComplexPersonRepository.class); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestUnsupportedRepositoryMethods") - , ID, REPO extends GenericPaginationMethods> - void testUnsupportedRepositoryMethods(Class repositoryClass) { - final REPO repository = context.getBean(repositoryClass); - - assertThrows(UnsupportedOperationException.class, repository::findAll); - assertThrows(UnsupportedOperationException.class, () -> repository.findAll(Sort.unsorted())); - } - - protected static Stream dataForTestPageableWithTrueCursorAndPageNumber() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(PAGE_SIZE), - PAGES_COUNT, - PAGES_COUNT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(1, PAGE_SIZE, new Person(9, null, "User-9")), - PAGES_COUNT - 1, - PAGES_COUNT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(2, PAGE_SIZE, new Person(19, null, "User-19")), - PAGES_COUNT - 2, - PAGES_COUNT)); - } - - private static void doTestPageableWithCursorAndPageNumber( - Pageable pageable, - BiFunction> repositoryFunction, - BiConsumer>, List>> assertionAction) { - List> forwardPages = new ArrayList<>(); - - Slice page = repositoryFunction.apply(0, pageable); - - forwardPages.add(page); - - while (page.hasNext()) { - page = repositoryFunction.apply(0, page.nextOrLastPageable()); - forwardPages.add(page); - } - - List> backwardPages = new ArrayList<>(); - for (int i = forwardPages.size() - 1; i >= 0; i--) { - Slice currentPage = forwardPages.get(i); - if (currentPage.getPageable().isPaged()) { - page = currentPage; - break; - } - } - backwardPages.add(page); - - page = repositoryFunction.apply(0, page.previousOrFirstPageable()); - backwardPages.add(page); - - while (page.hasPrevious()) { - page = repositoryFunction.apply(0, page.previousOrFirstPageable()); - backwardPages.add(page); - } - - assertionAction.accept(forwardPages, backwardPages); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageableWithTrueCursorAndPageNumber") - , ID, REPO extends GenericPaginationMethods> - void testPageableWithTrueCursorAndPageNumber( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCount, - int expectedBackwardPageCount) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - backwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestPageablePageNumberLessCursor() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // fourth page - new TarantoolPageRequest<>(0, PAGE_SIZE, new Person(29, null, "User-29")), - PAGES_COUNT - 2, - PAGES_COUNT - 3, - PAGES_COUNT - 3), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // third page - new TarantoolPageRequest<>(0, PAGE_SIZE, new Person(19, null, "User-19")), - PAGES_COUNT - 1, - PAGES_COUNT - 2, - PAGES_COUNT - 2)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageablePageNumberLessCursor") - , ID, REPO extends GenericPaginationMethods> - void testPageablePageNumberLessCursor( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCountForPage, - int expectedForwardPageCountForSlice, - int expectedBackwardPageCount) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - int expectedForwardPageCount = expectedForwardPageCountForSlice; - Slice firstPageable = forwardSlice.get(0); - if (firstPageable instanceof Page) { - expectedForwardPageCount = expectedForwardPageCountForPage; - } - - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - if (firstPageable instanceof Page) { - assertTrue(forwardSlice.get(forwardSlice.size() - 1).getPageable().isUnpaged()); - forwardSlice - .subList(0, forwardSlice.size() - 1) - .forEach(p -> assertTrue(p.getPageable().isPaged())); - } else { - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - } - backwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestPageablePageNumberGreaterCursor() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // second page - new TarantoolPageRequest<>(1, PAGE_SIZE, null), - PAGES_COUNT - 1, - PAGES_COUNT, - PAGES_COUNT, - PAGES_COUNT + 1), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // fourth page - new TarantoolPageRequest<>(3, PAGE_SIZE, new Person(9, null, "User-9")), - PAGES_COUNT - 3, - PAGES_COUNT - 1, - PAGES_COUNT - 1, - PAGES_COUNT + 1)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageablePageNumberGreaterCursor") - , ID, REPO extends GenericPaginationMethods> - void testPageablePageNumberGreaterCursor( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCountForPage, - int expectedForwardPageCountForSlice, - int expectedBackwardPageCountForPage, - int expectedBackwardPageCountForSlice) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - int expectedForwardPageCount = expectedForwardPageCountForPage; - int expectedBackwardPageCount = expectedBackwardPageCountForPage; - - Slice firstPageable = forwardSlice.get(0); - if (!(firstPageable instanceof Page)) { - expectedForwardPageCount = expectedForwardPageCountForSlice; - expectedBackwardPageCount = expectedBackwardPageCountForSlice; - } - - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - assertTrue(backwardSlice.get(backwardSlice.size() - 1).getPageable().isUnpaged()); - backwardSlice - .subList(0, backwardSlice.size() - 1) - .forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestRepositoryLimit() { - final int LIMITED_SIZE = 10; - final Limit LIMITED = Limit.of(LIMITED_SIZE); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - null, - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - Limit.unlimited(), - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - personGenerateAndInsertFunction, PersonRepository.class, LIMITED, LIMITED_SIZE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - null, - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - Limit.unlimited(), - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - LIMITED, - LIMITED_SIZE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryLimit") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryLimit( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Limit limit, - int expectedLimitSize) { - generateAndInsertFunction.apply(context, PERSONS_COUNT); - - REPO repository = context.getBean(repositoryClass); - - List selectedPersons = repository.findPersonByIdGreaterThanEqual(0, limit); - assertEquals(expectedLimitSize, selectedPersons.size()); - } - - protected static Stream dataForTestRepositoryLimitShouldThrow() { - final Limit BAD_LIMIT = Limit.of(-10); - return Stream.of( - Arguments.of(PersonRepository.class, BAD_LIMIT), - Arguments.of(ComplexPersonRepository.class, BAD_LIMIT)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryLimitShouldThrow") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryLimitShouldThrow(Class repositoryClass, Limit limit) { - REPO repository = context.getBean(repositoryClass); - assertThrows( - IllegalArgumentException.class, () -> repository.findPersonByIdGreaterThanEqual(0, limit)); - } - - protected static Stream dataForTestRepositoryLimitWithLimitInMethodName() { - final int LIMIT_FROM_METHOD_NAME = 4; - final int LIMITED_SIZE = 10; - final Limit LIMITED = Limit.of(LIMITED_SIZE); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, PersonRepository.class, null, LIMIT_FROM_METHOD_NAME), - Arguments.of( - personGenerateAndInsertFunction, PersonRepository.class, LIMITED, LIMITED_SIZE), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - Limit.unlimited(), - LIMIT_FROM_METHOD_NAME), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - null, - LIMIT_FROM_METHOD_NAME), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - LIMITED, - LIMITED_SIZE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - Limit.unlimited(), - LIMIT_FROM_METHOD_NAME)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryLimitWithLimitInMethodName") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryLimitWithLimitInMethodName( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Limit limit, - int expectedLimitSize) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - List selectedPersons = repository.findTop4ByIdGreaterThanEqual(0, limit); - - assertEquals(expectedLimitSize, selectedPersons.size()); - } - - @Test - void testConcurrentDerivedMethods() { - - final byte threadCount = 3; - final ExecutorService executor = Executors.newFixedThreadPool(threadCount); - final List>> futures = new ArrayList<>(threadCount); - final PersonRepository repository = context.getBean(PersonRepository.class); - - final List insertedPersons = - personGenerateAndInsertFunction.apply(context, (int) threadCount); - final Person firstPerson = insertedPersons.get(0); - final Person secondPerson = insertedPersons.get(1); - final Person thirdPerson = insertedPersons.get(2); - - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findPersonById(firstPerson.getId()), executor)); - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findByIsMarried(secondPerson.getIsMarried()), executor)); - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findByName(thirdPerson.getName()), executor)); - - CompletableFuture.allOf(futures.toArray(new CompletableFuture[] {})).join(); - - assertEquals(firstPerson, futures.get(0).join().get(0)); - assertEquals(secondPerson, futures.get(1).join().get(0)); - assertEquals(thirdPerson, futures.get(2).join().get(0)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/RepositoryViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/RepositoryViaJavaConfigTest.java deleted file mode 100644 index eddf4819..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/RepositoryViaJavaConfigTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data32.integration.crud.CrudConfigurations.JavaConfigConfiguration; - -@SpringBootTest(classes = {JavaConfigConfiguration.class}) -class RepositoryViaJavaConfigTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/TarantoolTemplateViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/TarantoolTemplateViaJavaConfigTest.java deleted file mode 100644 index 3a8eab90..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/TarantoolTemplateViaJavaConfigTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data32.integration.crud.CrudConfigurations.JavaConfigConfiguration; - -@SpringBootTest(classes = {JavaConfigConfiguration.class}) -class TarantoolTemplateViaJavaConfigTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/TarantoolTemplateViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/TarantoolTemplateViaPropertiesTest.java deleted file mode 100644 index 48e01944..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/TarantoolTemplateViaPropertiesTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data32.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; - -@SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) -class TarantoolTemplateViaPropertiesTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolKeysetScrollPositionTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolKeysetScrollPositionTest.java deleted file mode 100644 index 80df3af2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolKeysetScrollPositionTest.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.UUID; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.function.Executable; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.ScrollPosition; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.Pair; - -class TarantoolKeysetScrollPositionTest { - - private static final Pair INDEX_KEY = Pair.of("pk", 123); - - private static final Pair INDEX_KEY_WITH_NULL_VALUE = Pair.of("pk", null); - - static Stream dataForTestTarantoolScrollPositionCreateDoesntThrow() { - return Stream.of( - () -> TarantoolScrollPosition.forward(INDEX_KEY), - () -> TarantoolScrollPosition.forward(INDEX_KEY_WITH_NULL_VALUE), - () -> TarantoolScrollPosition.backward(INDEX_KEY), - () -> TarantoolScrollPosition.backward(INDEX_KEY_WITH_NULL_VALUE)); - } - - @ParameterizedTest - @MethodSource("dataForTestTarantoolScrollPositionCreateDoesntThrow") - void testTarantoolScrollPositionCreateDoesntThrow(Executable scrollPositionCreateAction) { - assertDoesNotThrow(scrollPositionCreateAction); - } - - static Stream dataForTestTarantoolScrollPositionCreateThrows() { - return Stream.of( - () -> TarantoolScrollPosition.forward(null), () -> TarantoolScrollPosition.backward(null)); - } - - @ParameterizedTest - @MethodSource("dataForTestTarantoolScrollPositionCreateThrows") - void testTarantoolScrollPositionCreateThrows(Executable scrollPositionCreateAction) { - assertThrows(IllegalArgumentException.class, scrollPositionCreateAction); - } - - static Stream dataForTestEqualsAndHashCode() { - - List equalScrollPositionsWithKey = - Arrays.asList( - TarantoolScrollPosition.forward(INDEX_KEY), TarantoolScrollPosition.forward(INDEX_KEY)); - - TarantoolScrollPosition notEqualScrollPosition = - TarantoolScrollPosition.forward(INDEX_KEY_WITH_NULL_VALUE); - - final int ITERATION_COUNT = 100; - - return Stream.of( - Arguments.of(equalScrollPositionsWithKey, notEqualScrollPosition, ITERATION_COUNT), - Arguments.of(equalScrollPositionsWithKey, null, ITERATION_COUNT)); - } - - @ParameterizedTest - @MethodSource("dataForTestEqualsAndHashCode") - void testEqualsAndHashCode( - List scrollPositions, - ScrollPosition notEqualScrollPosition, - int iterationCount) { - for (int i = 0; i < iterationCount; i++) { - for (ScrollPosition scrollPosition : scrollPositions) { - for (ScrollPosition otherScrollPosition : scrollPositions) { - assertEquals(scrollPosition, otherScrollPosition); - assertEquals(scrollPosition.hashCode(), otherScrollPosition.hashCode()); - } - assertNotEquals(scrollPosition, notEqualScrollPosition); - if (notEqualScrollPosition != null) { - assertNotEquals(scrollPosition.hashCode(), notEqualScrollPosition.hashCode()); - } - } - } - } - - static Stream dataForTestIsInitial() { - var startingIndex = Pair.of("pk", Collections.emptyList()); - var complexIndex = Pair.of("pk", Arrays.asList(1, UUID.randomUUID())); - Object nonNullCursor = Arrays.asList(1, 2, 3, 4); - return Stream.of( - Arguments.of(TarantoolScrollPosition.backward(INDEX_KEY), false), - Arguments.of(TarantoolScrollPosition.forward(INDEX_KEY), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, null), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, nonNullCursor), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, nonNullCursor), false), - Arguments.of(TarantoolScrollPosition.backward(startingIndex), true), - Arguments.of(TarantoolScrollPosition.forward(startingIndex), true), - Arguments.of(new TarantoolKeysetScrollPosition(startingIndex, FORWARD, null), true), - Arguments.of(new TarantoolKeysetScrollPosition(startingIndex, BACKWARD, null), true), - Arguments.of( - new TarantoolKeysetScrollPosition(startingIndex, FORWARD, nonNullCursor), false), - Arguments.of( - new TarantoolKeysetScrollPosition(startingIndex, BACKWARD, nonNullCursor), false), - Arguments.of(TarantoolScrollPosition.backward(complexIndex), false), - Arguments.of(TarantoolScrollPosition.forward(complexIndex), false)); - } - - @ParameterizedTest - @MethodSource("dataForTestIsInitial") - void testIsInitial(ScrollPosition scrollPosition, boolean expectedIsInitial) { - assertEquals(scrollPosition.isInitial(), expectedIsInitial); - } - - static Stream dataForTestGetCursor() { - var cursor = String.valueOf(2); - return Stream.of( - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), null), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, cursor), cursor)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetCursor") - void testGetCursor(TarantoolKeysetScrollPosition scrollPosition, Object expectedCursor) { - assertEquals(expectedCursor, scrollPosition.getCursor()); - } - - static Stream dataForTestGetKeyIndex() { - return Stream.of( - Arguments.of(TarantoolScrollPosition.forward(INDEX_KEY), INDEX_KEY), - Arguments.of(TarantoolScrollPosition.backward(INDEX_KEY), INDEX_KEY)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetKeyIndex") - void testGetKeyIndex( - TarantoolKeysetScrollPosition scrollPosition, Pair expectedIndexKey) { - assertEquals(expectedIndexKey, scrollPosition.getIndexKey()); - } - - static Stream dataForTestGetDirection() { - return Stream.of( - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), FORWARD), - Arguments.of( - new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, String.valueOf(2)), BACKWARD)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetDirection") - void testGetDirection( - TarantoolKeysetScrollPosition scrollPosition, PaginationDirection expectedDirection) { - assertEquals(expectedDirection, scrollPosition.getDirection()); - } - - static Stream dataForTestReverse() { - Object someKey = String.valueOf(1); - var indexKeyAfterReverse = Pair.of(INDEX_KEY.getFirst(), INDEX_KEY.getSecond()); - - return Stream.of( - Arguments.of( - TarantoolScrollPosition.forward(INDEX_KEY), - TarantoolScrollPosition.backward(indexKeyAfterReverse)), - Arguments.of( - new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, someKey), - new TarantoolKeysetScrollPosition(indexKeyAfterReverse, BACKWARD, someKey))); - } - - @ParameterizedTest - @MethodSource("dataForTestReverse") - void testGetReverse( - TarantoolScrollPosition scrollPosition, - TarantoolKeysetScrollPosition expectedReversedPosition) { - assertEquals(expectedReversedPosition, scrollPosition.reverse()); - } - - static Stream dataForTestIsScrollsBackward() { - return Stream.of( - Arguments.of( - TarantoolScrollPosition.forward(Pair.of("pk", Collections.emptyList())), false), - Arguments.of( - TarantoolScrollPosition.backward(Pair.of("pk", Collections.emptyList())), true)); - } - - @ParameterizedTest - @MethodSource("dataForTestIsScrollsBackward") - void testIsScrollsBackward(TarantoolScrollPosition position, boolean expectedIsScrollsBackward) { - assertEquals(expectedIsScrollsBackward, position.isScrollsBackward()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolPageImplTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolPageImplTest.java deleted file mode 100644 index a41c4900..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolPageImplTest.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data32.utils.entity.Person; - -class TarantoolPageImplTest { - - private static final List PERSONS = generatePersons(PERSONS_COUNT); - - private static final int DEFAULT_PAGE_SIZE_PER_TEST_CLASS = 10; - - private static final int DEFAULT_PAGE_NUMBER_PER_TEST_CLASS = 0; - - private static final Pageable FIRST_PAGE_PAGEABLE_PER_TEST_CLASS = - new TarantoolPageRequest<>( - DEFAULT_PAGE_NUMBER_PER_TEST_CLASS, DEFAULT_PAGE_SIZE_PER_TEST_CLASS, null); - - private static final long MULTIPLIER = 2L; - - private static final BiFunction GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE = - (pageSize, operator) -> { - switch (operator) { - // pageSize > totalPageCount - case ">": - { - return pageSize / MULTIPLIER; - } - // pageSize < totalPageCount - case "<": - { - return MULTIPLIER * pageSize; - } - // pageSize == totalPageCount - case "==": - { - return Long.valueOf(pageSize); - } - default: - throw new IllegalArgumentException("The passed option isn't supported"); - } - }; - - private static final List EMPTY_CONTENT = Collections.emptyList(); - - protected static Stream dataForTestConstructors() { - TarantoolPageable> pageable = - new TarantoolPageRequest<>(0, DEFAULT_PAGE_SIZE_PER_TEST_CLASS, null); - - long personsSize = PERSONS.size(); - - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>(PERSONS, pageable, personsSize), - PERSONS.size() / DEFAULT_PAGE_SIZE_PER_TEST_CLASS, - personsSize), - Arguments.of(new TarantoolPageImpl<>(PERSONS), 1, personsSize), - Arguments.of(new TarantoolPageImpl<>(), 1, 0L)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructors") - void testConstructors(Page> page, int totalPages, long totalElements) { - assertEquals(totalPages, page.getTotalPages()); - assertEquals(totalElements, page.getTotalElements()); - } - - static Stream dataForTestConstructorsThrowsIllegalArgumentException() { - final class DummyTarantoolPageRequest implements Pageable { - - @Override - public int getPageNumber() { - return 0; - } - - @Override - public int getPageSize() { - return 0; - } - - @Override - public long getOffset() { - return 0L; - } - - @Override - public Sort getSort() { - return null; - } - - @Override - public Pageable next() { - return null; - } - - @Override - public Pageable previousOrFirst() { - return null; - } - - @Override - public Pageable first() { - return null; - } - - @Override - public Pageable withPage(int pageNumber) { - return null; - } - - @Override - public boolean hasPrevious() { - return false; - } - } - - Pageable dummyPageable = new DummyTarantoolPageRequest(); - - return Stream.of( - Arguments.of(null, null, "Content must not be null"), - Arguments.of(Collections.emptyList(), null, "Pageable must not be null"), - Arguments.of( - Collections.emptyList(), - dummyPageable, - "Pageable must be TarantoolPageable or Unpaged type")); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructorsThrowsIllegalArgumentException") - void testConstructors_throws_IllegalArgumentException( - List content, Pageable pageable, String errorMsg) { - assertThrows( - IllegalArgumentException.class, - () -> new TarantoolPageImpl<>(content, pageable, 0L), - errorMsg); - } - - static Stream dataForTestGetTotalPages() { - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, ">")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "<")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - PERSONS.size() / FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, ">")), - 0), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "<")), - 0), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "==")), - 0)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTotalPages") - void testGetTotalPages(Page page, long totalPagesCount) { - assertEquals(totalPagesCount, page.getTotalPages()); - } - - static Stream dataForTestGetTotalElements() { - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() / MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() * MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - PERSONS.size()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() * MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTotalElements") - void testGetTotalElements(Page page, long totalElementCount) { - assertEquals(totalElementCount, page.getTotalElements()); - } - - static Stream dataForTestHasNext() { - return Stream.of( - Arguments.of( - false, - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())), - Arguments.of( - true, - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - MULTIPLIER * FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())), - Arguments.of( - false, - new TarantoolPageImpl<>( - PERSONS, - Pageable.unpaged(), - MULTIPLIER * FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()))); - } - - @ParameterizedTest - @MethodSource("dataForTestHasNext") - void testHasNext(boolean exceptedBool, Page page) { - assertEquals(exceptedBool, page.hasNext()); - } - - @ParameterizedTest - @MethodSource("dataForTestHasNext") - void testIsLast(boolean notEqualBool, Page page) { - assertNotEquals(notEqualBool, page.isLast()); - } - - static Stream dataForTestMap() { - List exceptedNames = PERSONS.stream().map(Person::getName).collect(Collectors.toList()); - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - exceptedNames, - (Function) Person::getName)); - } - - @ParameterizedTest - @MethodSource("dataForTestMap") - void testMap(Page page, List exceptedNames, Function mapFunction) { - List names = page.map(mapFunction).toList(); - assertEquals(exceptedNames, names); - } - - static Stream dataForTestEqualsAndHashCode() { - List> equalPages = - Arrays.asList( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())); - - final int ITERATION_COUNT = 100; - - return Stream.of( - Arguments.of( - equalPages, - new TarantoolPageImpl<>(EMPTY_CONTENT, Pageable.unpaged(), 150), - ITERATION_COUNT), - Arguments.of(equalPages, null, ITERATION_COUNT)); - } - - @ParameterizedTest - @MethodSource("dataForTestEqualsAndHashCode") - void testEqualsAndHashCode(List> pages, Page notEqualPage, int iterationCount) { - for (int i = 0; i < iterationCount; i++) { - for (Page page : pages) { - for (Page otherPage : pages) { - assertEquals(page, otherPage); - assertEquals(page.hashCode(), otherPage.hashCode()); - } - assertNotEquals(page, notEqualPage); - if (notEqualPage != null) { - assertNotEquals(page.hashCode(), notEqualPage.hashCode()); - } - } - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolPageRequestTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolPageRequestTest.java deleted file mode 100644 index b7bdaa20..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolPageRequestTest.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.util.Arrays; -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.AbstractPageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data32.utils.entity.Person; - -class TarantoolPageRequestTest { - - private static final int PAGE_SIZE = 10; - - private static final Person CURSOR = new Person(0, true, "0"); - - private static final int PAGE_NUMBER = 0; - - protected static Stream dataForTestConstructors() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - null, - FORWARD), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - CURSOR, - FORWARD), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, null), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - null, - FORWARD)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructors") - void testConstructors( - Supplier>> constructorGenerator, - int pageNumber, - int size, - Sort sort, - GenericPerson cursor, - PaginationDirection direction) { - TarantoolPageable> pageable = constructorGenerator.get(); - - assertEquals(size, pageable.getPageSize()); - assertEquals(pageNumber, pageable.getPageNumber()); - assertEquals(sort, pageable.getSort()); - assertEquals(cursor, pageable.getTupleCursor()); - assertEquals(direction, pageable.getPaginationDirection()); - } - - protected static Stream dataTestGetSort() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - Sort.unsorted()), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - Sort.unsorted())); - } - - @ParameterizedTest - @MethodSource("dataTestGetSort") - void testGetSort(Supplier>> constructorGenerator, Sort sort) { - Pageable pageable = constructorGenerator.get(); - assertEquals(sort, pageable.getSort()); - } - - protected static Stream dataForTestGetTupleCursor() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - null), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTupleCursor") - void testGetTupleCursor( - Supplier>> constructorGenerator, GenericPerson person) { - TarantoolPageable> pageable = constructorGenerator.get(); - assertEquals(person, pageable.getTupleCursor()); - } - - protected static Stream dataForTestNext() { - final Person NEXT_CURSOR = - new Person(CURSOR.getId() + PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), CURSOR, NEXT_CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataForTestNext") - void testNext( - TarantoolPageable> pageable, - GenericPerson cursor, - GenericPerson nextCursor) { - assertEquals(cursor, pageable.getTupleCursor()); - - TarantoolPageable> nextPageable = pageable.next(nextCursor); - assertEquals(nextCursor, nextPageable.getTupleCursor()); - - assertEquals(pageable.getPageSize(), nextPageable.getPageSize()); - assertEquals(pageable.getPageNumber() + 1, nextPageable.getPageNumber()); - assertEquals(pageable.getSort(), nextPageable.getSort()); - assertEquals(pageable.getOffset() + PAGE_SIZE, nextPageable.getOffset()); - } - - @Test - void testNextUnsupported() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::next); - } - - protected static Stream dataTestGetPaginationDirection() { - final Person PREV_CURSOR = new Person(CURSOR.getId(), CURSOR.getIsMarried(), CURSOR.getName()); - final Person NEXT_CURSOR = - new Person(PREV_CURSOR.getId() + PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, NEXT_CURSOR), NEXT_CURSOR, PREV_CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataTestGetPaginationDirection") - void testGetPaginationDirection( - TarantoolPageable> pageable, - GenericPerson nextCursor, - GenericPerson prevCursor) { - - assertEquals(FORWARD, pageable.getPaginationDirection()); - - TarantoolPageable> prevPageable = pageable.previousOrFirst(prevCursor); - assertEquals(PaginationDirection.BACKWARD, prevPageable.getPaginationDirection()); - - TarantoolPageable> nextPageable = prevPageable.next(nextCursor); - assertEquals(FORWARD, nextPageable.getPaginationDirection()); - assertEquals(pageable, nextPageable); - } - - protected static Stream dataTestFirst() { - final Person CURSOR = new Person(2 * PAGE_SIZE, true, "name"); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(0, PAGE_SIZE, null))); - } - - @ParameterizedTest - @MethodSource("dataTestFirst") - void testFirst( - TarantoolPageable> pageable, - TarantoolPageable> exceptedFirstPageable) { - assertEquals(exceptedFirstPageable, pageable.first()); - } - - @Test - void testWithPage() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, () -> pageable.withPage(100)); - } - - protected static Stream dataTestPreviousOrFirst() { - final Person CURSOR = new Person(PAGE_SIZE, true, "name"); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, CURSOR), - new Person(CURSOR.getId() - PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()))); - } - - @ParameterizedTest - @MethodSource("dataTestPreviousOrFirst") - void testPreviousOrFirst( - TarantoolPageable> pageable, GenericPerson prevCursor) { - - TarantoolPageable> prevPageable = pageable.previousOrFirst(prevCursor); - - assertNotEquals(pageable, prevPageable); - assertEquals(pageable.getPageSize(), prevPageable.getPageSize()); - assertEquals(pageable.getOffset() - PAGE_SIZE, prevPageable.getOffset()); - assertEquals(pageable.getSort(), prevPageable.getSort()); - assertEquals(pageable.getPageNumber() - 1, prevPageable.getPageNumber()); - - // here will be first with null cursor - TarantoolPageable> firstPageable = prevPageable.previousOrFirst(prevCursor); - assertNull(firstPageable.getTupleCursor()); - } - - @Test - void testPreviousOrFirstUnsupported() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::previousOrFirst); - } - - @Test - void testPreviousUnsupported() { - AbstractPageRequest pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::previous); - } - - protected static Stream dataForTestEquals() { - return Stream.of( - Arguments.of( - Arrays.asList( - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR)), - new TarantoolPageRequest<>(PAGE_SIZE))); - } - - @ParameterizedTest - @MethodSource("dataForTestEquals") - void testEquals( - List>> equalPageableList, - TarantoolPageable> notEqualPageable) { - - assertTrue(equalPageableList.size() > 0); - final int COUNT = 10; - - for (int i = 0; i < COUNT; i++) { - for (TarantoolPageable> pageable : equalPageableList) { - for (TarantoolPageable> secondPageable : equalPageableList) { - assertEquals(pageable, secondPageable); - } - assertNotEquals(pageable, null); - assertNotEquals(pageable, notEqualPageable); - } - } - } - - @ParameterizedTest - @MethodSource("dataForTestEquals") - void testHashCode( - List>> equalPageableList, - TarantoolPageable> notEqualPageable) { - - for (TarantoolPageable> pageable : equalPageableList) { - for (TarantoolPageable> secondPageable : equalPageableList) { - assertEquals(pageable.hashCode(), secondPageable.hashCode()); - } - assertNotEquals(pageable.hashCode(), notEqualPageable.hashCode()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolSliceTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolSliceTest.java deleted file mode 100644 index 65aa51d1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolSliceTest.java +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.function.Executable; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.spring.data32.utils.entity.Person; - -public class TarantoolSliceTest { - - private static final int PAGE_SIZE = 10; - - private static final int PAGE_NUMBER = 0; - - private static final Person SOME_CURSOR = new Person(0, true, "0"); - - private static List PERSONS; - - private static final Pageable SOME_PAGEABLE = - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR); - - @BeforeAll - static void setUp() { - PERSONS = generatePersons(PERSONS_COUNT); - } - - static Stream dataForTestConstructorsShouldThrow() { - Pageable tarantoolPageable = new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR); - Pageable notTarantoolPageable = Pageable.ofSize(PAGE_SIZE); - return Stream.of( - Arguments.of(null, tarantoolPageable, false), - Arguments.of(null, tarantoolPageable, true), - Arguments.of(PERSONS, null, false), - Arguments.of(PERSONS, null, true), - Arguments.of(PERSONS, notTarantoolPageable, false), - Arguments.of(PERSONS, notTarantoolPageable, true)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructorsShouldThrow") - public void testConstructorsShouldThrow(List content, Pageable pageable, boolean hasNext) { - assertThrows( - IllegalArgumentException.class, () -> new TarantoolSliceImpl<>(content, pageable, hasNext)); - } - - static Stream dataForTestConstructorsDoesntThrow() { - return Stream.of( - () -> new TarantoolSliceImpl<>(PERSONS), - () -> new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - () -> new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestConstructorsDoesntThrow") - public void testConstructorsDoesntThrow(Executable runTestCase) { - assertDoesNotThrow(runTestCase); - } - - static Stream dataForTestGetNumber() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getPageNumber()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetNumber") - public void testGetNumber(Slice slice, int expectedPageNumber) { - assertEquals(expectedPageNumber, slice.getNumber()); - } - - static Stream dataForTestGetSize() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getPageSize()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS.size()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), - SOME_PAGEABLE.getPageSize()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetSize") - public void testGetSize(Slice slice, int expectedSize) { - assertEquals(expectedSize, slice.getSize()); - } - - static Stream dataForTestGetNumberOfElements() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), PERSONS.size()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS.size()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), 0), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetNumberOfElements") - public void testGetNumberOfElements(Slice slice, int expectedNumberOfElements) { - assertEquals(expectedNumberOfElements, slice.getNumberOfElements()); - } - - static Stream dataForTestGetContent() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), PERSONS), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), - Collections.emptyList()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Collections.emptyList())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetContent") - public void testGetContent(Slice slice, List expectedContent) { - assertEquals(expectedContent, slice.getContent()); - } - - static Stream dataForTestHasContent() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), true), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), false), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasContent") - void testHasContent(Slice slice, boolean expectedHasContent) { - assertEquals(expectedHasContent, slice.hasContent()); - } - - static Stream dataForTestGetSort() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getSort()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Sort.unsorted())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetSort") - void testGetSort(Slice slice, Sort expectedSort) { - assertEquals(expectedSort, slice.getSort()); - } - - static Stream dataForTestIsFirst() { - final int MIDDLE_PAGE_NUMBER = 2; - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), true), - true), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), true), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - true), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), true)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestIsFirst") - void testIsFirst(Slice slice, boolean expectedIsFirst) { - assertEquals(expectedIsFirst, slice.isFirst()); - } - - static Stream dataForTestIsLast() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), false), - // last imitation - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, false), true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), true), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), true), - // last imitation - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, false), true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), true)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestIsLast") - void testIsLast(Slice slice, boolean expectedIsLast) { - assertEquals(expectedIsLast, slice.isLast()); - } - - static Stream dataForTestHasNext() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, new TarantoolPageRequest<>(PAGE_SIZE), true), true), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, new TarantoolPageRequest<>(PAGE_SIZE), false), false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), new TarantoolPageRequest<>(PAGE_SIZE), true), - false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), new TarantoolPageRequest<>(PAGE_SIZE), false), - false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasNext") - void testHasNext(Slice slice, boolean expectedHasNext) { - assertEquals(expectedHasNext, slice.hasNext()); - } - - static Stream dataForTestHasPrevious() { - final int MIDDLE_PAGE_NUMBER = 2; - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), false), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - false), - true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), false), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - false), - false), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), false), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasPrevious") - void testHasPrevious(Slice slice, boolean expectedHasPrevious) { - assertEquals(expectedHasPrevious, slice.hasPrevious()); - } - - static Stream dataForTestGetPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, pageable, true), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), pageable), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, pageable, false), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), pageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), - Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetPageable") - void testGetPageable(Slice slice, Pageable expectedPageable) { - assertEquals(expectedPageable, slice.getPageable()); - } - - static Stream dataForTestNextPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, true), - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - new TarantoolPageRequest<>(5, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestNextPageable") - void testNextPageable(Slice slice, Pageable expectedNextPageable) { - assertEquals(expectedNextPageable, slice.nextPageable()); - } - - static Stream dataForTestPreviousPageable() { - Pageable firstPagePageable = new TarantoolPageRequest<>(PAGE_SIZE); - Pageable secondPagePageable = - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)); - - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, false), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(4, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(0)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPreviousPageable") - void testPreviousPageable(Slice slice, Pageable expectedPrevPageable) { - assertEquals(expectedPrevPageable, slice.previousPageable()); - } - - static Stream dataForTestNextOrLastPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, true), - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), pageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, false), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), pageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - new TarantoolPageRequest<>(5, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - false), - new TarantoolPageRequest<>(4, PAGE_SIZE, null))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestNextOrLastPageable") - void testNextOrLastPageable(Slice slice, Pageable expectedNextOrLastPageable) { - assertEquals(expectedNextOrLastPageable, slice.nextOrLastPageable()); - } - - static Stream dataForTestPreviousOrFirstPageable() { - Pageable firstPagePageable = new TarantoolPageRequest<>(PAGE_SIZE); - Pageable secondPagePageable = - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)); - - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, true), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, true), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, false), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, false), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, true), - secondPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, false), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, false), - secondPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(4, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(0)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPreviousOrFirstPageable") - void testPreviousOrFirstPageable(Slice slice, Pageable expectedPrevOrFirstPageable) { - assertEquals(expectedPrevOrFirstPageable, slice.previousOrFirstPageable()); - } - - static Stream dataForTestMap() { - - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - List expectedNames = PERSONS.stream().map(Person::getName).collect(Collectors.toList()); - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, pageable, true), - (Function) Person::getName, - expectedNames, - new TarantoolSliceImpl<>(expectedNames, pageable, true))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestMap") - void testMap( - Slice slice, - Function mapper, - List expectedMappedList, - Slice expectedMappedSlice) { - assertEquals(expectedMappedSlice, slice.map(mapper)); - assertEquals(expectedMappedList, slice.map(mapper).getContent()); - } - - protected static Stream dataForTestEquals() { - - return Stream.of( - Arguments.of( - Arrays.asList( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true)), - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestEquals") - void testEquals(List> equalPageableList, Slice notEqualPageable) { - - assertFalse(equalPageableList.isEmpty()); - final int COUNT = 10; - - for (int i = 0; i < COUNT; i++) { - for (Slice pageable : equalPageableList) { - for (Slice secondPageable : equalPageableList) { - assertEquals(pageable, secondPageable); - } - assertNotEquals(pageable, null); - assertNotEquals(pageable, notEqualPageable); - } - } - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestEquals") - void testHashCode(List> equalPageableList, Slice notEqualPageable) { - for (Slice pageable : equalPageableList) { - for (Slice secondPageable : equalPageableList) { - assertEquals(pageable.hashCode(), secondPageable.hashCode()); - } - assertNotEquals(pageable.hashCode(), notEqualPageable.hashCode()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/TarantoolTestSupport.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/TarantoolTestSupport.java deleted file mode 100644 index 795e7489..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/TarantoolTestSupport.java +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.utils; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.UUID; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.Consumer; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.introspector.Property; -import org.yaml.snakeyaml.nodes.NodeTuple; -import org.yaml.snakeyaml.nodes.Tag; -import org.yaml.snakeyaml.representer.Representer; - -import static io.tarantool.balancer.BalancerMode.DEFAULT_BALANCER_MODE; -import static io.tarantool.client.TarantoolClient.DEFAULT_TAG; -import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_PASSWORD; -import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_USERNAME; -import static io.tarantool.core.protocol.requests.IProtoAuth.DEFAULT_AUTH_TYPE; -import static io.tarantool.pool.InstanceConnectionGroup.DEFAULT_HOST; -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import io.tarantool.balancer.BalancerMode; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.core.protocol.requests.IProtoAuth; -import io.tarantool.mapping.Tuple; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyFlushConsolidationHandler; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyHeartbeatOpts; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.spring.data32.config.properties.TarantoolProperties; -import io.tarantool.spring.data32.utils.entity.ComplexPerson; -import io.tarantool.spring.data32.utils.entity.Person; - -public class TarantoolTestSupport { - - private static final ThreadLocalRandom random = ThreadLocalRandom.current(); - private static final Map firstInternalMap = new HashMap<>(); - private static final Map secondInternalMap = new HashMap<>(); - private static final Map externalMap = new HashMap<>(); - private static final Representer representer; - public static final String PERSON_SPACE = "person"; - public static final String COMPLEX_PERSON_SPACE = "complex_person"; - public static final int PERSONS_COUNT = 100; - public static final Random RANDOMIZER = new Random(); - public static final Person UNKNOWN_PERSON = new Person(-1, true, "Alien"); - public static final ComplexPerson UNKNOWN_COMPLEX_PERSON = - new ComplexPerson(-1, new UUID(0, 0), true, "Alien"); - - public static final Path DEFAULT_TEST_PROPERTY_DIR = Paths.get("target", "test-classes"); - private static final Yaml yaml; - - static { - representer = - new Representer(new DumperOptions()) { - @Override - @Nullable - protected NodeTuple representJavaBeanProperty( - Object javaBean, Property property, @Nullable Object propertyValue, Tag customTag) { - if (propertyValue == null) { - return null; - } else { - return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag); - } - } - }; - representer.addClassTag(TarantoolProperties.class, Tag.MAP); - yaml = new Yaml(representer); - } - - public static TarantoolProperties writeTestPropertiesYaml(@NonNull final String fileName) - throws IOException { - return writeTestPropertiesYaml(fileName, createRandomProperty()); - } - - public static TarantoolProperties writeTestPropertiesYaml( - final String fileName, final TarantoolProperties properties) throws IOException { - final File FILE = DEFAULT_TEST_PROPERTY_DIR.resolve(fileName).toFile().getAbsoluteFile(); - - try (Writer writer = new FileWriter(FILE)) { - firstInternalMap.put("tarantool", properties); - secondInternalMap.put("data", firstInternalMap); - externalMap.put("spring", secondInternalMap); - - yaml.dump(externalMap, writer); - replaceNullToDefault(properties); - return properties; - } - } - - public static void writeTestEmptyPropertiesYaml(@NonNull final String fileName) - throws IOException { - final File FILE = DEFAULT_TEST_PROPERTY_DIR.resolve(fileName).toFile().getAbsoluteFile(); - try (Writer writer = new FileWriter(FILE)) { - yaml.dump(Collections.emptyMap(), writer); - } - } - - private static void replaceNullToDefault(final TarantoolProperties result) { - - if (result.getHost() == null) { - result.setHost(DEFAULT_HOST); - } - - if (result.getUserName() == null) { - result.setUserName(DEFAULT_CRUD_USERNAME); - } - - if (result.getBalancerMode() == null) { - result.setBalancerMode(DEFAULT_BALANCER_MODE); - } - - if (result.getPassword() == null) { - result.setPassword(DEFAULT_CRUD_PASSWORD); - } - - if (result.getConnectionGroups() != null) { - for (PropertyInstanceConnectionGroup propertyInstanceConnectionGroup : - result.getConnectionGroups()) { - if (propertyInstanceConnectionGroup.getAuthType() == null) { - propertyInstanceConnectionGroup.setAuthType(DEFAULT_AUTH_TYPE); - } - - if (propertyInstanceConnectionGroup.getHost() == null) { - propertyInstanceConnectionGroup.setHost(DEFAULT_HOST); - } - - if (propertyInstanceConnectionGroup.getTag() == null) { - propertyInstanceConnectionGroup.setTag(DEFAULT_TAG); - } - - if (propertyInstanceConnectionGroup.getUserName() == null) { - propertyInstanceConnectionGroup.setUserName(DEFAULT_CRUD_USERNAME); - } - - if (propertyInstanceConnectionGroup.getUserName() == null) { - propertyInstanceConnectionGroup.setPassword(DEFAULT_CRUD_PASSWORD); - } - } - } - } - - private static TarantoolProperties createRandomProperty() { - final int intVar = 999; - final long longVar = 9999L; - final List booleanVar = Arrays.asList(true, false); - - PropertyHeartbeatOpts propertyHeartbeatOpts = - heartbeat( - choiceOrNull(longVar), - choiceOrNull(intVar), - choiceOrNull(intVar), - choiceOrNull(intVar)); - - PropertyFlushConsolidationHandler propertyFlushConsolidationHandler = - choiceOrNull(flushConsolidation(choiceOrNull(intVar), choiceOrNull(booleanVar))); - - PropertyInstanceConnectionGroup propertyInstanceConnectionGroup = - choiceOrNull( - connectionGroup( - choiceOrNull("host"), - "password", - choiceOrNull(intVar), - choiceOrNull(intVar), - choiceOrNull("tag"), - "user", - choiceOrNull(Arrays.asList(IProtoAuth.AuthType.values())), - propertyFlushConsolidationHandler)); - List propertyInstanceConnectionGroups = null; - if (propertyInstanceConnectionGroup != null) { - propertyInstanceConnectionGroups = new ArrayList<>(); - propertyInstanceConnectionGroups.add(propertyInstanceConnectionGroup); - } - - return tarantoolProperties( - choiceOrNull("host"), - choiceOrNull("password"), - choiceOrNull(intVar), - choiceOrNull("user"), - propertyInstanceConnectionGroups, - choiceOrNull(intVar), - choiceOrNull(booleanVar), - choiceOrNull(propertyHeartbeatOpts), - choiceOrNull(longVar), - choiceOrNull(longVar), - choiceOrNull(booleanVar), - choiceOrNull(booleanVar), - choiceOrNull(Arrays.asList(BalancerMode.values()))); - } - - @Nullable - public static T choiceOrNull(@Nullable T element) { - int rnd = random.nextInt(2); - if (rnd == 0 || element == null) { - return null; - } - return element; - } - - public static PropertyHeartbeatOpts heartbeat( - @Nullable Long pingInterval, - @Nullable Integer invalidationThreshold, - @Nullable Integer windowSize, - @Nullable Integer deathThreshold) { - - PropertyHeartbeatOpts propertyHeartbeatOpts = new PropertyHeartbeatOpts(); - if (invalidationThreshold != null) { - propertyHeartbeatOpts.setInvalidationThreshold(invalidationThreshold); - } - if (pingInterval != null) { - propertyHeartbeatOpts.setPingInterval(pingInterval); - } - if (deathThreshold != null) { - propertyHeartbeatOpts.setDeathThreshold(deathThreshold); - } - if (windowSize != null) { - propertyHeartbeatOpts.setWindowSize(windowSize); - } - - return propertyHeartbeatOpts; - } - - public static PropertyFlushConsolidationHandler flushConsolidation( - @Nullable Integer explicitFlushAfterFlushes, - @Nullable Boolean consolidateWhenNoReadInProgress) { - - PropertyFlushConsolidationHandler propertyFlushConsolidationHandler = - new PropertyFlushConsolidationHandler(); - if (explicitFlushAfterFlushes != null) { - propertyFlushConsolidationHandler.setExplicitFlushAfterFlushes(explicitFlushAfterFlushes); - } - - if (consolidateWhenNoReadInProgress != null) { - propertyFlushConsolidationHandler.setConsolidateWhenNoReadInProgress( - consolidateWhenNoReadInProgress); - } - return propertyFlushConsolidationHandler; - } - - @Nullable - public static T choiceOrNull(@Nullable List list) { - if (list == null || list.isEmpty()) { - return null; - } - int rnd = random.nextInt(list.size() + 1); - - if (rnd == list.size()) { - return null; - } - return list.get(rnd); - } - - @NonNull - public static PropertyInstanceConnectionGroup connectionGroup( - @Nullable String host, - @Nullable String password, - @Nullable Integer port, - @Nullable Integer connectionNumber, - @Nullable String tag, - @Nullable String user, - @Nullable IProtoAuth.AuthType type, - @Nullable PropertyFlushConsolidationHandler propertyFlushConsolidationHandler) { - - PropertyInstanceConnectionGroup propertyInstanceConnectionGroup = - new PropertyInstanceConnectionGroup(); - propertyInstanceConnectionGroup.setHost(host); - if (connectionNumber != null) { - propertyInstanceConnectionGroup.setConnectionGroupSize(connectionNumber); - } - propertyInstanceConnectionGroup.setAuthType(type); - propertyInstanceConnectionGroup.setPassword(password); - if (port != null) { - propertyInstanceConnectionGroup.setPort(port); - } - propertyInstanceConnectionGroup.setTag(tag); - propertyInstanceConnectionGroup.setUserName(user); - - propertyInstanceConnectionGroup.setFlushConsolidationHandler(propertyFlushConsolidationHandler); - return propertyInstanceConnectionGroup; - } - - @NonNull - public static TarantoolProperties tarantoolProperties( - @Nullable String host, - @Nullable String password, - @Nullable Integer port, - @Nullable String user, - @Nullable List propertyInstanceConnectionGroups, - @Nullable Integer eventLoopThreadsCount, - @Nullable Boolean enableGracefulShutdown, - @Nullable PropertyHeartbeatOpts propertyHeartbeatOptsOpts, - @Nullable Long connectTimeout, - @Nullable Long reconnectAfter, - @Nullable Boolean fetchSchema, - @Nullable Boolean ignoreOldSchemaVersion, - @Nullable BalancerMode balancerClass) { - - TarantoolProperties prop = new TarantoolProperties(); - prop.setHost(host); - prop.setPassword(password); - if (port != null) { - prop.setPort(port); - } - prop.setUserName(user); - prop.setConnectionGroups(propertyInstanceConnectionGroups); - if (eventLoopThreadsCount != null) { - prop.setEventLoopThreadsCount(eventLoopThreadsCount); - } - - if (enableGracefulShutdown != null) { - prop.setGracefulShutdownEnabled(enableGracefulShutdown); - } - prop.setHeartbeat(propertyHeartbeatOptsOpts); - if (connectTimeout != null) { - prop.setConnectTimeout(connectTimeout); - } - if (reconnectAfter != null) { - prop.setReconnectAfter(reconnectAfter); - } - if (fetchSchema != null) { - prop.setFetchSchema(fetchSchema); - } - if (ignoreOldSchemaVersion != null) { - prop.setIgnoreOldSchemaVersion(ignoreOldSchemaVersion); - } - prop.setBalancerMode(balancerClass); - return prop; - } - - public static List generatePersons(int count) { - List persons = new ArrayList<>(); - for (int i = 0; i < count; i++) { - persons.add(new Person(i, i % 3 == 0 ? null : i % 2 == 0, "User-" + i)); - } - return persons; - } - - public static List generatePersons(int count, Consumer actionAtPerson) { - List persons = generatePersons(count); - persons.forEach(actionAtPerson); - return persons; - } - - public static List generateComplexPersons(int count) { - List persons = new ArrayList<>(); - for (int i = 0; i < count; i++) { - persons.add( - new ComplexPerson(i, UUID.randomUUID(), i % 3 == 0 ? null : i % 2 == 0, "User-" + i)); - } - return persons; - } - - public static List generateComplexPersons( - int count, Consumer actionAtPerson) { - List persons = generateComplexPersons(count); - persons.forEach(actionAtPerson); - return persons; - } - - public static List generateAndInsertPersons(int count, TarantoolCrudClient client) { - final List persons = generatePersons(count); - final TarantoolCrudSpace space = client.space(PERSON_SPACE); - - List> insertedPersons = space.insertMany(persons, Person.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertPersons( - int count, TarantoolCrudClient client, Consumer action) { - final List persons = generatePersons(count, action); - final TarantoolCrudSpace space = client.space(PERSON_SPACE); - - List> insertedPersons = space.insertMany(persons, Person.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertComplexPersons( - int count, TarantoolCrudClient client) { - final List persons = generateComplexPersons(count); - final TarantoolCrudSpace space = client.space(COMPLEX_PERSON_SPACE); - - List> insertedPersons = - space.insertMany(persons, ComplexPerson.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertComplexPersons( - int count, TarantoolCrudClient client, Consumer action) { - - final List persons = generateComplexPersons(count, action); - final TarantoolCrudSpace space = client.space(COMPLEX_PERSON_SPACE); - - List> insertedPersons = - space.insertMany(persons, ComplexPerson.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/ComplexPersonListRepository.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/ComplexPersonListRepository.java deleted file mode 100644 index 3651cd8b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/ComplexPersonListRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.utils.core; - -import org.springframework.data.repository.ListCrudRepository; - -import io.tarantool.spring.data.utils.GenericListRepositoryMethods; -import io.tarantool.spring.data32.utils.entity.ComplexPerson; -import io.tarantool.spring.data32.utils.entity.CompositePersonKey; - -public interface ComplexPersonListRepository - extends ListCrudRepository, - GenericListRepositoryMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/ComplexPersonRepository.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/ComplexPersonRepository.java deleted file mode 100644 index 7ea75af5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/ComplexPersonRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.utils.core; - -import org.springframework.data.repository.PagingAndSortingRepository; - -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data32.utils.entity.ComplexPerson; -import io.tarantool.spring.data32.utils.entity.CompositePersonKey; - -public interface ComplexPersonRepository - extends PagingAndSortingRepository, - GenericRepositoryMethods, - GenericPaginationMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/PersonListRepository.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/PersonListRepository.java deleted file mode 100644 index 56237f3b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/PersonListRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.utils.core; - -import org.springframework.data.repository.ListCrudRepository; - -import io.tarantool.spring.data.utils.GenericListRepositoryMethods; -import io.tarantool.spring.data32.utils.entity.Person; - -public interface PersonListRepository - extends ListCrudRepository, GenericListRepositoryMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/PersonRepository.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/PersonRepository.java deleted file mode 100644 index 647a2a5c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/PersonRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.utils.core; - -import org.springframework.data.repository.PagingAndSortingRepository; - -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data32.utils.entity.Person; - -public interface PersonRepository - extends PagingAndSortingRepository, - GenericRepositoryMethods, - GenericPaginationMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/ComplexPerson.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/ComplexPerson.java deleted file mode 100644 index 52d24af0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/ComplexPerson.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data32.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKey.class) -public class ComplexPerson implements GenericPerson { - - @Id - @Field("id") - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - protected Boolean isMarried; - - @Field("name") - @JsonProperty("name") - String name; - - @Override - public CompositePersonKey generateFullKey() { - return new CompositePersonKey(id, secondId); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/ComplexPersonWithIncorrectPK.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/ComplexPersonWithIncorrectPK.java deleted file mode 100644 index d92f5467..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/ComplexPersonWithIncorrectPK.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data32.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKeyWithoutJsonFormat.class) -public class ComplexPersonWithIncorrectPK { - - @Id - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositeKeyWithWrongFieldCount.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositeKeyWithWrongFieldCount.java deleted file mode 100644 index 835898da..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositeKeyWithWrongFieldCount.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -public class CompositeKeyWithWrongFieldCount implements CompositeKey { - - @JsonProperty("id") - private long id; -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositeKeyWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositeKeyWithWrongFieldTypes.java deleted file mode 100644 index ee3d2c5f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositeKeyWithWrongFieldTypes.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositeKeyWithWrongFieldTypes implements CompositeKey { - - @JsonProperty("id") - private long id; - - @JsonProperty("secondId") - private String secondId; - - @JsonProperty("thirdId") - private boolean thirdId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositePersonKeyWithJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositePersonKeyWithJsonFormat.java deleted file mode 100644 index e7ad0c39..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositePersonKeyWithJsonFormat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -public class CompositePersonKeyWithJsonFormat { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositePersonKeyWithoutJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositePersonKeyWithoutJsonFormat.java deleted file mode 100644 index 35a31d95..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositePersonKeyWithoutJsonFormat.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositePersonKeyWithoutJsonFormat { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/EntityWithWrongCompositeKeyPartsCount.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/EntityWithWrongCompositeKeyPartsCount.java deleted file mode 100644 index 342a4c8c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/EntityWithWrongCompositeKeyPartsCount.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data32.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@IdClass(CompositeKeyWithWrongFieldCount.class) -public class EntityWithWrongCompositeKeyPartsCount { - - @Id - @JsonProperty("id") - private long id; - - @Id - @JsonProperty("secondId") - private long secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/resources/application-crud-test.yaml b/tarantool-spring-data/tarantool-spring-data-32/src/test/resources/application-crud-test.yaml deleted file mode 100644 index 9bc8f9b2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/resources/application-crud-test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -spring: - data: - tarantool: - host: localhost - port: 3301 diff --git a/tarantool-spring-data/tarantool-spring-data-33/pom.xml b/tarantool-spring-data/tarantool-spring-data-33/pom.xml deleted file mode 100644 index 4496fdb6..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - 4.0.0 - - tarantool-spring-data-33 - Minimalistic java connector for Tarantool versions 2.11+ based on Netty framework - https://tarantool.io - - - io.tarantool - tarantool-spring-data - 2.0.0-SNAPSHOT - - - tarantool-spring-data-33 - 2.0.0-SNAPSHOT - jar - - - 17 - 17 - 3.3.13 - ${project.parent.parent.basedir}/tarantool-shared-resources/ - ${project.parent.parent.basedir}/LICENSE_HEADER.txt - - - - io.tarantool - tarantool-spring-data-core - - - diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/TarantoolBoxKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/TarantoolBoxKeyValueAdapter.java deleted file mode 100644 index 238b7bf5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/TarantoolBoxKeyValueAdapter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33; - -import java.util.Map; - -import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.NonNull; - -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(Object id, Object item, String keyspace) { - return adapter.put(id, item, keyspace); - } - - @Override - public boolean contains(Object id, String keyspace) { - return adapter.contains(id, keyspace); - } - - @Override - public Object get(Object id, String keyspace) { - return adapter.get(id, keyspace); - } - - @Override - public Object delete(Object id, String keyspace) { - return adapter.delete(id, keyspace); - } - - @Override - public Iterable getAllOf(String keyspace) { - return adapter.getAllOf(keyspace); - } - - @Override - public void deleteAllOf(String keyspace) { - adapter.deleteAllOf(keyspace); - } - - @Override - public void clear() { - adapter.clear(); - } - - @Override - public long count(String keyspace) { - return adapter.count(keyspace); - } - - @Override - public void destroy() throws Exception { - adapter.destroy(); - } - - @Override - public CloseableIterator> entries(String keyspace) { - throw new UnsupportedOperationException("Not implemented yet"); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/TarantoolCrudKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/TarantoolCrudKeyValueAdapter.java deleted file mode 100644 index eef926bc..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/TarantoolCrudKeyValueAdapter.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33; - -import java.util.Collections; -import java.util.Map.Entry; - -import com.fasterxml.jackson.annotation.JsonFormat; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.NonNull; - -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(Object id, Object item, String keyspace) { - return adapter.put(convertId(id), item, keyspace); - } - - @Override - public boolean contains(Object id, String keyspace) { - return adapter.contains(convertId(id), keyspace); - } - - @Override - public Object get(Object id, String keyspace) { - return adapter.get(convertId(id), keyspace); - } - - @Override - public T get(Object id, String keyspace, Class type) { - return adapter.get(convertId(id), keyspace, type); - } - - @Override - public Object delete(Object id, String keyspace) { - return adapter.delete(convertId(id), keyspace); - } - - @Override - public T delete(Object id, String keyspace, Class type) { - return adapter.delete(convertId(id), keyspace, type); - } - - @Override - public Iterable getAllOf(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> 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()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/TarantoolQueryEngine.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/TarantoolQueryEngine.java deleted file mode 100644 index 50b3f1fd..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/TarantoolQueryEngine.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33; - -import java.util.Collection; -import java.util.Comparator; -import java.util.Map.Entry; - -import org.springframework.data.keyvalue.core.QueryEngine; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.ProxyTarantoolQueryEngine; -import io.tarantool.spring.data.query.TarantoolCriteria; -import io.tarantool.spring.data33.query.TarantoolCriteriaAccessor; -import io.tarantool.spring.data33.query.TarantoolSortAccessor; - -/** - * Implementation of {@code findBy*()} and {@code countBy*{}} queries. - * - * @author Artyom Dubinin - */ -public class TarantoolQueryEngine - extends QueryEngine>> { - - 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> 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. - * - *

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 Collection execute( - @Nullable final TarantoolCriteria criteria, - @Nullable final Comparator> sort, - final long offset, - final int rows, - @NonNull final String keyspace, - @NonNull Class 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); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/config/TarantoolBoxConfiguration.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/config/TarantoolBoxConfiguration.java deleted file mode 100644 index c5f5f59e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/config/TarantoolBoxConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.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.data33.TarantoolBoxKeyValueAdapter; -import io.tarantool.spring.data33.config.properties.TarantoolProperties; - -@Configuration(proxyBeanMethods = false) -public class TarantoolBoxConfiguration extends BaseTarantoolBoxConfiguration { - - public TarantoolBoxConfiguration( - ObjectProvider properties, - ObjectProvider 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(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/config/TarantoolCrudConfiguration.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/config/TarantoolCrudConfiguration.java deleted file mode 100644 index 05c3a849..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/config/TarantoolCrudConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.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_CRUD_CLIENT_BEAN_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.spring.data.config.BaseTarantoolCrudConfiguration; -import io.tarantool.spring.data33.TarantoolCrudKeyValueAdapter; -import io.tarantool.spring.data33.config.properties.TarantoolProperties; - -@Configuration(proxyBeanMethods = false) -public class TarantoolCrudConfiguration extends BaseTarantoolCrudConfiguration { - - public TarantoolCrudConfiguration( - ObjectProvider properties, - ObjectProvider tarantoolClientConfiguration) { - super(properties.getIfAvailable(), tarantoolClientConfiguration.getIfAvailable()); - } - - @Bean(name = DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF) - @ConditionalOnMissingBean(TarantoolCrudKeyValueAdapter.class) - public TarantoolCrudKeyValueAdapter tarantoolCrudKeyValueAdapter( - TarantoolCrudClient tarantoolCrudClient) { - return new TarantoolCrudKeyValueAdapter(tarantoolCrudClient); - } - - @Bean(name = DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF) - @ConditionalOnMissingBean(TarantoolCrudClient.class) - public TarantoolCrudClient tarantoolCrudClient() throws Exception { - return super.tarantoolCrudClient(); - } - - public TarantoolCrudClientBuilder getClientBuilder() { - return super.getClientBuilder(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/config/package-info.java deleted file mode 100644 index 4551f3e2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/config/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Config package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data33.config; diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/config/properties/TarantoolProperties.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/config/properties/TarantoolProperties.java deleted file mode 100644 index 636d6604..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/config/properties/TarantoolProperties.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.config.properties; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties; - -/** - * Configuration properties for Tarantool. - * - * @author Nikolay Belonogov - */ -@ConfigurationProperties(prefix = "spring.data.tarantool") -public class TarantoolProperties extends BaseTarantoolProperties {} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/TarantoolTemplate.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/TarantoolTemplate.java deleted file mode 100644 index 54baf9b0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/TarantoolTemplate.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.core; - -import org.springframework.data.keyvalue.core.IdentifierGenerator; -import org.springframework.data.keyvalue.core.KeyValueAdapter; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.util.ClassUtils; - -import io.tarantool.spring.data33.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data33.core.mapping.TarantoolMappingContext; - -public class TarantoolTemplate extends KeyValueTemplate { - - public TarantoolTemplate(KeyValueAdapter adapter) { - super(adapter, new TarantoolMappingContext<>()); - } - - public TarantoolTemplate( - KeyValueAdapter adapter, - MappingContext< - ? extends KeyValuePersistentEntity, ? extends KeyValuePersistentProperty> - mappingContext) { - super(adapter, mappingContext); - } - - public TarantoolTemplate( - KeyValueAdapter adapter, - MappingContext< - ? extends KeyValuePersistentEntity, ? extends KeyValuePersistentProperty> - mappingContext, - IdentifierGenerator identifierGenerator) { - super(adapter, mappingContext, identifierGenerator); - } - - @Override - public T insert(T objectToInsert) { - if (DefaultIdClassResolver.INSTANCE.resolveIdClassType(objectToInsert.getClass()) == null) { - return super.insert(objectToInsert); - } - - PersistentEntity entity = - getMappingContext().getRequiredPersistentEntity(ClassUtils.getUserClass(objectToInsert)); - - IdentifierAccessor identifierAccessor = entity.getIdentifierAccessor(objectToInsert); - Object id = identifierAccessor.getRequiredIdentifier(); - return insert(id, objectToInsert); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/annotation/DefaultIdClassResolver.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/annotation/DefaultIdClassResolver.java deleted file mode 100644 index 9d22b4bb..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/annotation/DefaultIdClassResolver.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.core.annotation; - -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.core.annotation.IdClassResolver; - -/** Default implementation of {@link IdClassResolver}. */ -public enum DefaultIdClassResolver implements IdClassResolver { - INSTANCE; - - public static final String ANNOTATION_TYPE_EXCEPTION = - "The class of a composite identifier specified in the @IdClass annotation cannot be" - + " annotation!"; - - @Nullable - @Override - public Class resolveIdClassType(Class type) { - Assert.notNull(type, "Type for IdClass must be not null!"); - - IdClass idClassTypeAnnotation = AnnotatedElementUtils.findMergedAnnotation(type, IdClass.class); - - if (idClassTypeAnnotation == null) { - return null; - } - - Class idClassTypeValue = idClassTypeAnnotation.value(); - Assert.isTrue(!idClassTypeValue.isAnnotation(), ANNOTATION_TYPE_EXCEPTION); - - return idClassTypeValue; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/annotation/package-info.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/annotation/package-info.java deleted file mode 100644 index 39cf0630..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/annotation/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Core annotations of data mapping. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data33.core.annotation; diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/BasicKeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/BasicKeyValueCompositePersistentEntity.java deleted file mode 100644 index c32d471a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/BasicKeyValueCompositePersistentEntity.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.core.mapping; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.data.domain.Persistable; -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.support.IsNewStrategy; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.mapping.model.CompositeKey; -import io.tarantool.spring.data33.core.mapping.model.CompositeIdPropertyAccessor; -import io.tarantool.spring.data33.core.mapping.model.PersistentCompositeIdIsNewStrategy; - -public class BasicKeyValueCompositePersistentEntity> - extends BasicKeyValuePersistentEntity implements KeyValueCompositePersistentEntity { - - public static final String TYPE_MISMATCH = - "Target bean of type %s is not of type of the persistent entity (%s)"; - - private final Class idClassTypeValue; - private @Nullable P idProperty; - - private Map entityIdClassFields; - - /** - * @param information must not be {@literal null}. - * @param fallbackKeySpaceResolver can be {@literal null}. - * @param idClassTypeValue class that specified in {@link IdClass} - */ - public BasicKeyValueCompositePersistentEntity( - TypeInformation information, - @Nullable KeySpaceResolver fallbackKeySpaceResolver, - Class idClassTypeValue) { - super(information, fallbackKeySpaceResolver); - - Assert.notNull(idClassTypeValue, "idClassTypeValue must be not null for this class!"); - this.idClassTypeValue = idClassTypeValue; - } - - @Override - public IdentifierAccessor getIdentifierAccessor(Object bean) { - verifyBeanType(bean); - - if (Persistable.class.isAssignableFrom(getType())) { - throw new IllegalArgumentException( - "Persistable override is not currently supported for entities with a composite key."); - } - - return hasIdProperty() - ? new CompositeIdPropertyAccessor(bean, this.entityIdClassFields, getIdClassType()) - : new AbsentIdentifierAccessor(); - } - - @Override - public Class getIdClassType() { - return this.idClassTypeValue; - } - - @Override - public void verify() { - super.verify(); - - if (this.idProperty != null) { - this.entityIdClassFields = KeyPartTypeChecker.getFieldMapIfTypesValid(this, this.idProperty); - } - } - - @Override - protected IsNewStrategy getFallbackIsNewStrategy() { - return PersistentCompositeIdIsNewStrategy.of(this); - } - - @Override - protected P returnPropertyIfBetterIdPropertyCandidateOrNull(P property) { - Assert.isInstanceOf(Identifier.class, property, "property must be Identifier for this class"); - - if (!property.isIdProperty()) { - return null; - } - - if (this.idProperty == null) { - this.idProperty = property; - return this.idProperty; - } - - this.idProperty.addPart(property); - - return this.idProperty; - } - - /** - * Verifies the given bean type to no be {@literal null} and of the type of the current {@link - * PersistentEntity}. - * - * @param bean must not be {@literal null}. - */ - private void verifyBeanType(Object bean) { - - Assert.notNull(bean, "Target bean must not be null"); - Assert.isInstanceOf( - getType(), - bean, - () -> String.format(TYPE_MISMATCH, bean.getClass().getName(), getType().getName())); - } - - /** - * A null-object implementation of {@link IdentifierAccessor} to be able to return an accessor for - * entities that do not have an identifier property. - */ - private static class AbsentIdentifierAccessor implements IdentifierAccessor { - - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.IdentifierAccessor#getIdentifier() - */ - @Override - @Nullable - public Object getIdentifier() { - return null; - } - } - - /** - * A class that checks the types of fields of a composite key. In addition, the correspondence - * between types and field names marked with {@code @Id}. - */ - public static class KeyPartTypeChecker { - - public static final String COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION = - "Number of fields specified in domain class and composite class the key is different!"; - - public static final String COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION = - "Domain class fields marked with @Id differ from fields specified in the composite key" - + " class"; - - /** - * Check the number and types of entity fields, annotated {@code @Id} and fields {@link - * CompositeKey} and if the types and quantities match return the id part fields mapping. - * - * @param persistentEntity persistent entity - * @param idProperty id property - * @return mapping between fields of composite key class and fields annotated {@code @Id} in - * entity. - */ - public static Map getFieldMapIfTypesValid( - KeyValueCompositePersistentEntity persistentEntity, Identifier idProperty) { - Map entityIdClassFields = new HashMap<>(); - - List compositeKeyFields = persistentEntity.getIdClassTypeFields(); - - Field[] entityFields = idProperty.getFields(); - - if (compositeKeyFields.size() != entityFields.length) { - throw new IllegalArgumentException(COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION); - } - - for (int i = 0; i < compositeKeyFields.size(); i++) { - Field compositeKeyField = compositeKeyFields.get(i); - Field entityField = entityFields[i]; - - if (!equalFields(compositeKeyField, entityField)) { - throw new IllegalArgumentException(COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION); - } - - entityIdClassFields.put(entityField, compositeKeyField); - } - return entityIdClassFields; - } - - /** - * Compares two class fields by name and type. - * - * @param firstField first field - * @param secondField second field - * @return true if fields are equal - */ - private static boolean equalFields(Field firstField, Field secondField) { - return firstField.getName().equals(secondField.getName()) - && firstField.getType().equals(secondField.getType()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/Identifier.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/Identifier.java deleted file mode 100644 index 59bc77ca..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/Identifier.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.core.mapping; - -import java.lang.reflect.Field; -import java.util.Collection; - -import org.springframework.data.mapping.PersistentProperty; - -/** The interface of the identifier class that will contain information about the composite key. */ -public interface Identifier

> { - - /** - * Add a {@link PersistentProperty} tagged with {@code Id}. - * - * @param property {@link PersistentProperty} tagged {@code Id} - */ - void addPart(P property); - - /** - * Return the parts of a composite key that are {@link PersistentProperty}. - * - * @return parts of a composite key - */ - Collection

getParts(); - - /** - * Return a list {@link Field} of fields that are annotated {@code @Id}. Unlike method {@link - * #getParts()} this method returns an array {@link Field}, where {@link Field} is taken from each - * element of the collection returned by the {@link #getParts()} method. Necessary in order not to - * write polluting code. - * - * @return fields of a composite key - */ - Field[] getFields(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/KeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/KeyValueCompositePersistentEntity.java deleted file mode 100644 index 664f0376..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/KeyValueCompositePersistentEntity.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.core.mapping; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.model.MutablePersistentEntity; - -import io.tarantool.spring.data.core.annotation.IdClass; - -/** - * An interface to enable {@link PersistentEntity}-specific operations with a composite key. - * - * @param domain class type - * @param

{@link PersistentProperty} type - */ -public interface KeyValueCompositePersistentEntity> - extends MutablePersistentEntity { - - /** - * Returns the fields of the class specified in the {@link IdClass} annotation. - * - * @return all fields that are in composite key class - */ - default List getIdClassTypeFields() { - List fields = new ArrayList<>(); - - for (Field field : getIdClassType().getDeclaredFields()) { - if (!field.isSynthetic()) { - fields.add(field); - } - } - return fields; - } - - /** - * Returns the type of the class specified in the {@link IdClass} annotation. - * - * @return class that specified in {@link IdClass} - */ - Class getIdClassType(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/KeyValueCompositeProperty.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/KeyValueCompositeProperty.java deleted file mode 100644 index 47d52afd..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/KeyValueCompositeProperty.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.core.mapping; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; - -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.util.Assert; - -public class KeyValueCompositeProperty

> - extends KeyValuePersistentProperty

implements Identifier

{ - - private final List

identifierPartsWithoutFirst; - - public KeyValueCompositeProperty( - Property property, PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - super(property, owner, simpleTypeHolder); - this.identifierPartsWithoutFirst = new ArrayList<>(); - } - - @Override - public void addPart(P property) { - Assert.notNull(property, "property must be not null"); - - if (equals(property) || this.identifierPartsWithoutFirst.contains(property)) { - return; - } - this.identifierPartsWithoutFirst.add(property); - } - - @Override - @SuppressWarnings("unchecked") - public Collection

getParts() { - List

resultList = new ArrayList<>(this.identifierPartsWithoutFirst); - resultList.add(0, (P) this); - - return resultList; - } - - @Override - public Field[] getFields() { - int totalSize = this.identifierPartsWithoutFirst.size() + 1; - - final Field[] fields = new Field[totalSize]; - fields[0] = getField(); - - for (int i = 1; i < totalSize; i++) { - fields[i] = this.identifierPartsWithoutFirst.get(i - 1).getField(); - } - return fields; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - KeyValueCompositeProperty other = (KeyValueCompositeProperty) o; - - if (this.identifierPartsWithoutFirst.isEmpty() && other.identifierPartsWithoutFirst.isEmpty()) { - return super.equals(o); - } - - if (this.identifierPartsWithoutFirst.size() != other.identifierPartsWithoutFirst.size() - || !other.getProperty().equals(getProperty())) { - return false; - } - - for (int i = 0; i < this.identifierPartsWithoutFirst.size(); i++) { - // take Property from both parts - Property thisKeyPartProperty = - ((KeyValueCompositeProperty) this.identifierPartsWithoutFirst.get(i)).getProperty(); - Property otherKeyPartProperty = - ((KeyValueCompositeProperty) other.identifierPartsWithoutFirst.get(i)).getProperty(); - - if (!thisKeyPartProperty.equals(otherKeyPartProperty)) { - return false; - } - } - return true; - } - - @Override - public int hashCode() { - int hashCode = super.hashCode(); - - if (this.identifierPartsWithoutFirst.isEmpty()) { - return hashCode; - } - - // sublist to avoid endless recursion - return Objects.hash(hashCode, this.identifierPartsWithoutFirst); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/TarantoolMappingContext.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/TarantoolMappingContext.java deleted file mode 100644 index 7c1f1416..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/TarantoolMappingContext.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.core.mapping; - -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; - -import io.tarantool.spring.data.core.annotation.IdClassResolver; -import io.tarantool.spring.data33.core.annotation.DefaultIdClassResolver; - -public class TarantoolMappingContext< - E extends KeyValuePersistentEntity, P extends KeyValuePersistentProperty

> - extends KeyValueMappingContext { - - private final IdClassResolver idClassResolver; - - private @Nullable KeySpaceResolver keySpaceResolver; - - public TarantoolMappingContext() { - super(); - this.idClassResolver = DefaultIdClassResolver.INSTANCE; - } - - @Override - public void setKeySpaceResolver(KeySpaceResolver keySpaceResolver) { - super.setKeySpaceResolver(keySpaceResolver); - this.keySpaceResolver = keySpaceResolver; - } - - @SuppressWarnings("unchecked") - @Override - protected E createPersistentEntity(TypeInformation typeInformation) { - final Class idClassTypeValue = - this.idClassResolver.resolveIdClassType(typeInformation.getType()); - if (idClassTypeValue == null) { - return (E) new BasicKeyValuePersistentEntity(typeInformation, this.keySpaceResolver); - } - return (E) - new BasicKeyValueCompositePersistentEntity<>( - typeInformation, this.keySpaceResolver, idClassTypeValue); - } - - @SuppressWarnings("unchecked") - @Override - protected P createPersistentProperty( - Property property, E owner, SimpleTypeHolder simpleTypeHolder) { - if (KeyValueCompositePersistentEntity.class.isAssignableFrom(owner.getClass())) { - return (P) new KeyValueCompositeProperty<>(property, owner, simpleTypeHolder); - } - return (P) new KeyValuePersistentProperty<>(property, owner, simpleTypeHolder); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/model/CompositeIdPropertyAccessor.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/model/CompositeIdPropertyAccessor.java deleted file mode 100644 index 1d72f0fb..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/model/CompositeIdPropertyAccessor.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.core.mapping.model; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.util.Map; - -import org.springframework.data.mapping.TargetAwareIdentifierAccessor; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -/** Class that allows to convert {@code @Id} annotated fields in an entity into a composite key. */ -public class CompositeIdPropertyAccessor extends TargetAwareIdentifierAccessor { - - private final Map entityIdClassFields; - - private final Class idClassType; - - private final Object target; - - public CompositeIdPropertyAccessor( - Object target, @NonNull Map entityIdClassFields, Class idClassType) { - - super(target); - this.target = target; - this.entityIdClassFields = entityIdClassFields; - this.idClassType = idClassType; - } - - @Nullable - public Object getIdentifier() { - try { - return generateIdentifier(); - } catch (InstantiationException - | IllegalAccessException - | NoSuchMethodException - | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - /** - * Generates a composite identifier from those marked with the {@code @Id} annotation in a domain - * class based on fields, specified in the composite key class. - * - * @return identifier - * @throws IllegalAccessException if the class or its nullary constructor is not accessible. - * @throws InstantiationException if this {@code Class} represents an abstract class, an - * interface, an array class, a primitive type, or void; or if the class has no nullary - * constructor; or if the instantiation fails for some other reason. - */ - private Object generateIdentifier() - throws InstantiationException, - IllegalAccessException, - NoSuchMethodException, - InvocationTargetException { - Assert.notNull(this.target, "target object must be not null!"); - Object compositeKey = idClassType.getDeclaredConstructor().newInstance(); - for (Map.Entry fieldPair : this.entityIdClassFields.entrySet()) { - writeValuesFromEntityId(compositeKey, fieldPair.getKey(), fieldPair.getValue()); - } - return compositeKey; - } - - /** - * Write the composite primary key fields provided in the entity to the class which implements - * {@link CompositeKey}. - * - * @param compositeKey object of the composite key into which the values are written. - * @param entityField field from the represented entity. - * @param compositeKeyField field from the composite key class. - */ - private void writeValuesFromEntityId( - Object compositeKey, Field entityField, Field compositeKeyField) { - ReflectionUtils.makeAccessible(entityField); - ReflectionUtils.makeAccessible(compositeKeyField); - - Object value = ReflectionUtils.getField(entityField, this.target); - ReflectionUtils.setField(compositeKeyField, compositeKey, value); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/model/PersistentCompositeIdIsNewStrategy.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/model/PersistentCompositeIdIsNewStrategy.java deleted file mode 100644 index baecc283..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/model/PersistentCompositeIdIsNewStrategy.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.core.mapping.model; - -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.support.IsNewStrategy; -import org.springframework.util.Assert; - -/** - * Strategy class for entity with composite key to determine whether a given entity is to be - * considered new. - */ -public class PersistentCompositeIdIsNewStrategy implements IsNewStrategy { - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} for the given entity. - * - * @param entity must not be {@literal null}. - * @param idOnly check only id to determine - */ - private PersistentCompositeIdIsNewStrategy(PersistentEntity entity, boolean idOnly) { - // TODO сделать реализацию версионирования - // TODO add idOnly support - Assert.notNull(entity, "PersistentEntity must not be null"); - } - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} to only consider the identifier of the - * given entity. - * - * @param entity must not be {@literal null}. - * @return strategy to determine whether entity is new or not - */ - public static PersistentCompositeIdIsNewStrategy forIdOnly(PersistentEntity entity) { - return new PersistentCompositeIdIsNewStrategy(entity, true); - } - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} to consider version properties before - * falling back to the identifier. - * - * @param entity must not be {@literal null}. - * @return strategy to determine whether entity is new or not - */ - public static PersistentCompositeIdIsNewStrategy of(PersistentEntity entity) { - return new PersistentCompositeIdIsNewStrategy(entity, false); - } - - /** - * Determine whether the current domain entity type object is new. Currently stub and always - * returns false. - * - * @param entity must not be {@literal null}. - * @return result of the question of entity is new or not - */ - @Override - public boolean isNew(Object entity) { - return false; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/model/package-info.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/model/package-info.java deleted file mode 100644 index d2ad856f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/model/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Core implementation of the mapping subsystem's model. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data33.core.mapping.model; diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/package-info.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/package-info.java deleted file mode 100644 index ff3ea947..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/mapping/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Base package for the mapping subsystem. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data33.core.mapping; diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/package-info.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/package-info.java deleted file mode 100644 index 09c1dbcc..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/core/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Core package for integrating Tarantool with Spring - * concepts. - */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data33.core; diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/Field.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/Field.java deleted file mode 100644 index 0bff1ea4..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/Field.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.core.annotation.AliasFor; - -/** - * Allows adding some metadata to the class fields relevant for storing them in the Tarantool space - * - * @author Artyom Dubinin - */ -@Inherited -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) -public @interface Field { - - /** - * The target Tarantool space field for storing the marked class field. Alias for {@link #name()}. - * - * @return the name of a field in space - */ - @AliasFor("name") - String value() default ""; - - /** - * The target Tarantool space field for storing the marked class field. Alias for {@link - * #value()}. - * - * @return the name of a field in space - */ - @AliasFor("value") - String name() default ""; - - /** - * The order in which fields shall be stored in the tuple. Has to be a positive integer. - * - * @return the order the field shall have in the tuple or -1 if undefined. - */ - int order() default -1; -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/PaginationUtils.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/PaginationUtils.java deleted file mode 100644 index 30cfc23f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/PaginationUtils.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.keyvalue.core.IterableConverter; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class PaginationUtils { - - private static final String CRITERIA_NULL_EXC_MSG = "TarantoolCriteria must be not null"; - - /** - * Returns {@link TarantoolPageable} cast from {@link Pageable} with type checking. - * - * @param sliceParams pageable - * @return {@link TarantoolPageable} - */ - public static TarantoolPageable castToTarantoolPageable(Pageable sliceParams) { - Assert.isInstanceOf(TarantoolPageable.class, sliceParams, "Pageable must be TarantoolPageable"); - return (TarantoolPageable) sliceParams; - } - - /** - * A general method for retrieving data for paginated queries. - * - * @param query query - * @param pageRequest {@link TarantoolPageable} - * @param pageSize page size - * @return selection result. - */ - public static List doPaginationQuery( - final KeyValueQuery query, - TarantoolPageable pageRequest, - int pageSize, - KeyValueOperations keyValueOperations, - Class targetType) { - - TarantoolCriteria criteria = (TarantoolCriteria) query.getCriteria(); - PaginationDirection paginationDirection = pageRequest.getPaginationDirection(); - - Assert.notNull(criteria, CRITERIA_NULL_EXC_MSG); - criteria.withAfter(pageRequest.getTupleCursor()); - - query.setRows(pageSize * paginationDirection.getMultiplier()); - - return IterableConverter.toList(keyValueOperations.find(query, targetType)); - } - - public static Page doPageQuery( - Pageable pageable, - KeyValueQuery query, - KeyValueOperations keyValueOperations, - Class targetType) { - if (pageable.isUnpaged()) { - return new TarantoolPageImpl<>(); - } - TarantoolPageable resultSliceParams = castToTarantoolPageable(pageable); - - int pageSize = resultSliceParams.getPageSize(); - - // non transactional calls - List content = - doPaginationQuery(query, resultSliceParams, pageSize, keyValueOperations, targetType); - - if (content.isEmpty()) { - return new TarantoolPageImpl<>(); - } - - long totalElements = keyValueOperations.count(query, targetType); - return new TarantoolPageImpl<>(content, resultSliceParams, totalElements); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolChunk.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolChunk.java deleted file mode 100644 index bc686f6b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolChunk.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -/** - * A chunk of data restricted by the configured {@link Pageable} for Tarantool. - * - * @author Nikolay Belonogov - */ -abstract class TarantoolChunk implements Slice, Serializable { - - private static final long serialVersionUID = 867755909294344406L; - - private final List content = new ArrayList<>(); - - private final Pageable pageable; - - /** - * Creates a new {@link TarantoolChunk} with the given content and the given governing {@link - * TarantoolPageable}. - * - * @param content must not be {@literal null}. - * @param pageable must not be {@literal null}. - */ - public TarantoolChunk(List content, Pageable pageable) { - - Assert.notNull(content, "Content must not be null"); - Assert.notNull(pageable, "Pageable must not be null"); - - if (pageable.isPaged() && !(pageable instanceof TarantoolPageable)) { - throw new IllegalArgumentException("Pageable must be TarantoolPageable or Unpaged type"); - } - - this.content.addAll(content); - this.pageable = pageable; - } - - @Override - public boolean isFirst() { - return !hasPrevious(); - } - - @Override - public boolean isLast() { - return !hasNext(); - } - - @Override - public boolean hasPrevious() { - return getNumber() > 0 && hasContent(); - } - - @Override - public boolean hasContent() { - return !content.isEmpty(); - } - - /** - * Returns the {@link Pageable} to request the next {@link Slice}. Can be {@link - * Pageable#unpaged()} in case the current {@link Slice} is already the last one or when data - * content is empty. Clients should check {@link #hasNext()} and {@link #hasContent()} before - * calling this method. - * - * @see #nextOrLastPageable() - */ - @NonNull - @Override - @SuppressWarnings("unchecked") - public Pageable nextPageable() { - if (hasNext() && pageable.isPaged()) { - return ((TarantoolPageable) pageable).next(content.get(content.size() - 1)); - } - return Pageable.unpaged(); - } - - /** - * Returns the {@link Pageable} to request the previous {@link Slice}. Can be {@link - * Pageable#unpaged()} in case the current {@link Slice} is already the first one or data content - * is empty. Clients should check {@link #hasPrevious()} and {@link #hasContent()} before calling - * this method. - * - * @see #previousOrFirstPageable() - */ - @NonNull - @Override - @SuppressWarnings("unchecked") - public Pageable previousPageable() { - if (hasPrevious() && pageable.isPaged()) { - return ((TarantoolPageable) pageable).previousOrFirst(content.get(0)); - } - return Pageable.unpaged(); - } - - @Override - public Iterator iterator() { - return content.iterator(); - } - - @NonNull - @Override - public List getContent() { - return Collections.unmodifiableList(content); - } - - @NonNull - @Override - public Pageable getPageable() { - return pageable; - } - - @NonNull - @Override - public Sort getSort() { - return pageable.getSort(); - } - - @Override - public int getNumber() { - if (pageable.isPaged()) { - return pageable.getPageNumber(); - } - return 0; - } - - @Override - public int getSize() { - if (pageable.isPaged()) { - return pageable.getPageSize(); - } - return content.size(); - } - - @Override - public int getNumberOfElements() { - return content.size(); - } - - /** - * Applies the given {@link Function} to the content of the {@link TarantoolChunk}. - * - * @param converter must not be {@literal null}. - */ - protected List getConvertedContent(Function converter) { - - Assert.notNull(converter, "Function must not be null"); - - return this.stream().map(converter).collect(Collectors.toList()); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolChunk)) { - return false; - } - TarantoolChunk that = (TarantoolChunk) o; - return content.equals(that.content) && pageable.equals(that.pageable); - } - - @Override - public int hashCode() { - return Objects.hash(content, pageable); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolCriteriaAccessor.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolCriteriaAccessor.java deleted file mode 100644 index 9c49f58f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolCriteriaAccessor.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import org.springframework.data.keyvalue.core.CriteriaAccessor; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -import io.tarantool.spring.data.query.TarantoolCriteria; - -/** - * Provide a mechanism to convert the abstract query into the direct implementation in Tarantool. - * - * @author Artyom Dubinin - */ -public class TarantoolCriteriaAccessor implements CriteriaAccessor { - - /** - * @param query in Spring form - * @return The same in Tarantool form - */ - public TarantoolCriteria resolve(KeyValueQuery query) { - return (TarantoolCriteria) query.getCriteria(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolKeysetScrollPosition.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolKeysetScrollPosition.java deleted file mode 100644 index ac754cd9..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolKeysetScrollPosition.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.util.List; -import java.util.Objects; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.Pair; - -final class TarantoolKeysetScrollPosition implements TarantoolScrollPosition { - - private final Pair indexKey; - - private final PaginationDirection direction; - - private final Object cursor; - - TarantoolKeysetScrollPosition( - Pair indexKey, PaginationDirection direction, @Nullable Object cursor) { - - Assert.notNull(direction, "PaginationDirection must not be null"); - Assert.notNull(indexKey, "indexKey must not be null"); - - this.indexKey = indexKey; - this.direction = direction; - this.cursor = cursor; - } - - /** - * Creates a new {@link TarantoolKeysetScrollPosition} from a key set and {@link - * PaginationDirection}. - * - * @param indexKey must not be {@literal null}. - * @return will never be {@literal null}. - */ - static TarantoolScrollPosition forward(Pair indexKey) { - return new TarantoolKeysetScrollPosition(indexKey, FORWARD, null); - } - - static TarantoolScrollPosition backward(Pair indexKey) { - return new TarantoolKeysetScrollPosition(indexKey, BACKWARD, null); - } - - /** - * Returns whether the current scroll position is the initial one (from begin or from end) (see - * {@link PaginationDirection}). - * - * @return {@link Boolean} object. - */ - @Override - public boolean isInitial() { - if (indexKey.getSecond() instanceof List startingList) { - return startingList.isEmpty() && cursor == null; - } - return false; - } - - @Override - public TarantoolScrollPosition reverse() { - Pair newIndexKey = Pair.of(indexKey.getFirst(), indexKey.getSecond()); - return new TarantoolKeysetScrollPosition(newIndexKey, direction.reverse(), cursor); - } - - @Override - public boolean isScrollsBackward() { - return direction.equals(BACKWARD); - } - - /** - * Return the cursor relative to which the data is being found. - * - * @return returns cursor - */ - Object getCursor() { - return cursor; - } - - /** - * @return the scroll direction. - */ - PaginationDirection getDirection() { - return direction; - } - - /** - * @return the indexKey. - */ - Pair getIndexKey() { - return indexKey; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolKeysetScrollPosition that)) { - return false; - } - return indexKey.equals(that.indexKey) - && direction == that.direction - && Objects.equals(cursor, that.cursor); - } - - @Override - public int hashCode() { - return Objects.hash(indexKey, direction, cursor); - } - - @Override - public String toString() { - return String.format("TarantoolKeysetScrollPosition [%s, %s, %s]", direction, indexKey, cursor); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolPageImpl.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolPageImpl.java deleted file mode 100644 index 06679872..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolPageImpl.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.io.Serial; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.lang.NonNull; - -/** - * Basic {@code Page} implementation for Tarantool. - * - * @param domain class type. - * @author Nikolay Belonogov - */ -class TarantoolPageImpl extends TarantoolChunk implements Page { - - @Serial private static final long serialVersionUID = 867755909294344406L; - - private final long total; - - /** - * Creates a new {@link TarantoolPageImpl} with empty content. This will result in the created - * {@link Page} being identical to the entire {@link List}. - */ - public TarantoolPageImpl() { - this(Collections.emptyList(), Pageable.unpaged(), 0L); - } - - /** - * Creates a new {@link TarantoolPageImpl} with the given content. This will result in the created - * {@link Page} being identical to the entire {@link List}. - * - * @param content must not be {@literal null}. - */ - public TarantoolPageImpl(List content) { - this(content, Pageable.unpaged(), content == null ? 0L : content.size()); - } - - /** - * Constructor of {@link TarantoolPageImpl}. - * - * @param content the content of this page, must not be {@literal null}. - * @param pageable the paging information, must not be {@literal null}. - * @param total the total amount of items available. The total might be adapted considering the - * length of the content given, if it is going to be the content of the last page. This is in - * place to mitigate inconsistencies. - */ - public TarantoolPageImpl(List content, Pageable pageable, long total) { - - super(content, pageable); - - this.total = - pageable - .toOptional() - .filter(it -> !content.isEmpty()) - .filter(it -> it.getOffset() + it.getPageSize() > total) - .map(it -> it.getOffset() + content.size()) - .orElse(total); - } - - @Override - public int getTotalPages() { - return getSize() == 0 ? 1 : (int) Math.ceil((double) total / (double) getSize()); - } - - @Override - public long getTotalElements() { - return total; - } - - @Override - public boolean hasNext() { - return getNumber() + 1 < getTotalPages() && hasContent(); - } - - @Override - public boolean isLast() { - return !hasNext(); - } - - @Override - @NonNull - public Page map(@NonNull Function converter) { - return new PageImpl<>(getConvertedContent(converter), getPageable(), total); - } - - @Override - public String toString() { - - List content = getContent(); - boolean canGetContentType = !content.isEmpty() && content.get(0) != null; - - String contentType = canGetContentType ? content.get(0).getClass().getName() : "UNKNOWN"; - - return String.format( - "Page %s of %d containing %s instances", getNumber() + 1, getTotalPages(), contentType); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolPageImpl that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return total == that.total; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), total); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolPageRequest.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolPageRequest.java deleted file mode 100644 index bbdf175d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolPageRequest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.io.Serial; -import java.util.Objects; - -import org.springframework.data.domain.AbstractPageRequest; -import org.springframework.data.domain.Sort; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; - -/** - * Basic implementation of {@link TarantoolPageable} for Tarantool. - * - *

Important: When specifying a cursor tuple, you must adhere to the following - * rules: - * - *

1. To specify a page starting from the beginning of {@code space} (the first element of the - * page is the first element found in {@code space}), use {@code tupleCursor == null}. - * - *

2. To specify an arbitrary page (the first element of the page is the next/previous one from - * the given one tuple cursor depending on the methods used and page number), use {@code tupleCursor - * == someTupleCursor} . - * - * @param domain entity type - */ -public final class TarantoolPageRequest extends AbstractPageRequest - implements TarantoolPageable { - - @Serial private static final long serialVersionUID = -4541509938956089562L; - - private final Sort sort; - - private final T tupleCursor; - - private final PaginationDirection paginationDirection; - - /** - * Creates a new unsorted {@link TarantoolPageRequest} from begin of {@code space}. - * - * @param pageSize the size of the page to be returned, must be greater than 0. - */ - public TarantoolPageRequest(int pageSize) { - this(0, pageSize, null); - } - - /** - * Creates a new unsorted {@link TarantoolPageRequest}. - * - *

Important: Use this method with caution! It is important to know the exact - * match of number pages and the tuple after (before) which the page goes (without including this - * tuple in the page itself). A mistake in compliance results in the appearance of blank pages - * with unpaged pageable even when using methods {@link - * TarantoolPageImpl#previousOrFirstPageable()} / {@link TarantoolPageImpl#nextOrLastPageable()} - * and {@link TarantoolSliceImpl#previousOrFirstPageable()} / {@link - * TarantoolSliceImpl#nextOrLastPageable()}. - * - * @param page zero-based page index (virtual), must not be negative. - * @param size the size of the page to be returned, must be greater than 0. - * @param tupleCursor tuple cursor from which the page count begins. More: {@link - * TarantoolPageRequest}. - */ - public TarantoolPageRequest(int page, int size, T tupleCursor) { - this(page, size, Sort.unsorted(), tupleCursor, FORWARD); - } - - /** - * Private constructor to create an instance with a specific {@link PaginationDirection}. - * - * @param page zero-based page index, must not be negative. - * @param size the size of the page to be returned, must be greater than 0. - * @param sort must not be {@literal null}, use {@link Sort#unsorted()} instead. - * @param tupleCursor tuple cursor from which the page count begins. More: {@link - * TarantoolPageRequest}. - * @param direction direction of pagination. - */ - TarantoolPageRequest( - int page, int size, Sort sort, T tupleCursor, @NonNull PaginationDirection direction) { - super(page, size); - Assert.notNull(sort, "Sort must not be null"); - Assert.notNull(direction, "PaginationDirection must not be null"); - - this.sort = sort; - this.tupleCursor = tupleCursor; - this.paginationDirection = direction; - } - - /** Non supported for Tarantool. */ - @Override - @NonNull - public TarantoolPageRequest withPage(int pageNumber) throws UnsupportedOperationException { - throw new UnsupportedOperationException("method \"withPage(int pageNumber)\" unsupported"); - } - - @Override - @NonNull - public TarantoolPageable first() { - return new TarantoolPageRequest<>(getPageSize()); - } - - /** Non supported for Tarantool. Use {@link #next(Object)}. */ - @Override - @NonNull - public TarantoolPageRequest next() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"next()\" unsupported, use next(T nextTupleCursor)"); - } - - @Override - public TarantoolPageRequest next(T tupleCursor) { - return new TarantoolPageRequest<>( - getPageNumber() + 1, getPageSize(), getSort(), tupleCursor, FORWARD); - } - - /** Non supported for Tarantool. Use {@link #previous(Object)}. */ - @Override - @NonNull - public TarantoolPageRequest previous() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"previous()\" unsupported, use previous(T prevTupleCursor)"); - } - - private TarantoolPageRequest previous(T tupleCursor) { - if (hasPrevious()) { - return new TarantoolPageRequest<>( - getPageNumber() - 1, getPageSize(), getSort(), tupleCursor, BACKWARD); - } - return this; - } - - /** Non supported for Tarantool. Use {@link #previousOrFirst(Object)}. */ - @Override - @NonNull - public TarantoolPageable previousOrFirst() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"previousOrFirst()\" unsupported, use previousOrFirst(T prevTupleCursor)"); - } - - @Override - public TarantoolPageable previousOrFirst(T tupleCursor) { - if (hasPrevious()) { - return previous(tupleCursor); - } - return new TarantoolPageRequest<>(0, getPageSize(), getSort(), null, BACKWARD); - } - - @Override - public PaginationDirection getPaginationDirection() { - return this.paginationDirection; - } - - @Override - @NonNull - public Sort getSort() { - return this.sort; - } - - @Override - public T getTupleCursor() { - return this.tupleCursor; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolPageRequest that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return sort.equals(that.sort) - && Objects.equals(tupleCursor, that.tupleCursor) - && paginationDirection == that.paginationDirection; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), sort, tupleCursor, paginationDirection); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolPageable.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolPageable.java deleted file mode 100644 index 5d3bcc4f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolPageable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import org.springframework.data.domain.Pageable; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; - -import io.tarantool.spring.data.query.PaginationDirection; - -/** - * Abstract interface for pagination information in Tarantool. - * - * @param domain class type. - * @author Nikolay Belonogov - */ -public interface TarantoolPageable extends Pageable { - - /** - * Returns tuple cursor of domain type. Can be {@code null}. If the cursor is {@code null} then - * the page is counted from the first tuple in Tarantool. - * - * @return tuple cursor of domain type. - */ - @Nullable - T getTupleCursor(); - - /** - * Returns the {@link TarantoolPageable} for previous page or the {@link TarantoolPageable} for - * first page if the current one already is the first one. Important: this method - * always returns {@link TarantoolPageable} c {@link PaginationDirection#BACKWARD}. - * - * @param tupleCursor tuple cursor of domain type for previous page. - * @return {@link TarantoolPageable} instance. - */ - TarantoolPageable previousOrFirst(T tupleCursor); - - /** - * Returns the {@link TarantoolPageable} requesting the next {@link - * org.springframework.data.domain.Page}. - * - *

Important: method always creates a new {@link TarantoolPageable} with the - * same parameters Sort and page size. Pagination direction is {@link - * PaginationDirection#FORWARD}, the page number always has value {@code n+1}, n is the current - * page number. - * - * @param tupleCursor tuple cursor of domain type for next page. - * @return {@link TarantoolPageable} object - */ - TarantoolPageable next(T tupleCursor); - - /** - * Returns pagination direction by {@link PaginationDirection} enumeration. - * - * @return {@link PaginationDirection}. - */ - PaginationDirection getPaginationDirection(); - - /** - * Returns a {@link TarantoolPageable} that points to the first page with {@link - * PaginationDirection#FORWARD} pagination direction. - * - * @return {@link TarantoolPageable} which has {@code cursor == null}, page number is 0, the rest - * parameters are equivalent to the parameters of the current {@link TarantoolPageable}. - */ - @NonNull - TarantoolPageable first(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolPartTreeQuery.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolPartTreeQuery.java deleted file mode 100644 index 817373a2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolPartTreeQuery.java +++ /dev/null @@ -1,506 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.springframework.data.domain.Limit; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; -import org.springframework.data.keyvalue.core.IterableConverter; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery; -import org.springframework.data.repository.query.Parameter; -import org.springframework.data.repository.query.Parameters; -import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.data.util.StreamUtils; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -import static io.tarantool.client.crud.ConditionOperator.GREATER_EQ; -import static io.tarantool.client.crud.ConditionOperator.LESS_EQ; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import static io.tarantool.spring.data33.query.PaginationUtils.doPageQuery; -import static io.tarantool.spring.data33.query.PaginationUtils.doPaginationQuery; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.query.TarantoolCriteria; -import io.tarantool.spring.data.utils.Pair; - -/** - * There is one instance for each query method defined for a repository, providing a query from the - * bind parameters. - * - * @author Artyom Dubinin - */ -public class TarantoolPartTreeQuery extends KeyValuePartTreeQuery { - - public static final String ILLEGAL_RETURN_TYPE_FOR_DELETE = - "Illegal returned type: %s. The operation 'deleteBy' accepts only 'long' and 'Collection' as" - + " the returned object type"; - public static final String QUERY_METHOD_S_NOT_SUPPORTED = "Query method '%s' not supported."; - private final QueryMethod queryMethod; - private final KeyValueOperations keyValueOperations; - private final PartTree tree; - - private final boolean isCount; - private final boolean isDelete; - private final boolean isDistinct; - private final boolean isExists; - private final Class targetType; - private final Class returnType; - - private boolean isRearrangeKnown; - private boolean isRearrangeRequired; - private int[] rearrangeIndex; - - private final List EMPTY_KEY = Collections.emptyList(); - - /** - * Create a {@link RepositoryQuery} implementation for each query method defined in a tarantool - * repository. - * - * @param queryMethod Method defined in Tarantool Repositories - * @param evaluationContextProvider Not used - * @param keyValueOperations Interface to Tarantool - * @param queryCreator Not used - */ - public TarantoolPartTreeQuery( - QueryMethod queryMethod, - QueryMethodEvaluationContextProvider evaluationContextProvider, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - super(queryMethod, evaluationContextProvider, keyValueOperations, queryCreator); - this.queryMethod = queryMethod; - this.keyValueOperations = keyValueOperations; - this.isRearrangeKnown = false; - this.targetType = queryMethod.getEntityInformation().getJavaType(); - this.returnType = queryMethod.getReturnedObjectType(); - this.tree = new PartTree(getQueryMethod().getName(), targetType); - if (queryMethod.getParameters().getNumberOfParameters() > 0) { - this.isCount = tree.isCountProjection(); - this.isDelete = tree.isDelete(); - this.isDistinct = tree.isDistinct(); - this.isExists = tree.isExistsProjection(); - } else { - this.isCount = false; - this.isDelete = false; - this.isDistinct = false; - this.isExists = false; - } - } - - /** - * Execute this query instance, using any invocation parameters. - * - *

Expecting {@code findBy...()}, {@code countBy...()} or {@code deleteBy...()} - * - * @param parameters Any parameters - * @return Query result - */ - @Override - public Object execute(@NonNull Object[] parameters) { - ParametersParameterAccessor accessor = this.prepareAccessor(parameters, tree); - - KeyValueQuery query = prepareQuery(accessor); - - if (this.isCount) { - if (this.isDistinct) { - final Iterable iterable = this.keyValueOperations.find(query, targetType); - return StreamUtils.createStreamFromIterator(iterable.iterator()).distinct().count(); - } - return this.keyValueOperations.count(query, targetType); - } - - if (this.isDelete) { - return this.executeDeleteQuery(query); - } - - if (this.isExists) { - query.setOffset(0); - query.setRows(1); - final Iterable result = this.keyValueOperations.find(query, targetType); - return result.iterator().hasNext(); - } - - if (queryMethod.isPageQuery()) { - return this.executePageQuery(query, accessor); - } - - if (queryMethod.isSliceQuery()) { - return this.executeSliceQuery(query, accessor); - } - - if (queryMethod.isScrollQuery()) { - return this.executeScrollQuery(query, accessor); - } - - if (queryMethod.isCollectionQuery() - || queryMethod.isQueryForEntity() - || queryMethod.isStreamQuery()) { - return this.executeFindQuery(query); - } - - throw new UnsupportedOperationException( - String.format(QUERY_METHOD_S_NOT_SUPPORTED, queryMethod.getName())); - } - - /** - * Execute a "delete" query, not really a query more of an operation. - * - *

- * - * @param query The query to run - * @return Collection of deleted objects or the number of deleted objects - */ - private Object executeDeleteQuery(final KeyValueQuery query) { - - Iterable resultSet = this.keyValueOperations.find(query, targetType); - Iterator iterator = resultSet.iterator(); - - List result = new ArrayList<>(); - while (iterator.hasNext()) { - result.add(this.keyValueOperations.delete(iterator.next())); - } - - if (queryMethod.isCollectionQuery()) { - return result; - } - if (long.class.equals(returnType) || Long.class.equals(returnType)) { - return result.size(); - } - throw new UnsupportedOperationException( - String.format(ILLEGAL_RETURN_TYPE_FOR_DELETE, returnType)); - } - - /** - * Execute a retrieval query. The query engine will return this in an iterator, which may need - * conversion to a single domain entity or a stream. - * - * @param query The query to run - * @return Query result - */ - private Object executeFindQuery(final KeyValueQuery query) { - - Iterable resultSet = this.keyValueOperations.find(query, targetType); - - if (!queryMethod.isCollectionQuery() - && !queryMethod.isPageQuery() - && !queryMethod.isSliceQuery() - && !queryMethod.isStreamQuery()) { - // Singleton result - return resultSet.iterator().hasNext() ? resultSet.iterator().next() : null; - } - - Stream stream = StreamUtils.createStreamFromIterator(resultSet.iterator()); - if (this.isDistinct) { - stream = stream.distinct(); - } - - if (queryMethod.isStreamQuery()) { - return stream; - } - - // optimization: - // we can omit if condition - // but this will recreate result even if it's not distinct and isn't stream query - if (this.isDistinct) { - return stream.collect(Collectors.toList()); - } - - return resultSet; - } - - private Object executeScrollQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - ScrollPosition scrollPosition = accessor.getScrollPosition(); - - Assert.notNull( - scrollPosition, - "The ScrollPosition parameter must be specified. Method: " + queryMethod.getName()); - - if (!(scrollPosition instanceof TarantoolKeysetScrollPosition keysetScrollPosition)) { - throw new IllegalArgumentException( - "ScrollPosition must be an instance of TarantoolKeysetScrollPosition. Method: " - + queryMethod.getName()); - } - - int pageSize = query.getRows(); - List content = doScrollQuery(query, keysetScrollPosition, pageSize + 1); - - boolean hasNext = content.size() > pageSize; - - final List finalResult = getPaginationSubResult(content, pageSize, FORWARD, hasNext); - return Window.from( - finalResult, - value -> - new TarantoolKeysetScrollPosition( - keysetScrollPosition.getIndexKey(), - keysetScrollPosition.getDirection(), - finalResult.get(value)), - hasNext); - } - - private List doScrollQuery( - final KeyValueQuery query, TarantoolKeysetScrollPosition scrollPosition, int pageSize) { - TarantoolCriteria criteria = castToTarantoolCriteria(query.getCriteria()); - PaginationDirection paginationDirection = scrollPosition.getDirection(); - - Object cursor = scrollPosition.getCursor(); - Pair indexKey = scrollPosition.getIndexKey(); - - Object second = EMPTY_KEY; - if (cursor == null) { - second = indexKey.getSecond(); - } - - switch (paginationDirection) { - case FORWARD -> - criteria.addCondition(0, Condition.create(GREATER_EQ, indexKey.getFirst(), second)); - case BACKWARD -> - criteria.addCondition(0, Condition.create(LESS_EQ, indexKey.getFirst(), second)); - } - - criteria.withAfter(cursor); - query.setRows(pageSize); - return IterableConverter.toList(this.keyValueOperations.find(query, targetType)); - } - - /** - * Execute the slice request. - * - * @param query query - * @param accessor accessor - * @return slice selection result. - */ - private Object executePageQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - - Pageable pageParams = accessor.getPageable(); - - return doPageQuery(pageParams, query, this.keyValueOperations, targetType); - } - - private Object executeSliceQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - - Pageable sliceParams = accessor.getPageable(); - - if (sliceParams.isUnpaged()) { - return new TarantoolSliceImpl<>(Collections.emptyList()); - } - - TarantoolPageable resultSliceParams = castToTarantoolPageable(sliceParams); - - int pageSize = resultSliceParams.getPageSize(); - - List content = - doPaginationQuery( - query, resultSliceParams, pageSize + 1, this.keyValueOperations, targetType); - - if (content.isEmpty()) { - return new TarantoolSliceImpl<>(); - } - - boolean hasNext = content.size() > resultSliceParams.getPageSize(); - PaginationDirection paginationDirection = resultSliceParams.getPaginationDirection(); - - List result = getPaginationSubResult(content, pageSize, paginationDirection, hasNext); - return new TarantoolSliceImpl<>(result, resultSliceParams, hasNext); - } - - /** - * Returns {@link TarantoolPageable} cast from {@link Pageable} with type checking. - * - * @param sliceParams pageable - * @return {@link TarantoolPageable} - */ - private TarantoolPageable castToTarantoolPageable(Pageable sliceParams) { - Assert.isInstanceOf(TarantoolPageable.class, sliceParams, "Pageable must be TarantoolPageable"); - return (TarantoolPageable) sliceParams; - } - - /** - * The method allows you to get {@link TarantoolCriteria} even when pagination is used through - * methods the base repository (not via derived methods). - * - * @param criteria criteria object - * @return An instance of {@link TarantoolCriteria}, or creates a new one if null. - */ - private TarantoolCriteria castToTarantoolCriteria(Object criteria) { - if (criteria == null) { - return new TarantoolCriteria(); - } - - if (!(criteria instanceof TarantoolCriteria)) { - throw new IllegalArgumentException("criteria must be instance of TarantoolCriteria"); - } - return (TarantoolCriteria) criteria; - } - - private List getPaginationSubResult( - List content, int pageSize, PaginationDirection direction, boolean hasNext) { - if (hasNext) { - switch (direction) { - case FORWARD -> { - return content.subList(0, pageSize); - } - case BACKWARD -> { - return content.subList(1, content.size()); - } - } - } - return content; - } - - /** - * Create the query from the bind parameters. - * - * @return A ready-to-use query - */ - @NonNull - protected KeyValueQuery prepareQuery(ParametersParameterAccessor accessor) { - KeyValueQuery query = createQuery(accessor); - - /* - If there is no limitation in the name of the method, we always put a - limit so that don't think about this in the engine, especially when distinguishing between a regular query and a - paginated query. - */ - if (!tree.isLimiting()) { - query.setRows(SelectOptions.DEFAULT_LIMIT); - } - - Limit limit = accessor.getLimit(); - if (limit.isLimited()) { - final int max = limit.max(); - if (max < 0) { - throw new IllegalArgumentException( - "The max number of potential results should be positive! Method: " - + queryMethod - + ". Limit: " - + max); - } - query.setRows(limit.max()); - } - - if (accessor.getSort() != Sort.unsorted()) { - query.setSort(accessor.getSort()); - } - - return query; - } - - /** - * Handle {@code @Param}. - * - *
    - *
  1. Without {@code @Param} - *

    Arguments to the call are assumed to follow the same sequence as cited in the method - * name.
    - * Eg. - *

    -   *     findByOneAndTwo(String one, String two);
    -   *     
    - *
  2. With {@code @Param} - *

    Arguments to the call are use the {@code @Param} to match them against the fields. - *

    Eg. - *

    -   *   findByOneAndTwo(@Param("two") String two, @Param("one") String one);
    -   *   
    - *
- * - * @param originalParameters Possibly empty - * @param partTree Query tree to traverse - * @return Parameters in correct order - */ - private ParametersParameterAccessor prepareAccessor( - final Object[] originalParameters, final PartTree partTree) { - - if (!this.isRearrangeKnown) { - this.prepareRearrange(partTree, this.queryMethod.getParameters().getBindableParameters()); - this.isRearrangeKnown = true; - } - - Object[] parameters = originalParameters; - Assert.notNull(parameters, "Parameters must not be null."); - - if (this.isRearrangeRequired) { - parameters = new Object[originalParameters.length]; - - for (int i = 0; i < parameters.length; i++) { - int index = (i < rearrangeIndex.length) ? rearrangeIndex[i] : i; - parameters[i] = originalParameters[index]; - } - } - - return new ParametersParameterAccessor(this.queryMethod.getParameters(), parameters); - } - - /** - * Determine if the arguments to the method need reordered. - * - *

For searches such as {@code findBySomethingNotNull} there may be more parts than parameters - * needed to be bound to them. - * - * @param partTree Query parts - * @param bindableParameters Parameters expected - */ - @SuppressWarnings("unchecked") - private void prepareRearrange( - final PartTree partTree, final Parameters bindableParameters) { - - this.isRearrangeRequired = false; - if (partTree == null || bindableParameters == null) { - return; - } - - List queryParams = new ArrayList<>(); - List methodParams = new ArrayList<>(); - - for (Part part : partTree.getParts()) { - queryParams.add(part.getProperty().getSegment()); - } - - Iterator bindableParameterIterator = - (Iterator) bindableParameters.iterator(); - while (bindableParameterIterator.hasNext()) { - Parameter parameter = bindableParameterIterator.next(); - parameter.getName().ifPresent(methodParams::add); - } - - this.rearrangeIndex = new int[queryParams.size()]; - - String[] paramsExpected = queryParams.toArray(new String[0]); - String[] paramsProvided = methodParams.toArray(new String[0]); - - for (int i = 0; i < this.rearrangeIndex.length; i++) { - this.rearrangeIndex[i] = i; - - for (int j = 0; j < paramsProvided.length; j++) { - if (paramsProvided[j] != null && paramsProvided[j].equals(paramsExpected[i])) { - this.rearrangeIndex[i] = j; - this.isRearrangeRequired = true; - } - } - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolQueryCreator.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolQueryCreator.java deleted file mode 100644 index a62a234a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolQueryCreator.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.mapping.PropertyPath; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -import static io.tarantool.client.crud.ConditionOperator.EQ; -import static io.tarantool.client.crud.ConditionOperator.GREATER; -import static io.tarantool.client.crud.ConditionOperator.GREATER_EQ; -import static io.tarantool.client.crud.ConditionOperator.LESS; -import static io.tarantool.client.crud.ConditionOperator.LESS_EQ; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.ConditionOperator; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolQueryCreator - extends AbstractQueryCreator, TarantoolCriteria> { - - private final Map cache = new ConcurrentHashMap<>(); - - public static final String INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE = - "Logic error for '%s' in query. "; - - public TarantoolQueryCreator(PartTree tree, ParameterAccessor parameters) { - super(tree, parameters); - } - - private String getFieldName(Part part) { - PropertyPath property = part.getProperty(); - String segment = property.toDotPath(); - Class domainType = property.getOwningType().getType(); - java.lang.reflect.Field field = ReflectionUtils.findField(domainType, segment); - - if (field == null) { - throw new IllegalArgumentException("No such field: " + segment + " in " + domainType); - } - Field annotationField = field.getAnnotation(Field.class); - - if (annotationField != null) { - String value = annotationField.value(); - if (StringUtils.hasText(value)) { - return value; - } - String name = annotationField.name(); - if (StringUtils.hasText(name)) { - return name; - } - } - - return segment; - } - - @Override - @NonNull - protected TarantoolCriteria create(Part part, @NonNull Iterator iterator) { - final TarantoolCriteria tarantoolCriteria = new TarantoolCriteria(); - - Part.Type type = part.getType(); - if (isIgnoreCase(part)) { - throw new InvalidDataAccessApiUsageException( - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "IgnoreCase isn't supported yet", - type)); - } - String property = cache.computeIfAbsent(part, this::getFieldName); - - switch (type) { - case SIMPLE_PROPERTY: - generateConditions(tarantoolCriteria, type, property, iterator, EQ); - break; - case LESS_THAN: - case BEFORE: - generateConditions(tarantoolCriteria, type, property, iterator, LESS); - break; - case LESS_THAN_EQUAL: - generateConditions(tarantoolCriteria, type, property, iterator, LESS_EQ); - break; - case GREATER_THAN: - case AFTER: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER); - break; - case GREATER_THAN_EQUAL: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER_EQ); - break; - case BETWEEN: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER, LESS); - break; - case TRUE: - tarantoolCriteria.addCondition(Condition.create(EQ, property, true)); - break; - case FALSE: - tarantoolCriteria.addCondition(Condition.create(EQ, property, false)); - break; - case IS_EMPTY: - tarantoolCriteria.addCondition(Condition.create(EQ, property, "")); - break; - case IS_NULL: - tarantoolCriteria.addCondition(Condition.create(EQ, property, null)); - break; - default: - throw new InvalidDataAccessApiUsageException(String.format("Unsupported type '%s'", type)); - } - - return tarantoolCriteria; - } - - private void generateConditions( - TarantoolCriteria tarantoolCriteria, - Part.Type type, - String property, - Iterator iterator, - ConditionOperator... operators) { - for (int i = 0; i < type.getNumberOfArguments(); i++) { - if (!iterator.hasNext()) { - throw new InvalidDataAccessApiUsageException( - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "Transmitted not enough arguments (%d of %d)", - type, - i, - type.getNumberOfArguments())); - } - tarantoolCriteria.addCondition(Condition.create(operators[i], property, iterator.next())); - } - } - - private boolean isIgnoreCase(Part part) { - switch (part.shouldIgnoreCase()) { - case ALWAYS: - Assert.state( - canUpperCase(part.getProperty()), - String.format( - "Unable to ignore case of %s types, the property '%s' must reference a String", - part.getProperty().getType().getName(), part.getProperty().getSegment())); - return true; - case WHEN_POSSIBLE: - return canUpperCase(part.getProperty()); - case NEVER: - default: - return false; - } - } - - private boolean canUpperCase(PropertyPath path) { - return String.class.equals(path.getType()); - } - - @Override - @NonNull - protected TarantoolCriteria and( - @NonNull Part part, @NonNull TarantoolCriteria base, @NonNull Iterator iterator) { - throw new UnsupportedOperationException(); - } - - @Override - @NonNull - protected TarantoolCriteria or( - @NonNull TarantoolCriteria base, @NonNull TarantoolCriteria criteria) { - throw new UnsupportedOperationException(); - } - - @Override - @NonNull - protected KeyValueQuery complete( - @Nullable final TarantoolCriteria criteria, @NonNull Sort sort) { - return new KeyValueQuery<>(criteria); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolQueryMethodImpl.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolQueryMethodImpl.java deleted file mode 100644 index 2b636c42..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolQueryMethodImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.lang.reflect.Method; - -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryMethod; - -import io.tarantool.spring.data.query.Query; -import io.tarantool.spring.data.query.TarantoolQueryMethod; - -/** Tarantool {@link QueryMethod} Implementation */ -public class TarantoolQueryMethodImpl extends QueryMethod implements TarantoolQueryMethod { - - private final Method method; - - public TarantoolQueryMethodImpl( - Method method, RepositoryMetadata metadata, ProjectionFactory factory) { - super(method, metadata, factory); - this.method = method; - } - - public boolean hasAnnotatedQuery() { - return getQuery() != null; - } - - public String getQueryValue(Query query) { - return (String) AnnotationUtils.getValue(query); - } - - public Query getQuery() { - return method.getAnnotation(Query.class); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolRepositoryQuery.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolRepositoryQuery.java deleted file mode 100644 index 46b24738..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolRepositoryQuery.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.RepositoryQuery; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.query.ProxyTarantoolRepositoryQuery; - -/** {@link RepositoryQuery} using String based function name to call function in Tarantool. */ -public class TarantoolRepositoryQuery implements RepositoryQuery { - - private final ProxyTarantoolRepositoryQuery proxy; - private final TarantoolQueryMethodImpl queryMethod; - - public TarantoolRepositoryQuery( - TarantoolCrudClient client, TarantoolQueryMethodImpl queryMethod) { - this.queryMethod = queryMethod; - this.proxy = new ProxyTarantoolRepositoryQuery(client, queryMethod); - } - - @Override - public Object execute(Object[] parameters) { - return proxy.execute(parameters); - } - - @Override - public QueryMethod getQueryMethod() { - return queryMethod; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolSliceImpl.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolSliceImpl.java deleted file mode 100644 index 311be76e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolSliceImpl.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.io.Serial; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.lang.NonNull; - -/** - * Default implementation of {@link Slice} for Tarantool. - * - * @author Nikolay Belonogov - */ -class TarantoolSliceImpl extends TarantoolChunk { - - @Serial private static final long serialVersionUID = 867755909294344406L; - - private final boolean hasNext; - - private final Pageable pageable; - - /** - * Creates a new {@link TarantoolSliceImpl} with the empty content. This will result in the - * created {@link Slice} being identical to the entire {@link List}. - */ - public TarantoolSliceImpl() { - this(Collections.emptyList(), Pageable.unpaged(), false); - } - - /** - * Creates a new {@link TarantoolSliceImpl} with the given content. This will result in the - * created {@link Slice} being identical to the entire {@link List}. - * - * @param content must not be {@literal null}. - */ - public TarantoolSliceImpl(List content) { - this(content, Pageable.unpaged(), false); - } - - /** - * Creates a new {@link TarantoolSliceImpl} with the given content and {@link Pageable}. - * - * @param content the content of this {@link Slice}, must not be {@literal null}. - * @param pageable the paging information, must not be {@literal null}. - * @param hasNext whether there's another slice following the current one. - */ - public TarantoolSliceImpl(List content, Pageable pageable, boolean hasNext) { - super(content, pageable); - - this.hasNext = hasContent() && hasNext; - this.pageable = pageable; - } - - /** - * Returns true if there is a next data slice. No data content means that the next slice does not - * exist and method will return false. - * - * @return Returns true if there is a next data slice. No data content means that the next slice - * does not exist and method will return false. - */ - @Override - public boolean hasNext() { - return hasNext && hasContent(); - } - - @Override - @NonNull - public Slice map(@NonNull Function converter) { - return new TarantoolSliceImpl<>(getConvertedContent(converter), pageable, hasNext); - } - - @Override - public String toString() { - - String contentType = "UNKNOWN"; - List content = getContent(); - - if (content.size() > 0) { - contentType = content.get(0).getClass().getName(); - } - - return String.format("Slice %d containing %s instances", getNumber(), contentType); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolSliceImpl that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return hasNext == that.hasNext && pageable.equals(that.pageable); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), hasNext, pageable); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolSortAccessor.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolSortAccessor.java deleted file mode 100644 index 2983db0a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolSortAccessor.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.util.Comparator; -import java.util.Map.Entry; - -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Sort.Order; -import org.springframework.data.keyvalue.core.SortAccessor; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -/** - * Implements sorting for Tarantool repository queries. - * - * @author Artyom Dubinin - */ -public class TarantoolSortAccessor implements SortAccessor>> { - - /** - * Sort on a sequence of fields, possibly none. - * - * @param query If not null, will contain one of more {@link Order} objects. - * @return A sequence of comparators or {@code null} - */ - public Comparator> resolve(KeyValueQuery query) { - if (query == null || query.getSort() == Sort.unsorted()) { - return null; - } - - throw new UnsupportedOperationException(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolWindowIterator.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolWindowIterator.java deleted file mode 100644 index 9d4dd8a8..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolWindowIterator.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.function.Function; - -import org.springframework.data.domain.Window; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * The class is a complete analogue of {@link org.springframework.data.support.WindowIterator} for - * Tarantool. - * - *

Example of usage: - * - *

- * - *
{@code
- * TarantoolScrollPosition initialScrollPosition =
- *     TarantoolScrollPosition.forward(Pair.of("pk", Collections.emptyList()));
- *
- * TarantoolWindowIterator personIterator =
- *     TarantoolWindowIterator.of(scrollPosition -> repository.findFirst10ByAge(10, scrollPosition))
- *         .startingAt(initialScrollPosition);
- *
- * List result = new ArrayList<>();
- *
- * while (personIterator.hasNext()) {
- *   result.add(personIterator.next());
- * }
- * }
- * - *
- * - * @param domain class type. - */ -public class TarantoolWindowIterator implements Iterator { - - private final Function> windowFunction; - - private TarantoolScrollPosition currentPosition; - - private @Nullable Window currentWindow; - - private @Nullable Iterator currentIterator; - - /** - * Entrypoint to create a new {@link TarantoolWindowIterator} for the given windowFunction. - * - * @param windowFunction must not be {@literal null}. - * @param domain class type. - * @return new instance of {@link TarantoolWindowIteratorBuilder}. - */ - public static TarantoolWindowIteratorBuilder of( - Function> windowFunction) { - return new TarantoolWindowIteratorBuilder<>(windowFunction); - } - - TarantoolWindowIterator( - Function> windowFunction, - TarantoolScrollPosition position) { - - this.windowFunction = windowFunction; - this.currentPosition = position; - } - - @Override - public boolean hasNext() { - - // use while loop instead of recursion to fetch the next window. - do { - if (currentWindow == null) { - currentWindow = windowFunction.apply(currentPosition); - } - - if (currentIterator == null) { - if (currentWindow != null) { - currentIterator = currentWindow.iterator(); - } - } - - if (currentIterator != null) { - - if (currentIterator.hasNext()) { - return true; - } - - if (currentWindow != null && currentWindow.hasNext()) { - - currentPosition = getNextPosition(currentWindow); - currentIterator = null; - currentWindow = null; - continue; - } - } - - return false; - } while (true); - } - - @Override - public T next() { - - if (!hasNext()) { - throw new NoSuchElementException(); - } - - return currentIterator.next(); - } - - private static TarantoolScrollPosition getNextPosition(Window window) { - return (TarantoolScrollPosition) window.positionAt(window.size() - 1); - } - - /** Builder API to construct a {@link TarantoolWindowIterator}. */ - public static class TarantoolWindowIteratorBuilder { - - private final Function> windowFunction; - - TarantoolWindowIteratorBuilder(Function> windowFunction) { - - Assert.notNull(windowFunction, "WindowFunction must not be null"); - - this.windowFunction = windowFunction; - } - - /** - * Create a {@link TarantoolWindowIterator} given {@link TarantoolScrollPosition}. - * - * @param position {@link TarantoolScrollPosition} instance. Must be not null. - * @return {@link TarantoolWindowIterator} instance. - */ - public TarantoolWindowIterator startingAt(TarantoolScrollPosition position) { - - Assert.notNull(position, "TarantoolScrollPosition must not be null"); - - return new TarantoolWindowIterator<>(windowFunction, position); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/TarantoolRepositoryFactory.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/TarantoolRepositoryFactory.java deleted file mode 100644 index 5565da8d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/TarantoolRepositoryFactory.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.repository; - -import java.util.Optional; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.SpelQueryCreator; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data33.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data33.repository.config.TarantoolQueryLookupStrategy; -import io.tarantool.spring.data33.repository.support.TarantoolSimpleRepository; - -/** - * Tarantool version of {@link KeyValueRepositoryFactory}, a factory to build tarantool repository - * instances. - * - *

The purpose of extending is to ensure that the {@link #getQueryLookupStrategy} method returns - * a {@link TarantoolQueryLookupStrategy} rather than the default. - * - *

The end goal of this bean is for {@link TarantoolPartTreeQuery} to be used for query - * preparation. - * - * @author Artyom Dubinin - */ -public class TarantoolRepositoryFactory extends KeyValueRepositoryFactory { - - private static final Class DEFAULT_QUERY_CREATOR = SpelQueryCreator.class; - - private final KeyValueOperations keyValueOperations; - private final Class> queryCreator; - private final TarantoolCrudClient client; - - /* Mirror functionality of super, to ensure private - * fields are set. - */ - public TarantoolRepositoryFactory( - TarantoolCrudClient client, KeyValueOperations keyValueOperations) { - this(client, keyValueOperations, DEFAULT_QUERY_CREATOR); - } - - /* Capture KeyValueOperations and QueryCreator objects after passing to super. - */ - public TarantoolRepositoryFactory( - TarantoolCrudClient client, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - - super(keyValueOperations, queryCreator); - - this.client = client; - this.keyValueOperations = keyValueOperations; - this.queryCreator = queryCreator; - } - - /** - * Ensure the mechanism for query evaluation is Tarantool specific, as the original {@code - * KeyValueQueryLookupStrategy} does not function correctly for Tarantool. - */ - @Override - protected Optional getQueryLookupStrategy( - QueryLookupStrategy.Key key, QueryMethodEvaluationContextProvider evaluationContextProvider) { - return Optional.of( - new TarantoolQueryLookupStrategy( - client, key, evaluationContextProvider, keyValueOperations, queryCreator)); - } - - @Override - protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { - return TarantoolSimpleRepository.class; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/EnableTarantoolRepositories.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/EnableTarantoolRepositories.java deleted file mode 100644 index 254493fd..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/EnableTarantoolRepositories.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.repository.config; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.ComponentScan.Filter; -import org.springframework.context.annotation.Import; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.config.QueryCreatorType; -import org.springframework.data.repository.config.DefaultRepositoryBaseClass; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryLookupStrategy.Key; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.spring.data33.config.properties.TarantoolProperties; -import io.tarantool.spring.data33.query.TarantoolQueryCreator; -import io.tarantool.spring.data33.repository.support.TarantoolRepositoryFactoryBean; - -@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@Import(TarantoolRepositoriesRegistrar.class) -@EnableConfigurationProperties(TarantoolProperties.class) -@QueryCreatorType(TarantoolQueryCreator.class) -public @interface EnableTarantoolRepositories { - - /** - * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation - * declarations e.g.: {@code @EnableJpaRepositories("org.my.pkg")} instead of - * {@code @EnableJpaRepositories(basePackages="org.my.pkg")}. - * - * @return value - */ - String[] value() default {}; - - /** - * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually - * exclusive with) this attribute. Use {@link #basePackageClasses()} for a type-safe alternative - * to String-based package names. - * - * @return base packages - */ - String[] basePackages() default {}; - - /** - * Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for - * annotated components. The package of each class specified will be scanned. Consider creating a - * special no-op marker class or interface in each package that serves no purpose other than being - * referenced by this attribute. - * - * @return classes - */ - Class[] basePackageClasses() default {}; - - /** - * Specifies which types are not eligible for component scanning. - * - * @return filters - */ - Filter[] excludeFilters() default {}; - - /** - * Specifies which types are eligible for component scanning. Further, narrows the set of - * candidate components from everything in {@link #basePackages()} to everything in the base - * packages that matches the given filter or filters. - * - * @return filters - */ - Filter[] includeFilters() default {}; - - /** - * Returns the postfix to be used when looking up custom repository implementations. Defaults to - * {@literal Impl}. So for a repository named {@code PersonRepository} the corresponding - * implementation class will be looked up scanning for {@code PersonRepositoryImpl}. - * - * @return postfix - */ - String repositoryImplementationPostfix() default "Impl"; - - /** - * Configures the location of where to find the Spring Data named queries properties file. - * - * @return location - */ - String namedQueriesLocation() default ""; - - /** - * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query - * methods. Defaults to {@link Key#CREATE_IF_NOT_FOUND}. - * - * @return strategy - */ - Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND; - - Class repositoryFactoryBeanClass() default TarantoolRepositoryFactoryBean.class; - - /** - * Allow custom base classes, for generic behavior shared amongst selected repositories. - * - * @return base class - */ - Class repositoryBaseClass() default DefaultRepositoryBaseClass.class; - - /** - * Configures the name of the {@link KeyValueOperations} bean to be used with the repositories - * detected. - * - * @return reference to {@link KeyValueOperations} bean. - */ - String keyValueTemplateRef() default DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; - - /** - * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be - * discovered by the repositories' infrastructure. - * - * @return result of consideration - */ - boolean considerNestedRepositories() default false; - - /** - * Configures the {@link ClientType} to be used as driver client type to connection to Tarantool. - * Must match the referenced type in {@link #keyValueTemplateRef()}} if these values differ from - * the default ones. - * - * @return the type of client through which communication with Tarantool will be made. - */ - ClientType clientType() default ClientType.CRUD; -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/TarantoolQueryLookupStrategy.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/TarantoolQueryLookupStrategy.java deleted file mode 100644 index 8d5bc5ca..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/TarantoolQueryLookupStrategy.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.repository.config; - -import java.lang.reflect.Method; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery; -import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.repository.core.NamedQueries; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.util.Assert; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data33.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data33.query.TarantoolQueryMethodImpl; -import io.tarantool.spring.data33.query.TarantoolRepositoryQuery; - -/** - * Ensures {@link TarantoolPartTreeQuery} is used for query preparation rather than {@link - * KeyValuePartTreeQuery} or other alternatives. - * - * @author Artyom Dubinin - */ -public class TarantoolQueryLookupStrategy implements QueryLookupStrategy { - - private final QueryMethodEvaluationContextProvider evaluationContextProvider; - private final KeyValueOperations keyValueOperations; - private final Class> queryCreator; - private final TarantoolCrudClient client; - - /** - * Required constructor, capturing arguments for use in {@link #resolveQuery}. - * - * @param client tarantool crud client - * @param key Not used - * @param evaluationContextProvider For evaluation of query expressions - * @param keyValueOperations Bean to use for Key/Value operations on Tarantool repos - * @param queryCreator Query creator - */ - public TarantoolQueryLookupStrategy( - TarantoolCrudClient client, - Key key, - QueryMethodEvaluationContextProvider evaluationContextProvider, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - - Assert.notNull(evaluationContextProvider, "EvaluationContextProvider must not be null!"); - Assert.notNull(keyValueOperations, "KeyValueOperations must not be null!"); - Assert.notNull(queryCreator, "Query creator type must not be null!"); - - this.client = client; - this.evaluationContextProvider = evaluationContextProvider; - this.keyValueOperations = keyValueOperations; - this.queryCreator = queryCreator; - } - - /** - * Use {@link TarantoolPartTreeQuery} for resolving queries against Tarantool repositories. - * - * @param method, the query method - * @param metadata, not used - * @param projectionFactory, not used - * @param namedQueries, not used - * @return A mechanism for querying Tarantool repositories - */ - public RepositoryQuery resolveQuery( - Method method, - RepositoryMetadata metadata, - ProjectionFactory projectionFactory, - NamedQueries namedQueries) { - - TarantoolQueryMethodImpl queryMethod = - new TarantoolQueryMethodImpl(method, metadata, projectionFactory); - - if (queryMethod.hasAnnotatedQuery()) { - return new TarantoolRepositoryQuery(client, queryMethod); - } - - return new TarantoolPartTreeQuery( - queryMethod, evaluationContextProvider, this.keyValueOperations, this.queryCreator); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/TarantoolRepositoriesRegistrar.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/TarantoolRepositoriesRegistrar.java deleted file mode 100644 index 73656661..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/TarantoolRepositoriesRegistrar.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.repository.config; - -import java.lang.annotation.Annotation; - -import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport; -import org.springframework.data.repository.config.RepositoryConfigurationExtension; - -class TarantoolRepositoriesRegistrar extends RepositoryBeanDefinitionRegistrarSupport { - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoriesRegistrar#getAnnotation() - */ - @Override - protected Class getAnnotation() { - return EnableTarantoolRepositories.class; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport#getExtension() - */ - @Override - protected RepositoryConfigurationExtension getExtension() { - return new TarantoolRepositoryConfigurationExtension(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/TarantoolRepositoryConfigurationExtension.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/TarantoolRepositoryConfigurationExtension.java deleted file mode 100644 index ac26055a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/TarantoolRepositoryConfigurationExtension.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.repository.config; - -import org.springframework.beans.factory.config.ConstructorArgumentValues; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension; -import org.springframework.data.repository.config.RepositoryConfigurationSource; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.spring.data33.config.TarantoolCrudConfiguration; -import io.tarantool.spring.data33.core.TarantoolTemplate; -import io.tarantool.spring.data33.core.mapping.TarantoolMappingContext; - -public class TarantoolRepositoryConfigurationExtension - extends KeyValueRepositoryConfigurationExtension { - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getModuleName() - */ - @Override - public String getModuleName() { - return "Tarantool"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getModulePrefix() - */ - @Override - public String getModulePrefix() { - return "tarantool"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getDefaultKeyValueTemplateRef() - */ - @Override - public String getDefaultKeyValueTemplateRef() { - return DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #registerBeansForRoot() - */ - @Override - public void registerBeansForRoot( - BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) { - // register a default set of beans based on the passed annotation attributes. - final ClientType clientTypeAttribute = - configurationSource.getRequiredAttribute("clientType", ClientType.class); - - if (clientTypeAttribute == ClientType.CRUD) { - final String defaultCrudConfigurationBeanName = - TarantoolCrudConfiguration.class.getCanonicalName(); - registerIfNotAlreadyRegistered( - () -> new RootBeanDefinition(TarantoolCrudConfiguration.class), - registry, - defaultCrudConfigurationBeanName, - configurationSource); - } else { - throw new IllegalArgumentException("The Box client is not yet supported."); - } - super.registerBeansForRoot(registry, configurationSource); - - // remove KeyValueMappingContext to add TarantoolMappingContext - registry.removeBeanDefinition(getMappingContextBeanRef()); - registerIfNotAlreadyRegistered( - () -> { - RootBeanDefinition definition = new RootBeanDefinition(TarantoolMappingContext.class); - definition.setSource(configurationSource.getSource()); - - return definition; - }, - registry, - getMappingContextBeanRef(), - configurationSource); - } - - @Override - protected AbstractBeanDefinition getDefaultKeyValueTemplateBeanDefinition( - RepositoryConfigurationSource configurationSource) { - final RootBeanDefinition keyValueTemplateBeanDefinition = - new RootBeanDefinition(TarantoolTemplate.class); - - final ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); - constructorArgumentValues.addIndexedArgumentValue( - 0, new RuntimeBeanReference(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF)); - constructorArgumentValues.addIndexedArgumentValue( - 1, new RuntimeBeanReference(getMappingContextBeanRef())); - - keyValueTemplateBeanDefinition.setConstructorArgumentValues(constructorArgumentValues); - keyValueTemplateBeanDefinition.setSource(configurationSource); - keyValueTemplateBeanDefinition.setDependsOn(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF); - keyValueTemplateBeanDefinition.setDependsOn(getMappingContextBeanRef()); - - return keyValueTemplateBeanDefinition; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/package-info.java deleted file mode 100644 index 788bf57a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/config/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository config package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data33.repository.config; diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/package-info.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/package-info.java deleted file mode 100644 index 0bb1367c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data33.repository; diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/support/TarantoolRepositoryFactoryBean.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/support/TarantoolRepositoryFactoryBean.java deleted file mode 100644 index 398f5537..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/support/TarantoolRepositoryFactoryBean.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.repository.support; - -import java.io.Serializable; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean; -import org.springframework.data.repository.Repository; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data33.repository.TarantoolRepositoryFactory; - -public class TarantoolRepositoryFactoryBean, S, ID extends Serializable> - extends KeyValueRepositoryFactoryBean { - - @Autowired private TarantoolCrudClient client; - - public TarantoolRepositoryFactoryBean(Class repositoryInterface) { - super(repositoryInterface); - } - - /** - * Return a {@link TarantoolRepositoryFactory}. - * - *

{@code super} would return {@link KeyValueRepositoryFactory} which in turn builds {@code - * KeyValueRepository} instances, and these have a private method that implement querying in a - * manner that does not fit with Tarantool. More details are in {@link - * TarantoolRepositoryFactory}. - * - * @param operations operations - * @param queryCreator creator - * @param repositoryQueryType, not used - * @return A {@link TarantoolRepositoryFactory} that creates tarantool repository instances. - */ - @Override - protected KeyValueRepositoryFactory createRepositoryFactory( - KeyValueOperations operations, - Class> queryCreator, - Class repositoryQueryType) { - return new TarantoolRepositoryFactory(client, operations, queryCreator); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/support/TarantoolSimpleRepository.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/support/TarantoolSimpleRepository.java deleted file mode 100644 index aa54c70c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/support/TarantoolSimpleRepository.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.repository.support; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository; -import org.springframework.data.repository.core.EntityInformation; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data33.query.PaginationUtils.doPageQuery; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolSimpleRepository extends SimpleKeyValueRepository { - - private static final String FIND_ALL_EXC_MSG = - "This method is not supported to avoid sampling huge data massive. " - + "Please use derived methods with scrolling or pagination to select all data."; - - private static final String FIND_ALL_SORT_EXC_MSG = - "This method is not supported because sorting is not supported " - + "in Tarantool. Organize sorting of results using Java tools."; - - private static final String PAGEABLE_NULL_EXC_MSG = "Pageable must be not null"; - - private final KeyValueOperations operations; - private final EntityInformation entityInformation; - - /** - * Creates a new {@link SimpleKeyValueRepository} for the given {@link EntityInformation} and - * {@link KeyValueOperations}. - * - * @param metadata must not be {@literal null}. - * @param operations must not be {@literal null}. - */ - public TarantoolSimpleRepository( - EntityInformation metadata, KeyValueOperations operations) { - super(metadata, operations); - this.entityInformation = metadata; - this.operations = operations; - } - - @Override - public List findAll() { - throw new UnsupportedOperationException(FIND_ALL_EXC_MSG); - } - - @Override - public List findAll(Sort sort) { - throw new UnsupportedOperationException(FIND_ALL_SORT_EXC_MSG); - } - - @Override - @SuppressWarnings("unchecked") - public Page findAll(Pageable pageable) { - Assert.notNull(pageable, PAGEABLE_NULL_EXC_MSG); - - KeyValueQuery query = new KeyValueQuery<>(new TarantoolCriteria()); - return (Page) - doPageQuery(pageable, query, this.operations, this.entityInformation.getJavaType()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/support/package-info.java b/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/support/package-info.java deleted file mode 100644 index 5ba66be8..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/repository/support/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository support package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data33.repository.support; diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/GenericTarantoolConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/GenericTarantoolConfigurationTest.java deleted file mode 100644 index 5beebeb7..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/GenericTarantoolConfigurationTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.config; - -import java.io.IOException; -import java.nio.file.Files; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.test.context.TestPropertySource; - -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data33.config.properties.TarantoolProperties; -import io.tarantool.spring.data33.utils.TarantoolTestSupport; - -@TestPropertySource(properties = {Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -public abstract class GenericTarantoolConfigurationTest implements ApplicationContextAware { - - protected static TarantoolProperties testProperties; - - protected ApplicationContext applicationContext; - - @Autowired protected TarantoolProperties properties; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - @BeforeAll - static void beforeAll() throws IOException { - testProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists( - TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR.resolve( - Constants.DEFAULT_PROPERTY_FILE_NAME)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/TarantoolBoxConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/TarantoolBoxConfigurationTest.java deleted file mode 100644 index 205fcbcb..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/TarantoolBoxConfigurationTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.config; - -import java.io.IOException; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.RepeatedTest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; - -import io.tarantool.client.box.TarantoolBoxClient; -import io.tarantool.client.factory.TarantoolBoxClientBuilder; -import io.tarantool.pool.HeartbeatOpts; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data33.config.properties.TarantoolProperties; -import io.tarantool.spring.data33.utils.TarantoolTestSupport; - -@SpringBootTest(classes = {TarantoolBoxConfigurationTest.Config.class}) -public class TarantoolBoxConfigurationTest extends GenericTarantoolConfigurationTest { - - @MockBean TarantoolBoxClient client; - - @Autowired private TarantoolBoxConfiguration tarantoolBoxConfiguration; - - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testGetBoxClientBuilder() throws IOException { - assertEquals(properties, tarantoolBoxConfiguration.getProperties()); - - final TarantoolBoxClientBuilder boxClientBuilder = tarantoolBoxConfiguration.getClientBuilder(); - - if (properties.getConnectionGroups() == null) { - assertNull(boxClientBuilder.getGroups()); - } else { - Assertions.assertEquals( - properties.getConnectionGroups().size(), boxClientBuilder.getGroups().size()); - List connectionGroupsFromBuilder = boxClientBuilder.getGroups(); - List connectionGroupsFromProperty = - properties.getInstanceConnectionGroups(); - - assertNotNull(connectionGroupsFromBuilder); - assertNotNull(connectionGroupsFromProperty); - for (int i = 0; i < connectionGroupsFromBuilder.size(); i++) { - InstanceConnectionGroup groupFromBuilder = connectionGroupsFromBuilder.get(i); - InstanceConnectionGroup groupFromProperty = connectionGroupsFromProperty.get(i); - - assertEquals(groupFromProperty.getAuthType(), groupFromBuilder.getAuthType()); - assertEquals(groupFromProperty.getTag(), groupFromBuilder.getTag()); - assertEquals(groupFromProperty.getSize(), groupFromBuilder.getSize()); - assertEquals(groupFromProperty.getUser(), groupFromBuilder.getUser()); - assertEquals(groupFromProperty.getPassword(), groupFromBuilder.getPassword()); - assertEquals(groupFromProperty.getPort(), groupFromBuilder.getPort()); - assertEquals(groupFromProperty.getHost(), groupFromBuilder.getHost()); - } - } - - final HeartbeatOpts propertiesHeartbeatOpts = properties.getHeartbeatOpts(); - if (propertiesHeartbeatOpts == null) { - assertNull(boxClientBuilder.getHeartbeatOpts()); - } else { - HeartbeatOpts builderHeartbeatOpts = boxClientBuilder.getHeartbeatOpts(); - assertEquals( - propertiesHeartbeatOpts.getPingInterval(), builderHeartbeatOpts.getPingInterval()); - assertEquals( - propertiesHeartbeatOpts.getDeathThreshold(), builderHeartbeatOpts.getDeathThreshold()); - assertEquals( - propertiesHeartbeatOpts.getInvalidationThreshold(), - builderHeartbeatOpts.getInvalidationThreshold()); - assertEquals(propertiesHeartbeatOpts.getWindowSize(), builderHeartbeatOpts.getWindowSize()); - } - - Assertions.assertEquals(properties.getUserName(), boxClientBuilder.getUser()); - Assertions.assertEquals(properties.getPort(), boxClientBuilder.getPort()); - Assertions.assertEquals(properties.getEventLoopThreadsCount(), boxClientBuilder.getnThreads()); - Assertions.assertEquals(properties.getBalancerClass(), boxClientBuilder.getBalancerClass()); - Assertions.assertEquals( - properties.isGracefulShutdownEnabled(), boxClientBuilder.isGracefulShutdown()); - Assertions.assertEquals(properties.getConnectTimeout(), boxClientBuilder.getConnectTimeout()); - Assertions.assertEquals(properties.getReconnectAfter(), boxClientBuilder.getReconnectAfter()); - Assertions.assertEquals(properties.getHost(), boxClientBuilder.getHost()); - Assertions.assertEquals(properties.getPassword(), boxClientBuilder.getPassword()); - Assertions.assertEquals(properties.isFetchSchema(), boxClientBuilder.isFetchSchema()); - Assertions.assertEquals( - properties.isIgnoreOldSchemaVersion(), boxClientBuilder.isIgnoreOldSchemaVersion()); - - testProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @Configuration - @EnableConfigurationProperties(TarantoolProperties.class) - @Import(TarantoolBoxConfiguration.class) - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/TarantoolCrudConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/TarantoolCrudConfigurationTest.java deleted file mode 100644 index e71920df..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/TarantoolCrudConfigurationTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.config; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.test.annotation.DirtiesContext; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.pool.HeartbeatOpts; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyHeartbeatOpts; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.spring.data33.repository.config.EnableTarantoolRepositories; - -@SpringBootTest(classes = {TarantoolCrudConfigurationTest.Config.class}) -public class TarantoolCrudConfigurationTest extends GenericTarantoolConfigurationTest { - - @MockBean TarantoolCrudClient client; - - @Autowired private TarantoolCrudConfiguration tarantoolCrudConfiguration; - - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testGetCrudClientBuilder() throws IOException { - assertEquals(properties, tarantoolCrudConfiguration.getProperties()); - - final TarantoolCrudClientBuilder crudClientBuilder = - tarantoolCrudConfiguration.getClientBuilder(); - - if (properties.getConnectionGroups() == null) { - assertNull(crudClientBuilder.getGroups()); - } else { - assertEquals(properties.getConnectionGroups().size(), crudClientBuilder.getGroups().size()); - List connectionGroupsFromBuilder = crudClientBuilder.getGroups(); - List connectionGroupsFromProperty = - properties.getConnectionGroups(); - assertNotNull(connectionGroupsFromBuilder); - assertNotNull(connectionGroupsFromProperty); - for (int i = 0; i < connectionGroupsFromBuilder.size(); i++) { - InstanceConnectionGroup groupFromBuilder = connectionGroupsFromBuilder.get(i); - PropertyInstanceConnectionGroup groupFromProperty = connectionGroupsFromProperty.get(i); - - assertEquals(groupFromProperty.getAuthType(), groupFromBuilder.getAuthType()); - assertEquals(groupFromProperty.getTag(), groupFromBuilder.getTag()); - assertEquals(groupFromProperty.getConnectionGroupSize(), groupFromBuilder.getSize()); - assertEquals(groupFromProperty.getUserName(), groupFromBuilder.getUser()); - assertEquals(groupFromProperty.getPassword(), groupFromBuilder.getPassword()); - assertEquals(groupFromProperty.getPort(), groupFromBuilder.getPort()); - assertEquals(groupFromProperty.getHost(), groupFromBuilder.getHost()); - } - } - - final PropertyHeartbeatOpts propertiesHeartbeatOpts = properties.getHeartbeat(); - if (propertiesHeartbeatOpts == null) { - assertNull(crudClientBuilder.getHeartbeatOpts()); - } else { - HeartbeatOpts builderHeartbeatOpts = crudClientBuilder.getHeartbeatOpts(); - - assertEquals( - propertiesHeartbeatOpts.getPingInterval(), builderHeartbeatOpts.getPingInterval()); - assertEquals( - propertiesHeartbeatOpts.getDeathThreshold(), builderHeartbeatOpts.getDeathThreshold()); - assertEquals( - propertiesHeartbeatOpts.getInvalidationThreshold(), - builderHeartbeatOpts.getInvalidationThreshold()); - assertEquals(propertiesHeartbeatOpts.getWindowSize(), builderHeartbeatOpts.getWindowSize()); - } - - assertEquals(properties.getUserName(), crudClientBuilder.getUser()); - assertEquals(properties.getPort(), crudClientBuilder.getPort()); - assertEquals(properties.getEventLoopThreadsCount(), crudClientBuilder.getnThreads()); - assertEquals(properties.getBalancerClass(), crudClientBuilder.getBalancerClass()); - assertEquals(properties.isGracefulShutdownEnabled(), crudClientBuilder.isGracefulShutdown()); - assertEquals(properties.getConnectTimeout(), crudClientBuilder.getConnectTimeout()); - assertEquals(properties.getReconnectAfter(), crudClientBuilder.getReconnectAfter()); - assertEquals(properties.getHost(), crudClientBuilder.getHost()); - assertEquals(properties.getPassword(), crudClientBuilder.getPassword()); - - testProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @Test - void testKeyValueTemplate() { - final List beanDefinitions = Arrays.asList(applicationContext.getBeanDefinitionNames()); - assertTrue(beanDefinitions.contains(DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF)); - - final KeyValueTemplate keyValueTemplate = - applicationContext.getBean( - DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF, KeyValueTemplate.class); - assertNotNull(keyValueTemplate); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/TarantoolPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/TarantoolPropertiesTest.java deleted file mode 100644 index a57b6f07..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/TarantoolPropertiesTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.config; - -import java.io.IOException; -import java.nio.file.Files; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Timeout; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.TestPropertySource; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data33.config.properties.TarantoolProperties; -import io.tarantool.spring.data33.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data33.utils.TarantoolTestSupport; - -/** - * The test checks whether the Spring framework parses a file with the specified properties - * correctly. Before creating the test class, a random file with properties is written to the - * classpath:properties-test.yaml file. Next, when creating a test class the Spring context is - * raised and parses the file with properties. A test is launched to check the uniqueness of the - * current properties and properties that were specified in the previous iteration. It is checked - * that the generated Spring class TarantoolProperty is equal to the class written to the file. - * Next, the next entry to the file occurs, after which there is a forced reload of the Spring - * context -> the file with properties is parsed again and everything happens according to circle. - */ -@SpringBootTest(classes = {TarantoolPropertiesTest.Config.class}) -@TestPropertySource(properties = {Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -@Timeout(5) -public class TarantoolPropertiesTest { - - private static TarantoolProperties writtenToFileProperties; - private static TarantoolProperties prevSpringParsedProperties; - private static TarantoolProperties prevWrittenToFileProperties; - @Autowired private TarantoolProperties springParsedProperties; - - @MockBean private TarantoolCrudClient client; - - @BeforeAll - static void beforeAll() throws IOException { - writtenToFileProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists( - TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR.resolve( - Constants.DEFAULT_PROPERTY_FILE_NAME)); - } - - /** - * The annotation allows you to tell Spring that the context is dirty and needs to be reloaded - * after the test. - */ - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testParseProperty() throws IOException { - assertNotEquals(prevWrittenToFileProperties, writtenToFileProperties); - assertNotEquals(prevSpringParsedProperties, springParsedProperties); - assertEquals(writtenToFileProperties, springParsedProperties); - - prevWrittenToFileProperties = writtenToFileProperties; - prevSpringParsedProperties = springParsedProperties; - - // Write the Properties class that will be parsed by Spring in the next iteration. - writtenToFileProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/core/annotation/IdClassResolverTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/core/annotation/IdClassResolverTest.java deleted file mode 100644 index 2ed7de5a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/core/annotation/IdClassResolverTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.core.annotation; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import io.tarantool.spring.data33.utils.entity.ComplexPerson; -import io.tarantool.spring.data33.utils.entity.CompositePersonKey; -import io.tarantool.spring.data33.utils.entity.EntityWithAnnotationAsIdClass; -import io.tarantool.spring.data33.utils.entity.Person; - -@Timeout(5) -class IdClassResolverTest { - - public static final DefaultIdClassResolver ID_CLASS_RESOLVER = DefaultIdClassResolver.INSTANCE; - - @Test - void testResolveIdClassTypeWithNullEntity() { - - final IllegalArgumentException throwable = - assertThrows( - IllegalArgumentException.class, () -> ID_CLASS_RESOLVER.resolveIdClassType(null)); - final String EXCEPTION_MESSAGE = "Type for IdClass must be not null!"; - assertEquals(EXCEPTION_MESSAGE, throwable.getMessage()); - } - - @Test - void testResolveIdClassTypeWithEntityWithoutAnnotation() { - assertNull(ID_CLASS_RESOLVER.resolveIdClassType(Person.class)); - } - - @Test - void testResolveIdClassTypeWithEntityWithAnnotation() { - assertEquals( - ID_CLASS_RESOLVER.resolveIdClassType(ComplexPerson.class), CompositePersonKey.class); - } - - @Test - void testResolveIdClassTypeWithCrossAnnotation() { - final IllegalArgumentException throwable = - assertThrows( - IllegalArgumentException.class, - () -> ID_CLASS_RESOLVER.resolveIdClassType(EntityWithAnnotationAsIdClass.class)); - - assertEquals(DefaultIdClassResolver.ANNOTATION_TYPE_EXCEPTION, throwable.getMessage()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/core/mapping/KeyValueCompositePropertyTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/core/mapping/KeyValueCompositePropertyTest.java deleted file mode 100644 index 9fcf9759..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/core/mapping/KeyValueCompositePropertyTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.core.mapping; - -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.ReflectionUtils; - -public class KeyValueCompositePropertyTest

> { - - private @Nullable Identifier

identifier; - - @BeforeEach - public void setUp() { - this.identifier = null; - } - - /** Check methods for adding and retrieving parts of a composite key. */ - @Test - public void testAddAndGetParts() { - Class entityClass = TestEntity.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - - ReflectionUtils.FieldFilter isIdFieldFiler = field -> field.isAnnotationPresent(Id.class); - ReflectionUtils.doWithFields(entityClass, field -> addPart(field, owner), isIdFieldFiler); - - assertNotNull(identifier); - List identifierFieldsFromProperties = - this.identifier.getParts().stream() - .map(PersistentProperty::getField) - .collect(Collectors.toList()); - - compareFieldCollection(identifierFieldsFromProperties, getExpectedIdFields(entityClass)); - } - - /** Check methods for adding and retrieving parts of a composite key. */ - @Test - public void testAddAndGetFields() { - Class entityClass = TestEntity.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - - ReflectionUtils.FieldFilter isIdFieldFiler = field -> field.isAnnotationPresent(Id.class); - ReflectionUtils.doWithFields(entityClass, field -> addPart(field, owner), isIdFieldFiler); - - assertNotNull(identifier); - List fieldsFromIdentifier = Arrays.asList(identifier.getFields()); - - compareFieldCollection(fieldsFromIdentifier, getExpectedIdFields(entityClass)); - } - - /** - * Check methods for adding and getting parts of a composite key for an object without - * {@code @Id}. - */ - @Test - public void testAddAndGetPartsWithEntityWithoutId() { - Class entityClass = TestEntityWithoutId.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - ReflectionUtils.doWithFields( - entityClass, field -> addPart(field, owner), field -> field.isAnnotationPresent(Id.class)); - - assertNull(identifier); - } - - static class TestEntity { - - @Id private long id; - - @Id private int secondId; - } - - static class TestEntityWithoutId { - - private long id; - - @Nullable private String name; - - private int secondId; - } - - /** Create a PersistentProperty and add to first id property. */ - @SuppressWarnings("unchecked") - private void addPart(Field field, PersistentEntity owner) { - Property property = Property.of(owner.getTypeInformation(), field); - Identifier

persistentProperty = - new KeyValueCompositeProperty<>(property, owner, SimpleTypeHolder.DEFAULT); - - if (this.identifier == null) { - this.identifier = persistentProperty; - } - this.identifier.addPart((P) persistentProperty); - } - - /** Compare fields by name and type. */ - private void compareFieldCollection(List first, List second) { - assertEquals(first.size(), second.size()); - - first.sort(Comparator.comparing(Field::getName)); - second.sort(Comparator.comparing(Field::getName)); - - for (int i = 0; i < first.size(); i++) { - assertEquals(first.get(i).getName(), second.get(i).getName()); - assertEquals(first.get(i).getType(), second.get(i).getType()); - } - } - - /** Get the expected fields marked with the {@code @Id} annotation. */ - private List getExpectedIdFields(Class entityClass) { - return Arrays.stream(entityClass.getDeclaredFields()) - .filter(field -> field.isAnnotationPresent(Id.class)) - .collect(Collectors.toList()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/core/mapping/TarantoolMappingContextTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/core/mapping/TarantoolMappingContextTest.java deleted file mode 100644 index a794ed3a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/core/mapping/TarantoolMappingContextTest.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.core.mapping; - -import java.lang.reflect.Field; -import java.util.HashSet; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data33.core.mapping.BasicKeyValueCompositePersistentEntity.KeyPartTypeChecker; -import io.tarantool.spring.data33.utils.entity.ComplexPerson; -import io.tarantool.spring.data33.utils.entity.EntityWithWrongCompositeKeyPartsCount; -import io.tarantool.spring.data33.utils.entity.EntityWithWrongFieldTypes; -import io.tarantool.spring.data33.utils.entity.Person; - -class TarantoolMappingContextTest { - - @Test - void testSetFallbackKeySpaceResolver() throws NoSuchFieldException { - final KeySpaceResolver RESOLVER = TestResolver.INSTANCE; - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - mappingContext.setKeySpaceResolver(RESOLVER); - - final Field field = TarantoolMappingContext.class.getDeclaredField("keySpaceResolver"); - ReflectionUtils.makeAccessible(field); - - final Object resolverFieldValue = ReflectionUtils.getField(field, mappingContext); - - assertEquals(RESOLVER, resolverFieldValue); - } - - @Test - void testCreatePersistentEntity() { - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - final TypeInformation informationForSimpleClass = TypeInformation.of(Person.class); - - final TypeInformation informationForIdentifierClass = - TypeInformation.of(ComplexPerson.class); - - assertInstanceOf( - KeyValueCompositePersistentEntity.class, createEntityForClass(ComplexPerson.class)); - - assertInstanceOf(KeyValuePersistentEntity.class, createEntityForClass(ComplexPerson.class)); - } - - @Test - void testCreatePersistentProperty() { - ReflectionUtils.FieldFilter idFilter = field -> field.isAnnotationPresent(Id.class); - - PersistentProperty simpleIdProperty = createProperty(Person.class, idFilter); - assertInstanceOf(KeyValuePersistentProperty.class, simpleIdProperty); - - PersistentProperty compositeIdProperty = createProperty(ComplexPerson.class, idFilter); - assertInstanceOf(KeyValueCompositeProperty.class, compositeIdProperty); - } - - @Test - void testCreateEntityWithWrongCompositeKeyPartTypes() { - Set> initialSet = - new HashSet>() { - { - add(EntityWithWrongFieldTypes.class); - } - }; - IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> initEntities(initialSet)); - - Assertions.assertEquals( - KeyPartTypeChecker.COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION, exception.getMessage()); - } - - @Test - void testCreateEntityWithWrongCompositeKeyPartCount() { - Set> initialSet = - new HashSet>() { - { - add(EntityWithWrongCompositeKeyPartsCount.class); - } - }; - IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> initEntities(initialSet)); - - assertEquals(KeyPartTypeChecker.COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION, exception.getMessage()); - } - - /** - * Create a mappingContext from the passed domain classes. After initialize - create for them - * PersistentEntities and add PersistentProperties to them. - * - * @param entitySet - * @return - */ - private MappingContext initEntities(Set> entitySet) { - TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - mappingContext.setInitialEntitySet(entitySet); - mappingContext.initialize(); - return mappingContext; - } - - private enum TestResolver implements KeySpaceResolver { - INSTANCE; - - @Override - @Nullable - public String resolveKeySpace(Class type) { - - Assert.notNull(type, "Type for keyspace for null!"); - - Class userClass = ClassUtils.getUserClass(type); - Object keySpace = getKeySpace(userClass); - - return keySpace != null ? keySpace.toString() : null; - } - - @Nullable - private static Object getKeySpace(Class type) { - - KeySpace keyspace = AnnotatedElementUtils.findMergedAnnotation(type, KeySpace.class); - - if (keyspace != null) { - return AnnotationUtils.getValue(keyspace); - } - - return null; - } - } - - private PersistentEntity createEntityForClass(Class entityClass) { - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - final TypeInformation informationForClass = TypeInformation.of(entityClass); - return mappingContext.createPersistentEntity(informationForClass); - } - - private

> PersistentProperty createProperty( - Class classType, ReflectionUtils.FieldFilter fieldFilter) { - - final TarantoolMappingContext, P> context = - new TarantoolMappingContext<>(); - KeyValuePersistentEntity entity = - context.createPersistentEntity(TypeInformation.of(classType)); - Field field = org.springframework.data.util.ReflectionUtils.findField(classType, fieldFilter); - assertNotNull(field); - - return context.createPersistentProperty( - Property.of(entity.getTypeInformation(), field), entity, SimpleTypeHolder.DEFAULT); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java deleted file mode 100644 index 9bbb632d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.core.mapping.model; - -import java.lang.reflect.Field; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.Test; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data33.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data33.core.mapping.BasicKeyValueCompositePersistentEntity; -import io.tarantool.spring.data33.core.mapping.KeyValueCompositeProperty; -import io.tarantool.spring.data33.utils.entity.ComplexPerson; - -public class PersistentCompositeIdIsNewStrategyTest

> { - - /** Check the strategy creation method and check whether the domain entity is new. */ - @Test - public void testForIdOnly() { - - // Currently identical like of 'of' method (version doesn't support) - PersistentCompositeIdIsNewStrategy strategy = - PersistentCompositeIdIsNewStrategy.forIdOnly(createPersistentEntity(ComplexPerson.class)); - - // Now is stub - always is false - ComplexPerson emptyEntity = new ComplexPerson(); - assertFalse(strategy.isNew(emptyEntity)); - } - - /** Check the strategy creation method and check whether the domain entity is new. */ - @Test - public void testIsNew() { - PersistentCompositeIdIsNewStrategy strategy = - PersistentCompositeIdIsNewStrategy.of(createPersistentEntity(ComplexPerson.class)); - - // Now is stub - always is false - ComplexPerson emptyEntity = new ComplexPerson(); - assertFalse(strategy.isNew(emptyEntity)); - } - - private BasicKeyValueCompositePersistentEntity createPersistentEntity(Class entityType) { - Class compositeKeyType = DefaultIdClassResolver.INSTANCE.resolveIdClassType(entityType); - assertNotNull(compositeKeyType); - - BasicKeyValueCompositePersistentEntity persistentEntity = - new BasicKeyValueCompositePersistentEntity<>( - TypeInformation.of(entityType), null, compositeKeyType); - ReflectionUtils.doWithFields(entityType, field -> addProperty(field, persistentEntity)); - return persistentEntity; - } - - /** Add Persistent property into PersistentEntity. */ - @SuppressWarnings("unchecked") - private void addProperty(Field field, BasicKeyValueCompositePersistentEntity owner) { - Property property = Property.of(owner.getTypeInformation(), field); - P persistentProperty = - (P) new KeyValueCompositeProperty<>(property, owner, SimpleTypeHolder.DEFAULT); - owner.addPersistentProperty(persistentProperty); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/BaseIntegrationTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/BaseIntegrationTest.java deleted file mode 100644 index b9d60d84..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/BaseIntegrationTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.integration; - -import java.io.IOException; -import java.nio.file.Files; -import java.time.Duration; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Timeout; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.cluster.ClusterContainer; -import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer; -import org.testcontainers.containers.cluster.vshard.VshardClusterContainer; -import org.testcontainers.containers.output.Slf4jLogConsumer; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.spring.data33.config.properties.TarantoolProperties; - -@Timeout(60) -public abstract class BaseIntegrationTest { - - protected static ClusterContainer clusterContainer; - - private static final String dockerRegistry = - System.getenv().getOrDefault("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", ""); - - @BeforeAll - protected static void beforeAll() throws IOException { - configureContainer(); - writeConfigurationFile(); - } - - private static void configureContainer() { - if (!isCartridgeAvailable()) { - VshardClusterContainer vshardClusterContainer = - new VshardClusterContainer( - "vshard_cluster/Dockerfile", - dockerRegistry + "vshard-cluster-java", - "vshard_cluster/instances.yaml", - "vshard_cluster/config.yaml", - "tarantool/tarantool"); - - if (!vshardClusterContainer.isRunning()) { - vshardClusterContainer.withPrivilegedMode(true); - vshardClusterContainer.start(); - } - clusterContainer = vshardClusterContainer; - } else { - CartridgeClusterContainer cartridgeContainer = - new CartridgeClusterContainer( - "cartridge/Dockerfile", - dockerRegistry + "cartridge", - "cartridge/instances.yml", - "cartridge/replicasets.yml", - org.testcontainers.containers.Arguments.get("tarantool/tarantool")) - .withStartupTimeout(Duration.ofMinutes(5)) - .withLogConsumer( - new Slf4jLogConsumer(LoggerFactory.getLogger(BaseIntegrationTest.class))); - - if (!cartridgeContainer.isRunning()) { - cartridgeContainer.start(); - } - clusterContainer = cartridgeContainer; - } - } - - private static void writeConfigurationFile() throws IOException { - final TarantoolProperties properties = new TarantoolProperties(); - properties.setHost(clusterContainer.getHost()); - properties.setPort(clusterContainer.getPort()); - properties.setUserName(clusterContainer.getUsername()); - properties.setPassword(clusterContainer.getPassword()); - - writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME, properties); - } - - @AfterAll - protected static void afterAll() throws IOException { - Files.deleteIfExists(DEFAULT_TEST_PROPERTY_DIR.resolve(DEFAULT_PROPERTY_FILE_NAME)); - } - - protected static String getHost() { - return clusterContainer.getHost(); - } - - protected static int getPort() { - return clusterContainer.getPort(); - } - - protected static String getUsername() { - return clusterContainer.getUsername(); - } - - protected static String getPassword() { - return clusterContainer.getPassword(); - } - - protected static boolean isCartridgeAvailable() { - return System.getenv().getOrDefault("TARANTOOL_VERSION", "").matches("2.*"); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/CrudConfigurations.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/CrudConfigurations.java deleted file mode 100644 index 5eaa55f3..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/CrudConfigurations.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.integration.crud; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.TestPropertySource; - -import static io.tarantool.client.TarantoolClient.DEFAULT_TAG; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.PERSON_SPACE; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data33.integration.BaseIntegrationTest; -import io.tarantool.spring.data33.repository.config.EnableTarantoolRepositories; - -@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -abstract class CrudConfigurations extends BaseIntegrationTest { - - @Autowired protected TarantoolCrudClient client; - - private static InstanceConnectionGroup groupFromJavaConfig; - - private static final String PACKAGE_PATH = "io.tarantool.spring.data33.utils.core"; - - @BeforeAll - protected static void beforeAll() throws IOException { - BaseIntegrationTest.beforeAll(); - groupFromJavaConfig = - InstanceConnectionGroup.builder() - .withHost(clusterContainer.getHost()) - .withPort(clusterContainer.getPort()) - .withUser(getUsername()) - .withPassword(getPassword()) - .withTag(DEFAULT_TAG) - .withSize(4) - .build(); - } - - @BeforeEach - public void truncateSpaces() { - client.space(PERSON_SPACE).truncate().join(); - client.space(COMPLEX_PERSON_SPACE).truncate().join(); - } - - @EnableTarantoolRepositories(basePackages = {PACKAGE_PATH}) - @Configuration - static class JavaConfigConfiguration { - - @Bean - TarantoolCrudClientBuilder crudClientBuilder() { - return TarantoolFactory.crud().withGroups(Collections.singletonList(groupFromJavaConfig)); - } - } - - @EnableTarantoolRepositories(basePackages = {PACKAGE_PATH}) - @Configuration - static class ViaPropertyFileConfiguration {} - - @Test - void testSimpleClient() { - TarantoolCrudSpace space = client.space(PERSON_SPACE); - - assertEquals(0, space.select().join().size()); - - List tuple = Arrays.asList(0, true, "petya"); - List insertTuple = space.insert(tuple).join().get(); - - assertEquals(tuple, insertTuple.subList(0, insertTuple.size() - 1)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/GenericRepositoryTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/GenericRepositoryTest.java deleted file mode 100644 index 8d26731a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/GenericRepositoryTest.java +++ /dev/null @@ -1,2080 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.integration.crud; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Limit; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.util.Streamable; - -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data33.query.TarantoolQueryCreator.INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.UNKNOWN_PERSON; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.generateAndInsertPersons; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.mapping.Tuple; -import io.tarantool.spring.data.query.Conditions; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data.utils.Pair; -import io.tarantool.spring.data33.query.TarantoolPageRequest; -import io.tarantool.spring.data33.query.TarantoolScrollPosition; -import io.tarantool.spring.data33.query.TarantoolWindowIterator; -import io.tarantool.spring.data33.utils.TarantoolTestSupport; -import io.tarantool.spring.data33.utils.core.ComplexPersonRepository; -import io.tarantool.spring.data33.utils.core.GenericPaginationMethods; -import io.tarantool.spring.data33.utils.core.PersonRepository; -import io.tarantool.spring.data33.utils.entity.ComplexPerson; -import io.tarantool.spring.data33.utils.entity.Person; - -abstract class GenericRepositoryTest extends CrudConfigurations { - - @Autowired protected ApplicationContext context; - - protected static BiFunction> - complexPersonGenerateAndInsertFunction = - (context, personCount) -> - generateAndInsertComplexPersons( - personCount, context.getBean(TarantoolCrudClient.class)); - - protected static BiFunction> - personGenerateAndInsertFunction = - (context, personCount) -> - generateAndInsertPersons(personCount, context.getBean(TarantoolCrudClient.class)); - - protected static Function> complexPersonGenerateFunction = - TarantoolTestSupport::generateComplexPersons; - - protected static Function> personGenerateFunction = - TarantoolTestSupport::generatePersons; - - protected static final int INDEX_ID_VALUE = 50; - - protected static final Pair PERSON_INDEX_KEY = Pair.of("pk", INDEX_ID_VALUE); - - protected static final Pair PERSON_INITIAL_INDEX_KEY = - Pair.of("pk", Collections.emptyList()); - - protected static Stream dataForTestRepositoryWithFindByIs() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByIs") - , ID> void testRepositoryWithFindByIs( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - List foundPersons = repository.findByName(person.getName()); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(1, foundPersons.size()); - assertEquals(person, foundPersons.get(0)); - } - - protected static Stream dataForTestRepositoryWithFindById() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindById") - , ID> void testRepositoryWithFindById( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - Optional foundPerson = repository.findById(person.generateFullKey()); - - assertTrue(foundPerson.isPresent()); - assertEquals(person, foundPerson.get()); - } - - protected static Stream dataForTestRepositoryWithFindAllById() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllById") - , ID> void testRepositoryWithFindAllById( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - Iterable foundPersons = - repository.findAllById( - persons.stream().map(PERSON::generateFullKey).collect(Collectors.toList())); - List foundPersonsAsList = - StreamSupport.stream(foundPersons.spliterator(), false) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(persons, foundPersonsAsList); - } - - protected static Stream dataForTestRepositoryWithCount() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithCount") - , ID> void testRepositoryWithCount( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - assertEquals(PERSONS_COUNT, context.getBean(repositoryClass).count()); - } - - protected static Stream dataForTestRepositoryWithCountBy() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithCountBy") - , ID> void testRepositoryWithCountBy( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - assertEquals(1, repository.countByName(person.getName())); - } - - protected static Stream dataForTestRepositoryWithDelete() { - return Stream.of( - Arguments.of( - personGenerateFunction, - PersonRepository.class, - PERSON_SPACE, - (BiFunction>) - (space, key) -> { - Tuple tuple = - space.get(Collections.singletonList(key), Person.class).join(); - if (tuple != null) { - return tuple.get(); - } - return null; - }), - Arguments.of( - complexPersonGenerateFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (BiFunction>) - (space, key) -> { - Tuple tuple = space.get(key, ComplexPerson.class).join(); - if (tuple != null) { - return tuple.get(); - } - return null; - })); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithDelete") - , ID> void testRepositoryWithDelete( - Function> generateFunction, - Class> repositoryClass, - String spaceName, - BiFunction spaceGetFunction) { - - final List persons = generateFunction.apply(PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - space.insertMany(persons).join(); - - final PERSON deletingPerson = persons.get(0); - - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - // by object - repository.delete(deletingPerson); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - space.insert(deletingPerson).join(); - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - // by id - repository.deleteById(deletingPerson.generateFullKey()); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - space.insert(deletingPerson).join(); - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - // by name - repository.deleteByName(deletingPerson.getName()); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - } - - protected static Stream dataForTestRepositoryWithExistId() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiConsumer) - (space, key) -> space.delete(Collections.singletonList(key)).join(), - PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - (BiConsumer) (space, key) -> space.delete(key).join(), - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithExistId") - , ID> void testRepositoryWithExistId( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - BiConsumer deleteConsumer, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final PERSON person = persons.get(0); - - assertTrue(repository.existsById(person.generateFullKey())); - deleteConsumer.accept(space, person.generateFullKey()); - assertFalse(repository.existsById(person.generateFullKey())); - } - - protected static Stream dataForTestQueryAnnotationAsCall() { - return Stream.of( - Arguments.of(PersonRepository.class), Arguments.of(ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsCall") - , ID> void testQueryAnnotationAsCall( - Class> repositoryClass) { - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - assertEquals(Arrays.asList(1, "hi", false), repository.getStatic().get()); - } - - protected static Stream dataForTestQueryAnnotationAsCallWithArgs() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsCallWithArgs") - , ID> void testQueryAnnotationAsCallWithArgs( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals(Arrays.asList("hello", true, 13), repository.echo("hello", true, 13).get()); - } - - protected static Stream dataForTestQueryAnnotationAsEval() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsEval") - , ID> void testQueryAnnotationAsEval( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals(Arrays.asList("hello", 123, true), repository.evalGetStatic().get()); - } - - protected static Stream dataForTestQueryAnnotationAsEvalWithArgs() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsEvalWithArgs") - , ID> void testQueryAnnotationAsEvalWithArgs( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals( - Arrays.asList("hello", true, 13), repository.evalWithArgs("hello", true, 13).get()); - } - - protected static Stream dataForTestRepositoryWithExistName() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiConsumer) - (space, key) -> space.delete(Collections.singletonList(key)).join(), - PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - (BiConsumer) (space, key) -> space.delete(key).join(), - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithExistName") - , ID> void testRepositoryWithExistName( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - BiConsumer deleteConsumer, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final PERSON person = persons.get(0); - - assertTrue(repository.existsByName(person.getName())); - deleteConsumer.accept(space, person.generateFullKey()); - assertFalse(repository.existsByName(person.getName())); - } - - protected static Stream dataForTestRepositoryWithFindByLessThan() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByLessThan") - , ID> void testRepositoryWithFindByLessThan( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 10; - final List foundPersons = repository.findAllByIdIsLessThan(findLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(findLimiter, foundPersons.size()); - assertEquals(persons.subList(0, findLimiter), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsTrue() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsTrue") - , ID> void testRepositoryWithFindAllByIsMarriedIsTrue( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsTrue(); - assertEquals(PERSONS_COUNT / 3, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(GenericPerson::getIsMarried)); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsFalse() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsFalse") - , ID> void testRepositoryWithFindAllByIsMarriedIsFalse( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsFalse(); - assertEquals(PERSONS_COUNT / 3, foundPersons.size()); - assertTrue(foundPersons.stream().noneMatch(GenericPerson::getIsMarried)); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsNull() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsNull") - , ID> void testRepositoryWithFindAllByIsMarriedIsNull( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsNull(); - assertEquals(PERSONS_COUNT / 3 + 1, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(p -> p.getIsMarried() == null)); - } - - protected static Stream dataForTestRepositoryWithFindAllByNameIsEmpty() { - return Stream.of( - Arguments.of(personGenerateFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByNameIsEmpty") - , ID> void testRepositoryWithFindAllByNameIsEmpty( - Function> generateFunction, - Class> repositoryClass) { - - List persons = generateFunction.apply(PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - PERSON person = persons.get(0); - person.setName(""); - persons.set(0, person); - - repository.saveAll(persons); - - final List foundPersons = repository.findAllByNameIsEmpty(); - assertEquals(1, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(p -> p.getName().isEmpty())); - } - - protected static Stream dataForTestRepositoryWithFindByLessThanEqual() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByLessThanEqual") - , ID> void testRepositoryWithFindByLessThanEqual( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 10; - final List foundPersonsWithEqual = repository.findAllByIdLessThanEqual(findLimiter); - - foundPersonsWithEqual.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(findLimiter + 1, foundPersonsWithEqual.size()); - assertEquals(persons.subList(0, findLimiter + 1), foundPersonsWithEqual); - } - - protected static Stream dataForTestRepositoryWithFindByGreaterThan() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByGreaterThan") - , ID> void testRepositoryWithFindByGreaterThan( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 90; - final List foundPersons = repository.findAllByIdIsGreaterThan(findLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(PERSONS_COUNT - findLimiter - 1, foundPersons.size()); - assertEquals(persons.subList(findLimiter + 1, PERSONS_COUNT), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindByGreaterThanEqual() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByGreaterThanEqual") - , ID> void testRepositoryWithFindByGreaterThanEqual( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 90; - final List foundPersonsWithEqual = repository.findAllByIdGreaterThanEqual(findLimiter); - - foundPersonsWithEqual.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(PERSONS_COUNT - findLimiter, foundPersonsWithEqual.size()); - assertEquals(persons.subList(findLimiter, PERSONS_COUNT), foundPersonsWithEqual); - } - - protected static Stream dataForTestRepositoryWithFindByBetween() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByBetween") - , ID> void testRepositoryWithFindByBetween( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int startFindLimiter = 50; - final int endFindLimiter = 90; - final List foundPersons = - repository.findAllByIdBetween(startFindLimiter, endFindLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - final int foundPersonsCount = endFindLimiter - startFindLimiter - 1; - assertEquals(foundPersonsCount, foundPersons.size()); - assertEquals(persons.subList(startFindLimiter + 1, endFindLimiter), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindByBetweenNegativeInts() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByBetweenNegativeInts") - , ID> void testRepositoryWithFindByBetweenNegativeInts( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int startFindLimiter = -1; - final int endFindLimiter = -10; - final List foundPersons = - repository.findAllByIdBetween(startFindLimiter, endFindLimiter); - assertTrue(foundPersons.isEmpty()); - } - - protected static Stream dataForTestRepositoryIgnoreCase() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryIgnoreCase") - , ID> void testRepositoryIgnoreCase( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - final String name = persons.get(0).getName(); - - final InvalidDataAccessApiUsageException exception = - assertThrows( - InvalidDataAccessApiUsageException.class, () -> repository.findByNameIgnoreCase(name)); - final String EXCEPTION_MESSAGE = - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "IgnoreCase isn't supported yet", - Part.Type.SIMPLE_PROPERTY); - assertEquals(EXCEPTION_MESSAGE, exception.getMessage()); - } - - protected static Stream dataForTestRepositoryWithTarantoolNamingNotation() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithTarantoolNamingNotation") - , ID> void testRepositoryWithTarantoolNamingNotation( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List marriedPersons = repository.findByIsMarried(true); - final List nonMarriedPersons = repository.findByIsMarried(false); - final int expectedCount = PERSONS_COUNT / 3; - assertEquals(expectedCount, marriedPersons.size()); - assertEquals(expectedCount, nonMarriedPersons.size()); - } - - protected static Stream dataForTestRepositoryNotEnoughArguments() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryNotEnoughArguments") - , ID> void testRepositoryNotEnoughArguments( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertThrows(InvalidDataAccessApiUsageException.class, repository::findById); - } - - protected static Stream dataForTestRepositorySave() { - return dataForTestRepositoryWithDelete(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySave") - , ID> void testRepositorySave( - Function> generateFunction, - Class> repositoryClass, - String spaceName, - BiFunction getFunction) { - - List persons = generateFunction.apply(PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - TarantoolCrudSpace space = client.space(spaceName); - final PERSON person = persons.get(0); - - repository.save(person); - - PERSON gotPerson = getFunction.apply(space, person.generateFullKey()); - assertEquals(person, gotPerson); - } - - protected static Stream dataForTestRepositorySaveAll() { - Conditions conditions = new Conditions(); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - PERSON_SPACE, - (Function>) - (space) -> unwrapTuples(space.select(conditions, Person.class).join())), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (Function>) - (space) -> unwrapTuples(space.select(conditions, ComplexPerson.class).join()))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySaveAll") - , ID> void testRepositorySaveAll( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - Function> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - repository.saveAll(persons); - - List selectedPersons = selectFunction.apply(space); - selectedPersons.sort(Comparator.comparing(GenericPerson::getId)); - - assertEquals(persons, selectedPersons); - } - - protected static Stream dataForTestDeleteAll() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class, PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteAll") - , ID> void testDeleteAll( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow(() -> repository.deleteAll()); - assertEquals(0, space.count(new Conditions()).join()); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow(() -> repository.deleteAll(persons)); - assertEquals(0, space.count(new Conditions()).join()); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow( - () -> - repository.deleteAllById( - persons.stream().map(PERSON::generateFullKey).collect(Collectors.toList()))); - assertEquals(0, space.count(new Conditions()).join()); - } - - protected static Stream dataForTestRepositoryFindByAfter() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByAfter") - , ID> void testRepositoryFindByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - final List selectedPersons = repository.findByNameAfter(person.getName()); - selectedPersons.sort(Comparator.comparing(PERSON::getName)); - - final List expectedList = - persons.stream() - .filter(p -> p.getName().compareTo(person.getName()) > 0) - .limit(SelectOptions.DEFAULT_LIMIT) - .sorted(Comparator.comparing(PERSON::getName)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - } - - protected static Stream dataForTestRepositoryFindByAfterWithLimit() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByAfterWithLimit") - , ID> void testRepositoryFindByAfterWithLimit( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int LIMIT = 5; - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findFirst5ByIdAfter(person.getId()); - selectedPersons.sort(Comparator.comparing(PERSON::getId)); - - final List selectedPersonsWithTopKeyword = repository.findTop5ByIdAfter(person.getId()); - selectedPersonsWithTopKeyword.sort(Comparator.comparing(PERSON::getId)); - - final List expectedList = - persons.stream() - .filter(p -> p.getId().compareTo(person.getId()) > 0) - .limit(LIMIT) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - - assertEquals(expectedList.size(), selectedPersonsWithTopKeyword.size()); - assertEquals(expectedList, selectedPersonsWithTopKeyword); - } - - protected static Stream dataForTestRepositoryFindByBefore() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByBefore") - , ID> void testRepositoryFindByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findByNameBefore(person.getName()); - selectedPersons.sort(Comparator.comparing(PERSON::getName)); - - final List expectedList = - persons.stream() - .filter(p -> p.getName().compareTo(person.getName()) < 0) - .limit(SelectOptions.DEFAULT_LIMIT) - .sorted(Comparator.comparing(PERSON::getName)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - } - - protected static Stream dataForTestRepositoryFindByBeforeWithLimit() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByBeforeWithLimit") - , ID> void testRepositoryFindByBeforeWithLimit( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int LIMIT = 5; - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findFirst5ByIdBefore(person.getId()); - selectedPersons.sort(Comparator.comparing(PERSON::getId)); - - final List selectedPersonsWithTopKeyword = - repository.findTop5ByIdBefore(person.getId()); - selectedPersonsWithTopKeyword.sort(Comparator.comparing(PERSON::getId)); - - // Because id (not fullscan) - persons.sort(Comparator.comparing(PERSON::getId, (o1, o2) -> Integer.compare(o2, o1))); - - final List expectedList = - persons.stream() - .filter(p -> p.getId().compareTo(person.getId()) < 0) - .limit(LIMIT) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - - assertEquals(expectedList.size(), selectedPersonsWithTopKeyword.size()); - assertEquals(expectedList, selectedPersonsWithTopKeyword); - } - - protected static Stream dataForTestDeleteByAfter() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - PERSON_SPACE, - (BiFunction>) - (space, options) -> - unwrapTuples( - space.select(Collections.emptyList(), options, Person.class).join())), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (BiFunction>) - (space, options) -> - unwrapTuples( - space - .select(Collections.emptyList(), options, ComplexPerson.class) - .join()))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteByAfter") - , ID> void testDeleteByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - BiFunction> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - persons.sort(Comparator.comparing(PERSON::getName)); - - final int RANDOM_INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final SelectOptions options = SelectOptions.builder().withFirst(PERSONS_COUNT).build(); - final PERSON deletingAfterPerson = persons.get(RANDOM_INDEX); - - final List deletedPersons = repository.deleteByNameAfter(deletingAfterPerson.getName()); - - List allPersonsInBaseAfterDeleted = selectFunction.apply(space, options); - assertEquals(PERSONS_COUNT - deletedPersons.size(), allPersonsInBaseAfterDeleted.size()); - - persons.removeAll(deletedPersons); - allPersonsInBaseAfterDeleted.sort(Comparator.comparing(PERSON::getId)); - persons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(persons, allPersonsInBaseAfterDeleted); - } - - protected static Stream dataForTestDeleteByBefore() { - return dataForTestDeleteByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteByBefore") - , ID> void testDeleteByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - BiFunction> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final SelectOptions options = SelectOptions.builder().withFirst(PERSONS_COUNT).build(); - final int RANDOM_INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - - final PERSON deletingBeforePerson = persons.get(RANDOM_INDEX); - final List deletedPersons = - repository.deleteByNameBefore(deletingBeforePerson.getName()); - - List allPersonsInBaseAfterDeleted = selectFunction.apply(space, options); - - assertEquals(PERSONS_COUNT - deletedPersons.size(), allPersonsInBaseAfterDeleted.size()); - - persons.removeAll(deletedPersons); - allPersonsInBaseAfterDeleted.sort(Comparator.comparing(PERSON::getId)); - persons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(persons, allPersonsInBaseAfterDeleted); - } - - protected static Stream dataForTestCountByAfter() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestCountByAfter") - , ID> void testCountByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final int ID_AFTER = persons.get(INDEX).getId(); - - final long count = repository.countByIdAfter(ID_AFTER); - - final int EXPECTED_COUNT = PERSONS_COUNT - ID_AFTER - 1; - assertEquals(EXPECTED_COUNT, count); - } - - protected static Stream dataForTestCountByBefore() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestCountByBefore") - , ID> void testCountByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - persons.sort(Comparator.comparing(PERSON::getName)); - - final int indexBefore = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final String name = persons.get(indexBefore).getName(); - final long count = repository.countByNameBefore(name); - - assertEquals(indexBefore, count); - - final long unknownNameCount = repository.countByNameBefore(UNKNOWN_PERSON.getName()); - assertEquals(0, unknownNameCount); - } - - protected static < - REPO extends GenericPaginationMethods, PERSON extends GenericPerson, ID> - Stream dataForTestRepositorySlicePagePageableEqual() { - final int PAGE_SIZE = ThreadLocalRandom.current().nextInt(1, PERSONS_COUNT / 3 - 1); - final String NAME = "name"; - final Pageable beginPageable = new TarantoolPageRequest>(PAGE_SIZE); - - BiFunction> generatePersonAndInsertFunction = - (context, size) -> - generateAndInsertPersons( - size, context.getBean(TarantoolCrudClient.class), (person) -> person.setName(NAME)); - - BiFunction> - generateComplexPersonAndInsertFunction = - (context, size) -> - generateAndInsertComplexPersons( - size, - context.getBean(TarantoolCrudClient.class), - (person) -> person.setName(NAME)); - - Function personRepositoryFunc = - (context) -> context.getBean(PersonRepository.class); - - Function complexPersonRepositoryFunc = - (context) -> context.getBean(ComplexPersonRepository.class); - - BiFunction> executionForFindAllByName = - (repo, pageable) -> repo.findAllByName(NAME, pageable); - - Function, List> expectedListForFindAllByNameFunc = - (persons) -> - persons.stream() - .filter(person -> NAME.equals(person.getName())) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()) - .subList(0, PAGE_SIZE); - - BiFunction> executionForFindByName = - (repo, pageable) -> repo.findPersonByName(NAME, pageable); - - List> generateFunctionPairs = - Arrays.asList( - Arrays.asList(generatePersonAndInsertFunction, personRepositoryFunc), - Arrays.asList(generateComplexPersonAndInsertFunction, complexPersonRepositoryFunc)); - - List executionFunctions = Arrays.asList(executionForFindAllByName, executionForFindByName); - - // add arguments set - List arguments = new ArrayList<>(); - for (List generateFunctionPair : generateFunctionPairs) { - for (Object executionFunction : executionFunctions) { - arguments.add( - Arguments.of( - generateFunctionPair.get(0), - executionFunction, - generateFunctionPair.get(1), - expectedListForFindAllByNameFunc, - beginPageable)); - } - } - - return arguments.stream(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySlicePagePageableEqual") - , PERSON extends GenericPerson, ID> - void testRepositorySlicePagePageableEqual( - BiFunction> generateAndInsertFunction, - BiFunction> executingRepositoryMethod, - Function giveRepositoryFunction, - Function, List> expectedSlicePageContent, - Pageable beginPageable) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - Slice slicePage = - executingRepositoryMethod.apply(giveRepositoryFunction.apply(context), beginPageable); - - assertEquals(beginPageable, slicePage.getPageable()); - assertEquals(expectedSlicePageContent.apply(persons), slicePage.getContent()); - } - - protected static Stream dataForTestRepositorySliceMethodWithoutPageable() { - final String NAME = "name"; - return Stream.of( - Arguments.of(PersonRepository.class, NAME), - Arguments.of(ComplexPersonRepository.class, NAME)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySliceMethodWithoutPageable") - , ID> void testRepositorySliceMethodWithoutPageable( - Class> repositoryClass, String name) { - GenericPaginationMethods repository = context.getBean(repositoryClass); - - assertEquals(Pageable.unpaged(), repository.findAllByName(name).getPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).nextPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).nextOrLastPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).previousPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).previousOrFirstPageable()); - } - - @SuppressWarnings("unchecked") - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Stream dataForTestRepositorySliceWithDifferentFields() { - final int PAGE_SIZE = 10; - - Function, Pageable> nextPageableFunc = Slice::nextPageable; - Function, Pageable> prevPageableFunc = Slice::previousPageable; - Function, Pageable> nextOrLastPageableFunc = Slice::nextOrLastPageable; - Function, Pageable> prevOrFirstPageableFunc = Slice::previousOrFirstPageable; - BiFunction predicateForNextPageableFunc = - (currentPageable, nextPageable) -> nextPageable.isPaged(); - - BiFunction predicateForNextOrPageableFunc = - (currentPageable, nextPageable) -> !currentPageable.equals(nextPageable); - - Function personRepositoryFunc = - (context) -> context.getBean(PersonRepository.class); - - Function complexPersonRepositoryFunc = - (context) -> context.getBean(ComplexPersonRepository.class); - - Pageable beginPageable = new TarantoolPageRequest<>(PAGE_SIZE); - - BiFunction, Integer, Integer> idExtractionFunction = - (args, index) -> { - List persons = (List) args.get(0); - return persons.get(index).getId(); - }; - - BiFunction, Integer, String> nameExtractionFunction = - (args, index) -> { - List persons = (List) args.get(0); - return persons.get(index).getName(); - }; - - BiFunction, Slice> executionForFindAllByIdLessThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, PERSONS_COUNT - 1); - return repo.findAllByIdLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByIdLessThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, PERSONS_COUNT - 1); - return repo.findPersonByIdLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByIdGreaterThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, 0); - return repo.findAllByIdGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByIdGreaterThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, 0); - return repo.findPersonByIdGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByIsMarriedLessThanEqual = - (repo, arguments) -> - repo.findAllByIsMarriedLessThanEqual(false, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindPersonByIsMarriedLessThanEqual = - (repo, arguments) -> - repo.findPersonByIsMarriedLessThanEqual(false, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindAllByIsMarriedGreaterThanEqual = - (repo, arguments) -> - repo.findAllByIsMarriedGreaterThanEqual(null, (Pageable) arguments.get(1)); - - BiFunction, Slice> - executionForFindPersonByIsMarriedGreaterThanEqual = - (repo, arguments) -> - repo.findPersonByIsMarriedGreaterThanEqual(null, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindAllByNameLessThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findAllByNameLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByNameLessThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findPersonByNameLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByNameGreaterThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findAllByNameGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByNameGreaterThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findPersonByNameGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAll = - (repo, arguments) -> repo.findAll((Pageable) arguments.get(1)); - - Function, List> expectedListForFindAllByIdLessThanEqualFunc = - (persons) -> - persons.stream() - .sorted(Comparator.comparing(PERSON::getId).reversed()) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByIdGreaterThanEqualFunc = - (persons) -> persons; - - Function, List> expectedListForFindAllByIsMarriedGreaterThanEqual = - (persons) -> - persons.stream() - .sorted( - Comparator.comparing( - PERSON::getIsMarried, Comparator.nullsFirst(Comparator.naturalOrder()))) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByIsMarriedLessThanEqual = - (persons) -> - persons.stream() - .filter(person -> person.getIsMarried() == null || !person.getIsMarried()) - .sorted( - Comparator.comparing( - PERSON::getIsMarried, Comparator.nullsLast(Comparator.naturalOrder())) - .thenComparing(Comparator.comparing(PERSON::getId).reversed())) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByNameLessThanEqual = - (persons) -> { - String name = persons.get(persons.size() / 2).getName(); - return persons.stream() - .filter(person -> person.getName().compareTo(name) <= 0) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - }; - - Function, List> expectedListForFindAllByNameGreaterThanEqual = - (persons) -> { - String name = persons.get(persons.size() / 2).getName(); - return persons.stream() - .filter(person -> person.getName().compareTo(name) >= 0) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - }; - - Function, List> expectedListForFindAll = (persons) -> persons; - - List> getNextPageableMethodFunctionPairs = - Arrays.asList( - Arrays.asList(nextPageableFunc, prevPageableFunc, predicateForNextPageableFunc), - Arrays.asList( - nextOrLastPageableFunc, prevOrFirstPageableFunc, predicateForNextOrPageableFunc)); - - List> generateFunctions = - Arrays.asList( - Arrays.asList(personGenerateAndInsertFunction, personRepositoryFunc), - Arrays.asList(complexPersonGenerateAndInsertFunction, complexPersonRepositoryFunc)); - - List> executeExpectedFunctionPairs = - Arrays.asList( - Arrays.asList( - executionForFindAllByIdLessThanEqualFunc, - expectedListForFindAllByIdLessThanEqualFunc), - Arrays.asList( - executionForFindAllByIdGreaterThanEqualFunc, - expectedListForFindAllByIdGreaterThanEqualFunc), - Arrays.asList( - executionForFindAllByIsMarriedGreaterThanEqual, - expectedListForFindAllByIsMarriedGreaterThanEqual), - Arrays.asList( - executionForFindAllByIsMarriedLessThanEqual, - expectedListForFindAllByIsMarriedLessThanEqual), - Arrays.asList( - executionForFindAllByNameLessThanEqual, expectedListForFindAllByNameLessThanEqual), - Arrays.asList( - executionForFindAllByNameGreaterThanEqual, - expectedListForFindAllByNameGreaterThanEqual), - Arrays.asList( - executionForFindPersonByIdLessThanEqualFunc, - expectedListForFindAllByIdLessThanEqualFunc), - Arrays.asList( - executionForFindPersonByIdGreaterThanEqualFunc, - expectedListForFindAllByIdGreaterThanEqualFunc), - Arrays.asList( - executionForFindPersonByIsMarriedGreaterThanEqual, - expectedListForFindAllByIsMarriedGreaterThanEqual), - Arrays.asList( - executionForFindPersonByIsMarriedLessThanEqual, - expectedListForFindAllByIsMarriedLessThanEqual), - Arrays.asList( - executionForFindPersonByNameLessThanEqual, - expectedListForFindAllByNameLessThanEqual), - Arrays.asList( - executionForFindPersonByNameGreaterThanEqual, - expectedListForFindAllByNameGreaterThanEqual), - Arrays.asList(executionForFindAll, expectedListForFindAll)); - - // add arguments set - List arguments = new ArrayList<>(); - for (List generateFunctionPair : generateFunctions) { - for (List getNextPrevPageableFuncTriple : getNextPageableMethodFunctionPairs) { - for (List executeExpectedFunctionPair : executeExpectedFunctionPairs) { - arguments.add( - Arguments.of( - generateFunctionPair.get(0), - generateFunctionPair.get(1), - executeExpectedFunctionPair.get(0), - getNextPrevPageableFuncTriple.get(0), - getNextPrevPageableFuncTriple.get(1), - getNextPrevPageableFuncTriple.get(2), - executeExpectedFunctionPair.get(1), - beginPageable)); - } - } - } - return arguments.stream(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySliceWithDifferentFields") - , ID> void testRepositorySliceWithDifferentFields( - BiFunction> generateAndInsertFunction, - Function> giveRepositoryFunction, - BiFunction, List, Slice> - executingRepositoryMethod, - Function, Pageable> nextPageableMethod, - Function, Pageable> prevPageableMethod, - BiFunction stopPaginationPredicateFunction, - Function, List> expectedResultListMovingFunction, - Pageable beginPageable) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - - // moving forward - Pageable nextPageable = beginPageable; - List> forwardSlices = new ArrayList<>(); - Slice slice; - do { - slice = - executingRepositoryMethod.apply( - giveRepositoryFunction.apply(context), Arrays.asList(persons, nextPageable)); - forwardSlices.add(slice); - nextPageable = nextPageableMethod.apply(slice); - } while (stopPaginationPredicateFunction.apply(slice.getPageable(), nextPageable)); - - List forwardMovingResultList = - forwardSlices.stream().flatMap(Streamable::stream).collect(Collectors.toList()); - assertEquals(expectedResultListMovingFunction.apply(persons), forwardMovingResultList); - - // moving backward - List> reverseSlices = new ArrayList<>(); - nextPageable = forwardSlices.get(forwardSlices.size() - 1).getPageable(); - do { - slice = - executingRepositoryMethod.apply( - giveRepositoryFunction.apply(context), Arrays.asList(persons, nextPageable)); - reverseSlices.add(slice); - nextPageable = prevPageableMethod.apply(slice); - } while (stopPaginationPredicateFunction.apply(slice.getPageable(), nextPageable)); - - List backwardMovingResultList = - reverseSlices.stream() - .sorted(Comparator.comparing(Slice::getNumber)) - .flatMap(Streamable::stream) - .collect(Collectors.toList()); - - assertEquals(expectedResultListMovingFunction.apply(persons), backwardMovingResultList); - } - - protected static , ID> - List expectedForwardFuncForFindFirst5ByIsMarriedInitial(List persons) { - return persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst5ByIsMarriedInitial(List persons) { - List result = - new ArrayList<>(expectedForwardFuncForFindFirst5ByIsMarriedInitial(persons)); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial( - List persons) { - return persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial( - List persons) { - List result = - new ArrayList<>( - expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial(persons)); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst5ByIsMarriedIndexKey(List persons) { - return persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst5ByIsMarriedIndexKey(List persons) { - List result = - new ArrayList<>( - persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .sorted(Comparator.comparing(PERSON::getId)) - .toList()); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey( - List persons) { - return persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey( - List persons) { - List result = - new ArrayList<>( - persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .sorted(Comparator.comparing(PERSON::getId)) - .toList()); - Collections.reverse(result); - return result; - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Window executionFunctionForFindFirst5ByIsMarried(REPO repository, List args) { - ScrollPosition scrollPosition = (ScrollPosition) args.get(0); - return repository.findFirst5ByIsMarried(false, scrollPosition); - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Window executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual( - REPO repository, List args) { - ScrollPosition scrollPosition = (ScrollPosition) args.get(0); - return repository.findFirst10ByIsMarriedGreaterThanEqual(false, scrollPosition); - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Stream dataForTestRepositoryScrollForwardAndBackwardMoving() { - - ScrollPosition beginScrollPositionInitial = - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY); - ScrollPosition beginScrollPositionIndexKey = TarantoolScrollPosition.forward(PERSON_INDEX_KEY); - - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst5ByIsMarried, - (Function, List>) - GenericRepositoryTest::expectedForwardFuncForFindFirst5ByIsMarriedInitial, - (Function, List>) - GenericRepositoryTest::expectedBackwardFuncForFindFirst5ByIsMarriedInitial, - beginScrollPositionInitial), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst5ByIsMarried, - (Function, List>) - GenericRepositoryTest::expectedForwardFuncForFindFirst5ByIsMarriedIndexKey, - (Function, List>) - GenericRepositoryTest::expectedBackwardFuncForFindFirst5ByIsMarriedIndexKey, - beginScrollPositionIndexKey), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual, - (Function, List>) - GenericRepositoryTest - ::expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial, - (Function, List>) - GenericRepositoryTest - ::expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial, - beginScrollPositionInitial), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual, - (Function, List>) - GenericRepositoryTest - ::expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey, - (Function, List>) - GenericRepositoryTest - ::expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey, - beginScrollPositionIndexKey)); - } - - @ParameterizedTest - @MethodSource("dataForTestRepositoryScrollForwardAndBackwardMoving") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryScrollForwardAndBackwardMoving( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - BiFunction, Window> executingRepositoryMethod, - Function, List> expectedForwardResultFunction, - Function, List> expectedBackwardResultFunction, - ScrollPosition beginScrollPosition) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - Window personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(beginScrollPosition)); - List forwardResult = new ArrayList<>(); - - while (!personWindow.isEmpty() && personWindow.hasNext()) { - personWindow.forEach(forwardResult::add); - ScrollPosition nextPosition = personWindow.positionAt(personWindow.size() - 1); - personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(nextPosition)); - } - personWindow.forEach(forwardResult::add); - - assertEquals(expectedForwardResultFunction.apply(persons), forwardResult); - - TarantoolScrollPosition backwardScrollPosition = - ((TarantoolScrollPosition) personWindow.positionAt(0)).reverse(); - List backwardResult = personWindow.getContent(); - Collections.reverse(backwardResult); - - personWindow = - executingRepositoryMethod.apply( - repository, Collections.singletonList(backwardScrollPosition)); - while (!personWindow.isEmpty() && personWindow.hasNext()) { - personWindow.forEach(backwardResult::add); - ScrollPosition nextPosition = personWindow.positionAt(personWindow.size() - 1); - personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(nextPosition)); - } - personWindow.forEach(backwardResult::add); - - assertEquals(expectedBackwardResultFunction.apply(persons), backwardResult); - } - - protected static > - Stream dataForTestWindowIterator() { - return Stream.of( - Arguments.of( - (BiFunction>) - (context, size) -> Collections.emptyList(), - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY), - (Function, List>) (persons) -> Collections.emptyList(), - (Function, List>) (persons) -> Collections.emptyList()), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY), - (Function, List>) (persons) -> persons, - (Function, List>) - (persons) -> { - Collections.reverse(persons); - return persons; - }), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INDEX_KEY), - (Function, List>) - GenericRepositoryTest::expectedWindowIteratorForwardFromSomeCursor, - (Function, List>) - GenericRepositoryTest::expectedWindowIteratorBackwardFromSomeCursor)); - } - - protected static , ID> - List expectedWindowIteratorForwardFromSomeCursor(List persons) { - return persons.stream() - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .collect(Collectors.toList()); - } - - protected static , ID> - List expectedWindowIteratorBackwardFromSomeCursor(List persons) { - return persons.stream() - .filter(person -> person.getId() <= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId).reversed()) - .collect(Collectors.toList()); - } - - @ParameterizedTest - @MethodSource("dataForTestWindowIterator") - , ID, REPO extends GenericPaginationMethods> - void testWithWindowIteratorMoving( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - TarantoolScrollPosition beginScrollPosition, - Function, List> expectedForwardResultFunction, - Function, List> expectedBackwardResultFunction) { - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - TarantoolWindowIterator personForwardIterator = - TarantoolWindowIterator.of( - scrollPosition -> - repository.findFirst10ByIsMarriedGreaterThanEqual(null, scrollPosition)) - .startingAt(beginScrollPosition); - - List forwardResult = new ArrayList<>(); - - while (personForwardIterator.hasNext()) { - forwardResult.add(personForwardIterator.next()); - } - - forwardResult.sort(Comparator.comparing(PERSON::getId)); - assertEquals(expectedForwardResultFunction.apply(persons), forwardResult); - - // go back - List backwardResult = new ArrayList<>(); - - TarantoolWindowIterator personBackwardIterator = - TarantoolWindowIterator.of( - scrollPosition -> - repository.findFirst10ByIsMarriedGreaterThanEqual(null, scrollPosition)) - .startingAt(beginScrollPosition.reverse()); - - while (personBackwardIterator.hasNext()) { - backwardResult.add(personBackwardIterator.next()); - } - - assertEquals(expectedBackwardResultFunction.apply(persons), backwardResult); - } - - protected static Stream dataForTestUnsupportedRepositoryMethods() { - return Stream.of(PersonRepository.class, ComplexPersonRepository.class); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestUnsupportedRepositoryMethods") - , ID, REPO extends GenericPaginationMethods> - void testUnsupportedRepositoryMethods(Class repositoryClass) { - final REPO repository = context.getBean(repositoryClass); - - assertThrows(UnsupportedOperationException.class, repository::findAll); - assertThrows(UnsupportedOperationException.class, () -> repository.findAll(Sort.unsorted())); - } - - protected static Stream dataForTestPageableWithTrueCursorAndPageNumber() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(PAGE_SIZE), - PAGES_COUNT, - PAGES_COUNT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(1, PAGE_SIZE, new Person(9, null, "User-9")), - PAGES_COUNT - 1, - PAGES_COUNT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(2, PAGE_SIZE, new Person(19, null, "User-19")), - PAGES_COUNT - 2, - PAGES_COUNT)); - } - - private static void doTestPageableWithCursorAndPageNumber( - Pageable pageable, - BiFunction> repositoryFunction, - BiConsumer>, List>> assertionAction) { - List> forwardPages = new ArrayList<>(); - - Slice page = repositoryFunction.apply(0, pageable); - - forwardPages.add(page); - - while (page.hasNext()) { - page = repositoryFunction.apply(0, page.nextOrLastPageable()); - forwardPages.add(page); - } - - List> backwardPages = new ArrayList<>(); - for (int i = forwardPages.size() - 1; i >= 0; i--) { - Slice currentPage = forwardPages.get(i); - if (currentPage.getPageable().isPaged()) { - page = currentPage; - break; - } - } - backwardPages.add(page); - - page = repositoryFunction.apply(0, page.previousOrFirstPageable()); - backwardPages.add(page); - - while (page.hasPrevious()) { - page = repositoryFunction.apply(0, page.previousOrFirstPageable()); - backwardPages.add(page); - } - - assertionAction.accept(forwardPages, backwardPages); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageableWithTrueCursorAndPageNumber") - , ID, REPO extends GenericPaginationMethods> - void testPageableWithTrueCursorAndPageNumber( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCount, - int expectedBackwardPageCount) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - backwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestPageablePageNumberLessCursor() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // fourth page - new TarantoolPageRequest<>(0, PAGE_SIZE, new Person(29, null, "User-29")), - PAGES_COUNT - 2, - PAGES_COUNT - 3, - PAGES_COUNT - 3), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // third page - new TarantoolPageRequest<>(0, PAGE_SIZE, new Person(19, null, "User-19")), - PAGES_COUNT - 1, - PAGES_COUNT - 2, - PAGES_COUNT - 2)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageablePageNumberLessCursor") - , ID, REPO extends GenericPaginationMethods> - void testPageablePageNumberLessCursor( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCountForPage, - int expectedForwardPageCountForSlice, - int expectedBackwardPageCount) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - int expectedForwardPageCount = expectedForwardPageCountForSlice; - Slice firstPageable = forwardSlice.get(0); - if (firstPageable instanceof Page) { - expectedForwardPageCount = expectedForwardPageCountForPage; - } - - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - if (firstPageable instanceof Page) { - assertTrue(forwardSlice.get(forwardSlice.size() - 1).getPageable().isUnpaged()); - forwardSlice - .subList(0, forwardSlice.size() - 1) - .forEach(p -> assertTrue(p.getPageable().isPaged())); - } else { - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - } - backwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestPageablePageNumberGreaterCursor() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // second page - new TarantoolPageRequest<>(1, PAGE_SIZE, null), - PAGES_COUNT - 1, - PAGES_COUNT, - PAGES_COUNT, - PAGES_COUNT + 1), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // fourth page - new TarantoolPageRequest<>(3, PAGE_SIZE, new Person(9, null, "User-9")), - PAGES_COUNT - 3, - PAGES_COUNT - 1, - PAGES_COUNT - 1, - PAGES_COUNT + 1)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageablePageNumberGreaterCursor") - , ID, REPO extends GenericPaginationMethods> - void testPageablePageNumberGreaterCursor( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCountForPage, - int expectedForwardPageCountForSlice, - int expectedBackwardPageCountForPage, - int expectedBackwardPageCountForSlice) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - int expectedForwardPageCount = expectedForwardPageCountForPage; - int expectedBackwardPageCount = expectedBackwardPageCountForPage; - - Slice firstPageable = forwardSlice.get(0); - if (!(firstPageable instanceof Page)) { - expectedForwardPageCount = expectedForwardPageCountForSlice; - expectedBackwardPageCount = expectedBackwardPageCountForSlice; - } - - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - assertTrue(backwardSlice.get(backwardSlice.size() - 1).getPageable().isUnpaged()); - backwardSlice - .subList(0, backwardSlice.size() - 1) - .forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestRepositoryLimit() { - final int LIMITED_SIZE = 10; - final Limit LIMITED = Limit.of(LIMITED_SIZE); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - null, - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - Limit.unlimited(), - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - personGenerateAndInsertFunction, PersonRepository.class, LIMITED, LIMITED_SIZE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - null, - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - Limit.unlimited(), - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - LIMITED, - LIMITED_SIZE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryLimit") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryLimit( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Limit limit, - int expectedLimitSize) { - generateAndInsertFunction.apply(context, PERSONS_COUNT); - - REPO repository = context.getBean(repositoryClass); - - List selectedPersons = repository.findPersonByIdGreaterThanEqual(0, limit); - assertEquals(expectedLimitSize, selectedPersons.size()); - } - - protected static Stream dataForTestRepositoryLimitShouldThrow() { - final Limit BAD_LIMIT = Limit.of(-10); - return Stream.of( - Arguments.of(PersonRepository.class, BAD_LIMIT), - Arguments.of(ComplexPersonRepository.class, BAD_LIMIT)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryLimitShouldThrow") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryLimitShouldThrow(Class repositoryClass, Limit limit) { - REPO repository = context.getBean(repositoryClass); - assertThrows( - IllegalArgumentException.class, () -> repository.findPersonByIdGreaterThanEqual(0, limit)); - } - - protected static Stream dataForTestRepositoryLimitWithLimitInMethodName() { - final int LIMIT_FROM_METHOD_NAME = 4; - final int LIMITED_SIZE = 10; - final Limit LIMITED = Limit.of(LIMITED_SIZE); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, PersonRepository.class, null, LIMIT_FROM_METHOD_NAME), - Arguments.of( - personGenerateAndInsertFunction, PersonRepository.class, LIMITED, LIMITED_SIZE), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - Limit.unlimited(), - LIMIT_FROM_METHOD_NAME), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - null, - LIMIT_FROM_METHOD_NAME), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - LIMITED, - LIMITED_SIZE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - Limit.unlimited(), - LIMIT_FROM_METHOD_NAME)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryLimitWithLimitInMethodName") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryLimitWithLimitInMethodName( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Limit limit, - int expectedLimitSize) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - List selectedPersons = repository.findTop4ByIdGreaterThanEqual(0, limit); - - assertEquals(expectedLimitSize, selectedPersons.size()); - } - - @Test - void testConcurrentDerivedMethods() { - - final byte threadCount = 3; - final ExecutorService executor = Executors.newFixedThreadPool(threadCount); - final List>> futures = new ArrayList<>(threadCount); - final PersonRepository repository = context.getBean(PersonRepository.class); - - final List insertedPersons = - personGenerateAndInsertFunction.apply(context, (int) threadCount); - final Person firstPerson = insertedPersons.get(0); - final Person secondPerson = insertedPersons.get(1); - final Person thirdPerson = insertedPersons.get(2); - - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findPersonById(firstPerson.getId()), executor)); - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findByIsMarried(secondPerson.getIsMarried()), executor)); - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findByName(thirdPerson.getName()), executor)); - - CompletableFuture.allOf(futures.toArray(new CompletableFuture[] {})).join(); - - assertEquals(firstPerson, futures.get(0).join().get(0)); - assertEquals(secondPerson, futures.get(1).join().get(0)); - assertEquals(thirdPerson, futures.get(2).join().get(0)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/GenericTarantoolTemplateTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/GenericTarantoolTemplateTest.java deleted file mode 100644 index 6bc4fee5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/GenericTarantoolTemplateTest.java +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.integration.crud; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.core.UncategorizedKeyValueException; - -import static io.tarantool.spring.data.ProxyTarantoolCrudKeyValueAdapter.POTENTIAL_PERFORMANCE_ISSUES_EXCEPTION_MESSAGE; -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.generateAndInsertPersons; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.generateComplexPersons; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.mapping.crud.CrudException; -import io.tarantool.spring.data33.core.TarantoolTemplate; -import io.tarantool.spring.data33.utils.entity.ComplexPerson; -import io.tarantool.spring.data33.utils.entity.ComplexPersonWithIncorrectPK; -import io.tarantool.spring.data33.utils.entity.ComplexPersonWithJsonFormatVariantPK; -import io.tarantool.spring.data33.utils.entity.CompositePersonKey; -import io.tarantool.spring.data33.utils.entity.CompositePersonKeyWithJsonFormat; -import io.tarantool.spring.data33.utils.entity.Person; - -abstract class GenericTarantoolTemplateTest extends CrudConfigurations { - - @Autowired protected TarantoolTemplate tarantoolTemplate; - - @Test - void testGetAllOf() { - final Throwable throwable = - assertThrows( - UncategorizedKeyValueException.class, () -> tarantoolTemplate.findAll(Person.class)) - .getCause(); - - assertEquals(UnsupportedOperationException.class, throwable.getClass()); - assertEquals(POTENTIAL_PERFORMANCE_ISSUES_EXCEPTION_MESSAGE, throwable.getMessage()); - } - - static Stream dataForInsert() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - return Stream.of( - Arguments.of( - simpleKeyPerson, - (Function) (kv) -> kv.insert(simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - compositeKeyPerson, - (Function) (kv) -> kv.insert(compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForInsert") - void testKVTemplateInsert( - Object result, - Function callingMethod, - Function> selectAction) { - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForInsertById() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - return Stream.of( - Arguments.of( - simpleKeyPerson, - (Function) (kv) -> kv.insert(simpleKey, simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - compositeKeyPerson, - (Function) - (kv) -> kv.insert(compositeKey, compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForInsertById") - void testKVTemplateInsertById( - Object result, - Function callingMethod, - Function> selectAction) { - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForUpdate() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - Consumer prepareActionForSimpleKeyPerson = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer prepareActionForCompositeKeyPerson = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - return Stream.of( - Arguments.of( - prepareActionForSimpleKeyPerson, - simpleKeyPerson, - (Function) (kv) -> kv.update(simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - prepareActionForCompositeKeyPerson, - compositeKeyPerson, - (Function) (kv) -> kv.update(compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForUpdate") - void testKVTemplateUpdate( - Consumer prepareAction, - Object result, - Function callingMethod, - Function> selectAction) { - prepareAction.accept(client); - - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForUpdateById() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - Consumer prepareActionForSimpleKeyPerson = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer prepareActionForCompositeKeyPerson = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - return Stream.of( - Arguments.of( - prepareActionForSimpleKeyPerson, - simpleKeyPerson, - (Function) (kv) -> kv.update(simpleKey, simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - prepareActionForCompositeKeyPerson, - compositeKeyPerson, - (Function) - (kv) -> kv.update(compositeKey, compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForUpdateById") - void testKVTemplateUpdateById( - Consumer prepareAction, - Object result, - Function callingMethod, - Function> selectAction) { - prepareAction.accept(client); - - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForDelete() { - - Runnable simpleKeyPrepareAction = () -> generatePersons(PERSONS_COUNT); - Runnable compositeKeyPrepareAction = () -> generateComplexPersons(PERSONS_COUNT); - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(Person.class), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(ComplexPerson.class), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDelete") - void testKVTemplateDelete( - Runnable prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.run(); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForDeleteEntities() { - - Person simpleKeyPerson = new Person(0, true, "0"); - ComplexPerson compositeKeyPerson = new ComplexPerson(0, UUID.randomUUID(), true, "0"); - - Consumer simpleKeyPrepareAction = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer compositeKeyPrepareAction = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(simpleKeyPerson), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(compositeKeyPerson), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDeleteEntities") - void testKVTemplateDeleteEntities( - Consumer prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.accept(client); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForDeleteEntitiesById() { - - Person simpleKeyPerson = new Person(0, true, "0"); - ComplexPerson compositeKeyPerson = new ComplexPerson(0, UUID.randomUUID(), true, "0"); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Consumer simpleKeyPrepareAction = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer compositeKeyPrepareAction = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(simpleKey, Person.class), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(compositeKey, ComplexPerson.class), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDeleteEntitiesById") - void testKVTemplateDeleteEntitiesById( - Consumer prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.accept(client); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForCount() { - - Consumer simpleKeyPrepareAction = - (client) -> generateAndInsertPersons(PERSONS_COUNT, client); - - Consumer compositeKeyPrepareAction = - (client) -> generateAndInsertComplexPersons(PERSONS_COUNT, client); - - return Stream.of( - Arguments.of( - PERSONS_COUNT, - simpleKeyPrepareAction, - (Function) (kv) -> kv.count(Person.class)), - Arguments.of( - PERSONS_COUNT, - compositeKeyPrepareAction, - (Function) (kv) -> kv.count(ComplexPerson.class))); - } - - @ParameterizedTest - @MethodSource("dataForCount") - void testCount( - long expectedCount, - Consumer prepareAction, - Function callingMethod) { - prepareAction.accept(client); - assertEquals(expectedCount, callingMethod.apply(tarantoolTemplate)); - } - - @Test - void testCompositeKeyWithJsonFormat() { - ComplexPersonWithJsonFormatVariantPK complexPersonWithJsonFormatVariantPK = - new ComplexPersonWithJsonFormatVariantPK(0, UUID.randomUUID(), null, "0"); - - assertEquals( - complexPersonWithJsonFormatVariantPK, - tarantoolTemplate.insert(complexPersonWithJsonFormatVariantPK)); - - CompositePersonKeyWithJsonFormat key = - new CompositePersonKeyWithJsonFormat( - complexPersonWithJsonFormatVariantPK.getId(), - complexPersonWithJsonFormatVariantPK.getSecondId()); - Optional foundPerson = - tarantoolTemplate.findById(key, ComplexPersonWithJsonFormatVariantPK.class); - assertTrue(foundPerson.isPresent()); - assertEquals(complexPersonWithJsonFormatVariantPK, foundPerson.get()); - } - - @Test - void testCompositeKeyWithoutJsonFormat() { - ComplexPersonWithIncorrectPK complexPersonWithIncorrectPK = - new ComplexPersonWithIncorrectPK(0, UUID.randomUUID(), null, "0"); - - Throwable exception = - assertThrows( - UncategorizedKeyValueException.class, - () -> tarantoolTemplate.insert(complexPersonWithIncorrectPK)) - .getRootCause(); - assertInstanceOf(CrudException.class, exception); - } - - public static Stream dataForTestCompositeKeyWithConcurrency() { - final List threadsCount = Arrays.asList(1, 2, 3); - final List tuplesCount = Arrays.asList(20, 120, 360, 1200, 3000); - final List totalArguments = new ArrayList<>(); - - for (final Integer threadCount : threadsCount) { - for (final Integer tupleCount : tuplesCount) { - totalArguments.add(Arguments.of(threadCount, tupleCount)); - } - } - - return totalArguments.stream(); - } - - @DisplayName("Checking the insertion of an entity with a composite key") - @ParameterizedTest(autoCloseArguments = false, name = "thread count: {0}, tuples count: {1}") - @MethodSource("dataForTestCompositeKeyWithConcurrency") - void testCompositeKeyWithConcurrency(int threadsCount, int tuplesCount) { - final ExecutorService executor = Executors.newFixedThreadPool(threadsCount); - final List> futures = new ArrayList<>(); - final List tuples = generateComplexPersons(tuplesCount); - - for (final ComplexPerson tuple : tuples) { - futures.add( - CompletableFuture.supplyAsync(() -> this.tarantoolTemplate.insert(tuple), executor)); - } - - CompletableFuture.allOf(futures.toArray(new CompletableFuture[] {})).join(); - - for (int i = 0; i < tuplesCount; i++) { - assertEquals(tuples.get(i), futures.get(i).join()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/RepositoryConfigurationExtensionTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/RepositoryConfigurationExtensionTest.java deleted file mode 100644 index 787da3da..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/RepositoryConfigurationExtensionTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.integration.crud; - -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.client.factory.TarantoolBoxClientBuilder; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.spring.data33.integration.BaseIntegrationTest; -import io.tarantool.spring.data33.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data33.repository.config.TarantoolRepositoryConfigurationExtension; - -class RepositoryConfigurationExtensionTest extends BaseIntegrationTest { - - private static TarantoolRepositoryConfigurationExtension defaultExtension; - - @BeforeAll - static void setUp() throws IOException { - BaseIntegrationTest.beforeAll(); - defaultExtension = new TarantoolRepositoryConfigurationExtension(); - } - - @Test - void testGetModuleName() { - assertEquals("Tarantool", defaultExtension.getModuleName()); - } - - @Test - void testGetModulePrefix() { - assertEquals("tarantool", defaultExtension.getModulePrefix()); - } - - @Test - void testGetDefaultKeyValueTemplateRef() { - assertEquals( - DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF, defaultExtension.getDefaultKeyValueTemplateRef()); - } - - @Test - void testRegisterBeansForRootWithDefaultConfig() { - final ApplicationContext context = new AnnotationConfigApplicationContext(DefaultConfig.class); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF)); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF)); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF)); - } - - @Test - void testRegisterBeansForRootWithCustomClientConfigShouldThrows() { - final Throwable throwable = - assertThrows( - IllegalArgumentException.class, - () -> new AnnotationConfigApplicationContext(BoxNonSupportConfig.class)); - - final String exceptionMessage = "The Box client is not yet supported."; - assertEquals(exceptionMessage, throwable.getMessage()); - } - - private static TarantoolCrudClientBuilder getCrudClientSettings() { - return TarantoolFactory.crud() - .withHost(getHost()) - .withPort(getPort()) - .withUser(getUsername()) - .withPassword(getPassword()); - } - - private static TarantoolBoxClientBuilder getBoxClientSettings() { - return TarantoolFactory.box().withHost(getHost()).withPort(getPort()); - } - - @EnableTarantoolRepositories - static class DefaultConfig { - - @Bean - public TarantoolCrudClientBuilder clientSettings() { - return getCrudClientSettings(); - } - } - - @EnableTarantoolRepositories(clientType = ClientType.BOX) - static class BoxNonSupportConfig { - - @Bean - public TarantoolBoxClientBuilder clientSettings() { - return getBoxClientSettings(); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/RepositoryViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/RepositoryViaJavaConfigTest.java deleted file mode 100644 index a5392d37..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/RepositoryViaJavaConfigTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data33.integration.crud.CrudConfigurations.JavaConfigConfiguration; - -@SpringBootTest(classes = {JavaConfigConfiguration.class}) -class RepositoryViaJavaConfigTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/RepositoryViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/RepositoryViaPropertiesTest.java deleted file mode 100644 index b6d82503..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/RepositoryViaPropertiesTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data33.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; - -@SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) -class RepositoryViaPropertiesTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/TarantoolTemplateViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/TarantoolTemplateViaJavaConfigTest.java deleted file mode 100644 index 56536ac0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/TarantoolTemplateViaJavaConfigTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data33.integration.crud.CrudConfigurations.JavaConfigConfiguration; - -@SpringBootTest(classes = {JavaConfigConfiguration.class}) -class TarantoolTemplateViaJavaConfigTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/TarantoolTemplateViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/TarantoolTemplateViaPropertiesTest.java deleted file mode 100644 index 8a2ff48c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/TarantoolTemplateViaPropertiesTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data33.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; - -@SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) -class TarantoolTemplateViaPropertiesTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolCriteriaTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolCriteriaTest.java deleted file mode 100644 index 0da2aab0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolCriteriaTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.util.Arrays; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; - -import static io.tarantool.client.crud.ConditionOperator.EQ; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.spring.data.query.Conditions; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolCriteriaTest { - - @Test - void testAddAndGetConditions() { - final TarantoolCriteria tarantoolCriteria = new TarantoolCriteria(); - final String identifier = "name"; - final Object value = "value"; - final String operator = "=="; - - final Condition condition = Condition.create(operator, identifier, value); - assertEquals(operator, condition.getOperator()); - assertEquals(identifier, condition.getFieldIdentifier()); - assertEquals(value, condition.getValue()); - - final Condition conditionConstructor = new Condition(operator, identifier, value); - assertEquals(operator, conditionConstructor.getOperator()); - assertEquals(identifier, conditionConstructor.getFieldIdentifier()); - assertEquals(value, conditionConstructor.getValue()); - - final Condition conditionFromBuilder = - Condition.builder() - .withOperator(operator) - .withValue(value) - .withFieldIdentifier(identifier) - .build(); - assertEquals(operator, conditionFromBuilder.getOperator()); - assertEquals(identifier, conditionFromBuilder.getFieldIdentifier()); - assertEquals(value, conditionFromBuilder.getValue()); - - final Condition conditionWithEnum = Condition.create(EQ, identifier, value); - assertEquals(operator, conditionWithEnum.getOperator()); - assertEquals(identifier, conditionWithEnum.getFieldIdentifier()); - assertEquals(value, conditionWithEnum.getValue()); - - final Condition conditionConstructorWithEnum = new Condition(EQ, identifier, value); - assertEquals(operator, conditionConstructorWithEnum.getOperator()); - assertEquals(identifier, conditionConstructorWithEnum.getFieldIdentifier()); - assertEquals(value, conditionConstructorWithEnum.getValue()); - - final Condition conditionFromBuilderWithEnum = - Condition.builder() - .withOperator(EQ) - .withValue(value) - .withFieldIdentifier(identifier) - .build(); - assertEquals(operator, conditionFromBuilderWithEnum.getOperator()); - assertEquals(identifier, conditionFromBuilderWithEnum.getFieldIdentifier()); - assertEquals(value, conditionFromBuilderWithEnum.getValue()); - - tarantoolCriteria.addCondition(condition); - tarantoolCriteria.addCondition(conditionConstructor); - tarantoolCriteria.addCondition(conditionFromBuilder); - - tarantoolCriteria.addCondition(conditionWithEnum); - tarantoolCriteria.addCondition(conditionConstructorWithEnum); - tarantoolCriteria.addCondition(conditionFromBuilderWithEnum); - - final Conditions expectedConditions = new Conditions(); - expectedConditions.addAll( - Arrays.asList( - condition, - conditionConstructor, - conditionFromBuilder, - conditionWithEnum, - conditionConstructorWithEnum, - conditionFromBuilderWithEnum)); - - assertEquals(expectedConditions, tarantoolCriteria.getConditions()); - } - - @Test - void testFirst() { - final TarantoolCriteria criteria = new TarantoolCriteria(); - criteria.withFirst(1); - - final String key = "first"; - SelectOptions options = criteria.getOptions(); - assertEquals(1, options.getOptions().get(key)); - - criteria.clear(); - criteria.withFirst(-1); - options = criteria.getOptions(); - assertEquals(-1, options.getOptions().get(key)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolPageImplTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolPageImplTest.java deleted file mode 100644 index 5864516b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolPageImplTest.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data33.utils.entity.Person; - -class TarantoolPageImplTest { - - private static final List PERSONS = generatePersons(PERSONS_COUNT); - - private static final int DEFAULT_PAGE_SIZE_PER_TEST_CLASS = 10; - - private static final int DEFAULT_PAGE_NUMBER_PER_TEST_CLASS = 0; - - private static final Pageable FIRST_PAGE_PAGEABLE_PER_TEST_CLASS = - new TarantoolPageRequest<>( - DEFAULT_PAGE_NUMBER_PER_TEST_CLASS, DEFAULT_PAGE_SIZE_PER_TEST_CLASS, null); - - private static final long MULTIPLIER = 2L; - - private static final BiFunction GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE = - (pageSize, operator) -> { - switch (operator) { - // pageSize > totalPageCount - case ">": - { - return pageSize / MULTIPLIER; - } - // pageSize < totalPageCount - case "<": - { - return MULTIPLIER * pageSize; - } - // pageSize == totalPageCount - case "==": - { - return Long.valueOf(pageSize); - } - default: - throw new IllegalArgumentException("The passed option isn't supported"); - } - }; - - private static final List EMPTY_CONTENT = Collections.emptyList(); - - protected static Stream dataForTestConstructors() { - TarantoolPageable> pageable = - new TarantoolPageRequest<>(0, DEFAULT_PAGE_SIZE_PER_TEST_CLASS, null); - - long personsSize = PERSONS.size(); - - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>(PERSONS, pageable, personsSize), - PERSONS.size() / DEFAULT_PAGE_SIZE_PER_TEST_CLASS, - personsSize), - Arguments.of(new TarantoolPageImpl<>(PERSONS), 1, personsSize), - Arguments.of(new TarantoolPageImpl<>(), 1, 0L)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructors") - void testConstructors(Page> page, int totalPages, long totalElements) { - assertEquals(totalPages, page.getTotalPages()); - assertEquals(totalElements, page.getTotalElements()); - } - - static Stream dataForTestConstructorsThrowsIllegalArgumentException() { - final class DummyTarantoolPageRequest implements Pageable { - - @Override - public int getPageNumber() { - return 0; - } - - @Override - public int getPageSize() { - return 0; - } - - @Override - public long getOffset() { - return 0L; - } - - @Override - public Sort getSort() { - return null; - } - - @Override - public Pageable next() { - return null; - } - - @Override - public Pageable previousOrFirst() { - return null; - } - - @Override - public Pageable first() { - return null; - } - - @Override - public Pageable withPage(int pageNumber) { - return null; - } - - @Override - public boolean hasPrevious() { - return false; - } - } - - Pageable dummyPageable = new DummyTarantoolPageRequest(); - - return Stream.of( - Arguments.of(null, null, "Content must not be null"), - Arguments.of(Collections.emptyList(), null, "Pageable must not be null"), - Arguments.of( - Collections.emptyList(), - dummyPageable, - "Pageable must be TarantoolPageable or Unpaged type")); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructorsThrowsIllegalArgumentException") - void testConstructors_throws_IllegalArgumentException( - List content, Pageable pageable, String errorMsg) { - assertThrows( - IllegalArgumentException.class, - () -> new TarantoolPageImpl<>(content, pageable, 0L), - errorMsg); - } - - static Stream dataForTestGetTotalPages() { - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, ">")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "<")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - PERSONS.size() / FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, ">")), - 0), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "<")), - 0), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "==")), - 0)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTotalPages") - void testGetTotalPages(Page page, long totalPagesCount) { - assertEquals(totalPagesCount, page.getTotalPages()); - } - - static Stream dataForTestGetTotalElements() { - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() / MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() * MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - PERSONS.size()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() * MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTotalElements") - void testGetTotalElements(Page page, long totalElementCount) { - assertEquals(totalElementCount, page.getTotalElements()); - } - - static Stream dataForTestHasNext() { - return Stream.of( - Arguments.of( - false, - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())), - Arguments.of( - true, - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - MULTIPLIER * FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())), - Arguments.of( - false, - new TarantoolPageImpl<>( - PERSONS, - Pageable.unpaged(), - MULTIPLIER * FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()))); - } - - @ParameterizedTest - @MethodSource("dataForTestHasNext") - void testHasNext(boolean exceptedBool, Page page) { - assertEquals(exceptedBool, page.hasNext()); - } - - @ParameterizedTest - @MethodSource("dataForTestHasNext") - void testIsLast(boolean notEqualBool, Page page) { - assertNotEquals(notEqualBool, page.isLast()); - } - - static Stream dataForTestMap() { - List exceptedNames = PERSONS.stream().map(Person::getName).collect(Collectors.toList()); - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - exceptedNames, - (Function) Person::getName)); - } - - @ParameterizedTest - @MethodSource("dataForTestMap") - void testMap(Page page, List exceptedNames, Function mapFunction) { - List names = page.map(mapFunction).toList(); - assertEquals(exceptedNames, names); - } - - static Stream dataForTestEqualsAndHashCode() { - List> equalPages = - Arrays.asList( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())); - - final int ITERATION_COUNT = 100; - - return Stream.of( - Arguments.of( - equalPages, - new TarantoolPageImpl<>(EMPTY_CONTENT, Pageable.unpaged(), 150), - ITERATION_COUNT), - Arguments.of(equalPages, null, ITERATION_COUNT)); - } - - @ParameterizedTest - @MethodSource("dataForTestEqualsAndHashCode") - void testEqualsAndHashCode(List> pages, Page notEqualPage, int iterationCount) { - for (int i = 0; i < iterationCount; i++) { - for (Page page : pages) { - for (Page otherPage : pages) { - assertEquals(page, otherPage); - assertEquals(page.hashCode(), otherPage.hashCode()); - } - assertNotEquals(page, notEqualPage); - if (notEqualPage != null) { - assertNotEquals(page.hashCode(), notEqualPage.hashCode()); - } - } - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolPageRequestTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolPageRequestTest.java deleted file mode 100644 index 478bacc5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolPageRequestTest.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.util.Arrays; -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.AbstractPageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data33.utils.entity.Person; - -class TarantoolPageRequestTest { - - private static final int PAGE_SIZE = 10; - - private static final Person CURSOR = new Person(0, true, "0"); - - private static final int PAGE_NUMBER = 0; - - protected static Stream dataForTestConstructors() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - null, - FORWARD), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - CURSOR, - FORWARD), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, null), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - null, - FORWARD)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructors") - void testConstructors( - Supplier>> constructorGenerator, - int pageNumber, - int size, - Sort sort, - GenericPerson cursor, - PaginationDirection direction) { - TarantoolPageable> pageable = constructorGenerator.get(); - - assertEquals(size, pageable.getPageSize()); - assertEquals(pageNumber, pageable.getPageNumber()); - assertEquals(sort, pageable.getSort()); - assertEquals(cursor, pageable.getTupleCursor()); - assertEquals(direction, pageable.getPaginationDirection()); - } - - protected static Stream dataTestGetSort() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - Sort.unsorted()), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - Sort.unsorted())); - } - - @ParameterizedTest - @MethodSource("dataTestGetSort") - void testGetSort(Supplier>> constructorGenerator, Sort sort) { - Pageable pageable = constructorGenerator.get(); - assertEquals(sort, pageable.getSort()); - } - - protected static Stream dataForTestGetTupleCursor() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - null), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTupleCursor") - void testGetTupleCursor( - Supplier>> constructorGenerator, GenericPerson person) { - TarantoolPageable> pageable = constructorGenerator.get(); - assertEquals(person, pageable.getTupleCursor()); - } - - protected static Stream dataForTestNext() { - final Person NEXT_CURSOR = - new Person(CURSOR.getId() + PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), CURSOR, NEXT_CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataForTestNext") - void testNext( - TarantoolPageable> pageable, - GenericPerson cursor, - GenericPerson nextCursor) { - assertEquals(cursor, pageable.getTupleCursor()); - - TarantoolPageable> nextPageable = pageable.next(nextCursor); - assertEquals(nextCursor, nextPageable.getTupleCursor()); - - assertEquals(pageable.getPageSize(), nextPageable.getPageSize()); - assertEquals(pageable.getPageNumber() + 1, nextPageable.getPageNumber()); - assertEquals(pageable.getSort(), nextPageable.getSort()); - assertEquals(pageable.getOffset() + PAGE_SIZE, nextPageable.getOffset()); - } - - @Test - void testNextUnsupported() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::next); - } - - protected static Stream dataTestGetPaginationDirection() { - final Person PREV_CURSOR = new Person(CURSOR.getId(), CURSOR.getIsMarried(), CURSOR.getName()); - final Person NEXT_CURSOR = - new Person(PREV_CURSOR.getId() + PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, NEXT_CURSOR), NEXT_CURSOR, PREV_CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataTestGetPaginationDirection") - void testGetPaginationDirection( - TarantoolPageable> pageable, - GenericPerson nextCursor, - GenericPerson prevCursor) { - - assertEquals(FORWARD, pageable.getPaginationDirection()); - - TarantoolPageable> prevPageable = pageable.previousOrFirst(prevCursor); - assertEquals(PaginationDirection.BACKWARD, prevPageable.getPaginationDirection()); - - TarantoolPageable> nextPageable = prevPageable.next(nextCursor); - assertEquals(FORWARD, nextPageable.getPaginationDirection()); - assertEquals(pageable, nextPageable); - } - - protected static Stream dataTestFirst() { - final Person CURSOR = new Person(2 * PAGE_SIZE, true, "name"); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(0, PAGE_SIZE, null))); - } - - @ParameterizedTest - @MethodSource("dataTestFirst") - void testFirst( - TarantoolPageable> pageable, - TarantoolPageable> exceptedFirstPageable) { - assertEquals(exceptedFirstPageable, pageable.first()); - } - - @Test - void testWithPage() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, () -> pageable.withPage(100)); - } - - protected static Stream dataTestPreviousOrFirst() { - final Person CURSOR = new Person(PAGE_SIZE, true, "name"); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, CURSOR), - new Person(CURSOR.getId() - PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()))); - } - - @ParameterizedTest - @MethodSource("dataTestPreviousOrFirst") - void testPreviousOrFirst( - TarantoolPageable> pageable, GenericPerson prevCursor) { - - TarantoolPageable> prevPageable = pageable.previousOrFirst(prevCursor); - - assertNotEquals(pageable, prevPageable); - assertEquals(pageable.getPageSize(), prevPageable.getPageSize()); - assertEquals(pageable.getOffset() - PAGE_SIZE, prevPageable.getOffset()); - assertEquals(pageable.getSort(), prevPageable.getSort()); - assertEquals(pageable.getPageNumber() - 1, prevPageable.getPageNumber()); - - // here will be first with null cursor - TarantoolPageable> firstPageable = prevPageable.previousOrFirst(prevCursor); - assertNull(firstPageable.getTupleCursor()); - } - - @Test - void testPreviousOrFirstUnsupported() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::previousOrFirst); - } - - @Test - void testPreviousUnsupported() { - AbstractPageRequest pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::previous); - } - - protected static Stream dataForTestEquals() { - return Stream.of( - Arguments.of( - Arrays.asList( - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR)), - new TarantoolPageRequest<>(PAGE_SIZE))); - } - - @ParameterizedTest - @MethodSource("dataForTestEquals") - void testEquals( - List>> equalPageableList, - TarantoolPageable> notEqualPageable) { - - assertTrue(equalPageableList.size() > 0); - final int COUNT = 10; - - for (int i = 0; i < COUNT; i++) { - for (TarantoolPageable> pageable : equalPageableList) { - for (TarantoolPageable> secondPageable : equalPageableList) { - assertEquals(pageable, secondPageable); - } - assertNotEquals(pageable, null); - assertNotEquals(pageable, notEqualPageable); - } - } - } - - @ParameterizedTest - @MethodSource("dataForTestEquals") - void testHashCode( - List>> equalPageableList, - TarantoolPageable> notEqualPageable) { - - for (TarantoolPageable> pageable : equalPageableList) { - for (TarantoolPageable> secondPageable : equalPageableList) { - assertEquals(pageable.hashCode(), secondPageable.hashCode()); - } - assertNotEquals(pageable.hashCode(), notEqualPageable.hashCode()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolSliceTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolSliceTest.java deleted file mode 100644 index bf1da347..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolSliceTest.java +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.function.Executable; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data33.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.spring.data33.utils.entity.Person; - -public class TarantoolSliceTest { - - private static final int PAGE_SIZE = 10; - - private static final int PAGE_NUMBER = 0; - - private static final Person SOME_CURSOR = new Person(0, true, "0"); - - private static List PERSONS; - - private static final Pageable SOME_PAGEABLE = - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR); - - @BeforeAll - static void setUp() { - PERSONS = generatePersons(PERSONS_COUNT); - } - - static Stream dataForTestConstructorsShouldThrow() { - Pageable tarantoolPageable = new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR); - Pageable notTarantoolPageable = Pageable.ofSize(PAGE_SIZE); - return Stream.of( - Arguments.of(null, tarantoolPageable, false), - Arguments.of(null, tarantoolPageable, true), - Arguments.of(PERSONS, null, false), - Arguments.of(PERSONS, null, true), - Arguments.of(PERSONS, notTarantoolPageable, false), - Arguments.of(PERSONS, notTarantoolPageable, true)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructorsShouldThrow") - public void testConstructorsShouldThrow(List content, Pageable pageable, boolean hasNext) { - assertThrows( - IllegalArgumentException.class, () -> new TarantoolSliceImpl<>(content, pageable, hasNext)); - } - - static Stream dataForTestConstructorsDoesntThrow() { - return Stream.of( - () -> new TarantoolSliceImpl<>(PERSONS), - () -> new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - () -> new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestConstructorsDoesntThrow") - public void testConstructorsDoesntThrow(Executable runTestCase) { - assertDoesNotThrow(runTestCase); - } - - static Stream dataForTestGetNumber() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getPageNumber()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetNumber") - public void testGetNumber(Slice slice, int expectedPageNumber) { - assertEquals(expectedPageNumber, slice.getNumber()); - } - - static Stream dataForTestGetSize() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getPageSize()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS.size()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), - SOME_PAGEABLE.getPageSize()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetSize") - public void testGetSize(Slice slice, int expectedSize) { - assertEquals(expectedSize, slice.getSize()); - } - - static Stream dataForTestGetNumberOfElements() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), PERSONS.size()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS.size()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), 0), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetNumberOfElements") - public void testGetNumberOfElements(Slice slice, int expectedNumberOfElements) { - assertEquals(expectedNumberOfElements, slice.getNumberOfElements()); - } - - static Stream dataForTestGetContent() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), PERSONS), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), - Collections.emptyList()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Collections.emptyList())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetContent") - public void testGetContent(Slice slice, List expectedContent) { - assertEquals(expectedContent, slice.getContent()); - } - - static Stream dataForTestHasContent() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), true), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), false), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasContent") - void testHasContent(Slice slice, boolean expectedHasContent) { - assertEquals(expectedHasContent, slice.hasContent()); - } - - static Stream dataForTestGetSort() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getSort()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Sort.unsorted())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetSort") - void testGetSort(Slice slice, Sort expectedSort) { - assertEquals(expectedSort, slice.getSort()); - } - - static Stream dataForTestIsFirst() { - final int MIDDLE_PAGE_NUMBER = 2; - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), true), - true), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), true), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - true), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), true)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestIsFirst") - void testIsFirst(Slice slice, boolean expectedIsFirst) { - assertEquals(expectedIsFirst, slice.isFirst()); - } - - static Stream dataForTestIsLast() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), false), - // last imitation - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, false), true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), true), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), true), - // last imitation - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, false), true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), true)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestIsLast") - void testIsLast(Slice slice, boolean expectedIsLast) { - assertEquals(expectedIsLast, slice.isLast()); - } - - static Stream dataForTestHasNext() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, new TarantoolPageRequest<>(PAGE_SIZE), true), true), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, new TarantoolPageRequest<>(PAGE_SIZE), false), false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), new TarantoolPageRequest<>(PAGE_SIZE), true), - false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), new TarantoolPageRequest<>(PAGE_SIZE), false), - false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasNext") - void testHasNext(Slice slice, boolean expectedHasNext) { - assertEquals(expectedHasNext, slice.hasNext()); - } - - static Stream dataForTestHasPrevious() { - final int MIDDLE_PAGE_NUMBER = 2; - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), false), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - false), - true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), false), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - false), - false), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), false), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasPrevious") - void testHasPrevious(Slice slice, boolean expectedHasPrevious) { - assertEquals(expectedHasPrevious, slice.hasPrevious()); - } - - static Stream dataForTestGetPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, pageable, true), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), pageable), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, pageable, false), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), pageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), - Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetPageable") - void testGetPageable(Slice slice, Pageable expectedPageable) { - assertEquals(expectedPageable, slice.getPageable()); - } - - static Stream dataForTestNextPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, true), - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - new TarantoolPageRequest<>(5, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestNextPageable") - void testNextPageable(Slice slice, Pageable expectedNextPageable) { - assertEquals(expectedNextPageable, slice.nextPageable()); - } - - static Stream dataForTestPreviousPageable() { - Pageable firstPagePageable = new TarantoolPageRequest<>(PAGE_SIZE); - Pageable secondPagePageable = - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)); - - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, false), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(4, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(0)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPreviousPageable") - void testPreviousPageable(Slice slice, Pageable expectedPrevPageable) { - assertEquals(expectedPrevPageable, slice.previousPageable()); - } - - static Stream dataForTestNextOrLastPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, true), - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), pageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, false), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), pageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - new TarantoolPageRequest<>(5, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - false), - new TarantoolPageRequest<>(4, PAGE_SIZE, null))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestNextOrLastPageable") - void testNextOrLastPageable(Slice slice, Pageable expectedNextOrLastPageable) { - assertEquals(expectedNextOrLastPageable, slice.nextOrLastPageable()); - } - - static Stream dataForTestPreviousOrFirstPageable() { - Pageable firstPagePageable = new TarantoolPageRequest<>(PAGE_SIZE); - Pageable secondPagePageable = - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)); - - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, true), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, true), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, false), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, false), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, true), - secondPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, false), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, false), - secondPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(4, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(0)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPreviousOrFirstPageable") - void testPreviousOrFirstPageable(Slice slice, Pageable expectedPrevOrFirstPageable) { - assertEquals(expectedPrevOrFirstPageable, slice.previousOrFirstPageable()); - } - - static Stream dataForTestMap() { - - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - List expectedNames = PERSONS.stream().map(Person::getName).collect(Collectors.toList()); - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, pageable, true), - (Function) Person::getName, - expectedNames, - new TarantoolSliceImpl<>(expectedNames, pageable, true))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestMap") - void testMap( - Slice slice, - Function mapper, - List expectedMappedList, - Slice expectedMappedSlice) { - assertEquals(expectedMappedSlice, slice.map(mapper)); - assertEquals(expectedMappedList, slice.map(mapper).getContent()); - } - - protected static Stream dataForTestEquals() { - - return Stream.of( - Arguments.of( - Arrays.asList( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true)), - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestEquals") - void testEquals(List> equalPageableList, Slice notEqualPageable) { - - assertFalse(equalPageableList.isEmpty()); - final int COUNT = 10; - - for (int i = 0; i < COUNT; i++) { - for (Slice pageable : equalPageableList) { - for (Slice secondPageable : equalPageableList) { - assertEquals(pageable, secondPageable); - } - assertNotEquals(pageable, null); - assertNotEquals(pageable, notEqualPageable); - } - } - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestEquals") - void testHashCode(List> equalPageableList, Slice notEqualPageable) { - for (Slice pageable : equalPageableList) { - for (Slice secondPageable : equalPageableList) { - assertEquals(pageable.hashCode(), secondPageable.hashCode()); - } - assertNotEquals(pageable.hashCode(), notEqualPageable.hashCode()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/TarantoolTestSupport.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/TarantoolTestSupport.java deleted file mode 100644 index 58c59c95..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/TarantoolTestSupport.java +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.UUID; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.Consumer; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.introspector.Property; -import org.yaml.snakeyaml.nodes.NodeTuple; -import org.yaml.snakeyaml.nodes.Tag; -import org.yaml.snakeyaml.representer.Representer; - -import static io.tarantool.balancer.BalancerMode.DEFAULT_BALANCER_MODE; -import static io.tarantool.client.TarantoolClient.DEFAULT_TAG; -import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_PASSWORD; -import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_USERNAME; -import static io.tarantool.core.protocol.requests.IProtoAuth.DEFAULT_AUTH_TYPE; -import static io.tarantool.pool.InstanceConnectionGroup.DEFAULT_HOST; -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import io.tarantool.balancer.BalancerMode; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.core.protocol.requests.IProtoAuth; -import io.tarantool.mapping.Tuple; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyFlushConsolidationHandler; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyHeartbeatOpts; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.spring.data33.config.properties.TarantoolProperties; -import io.tarantool.spring.data33.utils.entity.ComplexPerson; -import io.tarantool.spring.data33.utils.entity.Person; - -public class TarantoolTestSupport { - - private static final ThreadLocalRandom random = ThreadLocalRandom.current(); - private static final Map firstInternalMap = new HashMap<>(); - private static final Map secondInternalMap = new HashMap<>(); - private static final Map externalMap = new HashMap<>(); - private static final Representer representer; - public static final String PERSON_SPACE = "person"; - public static final String COMPLEX_PERSON_SPACE = "complex_person"; - public static final int PERSONS_COUNT = 100; - public static final Random RANDOMIZER = new Random(); - public static final Person UNKNOWN_PERSON = new Person(-1, true, "Alien"); - public static final ComplexPerson UNKNOWN_COMPLEX_PERSON = - new ComplexPerson(-1, new UUID(0, 0), true, "Alien"); - - public static final Path DEFAULT_TEST_PROPERTY_DIR = Paths.get("target", "test-classes"); - private static final Yaml yaml; - - static { - representer = - new Representer(new DumperOptions()) { - @Override - @Nullable - protected NodeTuple representJavaBeanProperty( - Object javaBean, Property property, @Nullable Object propertyValue, Tag customTag) { - if (propertyValue == null) { - return null; - } else { - return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag); - } - } - }; - representer.addClassTag(TarantoolProperties.class, Tag.MAP); - yaml = new Yaml(representer); - } - - public static TarantoolProperties writeTestPropertiesYaml(@NonNull final String fileName) - throws IOException { - return writeTestPropertiesYaml(fileName, createRandomProperty()); - } - - public static TarantoolProperties writeTestPropertiesYaml( - final String fileName, final TarantoolProperties properties) throws IOException { - final File FILE = DEFAULT_TEST_PROPERTY_DIR.resolve(fileName).toFile().getAbsoluteFile(); - - try (Writer writer = new FileWriter(FILE)) { - firstInternalMap.put("tarantool", properties); - secondInternalMap.put("data", firstInternalMap); - externalMap.put("spring", secondInternalMap); - - yaml.dump(externalMap, writer); - replaceNullToDefault(properties); - return properties; - } - } - - public static void writeTestEmptyPropertiesYaml(@NonNull final String fileName) - throws IOException { - final File FILE = DEFAULT_TEST_PROPERTY_DIR.resolve(fileName).toFile().getAbsoluteFile(); - try (Writer writer = new FileWriter(FILE)) { - yaml.dump(Collections.emptyMap(), writer); - } - } - - private static void replaceNullToDefault(final TarantoolProperties result) { - - if (result.getHost() == null) { - result.setHost(DEFAULT_HOST); - } - - if (result.getUserName() == null) { - result.setUserName(DEFAULT_CRUD_USERNAME); - } - - if (result.getBalancerMode() == null) { - result.setBalancerMode(DEFAULT_BALANCER_MODE); - } - - if (result.getPassword() == null) { - result.setPassword(DEFAULT_CRUD_PASSWORD); - } - - if (result.getConnectionGroups() != null) { - for (PropertyInstanceConnectionGroup propertyInstanceConnectionGroup : - result.getConnectionGroups()) { - if (propertyInstanceConnectionGroup.getAuthType() == null) { - propertyInstanceConnectionGroup.setAuthType(DEFAULT_AUTH_TYPE); - } - - if (propertyInstanceConnectionGroup.getHost() == null) { - propertyInstanceConnectionGroup.setHost(DEFAULT_HOST); - } - - if (propertyInstanceConnectionGroup.getTag() == null) { - propertyInstanceConnectionGroup.setTag(DEFAULT_TAG); - } - - if (propertyInstanceConnectionGroup.getUserName() == null) { - propertyInstanceConnectionGroup.setUserName(DEFAULT_CRUD_USERNAME); - } - - if (propertyInstanceConnectionGroup.getUserName() == null) { - propertyInstanceConnectionGroup.setPassword(DEFAULT_CRUD_PASSWORD); - } - } - } - } - - private static TarantoolProperties createRandomProperty() { - final int intVar = 999; - final long longVar = 9999L; - final List booleanVar = Arrays.asList(true, false); - - PropertyHeartbeatOpts propertyHeartbeatOpts = - heartbeat( - choiceOrNull(longVar), - choiceOrNull(intVar), - choiceOrNull(intVar), - choiceOrNull(intVar)); - - PropertyFlushConsolidationHandler propertyFlushConsolidationHandler = - choiceOrNull(flushConsolidation(choiceOrNull(intVar), choiceOrNull(booleanVar))); - - PropertyInstanceConnectionGroup propertyInstanceConnectionGroup = - choiceOrNull( - connectionGroup( - choiceOrNull("host"), - "password", - choiceOrNull(intVar), - choiceOrNull(intVar), - choiceOrNull("tag"), - "user", - choiceOrNull(Arrays.asList(IProtoAuth.AuthType.values())), - propertyFlushConsolidationHandler)); - List propertyInstanceConnectionGroups = null; - if (propertyInstanceConnectionGroup != null) { - propertyInstanceConnectionGroups = new ArrayList<>(); - propertyInstanceConnectionGroups.add(propertyInstanceConnectionGroup); - } - - return tarantoolProperties( - choiceOrNull("host"), - choiceOrNull("password"), - choiceOrNull(intVar), - choiceOrNull("user"), - propertyInstanceConnectionGroups, - choiceOrNull(intVar), - choiceOrNull(booleanVar), - choiceOrNull(propertyHeartbeatOpts), - choiceOrNull(longVar), - choiceOrNull(longVar), - choiceOrNull(booleanVar), - choiceOrNull(booleanVar), - choiceOrNull(Arrays.asList(BalancerMode.values()))); - } - - @Nullable - public static T choiceOrNull(@Nullable T element) { - int rnd = random.nextInt(2); - if (rnd == 0 || element == null) { - return null; - } - return element; - } - - public static PropertyHeartbeatOpts heartbeat( - @Nullable Long pingInterval, - @Nullable Integer invalidationThreshold, - @Nullable Integer windowSize, - @Nullable Integer deathThreshold) { - - PropertyHeartbeatOpts propertyHeartbeatOpts = new PropertyHeartbeatOpts(); - if (invalidationThreshold != null) { - propertyHeartbeatOpts.setInvalidationThreshold(invalidationThreshold); - } - if (pingInterval != null) { - propertyHeartbeatOpts.setPingInterval(pingInterval); - } - if (deathThreshold != null) { - propertyHeartbeatOpts.setDeathThreshold(deathThreshold); - } - if (windowSize != null) { - propertyHeartbeatOpts.setWindowSize(windowSize); - } - - return propertyHeartbeatOpts; - } - - public static PropertyFlushConsolidationHandler flushConsolidation( - @Nullable Integer explicitFlushAfterFlushes, - @Nullable Boolean consolidateWhenNoReadInProgress) { - - PropertyFlushConsolidationHandler propertyFlushConsolidationHandler = - new PropertyFlushConsolidationHandler(); - if (explicitFlushAfterFlushes != null) { - propertyFlushConsolidationHandler.setExplicitFlushAfterFlushes(explicitFlushAfterFlushes); - } - - if (consolidateWhenNoReadInProgress != null) { - propertyFlushConsolidationHandler.setConsolidateWhenNoReadInProgress( - consolidateWhenNoReadInProgress); - } - return propertyFlushConsolidationHandler; - } - - @Nullable - public static T choiceOrNull(@Nullable List list) { - if (list == null || list.isEmpty()) { - return null; - } - int rnd = random.nextInt(list.size() + 1); - - if (rnd == list.size()) { - return null; - } - return list.get(rnd); - } - - @NonNull - public static PropertyInstanceConnectionGroup connectionGroup( - @Nullable String host, - @Nullable String password, - @Nullable Integer port, - @Nullable Integer connectionNumber, - @Nullable String tag, - @Nullable String user, - @Nullable IProtoAuth.AuthType type, - @Nullable PropertyFlushConsolidationHandler propertyFlushConsolidationHandler) { - - PropertyInstanceConnectionGroup propertyInstanceConnectionGroup = - new PropertyInstanceConnectionGroup(); - propertyInstanceConnectionGroup.setHost(host); - if (connectionNumber != null) { - propertyInstanceConnectionGroup.setConnectionGroupSize(connectionNumber); - } - propertyInstanceConnectionGroup.setAuthType(type); - propertyInstanceConnectionGroup.setPassword(password); - if (port != null) { - propertyInstanceConnectionGroup.setPort(port); - } - propertyInstanceConnectionGroup.setTag(tag); - propertyInstanceConnectionGroup.setUserName(user); - - propertyInstanceConnectionGroup.setFlushConsolidationHandler(propertyFlushConsolidationHandler); - return propertyInstanceConnectionGroup; - } - - @NonNull - public static TarantoolProperties tarantoolProperties( - @Nullable String host, - @Nullable String password, - @Nullable Integer port, - @Nullable String user, - @Nullable List propertyInstanceConnectionGroups, - @Nullable Integer eventLoopThreadsCount, - @Nullable Boolean enableGracefulShutdown, - @Nullable PropertyHeartbeatOpts propertyHeartbeatOptsOpts, - @Nullable Long connectTimeout, - @Nullable Long reconnectAfter, - @Nullable Boolean fetchSchema, - @Nullable Boolean ignoreOldSchemaVersion, - @Nullable BalancerMode balancerClass) { - - TarantoolProperties prop = new TarantoolProperties(); - prop.setHost(host); - prop.setPassword(password); - if (port != null) { - prop.setPort(port); - } - prop.setUserName(user); - prop.setConnectionGroups(propertyInstanceConnectionGroups); - if (eventLoopThreadsCount != null) { - prop.setEventLoopThreadsCount(eventLoopThreadsCount); - } - - if (enableGracefulShutdown != null) { - prop.setGracefulShutdownEnabled(enableGracefulShutdown); - } - prop.setHeartbeat(propertyHeartbeatOptsOpts); - if (connectTimeout != null) { - prop.setConnectTimeout(connectTimeout); - } - if (reconnectAfter != null) { - prop.setReconnectAfter(reconnectAfter); - } - if (fetchSchema != null) { - prop.setFetchSchema(fetchSchema); - } - if (ignoreOldSchemaVersion != null) { - prop.setIgnoreOldSchemaVersion(ignoreOldSchemaVersion); - } - prop.setBalancerMode(balancerClass); - return prop; - } - - public static List generatePersons(int count) { - List persons = new ArrayList<>(); - for (int i = 0; i < count; i++) { - persons.add(new Person(i, i % 3 == 0 ? null : i % 2 == 0, "User-" + i)); - } - return persons; - } - - public static List generatePersons(int count, Consumer actionAtPerson) { - List persons = generatePersons(count); - persons.forEach(actionAtPerson); - return persons; - } - - public static List generateComplexPersons(int count) { - List persons = new ArrayList<>(); - for (int i = 0; i < count; i++) { - persons.add( - new ComplexPerson(i, UUID.randomUUID(), i % 3 == 0 ? null : i % 2 == 0, "User-" + i)); - } - return persons; - } - - public static List generateComplexPersons( - int count, Consumer actionAtPerson) { - List persons = generateComplexPersons(count); - persons.forEach(actionAtPerson); - return persons; - } - - public static List generateAndInsertPersons(int count, TarantoolCrudClient client) { - final List persons = generatePersons(count); - final TarantoolCrudSpace space = client.space(PERSON_SPACE); - - List> insertedPersons = space.insertMany(persons, Person.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertPersons( - int count, TarantoolCrudClient client, Consumer action) { - final List persons = generatePersons(count, action); - final TarantoolCrudSpace space = client.space(PERSON_SPACE); - - List> insertedPersons = space.insertMany(persons, Person.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertComplexPersons( - int count, TarantoolCrudClient client) { - final List persons = generateComplexPersons(count); - final TarantoolCrudSpace space = client.space(COMPLEX_PERSON_SPACE); - - List> insertedPersons = - space.insertMany(persons, ComplexPerson.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertComplexPersons( - int count, TarantoolCrudClient client, Consumer action) { - - final List persons = generateComplexPersons(count, action); - final TarantoolCrudSpace space = client.space(COMPLEX_PERSON_SPACE); - - List> insertedPersons = - space.insertMany(persons, ComplexPerson.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/ComplexPersonListRepository.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/ComplexPersonListRepository.java deleted file mode 100644 index eb9e2b9d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/ComplexPersonListRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.core; - -import org.springframework.data.repository.ListCrudRepository; - -import io.tarantool.spring.data.utils.GenericListRepositoryMethods; -import io.tarantool.spring.data33.utils.entity.ComplexPerson; -import io.tarantool.spring.data33.utils.entity.CompositePersonKey; - -public interface ComplexPersonListRepository - extends ListCrudRepository, - GenericListRepositoryMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/ComplexPersonRepository.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/ComplexPersonRepository.java deleted file mode 100644 index 655b9593..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/ComplexPersonRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.core; - -import org.springframework.data.repository.PagingAndSortingRepository; - -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data33.utils.entity.ComplexPerson; -import io.tarantool.spring.data33.utils.entity.CompositePersonKey; - -public interface ComplexPersonRepository - extends PagingAndSortingRepository, - GenericRepositoryMethods, - GenericPaginationMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/GenericPaginationMethods.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/GenericPaginationMethods.java deleted file mode 100644 index c8136a87..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/GenericPaginationMethods.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.core; - -import java.util.List; - -import org.springframework.data.domain.Limit; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; - -public interface GenericPaginationMethods { - - Slice findAllByName(String name); - - Slice findAllByName(String name, Pageable pageable); - - Slice findAllByNameGreaterThanEqual(String name, Pageable pageable); - - Slice findAllByNameLessThanEqual(String name, Pageable pageable); - - Slice findAllByIdLessThanEqual(int id, Pageable pageable); - - Slice findAllByIdGreaterThanEqual(int id, Pageable pageable); - - Slice findAllByIsMarriedLessThanEqual(Boolean id, Pageable pageable); - - Slice findAllByIsMarriedGreaterThanEqual(Boolean id, Pageable pageable); - - Page findPersonByName(String name, Pageable pageable); - - Page findPersonByNameGreaterThanEqual(String name, Pageable pageable); - - Page findPersonByNameLessThanEqual(String name, Pageable pageable); - - Page findPersonByIdLessThanEqual(int id, Pageable pageable); - - Page findPersonByIdGreaterThanEqual(int id, Pageable pageable); - - Page findPersonByIsMarriedLessThanEqual(Boolean id, Pageable pageable); - - Page findPersonByIsMarriedGreaterThanEqual(Boolean id, Pageable pageable); - - Window findFirst5ByIsMarried(Boolean isMarried, ScrollPosition scrollPosition); - - Window findFirst10ByIsMarriedGreaterThanEqual( - Boolean isMarried, ScrollPosition scrollPosition); - - List findAll(Sort sort); - - Page findAll(Pageable pageable); - - List findAll(); - - List findPersonByIdGreaterThanEqual(int id, Limit limit); - - List findTop4ByIdGreaterThanEqual(int id, Limit limit); -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/PersonRepository.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/PersonRepository.java deleted file mode 100644 index ad87d819..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/PersonRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.core; - -import org.springframework.data.repository.PagingAndSortingRepository; - -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data33.utils.entity.Person; - -public interface PersonRepository - extends PagingAndSortingRepository, - GenericRepositoryMethods, - GenericPaginationMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/ComplexPerson.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/ComplexPerson.java deleted file mode 100644 index 079c45f5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/ComplexPerson.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data33.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKey.class) -public class ComplexPerson implements GenericPerson { - - @Id - @Field("id") - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - protected Boolean isMarried; - - @Field("name") - @JsonProperty("name") - String name; - - @Override - public CompositePersonKey generateFullKey() { - return new CompositePersonKey(id, secondId); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/ComplexPersonWithIncorrectPK.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/ComplexPersonWithIncorrectPK.java deleted file mode 100644 index 8dec307f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/ComplexPersonWithIncorrectPK.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data33.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKeyWithoutJsonFormat.class) -public class ComplexPersonWithIncorrectPK { - - @Id - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/ComplexPersonWithJsonFormatVariantPK.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/ComplexPersonWithJsonFormatVariantPK.java deleted file mode 100644 index eddf0c5d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/ComplexPersonWithJsonFormatVariantPK.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data33.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKeyWithJsonFormat.class) -public class ComplexPersonWithJsonFormatVariantPK { - - @Id - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositeKeyWithWrongFieldCount.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositeKeyWithWrongFieldCount.java deleted file mode 100644 index c5a87f86..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositeKeyWithWrongFieldCount.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -public class CompositeKeyWithWrongFieldCount implements CompositeKey { - - @JsonProperty("id") - private long id; -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositeKeyWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositeKeyWithWrongFieldTypes.java deleted file mode 100644 index e13bdbc3..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositeKeyWithWrongFieldTypes.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositeKeyWithWrongFieldTypes implements CompositeKey { - - @JsonProperty("id") - private long id; - - @JsonProperty("secondId") - private String secondId; - - @JsonProperty("thirdId") - private boolean thirdId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositePersonKey.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositePersonKey.java deleted file mode 100644 index 8812c7d3..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositePersonKey.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositePersonKey implements CompositeKey { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositePersonKeyWithJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositePersonKeyWithJsonFormat.java deleted file mode 100644 index fed17762..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositePersonKeyWithJsonFormat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -public class CompositePersonKeyWithJsonFormat { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositePersonKeyWithoutJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositePersonKeyWithoutJsonFormat.java deleted file mode 100644 index 7d42dd7b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/CompositePersonKeyWithoutJsonFormat.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositePersonKeyWithoutJsonFormat { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/EntityWithAnnotationAsIdClass.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/EntityWithAnnotationAsIdClass.java deleted file mode 100644 index c90773a1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/EntityWithAnnotationAsIdClass.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.entity; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@IdClass(IdClass.class) -public class EntityWithAnnotationAsIdClass {} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/EntityWithWrongCompositeKeyPartsCount.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/EntityWithWrongCompositeKeyPartsCount.java deleted file mode 100644 index 14a6ea14..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/EntityWithWrongCompositeKeyPartsCount.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@IdClass(CompositeKeyWithWrongFieldCount.class) -public class EntityWithWrongCompositeKeyPartsCount { - - @Id - @JsonProperty("id") - private long id; - - @Id - @JsonProperty("secondId") - private long secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/EntityWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/EntityWithWrongFieldTypes.java deleted file mode 100644 index c2defdf2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/EntityWithWrongFieldTypes.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@IdClass(CompositeKeyWithWrongFieldTypes.class) -public class EntityWithWrongFieldTypes { - - @Id - @JsonProperty("id") - private long id; - - @Id - @JsonProperty("secondId") - private String secondId; - - @Id - @JsonProperty("thirdId") - private int thirdId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/Person.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/Person.java deleted file mode 100644 index beefbe6a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/entity/Person.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data33.utils.entity; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data33.query.Field; - -/** - * @author Artyom Dubinin - */ -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("person") -public class Person implements GenericPerson { - - @Id - @Field("id") - @JsonProperty("id") - public Integer id; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; - - @Override - public Integer generateFullKey() { - return id; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/resources/application-crud-test.yaml b/tarantool-spring-data/tarantool-spring-data-33/src/test/resources/application-crud-test.yaml deleted file mode 100644 index 9bc8f9b2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/resources/application-crud-test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -spring: - data: - tarantool: - host: localhost - port: 3301 diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/TarantoolBoxKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/TarantoolBoxKeyValueAdapter.java deleted file mode 100644 index 5b7ba190..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/TarantoolBoxKeyValueAdapter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34; - -import java.util.Map; - -import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.NonNull; - -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(Object id, Object item, String keyspace) { - return adapter.put(id, item, keyspace); - } - - @Override - public boolean contains(Object id, String keyspace) { - return adapter.contains(id, keyspace); - } - - @Override - public Object get(Object id, String keyspace) { - return adapter.get(id, keyspace); - } - - @Override - public Object delete(Object id, String keyspace) { - return adapter.delete(id, keyspace); - } - - @Override - public Iterable getAllOf(String keyspace) { - return adapter.getAllOf(keyspace); - } - - @Override - public void deleteAllOf(String keyspace) { - adapter.deleteAllOf(keyspace); - } - - @Override - public void clear() { - adapter.clear(); - } - - @Override - public long count(String keyspace) { - return adapter.count(keyspace); - } - - @Override - public void destroy() throws Exception { - adapter.destroy(); - } - - @Override - public CloseableIterator> entries(String keyspace) { - throw new UnsupportedOperationException("Not implemented yet"); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/TarantoolCrudKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/TarantoolCrudKeyValueAdapter.java deleted file mode 100644 index 418027fc..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/TarantoolCrudKeyValueAdapter.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34; - -import java.util.Collections; -import java.util.Map.Entry; - -import com.fasterxml.jackson.annotation.JsonFormat; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.NonNull; - -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(Object id, Object item, String keyspace) { - return adapter.put(convertId(id), item, keyspace); - } - - @Override - public boolean contains(Object id, String keyspace) { - return adapter.contains(convertId(id), keyspace); - } - - @Override - public Object get(Object id, String keyspace) { - return adapter.get(convertId(id), keyspace); - } - - @Override - public T get(Object id, String keyspace, Class type) { - return adapter.get(convertId(id), keyspace, type); - } - - @Override - public Object delete(Object id, String keyspace) { - return adapter.delete(convertId(id), keyspace); - } - - @Override - public T delete(Object id, String keyspace, Class type) { - return adapter.delete(convertId(id), keyspace, type); - } - - @Override - public Iterable getAllOf(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> 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()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/TarantoolQueryEngine.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/TarantoolQueryEngine.java deleted file mode 100644 index 9448338f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/TarantoolQueryEngine.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34; - -import java.util.Collection; -import java.util.Comparator; -import java.util.Map.Entry; - -import org.springframework.data.keyvalue.core.QueryEngine; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.ProxyTarantoolQueryEngine; -import io.tarantool.spring.data.query.TarantoolCriteria; -import io.tarantool.spring.data34.query.TarantoolCriteriaAccessor; -import io.tarantool.spring.data34.query.TarantoolSortAccessor; - -/** - * Implementation of {@code findBy*()} and {@code countBy*{}} queries. - * - * @author Artyom Dubinin - */ -public class TarantoolQueryEngine - extends QueryEngine>> { - - 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> 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. - * - *

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 Collection execute( - @Nullable final TarantoolCriteria criteria, - @Nullable final Comparator> sort, - final long offset, - final int rows, - @NonNull final String keyspace, - @NonNull Class 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); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/config/TarantoolBoxConfiguration.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/config/TarantoolBoxConfiguration.java deleted file mode 100644 index ac131bac..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/config/TarantoolBoxConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.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.data34.TarantoolBoxKeyValueAdapter; -import io.tarantool.spring.data34.config.properties.TarantoolProperties; - -@Configuration(proxyBeanMethods = false) -public class TarantoolBoxConfiguration extends BaseTarantoolBoxConfiguration { - - public TarantoolBoxConfiguration( - ObjectProvider properties, - ObjectProvider 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(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/config/TarantoolCrudConfiguration.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/config/TarantoolCrudConfiguration.java deleted file mode 100644 index b327ecf2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/config/TarantoolCrudConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.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_CRUD_CLIENT_BEAN_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.spring.data.config.BaseTarantoolCrudConfiguration; -import io.tarantool.spring.data34.TarantoolCrudKeyValueAdapter; -import io.tarantool.spring.data34.config.properties.TarantoolProperties; - -@Configuration(proxyBeanMethods = false) -public class TarantoolCrudConfiguration extends BaseTarantoolCrudConfiguration { - - public TarantoolCrudConfiguration( - ObjectProvider properties, - ObjectProvider tarantoolClientConfiguration) { - super(properties.getIfAvailable(), tarantoolClientConfiguration.getIfAvailable()); - } - - @Bean(name = DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF) - @ConditionalOnMissingBean(TarantoolCrudKeyValueAdapter.class) - public TarantoolCrudKeyValueAdapter tarantoolCrudKeyValueAdapter( - TarantoolCrudClient tarantoolCrudClient) { - return new TarantoolCrudKeyValueAdapter(tarantoolCrudClient); - } - - @Bean(name = DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF) - @ConditionalOnMissingBean(TarantoolCrudClient.class) - public TarantoolCrudClient tarantoolCrudClient() throws Exception { - return super.tarantoolCrudClient(); - } - - public TarantoolCrudClientBuilder getClientBuilder() { - return super.getClientBuilder(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/config/package-info.java deleted file mode 100644 index b8fc6d9f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/config/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Config package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data34.config; diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/config/properties/TarantoolProperties.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/config/properties/TarantoolProperties.java deleted file mode 100644 index 365bff05..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/config/properties/TarantoolProperties.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.config.properties; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties; - -/** - * Configuration properties for Tarantool. - * - * @author Nikolay Belonogov - */ -@ConfigurationProperties(prefix = "spring.data.tarantool") -public class TarantoolProperties extends BaseTarantoolProperties {} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/TarantoolTemplate.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/TarantoolTemplate.java deleted file mode 100644 index 5713b38d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/TarantoolTemplate.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.core; - -import org.springframework.data.keyvalue.core.IdentifierGenerator; -import org.springframework.data.keyvalue.core.KeyValueAdapter; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.util.ClassUtils; - -import io.tarantool.spring.data34.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data34.core.mapping.TarantoolMappingContext; - -public class TarantoolTemplate extends KeyValueTemplate { - - public TarantoolTemplate(KeyValueAdapter adapter) { - super(adapter, new TarantoolMappingContext<>()); - } - - public TarantoolTemplate( - KeyValueAdapter adapter, - MappingContext< - ? extends KeyValuePersistentEntity, ? extends KeyValuePersistentProperty> - mappingContext) { - super(adapter, mappingContext); - } - - public TarantoolTemplate( - KeyValueAdapter adapter, - MappingContext< - ? extends KeyValuePersistentEntity, ? extends KeyValuePersistentProperty> - mappingContext, - IdentifierGenerator identifierGenerator) { - super(adapter, mappingContext, identifierGenerator); - } - - @Override - public T insert(T objectToInsert) { - if (DefaultIdClassResolver.INSTANCE.resolveIdClassType(objectToInsert.getClass()) == null) { - return super.insert(objectToInsert); - } - - PersistentEntity entity = - getMappingContext().getRequiredPersistentEntity(ClassUtils.getUserClass(objectToInsert)); - - IdentifierAccessor identifierAccessor = entity.getIdentifierAccessor(objectToInsert); - Object id = identifierAccessor.getRequiredIdentifier(); - return insert(id, objectToInsert); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/annotation/DefaultIdClassResolver.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/annotation/DefaultIdClassResolver.java deleted file mode 100644 index 838750eb..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/annotation/DefaultIdClassResolver.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.core.annotation; - -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.core.annotation.IdClassResolver; - -/** Default implementation of {@link IdClassResolver}. */ -public enum DefaultIdClassResolver implements IdClassResolver { - INSTANCE; - - public static final String ANNOTATION_TYPE_EXCEPTION = - "The class of a composite identifier specified in the @IdClass annotation cannot be" - + " annotation!"; - - @Nullable - @Override - public Class resolveIdClassType(Class type) { - Assert.notNull(type, "Type for IdClass must be not null!"); - - IdClass idClassTypeAnnotation = AnnotatedElementUtils.findMergedAnnotation(type, IdClass.class); - - if (idClassTypeAnnotation == null) { - return null; - } - - Class idClassTypeValue = idClassTypeAnnotation.value(); - Assert.isTrue(!idClassTypeValue.isAnnotation(), ANNOTATION_TYPE_EXCEPTION); - - return idClassTypeValue; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/annotation/package-info.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/annotation/package-info.java deleted file mode 100644 index 3c0bdf42..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/annotation/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Core annotations of data mapping. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data34.core.annotation; diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/BasicKeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/BasicKeyValueCompositePersistentEntity.java deleted file mode 100644 index 0fb87b92..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/BasicKeyValueCompositePersistentEntity.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.core.mapping; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.data.domain.Persistable; -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.support.IsNewStrategy; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.mapping.model.CompositeKey; -import io.tarantool.spring.data34.core.mapping.model.CompositeIdPropertyAccessor; -import io.tarantool.spring.data34.core.mapping.model.PersistentCompositeIdIsNewStrategy; - -public class BasicKeyValueCompositePersistentEntity> - extends BasicKeyValuePersistentEntity implements KeyValueCompositePersistentEntity { - - public static final String TYPE_MISMATCH = - "Target bean of type %s is not of type of the persistent entity (%s)"; - - private final Class idClassTypeValue; - private @Nullable P idProperty; - - private Map entityIdClassFields; - - /** - * @param information must not be {@literal null}. - * @param fallbackKeySpaceResolver can be {@literal null}. - * @param idClassTypeValue class that specified in {@link IdClass} - */ - public BasicKeyValueCompositePersistentEntity( - TypeInformation information, - @Nullable KeySpaceResolver fallbackKeySpaceResolver, - Class idClassTypeValue) { - super(information, fallbackKeySpaceResolver); - - Assert.notNull(idClassTypeValue, "idClassTypeValue must be not null for this class!"); - this.idClassTypeValue = idClassTypeValue; - } - - @Override - public IdentifierAccessor getIdentifierAccessor(Object bean) { - verifyBeanType(bean); - - if (Persistable.class.isAssignableFrom(getType())) { - throw new IllegalArgumentException( - "Persistable override is not currently supported for entities with a composite key."); - } - - return hasIdProperty() - ? new CompositeIdPropertyAccessor(bean, this.entityIdClassFields, getIdClassType()) - : new AbsentIdentifierAccessor(); - } - - @Override - public Class getIdClassType() { - return this.idClassTypeValue; - } - - @Override - public void verify() { - super.verify(); - - if (this.idProperty != null) { - this.entityIdClassFields = KeyPartTypeChecker.getFieldMapIfTypesValid(this, this.idProperty); - } - } - - @Override - protected IsNewStrategy getFallbackIsNewStrategy() { - return PersistentCompositeIdIsNewStrategy.of(this); - } - - @Override - protected P returnPropertyIfBetterIdPropertyCandidateOrNull(P property) { - Assert.isInstanceOf(Identifier.class, property, "property must be Identifier for this class"); - - if (!property.isIdProperty()) { - return null; - } - - if (this.idProperty == null) { - this.idProperty = property; - return this.idProperty; - } - - this.idProperty.addPart(property); - - return this.idProperty; - } - - /** - * Verifies the given bean type to no be {@literal null} and of the type of the current {@link - * PersistentEntity}. - * - * @param bean must not be {@literal null}. - */ - private void verifyBeanType(Object bean) { - - Assert.notNull(bean, "Target bean must not be null"); - Assert.isInstanceOf( - getType(), - bean, - () -> String.format(TYPE_MISMATCH, bean.getClass().getName(), getType().getName())); - } - - /** - * A null-object implementation of {@link IdentifierAccessor} to be able to return an accessor for - * entities that do not have an identifier property. - */ - private static class AbsentIdentifierAccessor implements IdentifierAccessor { - - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.IdentifierAccessor#getIdentifier() - */ - @Override - @Nullable - public Object getIdentifier() { - return null; - } - } - - /** - * A class that checks the types of fields of a composite key. In addition, the correspondence - * between types and field names marked with {@code @Id}. - */ - public static class KeyPartTypeChecker { - - public static final String COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION = - "Number of fields specified in domain class and composite class the key is different!"; - - public static final String COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION = - "Domain class fields marked with @Id differ from fields specified in the composite key" - + " class"; - - /** - * Check the number and types of entity fields, annotated {@code @Id} and fields {@link - * CompositeKey} and if the types and quantities match return the id part fields mapping. - * - * @param persistentEntity persistent entity - * @param idProperty id property - * @return mapping between fields of composite key class and fields annotated {@code @Id} in - * entity. - */ - public static Map getFieldMapIfTypesValid( - KeyValueCompositePersistentEntity persistentEntity, Identifier idProperty) { - Map entityIdClassFields = new HashMap<>(); - - List compositeKeyFields = persistentEntity.getIdClassTypeFields(); - - Field[] entityFields = idProperty.getFields(); - - if (compositeKeyFields.size() != entityFields.length) { - throw new IllegalArgumentException(COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION); - } - - for (int i = 0; i < compositeKeyFields.size(); i++) { - Field compositeKeyField = compositeKeyFields.get(i); - Field entityField = entityFields[i]; - - if (!equalFields(compositeKeyField, entityField)) { - throw new IllegalArgumentException(COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION); - } - - entityIdClassFields.put(entityField, compositeKeyField); - } - return entityIdClassFields; - } - - /** - * Compares two class fields by name and type. - * - * @param firstField first field - * @param secondField second field - * @return true if fields are equal - */ - private static boolean equalFields(Field firstField, Field secondField) { - return firstField.getName().equals(secondField.getName()) - && firstField.getType().equals(secondField.getType()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/Identifier.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/Identifier.java deleted file mode 100644 index 994365b1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/Identifier.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.core.mapping; - -import java.lang.reflect.Field; -import java.util.Collection; - -import org.springframework.data.mapping.PersistentProperty; - -/** The interface of the identifier class that will contain information about the composite key. */ -public interface Identifier

> { - - /** - * Add a {@link PersistentProperty} tagged with {@code Id}. - * - * @param property {@link PersistentProperty} tagged {@code Id} - */ - void addPart(P property); - - /** - * Return the parts of a composite key that are {@link PersistentProperty}. - * - * @return parts of a composite key - */ - Collection

getParts(); - - /** - * Return a list {@link Field} of fields that are annotated {@code @Id}. Unlike method {@link - * #getParts()} this method returns an array {@link Field}, where {@link Field} is taken from each - * element of the collection returned by the {@link #getParts()} method. Necessary in order not to - * write polluting code. - * - * @return fields of a composite key - */ - Field[] getFields(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/KeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/KeyValueCompositePersistentEntity.java deleted file mode 100644 index 41128b67..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/KeyValueCompositePersistentEntity.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.core.mapping; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.model.MutablePersistentEntity; - -import io.tarantool.spring.data.core.annotation.IdClass; - -/** - * An interface to enable {@link PersistentEntity}-specific operations with a composite key. - * - * @param domain class type - * @param

{@link PersistentProperty} type - */ -public interface KeyValueCompositePersistentEntity> - extends MutablePersistentEntity { - - /** - * Returns the fields of the class specified in the {@link IdClass} annotation. - * - * @return all fields that are in composite key class - */ - default List getIdClassTypeFields() { - List fields = new ArrayList<>(); - - for (Field field : getIdClassType().getDeclaredFields()) { - if (!field.isSynthetic()) { - fields.add(field); - } - } - return fields; - } - - /** - * Returns the type of the class specified in the {@link IdClass} annotation. - * - * @return class that specified in {@link IdClass} - */ - Class getIdClassType(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/KeyValueCompositeProperty.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/KeyValueCompositeProperty.java deleted file mode 100644 index 2617adb8..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/KeyValueCompositeProperty.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.core.mapping; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; - -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.util.Assert; - -public class KeyValueCompositeProperty

> - extends KeyValuePersistentProperty

implements Identifier

{ - - private final List

identifierPartsWithoutFirst; - - public KeyValueCompositeProperty( - Property property, PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - super(property, owner, simpleTypeHolder); - this.identifierPartsWithoutFirst = new ArrayList<>(); - } - - @Override - public void addPart(P property) { - Assert.notNull(property, "property must be not null"); - - if (equals(property) || this.identifierPartsWithoutFirst.contains(property)) { - return; - } - this.identifierPartsWithoutFirst.add(property); - } - - @Override - @SuppressWarnings("unchecked") - public Collection

getParts() { - List

resultList = new ArrayList<>(this.identifierPartsWithoutFirst); - resultList.add(0, (P) this); - - return resultList; - } - - @Override - public Field[] getFields() { - int totalSize = this.identifierPartsWithoutFirst.size() + 1; - - final Field[] fields = new Field[totalSize]; - fields[0] = getField(); - - for (int i = 1; i < totalSize; i++) { - fields[i] = this.identifierPartsWithoutFirst.get(i - 1).getField(); - } - return fields; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - KeyValueCompositeProperty other = (KeyValueCompositeProperty) o; - - if (this.identifierPartsWithoutFirst.isEmpty() && other.identifierPartsWithoutFirst.isEmpty()) { - return super.equals(o); - } - - if (this.identifierPartsWithoutFirst.size() != other.identifierPartsWithoutFirst.size() - || !other.getProperty().equals(getProperty())) { - return false; - } - - for (int i = 0; i < this.identifierPartsWithoutFirst.size(); i++) { - // take Property from both parts - Property thisKeyPartProperty = - ((KeyValueCompositeProperty) this.identifierPartsWithoutFirst.get(i)).getProperty(); - Property otherKeyPartProperty = - ((KeyValueCompositeProperty) other.identifierPartsWithoutFirst.get(i)).getProperty(); - - if (!thisKeyPartProperty.equals(otherKeyPartProperty)) { - return false; - } - } - return true; - } - - @Override - public int hashCode() { - int hashCode = super.hashCode(); - - if (this.identifierPartsWithoutFirst.isEmpty()) { - return hashCode; - } - - // sublist to avoid endless recursion - return Objects.hash(hashCode, this.identifierPartsWithoutFirst); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/TarantoolMappingContext.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/TarantoolMappingContext.java deleted file mode 100644 index 7e913f6e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/TarantoolMappingContext.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.core.mapping; - -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; - -import io.tarantool.spring.data.core.annotation.IdClassResolver; -import io.tarantool.spring.data34.core.annotation.DefaultIdClassResolver; - -public class TarantoolMappingContext< - E extends KeyValuePersistentEntity, P extends KeyValuePersistentProperty

> - extends KeyValueMappingContext { - - private final IdClassResolver idClassResolver; - - private @Nullable KeySpaceResolver keySpaceResolver; - - public TarantoolMappingContext() { - super(); - this.idClassResolver = DefaultIdClassResolver.INSTANCE; - } - - @Override - public void setKeySpaceResolver(KeySpaceResolver keySpaceResolver) { - super.setKeySpaceResolver(keySpaceResolver); - this.keySpaceResolver = keySpaceResolver; - } - - @SuppressWarnings("unchecked") - @Override - protected E createPersistentEntity(TypeInformation typeInformation) { - final Class idClassTypeValue = - this.idClassResolver.resolveIdClassType(typeInformation.getType()); - if (idClassTypeValue == null) { - return (E) new BasicKeyValuePersistentEntity(typeInformation, this.keySpaceResolver); - } - return (E) - new BasicKeyValueCompositePersistentEntity<>( - typeInformation, this.keySpaceResolver, idClassTypeValue); - } - - @SuppressWarnings("unchecked") - @Override - protected P createPersistentProperty( - Property property, E owner, SimpleTypeHolder simpleTypeHolder) { - if (KeyValueCompositePersistentEntity.class.isAssignableFrom(owner.getClass())) { - return (P) new KeyValueCompositeProperty<>(property, owner, simpleTypeHolder); - } - return (P) new KeyValuePersistentProperty<>(property, owner, simpleTypeHolder); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/model/CompositeIdPropertyAccessor.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/model/CompositeIdPropertyAccessor.java deleted file mode 100644 index 78611f28..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/model/CompositeIdPropertyAccessor.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.core.mapping.model; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.util.Map; - -import org.springframework.data.mapping.TargetAwareIdentifierAccessor; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -/** Class that allows to convert {@code @Id} annotated fields in an entity into a composite key. */ -public class CompositeIdPropertyAccessor extends TargetAwareIdentifierAccessor { - - private final Map entityIdClassFields; - - private final Class idClassType; - - private final Object target; - - public CompositeIdPropertyAccessor( - Object target, @NonNull Map entityIdClassFields, Class idClassType) { - - super(target); - this.target = target; - this.entityIdClassFields = entityIdClassFields; - this.idClassType = idClassType; - } - - @Nullable - public Object getIdentifier() { - try { - return generateIdentifier(); - } catch (InstantiationException - | IllegalAccessException - | NoSuchMethodException - | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - /** - * Generates a composite identifier from those marked with the {@code @Id} annotation in a domain - * class based on fields, specified in the composite key class. - * - * @return identifier - * @throws IllegalAccessException if the class or its nullary constructor is not accessible. - * @throws InstantiationException if this {@code Class} represents an abstract class, an - * interface, an array class, a primitive type, or void; or if the class has no nullary - * constructor; or if the instantiation fails for some other reason. - */ - private Object generateIdentifier() - throws InstantiationException, - IllegalAccessException, - NoSuchMethodException, - InvocationTargetException { - Assert.notNull(this.target, "target object must be not null!"); - Object compositeKey = idClassType.getDeclaredConstructor().newInstance(); - for (Map.Entry fieldPair : this.entityIdClassFields.entrySet()) { - writeValuesFromEntityId(compositeKey, fieldPair.getKey(), fieldPair.getValue()); - } - return compositeKey; - } - - /** - * Write the composite primary key fields provided in the entity to the class which implements - * {@link CompositeKey}. - * - * @param compositeKey object of the composite key into which the values are written. - * @param entityField field from the represented entity. - * @param compositeKeyField field from the composite key class. - */ - private void writeValuesFromEntityId( - Object compositeKey, Field entityField, Field compositeKeyField) { - ReflectionUtils.makeAccessible(entityField); - ReflectionUtils.makeAccessible(compositeKeyField); - - Object value = ReflectionUtils.getField(entityField, this.target); - ReflectionUtils.setField(compositeKeyField, compositeKey, value); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/model/PersistentCompositeIdIsNewStrategy.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/model/PersistentCompositeIdIsNewStrategy.java deleted file mode 100644 index f82fdeda..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/model/PersistentCompositeIdIsNewStrategy.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.core.mapping.model; - -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.support.IsNewStrategy; -import org.springframework.util.Assert; - -/** - * Strategy class for entity with composite key to determine whether a given entity is to be - * considered new. - */ -public class PersistentCompositeIdIsNewStrategy implements IsNewStrategy { - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} for the given entity. - * - * @param entity must not be {@literal null}. - * @param idOnly check only id to determine - */ - private PersistentCompositeIdIsNewStrategy(PersistentEntity entity, boolean idOnly) { - // TODO сделать реализацию версионирования - // TODO add idOnly support - Assert.notNull(entity, "PersistentEntity must not be null"); - } - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} to only consider the identifier of the - * given entity. - * - * @param entity must not be {@literal null}. - * @return strategy to determine whether entity is new or not - */ - public static PersistentCompositeIdIsNewStrategy forIdOnly(PersistentEntity entity) { - return new PersistentCompositeIdIsNewStrategy(entity, true); - } - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} to consider version properties before - * falling back to the identifier. - * - * @param entity must not be {@literal null}. - * @return strategy to determine whether entity is new or not - */ - public static PersistentCompositeIdIsNewStrategy of(PersistentEntity entity) { - return new PersistentCompositeIdIsNewStrategy(entity, false); - } - - /** - * Determine whether the current domain entity type object is new. Currently stub and always - * returns false. - * - * @param entity must not be {@literal null}. - * @return result of the question of entity is new or not - */ - @Override - public boolean isNew(Object entity) { - return false; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/model/package-info.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/model/package-info.java deleted file mode 100644 index abd8754d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/model/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Core implementation of the mapping subsystem's model. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data34.core.mapping.model; diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/package-info.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/package-info.java deleted file mode 100644 index ee671716..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/mapping/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Base package for the mapping subsystem. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data34.core.mapping; diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/package-info.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/package-info.java deleted file mode 100644 index 797497c3..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/core/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Core package for integrating Tarantool with Spring - * concepts. - */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data34.core; diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/Field.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/Field.java deleted file mode 100644 index b5e3436b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/Field.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.core.annotation.AliasFor; - -/** - * Allows adding some metadata to the class fields relevant for storing them in the Tarantool space - * - * @author Artyom Dubinin - */ -@Inherited -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) -public @interface Field { - - /** - * The target Tarantool space field for storing the marked class field. Alias for {@link #name()}. - * - * @return the name of a field in space - */ - @AliasFor("name") - String value() default ""; - - /** - * The target Tarantool space field for storing the marked class field. Alias for {@link - * #value()}. - * - * @return the name of a field in space - */ - @AliasFor("value") - String name() default ""; - - /** - * The order in which fields shall be stored in the tuple. Has to be a positive integer. - * - * @return the order the field shall have in the tuple or -1 if undefined. - */ - int order() default -1; -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/PaginationUtils.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/PaginationUtils.java deleted file mode 100644 index 55859680..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/PaginationUtils.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.keyvalue.core.IterableConverter; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class PaginationUtils { - - private static final String CRITERIA_NULL_EXC_MSG = "TarantoolCriteria must be not null"; - - /** - * Returns {@link TarantoolPageable} cast from {@link Pageable} with type checking. - * - * @param sliceParams pageable - * @return {@link TarantoolPageable} - */ - public static TarantoolPageable castToTarantoolPageable(Pageable sliceParams) { - Assert.isInstanceOf(TarantoolPageable.class, sliceParams, "Pageable must be TarantoolPageable"); - return (TarantoolPageable) sliceParams; - } - - /** - * A general method for retrieving data for paginated queries. - * - * @param query query - * @param pageRequest {@link TarantoolPageable} - * @param pageSize page size - * @return selection result. - */ - public static List doPaginationQuery( - final KeyValueQuery query, - TarantoolPageable pageRequest, - int pageSize, - KeyValueOperations keyValueOperations, - Class targetType) { - - TarantoolCriteria criteria = (TarantoolCriteria) query.getCriteria(); - PaginationDirection paginationDirection = pageRequest.getPaginationDirection(); - - Assert.notNull(criteria, CRITERIA_NULL_EXC_MSG); - criteria.withAfter(pageRequest.getTupleCursor()); - - query.setRows(pageSize * paginationDirection.getMultiplier()); - - return IterableConverter.toList(keyValueOperations.find(query, targetType)); - } - - public static Page doPageQuery( - Pageable pageable, - KeyValueQuery query, - KeyValueOperations keyValueOperations, - Class targetType) { - if (pageable.isUnpaged()) { - return new TarantoolPageImpl<>(); - } - TarantoolPageable resultSliceParams = castToTarantoolPageable(pageable); - - int pageSize = resultSliceParams.getPageSize(); - - // non transactional calls - List content = - doPaginationQuery(query, resultSliceParams, pageSize, keyValueOperations, targetType); - - if (content.isEmpty()) { - return new TarantoolPageImpl<>(); - } - - long totalElements = keyValueOperations.count(query, targetType); - return new TarantoolPageImpl<>(content, resultSliceParams, totalElements); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolChunk.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolChunk.java deleted file mode 100644 index c6c61e26..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolChunk.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -/** - * A chunk of data restricted by the configured {@link Pageable} for Tarantool. - * - * @author Nikolay Belonogov - */ -abstract class TarantoolChunk implements Slice, Serializable { - - private static final long serialVersionUID = 867755909294344406L; - - private final List content = new ArrayList<>(); - - private final Pageable pageable; - - /** - * Creates a new {@link TarantoolChunk} with the given content and the given governing {@link - * TarantoolPageable}. - * - * @param content must not be {@literal null}. - * @param pageable must not be {@literal null}. - */ - public TarantoolChunk(List content, Pageable pageable) { - - Assert.notNull(content, "Content must not be null"); - Assert.notNull(pageable, "Pageable must not be null"); - - if (pageable.isPaged() && !(pageable instanceof TarantoolPageable)) { - throw new IllegalArgumentException("Pageable must be TarantoolPageable or Unpaged type"); - } - - this.content.addAll(content); - this.pageable = pageable; - } - - @Override - public boolean isFirst() { - return !hasPrevious(); - } - - @Override - public boolean isLast() { - return !hasNext(); - } - - @Override - public boolean hasPrevious() { - return getNumber() > 0 && hasContent(); - } - - @Override - public boolean hasContent() { - return !content.isEmpty(); - } - - /** - * Returns the {@link Pageable} to request the next {@link Slice}. Can be {@link - * Pageable#unpaged()} in case the current {@link Slice} is already the last one or when data - * content is empty. Clients should check {@link #hasNext()} and {@link #hasContent()} before - * calling this method. - * - * @see #nextOrLastPageable() - */ - @NonNull - @Override - @SuppressWarnings("unchecked") - public Pageable nextPageable() { - if (hasNext() && pageable.isPaged()) { - return ((TarantoolPageable) pageable).next(content.get(content.size() - 1)); - } - return Pageable.unpaged(); - } - - /** - * Returns the {@link Pageable} to request the previous {@link Slice}. Can be {@link - * Pageable#unpaged()} in case the current {@link Slice} is already the first one or data content - * is empty. Clients should check {@link #hasPrevious()} and {@link #hasContent()} before calling - * this method. - * - * @see #previousOrFirstPageable() - */ - @NonNull - @Override - @SuppressWarnings("unchecked") - public Pageable previousPageable() { - if (hasPrevious() && pageable.isPaged()) { - return ((TarantoolPageable) pageable).previousOrFirst(content.get(0)); - } - return Pageable.unpaged(); - } - - @Override - public Iterator iterator() { - return content.iterator(); - } - - @NonNull - @Override - public List getContent() { - return Collections.unmodifiableList(content); - } - - @NonNull - @Override - public Pageable getPageable() { - return pageable; - } - - @NonNull - @Override - public Sort getSort() { - return pageable.getSort(); - } - - @Override - public int getNumber() { - if (pageable.isPaged()) { - return pageable.getPageNumber(); - } - return 0; - } - - @Override - public int getSize() { - if (pageable.isPaged()) { - return pageable.getPageSize(); - } - return content.size(); - } - - @Override - public int getNumberOfElements() { - return content.size(); - } - - /** - * Applies the given {@link Function} to the content of the {@link TarantoolChunk}. - * - * @param converter must not be {@literal null}. - */ - protected List getConvertedContent(Function converter) { - - Assert.notNull(converter, "Function must not be null"); - - return this.stream().map(converter).collect(Collectors.toList()); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolChunk)) { - return false; - } - TarantoolChunk that = (TarantoolChunk) o; - return content.equals(that.content) && pageable.equals(that.pageable); - } - - @Override - public int hashCode() { - return Objects.hash(content, pageable); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolCriteriaAccessor.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolCriteriaAccessor.java deleted file mode 100644 index e6a45b03..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolCriteriaAccessor.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import org.springframework.data.keyvalue.core.CriteriaAccessor; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -import io.tarantool.spring.data.query.TarantoolCriteria; - -/** - * Provide a mechanism to convert the abstract query into the direct implementation in Tarantool. - * - * @author Artyom Dubinin - */ -public class TarantoolCriteriaAccessor implements CriteriaAccessor { - - /** - * @param query in Spring form - * @return The same in Tarantool form - */ - public TarantoolCriteria resolve(KeyValueQuery query) { - return (TarantoolCriteria) query.getCriteria(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolKeysetScrollPosition.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolKeysetScrollPosition.java deleted file mode 100644 index f550164d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolKeysetScrollPosition.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.util.List; -import java.util.Objects; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.Pair; - -final class TarantoolKeysetScrollPosition implements TarantoolScrollPosition { - - private final Pair indexKey; - - private final PaginationDirection direction; - - private final Object cursor; - - TarantoolKeysetScrollPosition( - Pair indexKey, PaginationDirection direction, @Nullable Object cursor) { - - Assert.notNull(direction, "PaginationDirection must not be null"); - Assert.notNull(indexKey, "indexKey must not be null"); - - this.indexKey = indexKey; - this.direction = direction; - this.cursor = cursor; - } - - /** - * Creates a new {@link TarantoolKeysetScrollPosition} from a key set and {@link - * PaginationDirection}. - * - * @param indexKey must not be {@literal null}. - * @return will never be {@literal null}. - */ - static TarantoolScrollPosition forward(Pair indexKey) { - return new TarantoolKeysetScrollPosition(indexKey, FORWARD, null); - } - - static TarantoolScrollPosition backward(Pair indexKey) { - return new TarantoolKeysetScrollPosition(indexKey, BACKWARD, null); - } - - /** - * Returns whether the current scroll position is the initial one (from begin or from end) (see - * {@link PaginationDirection}). - * - * @return {@link Boolean} object. - */ - @Override - public boolean isInitial() { - if (indexKey.getSecond() instanceof List startingList) { - return startingList.isEmpty() && cursor == null; - } - return false; - } - - @Override - public TarantoolScrollPosition reverse() { - Pair newIndexKey = Pair.of(indexKey.getFirst(), indexKey.getSecond()); - return new TarantoolKeysetScrollPosition(newIndexKey, direction.reverse(), cursor); - } - - @Override - public boolean isScrollsBackward() { - return direction.equals(BACKWARD); - } - - /** - * Return the cursor relative to which the data is being found. - * - * @return returns cursor - */ - Object getCursor() { - return cursor; - } - - /** - * @return the scroll direction. - */ - PaginationDirection getDirection() { - return direction; - } - - /** - * @return the indexKey. - */ - Pair getIndexKey() { - return indexKey; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolKeysetScrollPosition that)) { - return false; - } - return indexKey.equals(that.indexKey) - && direction == that.direction - && Objects.equals(cursor, that.cursor); - } - - @Override - public int hashCode() { - return Objects.hash(indexKey, direction, cursor); - } - - @Override - public String toString() { - return String.format("TarantoolKeysetScrollPosition [%s, %s, %s]", direction, indexKey, cursor); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolPageImpl.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolPageImpl.java deleted file mode 100644 index da226752..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolPageImpl.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.io.Serial; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.lang.NonNull; - -/** - * Basic {@code Page} implementation for Tarantool. - * - * @param domain class type. - * @author Nikolay Belonogov - */ -class TarantoolPageImpl extends TarantoolChunk implements Page { - - @Serial private static final long serialVersionUID = 867755909294344406L; - - private final long total; - - /** - * Creates a new {@link TarantoolPageImpl} with empty content. This will result in the created - * {@link Page} being identical to the entire {@link List}. - */ - public TarantoolPageImpl() { - this(Collections.emptyList(), Pageable.unpaged(), 0L); - } - - /** - * Creates a new {@link TarantoolPageImpl} with the given content. This will result in the created - * {@link Page} being identical to the entire {@link List}. - * - * @param content must not be {@literal null}. - */ - public TarantoolPageImpl(List content) { - this(content, Pageable.unpaged(), content == null ? 0L : content.size()); - } - - /** - * Constructor of {@link TarantoolPageImpl}. - * - * @param content the content of this page, must not be {@literal null}. - * @param pageable the paging information, must not be {@literal null}. - * @param total the total amount of items available. The total might be adapted considering the - * length of the content given, if it is going to be the content of the last page. This is in - * place to mitigate inconsistencies. - */ - public TarantoolPageImpl(List content, Pageable pageable, long total) { - - super(content, pageable); - - this.total = - pageable - .toOptional() - .filter(it -> !content.isEmpty()) - .filter(it -> it.getOffset() + it.getPageSize() > total) - .map(it -> it.getOffset() + content.size()) - .orElse(total); - } - - @Override - public int getTotalPages() { - return getSize() == 0 ? 1 : (int) Math.ceil((double) total / (double) getSize()); - } - - @Override - public long getTotalElements() { - return total; - } - - @Override - public boolean hasNext() { - return getNumber() + 1 < getTotalPages() && hasContent(); - } - - @Override - public boolean isLast() { - return !hasNext(); - } - - @Override - @NonNull - public Page map(@NonNull Function converter) { - return new PageImpl<>(getConvertedContent(converter), getPageable(), total); - } - - @Override - public String toString() { - - List content = getContent(); - boolean canGetContentType = !content.isEmpty() && content.get(0) != null; - - String contentType = canGetContentType ? content.get(0).getClass().getName() : "UNKNOWN"; - - return String.format( - "Page %s of %d containing %s instances", getNumber() + 1, getTotalPages(), contentType); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolPageImpl that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return total == that.total; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), total); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolPageRequest.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolPageRequest.java deleted file mode 100644 index 5eb757c1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolPageRequest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.io.Serial; -import java.util.Objects; - -import org.springframework.data.domain.AbstractPageRequest; -import org.springframework.data.domain.Sort; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; - -/** - * Basic implementation of {@link TarantoolPageable} for Tarantool. - * - *

Important: When specifying a cursor tuple, you must adhere to the following - * rules: - * - *

1. To specify a page starting from the beginning of {@code space} (the first element of the - * page is the first element found in {@code space}), use {@code tupleCursor == null}. - * - *

2. To specify an arbitrary page (the first element of the page is the next/previous one from - * the given one tuple cursor depending on the methods used and page number), use {@code tupleCursor - * == someTupleCursor} . - * - * @param domain entity type - */ -public final class TarantoolPageRequest extends AbstractPageRequest - implements TarantoolPageable { - - @Serial private static final long serialVersionUID = -4541509938956089562L; - - private final Sort sort; - - private final T tupleCursor; - - private final PaginationDirection paginationDirection; - - /** - * Creates a new unsorted {@link TarantoolPageRequest} from begin of {@code space}. - * - * @param pageSize the size of the page to be returned, must be greater than 0. - */ - public TarantoolPageRequest(int pageSize) { - this(0, pageSize, null); - } - - /** - * Creates a new unsorted {@link TarantoolPageRequest}. - * - *

Important: Use this method with caution! It is important to know the exact - * match of number pages and the tuple after (before) which the page goes (without including this - * tuple in the page itself). A mistake in compliance results in the appearance of blank pages - * with unpaged pageable even when using methods {@link - * TarantoolPageImpl#previousOrFirstPageable()} / {@link TarantoolPageImpl#nextOrLastPageable()} - * and {@link TarantoolSliceImpl#previousOrFirstPageable()} / {@link - * TarantoolSliceImpl#nextOrLastPageable()}. - * - * @param page zero-based page index (virtual), must not be negative. - * @param size the size of the page to be returned, must be greater than 0. - * @param tupleCursor tuple cursor from which the page count begins. More: {@link - * TarantoolPageRequest}. - */ - public TarantoolPageRequest(int page, int size, T tupleCursor) { - this(page, size, Sort.unsorted(), tupleCursor, FORWARD); - } - - /** - * Private constructor to create an instance with a specific {@link PaginationDirection}. - * - * @param page zero-based page index, must not be negative. - * @param size the size of the page to be returned, must be greater than 0. - * @param sort must not be {@literal null}, use {@link Sort#unsorted()} instead. - * @param tupleCursor tuple cursor from which the page count begins. More: {@link - * TarantoolPageRequest}. - * @param direction direction of pagination. - */ - TarantoolPageRequest( - int page, int size, Sort sort, T tupleCursor, @NonNull PaginationDirection direction) { - super(page, size); - Assert.notNull(sort, "Sort must not be null"); - Assert.notNull(direction, "PaginationDirection must not be null"); - - this.sort = sort; - this.tupleCursor = tupleCursor; - this.paginationDirection = direction; - } - - /** Non supported for Tarantool. */ - @Override - @NonNull - public TarantoolPageRequest withPage(int pageNumber) throws UnsupportedOperationException { - throw new UnsupportedOperationException("method \"withPage(int pageNumber)\" unsupported"); - } - - @Override - @NonNull - public TarantoolPageable first() { - return new TarantoolPageRequest<>(getPageSize()); - } - - /** Non supported for Tarantool. Use {@link #next(Object)}. */ - @Override - @NonNull - public TarantoolPageRequest next() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"next()\" unsupported, use next(T nextTupleCursor)"); - } - - @Override - public TarantoolPageRequest next(T tupleCursor) { - return new TarantoolPageRequest<>( - getPageNumber() + 1, getPageSize(), getSort(), tupleCursor, FORWARD); - } - - /** Non supported for Tarantool. Use {@link #previous(Object)}. */ - @Override - @NonNull - public TarantoolPageRequest previous() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"previous()\" unsupported, use previous(T prevTupleCursor)"); - } - - private TarantoolPageRequest previous(T tupleCursor) { - if (hasPrevious()) { - return new TarantoolPageRequest<>( - getPageNumber() - 1, getPageSize(), getSort(), tupleCursor, BACKWARD); - } - return this; - } - - /** Non supported for Tarantool. Use {@link #previousOrFirst(Object)}. */ - @Override - @NonNull - public TarantoolPageable previousOrFirst() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"previousOrFirst()\" unsupported, use previousOrFirst(T prevTupleCursor)"); - } - - @Override - public TarantoolPageable previousOrFirst(T tupleCursor) { - if (hasPrevious()) { - return previous(tupleCursor); - } - return new TarantoolPageRequest<>(0, getPageSize(), getSort(), null, BACKWARD); - } - - @Override - public PaginationDirection getPaginationDirection() { - return this.paginationDirection; - } - - @Override - @NonNull - public Sort getSort() { - return this.sort; - } - - @Override - public T getTupleCursor() { - return this.tupleCursor; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolPageRequest that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return sort.equals(that.sort) - && Objects.equals(tupleCursor, that.tupleCursor) - && paginationDirection == that.paginationDirection; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), sort, tupleCursor, paginationDirection); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolPageable.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolPageable.java deleted file mode 100644 index f2293f96..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolPageable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import org.springframework.data.domain.Pageable; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; - -import io.tarantool.spring.data.query.PaginationDirection; - -/** - * Abstract interface for pagination information in Tarantool. - * - * @param domain class type. - * @author Nikolay Belonogov - */ -public interface TarantoolPageable extends Pageable { - - /** - * Returns tuple cursor of domain type. Can be {@code null}. If the cursor is {@code null} then - * the page is counted from the first tuple in Tarantool. - * - * @return tuple cursor of domain type. - */ - @Nullable - T getTupleCursor(); - - /** - * Returns the {@link TarantoolPageable} for previous page or the {@link TarantoolPageable} for - * first page if the current one already is the first one. Important: this method - * always returns {@link TarantoolPageable} c {@link PaginationDirection#BACKWARD}. - * - * @param tupleCursor tuple cursor of domain type for previous page. - * @return {@link TarantoolPageable} instance. - */ - TarantoolPageable previousOrFirst(T tupleCursor); - - /** - * Returns the {@link TarantoolPageable} requesting the next {@link - * org.springframework.data.domain.Page}. - * - *

Important: method always creates a new {@link TarantoolPageable} with the - * same parameters Sort and page size. Pagination direction is {@link - * PaginationDirection#FORWARD}, the page number always has value {@code n+1}, n is the current - * page number. - * - * @param tupleCursor tuple cursor of domain type for next page. - * @return {@link TarantoolPageable} object - */ - TarantoolPageable next(T tupleCursor); - - /** - * Returns pagination direction by {@link PaginationDirection} enumeration. - * - * @return {@link PaginationDirection}. - */ - PaginationDirection getPaginationDirection(); - - /** - * Returns a {@link TarantoolPageable} that points to the first page with {@link - * PaginationDirection#FORWARD} pagination direction. - * - * @return {@link TarantoolPageable} which has {@code cursor == null}, page number is 0, the rest - * parameters are equivalent to the parameters of the current {@link TarantoolPageable}. - */ - @NonNull - TarantoolPageable first(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolPartTreeQuery.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolPartTreeQuery.java deleted file mode 100644 index d3c6391b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolPartTreeQuery.java +++ /dev/null @@ -1,506 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.springframework.data.domain.Limit; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; -import org.springframework.data.keyvalue.core.IterableConverter; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery; -import org.springframework.data.repository.query.Parameter; -import org.springframework.data.repository.query.Parameters; -import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.data.util.StreamUtils; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -import static io.tarantool.client.crud.ConditionOperator.GREATER_EQ; -import static io.tarantool.client.crud.ConditionOperator.LESS_EQ; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import static io.tarantool.spring.data34.query.PaginationUtils.doPageQuery; -import static io.tarantool.spring.data34.query.PaginationUtils.doPaginationQuery; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.query.TarantoolCriteria; -import io.tarantool.spring.data.utils.Pair; - -/** - * There is one instance for each query method defined for a repository, providing a query from the - * bind parameters. - * - * @author Artyom Dubinin - */ -public class TarantoolPartTreeQuery extends KeyValuePartTreeQuery { - - public static final String ILLEGAL_RETURN_TYPE_FOR_DELETE = - "Illegal returned type: %s. The operation 'deleteBy' accepts only 'long' and 'Collection' as" - + " the returned object type"; - public static final String QUERY_METHOD_S_NOT_SUPPORTED = "Query method '%s' not supported."; - private final QueryMethod queryMethod; - private final KeyValueOperations keyValueOperations; - private final PartTree tree; - - private final boolean isCount; - private final boolean isDelete; - private final boolean isDistinct; - private final boolean isExists; - private final Class targetType; - private final Class returnType; - - private boolean isRearrangeKnown; - private boolean isRearrangeRequired; - private int[] rearrangeIndex; - - private final List EMPTY_KEY = Collections.emptyList(); - - /** - * Create a {@link RepositoryQuery} implementation for each query method defined in a tarantool - * repository. - * - * @param queryMethod Method defined in Tarantool Repositories - * @param evaluationContextProvider Not used - * @param keyValueOperations Interface to Tarantool - * @param queryCreator Not used - */ - public TarantoolPartTreeQuery( - QueryMethod queryMethod, - QueryMethodEvaluationContextProvider evaluationContextProvider, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - super(queryMethod, evaluationContextProvider, keyValueOperations, queryCreator); - this.queryMethod = queryMethod; - this.keyValueOperations = keyValueOperations; - this.isRearrangeKnown = false; - this.targetType = queryMethod.getEntityInformation().getJavaType(); - this.returnType = queryMethod.getReturnedObjectType(); - this.tree = new PartTree(getQueryMethod().getName(), targetType); - if (queryMethod.getParameters().getNumberOfParameters() > 0) { - this.isCount = tree.isCountProjection(); - this.isDelete = tree.isDelete(); - this.isDistinct = tree.isDistinct(); - this.isExists = tree.isExistsProjection(); - } else { - this.isCount = false; - this.isDelete = false; - this.isDistinct = false; - this.isExists = false; - } - } - - /** - * Execute this query instance, using any invocation parameters. - * - *

Expecting {@code findBy...()}, {@code countBy...()} or {@code deleteBy...()} - * - * @param parameters Any parameters - * @return Query result - */ - @Override - public Object execute(@NonNull Object[] parameters) { - ParametersParameterAccessor accessor = this.prepareAccessor(parameters, tree); - - KeyValueQuery query = prepareQuery(accessor); - - if (this.isCount) { - if (this.isDistinct) { - final Iterable iterable = this.keyValueOperations.find(query, targetType); - return StreamUtils.createStreamFromIterator(iterable.iterator()).distinct().count(); - } - return this.keyValueOperations.count(query, targetType); - } - - if (this.isDelete) { - return this.executeDeleteQuery(query); - } - - if (this.isExists) { - query.setOffset(0); - query.setRows(1); - final Iterable result = this.keyValueOperations.find(query, targetType); - return result.iterator().hasNext(); - } - - if (queryMethod.isPageQuery()) { - return this.executePageQuery(query, accessor); - } - - if (queryMethod.isSliceQuery()) { - return this.executeSliceQuery(query, accessor); - } - - if (queryMethod.isScrollQuery()) { - return this.executeScrollQuery(query, accessor); - } - - if (queryMethod.isCollectionQuery() - || queryMethod.isQueryForEntity() - || queryMethod.isStreamQuery()) { - return this.executeFindQuery(query); - } - - throw new UnsupportedOperationException( - String.format(QUERY_METHOD_S_NOT_SUPPORTED, queryMethod.getName())); - } - - /** - * Execute a "delete" query, not really a query more of an operation. - * - *

- * - * @param query The query to run - * @return Collection of deleted objects or the number of deleted objects - */ - private Object executeDeleteQuery(final KeyValueQuery query) { - - Iterable resultSet = this.keyValueOperations.find(query, targetType); - Iterator iterator = resultSet.iterator(); - - List result = new ArrayList<>(); - while (iterator.hasNext()) { - result.add(this.keyValueOperations.delete(iterator.next())); - } - - if (queryMethod.isCollectionQuery()) { - return result; - } - if (long.class.equals(returnType) || Long.class.equals(returnType)) { - return result.size(); - } - throw new UnsupportedOperationException( - String.format(ILLEGAL_RETURN_TYPE_FOR_DELETE, returnType)); - } - - /** - * Execute a retrieval query. The query engine will return this in an iterator, which may need - * conversion to a single domain entity or a stream. - * - * @param query The query to run - * @return Query result - */ - private Object executeFindQuery(final KeyValueQuery query) { - - Iterable resultSet = this.keyValueOperations.find(query, targetType); - - if (!queryMethod.isCollectionQuery() - && !queryMethod.isPageQuery() - && !queryMethod.isSliceQuery() - && !queryMethod.isStreamQuery()) { - // Singleton result - return resultSet.iterator().hasNext() ? resultSet.iterator().next() : null; - } - - Stream stream = StreamUtils.createStreamFromIterator(resultSet.iterator()); - if (this.isDistinct) { - stream = stream.distinct(); - } - - if (queryMethod.isStreamQuery()) { - return stream; - } - - // optimization: - // we can omit if condition - // but this will recreate result even if it's not distinct and isn't stream query - if (this.isDistinct) { - return stream.collect(Collectors.toList()); - } - - return resultSet; - } - - private Object executeScrollQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - ScrollPosition scrollPosition = accessor.getScrollPosition(); - - Assert.notNull( - scrollPosition, - "The ScrollPosition parameter must be specified. Method: " + queryMethod.getName()); - - if (!(scrollPosition instanceof TarantoolKeysetScrollPosition keysetScrollPosition)) { - throw new IllegalArgumentException( - "ScrollPosition must be an instance of TarantoolKeysetScrollPosition. Method: " - + queryMethod.getName()); - } - - int pageSize = query.getRows(); - List content = doScrollQuery(query, keysetScrollPosition, pageSize + 1); - - boolean hasNext = content.size() > pageSize; - - final List finalResult = getPaginationSubResult(content, pageSize, FORWARD, hasNext); - return Window.from( - finalResult, - value -> - new TarantoolKeysetScrollPosition( - keysetScrollPosition.getIndexKey(), - keysetScrollPosition.getDirection(), - finalResult.get(value)), - hasNext); - } - - private List doScrollQuery( - final KeyValueQuery query, TarantoolKeysetScrollPosition scrollPosition, int pageSize) { - TarantoolCriteria criteria = castToTarantoolCriteria(query.getCriteria()); - PaginationDirection paginationDirection = scrollPosition.getDirection(); - - Object cursor = scrollPosition.getCursor(); - Pair indexKey = scrollPosition.getIndexKey(); - - Object second = EMPTY_KEY; - if (cursor == null) { - second = indexKey.getSecond(); - } - - switch (paginationDirection) { - case FORWARD -> - criteria.addCondition(0, Condition.create(GREATER_EQ, indexKey.getFirst(), second)); - case BACKWARD -> - criteria.addCondition(0, Condition.create(LESS_EQ, indexKey.getFirst(), second)); - } - - criteria.withAfter(cursor); - query.setRows(pageSize); - return IterableConverter.toList(this.keyValueOperations.find(query, targetType)); - } - - /** - * Execute the slice request. - * - * @param query query - * @param accessor accessor - * @return slice selection result. - */ - private Object executePageQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - - Pageable pageParams = accessor.getPageable(); - - return doPageQuery(pageParams, query, this.keyValueOperations, targetType); - } - - private Object executeSliceQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - - Pageable sliceParams = accessor.getPageable(); - - if (sliceParams.isUnpaged()) { - return new TarantoolSliceImpl<>(Collections.emptyList()); - } - - TarantoolPageable resultSliceParams = castToTarantoolPageable(sliceParams); - - int pageSize = resultSliceParams.getPageSize(); - - List content = - doPaginationQuery( - query, resultSliceParams, pageSize + 1, this.keyValueOperations, targetType); - - if (content.isEmpty()) { - return new TarantoolSliceImpl<>(); - } - - boolean hasNext = content.size() > resultSliceParams.getPageSize(); - PaginationDirection paginationDirection = resultSliceParams.getPaginationDirection(); - - List result = getPaginationSubResult(content, pageSize, paginationDirection, hasNext); - return new TarantoolSliceImpl<>(result, resultSliceParams, hasNext); - } - - /** - * Returns {@link TarantoolPageable} cast from {@link Pageable} with type checking. - * - * @param sliceParams pageable - * @return {@link TarantoolPageable} - */ - private TarantoolPageable castToTarantoolPageable(Pageable sliceParams) { - Assert.isInstanceOf(TarantoolPageable.class, sliceParams, "Pageable must be TarantoolPageable"); - return (TarantoolPageable) sliceParams; - } - - /** - * The method allows you to get {@link TarantoolCriteria} even when pagination is used through - * methods the base repository (not via derived methods). - * - * @param criteria criteria object - * @return An instance of {@link TarantoolCriteria}, or creates a new one if null. - */ - private TarantoolCriteria castToTarantoolCriteria(Object criteria) { - if (criteria == null) { - return new TarantoolCriteria(); - } - - if (!(criteria instanceof TarantoolCriteria)) { - throw new IllegalArgumentException("criteria must be instance of TarantoolCriteria"); - } - return (TarantoolCriteria) criteria; - } - - private List getPaginationSubResult( - List content, int pageSize, PaginationDirection direction, boolean hasNext) { - if (hasNext) { - switch (direction) { - case FORWARD -> { - return content.subList(0, pageSize); - } - case BACKWARD -> { - return content.subList(1, content.size()); - } - } - } - return content; - } - - /** - * Create the query from the bind parameters. - * - * @return A ready-to-use query - */ - @NonNull - protected KeyValueQuery prepareQuery(ParametersParameterAccessor accessor) { - KeyValueQuery query = createQuery(accessor); - - /* - If there is no limitation in the name of the method, we always put a - limit so that don't think about this in the engine, especially when distinguishing between a regular query and a - paginated query. - */ - if (!tree.isLimiting()) { - query.setRows(SelectOptions.DEFAULT_LIMIT); - } - - Limit limit = accessor.getLimit(); - if (limit.isLimited()) { - final int max = limit.max(); - if (max < 0) { - throw new IllegalArgumentException( - "The max number of potential results should be positive! Method: " - + queryMethod - + ". Limit: " - + max); - } - query.setRows(limit.max()); - } - - if (accessor.getSort() != Sort.unsorted()) { - query.setSort(accessor.getSort()); - } - - return query; - } - - /** - * Handle {@code @Param}. - * - *
    - *
  1. Without {@code @Param} - *

    Arguments to the call are assumed to follow the same sequence as cited in the method - * name.
    - * Eg. - *

    -   *     findByOneAndTwo(String one, String two);
    -   *     
    - *
  2. With {@code @Param} - *

    Arguments to the call are use the {@code @Param} to match them against the fields. - *

    Eg. - *

    -   *   findByOneAndTwo(@Param("two") String two, @Param("one") String one);
    -   *   
    - *
- * - * @param originalParameters Possibly empty - * @param partTree Query tree to traverse - * @return Parameters in correct order - */ - private ParametersParameterAccessor prepareAccessor( - final Object[] originalParameters, final PartTree partTree) { - - if (!this.isRearrangeKnown) { - this.prepareRearrange(partTree, this.queryMethod.getParameters().getBindableParameters()); - this.isRearrangeKnown = true; - } - - Object[] parameters = originalParameters; - Assert.notNull(parameters, "Parameters must not be null."); - - if (this.isRearrangeRequired) { - parameters = new Object[originalParameters.length]; - - for (int i = 0; i < parameters.length; i++) { - int index = (i < rearrangeIndex.length) ? rearrangeIndex[i] : i; - parameters[i] = originalParameters[index]; - } - } - - return new ParametersParameterAccessor(this.queryMethod.getParameters(), parameters); - } - - /** - * Determine if the arguments to the method need reordered. - * - *

For searches such as {@code findBySomethingNotNull} there may be more parts than parameters - * needed to be bound to them. - * - * @param partTree Query parts - * @param bindableParameters Parameters expected - */ - @SuppressWarnings("unchecked") - private void prepareRearrange( - final PartTree partTree, final Parameters bindableParameters) { - - this.isRearrangeRequired = false; - if (partTree == null || bindableParameters == null) { - return; - } - - List queryParams = new ArrayList<>(); - List methodParams = new ArrayList<>(); - - for (Part part : partTree.getParts()) { - queryParams.add(part.getProperty().getSegment()); - } - - Iterator bindableParameterIterator = - (Iterator) bindableParameters.iterator(); - while (bindableParameterIterator.hasNext()) { - Parameter parameter = bindableParameterIterator.next(); - parameter.getName().ifPresent(methodParams::add); - } - - this.rearrangeIndex = new int[queryParams.size()]; - - String[] paramsExpected = queryParams.toArray(new String[0]); - String[] paramsProvided = methodParams.toArray(new String[0]); - - for (int i = 0; i < this.rearrangeIndex.length; i++) { - this.rearrangeIndex[i] = i; - - for (int j = 0; j < paramsProvided.length; j++) { - if (paramsProvided[j] != null && paramsProvided[j].equals(paramsExpected[i])) { - this.rearrangeIndex[i] = j; - this.isRearrangeRequired = true; - } - } - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolQueryCreator.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolQueryCreator.java deleted file mode 100644 index e2d22cb4..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolQueryCreator.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.mapping.PropertyPath; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -import static io.tarantool.client.crud.ConditionOperator.EQ; -import static io.tarantool.client.crud.ConditionOperator.GREATER; -import static io.tarantool.client.crud.ConditionOperator.GREATER_EQ; -import static io.tarantool.client.crud.ConditionOperator.LESS; -import static io.tarantool.client.crud.ConditionOperator.LESS_EQ; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.ConditionOperator; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolQueryCreator - extends AbstractQueryCreator, TarantoolCriteria> { - - private final Map cache = new ConcurrentHashMap<>(); - - public static final String INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE = - "Logic error for '%s' in query. "; - - public TarantoolQueryCreator(PartTree tree, ParameterAccessor parameters) { - super(tree, parameters); - } - - private String getFieldName(Part part) { - PropertyPath property = part.getProperty(); - String segment = property.toDotPath(); - Class domainType = property.getOwningType().getType(); - java.lang.reflect.Field field = ReflectionUtils.findField(domainType, segment); - - if (field == null) { - throw new IllegalArgumentException("No such field: " + segment + " in " + domainType); - } - Field annotationField = field.getAnnotation(Field.class); - - if (annotationField != null) { - String value = annotationField.value(); - if (StringUtils.hasText(value)) { - return value; - } - String name = annotationField.name(); - if (StringUtils.hasText(name)) { - return name; - } - } - - return segment; - } - - @Override - @NonNull - protected TarantoolCriteria create(Part part, @NonNull Iterator iterator) { - final TarantoolCriteria tarantoolCriteria = new TarantoolCriteria(); - - Part.Type type = part.getType(); - if (isIgnoreCase(part)) { - throw new InvalidDataAccessApiUsageException( - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "IgnoreCase isn't supported yet", - type)); - } - String property = cache.computeIfAbsent(part, this::getFieldName); - - switch (type) { - case SIMPLE_PROPERTY: - generateConditions(tarantoolCriteria, type, property, iterator, EQ); - break; - case LESS_THAN: - case BEFORE: - generateConditions(tarantoolCriteria, type, property, iterator, LESS); - break; - case LESS_THAN_EQUAL: - generateConditions(tarantoolCriteria, type, property, iterator, LESS_EQ); - break; - case GREATER_THAN: - case AFTER: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER); - break; - case GREATER_THAN_EQUAL: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER_EQ); - break; - case BETWEEN: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER, LESS); - break; - case TRUE: - tarantoolCriteria.addCondition(Condition.create(EQ, property, true)); - break; - case FALSE: - tarantoolCriteria.addCondition(Condition.create(EQ, property, false)); - break; - case IS_EMPTY: - tarantoolCriteria.addCondition(Condition.create(EQ, property, "")); - break; - case IS_NULL: - tarantoolCriteria.addCondition(Condition.create(EQ, property, null)); - break; - default: - throw new InvalidDataAccessApiUsageException(String.format("Unsupported type '%s'", type)); - } - - return tarantoolCriteria; - } - - private void generateConditions( - TarantoolCriteria tarantoolCriteria, - Part.Type type, - String property, - Iterator iterator, - ConditionOperator... operators) { - for (int i = 0; i < type.getNumberOfArguments(); i++) { - if (!iterator.hasNext()) { - throw new InvalidDataAccessApiUsageException( - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "Transmitted not enough arguments (%d of %d)", - type, - i, - type.getNumberOfArguments())); - } - tarantoolCriteria.addCondition(Condition.create(operators[i], property, iterator.next())); - } - } - - private boolean isIgnoreCase(Part part) { - switch (part.shouldIgnoreCase()) { - case ALWAYS: - Assert.state( - canUpperCase(part.getProperty()), - String.format( - "Unable to ignore case of %s types, the property '%s' must reference a String", - part.getProperty().getType().getName(), part.getProperty().getSegment())); - return true; - case WHEN_POSSIBLE: - return canUpperCase(part.getProperty()); - case NEVER: - default: - return false; - } - } - - private boolean canUpperCase(PropertyPath path) { - return String.class.equals(path.getType()); - } - - @Override - @NonNull - protected TarantoolCriteria and( - @NonNull Part part, @NonNull TarantoolCriteria base, @NonNull Iterator iterator) { - throw new UnsupportedOperationException(); - } - - @Override - @NonNull - protected TarantoolCriteria or( - @NonNull TarantoolCriteria base, @NonNull TarantoolCriteria criteria) { - throw new UnsupportedOperationException(); - } - - @Override - @NonNull - protected KeyValueQuery complete( - @Nullable final TarantoolCriteria criteria, @NonNull Sort sort) { - return new KeyValueQuery<>(criteria); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolQueryMethodImpl.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolQueryMethodImpl.java deleted file mode 100644 index 8b7cc5fd..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolQueryMethodImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.lang.reflect.Method; - -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryMethod; - -import io.tarantool.spring.data.query.Query; -import io.tarantool.spring.data.query.TarantoolQueryMethod; - -/** Tarantool {@link QueryMethod} Implementation */ -public class TarantoolQueryMethodImpl extends QueryMethod implements TarantoolQueryMethod { - - private final Method method; - - public TarantoolQueryMethodImpl( - Method method, RepositoryMetadata metadata, ProjectionFactory factory) { - super(method, metadata, factory); - this.method = method; - } - - public boolean hasAnnotatedQuery() { - return getQuery() != null; - } - - public String getQueryValue(Query query) { - return (String) AnnotationUtils.getValue(query); - } - - public Query getQuery() { - return method.getAnnotation(Query.class); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolRepositoryQuery.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolRepositoryQuery.java deleted file mode 100644 index dc93c964..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolRepositoryQuery.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.RepositoryQuery; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.query.ProxyTarantoolRepositoryQuery; - -/** {@link RepositoryQuery} using String based function name to call function in Tarantool. */ -public class TarantoolRepositoryQuery implements RepositoryQuery { - - private final ProxyTarantoolRepositoryQuery proxy; - private final TarantoolQueryMethodImpl queryMethod; - - public TarantoolRepositoryQuery( - TarantoolCrudClient client, TarantoolQueryMethodImpl queryMethod) { - this.queryMethod = queryMethod; - this.proxy = new ProxyTarantoolRepositoryQuery(client, queryMethod); - } - - @Override - public Object execute(Object[] parameters) { - return proxy.execute(parameters); - } - - @Override - public QueryMethod getQueryMethod() { - return queryMethod; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolScrollPosition.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolScrollPosition.java deleted file mode 100644 index c695b367..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolScrollPosition.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import org.springframework.data.domain.ScrollPosition; - -import io.tarantool.spring.data.utils.Pair; - -/** - * Use keyset pagination adapted for Tarantool crud module.. - * - * @author Nikolay Belonogov - * @see #forward(Pair) - * @see #backward(Pair) - * @see #reverse() - */ -public sealed interface TarantoolScrollPosition extends ScrollPosition - permits TarantoolKeysetScrollPosition { - - /** - * Creates a new {@link ScrollPosition} based on the key index scrolling forward. - * - * @param indexKey pair, where the first element is the name of the index on which you want to - * perform pagination. Second element is the value of the indexed field from which you want to - * paginate (exclusive). To perform pagination from the beginning of the index, pass an empty - * list as the second element of the pair. indexKey must be not {@code null}. - * @return new {@link TarantoolScrollPosition} instance. - */ - static TarantoolScrollPosition forward(Pair indexKey) { - return TarantoolKeysetScrollPosition.forward(indexKey); - } - - /** - * Creates a new {@link ScrollPosition} based on the key index scrolling backward. - * - * @param indexKey pair, where the first element is the name of the index on which you want to - * perform pagination. Second element is the value of the indexed field from which you want to - * paginate (exclusive). To perform pagination from the end of the index, pass an empty list - * as the second element of the pair. indexKey must be not {@code null}. - * @return new {@link TarantoolScrollPosition} instance. - */ - static TarantoolScrollPosition backward(Pair indexKey) { - return TarantoolKeysetScrollPosition.backward(indexKey); - } - - /** - * Return {@link TarantoolScrollPosition} with the same parameters, but with the opposite - * pagination direction. If the current {@link TarantoolScrollPosition} was set from the beginning - * of the index, the method will return the {@link TarantoolScrollPosition} set from the end of - * the index. Returns the {@link TarantoolScrollPosition} set from the beginning of the index if - * the current {@link TarantoolScrollPosition} is set from the end of the index. - * - *

Important: when this method is called, the condition specified by the index in - * the current {@link TarantoolScrollPosition} is overridden to unconditional (i.e. it will be - * searched to the end or beginning of the index) - * - * @return {@link TarantoolScrollPosition} instance. - */ - TarantoolScrollPosition reverse(); - - /** - * Return {@code true} if scrolling has backward motion. This means that the current {@link - * TarantoolScrollPosition} has the direction of movement {@link - * io.tarantool.spring.data.query.PaginationDirection#BACKWARD}. Return {@code false} if scrolling - * has forward motion ({@link io.tarantool.spring.data.query.PaginationDirection#FORWARD}). - * - * @return {@link Boolean} primitive. - */ - boolean isScrollsBackward(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolSliceImpl.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolSliceImpl.java deleted file mode 100644 index 257a2c9e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolSliceImpl.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.io.Serial; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.lang.NonNull; - -/** - * Default implementation of {@link Slice} for Tarantool. - * - * @author Nikolay Belonogov - */ -class TarantoolSliceImpl extends TarantoolChunk { - - @Serial private static final long serialVersionUID = 867755909294344406L; - - private final boolean hasNext; - - private final Pageable pageable; - - /** - * Creates a new {@link TarantoolSliceImpl} with the empty content. This will result in the - * created {@link Slice} being identical to the entire {@link List}. - */ - public TarantoolSliceImpl() { - this(Collections.emptyList(), Pageable.unpaged(), false); - } - - /** - * Creates a new {@link TarantoolSliceImpl} with the given content. This will result in the - * created {@link Slice} being identical to the entire {@link List}. - * - * @param content must not be {@literal null}. - */ - public TarantoolSliceImpl(List content) { - this(content, Pageable.unpaged(), false); - } - - /** - * Creates a new {@link TarantoolSliceImpl} with the given content and {@link Pageable}. - * - * @param content the content of this {@link Slice}, must not be {@literal null}. - * @param pageable the paging information, must not be {@literal null}. - * @param hasNext whether there's another slice following the current one. - */ - public TarantoolSliceImpl(List content, Pageable pageable, boolean hasNext) { - super(content, pageable); - - this.hasNext = hasContent() && hasNext; - this.pageable = pageable; - } - - /** - * Returns true if there is a next data slice. No data content means that the next slice does not - * exist and method will return false. - * - * @return Returns true if there is a next data slice. No data content means that the next slice - * does not exist and method will return false. - */ - @Override - public boolean hasNext() { - return hasNext && hasContent(); - } - - @Override - @NonNull - public Slice map(@NonNull Function converter) { - return new TarantoolSliceImpl<>(getConvertedContent(converter), pageable, hasNext); - } - - @Override - public String toString() { - - String contentType = "UNKNOWN"; - List content = getContent(); - - if (content.size() > 0) { - contentType = content.get(0).getClass().getName(); - } - - return String.format("Slice %d containing %s instances", getNumber(), contentType); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolSliceImpl that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return hasNext == that.hasNext && pageable.equals(that.pageable); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), hasNext, pageable); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolSortAccessor.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolSortAccessor.java deleted file mode 100644 index 7f1e0ab6..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolSortAccessor.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.util.Comparator; -import java.util.Map.Entry; - -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Sort.Order; -import org.springframework.data.keyvalue.core.SortAccessor; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -/** - * Implements sorting for Tarantool repository queries. - * - * @author Artyom Dubinin - */ -public class TarantoolSortAccessor implements SortAccessor>> { - - /** - * Sort on a sequence of fields, possibly none. - * - * @param query If not null, will contain one of more {@link Order} objects. - * @return A sequence of comparators or {@code null} - */ - public Comparator> resolve(KeyValueQuery query) { - if (query == null || query.getSort() == Sort.unsorted()) { - return null; - } - - throw new UnsupportedOperationException(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolWindowIterator.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolWindowIterator.java deleted file mode 100644 index 9dc7110d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/query/TarantoolWindowIterator.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.function.Function; - -import org.springframework.data.domain.Window; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * The class is a complete analogue of {@link org.springframework.data.support.WindowIterator} for - * Tarantool. - * - *

Example of usage: - * - *

- * - *
{@code
- * TarantoolScrollPosition initialScrollPosition =
- *     TarantoolScrollPosition.forward(Pair.of("pk", Collections.emptyList()));
- *
- * TarantoolWindowIterator personIterator =
- *     TarantoolWindowIterator.of(scrollPosition -> repository.findFirst10ByAge(10, scrollPosition))
- *         .startingAt(initialScrollPosition);
- *
- * List result = new ArrayList<>();
- *
- * while (personIterator.hasNext()) {
- *   result.add(personIterator.next());
- * }
- * }
- * - *
- * - * @param domain class type. - */ -public class TarantoolWindowIterator implements Iterator { - - private final Function> windowFunction; - - private TarantoolScrollPosition currentPosition; - - private @Nullable Window currentWindow; - - private @Nullable Iterator currentIterator; - - /** - * Entrypoint to create a new {@link TarantoolWindowIterator} for the given windowFunction. - * - * @param windowFunction must not be {@literal null}. - * @param domain class type. - * @return new instance of {@link TarantoolWindowIteratorBuilder}. - */ - public static TarantoolWindowIteratorBuilder of( - Function> windowFunction) { - return new TarantoolWindowIteratorBuilder<>(windowFunction); - } - - TarantoolWindowIterator( - Function> windowFunction, - TarantoolScrollPosition position) { - - this.windowFunction = windowFunction; - this.currentPosition = position; - } - - @Override - public boolean hasNext() { - - // use while loop instead of recursion to fetch the next window. - do { - if (currentWindow == null) { - currentWindow = windowFunction.apply(currentPosition); - } - - if (currentIterator == null) { - if (currentWindow != null) { - currentIterator = currentWindow.iterator(); - } - } - - if (currentIterator != null) { - - if (currentIterator.hasNext()) { - return true; - } - - if (currentWindow != null && currentWindow.hasNext()) { - - currentPosition = getNextPosition(currentWindow); - currentIterator = null; - currentWindow = null; - continue; - } - } - - return false; - } while (true); - } - - @Override - public T next() { - - if (!hasNext()) { - throw new NoSuchElementException(); - } - - return currentIterator.next(); - } - - private static TarantoolScrollPosition getNextPosition(Window window) { - return (TarantoolScrollPosition) window.positionAt(window.size() - 1); - } - - /** Builder API to construct a {@link TarantoolWindowIterator}. */ - public static class TarantoolWindowIteratorBuilder { - - private final Function> windowFunction; - - TarantoolWindowIteratorBuilder(Function> windowFunction) { - - Assert.notNull(windowFunction, "WindowFunction must not be null"); - - this.windowFunction = windowFunction; - } - - /** - * Create a {@link TarantoolWindowIterator} given {@link TarantoolScrollPosition}. - * - * @param position {@link TarantoolScrollPosition} instance. Must be not null. - * @return {@link TarantoolWindowIterator} instance. - */ - public TarantoolWindowIterator startingAt(TarantoolScrollPosition position) { - - Assert.notNull(position, "TarantoolScrollPosition must not be null"); - - return new TarantoolWindowIterator<>(windowFunction, position); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/TarantoolRepositoryFactory.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/TarantoolRepositoryFactory.java deleted file mode 100644 index 54439c63..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/TarantoolRepositoryFactory.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.repository; - -import java.util.Optional; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.SpelQueryCreator; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data34.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data34.repository.config.TarantoolQueryLookupStrategy; -import io.tarantool.spring.data34.repository.support.TarantoolSimpleRepository; - -/** - * Tarantool version of {@link KeyValueRepositoryFactory}, a factory to build tarantool repository - * instances. - * - *

The purpose of extending is to ensure that the {@link #getQueryLookupStrategy} method returns - * a {@link TarantoolQueryLookupStrategy} rather than the default. - * - *

The end goal of this bean is for {@link TarantoolPartTreeQuery} to be used for query - * preparation. - * - * @author Artyom Dubinin - */ -public class TarantoolRepositoryFactory extends KeyValueRepositoryFactory { - - private static final Class DEFAULT_QUERY_CREATOR = SpelQueryCreator.class; - - private final KeyValueOperations keyValueOperations; - private final Class> queryCreator; - private final TarantoolCrudClient client; - - /* Mirror functionality of super, to ensure private - * fields are set. - */ - public TarantoolRepositoryFactory( - TarantoolCrudClient client, KeyValueOperations keyValueOperations) { - this(client, keyValueOperations, DEFAULT_QUERY_CREATOR); - } - - /* Capture KeyValueOperations and QueryCreator objects after passing to super. - */ - public TarantoolRepositoryFactory( - TarantoolCrudClient client, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - - super(keyValueOperations, queryCreator); - - this.client = client; - this.keyValueOperations = keyValueOperations; - this.queryCreator = queryCreator; - } - - /** - * Ensure the mechanism for query evaluation is Tarantool specific, as the original {@code - * KeyValueQueryLookupStrategy} does not function correctly for Tarantool. - */ - @Override - protected Optional getQueryLookupStrategy( - QueryLookupStrategy.Key key, QueryMethodEvaluationContextProvider evaluationContextProvider) { - return Optional.of( - new TarantoolQueryLookupStrategy( - client, key, evaluationContextProvider, keyValueOperations, queryCreator)); - } - - @Override - protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { - return TarantoolSimpleRepository.class; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/EnableTarantoolRepositories.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/EnableTarantoolRepositories.java deleted file mode 100644 index f0862b32..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/EnableTarantoolRepositories.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.repository.config; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.ComponentScan.Filter; -import org.springframework.context.annotation.Import; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.config.QueryCreatorType; -import org.springframework.data.repository.config.DefaultRepositoryBaseClass; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryLookupStrategy.Key; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.spring.data34.config.properties.TarantoolProperties; -import io.tarantool.spring.data34.query.TarantoolQueryCreator; -import io.tarantool.spring.data34.repository.support.TarantoolRepositoryFactoryBean; - -@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@Import(TarantoolRepositoriesRegistrar.class) -@EnableConfigurationProperties(TarantoolProperties.class) -@QueryCreatorType(TarantoolQueryCreator.class) -public @interface EnableTarantoolRepositories { - - /** - * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation - * declarations e.g.: {@code @EnableJpaRepositories("org.my.pkg")} instead of - * {@code @EnableJpaRepositories(basePackages="org.my.pkg")}. - * - * @return value - */ - String[] value() default {}; - - /** - * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually - * exclusive with) this attribute. Use {@link #basePackageClasses()} for a type-safe alternative - * to String-based package names. - * - * @return base packages - */ - String[] basePackages() default {}; - - /** - * Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for - * annotated components. The package of each class specified will be scanned. Consider creating a - * special no-op marker class or interface in each package that serves no purpose other than being - * referenced by this attribute. - * - * @return classes - */ - Class[] basePackageClasses() default {}; - - /** - * Specifies which types are not eligible for component scanning. - * - * @return filters - */ - Filter[] excludeFilters() default {}; - - /** - * Specifies which types are eligible for component scanning. Further, narrows the set of - * candidate components from everything in {@link #basePackages()} to everything in the base - * packages that matches the given filter or filters. - * - * @return filters - */ - Filter[] includeFilters() default {}; - - /** - * Returns the postfix to be used when looking up custom repository implementations. Defaults to - * {@literal Impl}. So for a repository named {@code PersonRepository} the corresponding - * implementation class will be looked up scanning for {@code PersonRepositoryImpl}. - * - * @return postfix - */ - String repositoryImplementationPostfix() default "Impl"; - - /** - * Configures the location of where to find the Spring Data named queries properties file. - * - * @return location - */ - String namedQueriesLocation() default ""; - - /** - * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query - * methods. Defaults to {@link Key#CREATE_IF_NOT_FOUND}. - * - * @return strategy - */ - Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND; - - Class repositoryFactoryBeanClass() default TarantoolRepositoryFactoryBean.class; - - /** - * Allow custom base classes, for generic behavior shared amongst selected repositories. - * - * @return base class - */ - Class repositoryBaseClass() default DefaultRepositoryBaseClass.class; - - /** - * Configures the name of the {@link KeyValueOperations} bean to be used with the repositories - * detected. - * - * @return reference to {@link KeyValueOperations} bean. - */ - String keyValueTemplateRef() default DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; - - /** - * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be - * discovered by the repositories' infrastructure. - * - * @return result of consideration - */ - boolean considerNestedRepositories() default false; - - /** - * Configures the {@link ClientType} to be used as driver client type to connection to Tarantool. - * Must match the referenced type in {@link #keyValueTemplateRef()}} if these values differ from - * the default ones. - * - * @return the type of client through which communication with Tarantool will be made. - */ - ClientType clientType() default ClientType.CRUD; -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/TarantoolQueryLookupStrategy.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/TarantoolQueryLookupStrategy.java deleted file mode 100644 index 5de6f8c5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/TarantoolQueryLookupStrategy.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.repository.config; - -import java.lang.reflect.Method; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery; -import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.repository.core.NamedQueries; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.util.Assert; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data34.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data34.query.TarantoolQueryMethodImpl; -import io.tarantool.spring.data34.query.TarantoolRepositoryQuery; - -/** - * Ensures {@link TarantoolPartTreeQuery} is used for query preparation rather than {@link - * KeyValuePartTreeQuery} or other alternatives. - * - * @author Artyom Dubinin - */ -public class TarantoolQueryLookupStrategy implements QueryLookupStrategy { - - private final QueryMethodEvaluationContextProvider evaluationContextProvider; - private final KeyValueOperations keyValueOperations; - private final Class> queryCreator; - private final TarantoolCrudClient client; - - /** - * Required constructor, capturing arguments for use in {@link #resolveQuery}. - * - * @param client tarantool crud client - * @param key Not used - * @param evaluationContextProvider For evaluation of query expressions - * @param keyValueOperations Bean to use for Key/Value operations on Tarantool repos - * @param queryCreator Query creator - */ - public TarantoolQueryLookupStrategy( - TarantoolCrudClient client, - Key key, - QueryMethodEvaluationContextProvider evaluationContextProvider, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - - Assert.notNull(evaluationContextProvider, "EvaluationContextProvider must not be null!"); - Assert.notNull(keyValueOperations, "KeyValueOperations must not be null!"); - Assert.notNull(queryCreator, "Query creator type must not be null!"); - - this.client = client; - this.evaluationContextProvider = evaluationContextProvider; - this.keyValueOperations = keyValueOperations; - this.queryCreator = queryCreator; - } - - /** - * Use {@link TarantoolPartTreeQuery} for resolving queries against Tarantool repositories. - * - * @param method, the query method - * @param metadata, not used - * @param projectionFactory, not used - * @param namedQueries, not used - * @return A mechanism for querying Tarantool repositories - */ - public RepositoryQuery resolveQuery( - Method method, - RepositoryMetadata metadata, - ProjectionFactory projectionFactory, - NamedQueries namedQueries) { - - TarantoolQueryMethodImpl queryMethod = - new TarantoolQueryMethodImpl(method, metadata, projectionFactory); - - if (queryMethod.hasAnnotatedQuery()) { - return new TarantoolRepositoryQuery(client, queryMethod); - } - - return new TarantoolPartTreeQuery( - queryMethod, evaluationContextProvider, this.keyValueOperations, this.queryCreator); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/TarantoolRepositoriesRegistrar.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/TarantoolRepositoriesRegistrar.java deleted file mode 100644 index d0bb73f9..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/TarantoolRepositoriesRegistrar.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.repository.config; - -import java.lang.annotation.Annotation; - -import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport; -import org.springframework.data.repository.config.RepositoryConfigurationExtension; - -class TarantoolRepositoriesRegistrar extends RepositoryBeanDefinitionRegistrarSupport { - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoriesRegistrar#getAnnotation() - */ - @Override - protected Class getAnnotation() { - return EnableTarantoolRepositories.class; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport#getExtension() - */ - @Override - protected RepositoryConfigurationExtension getExtension() { - return new TarantoolRepositoryConfigurationExtension(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/TarantoolRepositoryConfigurationExtension.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/TarantoolRepositoryConfigurationExtension.java deleted file mode 100644 index 1d99ce14..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/TarantoolRepositoryConfigurationExtension.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.repository.config; - -import org.springframework.beans.factory.config.ConstructorArgumentValues; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension; -import org.springframework.data.repository.config.RepositoryConfigurationSource; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.spring.data34.config.TarantoolCrudConfiguration; -import io.tarantool.spring.data34.core.TarantoolTemplate; -import io.tarantool.spring.data34.core.mapping.TarantoolMappingContext; - -public class TarantoolRepositoryConfigurationExtension - extends KeyValueRepositoryConfigurationExtension { - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getModuleName() - */ - @Override - public String getModuleName() { - return "Tarantool"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getModulePrefix() - */ - @Override - public String getModulePrefix() { - return "tarantool"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getDefaultKeyValueTemplateRef() - */ - @Override - public String getDefaultKeyValueTemplateRef() { - return DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #registerBeansForRoot() - */ - @Override - public void registerBeansForRoot( - BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) { - // register a default set of beans based on the passed annotation attributes. - final ClientType clientTypeAttribute = - configurationSource.getRequiredAttribute("clientType", ClientType.class); - - if (clientTypeAttribute == ClientType.CRUD) { - final String defaultCrudConfigurationBeanName = - TarantoolCrudConfiguration.class.getCanonicalName(); - registerIfNotAlreadyRegistered( - () -> new RootBeanDefinition(TarantoolCrudConfiguration.class), - registry, - defaultCrudConfigurationBeanName, - configurationSource); - } else { - throw new IllegalArgumentException("The Box client is not yet supported."); - } - super.registerBeansForRoot(registry, configurationSource); - - // remove KeyValueMappingContext to add TarantoolMappingContext - registry.removeBeanDefinition(getMappingContextBeanRef()); - registerIfNotAlreadyRegistered( - () -> { - RootBeanDefinition definition = new RootBeanDefinition(TarantoolMappingContext.class); - definition.setSource(configurationSource.getSource()); - - return definition; - }, - registry, - getMappingContextBeanRef(), - configurationSource); - } - - @Override - protected AbstractBeanDefinition getDefaultKeyValueTemplateBeanDefinition( - RepositoryConfigurationSource configurationSource) { - final RootBeanDefinition keyValueTemplateBeanDefinition = - new RootBeanDefinition(TarantoolTemplate.class); - - final ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); - constructorArgumentValues.addIndexedArgumentValue( - 0, new RuntimeBeanReference(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF)); - constructorArgumentValues.addIndexedArgumentValue( - 1, new RuntimeBeanReference(getMappingContextBeanRef())); - - keyValueTemplateBeanDefinition.setConstructorArgumentValues(constructorArgumentValues); - keyValueTemplateBeanDefinition.setSource(configurationSource); - keyValueTemplateBeanDefinition.setDependsOn(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF); - keyValueTemplateBeanDefinition.setDependsOn(getMappingContextBeanRef()); - - return keyValueTemplateBeanDefinition; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/package-info.java deleted file mode 100644 index ae9cb39f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/config/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository config package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data34.repository.config; diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/package-info.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/package-info.java deleted file mode 100644 index 26b345b4..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data34.repository; diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/support/TarantoolRepositoryFactoryBean.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/support/TarantoolRepositoryFactoryBean.java deleted file mode 100644 index 111519c5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/support/TarantoolRepositoryFactoryBean.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.repository.support; - -import java.io.Serializable; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean; -import org.springframework.data.repository.Repository; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data34.repository.TarantoolRepositoryFactory; - -public class TarantoolRepositoryFactoryBean, S, ID extends Serializable> - extends KeyValueRepositoryFactoryBean { - - @Autowired private TarantoolCrudClient client; - - public TarantoolRepositoryFactoryBean(Class repositoryInterface) { - super(repositoryInterface); - } - - /** - * Return a {@link TarantoolRepositoryFactory}. - * - *

{@code super} would return {@link KeyValueRepositoryFactory} which in turn builds {@code - * KeyValueRepository} instances, and these have a private method that implement querying in a - * manner that does not fit with Tarantool. More details are in {@link - * TarantoolRepositoryFactory}. - * - * @param operations operations - * @param queryCreator creator - * @param repositoryQueryType, not used - * @return A {@link TarantoolRepositoryFactory} that creates tarantool repository instances. - */ - @Override - protected KeyValueRepositoryFactory createRepositoryFactory( - KeyValueOperations operations, - Class> queryCreator, - Class repositoryQueryType) { - return new TarantoolRepositoryFactory(client, operations, queryCreator); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/support/TarantoolSimpleRepository.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/support/TarantoolSimpleRepository.java deleted file mode 100644 index 4048f798..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/support/TarantoolSimpleRepository.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.repository.support; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository; -import org.springframework.data.repository.core.EntityInformation; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data34.query.PaginationUtils.doPageQuery; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolSimpleRepository extends SimpleKeyValueRepository { - - private static final String FIND_ALL_EXC_MSG = - "This method is not supported to avoid sampling huge data massive. " - + "Please use derived methods with scrolling or pagination to select all data."; - - private static final String FIND_ALL_SORT_EXC_MSG = - "This method is not supported because sorting is not supported " - + "in Tarantool. Organize sorting of results using Java tools."; - - private static final String PAGEABLE_NULL_EXC_MSG = "Pageable must be not null"; - - private final KeyValueOperations operations; - private final EntityInformation entityInformation; - - /** - * Creates a new {@link SimpleKeyValueRepository} for the given {@link EntityInformation} and - * {@link KeyValueOperations}. - * - * @param metadata must not be {@literal null}. - * @param operations must not be {@literal null}. - */ - public TarantoolSimpleRepository( - EntityInformation metadata, KeyValueOperations operations) { - super(metadata, operations); - this.entityInformation = metadata; - this.operations = operations; - } - - @Override - public List findAll() { - throw new UnsupportedOperationException(FIND_ALL_EXC_MSG); - } - - @Override - public List findAll(Sort sort) { - throw new UnsupportedOperationException(FIND_ALL_SORT_EXC_MSG); - } - - @Override - @SuppressWarnings("unchecked") - public Page findAll(Pageable pageable) { - Assert.notNull(pageable, PAGEABLE_NULL_EXC_MSG); - - KeyValueQuery query = new KeyValueQuery<>(new TarantoolCriteria()); - return (Page) - doPageQuery(pageable, query, this.operations, this.entityInformation.getJavaType()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/support/package-info.java b/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/support/package-info.java deleted file mode 100644 index 624bbd67..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/main/java/io/tarantool/spring/data34/repository/support/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository support package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data34.repository.support; diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/GenericTarantoolConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/GenericTarantoolConfigurationTest.java deleted file mode 100644 index b8f33c02..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/GenericTarantoolConfigurationTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.config; - -import java.io.IOException; -import java.nio.file.Files; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.test.context.TestPropertySource; - -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data34.config.properties.TarantoolProperties; -import io.tarantool.spring.data34.utils.TarantoolTestSupport; - -@TestPropertySource(properties = {Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -public abstract class GenericTarantoolConfigurationTest implements ApplicationContextAware { - - protected static TarantoolProperties testProperties; - - protected ApplicationContext applicationContext; - - @Autowired protected TarantoolProperties properties; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - @BeforeAll - static void beforeAll() throws IOException { - testProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists( - TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR.resolve( - Constants.DEFAULT_PROPERTY_FILE_NAME)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/TarantoolBoxConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/TarantoolBoxConfigurationTest.java deleted file mode 100644 index 5e744a24..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/TarantoolBoxConfigurationTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.config; - -import java.io.IOException; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.RepeatedTest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.bean.override.mockito.MockitoBean; - -import io.tarantool.client.box.TarantoolBoxClient; -import io.tarantool.client.factory.TarantoolBoxClientBuilder; -import io.tarantool.pool.HeartbeatOpts; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data34.config.properties.TarantoolProperties; -import io.tarantool.spring.data34.utils.TarantoolTestSupport; - -@SpringBootTest(classes = {TarantoolBoxConfigurationTest.Config.class}) -public class TarantoolBoxConfigurationTest extends GenericTarantoolConfigurationTest { - - @MockitoBean TarantoolBoxClient client; - - @Autowired private TarantoolBoxConfiguration tarantoolBoxConfiguration; - - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testGetBoxClientBuilder() throws IOException { - assertEquals(properties, tarantoolBoxConfiguration.getProperties()); - - final TarantoolBoxClientBuilder boxClientBuilder = tarantoolBoxConfiguration.getClientBuilder(); - - if (properties.getConnectionGroups() == null) { - assertNull(boxClientBuilder.getGroups()); - } else { - Assertions.assertEquals( - properties.getConnectionGroups().size(), boxClientBuilder.getGroups().size()); - List connectionGroupsFromBuilder = boxClientBuilder.getGroups(); - List connectionGroupsFromProperty = - properties.getInstanceConnectionGroups(); - - assertNotNull(connectionGroupsFromBuilder); - assertNotNull(connectionGroupsFromProperty); - for (int i = 0; i < connectionGroupsFromBuilder.size(); i++) { - InstanceConnectionGroup groupFromBuilder = connectionGroupsFromBuilder.get(i); - InstanceConnectionGroup groupFromProperty = connectionGroupsFromProperty.get(i); - - assertEquals(groupFromProperty.getAuthType(), groupFromBuilder.getAuthType()); - assertEquals(groupFromProperty.getTag(), groupFromBuilder.getTag()); - assertEquals(groupFromProperty.getSize(), groupFromBuilder.getSize()); - assertEquals(groupFromProperty.getUser(), groupFromBuilder.getUser()); - assertEquals(groupFromProperty.getPassword(), groupFromBuilder.getPassword()); - assertEquals(groupFromProperty.getPort(), groupFromBuilder.getPort()); - assertEquals(groupFromProperty.getHost(), groupFromBuilder.getHost()); - } - } - - final HeartbeatOpts propertiesHeartbeatOpts = properties.getHeartbeatOpts(); - if (propertiesHeartbeatOpts == null) { - assertNull(boxClientBuilder.getHeartbeatOpts()); - } else { - HeartbeatOpts builderHeartbeatOpts = boxClientBuilder.getHeartbeatOpts(); - assertEquals( - propertiesHeartbeatOpts.getPingInterval(), builderHeartbeatOpts.getPingInterval()); - assertEquals( - propertiesHeartbeatOpts.getDeathThreshold(), builderHeartbeatOpts.getDeathThreshold()); - assertEquals( - propertiesHeartbeatOpts.getInvalidationThreshold(), - builderHeartbeatOpts.getInvalidationThreshold()); - assertEquals(propertiesHeartbeatOpts.getWindowSize(), builderHeartbeatOpts.getWindowSize()); - } - - Assertions.assertEquals(properties.getUserName(), boxClientBuilder.getUser()); - Assertions.assertEquals(properties.getPort(), boxClientBuilder.getPort()); - Assertions.assertEquals(properties.getEventLoopThreadsCount(), boxClientBuilder.getnThreads()); - Assertions.assertEquals(properties.getBalancerClass(), boxClientBuilder.getBalancerClass()); - Assertions.assertEquals( - properties.isGracefulShutdownEnabled(), boxClientBuilder.isGracefulShutdown()); - Assertions.assertEquals(properties.getConnectTimeout(), boxClientBuilder.getConnectTimeout()); - Assertions.assertEquals(properties.getReconnectAfter(), boxClientBuilder.getReconnectAfter()); - Assertions.assertEquals(properties.getHost(), boxClientBuilder.getHost()); - Assertions.assertEquals(properties.getPassword(), boxClientBuilder.getPassword()); - Assertions.assertEquals(properties.isFetchSchema(), boxClientBuilder.isFetchSchema()); - Assertions.assertEquals( - properties.isIgnoreOldSchemaVersion(), boxClientBuilder.isIgnoreOldSchemaVersion()); - - testProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @Configuration - @EnableConfigurationProperties(TarantoolProperties.class) - @Import(TarantoolBoxConfiguration.class) - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/TarantoolEmptyPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/TarantoolEmptyPropertiesTest.java deleted file mode 100644 index 6dd4c111..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/TarantoolEmptyPropertiesTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.config; - -import java.io.IOException; -import java.nio.file.Files; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.TestPropertySource; - -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data34.config.properties.TarantoolProperties; -import io.tarantool.spring.data34.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data34.utils.TarantoolTestSupport; - -/** - * @see TarantoolPropertiesTest - */ -@SpringBootTest(classes = {TarantoolEmptyPropertiesTest.Config.class}) -@TestPropertySource(properties = {Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -@Timeout(5) -public class TarantoolEmptyPropertiesTest { - - @Autowired private TarantoolProperties springParsedProperties; - - @BeforeAll - static void beforeAll() throws IOException { - TarantoolTestSupport.writeTestEmptyPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - /* - * The test checks that if property processing is enabled via the @EnableConfigurationProperties annotation, then - * TarantoolProperty always exists and has default values. - */ - @Test - void testParseEmptyProperties() { - assertNotNull(springParsedProperties); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists( - TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR.resolve( - Constants.DEFAULT_PROPERTY_FILE_NAME)); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/core/annotation/IdClassResolverTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/core/annotation/IdClassResolverTest.java deleted file mode 100644 index 2a33cf3d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/core/annotation/IdClassResolverTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.core.annotation; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import io.tarantool.spring.data34.utils.entity.ComplexPerson; -import io.tarantool.spring.data34.utils.entity.CompositePersonKey; -import io.tarantool.spring.data34.utils.entity.EntityWithAnnotationAsIdClass; -import io.tarantool.spring.data34.utils.entity.Person; - -@Timeout(5) -class IdClassResolverTest { - - public static final DefaultIdClassResolver ID_CLASS_RESOLVER = DefaultIdClassResolver.INSTANCE; - - @Test - void testResolveIdClassTypeWithNullEntity() { - - final IllegalArgumentException throwable = - assertThrows( - IllegalArgumentException.class, () -> ID_CLASS_RESOLVER.resolveIdClassType(null)); - final String EXCEPTION_MESSAGE = "Type for IdClass must be not null!"; - assertEquals(EXCEPTION_MESSAGE, throwable.getMessage()); - } - - @Test - void testResolveIdClassTypeWithEntityWithoutAnnotation() { - assertNull(ID_CLASS_RESOLVER.resolveIdClassType(Person.class)); - } - - @Test - void testResolveIdClassTypeWithEntityWithAnnotation() { - assertEquals( - ID_CLASS_RESOLVER.resolveIdClassType(ComplexPerson.class), CompositePersonKey.class); - } - - @Test - void testResolveIdClassTypeWithCrossAnnotation() { - final IllegalArgumentException throwable = - assertThrows( - IllegalArgumentException.class, - () -> ID_CLASS_RESOLVER.resolveIdClassType(EntityWithAnnotationAsIdClass.class)); - - assertEquals(DefaultIdClassResolver.ANNOTATION_TYPE_EXCEPTION, throwable.getMessage()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/core/mapping/KeyValueCompositePropertyTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/core/mapping/KeyValueCompositePropertyTest.java deleted file mode 100644 index 9aa08d70..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/core/mapping/KeyValueCompositePropertyTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.core.mapping; - -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.ReflectionUtils; - -public class KeyValueCompositePropertyTest

> { - - private @Nullable Identifier

identifier; - - @BeforeEach - public void setUp() { - this.identifier = null; - } - - /** Check methods for adding and retrieving parts of a composite key. */ - @Test - public void testAddAndGetParts() { - Class entityClass = TestEntity.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - - ReflectionUtils.FieldFilter isIdFieldFiler = field -> field.isAnnotationPresent(Id.class); - ReflectionUtils.doWithFields(entityClass, field -> addPart(field, owner), isIdFieldFiler); - - assertNotNull(identifier); - List identifierFieldsFromProperties = - this.identifier.getParts().stream() - .map(PersistentProperty::getField) - .collect(Collectors.toList()); - - compareFieldCollection(identifierFieldsFromProperties, getExpectedIdFields(entityClass)); - } - - /** Check methods for adding and retrieving parts of a composite key. */ - @Test - public void testAddAndGetFields() { - Class entityClass = TestEntity.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - - ReflectionUtils.FieldFilter isIdFieldFiler = field -> field.isAnnotationPresent(Id.class); - ReflectionUtils.doWithFields(entityClass, field -> addPart(field, owner), isIdFieldFiler); - - assertNotNull(identifier); - List fieldsFromIdentifier = Arrays.asList(identifier.getFields()); - - compareFieldCollection(fieldsFromIdentifier, getExpectedIdFields(entityClass)); - } - - /** - * Check methods for adding and getting parts of a composite key for an object without - * {@code @Id}. - */ - @Test - public void testAddAndGetPartsWithEntityWithoutId() { - Class entityClass = TestEntityWithoutId.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - ReflectionUtils.doWithFields( - entityClass, field -> addPart(field, owner), field -> field.isAnnotationPresent(Id.class)); - - assertNull(identifier); - } - - static class TestEntity { - - @Id private long id; - - @Id private int secondId; - } - - static class TestEntityWithoutId { - - private long id; - - @Nullable private String name; - - private int secondId; - } - - /** Create a PersistentProperty and add to first id property. */ - @SuppressWarnings("unchecked") - private void addPart(Field field, PersistentEntity owner) { - Property property = Property.of(owner.getTypeInformation(), field); - Identifier

persistentProperty = - new KeyValueCompositeProperty<>(property, owner, SimpleTypeHolder.DEFAULT); - - if (this.identifier == null) { - this.identifier = persistentProperty; - } - this.identifier.addPart((P) persistentProperty); - } - - /** Compare fields by name and type. */ - private void compareFieldCollection(List first, List second) { - assertEquals(first.size(), second.size()); - - first.sort(Comparator.comparing(Field::getName)); - second.sort(Comparator.comparing(Field::getName)); - - for (int i = 0; i < first.size(); i++) { - assertEquals(first.get(i).getName(), second.get(i).getName()); - assertEquals(first.get(i).getType(), second.get(i).getType()); - } - } - - /** Get the expected fields marked with the {@code @Id} annotation. */ - private List getExpectedIdFields(Class entityClass) { - return Arrays.stream(entityClass.getDeclaredFields()) - .filter(field -> field.isAnnotationPresent(Id.class)) - .collect(Collectors.toList()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/core/mapping/TarantoolMappingContextTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/core/mapping/TarantoolMappingContextTest.java deleted file mode 100644 index 4f783bb0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/core/mapping/TarantoolMappingContextTest.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.core.mapping; - -import java.lang.reflect.Field; -import java.util.HashSet; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data34.core.mapping.BasicKeyValueCompositePersistentEntity.KeyPartTypeChecker; -import io.tarantool.spring.data34.utils.entity.ComplexPerson; -import io.tarantool.spring.data34.utils.entity.EntityWithWrongCompositeKeyPartsCount; -import io.tarantool.spring.data34.utils.entity.EntityWithWrongFieldTypes; -import io.tarantool.spring.data34.utils.entity.Person; - -class TarantoolMappingContextTest { - - @Test - void testSetFallbackKeySpaceResolver() throws NoSuchFieldException { - final KeySpaceResolver RESOLVER = TestResolver.INSTANCE; - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - mappingContext.setKeySpaceResolver(RESOLVER); - - final Field field = TarantoolMappingContext.class.getDeclaredField("keySpaceResolver"); - ReflectionUtils.makeAccessible(field); - - final Object resolverFieldValue = ReflectionUtils.getField(field, mappingContext); - - assertEquals(RESOLVER, resolverFieldValue); - } - - @Test - void testCreatePersistentEntity() { - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - final TypeInformation informationForSimpleClass = TypeInformation.of(Person.class); - - final TypeInformation informationForIdentifierClass = - TypeInformation.of(ComplexPerson.class); - - assertInstanceOf( - KeyValueCompositePersistentEntity.class, createEntityForClass(ComplexPerson.class)); - - assertInstanceOf(KeyValuePersistentEntity.class, createEntityForClass(ComplexPerson.class)); - } - - @Test - void testCreatePersistentProperty() { - ReflectionUtils.FieldFilter idFilter = field -> field.isAnnotationPresent(Id.class); - - PersistentProperty simpleIdProperty = createProperty(Person.class, idFilter); - assertInstanceOf(KeyValuePersistentProperty.class, simpleIdProperty); - - PersistentProperty compositeIdProperty = createProperty(ComplexPerson.class, idFilter); - assertInstanceOf(KeyValueCompositeProperty.class, compositeIdProperty); - } - - @Test - void testCreateEntityWithWrongCompositeKeyPartTypes() { - Set> initialSet = - new HashSet>() { - { - add(EntityWithWrongFieldTypes.class); - } - }; - IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> initEntities(initialSet)); - - Assertions.assertEquals( - KeyPartTypeChecker.COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION, exception.getMessage()); - } - - @Test - void testCreateEntityWithWrongCompositeKeyPartCount() { - Set> initialSet = - new HashSet>() { - { - add(EntityWithWrongCompositeKeyPartsCount.class); - } - }; - IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> initEntities(initialSet)); - - assertEquals(KeyPartTypeChecker.COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION, exception.getMessage()); - } - - /** - * Create a mappingContext from the passed domain classes. After initialize - create for them - * PersistentEntities and add PersistentProperties to them. - * - * @param entitySet - * @return - */ - private MappingContext initEntities(Set> entitySet) { - TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - mappingContext.setInitialEntitySet(entitySet); - mappingContext.initialize(); - return mappingContext; - } - - private enum TestResolver implements KeySpaceResolver { - INSTANCE; - - @Override - @Nullable - public String resolveKeySpace(Class type) { - - Assert.notNull(type, "Type for keyspace for null!"); - - Class userClass = ClassUtils.getUserClass(type); - Object keySpace = getKeySpace(userClass); - - return keySpace != null ? keySpace.toString() : null; - } - - @Nullable - private static Object getKeySpace(Class type) { - - KeySpace keyspace = AnnotatedElementUtils.findMergedAnnotation(type, KeySpace.class); - - if (keyspace != null) { - return AnnotationUtils.getValue(keyspace); - } - - return null; - } - } - - private PersistentEntity createEntityForClass(Class entityClass) { - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - final TypeInformation informationForClass = TypeInformation.of(entityClass); - return mappingContext.createPersistentEntity(informationForClass); - } - - private

> PersistentProperty createProperty( - Class classType, ReflectionUtils.FieldFilter fieldFilter) { - - final TarantoolMappingContext, P> context = - new TarantoolMappingContext<>(); - KeyValuePersistentEntity entity = - context.createPersistentEntity(TypeInformation.of(classType)); - Field field = org.springframework.data.util.ReflectionUtils.findField(classType, fieldFilter); - assertNotNull(field); - - return context.createPersistentProperty( - Property.of(entity.getTypeInformation(), field), entity, SimpleTypeHolder.DEFAULT); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java deleted file mode 100644 index 7d19aa78..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.core.mapping.model; - -import java.lang.reflect.Field; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.Test; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data34.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data34.core.mapping.BasicKeyValueCompositePersistentEntity; -import io.tarantool.spring.data34.core.mapping.KeyValueCompositeProperty; -import io.tarantool.spring.data34.utils.entity.ComplexPerson; - -public class PersistentCompositeIdIsNewStrategyTest

> { - - /** Check the strategy creation method and check whether the domain entity is new. */ - @Test - public void testForIdOnly() { - - // Currently identical like of 'of' method (version doesn't support) - PersistentCompositeIdIsNewStrategy strategy = - PersistentCompositeIdIsNewStrategy.forIdOnly(createPersistentEntity(ComplexPerson.class)); - - // Now is stub - always is false - ComplexPerson emptyEntity = new ComplexPerson(); - assertFalse(strategy.isNew(emptyEntity)); - } - - /** Check the strategy creation method and check whether the domain entity is new. */ - @Test - public void testIsNew() { - PersistentCompositeIdIsNewStrategy strategy = - PersistentCompositeIdIsNewStrategy.of(createPersistentEntity(ComplexPerson.class)); - - // Now is stub - always is false - ComplexPerson emptyEntity = new ComplexPerson(); - assertFalse(strategy.isNew(emptyEntity)); - } - - private BasicKeyValueCompositePersistentEntity createPersistentEntity(Class entityType) { - Class compositeKeyType = DefaultIdClassResolver.INSTANCE.resolveIdClassType(entityType); - assertNotNull(compositeKeyType); - - BasicKeyValueCompositePersistentEntity persistentEntity = - new BasicKeyValueCompositePersistentEntity<>( - TypeInformation.of(entityType), null, compositeKeyType); - ReflectionUtils.doWithFields(entityType, field -> addProperty(field, persistentEntity)); - return persistentEntity; - } - - /** Add Persistent property into PersistentEntity. */ - @SuppressWarnings("unchecked") - private void addProperty(Field field, BasicKeyValueCompositePersistentEntity owner) { - Property property = Property.of(owner.getTypeInformation(), field); - P persistentProperty = - (P) new KeyValueCompositeProperty<>(property, owner, SimpleTypeHolder.DEFAULT); - owner.addPersistentProperty(persistentProperty); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/BaseIntegrationTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/BaseIntegrationTest.java deleted file mode 100644 index 824751db..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/BaseIntegrationTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.integration; - -import java.io.IOException; -import java.nio.file.Files; -import java.time.Duration; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Timeout; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.cluster.ClusterContainer; -import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer; -import org.testcontainers.containers.cluster.vshard.VshardClusterContainer; -import org.testcontainers.containers.output.Slf4jLogConsumer; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.spring.data34.config.properties.TarantoolProperties; - -@Timeout(60) -public abstract class BaseIntegrationTest { - - protected static ClusterContainer clusterContainer; - - private static final String dockerRegistry = - System.getenv().getOrDefault("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", ""); - - @BeforeAll - protected static void beforeAll() throws IOException { - configureContainer(); - writeConfigurationFile(); - } - - private static void configureContainer() { - if (!isCartridgeAvailable()) { - VshardClusterContainer vshardClusterContainer = - new VshardClusterContainer( - "vshard_cluster/Dockerfile", - dockerRegistry + "vshard-cluster-java", - "vshard_cluster/instances.yaml", - "vshard_cluster/config.yaml", - "tarantool/tarantool"); - - if (!vshardClusterContainer.isRunning()) { - vshardClusterContainer.withPrivilegedMode(true); - vshardClusterContainer.start(); - } - clusterContainer = vshardClusterContainer; - } else { - CartridgeClusterContainer cartridgeContainer = - new CartridgeClusterContainer( - "cartridge/Dockerfile", - dockerRegistry + "cartridge", - "cartridge/instances.yml", - "cartridge/replicasets.yml", - org.testcontainers.containers.Arguments.get("tarantool/tarantool")) - .withStartupTimeout(Duration.ofMinutes(5)) - .withLogConsumer( - new Slf4jLogConsumer(LoggerFactory.getLogger(BaseIntegrationTest.class))); - - if (!cartridgeContainer.isRunning()) { - cartridgeContainer.start(); - } - clusterContainer = cartridgeContainer; - } - } - - private static void writeConfigurationFile() throws IOException { - final TarantoolProperties properties = new TarantoolProperties(); - properties.setHost(clusterContainer.getHost()); - properties.setPort(clusterContainer.getPort()); - properties.setUserName(clusterContainer.getUsername()); - properties.setPassword(clusterContainer.getPassword()); - - writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME, properties); - } - - @AfterAll - protected static void afterAll() throws IOException { - Files.deleteIfExists(DEFAULT_TEST_PROPERTY_DIR.resolve(DEFAULT_PROPERTY_FILE_NAME)); - } - - protected static String getHost() { - return clusterContainer.getHost(); - } - - protected static int getPort() { - return clusterContainer.getPort(); - } - - protected static String getUsername() { - return clusterContainer.getUsername(); - } - - protected static String getPassword() { - return clusterContainer.getPassword(); - } - - protected static boolean isCartridgeAvailable() { - return System.getenv().getOrDefault("TARANTOOL_VERSION", "").matches("2.*"); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/CrudConfigurations.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/CrudConfigurations.java deleted file mode 100644 index 79652173..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/CrudConfigurations.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.integration.crud; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.TestPropertySource; - -import static io.tarantool.client.TarantoolClient.DEFAULT_TAG; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.PERSON_SPACE; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data34.integration.BaseIntegrationTest; -import io.tarantool.spring.data34.repository.config.EnableTarantoolRepositories; - -@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -abstract class CrudConfigurations extends BaseIntegrationTest { - - @Autowired protected TarantoolCrudClient client; - - private static InstanceConnectionGroup groupFromJavaConfig; - - private static final String PACKAGE_PATH = "io.tarantool.spring.data34.utils.core"; - - @BeforeAll - protected static void beforeAll() throws IOException { - BaseIntegrationTest.beforeAll(); - groupFromJavaConfig = - InstanceConnectionGroup.builder() - .withHost(clusterContainer.getHost()) - .withPort(clusterContainer.getPort()) - .withUser(getUsername()) - .withPassword(getPassword()) - .withTag(DEFAULT_TAG) - .withSize(4) - .build(); - } - - @BeforeEach - public void truncateSpaces() { - client.space(PERSON_SPACE).truncate().join(); - client.space(COMPLEX_PERSON_SPACE).truncate().join(); - } - - @EnableTarantoolRepositories(basePackages = {PACKAGE_PATH}) - @Configuration - static class JavaConfigConfiguration { - - @Bean - TarantoolCrudClientBuilder crudClientBuilder() { - return TarantoolFactory.crud().withGroups(Collections.singletonList(groupFromJavaConfig)); - } - } - - @EnableTarantoolRepositories(basePackages = {PACKAGE_PATH}) - @Configuration - static class ViaPropertyFileConfiguration {} - - @Test - void testSimpleClient() { - TarantoolCrudSpace space = client.space(PERSON_SPACE); - - assertEquals(0, space.select().join().size()); - - List tuple = Arrays.asList(0, true, "petya"); - List insertTuple = space.insert(tuple).join().get(); - - assertEquals(tuple, insertTuple.subList(0, insertTuple.size() - 1)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/GenericTarantoolTemplateTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/GenericTarantoolTemplateTest.java deleted file mode 100644 index bd94f2d3..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/GenericTarantoolTemplateTest.java +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.integration.crud; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.core.UncategorizedKeyValueException; - -import static io.tarantool.spring.data.ProxyTarantoolCrudKeyValueAdapter.POTENTIAL_PERFORMANCE_ISSUES_EXCEPTION_MESSAGE; -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.generateAndInsertPersons; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.generateComplexPersons; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.mapping.crud.CrudException; -import io.tarantool.spring.data34.core.TarantoolTemplate; -import io.tarantool.spring.data34.utils.entity.ComplexPerson; -import io.tarantool.spring.data34.utils.entity.ComplexPersonWithIncorrectPK; -import io.tarantool.spring.data34.utils.entity.ComplexPersonWithJsonFormatVariantPK; -import io.tarantool.spring.data34.utils.entity.CompositePersonKey; -import io.tarantool.spring.data34.utils.entity.CompositePersonKeyWithJsonFormat; -import io.tarantool.spring.data34.utils.entity.Person; - -abstract class GenericTarantoolTemplateTest extends CrudConfigurations { - - @Autowired protected TarantoolTemplate tarantoolTemplate; - - @Test - void testGetAllOf() { - final Throwable throwable = - assertThrows( - UncategorizedKeyValueException.class, () -> tarantoolTemplate.findAll(Person.class)) - .getCause(); - - assertEquals(UnsupportedOperationException.class, throwable.getClass()); - assertEquals(POTENTIAL_PERFORMANCE_ISSUES_EXCEPTION_MESSAGE, throwable.getMessage()); - } - - static Stream dataForInsert() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - return Stream.of( - Arguments.of( - simpleKeyPerson, - (Function) (kv) -> kv.insert(simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - compositeKeyPerson, - (Function) (kv) -> kv.insert(compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForInsert") - void testKVTemplateInsert( - Object result, - Function callingMethod, - Function> selectAction) { - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForInsertById() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - return Stream.of( - Arguments.of( - simpleKeyPerson, - (Function) (kv) -> kv.insert(simpleKey, simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - compositeKeyPerson, - (Function) - (kv) -> kv.insert(compositeKey, compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForInsertById") - void testKVTemplateInsertById( - Object result, - Function callingMethod, - Function> selectAction) { - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForUpdate() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - Consumer prepareActionForSimpleKeyPerson = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer prepareActionForCompositeKeyPerson = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - return Stream.of( - Arguments.of( - prepareActionForSimpleKeyPerson, - simpleKeyPerson, - (Function) (kv) -> kv.update(simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - prepareActionForCompositeKeyPerson, - compositeKeyPerson, - (Function) (kv) -> kv.update(compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForUpdate") - void testKVTemplateUpdate( - Consumer prepareAction, - Object result, - Function callingMethod, - Function> selectAction) { - prepareAction.accept(client); - - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForUpdateById() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - Consumer prepareActionForSimpleKeyPerson = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer prepareActionForCompositeKeyPerson = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - return Stream.of( - Arguments.of( - prepareActionForSimpleKeyPerson, - simpleKeyPerson, - (Function) (kv) -> kv.update(simpleKey, simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - prepareActionForCompositeKeyPerson, - compositeKeyPerson, - (Function) - (kv) -> kv.update(compositeKey, compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForUpdateById") - void testKVTemplateUpdateById( - Consumer prepareAction, - Object result, - Function callingMethod, - Function> selectAction) { - prepareAction.accept(client); - - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForDelete() { - - Runnable simpleKeyPrepareAction = () -> generatePersons(PERSONS_COUNT); - Runnable compositeKeyPrepareAction = () -> generateComplexPersons(PERSONS_COUNT); - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(Person.class), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(ComplexPerson.class), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDelete") - void testKVTemplateDelete( - Runnable prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.run(); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForDeleteEntities() { - - Person simpleKeyPerson = new Person(0, true, "0"); - ComplexPerson compositeKeyPerson = new ComplexPerson(0, UUID.randomUUID(), true, "0"); - - Consumer simpleKeyPrepareAction = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer compositeKeyPrepareAction = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(simpleKeyPerson), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(compositeKeyPerson), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDeleteEntities") - void testKVTemplateDeleteEntities( - Consumer prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.accept(client); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForDeleteEntitiesById() { - - Person simpleKeyPerson = new Person(0, true, "0"); - ComplexPerson compositeKeyPerson = new ComplexPerson(0, UUID.randomUUID(), true, "0"); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Consumer simpleKeyPrepareAction = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer compositeKeyPrepareAction = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(simpleKey, Person.class), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(compositeKey, ComplexPerson.class), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDeleteEntitiesById") - void testKVTemplateDeleteEntitiesById( - Consumer prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.accept(client); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForCount() { - - Consumer simpleKeyPrepareAction = - (client) -> generateAndInsertPersons(PERSONS_COUNT, client); - - Consumer compositeKeyPrepareAction = - (client) -> generateAndInsertComplexPersons(PERSONS_COUNT, client); - - return Stream.of( - Arguments.of( - PERSONS_COUNT, - simpleKeyPrepareAction, - (Function) (kv) -> kv.count(Person.class)), - Arguments.of( - PERSONS_COUNT, - compositeKeyPrepareAction, - (Function) (kv) -> kv.count(ComplexPerson.class))); - } - - @ParameterizedTest - @MethodSource("dataForCount") - void testCount( - long expectedCount, - Consumer prepareAction, - Function callingMethod) { - prepareAction.accept(client); - assertEquals(expectedCount, callingMethod.apply(tarantoolTemplate)); - } - - @Test - void testCompositeKeyWithJsonFormat() { - ComplexPersonWithJsonFormatVariantPK complexPersonWithJsonFormatVariantPK = - new ComplexPersonWithJsonFormatVariantPK(0, UUID.randomUUID(), null, "0"); - - assertEquals( - complexPersonWithJsonFormatVariantPK, - tarantoolTemplate.insert(complexPersonWithJsonFormatVariantPK)); - - CompositePersonKeyWithJsonFormat key = - new CompositePersonKeyWithJsonFormat( - complexPersonWithJsonFormatVariantPK.getId(), - complexPersonWithJsonFormatVariantPK.getSecondId()); - Optional foundPerson = - tarantoolTemplate.findById(key, ComplexPersonWithJsonFormatVariantPK.class); - assertTrue(foundPerson.isPresent()); - assertEquals(complexPersonWithJsonFormatVariantPK, foundPerson.get()); - } - - @Test - void testCompositeKeyWithoutJsonFormat() { - ComplexPersonWithIncorrectPK complexPersonWithIncorrectPK = - new ComplexPersonWithIncorrectPK(0, UUID.randomUUID(), null, "0"); - - Throwable exception = - assertThrows( - UncategorizedKeyValueException.class, - () -> tarantoolTemplate.insert(complexPersonWithIncorrectPK)) - .getRootCause(); - assertInstanceOf(CrudException.class, exception); - } - - public static Stream dataForTestCompositeKeyWithConcurrency() { - final List threadsCount = Arrays.asList(1, 2, 3); - final List tuplesCount = Arrays.asList(20, 120, 360, 1200, 3000); - final List totalArguments = new ArrayList<>(); - - for (final Integer threadCount : threadsCount) { - for (final Integer tupleCount : tuplesCount) { - totalArguments.add(Arguments.of(threadCount, tupleCount)); - } - } - - return totalArguments.stream(); - } - - @DisplayName("Checking the insertion of an entity with a composite key") - @ParameterizedTest(autoCloseArguments = false, name = "thread count: {0}, tuples count: {1}") - @MethodSource("dataForTestCompositeKeyWithConcurrency") - void testCompositeKeyWithConcurrency(int threadsCount, int tuplesCount) { - final ExecutorService executor = Executors.newFixedThreadPool(threadsCount); - final List> futures = new ArrayList<>(); - final List tuples = generateComplexPersons(tuplesCount); - - for (final ComplexPerson tuple : tuples) { - futures.add( - CompletableFuture.supplyAsync(() -> this.tarantoolTemplate.insert(tuple), executor)); - } - - CompletableFuture.allOf(futures.toArray(new CompletableFuture[] {})).join(); - - for (int i = 0; i < tuplesCount; i++) { - assertEquals(tuples.get(i), futures.get(i).join()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/RepositoryConfigurationExtensionTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/RepositoryConfigurationExtensionTest.java deleted file mode 100644 index 3414f738..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/RepositoryConfigurationExtensionTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.integration.crud; - -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.client.factory.TarantoolBoxClientBuilder; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.spring.data34.integration.BaseIntegrationTest; -import io.tarantool.spring.data34.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data34.repository.config.TarantoolRepositoryConfigurationExtension; - -class RepositoryConfigurationExtensionTest extends BaseIntegrationTest { - - private static TarantoolRepositoryConfigurationExtension defaultExtension; - - @BeforeAll - static void setUp() throws IOException { - BaseIntegrationTest.beforeAll(); - defaultExtension = new TarantoolRepositoryConfigurationExtension(); - } - - @Test - void testGetModuleName() { - assertEquals("Tarantool", defaultExtension.getModuleName()); - } - - @Test - void testGetModulePrefix() { - assertEquals("tarantool", defaultExtension.getModulePrefix()); - } - - @Test - void testGetDefaultKeyValueTemplateRef() { - assertEquals( - DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF, defaultExtension.getDefaultKeyValueTemplateRef()); - } - - @Test - void testRegisterBeansForRootWithDefaultConfig() { - final ApplicationContext context = new AnnotationConfigApplicationContext(DefaultConfig.class); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF)); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF)); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF)); - } - - @Test - void testRegisterBeansForRootWithCustomClientConfigShouldThrows() { - final Throwable throwable = - assertThrows( - IllegalArgumentException.class, - () -> new AnnotationConfigApplicationContext(BoxNonSupportConfig.class)); - - final String exceptionMessage = "The Box client is not yet supported."; - assertEquals(exceptionMessage, throwable.getMessage()); - } - - private static TarantoolCrudClientBuilder getCrudClientSettings() { - return TarantoolFactory.crud() - .withHost(getHost()) - .withPort(getPort()) - .withUser(getUsername()) - .withPassword(getPassword()); - } - - private static TarantoolBoxClientBuilder getBoxClientSettings() { - return TarantoolFactory.box().withHost(getHost()).withPort(getPort()); - } - - @EnableTarantoolRepositories - static class DefaultConfig { - - @Bean - public TarantoolCrudClientBuilder clientSettings() { - return getCrudClientSettings(); - } - } - - @EnableTarantoolRepositories(clientType = ClientType.BOX) - static class BoxNonSupportConfig { - - @Bean - public TarantoolBoxClientBuilder clientSettings() { - return getBoxClientSettings(); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/RepositoryViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/RepositoryViaJavaConfigTest.java deleted file mode 100644 index 1ebea21b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/RepositoryViaJavaConfigTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data34.integration.crud.CrudConfigurations.JavaConfigConfiguration; - -@SpringBootTest(classes = {JavaConfigConfiguration.class}) -class RepositoryViaJavaConfigTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/RepositoryViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/RepositoryViaPropertiesTest.java deleted file mode 100644 index 460e56cb..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/RepositoryViaPropertiesTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data34.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; - -@SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) -class RepositoryViaPropertiesTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/TarantoolTemplateViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/TarantoolTemplateViaJavaConfigTest.java deleted file mode 100644 index 423fe4d1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/TarantoolTemplateViaJavaConfigTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data34.integration.crud.CrudConfigurations.JavaConfigConfiguration; - -@SpringBootTest(classes = {JavaConfigConfiguration.class}) -class TarantoolTemplateViaJavaConfigTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/TarantoolTemplateViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/TarantoolTemplateViaPropertiesTest.java deleted file mode 100644 index 313daa4a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/TarantoolTemplateViaPropertiesTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data34.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; - -@SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) -class TarantoolTemplateViaPropertiesTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolCriteriaTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolCriteriaTest.java deleted file mode 100644 index 091eceb0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolCriteriaTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.util.Arrays; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; - -import static io.tarantool.client.crud.ConditionOperator.EQ; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.spring.data.query.Conditions; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolCriteriaTest { - - @Test - void testAddAndGetConditions() { - final TarantoolCriteria tarantoolCriteria = new TarantoolCriteria(); - final String identifier = "name"; - final Object value = "value"; - final String operator = "=="; - - final Condition condition = Condition.create(operator, identifier, value); - assertEquals(operator, condition.getOperator()); - assertEquals(identifier, condition.getFieldIdentifier()); - assertEquals(value, condition.getValue()); - - final Condition conditionConstructor = new Condition(operator, identifier, value); - assertEquals(operator, conditionConstructor.getOperator()); - assertEquals(identifier, conditionConstructor.getFieldIdentifier()); - assertEquals(value, conditionConstructor.getValue()); - - final Condition conditionFromBuilder = - Condition.builder() - .withOperator(operator) - .withValue(value) - .withFieldIdentifier(identifier) - .build(); - assertEquals(operator, conditionFromBuilder.getOperator()); - assertEquals(identifier, conditionFromBuilder.getFieldIdentifier()); - assertEquals(value, conditionFromBuilder.getValue()); - - final Condition conditionWithEnum = Condition.create(EQ, identifier, value); - assertEquals(operator, conditionWithEnum.getOperator()); - assertEquals(identifier, conditionWithEnum.getFieldIdentifier()); - assertEquals(value, conditionWithEnum.getValue()); - - final Condition conditionConstructorWithEnum = new Condition(EQ, identifier, value); - assertEquals(operator, conditionConstructorWithEnum.getOperator()); - assertEquals(identifier, conditionConstructorWithEnum.getFieldIdentifier()); - assertEquals(value, conditionConstructorWithEnum.getValue()); - - final Condition conditionFromBuilderWithEnum = - Condition.builder() - .withOperator(EQ) - .withValue(value) - .withFieldIdentifier(identifier) - .build(); - assertEquals(operator, conditionFromBuilderWithEnum.getOperator()); - assertEquals(identifier, conditionFromBuilderWithEnum.getFieldIdentifier()); - assertEquals(value, conditionFromBuilderWithEnum.getValue()); - - tarantoolCriteria.addCondition(condition); - tarantoolCriteria.addCondition(conditionConstructor); - tarantoolCriteria.addCondition(conditionFromBuilder); - - tarantoolCriteria.addCondition(conditionWithEnum); - tarantoolCriteria.addCondition(conditionConstructorWithEnum); - tarantoolCriteria.addCondition(conditionFromBuilderWithEnum); - - final Conditions expectedConditions = new Conditions(); - expectedConditions.addAll( - Arrays.asList( - condition, - conditionConstructor, - conditionFromBuilder, - conditionWithEnum, - conditionConstructorWithEnum, - conditionFromBuilderWithEnum)); - - assertEquals(expectedConditions, tarantoolCriteria.getConditions()); - } - - @Test - void testFirst() { - final TarantoolCriteria criteria = new TarantoolCriteria(); - criteria.withFirst(1); - - final String key = "first"; - SelectOptions options = criteria.getOptions(); - assertEquals(1, options.getOptions().get(key)); - - criteria.clear(); - criteria.withFirst(-1); - options = criteria.getOptions(); - assertEquals(-1, options.getOptions().get(key)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolKeysetScrollPositionTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolKeysetScrollPositionTest.java deleted file mode 100644 index ff6ca187..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolKeysetScrollPositionTest.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.UUID; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.function.Executable; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.ScrollPosition; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.Pair; - -class TarantoolKeysetScrollPositionTest { - - private static final Pair INDEX_KEY = Pair.of("pk", 123); - - private static final Pair INDEX_KEY_WITH_NULL_VALUE = Pair.of("pk", null); - - static Stream dataForTestTarantoolScrollPositionCreateDoesntThrow() { - return Stream.of( - () -> TarantoolScrollPosition.forward(INDEX_KEY), - () -> TarantoolScrollPosition.forward(INDEX_KEY_WITH_NULL_VALUE), - () -> TarantoolScrollPosition.backward(INDEX_KEY), - () -> TarantoolScrollPosition.backward(INDEX_KEY_WITH_NULL_VALUE)); - } - - @ParameterizedTest - @MethodSource("dataForTestTarantoolScrollPositionCreateDoesntThrow") - void testTarantoolScrollPositionCreateDoesntThrow(Executable scrollPositionCreateAction) { - assertDoesNotThrow(scrollPositionCreateAction); - } - - static Stream dataForTestTarantoolScrollPositionCreateThrows() { - return Stream.of( - () -> TarantoolScrollPosition.forward(null), () -> TarantoolScrollPosition.backward(null)); - } - - @ParameterizedTest - @MethodSource("dataForTestTarantoolScrollPositionCreateThrows") - void testTarantoolScrollPositionCreateThrows(Executable scrollPositionCreateAction) { - assertThrows(IllegalArgumentException.class, scrollPositionCreateAction); - } - - static Stream dataForTestEqualsAndHashCode() { - - List equalScrollPositionsWithKey = - Arrays.asList( - TarantoolScrollPosition.forward(INDEX_KEY), TarantoolScrollPosition.forward(INDEX_KEY)); - - TarantoolScrollPosition notEqualScrollPosition = - TarantoolScrollPosition.forward(INDEX_KEY_WITH_NULL_VALUE); - - final int ITERATION_COUNT = 100; - - return Stream.of( - Arguments.of(equalScrollPositionsWithKey, notEqualScrollPosition, ITERATION_COUNT), - Arguments.of(equalScrollPositionsWithKey, null, ITERATION_COUNT)); - } - - @ParameterizedTest - @MethodSource("dataForTestEqualsAndHashCode") - void testEqualsAndHashCode( - List scrollPositions, - ScrollPosition notEqualScrollPosition, - int iterationCount) { - for (int i = 0; i < iterationCount; i++) { - for (ScrollPosition scrollPosition : scrollPositions) { - for (ScrollPosition otherScrollPosition : scrollPositions) { - assertEquals(scrollPosition, otherScrollPosition); - assertEquals(scrollPosition.hashCode(), otherScrollPosition.hashCode()); - } - assertNotEquals(scrollPosition, notEqualScrollPosition); - if (notEqualScrollPosition != null) { - assertNotEquals(scrollPosition.hashCode(), notEqualScrollPosition.hashCode()); - } - } - } - } - - static Stream dataForTestIsInitial() { - var startingIndex = Pair.of("pk", Collections.emptyList()); - var complexIndex = Pair.of("pk", Arrays.asList(1, UUID.randomUUID())); - Object nonNullCursor = Arrays.asList(1, 2, 3, 4); - return Stream.of( - Arguments.of(TarantoolScrollPosition.backward(INDEX_KEY), false), - Arguments.of(TarantoolScrollPosition.forward(INDEX_KEY), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, null), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, nonNullCursor), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, nonNullCursor), false), - Arguments.of(TarantoolScrollPosition.backward(startingIndex), true), - Arguments.of(TarantoolScrollPosition.forward(startingIndex), true), - Arguments.of(new TarantoolKeysetScrollPosition(startingIndex, FORWARD, null), true), - Arguments.of(new TarantoolKeysetScrollPosition(startingIndex, BACKWARD, null), true), - Arguments.of( - new TarantoolKeysetScrollPosition(startingIndex, FORWARD, nonNullCursor), false), - Arguments.of( - new TarantoolKeysetScrollPosition(startingIndex, BACKWARD, nonNullCursor), false), - Arguments.of(TarantoolScrollPosition.backward(complexIndex), false), - Arguments.of(TarantoolScrollPosition.forward(complexIndex), false)); - } - - @ParameterizedTest - @MethodSource("dataForTestIsInitial") - void testIsInitial(ScrollPosition scrollPosition, boolean expectedIsInitial) { - assertEquals(scrollPosition.isInitial(), expectedIsInitial); - } - - static Stream dataForTestGetCursor() { - var cursor = String.valueOf(2); - return Stream.of( - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), null), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, cursor), cursor)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetCursor") - void testGetCursor(TarantoolKeysetScrollPosition scrollPosition, Object expectedCursor) { - assertEquals(expectedCursor, scrollPosition.getCursor()); - } - - static Stream dataForTestGetKeyIndex() { - return Stream.of( - Arguments.of(TarantoolScrollPosition.forward(INDEX_KEY), INDEX_KEY), - Arguments.of(TarantoolScrollPosition.backward(INDEX_KEY), INDEX_KEY)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetKeyIndex") - void testGetKeyIndex( - TarantoolKeysetScrollPosition scrollPosition, Pair expectedIndexKey) { - assertEquals(expectedIndexKey, scrollPosition.getIndexKey()); - } - - static Stream dataForTestGetDirection() { - return Stream.of( - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), FORWARD), - Arguments.of( - new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, String.valueOf(2)), BACKWARD)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetDirection") - void testGetDirection( - TarantoolKeysetScrollPosition scrollPosition, PaginationDirection expectedDirection) { - assertEquals(expectedDirection, scrollPosition.getDirection()); - } - - static Stream dataForTestReverse() { - Object someKey = String.valueOf(1); - var indexKeyAfterReverse = Pair.of(INDEX_KEY.getFirst(), INDEX_KEY.getSecond()); - - return Stream.of( - Arguments.of( - TarantoolScrollPosition.forward(INDEX_KEY), - TarantoolScrollPosition.backward(indexKeyAfterReverse)), - Arguments.of( - new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, someKey), - new TarantoolKeysetScrollPosition(indexKeyAfterReverse, BACKWARD, someKey))); - } - - @ParameterizedTest - @MethodSource("dataForTestReverse") - void testGetReverse( - TarantoolScrollPosition scrollPosition, - TarantoolKeysetScrollPosition expectedReversedPosition) { - assertEquals(expectedReversedPosition, scrollPosition.reverse()); - } - - static Stream dataForTestIsScrollsBackward() { - return Stream.of( - Arguments.of( - TarantoolScrollPosition.forward(Pair.of("pk", Collections.emptyList())), false), - Arguments.of( - TarantoolScrollPosition.backward(Pair.of("pk", Collections.emptyList())), true)); - } - - @ParameterizedTest - @MethodSource("dataForTestIsScrollsBackward") - void testIsScrollsBackward(TarantoolScrollPosition position, boolean expectedIsScrollsBackward) { - assertEquals(expectedIsScrollsBackward, position.isScrollsBackward()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolPageImplTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolPageImplTest.java deleted file mode 100644 index a6b15fa0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolPageImplTest.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data34.utils.entity.Person; - -class TarantoolPageImplTest { - - private static final List PERSONS = generatePersons(PERSONS_COUNT); - - private static final int DEFAULT_PAGE_SIZE_PER_TEST_CLASS = 10; - - private static final int DEFAULT_PAGE_NUMBER_PER_TEST_CLASS = 0; - - private static final Pageable FIRST_PAGE_PAGEABLE_PER_TEST_CLASS = - new TarantoolPageRequest<>( - DEFAULT_PAGE_NUMBER_PER_TEST_CLASS, DEFAULT_PAGE_SIZE_PER_TEST_CLASS, null); - - private static final long MULTIPLIER = 2L; - - private static final BiFunction GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE = - (pageSize, operator) -> { - switch (operator) { - // pageSize > totalPageCount - case ">": - { - return pageSize / MULTIPLIER; - } - // pageSize < totalPageCount - case "<": - { - return MULTIPLIER * pageSize; - } - // pageSize == totalPageCount - case "==": - { - return Long.valueOf(pageSize); - } - default: - throw new IllegalArgumentException("The passed option isn't supported"); - } - }; - - private static final List EMPTY_CONTENT = Collections.emptyList(); - - protected static Stream dataForTestConstructors() { - TarantoolPageable> pageable = - new TarantoolPageRequest<>(0, DEFAULT_PAGE_SIZE_PER_TEST_CLASS, null); - - long personsSize = PERSONS.size(); - - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>(PERSONS, pageable, personsSize), - PERSONS.size() / DEFAULT_PAGE_SIZE_PER_TEST_CLASS, - personsSize), - Arguments.of(new TarantoolPageImpl<>(PERSONS), 1, personsSize), - Arguments.of(new TarantoolPageImpl<>(), 1, 0L)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructors") - void testConstructors(Page> page, int totalPages, long totalElements) { - assertEquals(totalPages, page.getTotalPages()); - assertEquals(totalElements, page.getTotalElements()); - } - - static Stream dataForTestConstructorsThrowsIllegalArgumentException() { - final class DummyTarantoolPageRequest implements Pageable { - - @Override - public int getPageNumber() { - return 0; - } - - @Override - public int getPageSize() { - return 0; - } - - @Override - public long getOffset() { - return 0L; - } - - @Override - public Sort getSort() { - return null; - } - - @Override - public Pageable next() { - return null; - } - - @Override - public Pageable previousOrFirst() { - return null; - } - - @Override - public Pageable first() { - return null; - } - - @Override - public Pageable withPage(int pageNumber) { - return null; - } - - @Override - public boolean hasPrevious() { - return false; - } - } - - Pageable dummyPageable = new DummyTarantoolPageRequest(); - - return Stream.of( - Arguments.of(null, null, "Content must not be null"), - Arguments.of(Collections.emptyList(), null, "Pageable must not be null"), - Arguments.of( - Collections.emptyList(), - dummyPageable, - "Pageable must be TarantoolPageable or Unpaged type")); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructorsThrowsIllegalArgumentException") - void testConstructors_throws_IllegalArgumentException( - List content, Pageable pageable, String errorMsg) { - assertThrows( - IllegalArgumentException.class, - () -> new TarantoolPageImpl<>(content, pageable, 0L), - errorMsg); - } - - static Stream dataForTestGetTotalPages() { - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, ">")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "<")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - PERSONS.size() / FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, ">")), - 0), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "<")), - 0), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "==")), - 0)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTotalPages") - void testGetTotalPages(Page page, long totalPagesCount) { - assertEquals(totalPagesCount, page.getTotalPages()); - } - - static Stream dataForTestGetTotalElements() { - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() / MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() * MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - PERSONS.size()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() * MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTotalElements") - void testGetTotalElements(Page page, long totalElementCount) { - assertEquals(totalElementCount, page.getTotalElements()); - } - - static Stream dataForTestHasNext() { - return Stream.of( - Arguments.of( - false, - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())), - Arguments.of( - true, - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - MULTIPLIER * FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())), - Arguments.of( - false, - new TarantoolPageImpl<>( - PERSONS, - Pageable.unpaged(), - MULTIPLIER * FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()))); - } - - @ParameterizedTest - @MethodSource("dataForTestHasNext") - void testHasNext(boolean exceptedBool, Page page) { - assertEquals(exceptedBool, page.hasNext()); - } - - @ParameterizedTest - @MethodSource("dataForTestHasNext") - void testIsLast(boolean notEqualBool, Page page) { - assertNotEquals(notEqualBool, page.isLast()); - } - - static Stream dataForTestMap() { - List exceptedNames = PERSONS.stream().map(Person::getName).collect(Collectors.toList()); - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - exceptedNames, - (Function) Person::getName)); - } - - @ParameterizedTest - @MethodSource("dataForTestMap") - void testMap(Page page, List exceptedNames, Function mapFunction) { - List names = page.map(mapFunction).toList(); - assertEquals(exceptedNames, names); - } - - static Stream dataForTestEqualsAndHashCode() { - List> equalPages = - Arrays.asList( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())); - - final int ITERATION_COUNT = 100; - - return Stream.of( - Arguments.of( - equalPages, - new TarantoolPageImpl<>(EMPTY_CONTENT, Pageable.unpaged(), 150), - ITERATION_COUNT), - Arguments.of(equalPages, null, ITERATION_COUNT)); - } - - @ParameterizedTest - @MethodSource("dataForTestEqualsAndHashCode") - void testEqualsAndHashCode(List> pages, Page notEqualPage, int iterationCount) { - for (int i = 0; i < iterationCount; i++) { - for (Page page : pages) { - for (Page otherPage : pages) { - assertEquals(page, otherPage); - assertEquals(page.hashCode(), otherPage.hashCode()); - } - assertNotEquals(page, notEqualPage); - if (notEqualPage != null) { - assertNotEquals(page.hashCode(), notEqualPage.hashCode()); - } - } - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolPageRequestTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolPageRequestTest.java deleted file mode 100644 index b4a84225..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolPageRequestTest.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.util.Arrays; -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.AbstractPageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data34.utils.entity.Person; - -class TarantoolPageRequestTest { - - private static final int PAGE_SIZE = 10; - - private static final Person CURSOR = new Person(0, true, "0"); - - private static final int PAGE_NUMBER = 0; - - protected static Stream dataForTestConstructors() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - null, - FORWARD), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - CURSOR, - FORWARD), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, null), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - null, - FORWARD)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructors") - void testConstructors( - Supplier>> constructorGenerator, - int pageNumber, - int size, - Sort sort, - GenericPerson cursor, - PaginationDirection direction) { - TarantoolPageable> pageable = constructorGenerator.get(); - - assertEquals(size, pageable.getPageSize()); - assertEquals(pageNumber, pageable.getPageNumber()); - assertEquals(sort, pageable.getSort()); - assertEquals(cursor, pageable.getTupleCursor()); - assertEquals(direction, pageable.getPaginationDirection()); - } - - protected static Stream dataTestGetSort() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - Sort.unsorted()), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - Sort.unsorted())); - } - - @ParameterizedTest - @MethodSource("dataTestGetSort") - void testGetSort(Supplier>> constructorGenerator, Sort sort) { - Pageable pageable = constructorGenerator.get(); - assertEquals(sort, pageable.getSort()); - } - - protected static Stream dataForTestGetTupleCursor() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - null), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTupleCursor") - void testGetTupleCursor( - Supplier>> constructorGenerator, GenericPerson person) { - TarantoolPageable> pageable = constructorGenerator.get(); - assertEquals(person, pageable.getTupleCursor()); - } - - protected static Stream dataForTestNext() { - final Person NEXT_CURSOR = - new Person(CURSOR.getId() + PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), CURSOR, NEXT_CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataForTestNext") - void testNext( - TarantoolPageable> pageable, - GenericPerson cursor, - GenericPerson nextCursor) { - assertEquals(cursor, pageable.getTupleCursor()); - - TarantoolPageable> nextPageable = pageable.next(nextCursor); - assertEquals(nextCursor, nextPageable.getTupleCursor()); - - assertEquals(pageable.getPageSize(), nextPageable.getPageSize()); - assertEquals(pageable.getPageNumber() + 1, nextPageable.getPageNumber()); - assertEquals(pageable.getSort(), nextPageable.getSort()); - assertEquals(pageable.getOffset() + PAGE_SIZE, nextPageable.getOffset()); - } - - @Test - void testNextUnsupported() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::next); - } - - protected static Stream dataTestGetPaginationDirection() { - final Person PREV_CURSOR = new Person(CURSOR.getId(), CURSOR.getIsMarried(), CURSOR.getName()); - final Person NEXT_CURSOR = - new Person(PREV_CURSOR.getId() + PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, NEXT_CURSOR), NEXT_CURSOR, PREV_CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataTestGetPaginationDirection") - void testGetPaginationDirection( - TarantoolPageable> pageable, - GenericPerson nextCursor, - GenericPerson prevCursor) { - - assertEquals(FORWARD, pageable.getPaginationDirection()); - - TarantoolPageable> prevPageable = pageable.previousOrFirst(prevCursor); - assertEquals(PaginationDirection.BACKWARD, prevPageable.getPaginationDirection()); - - TarantoolPageable> nextPageable = prevPageable.next(nextCursor); - assertEquals(FORWARD, nextPageable.getPaginationDirection()); - assertEquals(pageable, nextPageable); - } - - protected static Stream dataTestFirst() { - final Person CURSOR = new Person(2 * PAGE_SIZE, true, "name"); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(0, PAGE_SIZE, null))); - } - - @ParameterizedTest - @MethodSource("dataTestFirst") - void testFirst( - TarantoolPageable> pageable, - TarantoolPageable> exceptedFirstPageable) { - assertEquals(exceptedFirstPageable, pageable.first()); - } - - @Test - void testWithPage() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, () -> pageable.withPage(100)); - } - - protected static Stream dataTestPreviousOrFirst() { - final Person CURSOR = new Person(PAGE_SIZE, true, "name"); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, CURSOR), - new Person(CURSOR.getId() - PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()))); - } - - @ParameterizedTest - @MethodSource("dataTestPreviousOrFirst") - void testPreviousOrFirst( - TarantoolPageable> pageable, GenericPerson prevCursor) { - - TarantoolPageable> prevPageable = pageable.previousOrFirst(prevCursor); - - assertNotEquals(pageable, prevPageable); - assertEquals(pageable.getPageSize(), prevPageable.getPageSize()); - assertEquals(pageable.getOffset() - PAGE_SIZE, prevPageable.getOffset()); - assertEquals(pageable.getSort(), prevPageable.getSort()); - assertEquals(pageable.getPageNumber() - 1, prevPageable.getPageNumber()); - - // here will be first with null cursor - TarantoolPageable> firstPageable = prevPageable.previousOrFirst(prevCursor); - assertNull(firstPageable.getTupleCursor()); - } - - @Test - void testPreviousOrFirstUnsupported() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::previousOrFirst); - } - - @Test - void testPreviousUnsupported() { - AbstractPageRequest pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::previous); - } - - protected static Stream dataForTestEquals() { - return Stream.of( - Arguments.of( - Arrays.asList( - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR)), - new TarantoolPageRequest<>(PAGE_SIZE))); - } - - @ParameterizedTest - @MethodSource("dataForTestEquals") - void testEquals( - List>> equalPageableList, - TarantoolPageable> notEqualPageable) { - - assertTrue(equalPageableList.size() > 0); - final int COUNT = 10; - - for (int i = 0; i < COUNT; i++) { - for (TarantoolPageable> pageable : equalPageableList) { - for (TarantoolPageable> secondPageable : equalPageableList) { - assertEquals(pageable, secondPageable); - } - assertNotEquals(pageable, null); - assertNotEquals(pageable, notEqualPageable); - } - } - } - - @ParameterizedTest - @MethodSource("dataForTestEquals") - void testHashCode( - List>> equalPageableList, - TarantoolPageable> notEqualPageable) { - - for (TarantoolPageable> pageable : equalPageableList) { - for (TarantoolPageable> secondPageable : equalPageableList) { - assertEquals(pageable.hashCode(), secondPageable.hashCode()); - } - assertNotEquals(pageable.hashCode(), notEqualPageable.hashCode()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolSliceTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolSliceTest.java deleted file mode 100644 index 8822d24c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/query/TarantoolSliceTest.java +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.function.Executable; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.spring.data34.utils.entity.Person; - -public class TarantoolSliceTest { - - private static final int PAGE_SIZE = 10; - - private static final int PAGE_NUMBER = 0; - - private static final Person SOME_CURSOR = new Person(0, true, "0"); - - private static List PERSONS; - - private static final Pageable SOME_PAGEABLE = - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR); - - @BeforeAll - static void setUp() { - PERSONS = generatePersons(PERSONS_COUNT); - } - - static Stream dataForTestConstructorsShouldThrow() { - Pageable tarantoolPageable = new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR); - Pageable notTarantoolPageable = Pageable.ofSize(PAGE_SIZE); - return Stream.of( - Arguments.of(null, tarantoolPageable, false), - Arguments.of(null, tarantoolPageable, true), - Arguments.of(PERSONS, null, false), - Arguments.of(PERSONS, null, true), - Arguments.of(PERSONS, notTarantoolPageable, false), - Arguments.of(PERSONS, notTarantoolPageable, true)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructorsShouldThrow") - public void testConstructorsShouldThrow(List content, Pageable pageable, boolean hasNext) { - assertThrows( - IllegalArgumentException.class, () -> new TarantoolSliceImpl<>(content, pageable, hasNext)); - } - - static Stream dataForTestConstructorsDoesntThrow() { - return Stream.of( - () -> new TarantoolSliceImpl<>(PERSONS), - () -> new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - () -> new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestConstructorsDoesntThrow") - public void testConstructorsDoesntThrow(Executable runTestCase) { - assertDoesNotThrow(runTestCase); - } - - static Stream dataForTestGetNumber() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getPageNumber()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetNumber") - public void testGetNumber(Slice slice, int expectedPageNumber) { - assertEquals(expectedPageNumber, slice.getNumber()); - } - - static Stream dataForTestGetSize() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getPageSize()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS.size()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), - SOME_PAGEABLE.getPageSize()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetSize") - public void testGetSize(Slice slice, int expectedSize) { - assertEquals(expectedSize, slice.getSize()); - } - - static Stream dataForTestGetNumberOfElements() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), PERSONS.size()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS.size()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), 0), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetNumberOfElements") - public void testGetNumberOfElements(Slice slice, int expectedNumberOfElements) { - assertEquals(expectedNumberOfElements, slice.getNumberOfElements()); - } - - static Stream dataForTestGetContent() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), PERSONS), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), - Collections.emptyList()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Collections.emptyList())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetContent") - public void testGetContent(Slice slice, List expectedContent) { - assertEquals(expectedContent, slice.getContent()); - } - - static Stream dataForTestHasContent() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), true), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), false), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasContent") - void testHasContent(Slice slice, boolean expectedHasContent) { - assertEquals(expectedHasContent, slice.hasContent()); - } - - static Stream dataForTestGetSort() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getSort()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Sort.unsorted())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetSort") - void testGetSort(Slice slice, Sort expectedSort) { - assertEquals(expectedSort, slice.getSort()); - } - - static Stream dataForTestIsFirst() { - final int MIDDLE_PAGE_NUMBER = 2; - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), true), - true), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), true), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - true), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), true)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestIsFirst") - void testIsFirst(Slice slice, boolean expectedIsFirst) { - assertEquals(expectedIsFirst, slice.isFirst()); - } - - static Stream dataForTestIsLast() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), false), - // last imitation - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, false), true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), true), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), true), - // last imitation - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, false), true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), true)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestIsLast") - void testIsLast(Slice slice, boolean expectedIsLast) { - assertEquals(expectedIsLast, slice.isLast()); - } - - static Stream dataForTestHasNext() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, new TarantoolPageRequest<>(PAGE_SIZE), true), true), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, new TarantoolPageRequest<>(PAGE_SIZE), false), false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), new TarantoolPageRequest<>(PAGE_SIZE), true), - false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), new TarantoolPageRequest<>(PAGE_SIZE), false), - false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasNext") - void testHasNext(Slice slice, boolean expectedHasNext) { - assertEquals(expectedHasNext, slice.hasNext()); - } - - static Stream dataForTestHasPrevious() { - final int MIDDLE_PAGE_NUMBER = 2; - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), false), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - false), - true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), false), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - false), - false), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), false), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasPrevious") - void testHasPrevious(Slice slice, boolean expectedHasPrevious) { - assertEquals(expectedHasPrevious, slice.hasPrevious()); - } - - static Stream dataForTestGetPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, pageable, true), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), pageable), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, pageable, false), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), pageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), - Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetPageable") - void testGetPageable(Slice slice, Pageable expectedPageable) { - assertEquals(expectedPageable, slice.getPageable()); - } - - static Stream dataForTestNextPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, true), - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - new TarantoolPageRequest<>(5, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestNextPageable") - void testNextPageable(Slice slice, Pageable expectedNextPageable) { - assertEquals(expectedNextPageable, slice.nextPageable()); - } - - static Stream dataForTestPreviousPageable() { - Pageable firstPagePageable = new TarantoolPageRequest<>(PAGE_SIZE); - Pageable secondPagePageable = - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)); - - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, false), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(4, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(0)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPreviousPageable") - void testPreviousPageable(Slice slice, Pageable expectedPrevPageable) { - assertEquals(expectedPrevPageable, slice.previousPageable()); - } - - static Stream dataForTestNextOrLastPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, true), - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), pageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, false), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), pageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - new TarantoolPageRequest<>(5, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - false), - new TarantoolPageRequest<>(4, PAGE_SIZE, null))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestNextOrLastPageable") - void testNextOrLastPageable(Slice slice, Pageable expectedNextOrLastPageable) { - assertEquals(expectedNextOrLastPageable, slice.nextOrLastPageable()); - } - - static Stream dataForTestPreviousOrFirstPageable() { - Pageable firstPagePageable = new TarantoolPageRequest<>(PAGE_SIZE); - Pageable secondPagePageable = - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)); - - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, true), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, true), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, false), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, false), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, true), - secondPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, false), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, false), - secondPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(4, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(0)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPreviousOrFirstPageable") - void testPreviousOrFirstPageable(Slice slice, Pageable expectedPrevOrFirstPageable) { - assertEquals(expectedPrevOrFirstPageable, slice.previousOrFirstPageable()); - } - - static Stream dataForTestMap() { - - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - List expectedNames = PERSONS.stream().map(Person::getName).collect(Collectors.toList()); - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, pageable, true), - (Function) Person::getName, - expectedNames, - new TarantoolSliceImpl<>(expectedNames, pageable, true))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestMap") - void testMap( - Slice slice, - Function mapper, - List expectedMappedList, - Slice expectedMappedSlice) { - assertEquals(expectedMappedSlice, slice.map(mapper)); - assertEquals(expectedMappedList, slice.map(mapper).getContent()); - } - - protected static Stream dataForTestEquals() { - - return Stream.of( - Arguments.of( - Arrays.asList( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true)), - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestEquals") - void testEquals(List> equalPageableList, Slice notEqualPageable) { - - assertFalse(equalPageableList.isEmpty()); - final int COUNT = 10; - - for (int i = 0; i < COUNT; i++) { - for (Slice pageable : equalPageableList) { - for (Slice secondPageable : equalPageableList) { - assertEquals(pageable, secondPageable); - } - assertNotEquals(pageable, null); - assertNotEquals(pageable, notEqualPageable); - } - } - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestEquals") - void testHashCode(List> equalPageableList, Slice notEqualPageable) { - for (Slice pageable : equalPageableList) { - for (Slice secondPageable : equalPageableList) { - assertEquals(pageable.hashCode(), secondPageable.hashCode()); - } - assertNotEquals(pageable.hashCode(), notEqualPageable.hashCode()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/TarantoolTestSupport.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/TarantoolTestSupport.java deleted file mode 100644 index 3223c0d0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/TarantoolTestSupport.java +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.UUID; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.Consumer; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.introspector.Property; -import org.yaml.snakeyaml.nodes.NodeTuple; -import org.yaml.snakeyaml.nodes.Tag; -import org.yaml.snakeyaml.representer.Representer; - -import static io.tarantool.balancer.BalancerMode.DEFAULT_BALANCER_MODE; -import static io.tarantool.client.TarantoolClient.DEFAULT_TAG; -import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_PASSWORD; -import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_USERNAME; -import static io.tarantool.core.protocol.requests.IProtoAuth.DEFAULT_AUTH_TYPE; -import static io.tarantool.pool.InstanceConnectionGroup.DEFAULT_HOST; -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import io.tarantool.balancer.BalancerMode; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.core.protocol.requests.IProtoAuth; -import io.tarantool.mapping.Tuple; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyFlushConsolidationHandler; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyHeartbeatOpts; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.spring.data34.config.properties.TarantoolProperties; -import io.tarantool.spring.data34.utils.entity.ComplexPerson; -import io.tarantool.spring.data34.utils.entity.Person; - -public class TarantoolTestSupport { - - private static final ThreadLocalRandom random = ThreadLocalRandom.current(); - private static final Map firstInternalMap = new HashMap<>(); - private static final Map secondInternalMap = new HashMap<>(); - private static final Map externalMap = new HashMap<>(); - private static final Representer representer; - public static final String PERSON_SPACE = "person"; - public static final String COMPLEX_PERSON_SPACE = "complex_person"; - public static final int PERSONS_COUNT = 100; - public static final Random RANDOMIZER = new Random(); - public static final Person UNKNOWN_PERSON = new Person(-1, true, "Alien"); - public static final ComplexPerson UNKNOWN_COMPLEX_PERSON = - new ComplexPerson(-1, new UUID(0, 0), true, "Alien"); - - public static final Path DEFAULT_TEST_PROPERTY_DIR = Paths.get("target", "test-classes"); - private static final Yaml yaml; - - static { - representer = - new Representer(new DumperOptions()) { - @Override - @Nullable - protected NodeTuple representJavaBeanProperty( - Object javaBean, Property property, @Nullable Object propertyValue, Tag customTag) { - if (propertyValue == null) { - return null; - } else { - return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag); - } - } - }; - representer.addClassTag(TarantoolProperties.class, Tag.MAP); - yaml = new Yaml(representer, new DumperOptions()); - } - - public static TarantoolProperties writeTestPropertiesYaml(@NonNull final String fileName) - throws IOException { - return writeTestPropertiesYaml(fileName, createRandomProperty()); - } - - public static TarantoolProperties writeTestPropertiesYaml( - final String fileName, final TarantoolProperties properties) throws IOException { - final File FILE = DEFAULT_TEST_PROPERTY_DIR.resolve(fileName).toFile().getAbsoluteFile(); - - try (Writer writer = new FileWriter(FILE)) { - firstInternalMap.put("tarantool", properties); - secondInternalMap.put("data", firstInternalMap); - externalMap.put("spring", secondInternalMap); - - yaml.dump(externalMap, writer); - replaceNullToDefault(properties); - return properties; - } - } - - public static void writeTestEmptyPropertiesYaml(@NonNull final String fileName) - throws IOException { - final File FILE = DEFAULT_TEST_PROPERTY_DIR.resolve(fileName).toFile().getAbsoluteFile(); - try (Writer writer = new FileWriter(FILE)) { - yaml.dump(Collections.emptyMap(), writer); - } - } - - private static void replaceNullToDefault(final TarantoolProperties result) { - - if (result.getHost() == null) { - result.setHost(DEFAULT_HOST); - } - - if (result.getUserName() == null) { - result.setUserName(DEFAULT_CRUD_USERNAME); - } - - if (result.getBalancerMode() == null) { - result.setBalancerMode(DEFAULT_BALANCER_MODE); - } - - if (result.getPassword() == null) { - result.setPassword(DEFAULT_CRUD_PASSWORD); - } - - if (result.getConnectionGroups() != null) { - for (PropertyInstanceConnectionGroup propertyInstanceConnectionGroup : - result.getConnectionGroups()) { - if (propertyInstanceConnectionGroup.getAuthType() == null) { - propertyInstanceConnectionGroup.setAuthType(DEFAULT_AUTH_TYPE); - } - - if (propertyInstanceConnectionGroup.getHost() == null) { - propertyInstanceConnectionGroup.setHost(DEFAULT_HOST); - } - - if (propertyInstanceConnectionGroup.getTag() == null) { - propertyInstanceConnectionGroup.setTag(DEFAULT_TAG); - } - - if (propertyInstanceConnectionGroup.getUserName() == null) { - propertyInstanceConnectionGroup.setUserName(DEFAULT_CRUD_USERNAME); - } - - if (propertyInstanceConnectionGroup.getUserName() == null) { - propertyInstanceConnectionGroup.setPassword(DEFAULT_CRUD_PASSWORD); - } - } - } - } - - private static TarantoolProperties createRandomProperty() { - final int intVar = 999; - final long longVar = 9999L; - final List booleanVar = Arrays.asList(true, false); - - PropertyHeartbeatOpts propertyHeartbeatOpts = - heartbeat( - choiceOrNull(longVar), - choiceOrNull(intVar), - choiceOrNull(intVar), - choiceOrNull(intVar)); - - PropertyFlushConsolidationHandler propertyFlushConsolidationHandler = - choiceOrNull(flushConsolidation(choiceOrNull(intVar), choiceOrNull(booleanVar))); - - PropertyInstanceConnectionGroup propertyInstanceConnectionGroup = - choiceOrNull( - connectionGroup( - choiceOrNull("host"), - "password", - choiceOrNull(intVar), - choiceOrNull(intVar), - choiceOrNull("tag"), - "user", - choiceOrNull(Arrays.asList(IProtoAuth.AuthType.values())), - propertyFlushConsolidationHandler)); - List propertyInstanceConnectionGroups = null; - if (propertyInstanceConnectionGroup != null) { - propertyInstanceConnectionGroups = new ArrayList<>(); - propertyInstanceConnectionGroups.add(propertyInstanceConnectionGroup); - } - - return tarantoolProperties( - choiceOrNull("host"), - choiceOrNull("password"), - choiceOrNull(intVar), - choiceOrNull("user"), - propertyInstanceConnectionGroups, - choiceOrNull(intVar), - choiceOrNull(booleanVar), - choiceOrNull(propertyHeartbeatOpts), - choiceOrNull(longVar), - choiceOrNull(longVar), - choiceOrNull(booleanVar), - choiceOrNull(booleanVar), - choiceOrNull(Arrays.asList(BalancerMode.values()))); - } - - @Nullable - public static T choiceOrNull(@Nullable T element) { - int rnd = random.nextInt(2); - if (rnd == 0 || element == null) { - return null; - } - return element; - } - - public static PropertyHeartbeatOpts heartbeat( - @Nullable Long pingInterval, - @Nullable Integer invalidationThreshold, - @Nullable Integer windowSize, - @Nullable Integer deathThreshold) { - - PropertyHeartbeatOpts propertyHeartbeatOpts = new PropertyHeartbeatOpts(); - if (invalidationThreshold != null) { - propertyHeartbeatOpts.setInvalidationThreshold(invalidationThreshold); - } - if (pingInterval != null) { - propertyHeartbeatOpts.setPingInterval(pingInterval); - } - if (deathThreshold != null) { - propertyHeartbeatOpts.setDeathThreshold(deathThreshold); - } - if (windowSize != null) { - propertyHeartbeatOpts.setWindowSize(windowSize); - } - - return propertyHeartbeatOpts; - } - - public static PropertyFlushConsolidationHandler flushConsolidation( - @Nullable Integer explicitFlushAfterFlushes, - @Nullable Boolean consolidateWhenNoReadInProgress) { - - PropertyFlushConsolidationHandler propertyFlushConsolidationHandler = - new PropertyFlushConsolidationHandler(); - if (explicitFlushAfterFlushes != null) { - propertyFlushConsolidationHandler.setExplicitFlushAfterFlushes(explicitFlushAfterFlushes); - } - - if (consolidateWhenNoReadInProgress != null) { - propertyFlushConsolidationHandler.setConsolidateWhenNoReadInProgress( - consolidateWhenNoReadInProgress); - } - return propertyFlushConsolidationHandler; - } - - @Nullable - public static T choiceOrNull(@Nullable List list) { - if (list == null || list.isEmpty()) { - return null; - } - int rnd = random.nextInt(list.size() + 1); - - if (rnd == list.size()) { - return null; - } - return list.get(rnd); - } - - @NonNull - public static PropertyInstanceConnectionGroup connectionGroup( - @Nullable String host, - @Nullable String password, - @Nullable Integer port, - @Nullable Integer connectionNumber, - @Nullable String tag, - @Nullable String user, - @Nullable IProtoAuth.AuthType type, - @Nullable PropertyFlushConsolidationHandler propertyFlushConsolidationHandler) { - - PropertyInstanceConnectionGroup propertyInstanceConnectionGroup = - new PropertyInstanceConnectionGroup(); - propertyInstanceConnectionGroup.setHost(host); - if (connectionNumber != null) { - propertyInstanceConnectionGroup.setConnectionGroupSize(connectionNumber); - } - propertyInstanceConnectionGroup.setAuthType(type); - propertyInstanceConnectionGroup.setPassword(password); - if (port != null) { - propertyInstanceConnectionGroup.setPort(port); - } - propertyInstanceConnectionGroup.setTag(tag); - propertyInstanceConnectionGroup.setUserName(user); - - propertyInstanceConnectionGroup.setFlushConsolidationHandler(propertyFlushConsolidationHandler); - return propertyInstanceConnectionGroup; - } - - @NonNull - public static TarantoolProperties tarantoolProperties( - @Nullable String host, - @Nullable String password, - @Nullable Integer port, - @Nullable String user, - @Nullable List propertyInstanceConnectionGroups, - @Nullable Integer eventLoopThreadsCount, - @Nullable Boolean enableGracefulShutdown, - @Nullable PropertyHeartbeatOpts propertyHeartbeatOptsOpts, - @Nullable Long connectTimeout, - @Nullable Long reconnectAfter, - @Nullable Boolean fetchSchema, - @Nullable Boolean ignoreOldSchemaVersion, - @Nullable BalancerMode balancerClass) { - - TarantoolProperties prop = new TarantoolProperties(); - prop.setHost(host); - prop.setPassword(password); - if (port != null) { - prop.setPort(port); - } - prop.setUserName(user); - prop.setConnectionGroups(propertyInstanceConnectionGroups); - if (eventLoopThreadsCount != null) { - prop.setEventLoopThreadsCount(eventLoopThreadsCount); - } - - if (enableGracefulShutdown != null) { - prop.setGracefulShutdownEnabled(enableGracefulShutdown); - } - prop.setHeartbeat(propertyHeartbeatOptsOpts); - if (connectTimeout != null) { - prop.setConnectTimeout(connectTimeout); - } - if (reconnectAfter != null) { - prop.setReconnectAfter(reconnectAfter); - } - if (fetchSchema != null) { - prop.setFetchSchema(fetchSchema); - } - if (ignoreOldSchemaVersion != null) { - prop.setIgnoreOldSchemaVersion(ignoreOldSchemaVersion); - } - prop.setBalancerMode(balancerClass); - return prop; - } - - public static List generatePersons(int count) { - List persons = new ArrayList<>(); - for (int i = 0; i < count; i++) { - persons.add(new Person(i, i % 3 == 0 ? null : i % 2 == 0, "User-" + i)); - } - return persons; - } - - public static List generatePersons(int count, Consumer actionAtPerson) { - List persons = generatePersons(count); - persons.forEach(actionAtPerson); - return persons; - } - - public static List generateComplexPersons(int count) { - List persons = new ArrayList<>(); - for (int i = 0; i < count; i++) { - persons.add( - new ComplexPerson(i, UUID.randomUUID(), i % 3 == 0 ? null : i % 2 == 0, "User-" + i)); - } - return persons; - } - - public static List generateComplexPersons( - int count, Consumer actionAtPerson) { - List persons = generateComplexPersons(count); - persons.forEach(actionAtPerson); - return persons; - } - - public static List generateAndInsertPersons(int count, TarantoolCrudClient client) { - final List persons = generatePersons(count); - final TarantoolCrudSpace space = client.space(PERSON_SPACE); - - List> insertedPersons = space.insertMany(persons, Person.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertPersons( - int count, TarantoolCrudClient client, Consumer action) { - final List persons = generatePersons(count, action); - final TarantoolCrudSpace space = client.space(PERSON_SPACE); - - List> insertedPersons = space.insertMany(persons, Person.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertComplexPersons( - int count, TarantoolCrudClient client) { - final List persons = generateComplexPersons(count); - final TarantoolCrudSpace space = client.space(COMPLEX_PERSON_SPACE); - - List> insertedPersons = - space.insertMany(persons, ComplexPerson.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertComplexPersons( - int count, TarantoolCrudClient client, Consumer action) { - - final List persons = generateComplexPersons(count, action); - final TarantoolCrudSpace space = client.space(COMPLEX_PERSON_SPACE); - - List> insertedPersons = - space.insertMany(persons, ComplexPerson.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/ComplexPersonListRepository.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/ComplexPersonListRepository.java deleted file mode 100644 index b3cea403..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/ComplexPersonListRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.core; - -import org.springframework.data.repository.ListCrudRepository; - -import io.tarantool.spring.data.utils.GenericListRepositoryMethods; -import io.tarantool.spring.data34.utils.entity.ComplexPerson; -import io.tarantool.spring.data34.utils.entity.CompositePersonKey; - -public interface ComplexPersonListRepository - extends ListCrudRepository, - GenericListRepositoryMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/ComplexPersonRepository.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/ComplexPersonRepository.java deleted file mode 100644 index 93c29ee5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/ComplexPersonRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.core; - -import org.springframework.data.repository.PagingAndSortingRepository; - -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data34.utils.entity.ComplexPerson; -import io.tarantool.spring.data34.utils.entity.CompositePersonKey; - -public interface ComplexPersonRepository - extends PagingAndSortingRepository, - GenericRepositoryMethods, - GenericPaginationMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/GenericPaginationMethods.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/GenericPaginationMethods.java deleted file mode 100644 index 9748f633..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/GenericPaginationMethods.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.core; - -import java.util.List; - -import org.springframework.data.domain.Limit; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; - -public interface GenericPaginationMethods { - - Slice findAllByName(String name); - - Slice findAllByName(String name, Pageable pageable); - - Slice findAllByNameGreaterThanEqual(String name, Pageable pageable); - - Slice findAllByNameLessThanEqual(String name, Pageable pageable); - - Slice findAllByIdLessThanEqual(int id, Pageable pageable); - - Slice findAllByIdGreaterThanEqual(int id, Pageable pageable); - - Slice findAllByIsMarriedLessThanEqual(Boolean id, Pageable pageable); - - Slice findAllByIsMarriedGreaterThanEqual(Boolean id, Pageable pageable); - - Page findPersonByName(String name, Pageable pageable); - - Page findPersonByNameGreaterThanEqual(String name, Pageable pageable); - - Page findPersonByNameLessThanEqual(String name, Pageable pageable); - - Page findPersonByIdLessThanEqual(int id, Pageable pageable); - - Page findPersonByIdGreaterThanEqual(int id, Pageable pageable); - - Page findPersonByIsMarriedLessThanEqual(Boolean id, Pageable pageable); - - Page findPersonByIsMarriedGreaterThanEqual(Boolean id, Pageable pageable); - - Window findFirst5ByIsMarried(Boolean isMarried, ScrollPosition scrollPosition); - - Window findFirst10ByIsMarriedGreaterThanEqual( - Boolean isMarried, ScrollPosition scrollPosition); - - List findAll(Sort sort); - - Page findAll(Pageable pageable); - - List findAll(); - - List findPersonByIdGreaterThanEqual(int id, Limit limit); - - List findTop4ByIdGreaterThanEqual(int id, Limit limit); -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/PersonListRepository.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/PersonListRepository.java deleted file mode 100644 index 9318ccf0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/PersonListRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.core; - -import org.springframework.data.repository.ListCrudRepository; - -import io.tarantool.spring.data.utils.GenericListRepositoryMethods; -import io.tarantool.spring.data34.utils.entity.Person; - -public interface PersonListRepository - extends ListCrudRepository, GenericListRepositoryMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/ComplexPerson.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/ComplexPerson.java deleted file mode 100644 index 9c1058be..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/ComplexPerson.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data34.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKey.class) -public class ComplexPerson implements GenericPerson { - - @Id - @Field("id") - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - protected Boolean isMarried; - - @Field("name") - @JsonProperty("name") - String name; - - @Override - public CompositePersonKey generateFullKey() { - return new CompositePersonKey(id, secondId); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/ComplexPersonWithIncorrectPK.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/ComplexPersonWithIncorrectPK.java deleted file mode 100644 index 807088fd..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/ComplexPersonWithIncorrectPK.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data34.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKeyWithoutJsonFormat.class) -public class ComplexPersonWithIncorrectPK { - - @Id - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/ComplexPersonWithJsonFormatVariantPK.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/ComplexPersonWithJsonFormatVariantPK.java deleted file mode 100644 index 6c4b918c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/ComplexPersonWithJsonFormatVariantPK.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data34.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKeyWithJsonFormat.class) -public class ComplexPersonWithJsonFormatVariantPK { - - @Id - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositeKeyWithWrongFieldCount.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositeKeyWithWrongFieldCount.java deleted file mode 100644 index 38031483..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositeKeyWithWrongFieldCount.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -public class CompositeKeyWithWrongFieldCount implements CompositeKey { - - @JsonProperty("id") - private long id; -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositeKeyWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositeKeyWithWrongFieldTypes.java deleted file mode 100644 index fa520af5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositeKeyWithWrongFieldTypes.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositeKeyWithWrongFieldTypes implements CompositeKey { - - @JsonProperty("id") - private long id; - - @JsonProperty("secondId") - private String secondId; - - @JsonProperty("thirdId") - private boolean thirdId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositePersonKey.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositePersonKey.java deleted file mode 100644 index 3b45948f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositePersonKey.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositePersonKey implements CompositeKey { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositePersonKeyWithJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositePersonKeyWithJsonFormat.java deleted file mode 100644 index 6c5f44df..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositePersonKeyWithJsonFormat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -public class CompositePersonKeyWithJsonFormat { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositePersonKeyWithoutJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositePersonKeyWithoutJsonFormat.java deleted file mode 100644 index 9c669ec3..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/CompositePersonKeyWithoutJsonFormat.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositePersonKeyWithoutJsonFormat { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/EntityWithAnnotationAsIdClass.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/EntityWithAnnotationAsIdClass.java deleted file mode 100644 index 5777327e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/EntityWithAnnotationAsIdClass.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.entity; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@IdClass(IdClass.class) -public class EntityWithAnnotationAsIdClass {} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/EntityWithWrongCompositeKeyPartsCount.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/EntityWithWrongCompositeKeyPartsCount.java deleted file mode 100644 index 7b75c922..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/EntityWithWrongCompositeKeyPartsCount.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@IdClass(CompositeKeyWithWrongFieldCount.class) -public class EntityWithWrongCompositeKeyPartsCount { - - @Id - @JsonProperty("id") - private long id; - - @Id - @JsonProperty("secondId") - private long secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/EntityWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/EntityWithWrongFieldTypes.java deleted file mode 100644 index 34c698ca..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/EntityWithWrongFieldTypes.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@IdClass(CompositeKeyWithWrongFieldTypes.class) -public class EntityWithWrongFieldTypes { - - @Id - @JsonProperty("id") - private long id; - - @Id - @JsonProperty("secondId") - private String secondId; - - @Id - @JsonProperty("thirdId") - private int thirdId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/Person.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/Person.java deleted file mode 100644 index 62f85770..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/entity/Person.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data34.utils.entity; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data34.query.Field; - -/** - * @author Artyom Dubinin - */ -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("person") -public class Person implements GenericPerson { - - @Id - @Field("id") - @JsonProperty("id") - public Integer id; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; - - @Override - public Integer generateFullKey() { - return id; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/resources/META-INF/spring.factories b/tarantool-spring-data/tarantool-spring-data-34/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 91134980..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1 +0,0 @@ -io.tarantool.spring.data34.utils.fragments.core.ReplaceManyFragment=io.tarantool.spring.data34.utils.fragments.implementations.PersonReplaceManyFragment \ No newline at end of file diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/resources/application-crud-test.yaml b/tarantool-spring-data/tarantool-spring-data-34/src/test/resources/application-crud-test.yaml deleted file mode 100644 index 9bc8f9b2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/resources/application-crud-test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -spring: - data: - tarantool: - host: localhost - port: 3301 diff --git a/tarantool-spring-data/tarantool-spring-data-35/pom.xml b/tarantool-spring-data/tarantool-spring-data-35/pom.xml deleted file mode 100644 index e9f3af46..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - 4.0.0 - - tarantool-spring-data-35 - Minimalistic java connector for Tarantool versions 2.11+ based on Netty framework - https://tarantool.io - - - io.tarantool - tarantool-spring-data - 2.0.0-SNAPSHOT - - - tarantool-spring-data-35 - jar - - - 17 - 17 - 3.5.16 - - 3.5.13 - ${project.parent.parent.basedir}/tarantool-shared-resources/ - ${project.parent.parent.basedir}/LICENSE_HEADER.txt - - - - - io.tarantool - tarantool-spring-data-core - - - org.springframework.data - spring-data-keyvalue - ${spring-data-keyvalue.version} - - - diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/TarantoolBoxKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/TarantoolBoxKeyValueAdapter.java deleted file mode 100644 index 3071dd89..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/TarantoolBoxKeyValueAdapter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35; - -import java.util.Map; - -import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.NonNull; - -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(Object id, Object item, String keyspace) { - return adapter.put(id, item, keyspace); - } - - @Override - public boolean contains(Object id, String keyspace) { - return adapter.contains(id, keyspace); - } - - @Override - public Object get(Object id, String keyspace) { - return adapter.get(id, keyspace); - } - - @Override - public Object delete(Object id, String keyspace) { - return adapter.delete(id, keyspace); - } - - @Override - public Iterable getAllOf(String keyspace) { - return adapter.getAllOf(keyspace); - } - - @Override - public void deleteAllOf(String keyspace) { - adapter.deleteAllOf(keyspace); - } - - @Override - public void clear() { - adapter.clear(); - } - - @Override - public long count(String keyspace) { - return adapter.count(keyspace); - } - - @Override - public void destroy() throws Exception { - adapter.destroy(); - } - - @Override - public CloseableIterator> entries(String keyspace) { - throw new UnsupportedOperationException("Not implemented yet"); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/TarantoolCrudKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/TarantoolCrudKeyValueAdapter.java deleted file mode 100644 index abb61390..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/TarantoolCrudKeyValueAdapter.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35; - -import java.util.Collections; -import java.util.Map.Entry; - -import com.fasterxml.jackson.annotation.JsonFormat; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.NonNull; - -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(Object id, Object item, String keyspace) { - return adapter.put(convertId(id), item, keyspace); - } - - @Override - public boolean contains(Object id, String keyspace) { - return adapter.contains(convertId(id), keyspace); - } - - @Override - public Object get(Object id, String keyspace) { - return adapter.get(convertId(id), keyspace); - } - - @Override - public T get(Object id, String keyspace, Class type) { - return adapter.get(convertId(id), keyspace, type); - } - - @Override - public Object delete(Object id, String keyspace) { - return adapter.delete(convertId(id), keyspace); - } - - @Override - public T delete(Object id, String keyspace, Class type) { - return adapter.delete(convertId(id), keyspace, type); - } - - @Override - public Iterable getAllOf(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> 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()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/TarantoolQueryEngine.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/TarantoolQueryEngine.java deleted file mode 100644 index fbdb0bbe..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/TarantoolQueryEngine.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35; - -import java.util.Collection; -import java.util.Comparator; -import java.util.Map.Entry; - -import org.springframework.data.keyvalue.core.QueryEngine; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.ProxyTarantoolQueryEngine; -import io.tarantool.spring.data.query.TarantoolCriteria; -import io.tarantool.spring.data35.query.TarantoolCriteriaAccessor; -import io.tarantool.spring.data35.query.TarantoolSortAccessor; - -/** - * Implementation of {@code findBy*()} and {@code countBy*{}} queries. - * - * @author Artyom Dubinin - */ -public class TarantoolQueryEngine - extends QueryEngine>> { - - 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> 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. - * - *

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 Collection execute( - @Nullable final TarantoolCriteria criteria, - @Nullable final Comparator> sort, - final long offset, - final int rows, - @NonNull final String keyspace, - @NonNull Class 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); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/config/TarantoolBoxConfiguration.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/config/TarantoolBoxConfiguration.java deleted file mode 100644 index c199db2f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/config/TarantoolBoxConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.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.data35.TarantoolBoxKeyValueAdapter; -import io.tarantool.spring.data35.config.properties.TarantoolProperties; - -@Configuration(proxyBeanMethods = false) -public class TarantoolBoxConfiguration extends BaseTarantoolBoxConfiguration { - - public TarantoolBoxConfiguration( - ObjectProvider properties, - ObjectProvider 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(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/config/TarantoolCrudConfiguration.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/config/TarantoolCrudConfiguration.java deleted file mode 100644 index 5a3d2bd1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/config/TarantoolCrudConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.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_CRUD_CLIENT_BEAN_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.spring.data.config.BaseTarantoolCrudConfiguration; -import io.tarantool.spring.data35.TarantoolCrudKeyValueAdapter; -import io.tarantool.spring.data35.config.properties.TarantoolProperties; - -@Configuration(proxyBeanMethods = false) -public class TarantoolCrudConfiguration extends BaseTarantoolCrudConfiguration { - - public TarantoolCrudConfiguration( - ObjectProvider properties, - ObjectProvider tarantoolClientConfiguration) { - super(properties.getIfAvailable(), tarantoolClientConfiguration.getIfAvailable()); - } - - @Bean(name = DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF) - @ConditionalOnMissingBean(TarantoolCrudKeyValueAdapter.class) - public TarantoolCrudKeyValueAdapter tarantoolCrudKeyValueAdapter( - TarantoolCrudClient tarantoolCrudClient) { - return new TarantoolCrudKeyValueAdapter(tarantoolCrudClient); - } - - @Bean(name = DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF) - @ConditionalOnMissingBean(TarantoolCrudClient.class) - public TarantoolCrudClient tarantoolCrudClient() throws Exception { - return super.tarantoolCrudClient(); - } - - public TarantoolCrudClientBuilder getClientBuilder() { - return super.getClientBuilder(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/config/package-info.java deleted file mode 100644 index 0f890630..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/config/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Config package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data35.config; diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/config/properties/TarantoolProperties.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/config/properties/TarantoolProperties.java deleted file mode 100644 index 895d2b3b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/config/properties/TarantoolProperties.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.config.properties; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties; - -/** - * Configuration properties for Tarantool. - * - * @author Nikolay Belonogov - */ -@ConfigurationProperties(prefix = "spring.data.tarantool") -public class TarantoolProperties extends BaseTarantoolProperties {} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/TarantoolTemplate.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/TarantoolTemplate.java deleted file mode 100644 index a6a162dd..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/TarantoolTemplate.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.core; - -import org.springframework.data.keyvalue.core.IdentifierGenerator; -import org.springframework.data.keyvalue.core.KeyValueAdapter; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.util.ClassUtils; - -import io.tarantool.spring.data35.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data35.core.mapping.TarantoolMappingContext; - -public class TarantoolTemplate extends KeyValueTemplate { - - public TarantoolTemplate(KeyValueAdapter adapter) { - super(adapter, new TarantoolMappingContext<>()); - } - - public TarantoolTemplate( - KeyValueAdapter adapter, - MappingContext< - ? extends KeyValuePersistentEntity, ? extends KeyValuePersistentProperty> - mappingContext) { - super(adapter, mappingContext); - } - - public TarantoolTemplate( - KeyValueAdapter adapter, - MappingContext< - ? extends KeyValuePersistentEntity, ? extends KeyValuePersistentProperty> - mappingContext, - IdentifierGenerator identifierGenerator) { - super(adapter, mappingContext, identifierGenerator); - } - - @Override - public T insert(T objectToInsert) { - if (DefaultIdClassResolver.INSTANCE.resolveIdClassType(objectToInsert.getClass()) == null) { - return super.insert(objectToInsert); - } - - PersistentEntity entity = - getMappingContext().getRequiredPersistentEntity(ClassUtils.getUserClass(objectToInsert)); - - IdentifierAccessor identifierAccessor = entity.getIdentifierAccessor(objectToInsert); - Object id = identifierAccessor.getRequiredIdentifier(); - return insert(id, objectToInsert); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/annotation/DefaultIdClassResolver.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/annotation/DefaultIdClassResolver.java deleted file mode 100644 index 4cda8387..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/annotation/DefaultIdClassResolver.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.core.annotation; - -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.core.annotation.IdClassResolver; - -/** Default implementation of {@link IdClassResolver}. */ -public enum DefaultIdClassResolver implements IdClassResolver { - INSTANCE; - - public static final String ANNOTATION_TYPE_EXCEPTION = - "The class of a composite identifier specified in the @IdClass annotation cannot be" - + " annotation!"; - - @Nullable - @Override - public Class resolveIdClassType(Class type) { - Assert.notNull(type, "Type for IdClass must be not null!"); - - IdClass idClassTypeAnnotation = AnnotatedElementUtils.findMergedAnnotation(type, IdClass.class); - - if (idClassTypeAnnotation == null) { - return null; - } - - Class idClassTypeValue = idClassTypeAnnotation.value(); - Assert.isTrue(!idClassTypeValue.isAnnotation(), ANNOTATION_TYPE_EXCEPTION); - - return idClassTypeValue; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/annotation/package-info.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/annotation/package-info.java deleted file mode 100644 index 93a1a063..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/annotation/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Core annotations of data mapping. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data35.core.annotation; diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/BasicKeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/BasicKeyValueCompositePersistentEntity.java deleted file mode 100644 index af69d013..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/BasicKeyValueCompositePersistentEntity.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.core.mapping; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.data.domain.Persistable; -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.support.IsNewStrategy; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.mapping.model.CompositeKey; -import io.tarantool.spring.data35.core.mapping.model.CompositeIdPropertyAccessor; -import io.tarantool.spring.data35.core.mapping.model.PersistentCompositeIdIsNewStrategy; - -public class BasicKeyValueCompositePersistentEntity> - extends BasicKeyValuePersistentEntity implements KeyValueCompositePersistentEntity { - - public static final String TYPE_MISMATCH = - "Target bean of type %s is not of type of the persistent entity (%s)"; - - private final Class idClassTypeValue; - private @Nullable P idProperty; - - private Map entityIdClassFields; - - /** - * @param information must not be {@literal null}. - * @param fallbackKeySpaceResolver can be {@literal null}. - * @param idClassTypeValue class that specified in {@link IdClass} - */ - public BasicKeyValueCompositePersistentEntity( - TypeInformation information, - @Nullable KeySpaceResolver fallbackKeySpaceResolver, - Class idClassTypeValue) { - super(information, fallbackKeySpaceResolver); - - Assert.notNull(idClassTypeValue, "idClassTypeValue must be not null for this class!"); - this.idClassTypeValue = idClassTypeValue; - } - - @Override - public IdentifierAccessor getIdentifierAccessor(Object bean) { - verifyBeanType(bean); - - if (Persistable.class.isAssignableFrom(getType())) { - throw new IllegalArgumentException( - "Persistable override is not currently supported for entities with a composite key."); - } - - return hasIdProperty() - ? new CompositeIdPropertyAccessor(bean, this.entityIdClassFields, getIdClassType()) - : new AbsentIdentifierAccessor(); - } - - @Override - public Class getIdClassType() { - return this.idClassTypeValue; - } - - @Override - public void verify() { - super.verify(); - - if (this.idProperty != null) { - this.entityIdClassFields = KeyPartTypeChecker.getFieldMapIfTypesValid(this, this.idProperty); - } - } - - @Override - protected IsNewStrategy getFallbackIsNewStrategy() { - return PersistentCompositeIdIsNewStrategy.of(this); - } - - @Override - protected P returnPropertyIfBetterIdPropertyCandidateOrNull(P property) { - Assert.isInstanceOf(Identifier.class, property, "property must be Identifier for this class"); - - if (!property.isIdProperty()) { - return null; - } - - if (this.idProperty == null) { - this.idProperty = property; - return this.idProperty; - } - - this.idProperty.addPart(property); - - return this.idProperty; - } - - /** - * Verifies the given bean type to no be {@literal null} and of the type of the current {@link - * PersistentEntity}. - * - * @param bean must not be {@literal null}. - */ - private void verifyBeanType(Object bean) { - - Assert.notNull(bean, "Target bean must not be null"); - Assert.isInstanceOf( - getType(), - bean, - () -> String.format(TYPE_MISMATCH, bean.getClass().getName(), getType().getName())); - } - - /** - * A null-object implementation of {@link IdentifierAccessor} to be able to return an accessor for - * entities that do not have an identifier property. - */ - private static class AbsentIdentifierAccessor implements IdentifierAccessor { - - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.IdentifierAccessor#getIdentifier() - */ - @Override - @Nullable - public Object getIdentifier() { - return null; - } - } - - /** - * A class that checks the types of fields of a composite key. In addition, the correspondence - * between types and field names marked with {@code @Id}. - */ - public static class KeyPartTypeChecker { - - public static final String COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION = - "Number of fields specified in domain class and composite class the key is different!"; - - public static final String COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION = - "Domain class fields marked with @Id differ from fields specified in the composite key" - + " class"; - - /** - * Check the number and types of entity fields, annotated {@code @Id} and fields {@link - * CompositeKey} and if the types and quantities match return the id part fields mapping. - * - * @param persistentEntity persistent entity - * @param idProperty id property - * @return mapping between fields of composite key class and fields annotated {@code @Id} in - * entity. - */ - public static Map getFieldMapIfTypesValid( - KeyValueCompositePersistentEntity persistentEntity, Identifier idProperty) { - Map entityIdClassFields = new HashMap<>(); - - List compositeKeyFields = persistentEntity.getIdClassTypeFields(); - - Field[] entityFields = idProperty.getFields(); - - if (compositeKeyFields.size() != entityFields.length) { - throw new IllegalArgumentException(COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION); - } - - for (int i = 0; i < compositeKeyFields.size(); i++) { - Field compositeKeyField = compositeKeyFields.get(i); - Field entityField = entityFields[i]; - - if (!equalFields(compositeKeyField, entityField)) { - throw new IllegalArgumentException(COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION); - } - - entityIdClassFields.put(entityField, compositeKeyField); - } - return entityIdClassFields; - } - - /** - * Compares two class fields by name and type. - * - * @param firstField first field - * @param secondField second field - * @return true if fields are equal - */ - private static boolean equalFields(Field firstField, Field secondField) { - return firstField.getName().equals(secondField.getName()) - && firstField.getType().equals(secondField.getType()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/Identifier.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/Identifier.java deleted file mode 100644 index f2b46a8f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/Identifier.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.core.mapping; - -import java.lang.reflect.Field; -import java.util.Collection; - -import org.springframework.data.mapping.PersistentProperty; - -/** The interface of the identifier class that will contain information about the composite key. */ -public interface Identifier

> { - - /** - * Add a {@link PersistentProperty} tagged with {@code Id}. - * - * @param property {@link PersistentProperty} tagged {@code Id} - */ - void addPart(P property); - - /** - * Return the parts of a composite key that are {@link PersistentProperty}. - * - * @return parts of a composite key - */ - Collection

getParts(); - - /** - * Return a list {@link Field} of fields that are annotated {@code @Id}. Unlike method {@link - * #getParts()} this method returns an array {@link Field}, where {@link Field} is taken from each - * element of the collection returned by the {@link #getParts()} method. Necessary in order not to - * write polluting code. - * - * @return fields of a composite key - */ - Field[] getFields(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/KeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/KeyValueCompositePersistentEntity.java deleted file mode 100644 index 4c9d9d01..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/KeyValueCompositePersistentEntity.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.core.mapping; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.model.MutablePersistentEntity; - -import io.tarantool.spring.data.core.annotation.IdClass; - -/** - * An interface to enable {@link PersistentEntity}-specific operations with a composite key. - * - * @param domain class type - * @param

{@link PersistentProperty} type - */ -public interface KeyValueCompositePersistentEntity> - extends MutablePersistentEntity { - - /** - * Returns the fields of the class specified in the {@link IdClass} annotation. - * - * @return all fields that are in composite key class - */ - default List getIdClassTypeFields() { - List fields = new ArrayList<>(); - - for (Field field : getIdClassType().getDeclaredFields()) { - if (!field.isSynthetic()) { - fields.add(field); - } - } - return fields; - } - - /** - * Returns the type of the class specified in the {@link IdClass} annotation. - * - * @return class that specified in {@link IdClass} - */ - Class getIdClassType(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/KeyValueCompositeProperty.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/KeyValueCompositeProperty.java deleted file mode 100644 index c1ac219e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/KeyValueCompositeProperty.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.core.mapping; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; - -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.util.Assert; - -public class KeyValueCompositeProperty

> - extends KeyValuePersistentProperty

implements Identifier

{ - - private final List

identifierPartsWithoutFirst; - - public KeyValueCompositeProperty( - Property property, PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - super(property, owner, simpleTypeHolder); - this.identifierPartsWithoutFirst = new ArrayList<>(); - } - - @Override - public void addPart(P property) { - Assert.notNull(property, "property must be not null"); - - if (equals(property) || this.identifierPartsWithoutFirst.contains(property)) { - return; - } - this.identifierPartsWithoutFirst.add(property); - } - - @Override - @SuppressWarnings("unchecked") - public Collection

getParts() { - List

resultList = new ArrayList<>(this.identifierPartsWithoutFirst); - resultList.add(0, (P) this); - - return resultList; - } - - @Override - public Field[] getFields() { - int totalSize = this.identifierPartsWithoutFirst.size() + 1; - - final Field[] fields = new Field[totalSize]; - fields[0] = getField(); - - for (int i = 1; i < totalSize; i++) { - fields[i] = this.identifierPartsWithoutFirst.get(i - 1).getField(); - } - return fields; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - KeyValueCompositeProperty other = (KeyValueCompositeProperty) o; - - if (this.identifierPartsWithoutFirst.isEmpty() && other.identifierPartsWithoutFirst.isEmpty()) { - return super.equals(o); - } - - if (this.identifierPartsWithoutFirst.size() != other.identifierPartsWithoutFirst.size() - || !other.getProperty().equals(getProperty())) { - return false; - } - - for (int i = 0; i < this.identifierPartsWithoutFirst.size(); i++) { - // take Property from both parts - Property thisKeyPartProperty = - ((KeyValueCompositeProperty) this.identifierPartsWithoutFirst.get(i)).getProperty(); - Property otherKeyPartProperty = - ((KeyValueCompositeProperty) other.identifierPartsWithoutFirst.get(i)).getProperty(); - - if (!thisKeyPartProperty.equals(otherKeyPartProperty)) { - return false; - } - } - return true; - } - - @Override - public int hashCode() { - int hashCode = super.hashCode(); - - if (this.identifierPartsWithoutFirst.isEmpty()) { - return hashCode; - } - - // sublist to avoid endless recursion - return Objects.hash(hashCode, this.identifierPartsWithoutFirst); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/TarantoolMappingContext.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/TarantoolMappingContext.java deleted file mode 100644 index 01a09e48..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/TarantoolMappingContext.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.core.mapping; - -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; - -import io.tarantool.spring.data.core.annotation.IdClassResolver; -import io.tarantool.spring.data35.core.annotation.DefaultIdClassResolver; - -public class TarantoolMappingContext< - E extends KeyValuePersistentEntity, P extends KeyValuePersistentProperty

> - extends KeyValueMappingContext { - - private final IdClassResolver idClassResolver; - - private @Nullable KeySpaceResolver keySpaceResolver; - - public TarantoolMappingContext() { - super(); - this.idClassResolver = DefaultIdClassResolver.INSTANCE; - } - - @Override - public void setKeySpaceResolver(KeySpaceResolver keySpaceResolver) { - super.setKeySpaceResolver(keySpaceResolver); - this.keySpaceResolver = keySpaceResolver; - } - - @SuppressWarnings("unchecked") - @Override - protected E createPersistentEntity(TypeInformation typeInformation) { - final Class idClassTypeValue = - this.idClassResolver.resolveIdClassType(typeInformation.getType()); - if (idClassTypeValue == null) { - return (E) new BasicKeyValuePersistentEntity(typeInformation, this.keySpaceResolver); - } - return (E) - new BasicKeyValueCompositePersistentEntity<>( - typeInformation, this.keySpaceResolver, idClassTypeValue); - } - - @SuppressWarnings("unchecked") - @Override - protected P createPersistentProperty( - Property property, E owner, SimpleTypeHolder simpleTypeHolder) { - if (KeyValueCompositePersistentEntity.class.isAssignableFrom(owner.getClass())) { - return (P) new KeyValueCompositeProperty<>(property, owner, simpleTypeHolder); - } - return (P) new KeyValuePersistentProperty<>(property, owner, simpleTypeHolder); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/model/CompositeIdPropertyAccessor.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/model/CompositeIdPropertyAccessor.java deleted file mode 100644 index 29a7a864..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/model/CompositeIdPropertyAccessor.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.core.mapping.model; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.util.Map; - -import org.springframework.data.mapping.TargetAwareIdentifierAccessor; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -/** Class that allows to convert {@code @Id} annotated fields in an entity into a composite key. */ -public class CompositeIdPropertyAccessor extends TargetAwareIdentifierAccessor { - - private final Map entityIdClassFields; - - private final Class idClassType; - - private final Object target; - - public CompositeIdPropertyAccessor( - Object target, @NonNull Map entityIdClassFields, Class idClassType) { - - super(target); - this.target = target; - this.entityIdClassFields = entityIdClassFields; - this.idClassType = idClassType; - } - - @Nullable - public Object getIdentifier() { - try { - return generateIdentifier(); - } catch (InstantiationException - | IllegalAccessException - | NoSuchMethodException - | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - /** - * Generates a composite identifier from those marked with the {@code @Id} annotation in a domain - * class based on fields, specified in the composite key class. - * - * @return identifier - * @throws IllegalAccessException if the class or its nullary constructor is not accessible. - * @throws InstantiationException if this {@code Class} represents an abstract class, an - * interface, an array class, a primitive type, or void; or if the class has no nullary - * constructor; or if the instantiation fails for some other reason. - */ - private Object generateIdentifier() - throws InstantiationException, - IllegalAccessException, - NoSuchMethodException, - InvocationTargetException { - Assert.notNull(this.target, "target object must be not null!"); - Object compositeKey = idClassType.getDeclaredConstructor().newInstance(); - for (Map.Entry fieldPair : this.entityIdClassFields.entrySet()) { - writeValuesFromEntityId(compositeKey, fieldPair.getKey(), fieldPair.getValue()); - } - return compositeKey; - } - - /** - * Write the composite primary key fields provided in the entity to the class which implements - * {@link CompositeKey}. - * - * @param compositeKey object of the composite key into which the values are written. - * @param entityField field from the represented entity. - * @param compositeKeyField field from the composite key class. - */ - private void writeValuesFromEntityId( - Object compositeKey, Field entityField, Field compositeKeyField) { - ReflectionUtils.makeAccessible(entityField); - ReflectionUtils.makeAccessible(compositeKeyField); - - Object value = ReflectionUtils.getField(entityField, this.target); - ReflectionUtils.setField(compositeKeyField, compositeKey, value); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/model/PersistentCompositeIdIsNewStrategy.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/model/PersistentCompositeIdIsNewStrategy.java deleted file mode 100644 index 1f3975a4..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/model/PersistentCompositeIdIsNewStrategy.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.core.mapping.model; - -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.support.IsNewStrategy; -import org.springframework.util.Assert; - -/** - * Strategy class for entity with composite key to determine whether a given entity is to be - * considered new. - */ -public class PersistentCompositeIdIsNewStrategy implements IsNewStrategy { - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} for the given entity. - * - * @param entity must not be {@literal null}. - * @param idOnly check only id to determine - */ - private PersistentCompositeIdIsNewStrategy(PersistentEntity entity, boolean idOnly) { - // TODO сделать реализацию версионирования - // TODO add idOnly support - Assert.notNull(entity, "PersistentEntity must not be null"); - } - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} to only consider the identifier of the - * given entity. - * - * @param entity must not be {@literal null}. - * @return strategy to determine whether entity is new or not - */ - public static PersistentCompositeIdIsNewStrategy forIdOnly(PersistentEntity entity) { - return new PersistentCompositeIdIsNewStrategy(entity, true); - } - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} to consider version properties before - * falling back to the identifier. - * - * @param entity must not be {@literal null}. - * @return strategy to determine whether entity is new or not - */ - public static PersistentCompositeIdIsNewStrategy of(PersistentEntity entity) { - return new PersistentCompositeIdIsNewStrategy(entity, false); - } - - /** - * Determine whether the current domain entity type object is new. Currently stub and always - * returns false. - * - * @param entity must not be {@literal null}. - * @return result of the question of entity is new or not - */ - @Override - public boolean isNew(Object entity) { - return false; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/model/package-info.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/model/package-info.java deleted file mode 100644 index 2e491de8..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/model/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Core implementation of the mapping subsystem's model. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data35.core.mapping.model; diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/package-info.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/package-info.java deleted file mode 100644 index df37bf92..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/mapping/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** Base package for the mapping subsystem. */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data35.core.mapping; diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/package-info.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/package-info.java deleted file mode 100644 index ec08e37e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/core/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Core package for integrating Tarantool with Spring - * concepts. - */ -@org.springframework.lang.NonNullFields -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data35.core; diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/Field.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/Field.java deleted file mode 100644 index 7de176fe..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/Field.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.core.annotation.AliasFor; - -/** - * Allows adding some metadata to the class fields relevant for storing them in the Tarantool space - * - * @author Artyom Dubinin - */ -@Inherited -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) -public @interface Field { - - /** - * The target Tarantool space field for storing the marked class field. Alias for {@link #name()}. - * - * @return the name of a field in space - */ - @AliasFor("name") - String value() default ""; - - /** - * The target Tarantool space field for storing the marked class field. Alias for {@link - * #value()}. - * - * @return the name of a field in space - */ - @AliasFor("value") - String name() default ""; - - /** - * The order in which fields shall be stored in the tuple. Has to be a positive integer. - * - * @return the order the field shall have in the tuple or -1 if undefined. - */ - int order() default -1; -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/PaginationUtils.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/PaginationUtils.java deleted file mode 100644 index 5de0478c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/PaginationUtils.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.keyvalue.core.IterableConverter; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class PaginationUtils { - - private static final String CRITERIA_NULL_EXC_MSG = "TarantoolCriteria must be not null"; - - /** - * Returns {@link TarantoolPageable} cast from {@link Pageable} with type checking. - * - * @param sliceParams pageable - * @return {@link TarantoolPageable} - */ - public static TarantoolPageable castToTarantoolPageable(Pageable sliceParams) { - Assert.isInstanceOf(TarantoolPageable.class, sliceParams, "Pageable must be TarantoolPageable"); - return (TarantoolPageable) sliceParams; - } - - /** - * A general method for retrieving data for paginated queries. - * - * @param query query - * @param pageRequest {@link TarantoolPageable} - * @param pageSize page size - * @return selection result. - */ - public static List doPaginationQuery( - final KeyValueQuery query, - TarantoolPageable pageRequest, - int pageSize, - KeyValueOperations keyValueOperations, - Class targetType) { - - TarantoolCriteria criteria = (TarantoolCriteria) query.getCriteria(); - PaginationDirection paginationDirection = pageRequest.getPaginationDirection(); - - Assert.notNull(criteria, CRITERIA_NULL_EXC_MSG); - criteria.withAfter(pageRequest.getTupleCursor()); - - query.setRows(pageSize * paginationDirection.getMultiplier()); - - return IterableConverter.toList(keyValueOperations.find(query, targetType)); - } - - public static Page doPageQuery( - Pageable pageable, - KeyValueQuery query, - KeyValueOperations keyValueOperations, - Class targetType) { - if (pageable.isUnpaged()) { - return new TarantoolPageImpl<>(); - } - TarantoolPageable resultSliceParams = castToTarantoolPageable(pageable); - - int pageSize = resultSliceParams.getPageSize(); - - // non transactional calls - List content = - doPaginationQuery(query, resultSliceParams, pageSize, keyValueOperations, targetType); - - if (content.isEmpty()) { - return new TarantoolPageImpl<>(); - } - - long totalElements = keyValueOperations.count(query, targetType); - return new TarantoolPageImpl<>(content, resultSliceParams, totalElements); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolChunk.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolChunk.java deleted file mode 100644 index eaf232fa..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolChunk.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -/** - * A chunk of data restricted by the configured {@link Pageable} for Tarantool. - * - * @author Nikolay Belonogov - */ -abstract class TarantoolChunk implements Slice, Serializable { - - private static final long serialVersionUID = 867755909294344406L; - - private final List content = new ArrayList<>(); - - private final Pageable pageable; - - /** - * Creates a new {@link TarantoolChunk} with the given content and the given governing {@link - * TarantoolPageable}. - * - * @param content must not be {@literal null}. - * @param pageable must not be {@literal null}. - */ - public TarantoolChunk(List content, Pageable pageable) { - - Assert.notNull(content, "Content must not be null"); - Assert.notNull(pageable, "Pageable must not be null"); - - if (pageable.isPaged() && !(pageable instanceof TarantoolPageable)) { - throw new IllegalArgumentException("Pageable must be TarantoolPageable or Unpaged type"); - } - - this.content.addAll(content); - this.pageable = pageable; - } - - @Override - public boolean isFirst() { - return !hasPrevious(); - } - - @Override - public boolean isLast() { - return !hasNext(); - } - - @Override - public boolean hasPrevious() { - return getNumber() > 0 && hasContent(); - } - - @Override - public boolean hasContent() { - return !content.isEmpty(); - } - - /** - * Returns the {@link Pageable} to request the next {@link Slice}. Can be {@link - * Pageable#unpaged()} in case the current {@link Slice} is already the last one or when data - * content is empty. Clients should check {@link #hasNext()} and {@link #hasContent()} before - * calling this method. - * - * @see #nextOrLastPageable() - */ - @NonNull - @Override - @SuppressWarnings("unchecked") - public Pageable nextPageable() { - if (hasNext() && pageable.isPaged()) { - return ((TarantoolPageable) pageable).next(content.get(content.size() - 1)); - } - return Pageable.unpaged(); - } - - /** - * Returns the {@link Pageable} to request the previous {@link Slice}. Can be {@link - * Pageable#unpaged()} in case the current {@link Slice} is already the first one or data content - * is empty. Clients should check {@link #hasPrevious()} and {@link #hasContent()} before calling - * this method. - * - * @see #previousOrFirstPageable() - */ - @NonNull - @Override - @SuppressWarnings("unchecked") - public Pageable previousPageable() { - if (hasPrevious() && pageable.isPaged()) { - return ((TarantoolPageable) pageable).previousOrFirst(content.get(0)); - } - return Pageable.unpaged(); - } - - @Override - public Iterator iterator() { - return content.iterator(); - } - - @NonNull - @Override - public List getContent() { - return Collections.unmodifiableList(content); - } - - @NonNull - @Override - public Pageable getPageable() { - return pageable; - } - - @NonNull - @Override - public Sort getSort() { - return pageable.getSort(); - } - - @Override - public int getNumber() { - if (pageable.isPaged()) { - return pageable.getPageNumber(); - } - return 0; - } - - @Override - public int getSize() { - if (pageable.isPaged()) { - return pageable.getPageSize(); - } - return content.size(); - } - - @Override - public int getNumberOfElements() { - return content.size(); - } - - /** - * Applies the given {@link Function} to the content of the {@link TarantoolChunk}. - * - * @param converter must not be {@literal null}. - */ - protected List getConvertedContent(Function converter) { - - Assert.notNull(converter, "Function must not be null"); - - return this.stream().map(converter).collect(Collectors.toList()); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolChunk)) { - return false; - } - TarantoolChunk that = (TarantoolChunk) o; - return content.equals(that.content) && pageable.equals(that.pageable); - } - - @Override - public int hashCode() { - return Objects.hash(content, pageable); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolCriteriaAccessor.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolCriteriaAccessor.java deleted file mode 100644 index a46ef802..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolCriteriaAccessor.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import org.springframework.data.keyvalue.core.CriteriaAccessor; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -import io.tarantool.spring.data.query.TarantoolCriteria; - -/** - * Provide a mechanism to convert the abstract query into the direct implementation in Tarantool. - * - * @author Artyom Dubinin - */ -public class TarantoolCriteriaAccessor implements CriteriaAccessor { - - /** - * @param query in Spring form - * @return The same in Tarantool form - */ - public TarantoolCriteria resolve(KeyValueQuery query) { - return (TarantoolCriteria) query.getCriteria(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolKeysetScrollPosition.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolKeysetScrollPosition.java deleted file mode 100644 index 2cdde90e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolKeysetScrollPosition.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.util.List; -import java.util.Objects; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.Pair; - -final class TarantoolKeysetScrollPosition implements TarantoolScrollPosition { - - private final Pair indexKey; - - private final PaginationDirection direction; - - private final Object cursor; - - TarantoolKeysetScrollPosition( - Pair indexKey, PaginationDirection direction, @Nullable Object cursor) { - - Assert.notNull(direction, "PaginationDirection must not be null"); - Assert.notNull(indexKey, "indexKey must not be null"); - - this.indexKey = indexKey; - this.direction = direction; - this.cursor = cursor; - } - - /** - * Creates a new {@link TarantoolKeysetScrollPosition} from a key set and {@link - * PaginationDirection}. - * - * @param indexKey must not be {@literal null}. - * @return will never be {@literal null}. - */ - static TarantoolScrollPosition forward(Pair indexKey) { - return new TarantoolKeysetScrollPosition(indexKey, FORWARD, null); - } - - static TarantoolScrollPosition backward(Pair indexKey) { - return new TarantoolKeysetScrollPosition(indexKey, BACKWARD, null); - } - - /** - * Returns whether the current scroll position is the initial one (from begin or from end) (see - * {@link PaginationDirection}). - * - * @return {@link Boolean} object. - */ - @Override - public boolean isInitial() { - if (indexKey.getSecond() instanceof List startingList) { - return startingList.isEmpty() && cursor == null; - } - return false; - } - - @Override - public TarantoolScrollPosition reverse() { - Pair newIndexKey = Pair.of(indexKey.getFirst(), indexKey.getSecond()); - return new TarantoolKeysetScrollPosition(newIndexKey, direction.reverse(), cursor); - } - - @Override - public boolean isScrollsBackward() { - return direction.equals(BACKWARD); - } - - /** - * Return the cursor relative to which the data is being found. - * - * @return returns cursor - */ - Object getCursor() { - return cursor; - } - - /** - * @return the scroll direction. - */ - PaginationDirection getDirection() { - return direction; - } - - /** - * @return the indexKey. - */ - Pair getIndexKey() { - return indexKey; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolKeysetScrollPosition that)) { - return false; - } - return indexKey.equals(that.indexKey) - && direction == that.direction - && Objects.equals(cursor, that.cursor); - } - - @Override - public int hashCode() { - return Objects.hash(indexKey, direction, cursor); - } - - @Override - public String toString() { - return String.format("TarantoolKeysetScrollPosition [%s, %s, %s]", direction, indexKey, cursor); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolPageImpl.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolPageImpl.java deleted file mode 100644 index 87f1be52..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolPageImpl.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.io.Serial; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.lang.NonNull; - -/** - * Basic {@code Page} implementation for Tarantool. - * - * @param domain class type. - * @author Nikolay Belonogov - */ -class TarantoolPageImpl extends TarantoolChunk implements Page { - - @Serial private static final long serialVersionUID = 867755909294344406L; - - private final long total; - - /** - * Creates a new {@link TarantoolPageImpl} with empty content. This will result in the created - * {@link Page} being identical to the entire {@link List}. - */ - public TarantoolPageImpl() { - this(Collections.emptyList(), Pageable.unpaged(), 0L); - } - - /** - * Creates a new {@link TarantoolPageImpl} with the given content. This will result in the created - * {@link Page} being identical to the entire {@link List}. - * - * @param content must not be {@literal null}. - */ - public TarantoolPageImpl(List content) { - this(content, Pageable.unpaged(), content == null ? 0L : content.size()); - } - - /** - * Constructor of {@link TarantoolPageImpl}. - * - * @param content the content of this page, must not be {@literal null}. - * @param pageable the paging information, must not be {@literal null}. - * @param total the total amount of items available. The total might be adapted considering the - * length of the content given, if it is going to be the content of the last page. This is in - * place to mitigate inconsistencies. - */ - public TarantoolPageImpl(List content, Pageable pageable, long total) { - - super(content, pageable); - - this.total = - pageable - .toOptional() - .filter(it -> !content.isEmpty()) - .filter(it -> it.getOffset() + it.getPageSize() > total) - .map(it -> it.getOffset() + content.size()) - .orElse(total); - } - - @Override - public int getTotalPages() { - return getSize() == 0 ? 1 : (int) Math.ceil((double) total / (double) getSize()); - } - - @Override - public long getTotalElements() { - return total; - } - - @Override - public boolean hasNext() { - return getNumber() + 1 < getTotalPages() && hasContent(); - } - - @Override - public boolean isLast() { - return !hasNext(); - } - - @Override - @NonNull - public Page map(@NonNull Function converter) { - return new PageImpl<>(getConvertedContent(converter), getPageable(), total); - } - - @Override - public String toString() { - - List content = getContent(); - boolean canGetContentType = !content.isEmpty() && content.get(0) != null; - - String contentType = canGetContentType ? content.get(0).getClass().getName() : "UNKNOWN"; - - return String.format( - "Page %s of %d containing %s instances", getNumber() + 1, getTotalPages(), contentType); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolPageImpl that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return total == that.total; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), total); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolPageRequest.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolPageRequest.java deleted file mode 100644 index 3f28e84c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolPageRequest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.io.Serial; -import java.util.Objects; - -import org.springframework.data.domain.AbstractPageRequest; -import org.springframework.data.domain.Sort; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; - -/** - * Basic implementation of {@link TarantoolPageable} for Tarantool. - * - *

Important: When specifying a cursor tuple, you must adhere to the following - * rules: - * - *

1. To specify a page starting from the beginning of {@code space} (the first element of the - * page is the first element found in {@code space}), use {@code tupleCursor == null}. - * - *

2. To specify an arbitrary page (the first element of the page is the next/previous one from - * the given one tuple cursor depending on the methods used and page number), use {@code tupleCursor - * == someTupleCursor} . - * - * @param domain entity type - */ -public final class TarantoolPageRequest extends AbstractPageRequest - implements TarantoolPageable { - - @Serial private static final long serialVersionUID = -4541509938956089562L; - - private final Sort sort; - - private final T tupleCursor; - - private final PaginationDirection paginationDirection; - - /** - * Creates a new unsorted {@link TarantoolPageRequest} from begin of {@code space}. - * - * @param pageSize the size of the page to be returned, must be greater than 0. - */ - public TarantoolPageRequest(int pageSize) { - this(0, pageSize, null); - } - - /** - * Creates a new unsorted {@link TarantoolPageRequest}. - * - *

Important: Use this method with caution! It is important to know the exact - * match of number pages and the tuple after (before) which the page goes (without including this - * tuple in the page itself). A mistake in compliance results in the appearance of blank pages - * with unpaged pageable even when using methods {@link - * TarantoolPageImpl#previousOrFirstPageable()} / {@link TarantoolPageImpl#nextOrLastPageable()} - * and {@link TarantoolSliceImpl#previousOrFirstPageable()} / {@link - * TarantoolSliceImpl#nextOrLastPageable()}. - * - * @param page zero-based page index (virtual), must not be negative. - * @param size the size of the page to be returned, must be greater than 0. - * @param tupleCursor tuple cursor from which the page count begins. More: {@link - * TarantoolPageRequest}. - */ - public TarantoolPageRequest(int page, int size, T tupleCursor) { - this(page, size, Sort.unsorted(), tupleCursor, FORWARD); - } - - /** - * Private constructor to create an instance with a specific {@link PaginationDirection}. - * - * @param page zero-based page index, must not be negative. - * @param size the size of the page to be returned, must be greater than 0. - * @param sort must not be {@literal null}, use {@link Sort#unsorted()} instead. - * @param tupleCursor tuple cursor from which the page count begins. More: {@link - * TarantoolPageRequest}. - * @param direction direction of pagination. - */ - TarantoolPageRequest( - int page, int size, Sort sort, T tupleCursor, @NonNull PaginationDirection direction) { - super(page, size); - Assert.notNull(sort, "Sort must not be null"); - Assert.notNull(direction, "PaginationDirection must not be null"); - - this.sort = sort; - this.tupleCursor = tupleCursor; - this.paginationDirection = direction; - } - - /** Non supported for Tarantool. */ - @Override - @NonNull - public TarantoolPageRequest withPage(int pageNumber) throws UnsupportedOperationException { - throw new UnsupportedOperationException("method \"withPage(int pageNumber)\" unsupported"); - } - - @Override - @NonNull - public TarantoolPageable first() { - return new TarantoolPageRequest<>(getPageSize()); - } - - /** Non supported for Tarantool. Use {@link #next(Object)}. */ - @Override - @NonNull - public TarantoolPageRequest next() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"next()\" unsupported, use next(T nextTupleCursor)"); - } - - @Override - public TarantoolPageRequest next(T tupleCursor) { - return new TarantoolPageRequest<>( - getPageNumber() + 1, getPageSize(), getSort(), tupleCursor, FORWARD); - } - - /** Non supported for Tarantool. Use {@link #previous(Object)}. */ - @Override - @NonNull - public TarantoolPageRequest previous() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"previous()\" unsupported, use previous(T prevTupleCursor)"); - } - - private TarantoolPageRequest previous(T tupleCursor) { - if (hasPrevious()) { - return new TarantoolPageRequest<>( - getPageNumber() - 1, getPageSize(), getSort(), tupleCursor, BACKWARD); - } - return this; - } - - /** Non supported for Tarantool. Use {@link #previousOrFirst(Object)}. */ - @Override - @NonNull - public TarantoolPageable previousOrFirst() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "method \"previousOrFirst()\" unsupported, use previousOrFirst(T prevTupleCursor)"); - } - - @Override - public TarantoolPageable previousOrFirst(T tupleCursor) { - if (hasPrevious()) { - return previous(tupleCursor); - } - return new TarantoolPageRequest<>(0, getPageSize(), getSort(), null, BACKWARD); - } - - @Override - public PaginationDirection getPaginationDirection() { - return this.paginationDirection; - } - - @Override - @NonNull - public Sort getSort() { - return this.sort; - } - - @Override - public T getTupleCursor() { - return this.tupleCursor; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolPageRequest that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return sort.equals(that.sort) - && Objects.equals(tupleCursor, that.tupleCursor) - && paginationDirection == that.paginationDirection; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), sort, tupleCursor, paginationDirection); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolPageable.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolPageable.java deleted file mode 100644 index a4e11d90..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolPageable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import org.springframework.data.domain.Pageable; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; - -import io.tarantool.spring.data.query.PaginationDirection; - -/** - * Abstract interface for pagination information in Tarantool. - * - * @param domain class type. - * @author Nikolay Belonogov - */ -public interface TarantoolPageable extends Pageable { - - /** - * Returns tuple cursor of domain type. Can be {@code null}. If the cursor is {@code null} then - * the page is counted from the first tuple in Tarantool. - * - * @return tuple cursor of domain type. - */ - @Nullable - T getTupleCursor(); - - /** - * Returns the {@link TarantoolPageable} for previous page or the {@link TarantoolPageable} for - * first page if the current one already is the first one. Important: this method - * always returns {@link TarantoolPageable} c {@link PaginationDirection#BACKWARD}. - * - * @param tupleCursor tuple cursor of domain type for previous page. - * @return {@link TarantoolPageable} instance. - */ - TarantoolPageable previousOrFirst(T tupleCursor); - - /** - * Returns the {@link TarantoolPageable} requesting the next {@link - * org.springframework.data.domain.Page}. - * - *

Important: method always creates a new {@link TarantoolPageable} with the - * same parameters Sort and page size. Pagination direction is {@link - * PaginationDirection#FORWARD}, the page number always has value {@code n+1}, n is the current - * page number. - * - * @param tupleCursor tuple cursor of domain type for next page. - * @return {@link TarantoolPageable} object - */ - TarantoolPageable next(T tupleCursor); - - /** - * Returns pagination direction by {@link PaginationDirection} enumeration. - * - * @return {@link PaginationDirection}. - */ - PaginationDirection getPaginationDirection(); - - /** - * Returns a {@link TarantoolPageable} that points to the first page with {@link - * PaginationDirection#FORWARD} pagination direction. - * - * @return {@link TarantoolPageable} which has {@code cursor == null}, page number is 0, the rest - * parameters are equivalent to the parameters of the current {@link TarantoolPageable}. - */ - @NonNull - TarantoolPageable first(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolPartTreeQuery.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolPartTreeQuery.java deleted file mode 100644 index 4a444f39..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolPartTreeQuery.java +++ /dev/null @@ -1,506 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.springframework.data.domain.Limit; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; -import org.springframework.data.keyvalue.core.IterableConverter; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery; -import org.springframework.data.repository.query.Parameter; -import org.springframework.data.repository.query.Parameters; -import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.data.util.StreamUtils; -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; - -import static io.tarantool.client.crud.ConditionOperator.GREATER_EQ; -import static io.tarantool.client.crud.ConditionOperator.LESS_EQ; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import static io.tarantool.spring.data35.query.PaginationUtils.doPageQuery; -import static io.tarantool.spring.data35.query.PaginationUtils.doPaginationQuery; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.query.TarantoolCriteria; -import io.tarantool.spring.data.utils.Pair; - -/** - * There is one instance for each query method defined for a repository, providing a query from the - * bind parameters. - * - * @author Artyom Dubinin - */ -public class TarantoolPartTreeQuery extends KeyValuePartTreeQuery { - - public static final String ILLEGAL_RETURN_TYPE_FOR_DELETE = - "Illegal returned type: %s. The operation 'deleteBy' accepts only 'long' and 'Collection' as" - + " the returned object type"; - public static final String QUERY_METHOD_S_NOT_SUPPORTED = "Query method '%s' not supported."; - private final QueryMethod queryMethod; - private final KeyValueOperations keyValueOperations; - private final PartTree tree; - - private final boolean isCount; - private final boolean isDelete; - private final boolean isDistinct; - private final boolean isExists; - private final Class targetType; - private final Class returnType; - - private boolean isRearrangeKnown; - private boolean isRearrangeRequired; - private int[] rearrangeIndex; - - private final List EMPTY_KEY = Collections.emptyList(); - - /** - * Create a {@link RepositoryQuery} implementation for each query method defined in a tarantool - * repository. - * - * @param queryMethod Method defined in Tarantool Repositories - * @param evaluationContextProvider Not used - * @param keyValueOperations Interface to Tarantool - * @param queryCreator Not used - */ - public TarantoolPartTreeQuery( - QueryMethod queryMethod, - QueryMethodEvaluationContextProvider evaluationContextProvider, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - super(queryMethod, evaluationContextProvider, keyValueOperations, queryCreator); - this.queryMethod = queryMethod; - this.keyValueOperations = keyValueOperations; - this.isRearrangeKnown = false; - this.targetType = queryMethod.getEntityInformation().getJavaType(); - this.returnType = queryMethod.getReturnedObjectType(); - this.tree = new PartTree(getQueryMethod().getName(), targetType); - if (queryMethod.getParameters().getNumberOfParameters() > 0) { - this.isCount = tree.isCountProjection(); - this.isDelete = tree.isDelete(); - this.isDistinct = tree.isDistinct(); - this.isExists = tree.isExistsProjection(); - } else { - this.isCount = false; - this.isDelete = false; - this.isDistinct = false; - this.isExists = false; - } - } - - /** - * Execute this query instance, using any invocation parameters. - * - *

Expecting {@code findBy...()}, {@code countBy...()} or {@code deleteBy...()} - * - * @param parameters Any parameters - * @return Query result - */ - @Override - public Object execute(@NonNull Object[] parameters) { - ParametersParameterAccessor accessor = this.prepareAccessor(parameters, tree); - - KeyValueQuery query = prepareQuery(accessor); - - if (this.isCount) { - if (this.isDistinct) { - final Iterable iterable = this.keyValueOperations.find(query, targetType); - return StreamUtils.createStreamFromIterator(iterable.iterator()).distinct().count(); - } - return this.keyValueOperations.count(query, targetType); - } - - if (this.isDelete) { - return this.executeDeleteQuery(query); - } - - if (this.isExists) { - query.setOffset(0); - query.setRows(1); - final Iterable result = this.keyValueOperations.find(query, targetType); - return result.iterator().hasNext(); - } - - if (queryMethod.isPageQuery()) { - return this.executePageQuery(query, accessor); - } - - if (queryMethod.isSliceQuery()) { - return this.executeSliceQuery(query, accessor); - } - - if (queryMethod.isScrollQuery()) { - return this.executeScrollQuery(query, accessor); - } - - if (queryMethod.isCollectionQuery() - || queryMethod.isQueryForEntity() - || queryMethod.isStreamQuery()) { - return this.executeFindQuery(query); - } - - throw new UnsupportedOperationException( - String.format(QUERY_METHOD_S_NOT_SUPPORTED, queryMethod.getName())); - } - - /** - * Execute a "delete" query, not really a query more of an operation. - * - *

- * - * @param query The query to run - * @return Collection of deleted objects or the number of deleted objects - */ - private Object executeDeleteQuery(final KeyValueQuery query) { - - Iterable resultSet = this.keyValueOperations.find(query, targetType); - Iterator iterator = resultSet.iterator(); - - List result = new ArrayList<>(); - while (iterator.hasNext()) { - result.add(this.keyValueOperations.delete(iterator.next())); - } - - if (queryMethod.isCollectionQuery()) { - return result; - } - if (long.class.equals(returnType) || Long.class.equals(returnType)) { - return result.size(); - } - throw new UnsupportedOperationException( - String.format(ILLEGAL_RETURN_TYPE_FOR_DELETE, returnType)); - } - - /** - * Execute a retrieval query. The query engine will return this in an iterator, which may need - * conversion to a single domain entity or a stream. - * - * @param query The query to run - * @return Query result - */ - private Object executeFindQuery(final KeyValueQuery query) { - - Iterable resultSet = this.keyValueOperations.find(query, targetType); - - if (!queryMethod.isCollectionQuery() - && !queryMethod.isPageQuery() - && !queryMethod.isSliceQuery() - && !queryMethod.isStreamQuery()) { - // Singleton result - return resultSet.iterator().hasNext() ? resultSet.iterator().next() : null; - } - - Stream stream = StreamUtils.createStreamFromIterator(resultSet.iterator()); - if (this.isDistinct) { - stream = stream.distinct(); - } - - if (queryMethod.isStreamQuery()) { - return stream; - } - - // optimization: - // we can omit if condition - // but this will recreate result even if it's not distinct and isn't stream query - if (this.isDistinct) { - return stream.collect(Collectors.toList()); - } - - return resultSet; - } - - private Object executeScrollQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - ScrollPosition scrollPosition = accessor.getScrollPosition(); - - Assert.notNull( - scrollPosition, - "The ScrollPosition parameter must be specified. Method: " + queryMethod.getName()); - - if (!(scrollPosition instanceof TarantoolKeysetScrollPosition keysetScrollPosition)) { - throw new IllegalArgumentException( - "ScrollPosition must be an instance of TarantoolKeysetScrollPosition. Method: " - + queryMethod.getName()); - } - - int pageSize = query.getRows(); - List content = doScrollQuery(query, keysetScrollPosition, pageSize + 1); - - boolean hasNext = content.size() > pageSize; - - final List finalResult = getPaginationSubResult(content, pageSize, FORWARD, hasNext); - return Window.from( - finalResult, - value -> - new TarantoolKeysetScrollPosition( - keysetScrollPosition.getIndexKey(), - keysetScrollPosition.getDirection(), - finalResult.get(value)), - hasNext); - } - - private List doScrollQuery( - final KeyValueQuery query, TarantoolKeysetScrollPosition scrollPosition, int pageSize) { - TarantoolCriteria criteria = castToTarantoolCriteria(query.getCriteria()); - PaginationDirection paginationDirection = scrollPosition.getDirection(); - - Object cursor = scrollPosition.getCursor(); - Pair indexKey = scrollPosition.getIndexKey(); - - Object second = EMPTY_KEY; - if (cursor == null) { - second = indexKey.getSecond(); - } - - switch (paginationDirection) { - case FORWARD -> - criteria.addCondition(0, Condition.create(GREATER_EQ, indexKey.getFirst(), second)); - case BACKWARD -> - criteria.addCondition(0, Condition.create(LESS_EQ, indexKey.getFirst(), second)); - } - - criteria.withAfter(cursor); - query.setRows(pageSize); - return IterableConverter.toList(this.keyValueOperations.find(query, targetType)); - } - - /** - * Execute the slice request. - * - * @param query query - * @param accessor accessor - * @return slice selection result. - */ - private Object executePageQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - - Pageable pageParams = accessor.getPageable(); - - return doPageQuery(pageParams, query, this.keyValueOperations, targetType); - } - - private Object executeSliceQuery( - final KeyValueQuery query, ParametersParameterAccessor accessor) { - - Pageable sliceParams = accessor.getPageable(); - - if (sliceParams.isUnpaged()) { - return new TarantoolSliceImpl<>(Collections.emptyList()); - } - - TarantoolPageable resultSliceParams = castToTarantoolPageable(sliceParams); - - int pageSize = resultSliceParams.getPageSize(); - - List content = - doPaginationQuery( - query, resultSliceParams, pageSize + 1, this.keyValueOperations, targetType); - - if (content.isEmpty()) { - return new TarantoolSliceImpl<>(); - } - - boolean hasNext = content.size() > resultSliceParams.getPageSize(); - PaginationDirection paginationDirection = resultSliceParams.getPaginationDirection(); - - List result = getPaginationSubResult(content, pageSize, paginationDirection, hasNext); - return new TarantoolSliceImpl<>(result, resultSliceParams, hasNext); - } - - /** - * Returns {@link TarantoolPageable} cast from {@link Pageable} with type checking. - * - * @param sliceParams pageable - * @return {@link TarantoolPageable} - */ - private TarantoolPageable castToTarantoolPageable(Pageable sliceParams) { - Assert.isInstanceOf(TarantoolPageable.class, sliceParams, "Pageable must be TarantoolPageable"); - return (TarantoolPageable) sliceParams; - } - - /** - * The method allows you to get {@link TarantoolCriteria} even when pagination is used through - * methods the base repository (not via derived methods). - * - * @param criteria criteria object - * @return An instance of {@link TarantoolCriteria}, or creates a new one if null. - */ - private TarantoolCriteria castToTarantoolCriteria(Object criteria) { - if (criteria == null) { - return new TarantoolCriteria(); - } - - if (!(criteria instanceof TarantoolCriteria)) { - throw new IllegalArgumentException("criteria must be instance of TarantoolCriteria"); - } - return (TarantoolCriteria) criteria; - } - - private List getPaginationSubResult( - List content, int pageSize, PaginationDirection direction, boolean hasNext) { - if (hasNext) { - switch (direction) { - case FORWARD -> { - return content.subList(0, pageSize); - } - case BACKWARD -> { - return content.subList(1, content.size()); - } - } - } - return content; - } - - /** - * Create the query from the bind parameters. - * - * @return A ready-to-use query - */ - @NonNull - protected KeyValueQuery prepareQuery(ParametersParameterAccessor accessor) { - KeyValueQuery query = createQuery(accessor); - - /* - If there is no limitation in the name of the method, we always put a - limit so that don't think about this in the engine, especially when distinguishing between a regular query and a - paginated query. - */ - if (!tree.isLimiting()) { - query.setRows(SelectOptions.DEFAULT_LIMIT); - } - - Limit limit = accessor.getLimit(); - if (limit.isLimited()) { - final int max = limit.max(); - if (max < 0) { - throw new IllegalArgumentException( - "The max number of potential results should be positive! Method: " - + queryMethod - + ". Limit: " - + max); - } - query.setRows(limit.max()); - } - - if (accessor.getSort() != Sort.unsorted()) { - query.setSort(accessor.getSort()); - } - - return query; - } - - /** - * Handle {@code @Param}. - * - *
    - *
  1. Without {@code @Param} - *

    Arguments to the call are assumed to follow the same sequence as cited in the method - * name.
    - * Eg. - *

    -   *     findByOneAndTwo(String one, String two);
    -   *     
    - *
  2. With {@code @Param} - *

    Arguments to the call are use the {@code @Param} to match them against the fields. - *

    Eg. - *

    -   *   findByOneAndTwo(@Param("two") String two, @Param("one") String one);
    -   *   
    - *
- * - * @param originalParameters Possibly empty - * @param partTree Query tree to traverse - * @return Parameters in correct order - */ - private ParametersParameterAccessor prepareAccessor( - final Object[] originalParameters, final PartTree partTree) { - - if (!this.isRearrangeKnown) { - this.prepareRearrange(partTree, this.queryMethod.getParameters().getBindableParameters()); - this.isRearrangeKnown = true; - } - - Object[] parameters = originalParameters; - Assert.notNull(parameters, "Parameters must not be null."); - - if (this.isRearrangeRequired) { - parameters = new Object[originalParameters.length]; - - for (int i = 0; i < parameters.length; i++) { - int index = (i < rearrangeIndex.length) ? rearrangeIndex[i] : i; - parameters[i] = originalParameters[index]; - } - } - - return new ParametersParameterAccessor(this.queryMethod.getParameters(), parameters); - } - - /** - * Determine if the arguments to the method need reordered. - * - *

For searches such as {@code findBySomethingNotNull} there may be more parts than parameters - * needed to be bound to them. - * - * @param partTree Query parts - * @param bindableParameters Parameters expected - */ - @SuppressWarnings("unchecked") - private void prepareRearrange( - final PartTree partTree, final Parameters bindableParameters) { - - this.isRearrangeRequired = false; - if (partTree == null || bindableParameters == null) { - return; - } - - List queryParams = new ArrayList<>(); - List methodParams = new ArrayList<>(); - - for (Part part : partTree.getParts()) { - queryParams.add(part.getProperty().getSegment()); - } - - Iterator bindableParameterIterator = - (Iterator) bindableParameters.iterator(); - while (bindableParameterIterator.hasNext()) { - Parameter parameter = bindableParameterIterator.next(); - parameter.getName().ifPresent(methodParams::add); - } - - this.rearrangeIndex = new int[queryParams.size()]; - - String[] paramsExpected = queryParams.toArray(new String[0]); - String[] paramsProvided = methodParams.toArray(new String[0]); - - for (int i = 0; i < this.rearrangeIndex.length; i++) { - this.rearrangeIndex[i] = i; - - for (int j = 0; j < paramsProvided.length; j++) { - if (paramsProvided[j] != null && paramsProvided[j].equals(paramsExpected[i])) { - this.rearrangeIndex[i] = j; - this.isRearrangeRequired = true; - } - } - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolQueryCreator.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolQueryCreator.java deleted file mode 100644 index 84b5a2f8..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolQueryCreator.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.mapping.PropertyPath; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -import static io.tarantool.client.crud.ConditionOperator.EQ; -import static io.tarantool.client.crud.ConditionOperator.GREATER; -import static io.tarantool.client.crud.ConditionOperator.GREATER_EQ; -import static io.tarantool.client.crud.ConditionOperator.LESS; -import static io.tarantool.client.crud.ConditionOperator.LESS_EQ; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.ConditionOperator; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolQueryCreator - extends AbstractQueryCreator, TarantoolCriteria> { - - private final Map cache = new ConcurrentHashMap<>(); - - public static final String INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE = - "Logic error for '%s' in query. "; - - public TarantoolQueryCreator(PartTree tree, ParameterAccessor parameters) { - super(tree, parameters); - } - - private String getFieldName(Part part) { - PropertyPath property = part.getProperty(); - String segment = property.toDotPath(); - Class domainType = property.getOwningType().getType(); - java.lang.reflect.Field field = ReflectionUtils.findField(domainType, segment); - - if (field == null) { - throw new IllegalArgumentException("No such field: " + segment + " in " + domainType); - } - Field annotationField = field.getAnnotation(Field.class); - - if (annotationField != null) { - String value = annotationField.value(); - if (StringUtils.hasText(value)) { - return value; - } - String name = annotationField.name(); - if (StringUtils.hasText(name)) { - return name; - } - } - - return segment; - } - - @Override - @NonNull - protected TarantoolCriteria create(Part part, @NonNull Iterator iterator) { - final TarantoolCriteria tarantoolCriteria = new TarantoolCriteria(); - - Part.Type type = part.getType(); - if (isIgnoreCase(part)) { - throw new InvalidDataAccessApiUsageException( - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "IgnoreCase isn't supported yet", - type)); - } - String property = cache.computeIfAbsent(part, this::getFieldName); - - switch (type) { - case SIMPLE_PROPERTY: - generateConditions(tarantoolCriteria, type, property, iterator, EQ); - break; - case LESS_THAN: - case BEFORE: - generateConditions(tarantoolCriteria, type, property, iterator, LESS); - break; - case LESS_THAN_EQUAL: - generateConditions(tarantoolCriteria, type, property, iterator, LESS_EQ); - break; - case GREATER_THAN: - case AFTER: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER); - break; - case GREATER_THAN_EQUAL: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER_EQ); - break; - case BETWEEN: - generateConditions(tarantoolCriteria, type, property, iterator, GREATER, LESS); - break; - case TRUE: - tarantoolCriteria.addCondition(Condition.create(EQ, property, true)); - break; - case FALSE: - tarantoolCriteria.addCondition(Condition.create(EQ, property, false)); - break; - case IS_EMPTY: - tarantoolCriteria.addCondition(Condition.create(EQ, property, "")); - break; - case IS_NULL: - tarantoolCriteria.addCondition(Condition.create(EQ, property, null)); - break; - default: - throw new InvalidDataAccessApiUsageException(String.format("Unsupported type '%s'", type)); - } - - return tarantoolCriteria; - } - - private void generateConditions( - TarantoolCriteria tarantoolCriteria, - Part.Type type, - String property, - Iterator iterator, - ConditionOperator... operators) { - for (int i = 0; i < type.getNumberOfArguments(); i++) { - if (!iterator.hasNext()) { - throw new InvalidDataAccessApiUsageException( - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "Transmitted not enough arguments (%d of %d)", - type, - i, - type.getNumberOfArguments())); - } - tarantoolCriteria.addCondition(Condition.create(operators[i], property, iterator.next())); - } - } - - private boolean isIgnoreCase(Part part) { - switch (part.shouldIgnoreCase()) { - case ALWAYS: - Assert.state( - canUpperCase(part.getProperty()), - String.format( - "Unable to ignore case of %s types, the property '%s' must reference a String", - part.getProperty().getType().getName(), part.getProperty().getSegment())); - return true; - case WHEN_POSSIBLE: - return canUpperCase(part.getProperty()); - case NEVER: - default: - return false; - } - } - - private boolean canUpperCase(PropertyPath path) { - return String.class.equals(path.getType()); - } - - @Override - @NonNull - protected TarantoolCriteria and( - @NonNull Part part, @NonNull TarantoolCriteria base, @NonNull Iterator iterator) { - throw new UnsupportedOperationException(); - } - - @Override - @NonNull - protected TarantoolCriteria or( - @NonNull TarantoolCriteria base, @NonNull TarantoolCriteria criteria) { - throw new UnsupportedOperationException(); - } - - @Override - @NonNull - protected KeyValueQuery complete( - @Nullable final TarantoolCriteria criteria, @NonNull Sort sort) { - return new KeyValueQuery<>(criteria); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolQueryMethodImpl.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolQueryMethodImpl.java deleted file mode 100644 index b30a7f45..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolQueryMethodImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.lang.reflect.Method; - -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryMethod; - -import io.tarantool.spring.data.query.Query; -import io.tarantool.spring.data.query.TarantoolQueryMethod; - -/** Tarantool {@link QueryMethod} Implementation */ -public class TarantoolQueryMethodImpl extends QueryMethod implements TarantoolQueryMethod { - - private final Method method; - - public TarantoolQueryMethodImpl( - Method method, RepositoryMetadata metadata, ProjectionFactory factory) { - super(method, metadata, factory); - this.method = method; - } - - public boolean hasAnnotatedQuery() { - return getQuery() != null; - } - - public String getQueryValue(Query query) { - return (String) AnnotationUtils.getValue(query); - } - - public Query getQuery() { - return method.getAnnotation(Query.class); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolRepositoryQuery.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolRepositoryQuery.java deleted file mode 100644 index 4307e2ec..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolRepositoryQuery.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.RepositoryQuery; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.query.ProxyTarantoolRepositoryQuery; - -/** {@link RepositoryQuery} using String based function name to call function in Tarantool. */ -public class TarantoolRepositoryQuery implements RepositoryQuery { - - private final ProxyTarantoolRepositoryQuery proxy; - private final TarantoolQueryMethodImpl queryMethod; - - public TarantoolRepositoryQuery( - TarantoolCrudClient client, TarantoolQueryMethodImpl queryMethod) { - this.queryMethod = queryMethod; - this.proxy = new ProxyTarantoolRepositoryQuery(client, queryMethod); - } - - @Override - public Object execute(Object[] parameters) { - return proxy.execute(parameters); - } - - @Override - public QueryMethod getQueryMethod() { - return queryMethod; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolScrollPosition.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolScrollPosition.java deleted file mode 100644 index 29dc19cc..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolScrollPosition.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import org.springframework.data.domain.ScrollPosition; - -import io.tarantool.spring.data.utils.Pair; - -/** - * Use keyset pagination adapted for Tarantool crud module.. - * - * @author Nikolay Belonogov - * @see #forward(Pair) - * @see #backward(Pair) - * @see #reverse() - */ -public sealed interface TarantoolScrollPosition extends ScrollPosition - permits TarantoolKeysetScrollPosition { - - /** - * Creates a new {@link ScrollPosition} based on the key index scrolling forward. - * - * @param indexKey pair, where the first element is the name of the index on which you want to - * perform pagination. Second element is the value of the indexed field from which you want to - * paginate (exclusive). To perform pagination from the beginning of the index, pass an empty - * list as the second element of the pair. indexKey must be not {@code null}. - * @return new {@link TarantoolScrollPosition} instance. - */ - static TarantoolScrollPosition forward(Pair indexKey) { - return TarantoolKeysetScrollPosition.forward(indexKey); - } - - /** - * Creates a new {@link ScrollPosition} based on the key index scrolling backward. - * - * @param indexKey pair, where the first element is the name of the index on which you want to - * perform pagination. Second element is the value of the indexed field from which you want to - * paginate (exclusive). To perform pagination from the end of the index, pass an empty list - * as the second element of the pair. indexKey must be not {@code null}. - * @return new {@link TarantoolScrollPosition} instance. - */ - static TarantoolScrollPosition backward(Pair indexKey) { - return TarantoolKeysetScrollPosition.backward(indexKey); - } - - /** - * Return {@link TarantoolScrollPosition} with the same parameters, but with the opposite - * pagination direction. If the current {@link TarantoolScrollPosition} was set from the beginning - * of the index, the method will return the {@link TarantoolScrollPosition} set from the end of - * the index. Returns the {@link TarantoolScrollPosition} set from the beginning of the index if - * the current {@link TarantoolScrollPosition} is set from the end of the index. - * - *

Important: when this method is called, the condition specified by the index in - * the current {@link TarantoolScrollPosition} is overridden to unconditional (i.e. it will be - * searched to the end or beginning of the index) - * - * @return {@link TarantoolScrollPosition} instance. - */ - TarantoolScrollPosition reverse(); - - /** - * Return {@code true} if scrolling has backward motion. This means that the current {@link - * TarantoolScrollPosition} has the direction of movement {@link - * io.tarantool.spring.data.query.PaginationDirection#BACKWARD}. Return {@code false} if scrolling - * has forward motion ({@link io.tarantool.spring.data.query.PaginationDirection#FORWARD}). - * - * @return {@link Boolean} primitive. - */ - boolean isScrollsBackward(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolSliceImpl.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolSliceImpl.java deleted file mode 100644 index 496ffd83..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolSliceImpl.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.io.Serial; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.lang.NonNull; - -/** - * Default implementation of {@link Slice} for Tarantool. - * - * @author Nikolay Belonogov - */ -class TarantoolSliceImpl extends TarantoolChunk { - - @Serial private static final long serialVersionUID = 867755909294344406L; - - private final boolean hasNext; - - private final Pageable pageable; - - /** - * Creates a new {@link TarantoolSliceImpl} with the empty content. This will result in the - * created {@link Slice} being identical to the entire {@link List}. - */ - public TarantoolSliceImpl() { - this(Collections.emptyList(), Pageable.unpaged(), false); - } - - /** - * Creates a new {@link TarantoolSliceImpl} with the given content. This will result in the - * created {@link Slice} being identical to the entire {@link List}. - * - * @param content must not be {@literal null}. - */ - public TarantoolSliceImpl(List content) { - this(content, Pageable.unpaged(), false); - } - - /** - * Creates a new {@link TarantoolSliceImpl} with the given content and {@link Pageable}. - * - * @param content the content of this {@link Slice}, must not be {@literal null}. - * @param pageable the paging information, must not be {@literal null}. - * @param hasNext whether there's another slice following the current one. - */ - public TarantoolSliceImpl(List content, Pageable pageable, boolean hasNext) { - super(content, pageable); - - this.hasNext = hasContent() && hasNext; - this.pageable = pageable; - } - - /** - * Returns true if there is a next data slice. No data content means that the next slice does not - * exist and method will return false. - * - * @return Returns true if there is a next data slice. No data content means that the next slice - * does not exist and method will return false. - */ - @Override - public boolean hasNext() { - return hasNext && hasContent(); - } - - @Override - @NonNull - public Slice map(@NonNull Function converter) { - return new TarantoolSliceImpl<>(getConvertedContent(converter), pageable, hasNext); - } - - @Override - public String toString() { - - String contentType = "UNKNOWN"; - List content = getContent(); - - if (content.size() > 0) { - contentType = content.get(0).getClass().getName(); - } - - return String.format("Slice %d containing %s instances", getNumber(), contentType); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof TarantoolSliceImpl that)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return hasNext == that.hasNext && pageable.equals(that.pageable); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), hasNext, pageable); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolSortAccessor.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolSortAccessor.java deleted file mode 100644 index c6f49c7d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolSortAccessor.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.util.Comparator; -import java.util.Map.Entry; - -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Sort.Order; -import org.springframework.data.keyvalue.core.SortAccessor; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -/** - * Implements sorting for Tarantool repository queries. - * - * @author Artyom Dubinin - */ -public class TarantoolSortAccessor implements SortAccessor>> { - - /** - * Sort on a sequence of fields, possibly none. - * - * @param query If not null, will contain one of more {@link Order} objects. - * @return A sequence of comparators or {@code null} - */ - public Comparator> resolve(KeyValueQuery query) { - if (query == null || query.getSort() == Sort.unsorted()) { - return null; - } - - throw new UnsupportedOperationException(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolWindowIterator.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolWindowIterator.java deleted file mode 100644 index c676887c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/query/TarantoolWindowIterator.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.function.Function; - -import org.springframework.data.domain.Window; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * The class is a complete analogue of {@link org.springframework.data.support.WindowIterator} for - * Tarantool. - * - *

Example of usage: - * - *

- * - *
{@code
- * TarantoolScrollPosition initialScrollPosition =
- *     TarantoolScrollPosition.forward(Pair.of("pk", Collections.emptyList()));
- *
- * TarantoolWindowIterator personIterator =
- *     TarantoolWindowIterator.of(scrollPosition -> repository.findFirst10ByAge(10, scrollPosition))
- *         .startingAt(initialScrollPosition);
- *
- * List result = new ArrayList<>();
- *
- * while (personIterator.hasNext()) {
- *   result.add(personIterator.next());
- * }
- * }
- * - *
- * - * @param domain class type. - */ -public class TarantoolWindowIterator implements Iterator { - - private final Function> windowFunction; - - private TarantoolScrollPosition currentPosition; - - private @Nullable Window currentWindow; - - private @Nullable Iterator currentIterator; - - /** - * Entrypoint to create a new {@link TarantoolWindowIterator} for the given windowFunction. - * - * @param windowFunction must not be {@literal null}. - * @param domain class type. - * @return new instance of {@link TarantoolWindowIteratorBuilder}. - */ - public static TarantoolWindowIteratorBuilder of( - Function> windowFunction) { - return new TarantoolWindowIteratorBuilder<>(windowFunction); - } - - TarantoolWindowIterator( - Function> windowFunction, - TarantoolScrollPosition position) { - - this.windowFunction = windowFunction; - this.currentPosition = position; - } - - @Override - public boolean hasNext() { - - // use while loop instead of recursion to fetch the next window. - do { - if (currentWindow == null) { - currentWindow = windowFunction.apply(currentPosition); - } - - if (currentIterator == null) { - if (currentWindow != null) { - currentIterator = currentWindow.iterator(); - } - } - - if (currentIterator != null) { - - if (currentIterator.hasNext()) { - return true; - } - - if (currentWindow != null && currentWindow.hasNext()) { - - currentPosition = getNextPosition(currentWindow); - currentIterator = null; - currentWindow = null; - continue; - } - } - - return false; - } while (true); - } - - @Override - public T next() { - - if (!hasNext()) { - throw new NoSuchElementException(); - } - - return currentIterator.next(); - } - - private static TarantoolScrollPosition getNextPosition(Window window) { - return (TarantoolScrollPosition) window.positionAt(window.size() - 1); - } - - /** Builder API to construct a {@link TarantoolWindowIterator}. */ - public static class TarantoolWindowIteratorBuilder { - - private final Function> windowFunction; - - TarantoolWindowIteratorBuilder(Function> windowFunction) { - - Assert.notNull(windowFunction, "WindowFunction must not be null"); - - this.windowFunction = windowFunction; - } - - /** - * Create a {@link TarantoolWindowIterator} given {@link TarantoolScrollPosition}. - * - * @param position {@link TarantoolScrollPosition} instance. Must be not null. - * @return {@link TarantoolWindowIterator} instance. - */ - public TarantoolWindowIterator startingAt(TarantoolScrollPosition position) { - - Assert.notNull(position, "TarantoolScrollPosition must not be null"); - - return new TarantoolWindowIterator<>(windowFunction, position); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/TarantoolRepositoryFactory.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/TarantoolRepositoryFactory.java deleted file mode 100644 index beabe445..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/TarantoolRepositoryFactory.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.repository; - -import java.util.Optional; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.SpelQueryCreator; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data35.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data35.repository.config.TarantoolQueryLookupStrategy; -import io.tarantool.spring.data35.repository.support.TarantoolSimpleRepository; - -/** - * Tarantool version of {@link KeyValueRepositoryFactory}, a factory to build tarantool repository - * instances. - * - *

The purpose of extending is to ensure that the {@link #getQueryLookupStrategy} method returns - * a {@link TarantoolQueryLookupStrategy} rather than the default. - * - *

The end goal of this bean is for {@link TarantoolPartTreeQuery} to be used for query - * preparation. - * - * @author Artyom Dubinin - */ -public class TarantoolRepositoryFactory extends KeyValueRepositoryFactory { - - private static final Class DEFAULT_QUERY_CREATOR = SpelQueryCreator.class; - - private final KeyValueOperations keyValueOperations; - private final Class> queryCreator; - private final TarantoolCrudClient client; - - /* Mirror functionality of super, to ensure private - * fields are set. - */ - public TarantoolRepositoryFactory( - TarantoolCrudClient client, KeyValueOperations keyValueOperations) { - this(client, keyValueOperations, DEFAULT_QUERY_CREATOR); - } - - /* Capture KeyValueOperations and QueryCreator objects after passing to super. - */ - public TarantoolRepositoryFactory( - TarantoolCrudClient client, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - - super(keyValueOperations, queryCreator); - - this.client = client; - this.keyValueOperations = keyValueOperations; - this.queryCreator = queryCreator; - } - - /** - * Ensure the mechanism for query evaluation is Tarantool specific, as the original {@code - * KeyValueQueryLookupStrategy} does not function correctly for Tarantool. - */ - @Override - protected Optional getQueryLookupStrategy( - QueryLookupStrategy.Key key, QueryMethodEvaluationContextProvider evaluationContextProvider) { - return Optional.of( - new TarantoolQueryLookupStrategy( - client, key, evaluationContextProvider, keyValueOperations, queryCreator)); - } - - @Override - protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { - return TarantoolSimpleRepository.class; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/EnableTarantoolRepositories.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/EnableTarantoolRepositories.java deleted file mode 100644 index 44eed3fc..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/EnableTarantoolRepositories.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.repository.config; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.ComponentScan.Filter; -import org.springframework.context.annotation.Import; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.config.QueryCreatorType; -import org.springframework.data.repository.config.DefaultRepositoryBaseClass; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryLookupStrategy.Key; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.spring.data35.config.properties.TarantoolProperties; -import io.tarantool.spring.data35.query.TarantoolQueryCreator; -import io.tarantool.spring.data35.repository.support.TarantoolRepositoryFactoryBean; - -@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@Import(TarantoolRepositoriesRegistrar.class) -@EnableConfigurationProperties(TarantoolProperties.class) -@QueryCreatorType(TarantoolQueryCreator.class) -public @interface EnableTarantoolRepositories { - - /** - * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation - * declarations e.g.: {@code @EnableJpaRepositories("org.my.pkg")} instead of - * {@code @EnableJpaRepositories(basePackages="org.my.pkg")}. - * - * @return value - */ - String[] value() default {}; - - /** - * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually - * exclusive with) this attribute. Use {@link #basePackageClasses()} for a type-safe alternative - * to String-based package names. - * - * @return base packages - */ - String[] basePackages() default {}; - - /** - * Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for - * annotated components. The package of each class specified will be scanned. Consider creating a - * special no-op marker class or interface in each package that serves no purpose other than being - * referenced by this attribute. - * - * @return classes - */ - Class[] basePackageClasses() default {}; - - /** - * Specifies which types are not eligible for component scanning. - * - * @return filters - */ - Filter[] excludeFilters() default {}; - - /** - * Specifies which types are eligible for component scanning. Further, narrows the set of - * candidate components from everything in {@link #basePackages()} to everything in the base - * packages that matches the given filter or filters. - * - * @return filters - */ - Filter[] includeFilters() default {}; - - /** - * Returns the postfix to be used when looking up custom repository implementations. Defaults to - * {@literal Impl}. So for a repository named {@code PersonRepository} the corresponding - * implementation class will be looked up scanning for {@code PersonRepositoryImpl}. - * - * @return postfix - */ - String repositoryImplementationPostfix() default "Impl"; - - /** - * Configures the location of where to find the Spring Data named queries properties file. - * - * @return location - */ - String namedQueriesLocation() default ""; - - /** - * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query - * methods. Defaults to {@link Key#CREATE_IF_NOT_FOUND}. - * - * @return strategy - */ - Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND; - - Class repositoryFactoryBeanClass() default TarantoolRepositoryFactoryBean.class; - - /** - * Allow custom base classes, for generic behavior shared amongst selected repositories. - * - * @return base class - */ - Class repositoryBaseClass() default DefaultRepositoryBaseClass.class; - - /** - * Configures the name of the {@link KeyValueOperations} bean to be used with the repositories - * detected. - * - * @return reference to {@link KeyValueOperations} bean. - */ - String keyValueTemplateRef() default DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; - - /** - * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be - * discovered by the repositories' infrastructure. - * - * @return result of consideration - */ - boolean considerNestedRepositories() default false; - - /** - * Configures the {@link ClientType} to be used as driver client type to connection to Tarantool. - * Must match the referenced type in {@link #keyValueTemplateRef()}} if these values differ from - * the default ones. - * - * @return the type of client through which communication with Tarantool will be made. - */ - ClientType clientType() default ClientType.CRUD; -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/TarantoolQueryLookupStrategy.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/TarantoolQueryLookupStrategy.java deleted file mode 100644 index 9b38b5e9..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/TarantoolQueryLookupStrategy.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.repository.config; - -import java.lang.reflect.Method; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery; -import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.repository.core.NamedQueries; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.util.Assert; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data35.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data35.query.TarantoolQueryMethodImpl; -import io.tarantool.spring.data35.query.TarantoolRepositoryQuery; - -/** - * Ensures {@link TarantoolPartTreeQuery} is used for query preparation rather than {@link - * KeyValuePartTreeQuery} or other alternatives. - * - * @author Artyom Dubinin - */ -public class TarantoolQueryLookupStrategy implements QueryLookupStrategy { - - private final QueryMethodEvaluationContextProvider evaluationContextProvider; - private final KeyValueOperations keyValueOperations; - private final Class> queryCreator; - private final TarantoolCrudClient client; - - /** - * Required constructor, capturing arguments for use in {@link #resolveQuery}. - * - * @param client tarantool crud client - * @param key Not used - * @param evaluationContextProvider For evaluation of query expressions - * @param keyValueOperations Bean to use for Key/Value operations on Tarantool repos - * @param queryCreator Query creator - */ - public TarantoolQueryLookupStrategy( - TarantoolCrudClient client, - Key key, - QueryMethodEvaluationContextProvider evaluationContextProvider, - KeyValueOperations keyValueOperations, - Class> queryCreator) { - - Assert.notNull(evaluationContextProvider, "EvaluationContextProvider must not be null!"); - Assert.notNull(keyValueOperations, "KeyValueOperations must not be null!"); - Assert.notNull(queryCreator, "Query creator type must not be null!"); - - this.client = client; - this.evaluationContextProvider = evaluationContextProvider; - this.keyValueOperations = keyValueOperations; - this.queryCreator = queryCreator; - } - - /** - * Use {@link TarantoolPartTreeQuery} for resolving queries against Tarantool repositories. - * - * @param method, the query method - * @param metadata, not used - * @param projectionFactory, not used - * @param namedQueries, not used - * @return A mechanism for querying Tarantool repositories - */ - public RepositoryQuery resolveQuery( - Method method, - RepositoryMetadata metadata, - ProjectionFactory projectionFactory, - NamedQueries namedQueries) { - - TarantoolQueryMethodImpl queryMethod = - new TarantoolQueryMethodImpl(method, metadata, projectionFactory); - - if (queryMethod.hasAnnotatedQuery()) { - return new TarantoolRepositoryQuery(client, queryMethod); - } - - return new TarantoolPartTreeQuery( - queryMethod, evaluationContextProvider, this.keyValueOperations, this.queryCreator); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/TarantoolRepositoriesRegistrar.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/TarantoolRepositoriesRegistrar.java deleted file mode 100644 index 8b3c7150..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/TarantoolRepositoriesRegistrar.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.repository.config; - -import java.lang.annotation.Annotation; - -import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport; -import org.springframework.data.repository.config.RepositoryConfigurationExtension; - -class TarantoolRepositoriesRegistrar extends RepositoryBeanDefinitionRegistrarSupport { - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoriesRegistrar#getAnnotation() - */ - @Override - protected Class getAnnotation() { - return EnableTarantoolRepositories.class; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport#getExtension() - */ - @Override - protected RepositoryConfigurationExtension getExtension() { - return new TarantoolRepositoryConfigurationExtension(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/TarantoolRepositoryConfigurationExtension.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/TarantoolRepositoryConfigurationExtension.java deleted file mode 100644 index f327f2d8..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/TarantoolRepositoryConfigurationExtension.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.repository.config; - -import org.springframework.beans.factory.config.ConstructorArgumentValues; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension; -import org.springframework.data.repository.config.RepositoryConfigurationSource; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.spring.data35.config.TarantoolCrudConfiguration; -import io.tarantool.spring.data35.core.TarantoolTemplate; -import io.tarantool.spring.data35.core.mapping.TarantoolMappingContext; - -public class TarantoolRepositoryConfigurationExtension - extends KeyValueRepositoryConfigurationExtension { - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getModuleName() - */ - @Override - public String getModuleName() { - return "Tarantool"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getModulePrefix() - */ - @Override - public String getModulePrefix() { - return "tarantool"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getDefaultKeyValueTemplateRef() - */ - @Override - public String getDefaultKeyValueTemplateRef() { - return DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #registerBeansForRoot() - */ - @Override - public void registerBeansForRoot( - BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) { - // register a default set of beans based on the passed annotation attributes. - final ClientType clientTypeAttribute = - configurationSource.getRequiredAttribute("clientType", ClientType.class); - - if (clientTypeAttribute == ClientType.CRUD) { - final String defaultCrudConfigurationBeanName = - TarantoolCrudConfiguration.class.getCanonicalName(); - registerIfNotAlreadyRegistered( - () -> new RootBeanDefinition(TarantoolCrudConfiguration.class), - registry, - defaultCrudConfigurationBeanName, - configurationSource); - } else { - throw new IllegalArgumentException("The Box client is not yet supported."); - } - super.registerBeansForRoot(registry, configurationSource); - - // remove KeyValueMappingContext to add TarantoolMappingContext - registry.removeBeanDefinition(getMappingContextBeanRef()); - registerIfNotAlreadyRegistered( - () -> { - RootBeanDefinition definition = new RootBeanDefinition(TarantoolMappingContext.class); - definition.setSource(configurationSource.getSource()); - - return definition; - }, - registry, - getMappingContextBeanRef(), - configurationSource); - } - - @Override - protected AbstractBeanDefinition getDefaultKeyValueTemplateBeanDefinition( - RepositoryConfigurationSource configurationSource) { - final RootBeanDefinition keyValueTemplateBeanDefinition = - new RootBeanDefinition(TarantoolTemplate.class); - - final ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); - constructorArgumentValues.addIndexedArgumentValue( - 0, new RuntimeBeanReference(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF)); - constructorArgumentValues.addIndexedArgumentValue( - 1, new RuntimeBeanReference(getMappingContextBeanRef())); - - keyValueTemplateBeanDefinition.setConstructorArgumentValues(constructorArgumentValues); - keyValueTemplateBeanDefinition.setSource(configurationSource); - keyValueTemplateBeanDefinition.setDependsOn(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF); - keyValueTemplateBeanDefinition.setDependsOn(getMappingContextBeanRef()); - - return keyValueTemplateBeanDefinition; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/package-info.java deleted file mode 100644 index e980ea2b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/config/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository config package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data35.repository.config; diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/package-info.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/package-info.java deleted file mode 100644 index 4f7d3489..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data35.repository; diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/support/TarantoolRepositoryFactoryBean.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/support/TarantoolRepositoryFactoryBean.java deleted file mode 100644 index baea36b9..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/support/TarantoolRepositoryFactoryBean.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.repository.support; - -import java.io.Serializable; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean; -import org.springframework.data.repository.Repository; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data35.repository.TarantoolRepositoryFactory; - -public class TarantoolRepositoryFactoryBean, S, ID extends Serializable> - extends KeyValueRepositoryFactoryBean { - - @Autowired private TarantoolCrudClient client; - - public TarantoolRepositoryFactoryBean(Class repositoryInterface) { - super(repositoryInterface); - } - - /** - * Return a {@link TarantoolRepositoryFactory}. - * - *

{@code super} would return {@link KeyValueRepositoryFactory} which in turn builds {@code - * KeyValueRepository} instances, and these have a private method that implement querying in a - * manner that does not fit with Tarantool. More details are in {@link - * TarantoolRepositoryFactory}. - * - * @param operations operations - * @param queryCreator creator - * @param repositoryQueryType, not used - * @return A {@link TarantoolRepositoryFactory} that creates tarantool repository instances. - */ - @Override - protected KeyValueRepositoryFactory createRepositoryFactory( - KeyValueOperations operations, - Class> queryCreator, - Class repositoryQueryType) { - return new TarantoolRepositoryFactory(client, operations, queryCreator); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/support/TarantoolSimpleRepository.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/support/TarantoolSimpleRepository.java deleted file mode 100644 index adcbfd48..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/support/TarantoolSimpleRepository.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.repository.support; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository; -import org.springframework.data.repository.core.EntityInformation; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data35.query.PaginationUtils.doPageQuery; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolSimpleRepository extends SimpleKeyValueRepository { - - private static final String FIND_ALL_EXC_MSG = - "This method is not supported to avoid sampling huge data massive. " - + "Please use derived methods with scrolling or pagination to select all data."; - - private static final String FIND_ALL_SORT_EXC_MSG = - "This method is not supported because sorting is not supported " - + "in Tarantool. Organize sorting of results using Java tools."; - - private static final String PAGEABLE_NULL_EXC_MSG = "Pageable must be not null"; - - private final KeyValueOperations operations; - private final EntityInformation entityInformation; - - /** - * Creates a new {@link SimpleKeyValueRepository} for the given {@link EntityInformation} and - * {@link KeyValueOperations}. - * - * @param metadata must not be {@literal null}. - * @param operations must not be {@literal null}. - */ - public TarantoolSimpleRepository( - EntityInformation metadata, KeyValueOperations operations) { - super(metadata, operations); - this.entityInformation = metadata; - this.operations = operations; - } - - @Override - public List findAll() { - throw new UnsupportedOperationException(FIND_ALL_EXC_MSG); - } - - @Override - public List findAll(Sort sort) { - throw new UnsupportedOperationException(FIND_ALL_SORT_EXC_MSG); - } - - @Override - @SuppressWarnings("unchecked") - public Page findAll(Pageable pageable) { - Assert.notNull(pageable, PAGEABLE_NULL_EXC_MSG); - - KeyValueQuery query = new KeyValueQuery<>(new TarantoolCriteria()); - return (Page) - doPageQuery(pageable, query, this.operations, this.entityInformation.getJavaType()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/support/package-info.java b/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/support/package-info.java deleted file mode 100644 index d878a125..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/main/java/io/tarantool/spring/data35/repository/support/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository support package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data35.repository.support; diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/GenericTarantoolConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/GenericTarantoolConfigurationTest.java deleted file mode 100644 index c7b5ca6d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/GenericTarantoolConfigurationTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.config; - -import java.io.IOException; -import java.nio.file.Files; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.test.context.TestPropertySource; - -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data35.config.properties.TarantoolProperties; -import io.tarantool.spring.data35.utils.TarantoolTestSupport; - -@TestPropertySource(properties = {Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -public abstract class GenericTarantoolConfigurationTest implements ApplicationContextAware { - - protected static TarantoolProperties testProperties; - - protected ApplicationContext applicationContext; - - @Autowired protected TarantoolProperties properties; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - @BeforeAll - static void beforeAll() throws IOException { - testProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists( - TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR.resolve( - Constants.DEFAULT_PROPERTY_FILE_NAME)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/TarantoolCrudConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/TarantoolCrudConfigurationTest.java deleted file mode 100644 index 624ceee8..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/TarantoolCrudConfigurationTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.config; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.bean.override.mockito.MockitoBean; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.pool.HeartbeatOpts; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyHeartbeatOpts; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.spring.data35.repository.config.EnableTarantoolRepositories; - -@SpringBootTest(classes = {TarantoolCrudConfigurationTest.Config.class}) -public class TarantoolCrudConfigurationTest extends GenericTarantoolConfigurationTest { - - @MockitoBean TarantoolCrudClient client; - - @Autowired private TarantoolCrudConfiguration tarantoolCrudConfiguration; - - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testGetCrudClientBuilder() throws IOException { - assertEquals(properties, tarantoolCrudConfiguration.getProperties()); - - final TarantoolCrudClientBuilder crudClientBuilder = - tarantoolCrudConfiguration.getClientBuilder(); - - if (properties.getConnectionGroups() == null) { - assertNull(crudClientBuilder.getGroups()); - } else { - assertEquals(properties.getConnectionGroups().size(), crudClientBuilder.getGroups().size()); - List connectionGroupsFromBuilder = crudClientBuilder.getGroups(); - List connectionGroupsFromProperty = - properties.getConnectionGroups(); - assertNotNull(connectionGroupsFromBuilder); - assertNotNull(connectionGroupsFromProperty); - for (int i = 0; i < connectionGroupsFromBuilder.size(); i++) { - InstanceConnectionGroup groupFromBuilder = connectionGroupsFromBuilder.get(i); - PropertyInstanceConnectionGroup groupFromProperty = connectionGroupsFromProperty.get(i); - - assertEquals(groupFromProperty.getAuthType(), groupFromBuilder.getAuthType()); - assertEquals(groupFromProperty.getTag(), groupFromBuilder.getTag()); - assertEquals(groupFromProperty.getConnectionGroupSize(), groupFromBuilder.getSize()); - assertEquals(groupFromProperty.getUserName(), groupFromBuilder.getUser()); - assertEquals(groupFromProperty.getPassword(), groupFromBuilder.getPassword()); - assertEquals(groupFromProperty.getPort(), groupFromBuilder.getPort()); - assertEquals(groupFromProperty.getHost(), groupFromBuilder.getHost()); - } - } - - final PropertyHeartbeatOpts propertiesHeartbeatOpts = properties.getHeartbeat(); - if (propertiesHeartbeatOpts == null) { - assertNull(crudClientBuilder.getHeartbeatOpts()); - } else { - HeartbeatOpts builderHeartbeatOpts = crudClientBuilder.getHeartbeatOpts(); - - assertEquals( - propertiesHeartbeatOpts.getPingInterval(), builderHeartbeatOpts.getPingInterval()); - assertEquals( - propertiesHeartbeatOpts.getDeathThreshold(), builderHeartbeatOpts.getDeathThreshold()); - assertEquals( - propertiesHeartbeatOpts.getInvalidationThreshold(), - builderHeartbeatOpts.getInvalidationThreshold()); - assertEquals(propertiesHeartbeatOpts.getWindowSize(), builderHeartbeatOpts.getWindowSize()); - } - - assertEquals(properties.getUserName(), crudClientBuilder.getUser()); - assertEquals(properties.getPort(), crudClientBuilder.getPort()); - assertEquals(properties.getEventLoopThreadsCount(), crudClientBuilder.getnThreads()); - assertEquals(properties.getBalancerClass(), crudClientBuilder.getBalancerClass()); - assertEquals(properties.isGracefulShutdownEnabled(), crudClientBuilder.isGracefulShutdown()); - assertEquals(properties.getConnectTimeout(), crudClientBuilder.getConnectTimeout()); - assertEquals(properties.getReconnectAfter(), crudClientBuilder.getReconnectAfter()); - assertEquals(properties.getHost(), crudClientBuilder.getHost()); - assertEquals(properties.getPassword(), crudClientBuilder.getPassword()); - - testProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @Test - void testKeyValueTemplate() { - final List beanDefinitions = Arrays.asList(applicationContext.getBeanDefinitionNames()); - assertTrue(beanDefinitions.contains(DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF)); - - final KeyValueTemplate keyValueTemplate = - applicationContext.getBean( - DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF, KeyValueTemplate.class); - assertNotNull(keyValueTemplate); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/TarantoolEmptyPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/TarantoolEmptyPropertiesTest.java deleted file mode 100644 index 81b71d7a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/TarantoolEmptyPropertiesTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.config; - -import java.io.IOException; -import java.nio.file.Files; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.TestPropertySource; - -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data35.config.properties.TarantoolProperties; -import io.tarantool.spring.data35.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data35.utils.TarantoolTestSupport; - -/** - * @see TarantoolPropertiesTest - */ -@SpringBootTest(classes = {TarantoolEmptyPropertiesTest.Config.class}) -@TestPropertySource(properties = {Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -@Timeout(5) -public class TarantoolEmptyPropertiesTest { - - @Autowired private TarantoolProperties springParsedProperties; - - @BeforeAll - static void beforeAll() throws IOException { - TarantoolTestSupport.writeTestEmptyPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - /* - * The test checks that if property processing is enabled via the @EnableConfigurationProperties annotation, then - * TarantoolProperty always exists and has default values. - */ - @Test - void testParseEmptyProperties() { - assertNotNull(springParsedProperties); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists( - TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR.resolve( - Constants.DEFAULT_PROPERTY_FILE_NAME)); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/TarantoolPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/TarantoolPropertiesTest.java deleted file mode 100644 index 5e47ea7b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/TarantoolPropertiesTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.config; - -import java.io.IOException; -import java.nio.file.Files; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Timeout; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.bean.override.mockito.MockitoBean; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data35.config.properties.TarantoolProperties; -import io.tarantool.spring.data35.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data35.utils.TarantoolTestSupport; - -/** - * The test checks whether the Spring framework parses a file with the specified properties - * correctly. Before creating the test class, a random file with properties is written to the - * classpath:properties-test.yaml file. Next, when creating a test class the Spring context is - * raised and parses the file with properties. A test is launched to check the uniqueness of the - * current properties and properties that were specified in the previous iteration. It is checked - * that the generated Spring class TarantoolProperty is equal to the class written to the file. - * Next, the next entry to the file occurs, after which there is a forced reload of the Spring - * context -> the file with properties is parsed again and everything happens according to circle. - */ -@SpringBootTest(classes = {TarantoolPropertiesTest.Config.class}) -@TestPropertySource(properties = {Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -@Timeout(5) -public class TarantoolPropertiesTest { - - private static TarantoolProperties writtenToFileProperties; - private static TarantoolProperties prevSpringParsedProperties; - private static TarantoolProperties prevWrittenToFileProperties; - @Autowired private TarantoolProperties springParsedProperties; - - @MockitoBean private TarantoolCrudClient client; - - @BeforeAll - static void beforeAll() throws IOException { - writtenToFileProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists( - TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR.resolve( - Constants.DEFAULT_PROPERTY_FILE_NAME)); - } - - /** - * The annotation allows you to tell Spring that the context is dirty and needs to be reloaded - * after the test. - */ - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testParseProperty() throws IOException { - assertNotEquals(prevWrittenToFileProperties, writtenToFileProperties); - assertNotEquals(prevSpringParsedProperties, springParsedProperties); - assertEquals(writtenToFileProperties, springParsedProperties); - - prevWrittenToFileProperties = writtenToFileProperties; - prevSpringParsedProperties = springParsedProperties; - - // Write the Properties class that will be parsed by Spring in the next iteration. - writtenToFileProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/core/annotation/IdClassResolverTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/core/annotation/IdClassResolverTest.java deleted file mode 100644 index dbb3ef18..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/core/annotation/IdClassResolverTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.core.annotation; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import io.tarantool.spring.data35.utils.entity.ComplexPerson; -import io.tarantool.spring.data35.utils.entity.CompositePersonKey; -import io.tarantool.spring.data35.utils.entity.EntityWithAnnotationAsIdClass; -import io.tarantool.spring.data35.utils.entity.Person; - -@Timeout(5) -class IdClassResolverTest { - - public static final DefaultIdClassResolver ID_CLASS_RESOLVER = DefaultIdClassResolver.INSTANCE; - - @Test - void testResolveIdClassTypeWithNullEntity() { - - final IllegalArgumentException throwable = - assertThrows( - IllegalArgumentException.class, () -> ID_CLASS_RESOLVER.resolveIdClassType(null)); - final String EXCEPTION_MESSAGE = "Type for IdClass must be not null!"; - assertEquals(EXCEPTION_MESSAGE, throwable.getMessage()); - } - - @Test - void testResolveIdClassTypeWithEntityWithoutAnnotation() { - assertNull(ID_CLASS_RESOLVER.resolveIdClassType(Person.class)); - } - - @Test - void testResolveIdClassTypeWithEntityWithAnnotation() { - assertEquals( - ID_CLASS_RESOLVER.resolveIdClassType(ComplexPerson.class), CompositePersonKey.class); - } - - @Test - void testResolveIdClassTypeWithCrossAnnotation() { - final IllegalArgumentException throwable = - assertThrows( - IllegalArgumentException.class, - () -> ID_CLASS_RESOLVER.resolveIdClassType(EntityWithAnnotationAsIdClass.class)); - - assertEquals(DefaultIdClassResolver.ANNOTATION_TYPE_EXCEPTION, throwable.getMessage()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/core/mapping/KeyValueCompositePropertyTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/core/mapping/KeyValueCompositePropertyTest.java deleted file mode 100644 index c03aa802..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/core/mapping/KeyValueCompositePropertyTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.core.mapping; - -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.ReflectionUtils; - -public class KeyValueCompositePropertyTest

> { - - private @Nullable Identifier

identifier; - - @BeforeEach - public void setUp() { - this.identifier = null; - } - - /** Check methods for adding and retrieving parts of a composite key. */ - @Test - public void testAddAndGetParts() { - Class entityClass = TestEntity.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - - ReflectionUtils.FieldFilter isIdFieldFiler = field -> field.isAnnotationPresent(Id.class); - ReflectionUtils.doWithFields(entityClass, field -> addPart(field, owner), isIdFieldFiler); - - assertNotNull(identifier); - List identifierFieldsFromProperties = - this.identifier.getParts().stream() - .map(PersistentProperty::getField) - .collect(Collectors.toList()); - - compareFieldCollection(identifierFieldsFromProperties, getExpectedIdFields(entityClass)); - } - - /** Check methods for adding and retrieving parts of a composite key. */ - @Test - public void testAddAndGetFields() { - Class entityClass = TestEntity.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - - ReflectionUtils.FieldFilter isIdFieldFiler = field -> field.isAnnotationPresent(Id.class); - ReflectionUtils.doWithFields(entityClass, field -> addPart(field, owner), isIdFieldFiler); - - assertNotNull(identifier); - List fieldsFromIdentifier = Arrays.asList(identifier.getFields()); - - compareFieldCollection(fieldsFromIdentifier, getExpectedIdFields(entityClass)); - } - - /** - * Check methods for adding and getting parts of a composite key for an object without - * {@code @Id}. - */ - @Test - public void testAddAndGetPartsWithEntityWithoutId() { - Class entityClass = TestEntityWithoutId.class; - - PersistentEntity owner = - new BasicKeyValuePersistentEntity<>(TypeInformation.of(TestEntity.class), null); - ReflectionUtils.doWithFields( - entityClass, field -> addPart(field, owner), field -> field.isAnnotationPresent(Id.class)); - - assertNull(identifier); - } - - static class TestEntity { - - @Id private long id; - - @Id private int secondId; - } - - static class TestEntityWithoutId { - - private long id; - - @Nullable private String name; - - private int secondId; - } - - /** Create a PersistentProperty and add to first id property. */ - @SuppressWarnings("unchecked") - private void addPart(Field field, PersistentEntity owner) { - Property property = Property.of(owner.getTypeInformation(), field); - Identifier

persistentProperty = - new KeyValueCompositeProperty<>(property, owner, SimpleTypeHolder.DEFAULT); - - if (this.identifier == null) { - this.identifier = persistentProperty; - } - this.identifier.addPart((P) persistentProperty); - } - - /** Compare fields by name and type. */ - private void compareFieldCollection(List first, List second) { - assertEquals(first.size(), second.size()); - - first.sort(Comparator.comparing(Field::getName)); - second.sort(Comparator.comparing(Field::getName)); - - for (int i = 0; i < first.size(); i++) { - assertEquals(first.get(i).getName(), second.get(i).getName()); - assertEquals(first.get(i).getType(), second.get(i).getType()); - } - } - - /** Get the expected fields marked with the {@code @Id} annotation. */ - private List getExpectedIdFields(Class entityClass) { - return Arrays.stream(entityClass.getDeclaredFields()) - .filter(field -> field.isAnnotationPresent(Id.class)) - .collect(Collectors.toList()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/core/mapping/TarantoolMappingContextTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/core/mapping/TarantoolMappingContextTest.java deleted file mode 100644 index c64fd13f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/core/mapping/TarantoolMappingContextTest.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.core.mapping; - -import java.lang.reflect.Field; -import java.util.HashSet; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; -import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data35.core.mapping.BasicKeyValueCompositePersistentEntity.KeyPartTypeChecker; -import io.tarantool.spring.data35.utils.entity.ComplexPerson; -import io.tarantool.spring.data35.utils.entity.EntityWithWrongCompositeKeyPartsCount; -import io.tarantool.spring.data35.utils.entity.EntityWithWrongFieldTypes; -import io.tarantool.spring.data35.utils.entity.Person; - -class TarantoolMappingContextTest { - - @Test - void testSetFallbackKeySpaceResolver() throws NoSuchFieldException { - final KeySpaceResolver RESOLVER = TestResolver.INSTANCE; - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - mappingContext.setKeySpaceResolver(RESOLVER); - - final Field field = TarantoolMappingContext.class.getDeclaredField("keySpaceResolver"); - ReflectionUtils.makeAccessible(field); - - final Object resolverFieldValue = ReflectionUtils.getField(field, mappingContext); - - assertEquals(RESOLVER, resolverFieldValue); - } - - @Test - void testCreatePersistentEntity() { - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - final TypeInformation informationForSimpleClass = TypeInformation.of(Person.class); - - final TypeInformation informationForIdentifierClass = - TypeInformation.of(ComplexPerson.class); - - assertInstanceOf( - KeyValueCompositePersistentEntity.class, createEntityForClass(ComplexPerson.class)); - - assertInstanceOf(KeyValuePersistentEntity.class, createEntityForClass(ComplexPerson.class)); - } - - @Test - void testCreatePersistentProperty() { - ReflectionUtils.FieldFilter idFilter = field -> field.isAnnotationPresent(Id.class); - - PersistentProperty simpleIdProperty = createProperty(Person.class, idFilter); - assertInstanceOf(KeyValuePersistentProperty.class, simpleIdProperty); - - PersistentProperty compositeIdProperty = createProperty(ComplexPerson.class, idFilter); - assertInstanceOf(KeyValueCompositeProperty.class, compositeIdProperty); - } - - @Test - void testCreateEntityWithWrongCompositeKeyPartTypes() { - Set> initialSet = - new HashSet>() { - { - add(EntityWithWrongFieldTypes.class); - } - }; - IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> initEntities(initialSet)); - - Assertions.assertEquals( - KeyPartTypeChecker.COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION, exception.getMessage()); - } - - @Test - void testCreateEntityWithWrongCompositeKeyPartCount() { - Set> initialSet = - new HashSet>() { - { - add(EntityWithWrongCompositeKeyPartsCount.class); - } - }; - IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> initEntities(initialSet)); - - assertEquals(KeyPartTypeChecker.COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION, exception.getMessage()); - } - - /** - * Create a mappingContext from the passed domain classes. After initialize - create for them - * PersistentEntities and add PersistentProperties to them. - * - * @param entitySet - * @return - */ - private MappingContext initEntities(Set> entitySet) { - TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - mappingContext.setInitialEntitySet(entitySet); - mappingContext.initialize(); - return mappingContext; - } - - private enum TestResolver implements KeySpaceResolver { - INSTANCE; - - @Override - @Nullable - public String resolveKeySpace(Class type) { - - Assert.notNull(type, "Type for keyspace for null!"); - - Class userClass = ClassUtils.getUserClass(type); - Object keySpace = getKeySpace(userClass); - - return keySpace != null ? keySpace.toString() : null; - } - - @Nullable - private static Object getKeySpace(Class type) { - - KeySpace keyspace = AnnotatedElementUtils.findMergedAnnotation(type, KeySpace.class); - - if (keyspace != null) { - return AnnotationUtils.getValue(keyspace); - } - - return null; - } - } - - private PersistentEntity createEntityForClass(Class entityClass) { - final TarantoolMappingContext mappingContext = new TarantoolMappingContext<>(); - - final TypeInformation informationForClass = TypeInformation.of(entityClass); - return mappingContext.createPersistentEntity(informationForClass); - } - - private

> PersistentProperty createProperty( - Class classType, ReflectionUtils.FieldFilter fieldFilter) { - - final TarantoolMappingContext, P> context = - new TarantoolMappingContext<>(); - KeyValuePersistentEntity entity = - context.createPersistentEntity(TypeInformation.of(classType)); - Field field = org.springframework.data.util.ReflectionUtils.findField(classType, fieldFilter); - assertNotNull(field); - - return context.createPersistentProperty( - Property.of(entity.getTypeInformation(), field), entity, SimpleTypeHolder.DEFAULT); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java deleted file mode 100644 index 37cb64cf..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.core.mapping.model; - -import java.lang.reflect.Field; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.Test; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; -import org.springframework.util.ReflectionUtils; - -import io.tarantool.spring.data35.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data35.core.mapping.BasicKeyValueCompositePersistentEntity; -import io.tarantool.spring.data35.core.mapping.KeyValueCompositeProperty; -import io.tarantool.spring.data35.utils.entity.ComplexPerson; - -public class PersistentCompositeIdIsNewStrategyTest

> { - - /** Check the strategy creation method and check whether the domain entity is new. */ - @Test - public void testForIdOnly() { - - // Currently identical like of 'of' method (version doesn't support) - PersistentCompositeIdIsNewStrategy strategy = - PersistentCompositeIdIsNewStrategy.forIdOnly(createPersistentEntity(ComplexPerson.class)); - - // Now is stub - always is false - ComplexPerson emptyEntity = new ComplexPerson(); - assertFalse(strategy.isNew(emptyEntity)); - } - - /** Check the strategy creation method and check whether the domain entity is new. */ - @Test - public void testIsNew() { - PersistentCompositeIdIsNewStrategy strategy = - PersistentCompositeIdIsNewStrategy.of(createPersistentEntity(ComplexPerson.class)); - - // Now is stub - always is false - ComplexPerson emptyEntity = new ComplexPerson(); - assertFalse(strategy.isNew(emptyEntity)); - } - - private BasicKeyValueCompositePersistentEntity createPersistentEntity(Class entityType) { - Class compositeKeyType = DefaultIdClassResolver.INSTANCE.resolveIdClassType(entityType); - assertNotNull(compositeKeyType); - - BasicKeyValueCompositePersistentEntity persistentEntity = - new BasicKeyValueCompositePersistentEntity<>( - TypeInformation.of(entityType), null, compositeKeyType); - ReflectionUtils.doWithFields(entityType, field -> addProperty(field, persistentEntity)); - return persistentEntity; - } - - /** Add Persistent property into PersistentEntity. */ - @SuppressWarnings("unchecked") - private void addProperty(Field field, BasicKeyValueCompositePersistentEntity owner) { - Property property = Property.of(owner.getTypeInformation(), field); - P persistentProperty = - (P) new KeyValueCompositeProperty<>(property, owner, SimpleTypeHolder.DEFAULT); - owner.addPersistentProperty(persistentProperty); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/BaseIntegrationTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/BaseIntegrationTest.java deleted file mode 100644 index a023ef6a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/BaseIntegrationTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.integration; - -import java.io.IOException; -import java.nio.file.Files; -import java.time.Duration; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Timeout; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.cluster.ClusterContainer; -import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer; -import org.testcontainers.containers.cluster.vshard.VshardClusterContainer; -import org.testcontainers.containers.output.Slf4jLogConsumer; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.spring.data35.config.properties.TarantoolProperties; - -@Timeout(60) -public abstract class BaseIntegrationTest { - - protected static ClusterContainer clusterContainer; - - private static final String dockerRegistry = - System.getenv().getOrDefault("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", ""); - - @BeforeAll - protected static void beforeAll() throws IOException { - configureContainer(); - writeConfigurationFile(); - } - - private static void configureContainer() { - if (!isCartridgeAvailable()) { - VshardClusterContainer vshardClusterContainer = - new VshardClusterContainer( - "vshard_cluster/Dockerfile", - dockerRegistry + "vshard-cluster-java", - "vshard_cluster/instances.yaml", - "vshard_cluster/config.yaml", - "tarantool/tarantool"); - - if (!vshardClusterContainer.isRunning()) { - vshardClusterContainer.withPrivilegedMode(true); - vshardClusterContainer.start(); - } - clusterContainer = vshardClusterContainer; - } else { - CartridgeClusterContainer cartridgeContainer = - new CartridgeClusterContainer( - "cartridge/Dockerfile", - dockerRegistry + "cartridge", - "cartridge/instances.yml", - "cartridge/replicasets.yml", - org.testcontainers.containers.Arguments.get("tarantool/tarantool")) - .withStartupTimeout(Duration.ofMinutes(5)) - .withLogConsumer( - new Slf4jLogConsumer(LoggerFactory.getLogger(BaseIntegrationTest.class))); - - if (!cartridgeContainer.isRunning()) { - cartridgeContainer.start(); - } - clusterContainer = cartridgeContainer; - } - } - - private static void writeConfigurationFile() throws IOException { - final TarantoolProperties properties = new TarantoolProperties(); - properties.setHost(clusterContainer.getHost()); - properties.setPort(clusterContainer.getPort()); - properties.setUserName(clusterContainer.getUsername()); - properties.setPassword(clusterContainer.getPassword()); - - writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME, properties); - } - - @AfterAll - protected static void afterAll() throws IOException { - Files.deleteIfExists(DEFAULT_TEST_PROPERTY_DIR.resolve(DEFAULT_PROPERTY_FILE_NAME)); - } - - protected static String getHost() { - return clusterContainer.getHost(); - } - - protected static int getPort() { - return clusterContainer.getPort(); - } - - protected static String getUsername() { - return clusterContainer.getUsername(); - } - - protected static String getPassword() { - return clusterContainer.getPassword(); - } - - protected static boolean isCartridgeAvailable() { - return System.getenv().getOrDefault("TARANTOOL_VERSION", "").matches("2.*"); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/CrudConfigurations.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/CrudConfigurations.java deleted file mode 100644 index 5a56f7a8..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/CrudConfigurations.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.integration.crud; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.TestPropertySource; - -import static io.tarantool.client.TarantoolClient.DEFAULT_TAG; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.PERSON_SPACE; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data35.integration.BaseIntegrationTest; -import io.tarantool.spring.data35.repository.config.EnableTarantoolRepositories; - -@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -abstract class CrudConfigurations extends BaseIntegrationTest { - - @Autowired protected TarantoolCrudClient client; - - private static InstanceConnectionGroup groupFromJavaConfig; - - private static final String PACKAGE_PATH = "io.tarantool.spring.data35.utils.core"; - - @BeforeAll - protected static void beforeAll() throws IOException { - BaseIntegrationTest.beforeAll(); - groupFromJavaConfig = - InstanceConnectionGroup.builder() - .withHost(clusterContainer.getHost()) - .withPort(clusterContainer.getPort()) - .withUser(getUsername()) - .withPassword(getPassword()) - .withTag(DEFAULT_TAG) - .withSize(4) - .build(); - } - - @BeforeEach - public void truncateSpaces() { - client.space(PERSON_SPACE).truncate().join(); - client.space(COMPLEX_PERSON_SPACE).truncate().join(); - } - - @EnableTarantoolRepositories(basePackages = {PACKAGE_PATH}) - @Configuration - static class JavaConfigConfiguration { - - @Bean - TarantoolCrudClientBuilder crudClientBuilder() { - return TarantoolFactory.crud().withGroups(Collections.singletonList(groupFromJavaConfig)); - } - } - - @EnableTarantoolRepositories(basePackages = {PACKAGE_PATH}) - @Configuration - static class ViaPropertyFileConfiguration {} - - @Test - void testSimpleClient() { - TarantoolCrudSpace space = client.space(PERSON_SPACE); - - assertEquals(0, space.select().join().size()); - - List tuple = Arrays.asList(0, true, "petya"); - List insertTuple = space.insert(tuple).join().get(); - - assertEquals(tuple, insertTuple.subList(0, insertTuple.size() - 1)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/GenericRepositoryTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/GenericRepositoryTest.java deleted file mode 100644 index 3b0b3bf8..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/GenericRepositoryTest.java +++ /dev/null @@ -1,2095 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.integration.crud; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Limit; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.util.Streamable; - -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data35.query.TarantoolQueryCreator.INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.UNKNOWN_PERSON; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.generateAndInsertPersons; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.mapping.Tuple; -import io.tarantool.spring.data.query.Conditions; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data.utils.Pair; -import io.tarantool.spring.data35.query.TarantoolPageRequest; -import io.tarantool.spring.data35.query.TarantoolScrollPosition; -import io.tarantool.spring.data35.query.TarantoolWindowIterator; -import io.tarantool.spring.data35.utils.TarantoolTestSupport; -import io.tarantool.spring.data35.utils.core.ComplexPersonRepository; -import io.tarantool.spring.data35.utils.core.GenericPaginationMethods; -import io.tarantool.spring.data35.utils.core.PersonRepository; -import io.tarantool.spring.data35.utils.entity.ComplexPerson; -import io.tarantool.spring.data35.utils.entity.Person; - -abstract class GenericRepositoryTest extends CrudConfigurations { - - @Autowired protected ApplicationContext context; - - protected static BiFunction> - complexPersonGenerateAndInsertFunction = - (context, personCount) -> - generateAndInsertComplexPersons( - personCount, context.getBean(TarantoolCrudClient.class)); - - protected static BiFunction> - personGenerateAndInsertFunction = - (context, personCount) -> - generateAndInsertPersons(personCount, context.getBean(TarantoolCrudClient.class)); - - protected static Function> complexPersonGenerateFunction = - TarantoolTestSupport::generateComplexPersons; - - protected static Function> personGenerateFunction = - TarantoolTestSupport::generatePersons; - - protected static final int INDEX_ID_VALUE = 50; - - protected static final Pair PERSON_INDEX_KEY = Pair.of("pk", INDEX_ID_VALUE); - - protected static final Pair PERSON_INITIAL_INDEX_KEY = - Pair.of("pk", Collections.emptyList()); - - protected static Stream dataForTestRepositoryWithFindByIs() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByIs") - , ID> void testRepositoryWithFindByIs( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - List foundPersons = repository.findByName(person.getName()); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(1, foundPersons.size()); - assertEquals(person, foundPersons.get(0)); - } - - protected static Stream dataForTestRepositoryWithFindById() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindById") - , ID> void testRepositoryWithFindById( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - Optional foundPerson = repository.findById(person.generateFullKey()); - - assertTrue(foundPerson.isPresent()); - assertEquals(person, foundPerson.get()); - } - - protected static Stream dataForTestRepositoryWithFindAllById() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllById") - , ID> void testRepositoryWithFindAllById( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - Iterable foundPersons = - repository.findAllById( - persons.stream().map(PERSON::generateFullKey).collect(Collectors.toList())); - List foundPersonsAsList = - StreamSupport.stream(foundPersons.spliterator(), false) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(persons, foundPersonsAsList); - } - - protected static Stream dataForTestRepositoryWithCount() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithCount") - , ID> void testRepositoryWithCount( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - assertEquals(PERSONS_COUNT, context.getBean(repositoryClass).count()); - } - - protected static Stream dataForTestRepositoryWithCountBy() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithCountBy") - , ID> void testRepositoryWithCountBy( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - assertEquals(1, repository.countByName(person.getName())); - } - - protected static Stream dataForTestRepositoryWithDelete() { - return Stream.of( - Arguments.of( - personGenerateFunction, - PersonRepository.class, - PERSON_SPACE, - (BiFunction>) - (space, key) -> { - Tuple tuple = - space.get(Collections.singletonList(key), Person.class).join(); - if (tuple != null) { - return tuple.get(); - } - return null; - }), - Arguments.of( - complexPersonGenerateFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (BiFunction>) - (space, key) -> { - Tuple tuple = space.get(key, ComplexPerson.class).join(); - if (tuple != null) { - return tuple.get(); - } - return null; - })); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithDelete") - , ID> void testRepositoryWithDelete( - Function> generateFunction, - Class> repositoryClass, - String spaceName, - BiFunction spaceGetFunction) { - - final List persons = generateFunction.apply(PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - space.insertMany(persons).join(); - - final PERSON deletingPerson = persons.get(0); - - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - // by object - repository.delete(deletingPerson); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - space.insert(deletingPerson).join(); - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - // by id - repository.deleteById(deletingPerson.generateFullKey()); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - space.insert(deletingPerson).join(); - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - // by name - repository.deleteByName(deletingPerson.getName()); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - } - - protected static Stream dataForTestRepositoryWithExistId() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiConsumer) - (space, key) -> space.delete(Collections.singletonList(key)).join(), - PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - (BiConsumer) (space, key) -> space.delete(key).join(), - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithExistId") - , ID> void testRepositoryWithExistId( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - BiConsumer deleteConsumer, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final PERSON person = persons.get(0); - - assertTrue(repository.existsById(person.generateFullKey())); - deleteConsumer.accept(space, person.generateFullKey()); - assertFalse(repository.existsById(person.generateFullKey())); - } - - protected static Stream dataForTestQueryAnnotationAsCall() { - return Stream.of( - Arguments.of(PersonRepository.class), Arguments.of(ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsCall") - , ID> void testQueryAnnotationAsCall( - Class> repositoryClass) { - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - assertEquals(Arrays.asList(1, "hi", false), repository.getStatic().get()); - } - - protected static Stream dataForTestQueryAnnotationAsCallWithArgs() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsCallWithArgs") - , ID> void testQueryAnnotationAsCallWithArgs( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals(Arrays.asList("hello", true, 13), repository.echo("hello", true, 13).get()); - } - - protected static Stream dataForTestQueryAnnotationAsEval() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsEval") - , ID> void testQueryAnnotationAsEval( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals(Arrays.asList("hello", 123, true), repository.evalGetStatic().get()); - } - - protected static Stream dataForTestQueryAnnotationAsEvalWithArgs() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsEvalWithArgs") - , ID> void testQueryAnnotationAsEvalWithArgs( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals( - Arrays.asList("hello", true, 13), repository.evalWithArgs("hello", true, 13).get()); - } - - protected static Stream dataForTestRepositoryWithExistName() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiConsumer) - (space, key) -> space.delete(Collections.singletonList(key)).join(), - PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - (BiConsumer) (space, key) -> space.delete(key).join(), - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithExistName") - , ID> void testRepositoryWithExistName( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - BiConsumer deleteConsumer, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final PERSON person = persons.get(0); - - assertTrue(repository.existsByName(person.getName())); - deleteConsumer.accept(space, person.generateFullKey()); - assertFalse(repository.existsByName(person.getName())); - } - - protected static Stream dataForTestRepositoryWithFindByLessThan() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByLessThan") - , ID> void testRepositoryWithFindByLessThan( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 10; - final List foundPersons = repository.findAllByIdIsLessThan(findLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(findLimiter, foundPersons.size()); - assertEquals(persons.subList(0, findLimiter), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsTrue() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsTrue") - , ID> void testRepositoryWithFindAllByIsMarriedIsTrue( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsTrue(); - assertEquals(PERSONS_COUNT / 3, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(GenericPerson::getIsMarried)); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsFalse() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsFalse") - , ID> void testRepositoryWithFindAllByIsMarriedIsFalse( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsFalse(); - assertEquals(PERSONS_COUNT / 3, foundPersons.size()); - assertTrue(foundPersons.stream().noneMatch(GenericPerson::getIsMarried)); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsNull() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsNull") - , ID> void testRepositoryWithFindAllByIsMarriedIsNull( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsNull(); - assertEquals(PERSONS_COUNT / 3 + 1, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(p -> p.getIsMarried() == null)); - } - - protected static Stream dataForTestRepositoryWithFindAllByNameIsEmpty() { - return Stream.of( - Arguments.of(personGenerateFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByNameIsEmpty") - , ID> void testRepositoryWithFindAllByNameIsEmpty( - Function> generateFunction, - Class> repositoryClass) { - - List persons = generateFunction.apply(PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - PERSON person = persons.get(0); - person.setName(""); - persons.set(0, person); - - repository.saveAll(persons); - - final List foundPersons = repository.findAllByNameIsEmpty(); - assertEquals(1, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(p -> p.getName().isEmpty())); - } - - protected static Stream dataForTestRepositoryWithFindByLessThanEqual() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByLessThanEqual") - , ID> void testRepositoryWithFindByLessThanEqual( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 10; - final List foundPersonsWithEqual = repository.findAllByIdLessThanEqual(findLimiter); - - foundPersonsWithEqual.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(findLimiter + 1, foundPersonsWithEqual.size()); - assertEquals(persons.subList(0, findLimiter + 1), foundPersonsWithEqual); - } - - protected static Stream dataForTestRepositoryWithFindByGreaterThan() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByGreaterThan") - , ID> void testRepositoryWithFindByGreaterThan( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 90; - final List foundPersons = repository.findAllByIdIsGreaterThan(findLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(PERSONS_COUNT - findLimiter - 1, foundPersons.size()); - assertEquals(persons.subList(findLimiter + 1, PERSONS_COUNT), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindByGreaterThanEqual() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByGreaterThanEqual") - , ID> void testRepositoryWithFindByGreaterThanEqual( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 90; - final List foundPersonsWithEqual = repository.findAllByIdGreaterThanEqual(findLimiter); - - foundPersonsWithEqual.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(PERSONS_COUNT - findLimiter, foundPersonsWithEqual.size()); - assertEquals(persons.subList(findLimiter, PERSONS_COUNT), foundPersonsWithEqual); - } - - protected static Stream dataForTestRepositoryWithFindByBetween() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByBetween") - , ID> void testRepositoryWithFindByBetween( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int startFindLimiter = 50; - final int endFindLimiter = 90; - final List foundPersons = - repository.findAllByIdBetween(startFindLimiter, endFindLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - final int foundPersonsCount = endFindLimiter - startFindLimiter - 1; - assertEquals(foundPersonsCount, foundPersons.size()); - assertEquals(persons.subList(startFindLimiter + 1, endFindLimiter), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindByBetweenNegativeInts() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByBetweenNegativeInts") - , ID> void testRepositoryWithFindByBetweenNegativeInts( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int startFindLimiter = -1; - final int endFindLimiter = -10; - final List foundPersons = - repository.findAllByIdBetween(startFindLimiter, endFindLimiter); - assertTrue(foundPersons.isEmpty()); - } - - protected static Stream dataForTestRepositoryIgnoreCase() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryIgnoreCase") - , ID> void testRepositoryIgnoreCase( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - final String name = persons.get(0).getName(); - - final InvalidDataAccessApiUsageException exception = - assertThrows( - InvalidDataAccessApiUsageException.class, () -> repository.findByNameIgnoreCase(name)); - final String EXCEPTION_MESSAGE = - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "IgnoreCase isn't supported yet", - Part.Type.SIMPLE_PROPERTY); - assertEquals(EXCEPTION_MESSAGE, exception.getMessage()); - } - - protected static Stream dataForTestRepositoryWithTarantoolNamingNotation() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithTarantoolNamingNotation") - , ID> void testRepositoryWithTarantoolNamingNotation( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List marriedPersons = repository.findByIsMarried(true); - final List nonMarriedPersons = repository.findByIsMarried(false); - final int expectedCount = PERSONS_COUNT / 3; - assertEquals(expectedCount, marriedPersons.size()); - assertEquals(expectedCount, nonMarriedPersons.size()); - } - - protected static Stream dataForTestRepositoryNotEnoughArguments() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryNotEnoughArguments") - , ID> void testRepositoryNotEnoughArguments( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertThrows(InvalidDataAccessApiUsageException.class, repository::findById); - } - - protected static Stream dataForTestRepositorySave() { - return dataForTestRepositoryWithDelete(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySave") - , ID> void testRepositorySave( - Function> generateFunction, - Class> repositoryClass, - String spaceName, - BiFunction getFunction) { - - List persons = generateFunction.apply(PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - TarantoolCrudSpace space = client.space(spaceName); - final PERSON person = persons.get(0); - - repository.save(person); - - PERSON gotPerson = getFunction.apply(space, person.generateFullKey()); - assertEquals(person, gotPerson); - } - - protected static Stream dataForTestRepositorySaveAll() { - Conditions conditions = new Conditions(); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - PERSON_SPACE, - (Function>) - (space) -> unwrapTuples(space.select(conditions, Person.class).join())), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (Function>) - (space) -> unwrapTuples(space.select(conditions, ComplexPerson.class).join()))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySaveAll") - , ID> void testRepositorySaveAll( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - Function> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - repository.saveAll(persons); - - List selectedPersons = selectFunction.apply(space); - selectedPersons.sort(Comparator.comparing(GenericPerson::getId)); - - assertEquals(persons, selectedPersons); - } - - protected static Stream dataForTestDeleteAll() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class, PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteAll") - , ID> void testDeleteAll( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow(() -> repository.deleteAll()); - assertEquals(0, space.count(new Conditions()).join()); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow(() -> repository.deleteAll(persons)); - assertEquals(0, space.count(new Conditions()).join()); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow( - () -> - repository.deleteAllById( - persons.stream().map(PERSON::generateFullKey).collect(Collectors.toList()))); - assertEquals(0, space.count(new Conditions()).join()); - } - - protected static Stream dataForTestRepositoryFindByAfter() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByAfter") - , ID> void testRepositoryFindByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - final List selectedPersons = repository.findByNameAfter(person.getName()); - selectedPersons.sort(Comparator.comparing(PERSON::getName)); - - final List expectedList = - persons.stream() - .filter(p -> p.getName().compareTo(person.getName()) > 0) - .limit(SelectOptions.DEFAULT_LIMIT) - .sorted(Comparator.comparing(PERSON::getName)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - } - - protected static Stream dataForTestRepositoryFindByAfterWithLimit() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByAfterWithLimit") - , ID> void testRepositoryFindByAfterWithLimit( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int LIMIT = 5; - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findFirst5ByIdAfter(person.getId()); - selectedPersons.sort(Comparator.comparing(PERSON::getId)); - - final List selectedPersonsWithTopKeyword = repository.findTop5ByIdAfter(person.getId()); - selectedPersonsWithTopKeyword.sort(Comparator.comparing(PERSON::getId)); - - final List expectedList = - persons.stream() - .filter(p -> p.getId().compareTo(person.getId()) > 0) - .limit(LIMIT) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - - assertEquals(expectedList.size(), selectedPersonsWithTopKeyword.size()); - assertEquals(expectedList, selectedPersonsWithTopKeyword); - } - - protected static Stream dataForTestRepositoryFindByBefore() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByBefore") - , ID> void testRepositoryFindByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findByNameBefore(person.getName()); - selectedPersons.sort(Comparator.comparing(PERSON::getName)); - - final List expectedList = - persons.stream() - .filter(p -> p.getName().compareTo(person.getName()) < 0) - .limit(SelectOptions.DEFAULT_LIMIT) - .sorted(Comparator.comparing(PERSON::getName)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - } - - protected static Stream dataForTestRepositoryFindByBeforeWithLimit() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByBeforeWithLimit") - , ID> void testRepositoryFindByBeforeWithLimit( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int LIMIT = 5; - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findFirst5ByIdBefore(person.getId()); - selectedPersons.sort(Comparator.comparing(PERSON::getId)); - - final List selectedPersonsWithTopKeyword = - repository.findTop5ByIdBefore(person.getId()); - selectedPersonsWithTopKeyword.sort(Comparator.comparing(PERSON::getId)); - - // Because id (not fullscan) - persons.sort(Comparator.comparing(PERSON::getId, (o1, o2) -> Integer.compare(o2, o1))); - - final List expectedList = - persons.stream() - .filter(p -> p.getId().compareTo(person.getId()) < 0) - .limit(LIMIT) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - - assertEquals(expectedList.size(), selectedPersonsWithTopKeyword.size()); - assertEquals(expectedList, selectedPersonsWithTopKeyword); - } - - protected static Stream dataForTestDeleteByAfter() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - PERSON_SPACE, - (BiFunction>) - (space, options) -> - unwrapTuples( - space.select(Collections.emptyList(), options, Person.class).join())), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (BiFunction>) - (space, options) -> - unwrapTuples( - space - .select(Collections.emptyList(), options, ComplexPerson.class) - .join()))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteByAfter") - , ID> void testDeleteByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - BiFunction> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - persons.sort(Comparator.comparing(PERSON::getName)); - - final int RANDOM_INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final SelectOptions options = SelectOptions.builder().withFirst(PERSONS_COUNT).build(); - final PERSON deletingAfterPerson = persons.get(RANDOM_INDEX); - - final List deletedPersons = repository.deleteByNameAfter(deletingAfterPerson.getName()); - - List allPersonsInBaseAfterDeleted = selectFunction.apply(space, options); - assertEquals(PERSONS_COUNT - deletedPersons.size(), allPersonsInBaseAfterDeleted.size()); - - persons.removeAll(deletedPersons); - allPersonsInBaseAfterDeleted.sort(Comparator.comparing(PERSON::getId)); - persons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(persons, allPersonsInBaseAfterDeleted); - } - - protected static Stream dataForTestDeleteByBefore() { - return dataForTestDeleteByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteByBefore") - , ID> void testDeleteByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - BiFunction> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final SelectOptions options = SelectOptions.builder().withFirst(PERSONS_COUNT).build(); - final int RANDOM_INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - - final PERSON deletingBeforePerson = persons.get(RANDOM_INDEX); - final List deletedPersons = - repository.deleteByNameBefore(deletingBeforePerson.getName()); - - List allPersonsInBaseAfterDeleted = selectFunction.apply(space, options); - - assertEquals(PERSONS_COUNT - deletedPersons.size(), allPersonsInBaseAfterDeleted.size()); - - persons.removeAll(deletedPersons); - allPersonsInBaseAfterDeleted.sort(Comparator.comparing(PERSON::getId)); - persons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(persons, allPersonsInBaseAfterDeleted); - } - - protected static Stream dataForTestCountByAfter() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestCountByAfter") - , ID> void testCountByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final int ID_AFTER = persons.get(INDEX).getId(); - - final long count = repository.countByIdAfter(ID_AFTER); - - final int EXPECTED_COUNT = PERSONS_COUNT - ID_AFTER - 1; - assertEquals(EXPECTED_COUNT, count); - } - - protected static Stream dataForTestCountByBefore() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestCountByBefore") - , ID> void testCountByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - persons.sort(Comparator.comparing(PERSON::getName)); - - final int indexBefore = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final String name = persons.get(indexBefore).getName(); - final long count = repository.countByNameBefore(name); - - assertEquals(indexBefore, count); - - final long unknownNameCount = repository.countByNameBefore(UNKNOWN_PERSON.getName()); - assertEquals(0, unknownNameCount); - } - - protected static < - REPO extends GenericPaginationMethods, PERSON extends GenericPerson, ID> - Stream dataForTestRepositorySlicePagePageableEqual() { - final int PAGE_SIZE = ThreadLocalRandom.current().nextInt(1, PERSONS_COUNT / 3 - 1); - final String NAME = "name"; - final Pageable beginPageable = new TarantoolPageRequest>(PAGE_SIZE); - - BiFunction> generatePersonAndInsertFunction = - (context, size) -> - generateAndInsertPersons( - size, context.getBean(TarantoolCrudClient.class), (person) -> person.setName(NAME)); - - BiFunction> - generateComplexPersonAndInsertFunction = - (context, size) -> - generateAndInsertComplexPersons( - size, - context.getBean(TarantoolCrudClient.class), - (person) -> person.setName(NAME)); - - Function personRepositoryFunc = - (context) -> context.getBean(PersonRepository.class); - - Function complexPersonRepositoryFunc = - (context) -> context.getBean(ComplexPersonRepository.class); - - BiFunction> executionForFindAllByName = - (repo, pageable) -> repo.findAllByName(NAME, pageable); - - Function, List> expectedListForFindAllByNameFunc = - (persons) -> - persons.stream() - .filter(person -> NAME.equals(person.getName())) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()) - .subList(0, PAGE_SIZE); - - BiFunction> executionForFindByName = - (repo, pageable) -> repo.findPersonByName(NAME, pageable); - - List> generateFunctionPairs = - Arrays.asList( - Arrays.asList(generatePersonAndInsertFunction, personRepositoryFunc), - Arrays.asList(generateComplexPersonAndInsertFunction, complexPersonRepositoryFunc)); - - List executionFunctions = Arrays.asList(executionForFindAllByName, executionForFindByName); - - // add arguments set - List arguments = new ArrayList<>(); - for (List generateFunctionPair : generateFunctionPairs) { - for (Object executionFunction : executionFunctions) { - arguments.add( - Arguments.of( - generateFunctionPair.get(0), - executionFunction, - generateFunctionPair.get(1), - expectedListForFindAllByNameFunc, - beginPageable)); - } - } - - return arguments.stream(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySlicePagePageableEqual") - , PERSON extends GenericPerson, ID> - void testRepositorySlicePagePageableEqual( - BiFunction> generateAndInsertFunction, - BiFunction> executingRepositoryMethod, - Function giveRepositoryFunction, - Function, List> expectedSlicePageContent, - Pageable beginPageable) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - Slice slicePage = - executingRepositoryMethod.apply(giveRepositoryFunction.apply(context), beginPageable); - - assertEquals(beginPageable, slicePage.getPageable()); - assertEquals(expectedSlicePageContent.apply(persons), slicePage.getContent()); - } - - protected static Stream dataForTestRepositorySliceMethodWithoutPageable() { - final String NAME = "name"; - return Stream.of( - Arguments.of(PersonRepository.class, NAME), - Arguments.of(ComplexPersonRepository.class, NAME)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySliceMethodWithoutPageable") - , ID> void testRepositorySliceMethodWithoutPageable( - Class> repositoryClass, String name) { - GenericPaginationMethods repository = context.getBean(repositoryClass); - - assertEquals(Pageable.unpaged(), repository.findAllByName(name).getPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).nextPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).nextOrLastPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).previousPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).previousOrFirstPageable()); - } - - @SuppressWarnings("unchecked") - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Stream dataForTestRepositorySliceWithDifferentFields() { - final int PAGE_SIZE = 10; - - Function, Pageable> nextPageableFunc = Slice::nextPageable; - Function, Pageable> prevPageableFunc = Slice::previousPageable; - Function, Pageable> nextOrLastPageableFunc = Slice::nextOrLastPageable; - Function, Pageable> prevOrFirstPageableFunc = Slice::previousOrFirstPageable; - BiFunction predicateForNextPageableFunc = - (currentPageable, nextPageable) -> nextPageable.isPaged(); - - BiFunction predicateForNextOrPageableFunc = - (currentPageable, nextPageable) -> !currentPageable.equals(nextPageable); - - Function personRepositoryFunc = - (context) -> context.getBean(PersonRepository.class); - - Function complexPersonRepositoryFunc = - (context) -> context.getBean(ComplexPersonRepository.class); - - Pageable beginPageable = new TarantoolPageRequest<>(PAGE_SIZE); - - BiFunction, Integer, Integer> idExtractionFunction = - (args, index) -> { - List persons = (List) args.get(0); - return persons.get(index).getId(); - }; - - BiFunction, Integer, String> nameExtractionFunction = - (args, index) -> { - List persons = (List) args.get(0); - return persons.get(index).getName(); - }; - - BiFunction, Slice> executionForFindAllByIdLessThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, PERSONS_COUNT - 1); - return repo.findAllByIdLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByIdLessThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, PERSONS_COUNT - 1); - return repo.findPersonByIdLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByIdGreaterThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, 0); - return repo.findAllByIdGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByIdGreaterThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, 0); - return repo.findPersonByIdGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByIsMarriedLessThanEqual = - (repo, arguments) -> - repo.findAllByIsMarriedLessThanEqual(false, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindPersonByIsMarriedLessThanEqual = - (repo, arguments) -> - repo.findPersonByIsMarriedLessThanEqual(false, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindAllByIsMarriedGreaterThanEqual = - (repo, arguments) -> - repo.findAllByIsMarriedGreaterThanEqual(null, (Pageable) arguments.get(1)); - - BiFunction, Slice> - executionForFindPersonByIsMarriedGreaterThanEqual = - (repo, arguments) -> - repo.findPersonByIsMarriedGreaterThanEqual(null, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindAllByNameLessThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findAllByNameLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByNameLessThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findPersonByNameLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByNameGreaterThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findAllByNameGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByNameGreaterThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findPersonByNameGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAll = - (repo, arguments) -> repo.findAll((Pageable) arguments.get(1)); - - Function, List> expectedListForFindAllByIdLessThanEqualFunc = - (persons) -> - persons.stream() - .sorted(Comparator.comparing(PERSON::getId).reversed()) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByIdGreaterThanEqualFunc = - (persons) -> persons; - - Function, List> expectedListForFindAllByIsMarriedGreaterThanEqual = - (persons) -> - persons.stream() - .sorted( - Comparator.comparing( - PERSON::getIsMarried, Comparator.nullsFirst(Comparator.naturalOrder()))) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByIsMarriedLessThanEqual = - (persons) -> - persons.stream() - .filter(person -> person.getIsMarried() == null || !person.getIsMarried()) - .sorted( - Comparator.comparing( - PERSON::getIsMarried, Comparator.nullsLast(Comparator.naturalOrder())) - .thenComparing(Comparator.comparing(PERSON::getId).reversed())) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByNameLessThanEqual = - (persons) -> { - String name = persons.get(persons.size() / 2).getName(); - return persons.stream() - .filter(person -> person.getName().compareTo(name) <= 0) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - }; - - Function, List> expectedListForFindAllByNameGreaterThanEqual = - (persons) -> { - String name = persons.get(persons.size() / 2).getName(); - return persons.stream() - .filter(person -> person.getName().compareTo(name) >= 0) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - }; - - Function, List> expectedListForFindAll = (persons) -> persons; - - List> getNextPageableMethodFunctionPairs = - Arrays.asList( - Arrays.asList(nextPageableFunc, prevPageableFunc, predicateForNextPageableFunc), - Arrays.asList( - nextOrLastPageableFunc, prevOrFirstPageableFunc, predicateForNextOrPageableFunc)); - - List> generateFunctions = - Arrays.asList( - Arrays.asList(personGenerateAndInsertFunction, personRepositoryFunc), - Arrays.asList(complexPersonGenerateAndInsertFunction, complexPersonRepositoryFunc)); - - List> executeExpectedFunctionPairs = - Arrays.asList( - Arrays.asList( - executionForFindAllByIdLessThanEqualFunc, - expectedListForFindAllByIdLessThanEqualFunc), - Arrays.asList( - executionForFindAllByIdGreaterThanEqualFunc, - expectedListForFindAllByIdGreaterThanEqualFunc), - Arrays.asList( - executionForFindAllByIsMarriedGreaterThanEqual, - expectedListForFindAllByIsMarriedGreaterThanEqual), - Arrays.asList( - executionForFindAllByIsMarriedLessThanEqual, - expectedListForFindAllByIsMarriedLessThanEqual), - Arrays.asList( - executionForFindAllByNameLessThanEqual, expectedListForFindAllByNameLessThanEqual), - Arrays.asList( - executionForFindAllByNameGreaterThanEqual, - expectedListForFindAllByNameGreaterThanEqual), - Arrays.asList( - executionForFindPersonByIdLessThanEqualFunc, - expectedListForFindAllByIdLessThanEqualFunc), - Arrays.asList( - executionForFindPersonByIdGreaterThanEqualFunc, - expectedListForFindAllByIdGreaterThanEqualFunc), - Arrays.asList( - executionForFindPersonByIsMarriedGreaterThanEqual, - expectedListForFindAllByIsMarriedGreaterThanEqual), - Arrays.asList( - executionForFindPersonByIsMarriedLessThanEqual, - expectedListForFindAllByIsMarriedLessThanEqual), - Arrays.asList( - executionForFindPersonByNameLessThanEqual, - expectedListForFindAllByNameLessThanEqual), - Arrays.asList( - executionForFindPersonByNameGreaterThanEqual, - expectedListForFindAllByNameGreaterThanEqual), - Arrays.asList(executionForFindAll, expectedListForFindAll)); - - // add arguments set - List arguments = new ArrayList<>(); - for (List generateFunctionPair : generateFunctions) { - for (List getNextPrevPageableFuncTriple : getNextPageableMethodFunctionPairs) { - for (List executeExpectedFunctionPair : executeExpectedFunctionPairs) { - arguments.add( - Arguments.of( - generateFunctionPair.get(0), - generateFunctionPair.get(1), - executeExpectedFunctionPair.get(0), - getNextPrevPageableFuncTriple.get(0), - getNextPrevPageableFuncTriple.get(1), - getNextPrevPageableFuncTriple.get(2), - executeExpectedFunctionPair.get(1), - beginPageable)); - } - } - } - return arguments.stream(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySliceWithDifferentFields") - , ID> void testRepositorySliceWithDifferentFields( - BiFunction> generateAndInsertFunction, - Function> giveRepositoryFunction, - BiFunction, List, Slice> - executingRepositoryMethod, - Function, Pageable> nextPageableMethod, - Function, Pageable> prevPageableMethod, - BiFunction stopPaginationPredicateFunction, - Function, List> expectedResultListMovingFunction, - Pageable beginPageable) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - - // moving forward - Pageable nextPageable = beginPageable; - List> forwardSlices = new ArrayList<>(); - Slice slice; - do { - slice = - executingRepositoryMethod.apply( - giveRepositoryFunction.apply(context), Arrays.asList(persons, nextPageable)); - forwardSlices.add(slice); - nextPageable = nextPageableMethod.apply(slice); - } while (stopPaginationPredicateFunction.apply(slice.getPageable(), nextPageable)); - - List forwardMovingResultList = - forwardSlices.stream().flatMap(Streamable::stream).collect(Collectors.toList()); - assertEquals(expectedResultListMovingFunction.apply(persons), forwardMovingResultList); - - // moving backward - List> reverseSlices = new ArrayList<>(); - nextPageable = forwardSlices.get(forwardSlices.size() - 1).getPageable(); - do { - slice = - executingRepositoryMethod.apply( - giveRepositoryFunction.apply(context), Arrays.asList(persons, nextPageable)); - reverseSlices.add(slice); - nextPageable = prevPageableMethod.apply(slice); - } while (stopPaginationPredicateFunction.apply(slice.getPageable(), nextPageable)); - - List backwardMovingResultList = - reverseSlices.stream() - .sorted(Comparator.comparing(Slice::getNumber)) - .flatMap(Streamable::stream) - .collect(Collectors.toList()); - - assertEquals(expectedResultListMovingFunction.apply(persons), backwardMovingResultList); - } - - protected static , ID> - List expectedForwardFuncForFindFirst5ByIsMarriedInitial(List persons) { - return persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst5ByIsMarriedInitial(List persons) { - List result = - new ArrayList<>(expectedForwardFuncForFindFirst5ByIsMarriedInitial(persons)); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial( - List persons) { - return persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial( - List persons) { - List result = - new ArrayList<>( - expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial(persons)); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst5ByIsMarriedIndexKey(List persons) { - return persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst5ByIsMarriedIndexKey(List persons) { - List result = - new ArrayList<>( - persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .sorted(Comparator.comparing(PERSON::getId)) - .toList()); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey( - List persons) { - return persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey( - List persons) { - List result = - new ArrayList<>( - persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .sorted(Comparator.comparing(PERSON::getId)) - .toList()); - Collections.reverse(result); - return result; - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Window executionFunctionForFindFirst5ByIsMarried(REPO repository, List args) { - ScrollPosition scrollPosition = (ScrollPosition) args.get(0); - return repository.findFirst5ByIsMarried(false, scrollPosition); - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Window executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual( - REPO repository, List args) { - ScrollPosition scrollPosition = (ScrollPosition) args.get(0); - return repository.findFirst10ByIsMarriedGreaterThanEqual(false, scrollPosition); - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Stream dataForTestRepositoryScrollForwardAndBackwardMoving() { - - ScrollPosition beginScrollPositionInitial = - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY); - ScrollPosition beginScrollPositionIndexKey = TarantoolScrollPosition.forward(PERSON_INDEX_KEY); - - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst5ByIsMarried, - (Function, List>) - GenericRepositoryTest::expectedForwardFuncForFindFirst5ByIsMarriedInitial, - (Function, List>) - GenericRepositoryTest::expectedBackwardFuncForFindFirst5ByIsMarriedInitial, - beginScrollPositionInitial), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst5ByIsMarried, - (Function, List>) - GenericRepositoryTest::expectedForwardFuncForFindFirst5ByIsMarriedIndexKey, - (Function, List>) - GenericRepositoryTest::expectedBackwardFuncForFindFirst5ByIsMarriedIndexKey, - beginScrollPositionIndexKey), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual, - (Function, List>) - GenericRepositoryTest - ::expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial, - (Function, List>) - GenericRepositoryTest - ::expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial, - beginScrollPositionInitial), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual, - (Function, List>) - GenericRepositoryTest - ::expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey, - (Function, List>) - GenericRepositoryTest - ::expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey, - beginScrollPositionIndexKey)); - } - - @ParameterizedTest - @MethodSource("dataForTestRepositoryScrollForwardAndBackwardMoving") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryScrollForwardAndBackwardMoving( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - BiFunction, Window> executingRepositoryMethod, - Function, List> expectedForwardResultFunction, - Function, List> expectedBackwardResultFunction, - ScrollPosition beginScrollPosition) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - Window personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(beginScrollPosition)); - List forwardResult = new ArrayList<>(); - - while (!personWindow.isEmpty() && personWindow.hasNext()) { - personWindow.forEach(forwardResult::add); - ScrollPosition nextPosition = personWindow.positionAt(personWindow.size() - 1); - personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(nextPosition)); - } - personWindow.forEach(forwardResult::add); - - assertEquals(expectedForwardResultFunction.apply(persons), forwardResult); - - TarantoolScrollPosition backwardScrollPosition = - ((TarantoolScrollPosition) personWindow.positionAt(0)).reverse(); - List backwardResult = personWindow.getContent(); - Collections.reverse(backwardResult); - - personWindow = - executingRepositoryMethod.apply( - repository, Collections.singletonList(backwardScrollPosition)); - while (!personWindow.isEmpty() && personWindow.hasNext()) { - personWindow.forEach(backwardResult::add); - ScrollPosition nextPosition = personWindow.positionAt(personWindow.size() - 1); - personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(nextPosition)); - } - personWindow.forEach(backwardResult::add); - - assertEquals(expectedBackwardResultFunction.apply(persons), backwardResult); - } - - protected static > - Stream dataForTestWindowIterator() { - return Stream.of( - Arguments.of( - (BiFunction>) - (context, size) -> Collections.emptyList(), - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY), - (Function, List>) (persons) -> Collections.emptyList(), - (Function, List>) (persons) -> Collections.emptyList()), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY), - (Function, List>) (persons) -> persons, - (Function, List>) - (persons) -> { - Collections.reverse(persons); - return persons; - }), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INDEX_KEY), - (Function, List>) - GenericRepositoryTest::expectedWindowIteratorForwardFromSomeCursor, - (Function, List>) - GenericRepositoryTest::expectedWindowIteratorBackwardFromSomeCursor)); - } - - protected static , ID> - List expectedWindowIteratorForwardFromSomeCursor(List persons) { - return persons.stream() - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .collect(Collectors.toList()); - } - - protected static , ID> - List expectedWindowIteratorBackwardFromSomeCursor(List persons) { - return persons.stream() - .filter(person -> person.getId() <= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId).reversed()) - .collect(Collectors.toList()); - } - - @ParameterizedTest - @MethodSource("dataForTestWindowIterator") - , ID, REPO extends GenericPaginationMethods> - void testWithWindowIteratorMoving( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - TarantoolScrollPosition beginScrollPosition, - Function, List> expectedForwardResultFunction, - Function, List> expectedBackwardResultFunction) { - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - TarantoolWindowIterator personForwardIterator = - TarantoolWindowIterator.of( - scrollPosition -> - repository.findFirst10ByIsMarriedGreaterThanEqual(null, scrollPosition)) - .startingAt(beginScrollPosition); - - List forwardResult = new ArrayList<>(); - - while (personForwardIterator.hasNext()) { - forwardResult.add(personForwardIterator.next()); - } - - forwardResult.sort(Comparator.comparing(PERSON::getId)); - assertEquals(expectedForwardResultFunction.apply(persons), forwardResult); - - // go back - List backwardResult = new ArrayList<>(); - - TarantoolWindowIterator personBackwardIterator = - TarantoolWindowIterator.of( - scrollPosition -> - repository.findFirst10ByIsMarriedGreaterThanEqual(null, scrollPosition)) - .startingAt(beginScrollPosition.reverse()); - - while (personBackwardIterator.hasNext()) { - backwardResult.add(personBackwardIterator.next()); - } - - assertEquals(expectedBackwardResultFunction.apply(persons), backwardResult); - } - - protected static Stream dataForTestUnsupportedRepositoryMethods() { - return Stream.of(PersonRepository.class, ComplexPersonRepository.class); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestUnsupportedRepositoryMethods") - , ID, REPO extends GenericPaginationMethods> - void testUnsupportedRepositoryMethods(Class repositoryClass) { - final REPO repository = context.getBean(repositoryClass); - - assertThrows(UnsupportedOperationException.class, repository::findAll); - assertThrows(UnsupportedOperationException.class, () -> repository.findAll(Sort.unsorted())); - } - - protected static Stream dataForTestPageableWithTrueCursorAndPageNumber() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(PAGE_SIZE), - PAGES_COUNT, - PAGES_COUNT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(1, PAGE_SIZE, new Person(9, null, "User-9")), - PAGES_COUNT - 1, - PAGES_COUNT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(2, PAGE_SIZE, new Person(19, null, "User-19")), - PAGES_COUNT - 2, - PAGES_COUNT)); - } - - private static void doTestPageableWithCursorAndPageNumber( - Pageable pageable, - BiFunction> repositoryFunction, - BiConsumer>, List>> assertionAction) { - List> forwardPages = new ArrayList<>(); - - Slice page = repositoryFunction.apply(0, pageable); - - forwardPages.add(page); - - while (page.hasNext()) { - page = repositoryFunction.apply(0, page.nextOrLastPageable()); - forwardPages.add(page); - } - - List> backwardPages = new ArrayList<>(); - for (int i = forwardPages.size() - 1; i >= 0; i--) { - Slice currentPage = forwardPages.get(i); - if (currentPage.getPageable().isPaged()) { - page = currentPage; - break; - } - } - backwardPages.add(page); - - page = repositoryFunction.apply(0, page.previousOrFirstPageable()); - backwardPages.add(page); - - while (page.hasPrevious()) { - page = repositoryFunction.apply(0, page.previousOrFirstPageable()); - backwardPages.add(page); - } - - assertionAction.accept(forwardPages, backwardPages); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageableWithTrueCursorAndPageNumber") - , ID, REPO extends GenericPaginationMethods> - void testPageableWithTrueCursorAndPageNumber( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCount, - int expectedBackwardPageCount) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - backwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestPageablePageNumberLessCursor() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // fourth page - new TarantoolPageRequest<>(0, PAGE_SIZE, new Person(29, null, "User-29")), - PAGES_COUNT - 2, - PAGES_COUNT - 3, - PAGES_COUNT - 3), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // third page - new TarantoolPageRequest<>(0, PAGE_SIZE, new Person(19, null, "User-19")), - PAGES_COUNT - 1, - PAGES_COUNT - 2, - PAGES_COUNT - 2)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageablePageNumberLessCursor") - , ID, REPO extends GenericPaginationMethods> - void testPageablePageNumberLessCursor( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCountForPage, - int expectedForwardPageCountForSlice, - int expectedBackwardPageCount) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - int expectedForwardPageCount = expectedForwardPageCountForSlice; - Slice firstPageable = forwardSlice.get(0); - if (firstPageable instanceof Page) { - expectedForwardPageCount = expectedForwardPageCountForPage; - } - - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - if (firstPageable instanceof Page) { - assertTrue(forwardSlice.get(forwardSlice.size() - 1).getPageable().isUnpaged()); - forwardSlice - .subList(0, forwardSlice.size() - 1) - .forEach(p -> assertTrue(p.getPageable().isPaged())); - } else { - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - } - backwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestPageablePageNumberGreaterCursor() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // second page - new TarantoolPageRequest<>(1, PAGE_SIZE, null), - PAGES_COUNT - 1, - PAGES_COUNT, - PAGES_COUNT, - PAGES_COUNT + 1), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // fourth page - new TarantoolPageRequest<>(3, PAGE_SIZE, new Person(9, null, "User-9")), - PAGES_COUNT - 3, - PAGES_COUNT - 1, - PAGES_COUNT - 1, - PAGES_COUNT + 1)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageablePageNumberGreaterCursor") - , ID, REPO extends GenericPaginationMethods> - void testPageablePageNumberGreaterCursor( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCountForPage, - int expectedForwardPageCountForSlice, - int expectedBackwardPageCountForPage, - int expectedBackwardPageCountForSlice) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - int expectedForwardPageCount = expectedForwardPageCountForPage; - int expectedBackwardPageCount = expectedBackwardPageCountForPage; - - Slice firstPageable = forwardSlice.get(0); - if (!(firstPageable instanceof Page)) { - expectedForwardPageCount = expectedForwardPageCountForSlice; - expectedBackwardPageCount = expectedBackwardPageCountForSlice; - } - - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - assertTrue(backwardSlice.get(backwardSlice.size() - 1).getPageable().isUnpaged()); - backwardSlice - .subList(0, backwardSlice.size() - 1) - .forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestRepositoryLimit() { - final int LIMITED_SIZE = 10; - final Limit LIMITED = Limit.of(LIMITED_SIZE); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - null, - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - Limit.unlimited(), - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - personGenerateAndInsertFunction, PersonRepository.class, LIMITED, LIMITED_SIZE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - null, - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - Limit.unlimited(), - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - LIMITED, - LIMITED_SIZE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryLimit") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryLimit( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Limit limit, - int expectedLimitSize) { - generateAndInsertFunction.apply(context, PERSONS_COUNT); - - REPO repository = context.getBean(repositoryClass); - - List selectedPersons = repository.findPersonByIdGreaterThanEqual(0, limit); - assertEquals(expectedLimitSize, selectedPersons.size()); - } - - protected static Stream dataForTestRepositoryLimitShouldThrow() { - final Limit BAD_LIMIT = Limit.of(-10); - return Stream.of( - Arguments.of(PersonRepository.class, BAD_LIMIT), - Arguments.of(ComplexPersonRepository.class, BAD_LIMIT)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryLimitShouldThrow") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryLimitShouldThrow(Class repositoryClass, Limit limit) { - REPO repository = context.getBean(repositoryClass); - assertThrows( - IllegalArgumentException.class, () -> repository.findPersonByIdGreaterThanEqual(0, limit)); - } - - protected static Stream dataForTestRepositoryLimitWithLimitInMethodName() { - final int LIMIT_FROM_METHOD_NAME = 4; - final int LIMITED_SIZE = 10; - final Limit LIMITED = Limit.of(LIMITED_SIZE); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, PersonRepository.class, null, LIMIT_FROM_METHOD_NAME), - Arguments.of( - personGenerateAndInsertFunction, PersonRepository.class, LIMITED, LIMITED_SIZE), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - Limit.unlimited(), - LIMIT_FROM_METHOD_NAME), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - null, - LIMIT_FROM_METHOD_NAME), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - LIMITED, - LIMITED_SIZE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - Limit.unlimited(), - LIMIT_FROM_METHOD_NAME)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryLimitWithLimitInMethodName") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryLimitWithLimitInMethodName( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Limit limit, - int expectedLimitSize) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - List selectedPersons = repository.findTop4ByIdGreaterThanEqual(0, limit); - - assertEquals(expectedLimitSize, selectedPersons.size()); - } - - @Test - void testConcurrentDerivedMethods() { - - final byte threadCount = 3; - final ExecutorService executor = Executors.newFixedThreadPool(threadCount); - final List>> futures = new ArrayList<>(threadCount); - final PersonRepository repository = context.getBean(PersonRepository.class); - - final List insertedPersons = - personGenerateAndInsertFunction.apply(context, (int) threadCount); - final Person firstPerson = insertedPersons.get(0); - final Person secondPerson = insertedPersons.get(1); - final Person thirdPerson = insertedPersons.get(2); - - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findPersonById(firstPerson.getId()), executor)); - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findByIsMarried(secondPerson.getIsMarried()), executor)); - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findByName(thirdPerson.getName()), executor)); - - CompletableFuture.allOf(futures.toArray(new CompletableFuture[] {})).join(); - - assertEquals(firstPerson, futures.get(0).join().get(0)); - assertEquals(secondPerson, futures.get(1).join().get(0)); - assertEquals(thirdPerson, futures.get(2).join().get(0)); - } - - @Test - void testFragmentsSPI() { - final int tupleCount = 100; - final List tuples = personGenerateFunction.apply(tupleCount); - - final PersonRepository repository = context.getBean(PersonRepository.class); - - final List insertedTuples = repository.replaceMany(tuples); - assertEquals(tupleCount, insertedTuples.size()); - - tuples.sort(Comparator.comparing(Person::getName)); - insertedTuples.sort(Comparator.comparing(Person::getName)); - assertEquals(tuples, insertedTuples); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/GenericTarantoolTemplateTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/GenericTarantoolTemplateTest.java deleted file mode 100644 index f43270f6..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/GenericTarantoolTemplateTest.java +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.integration.crud; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.core.UncategorizedKeyValueException; - -import static io.tarantool.spring.data.ProxyTarantoolCrudKeyValueAdapter.POTENTIAL_PERFORMANCE_ISSUES_EXCEPTION_MESSAGE; -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.generateAndInsertPersons; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.generateComplexPersons; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.mapping.crud.CrudException; -import io.tarantool.spring.data35.core.TarantoolTemplate; -import io.tarantool.spring.data35.utils.entity.ComplexPerson; -import io.tarantool.spring.data35.utils.entity.ComplexPersonWithIncorrectPK; -import io.tarantool.spring.data35.utils.entity.ComplexPersonWithJsonFormatVariantPK; -import io.tarantool.spring.data35.utils.entity.CompositePersonKey; -import io.tarantool.spring.data35.utils.entity.CompositePersonKeyWithJsonFormat; -import io.tarantool.spring.data35.utils.entity.Person; - -abstract class GenericTarantoolTemplateTest extends CrudConfigurations { - - @Autowired protected TarantoolTemplate tarantoolTemplate; - - @Test - void testGetAllOf() { - final Throwable throwable = - assertThrows( - UncategorizedKeyValueException.class, () -> tarantoolTemplate.findAll(Person.class)) - .getCause(); - - assertEquals(UnsupportedOperationException.class, throwable.getClass()); - assertEquals(POTENTIAL_PERFORMANCE_ISSUES_EXCEPTION_MESSAGE, throwable.getMessage()); - } - - static Stream dataForInsert() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - return Stream.of( - Arguments.of( - simpleKeyPerson, - (Function) (kv) -> kv.insert(simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - compositeKeyPerson, - (Function) (kv) -> kv.insert(compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForInsert") - void testKVTemplateInsert( - Object result, - Function callingMethod, - Function> selectAction) { - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForInsertById() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - return Stream.of( - Arguments.of( - simpleKeyPerson, - (Function) (kv) -> kv.insert(simpleKey, simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - compositeKeyPerson, - (Function) - (kv) -> kv.insert(compositeKey, compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForInsertById") - void testKVTemplateInsertById( - Object result, - Function callingMethod, - Function> selectAction) { - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForUpdate() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - Consumer prepareActionForSimpleKeyPerson = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer prepareActionForCompositeKeyPerson = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - return Stream.of( - Arguments.of( - prepareActionForSimpleKeyPerson, - simpleKeyPerson, - (Function) (kv) -> kv.update(simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - prepareActionForCompositeKeyPerson, - compositeKeyPerson, - (Function) (kv) -> kv.update(compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForUpdate") - void testKVTemplateUpdate( - Consumer prepareAction, - Object result, - Function callingMethod, - Function> selectAction) { - prepareAction.accept(client); - - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForUpdateById() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - Consumer prepareActionForSimpleKeyPerson = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer prepareActionForCompositeKeyPerson = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - return Stream.of( - Arguments.of( - prepareActionForSimpleKeyPerson, - simpleKeyPerson, - (Function) (kv) -> kv.update(simpleKey, simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - prepareActionForCompositeKeyPerson, - compositeKeyPerson, - (Function) - (kv) -> kv.update(compositeKey, compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForUpdateById") - void testKVTemplateUpdateById( - Consumer prepareAction, - Object result, - Function callingMethod, - Function> selectAction) { - prepareAction.accept(client); - - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForDelete() { - - Runnable simpleKeyPrepareAction = () -> generatePersons(PERSONS_COUNT); - Runnable compositeKeyPrepareAction = () -> generateComplexPersons(PERSONS_COUNT); - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(Person.class), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(ComplexPerson.class), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDelete") - void testKVTemplateDelete( - Runnable prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.run(); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForDeleteEntities() { - - Person simpleKeyPerson = new Person(0, true, "0"); - ComplexPerson compositeKeyPerson = new ComplexPerson(0, UUID.randomUUID(), true, "0"); - - Consumer simpleKeyPrepareAction = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer compositeKeyPrepareAction = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(simpleKeyPerson), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(compositeKeyPerson), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDeleteEntities") - void testKVTemplateDeleteEntities( - Consumer prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.accept(client); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForDeleteEntitiesById() { - - Person simpleKeyPerson = new Person(0, true, "0"); - ComplexPerson compositeKeyPerson = new ComplexPerson(0, UUID.randomUUID(), true, "0"); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Consumer simpleKeyPrepareAction = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer compositeKeyPrepareAction = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(simpleKey, Person.class), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(compositeKey, ComplexPerson.class), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDeleteEntitiesById") - void testKVTemplateDeleteEntitiesById( - Consumer prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.accept(client); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForCount() { - - Consumer simpleKeyPrepareAction = - (client) -> generateAndInsertPersons(PERSONS_COUNT, client); - - Consumer compositeKeyPrepareAction = - (client) -> generateAndInsertComplexPersons(PERSONS_COUNT, client); - - return Stream.of( - Arguments.of( - PERSONS_COUNT, - simpleKeyPrepareAction, - (Function) (kv) -> kv.count(Person.class)), - Arguments.of( - PERSONS_COUNT, - compositeKeyPrepareAction, - (Function) (kv) -> kv.count(ComplexPerson.class))); - } - - @ParameterizedTest - @MethodSource("dataForCount") - void testCount( - long expectedCount, - Consumer prepareAction, - Function callingMethod) { - prepareAction.accept(client); - assertEquals(expectedCount, callingMethod.apply(tarantoolTemplate)); - } - - @Test - void testCompositeKeyWithJsonFormat() { - ComplexPersonWithJsonFormatVariantPK complexPersonWithJsonFormatVariantPK = - new ComplexPersonWithJsonFormatVariantPK(0, UUID.randomUUID(), null, "0"); - - assertEquals( - complexPersonWithJsonFormatVariantPK, - tarantoolTemplate.insert(complexPersonWithJsonFormatVariantPK)); - - CompositePersonKeyWithJsonFormat key = - new CompositePersonKeyWithJsonFormat( - complexPersonWithJsonFormatVariantPK.getId(), - complexPersonWithJsonFormatVariantPK.getSecondId()); - Optional foundPerson = - tarantoolTemplate.findById(key, ComplexPersonWithJsonFormatVariantPK.class); - assertTrue(foundPerson.isPresent()); - assertEquals(complexPersonWithJsonFormatVariantPK, foundPerson.get()); - } - - @Test - void testCompositeKeyWithoutJsonFormat() { - ComplexPersonWithIncorrectPK complexPersonWithIncorrectPK = - new ComplexPersonWithIncorrectPK(0, UUID.randomUUID(), null, "0"); - - Throwable exception = - assertThrows( - UncategorizedKeyValueException.class, - () -> tarantoolTemplate.insert(complexPersonWithIncorrectPK)) - .getRootCause(); - assertInstanceOf(CrudException.class, exception); - } - - public static Stream dataForTestCompositeKeyWithConcurrency() { - final List threadsCount = Arrays.asList(1, 2, 3); - final List tuplesCount = Arrays.asList(20, 120, 360, 1200, 3000); - final List totalArguments = new ArrayList<>(); - - for (final Integer threadCount : threadsCount) { - for (final Integer tupleCount : tuplesCount) { - totalArguments.add(Arguments.of(threadCount, tupleCount)); - } - } - - return totalArguments.stream(); - } - - @DisplayName("Checking the insertion of an entity with a composite key") - @ParameterizedTest(autoCloseArguments = false, name = "thread count: {0}, tuples count: {1}") - @MethodSource("dataForTestCompositeKeyWithConcurrency") - void testCompositeKeyWithConcurrency(int threadsCount, int tuplesCount) { - final ExecutorService executor = Executors.newFixedThreadPool(threadsCount); - final List> futures = new ArrayList<>(); - final List tuples = generateComplexPersons(tuplesCount); - - for (final ComplexPerson tuple : tuples) { - futures.add( - CompletableFuture.supplyAsync(() -> this.tarantoolTemplate.insert(tuple), executor)); - } - - CompletableFuture.allOf(futures.toArray(new CompletableFuture[] {})).join(); - - for (int i = 0; i < tuplesCount; i++) { - assertEquals(tuples.get(i), futures.get(i).join()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/RepositoryConfigurationExtensionTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/RepositoryConfigurationExtensionTest.java deleted file mode 100644 index 6bac2c89..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/RepositoryConfigurationExtensionTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.integration.crud; - -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.client.factory.TarantoolBoxClientBuilder; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.spring.data35.integration.BaseIntegrationTest; -import io.tarantool.spring.data35.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data35.repository.config.TarantoolRepositoryConfigurationExtension; - -class RepositoryConfigurationExtensionTest extends BaseIntegrationTest { - - private static TarantoolRepositoryConfigurationExtension defaultExtension; - - @BeforeAll - static void setUp() throws IOException { - BaseIntegrationTest.beforeAll(); - defaultExtension = new TarantoolRepositoryConfigurationExtension(); - } - - @Test - void testGetModuleName() { - assertEquals("Tarantool", defaultExtension.getModuleName()); - } - - @Test - void testGetModulePrefix() { - assertEquals("tarantool", defaultExtension.getModulePrefix()); - } - - @Test - void testGetDefaultKeyValueTemplateRef() { - assertEquals( - DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF, defaultExtension.getDefaultKeyValueTemplateRef()); - } - - @Test - void testRegisterBeansForRootWithDefaultConfig() { - final ApplicationContext context = new AnnotationConfigApplicationContext(DefaultConfig.class); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF)); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF)); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF)); - } - - @Test - void testRegisterBeansForRootWithCustomClientConfigShouldThrows() { - final Throwable throwable = - assertThrows( - IllegalArgumentException.class, - () -> new AnnotationConfigApplicationContext(BoxNonSupportConfig.class)); - - final String exceptionMessage = "The Box client is not yet supported."; - assertEquals(exceptionMessage, throwable.getMessage()); - } - - private static TarantoolCrudClientBuilder getCrudClientSettings() { - return TarantoolFactory.crud() - .withHost(getHost()) - .withPort(getPort()) - .withUser(getUsername()) - .withPassword(getPassword()); - } - - private static TarantoolBoxClientBuilder getBoxClientSettings() { - return TarantoolFactory.box().withHost(getHost()).withPort(getPort()); - } - - @EnableTarantoolRepositories - static class DefaultConfig { - - @Bean - public TarantoolCrudClientBuilder clientSettings() { - return getCrudClientSettings(); - } - } - - @EnableTarantoolRepositories(clientType = ClientType.BOX) - static class BoxNonSupportConfig { - - @Bean - public TarantoolBoxClientBuilder clientSettings() { - return getBoxClientSettings(); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/RepositoryViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/RepositoryViaJavaConfigTest.java deleted file mode 100644 index 8caec63f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/RepositoryViaJavaConfigTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data35.integration.crud.CrudConfigurations.JavaConfigConfiguration; - -@SpringBootTest(classes = {JavaConfigConfiguration.class}) -class RepositoryViaJavaConfigTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/RepositoryViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/RepositoryViaPropertiesTest.java deleted file mode 100644 index a1906614..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/RepositoryViaPropertiesTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data35.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; - -@SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) -class RepositoryViaPropertiesTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/TarantoolTemplateViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/TarantoolTemplateViaJavaConfigTest.java deleted file mode 100644 index 50afb1c2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/TarantoolTemplateViaJavaConfigTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data35.integration.crud.CrudConfigurations.JavaConfigConfiguration; - -@SpringBootTest(classes = {JavaConfigConfiguration.class}) -class TarantoolTemplateViaJavaConfigTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/TarantoolTemplateViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/TarantoolTemplateViaPropertiesTest.java deleted file mode 100644 index 3ebb67a1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/TarantoolTemplateViaPropertiesTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data35.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; - -@SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) -class TarantoolTemplateViaPropertiesTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolCriteriaTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolCriteriaTest.java deleted file mode 100644 index 5843a2df..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolCriteriaTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.util.Arrays; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; - -import static io.tarantool.client.crud.ConditionOperator.EQ; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.spring.data.query.Conditions; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolCriteriaTest { - - @Test - void testAddAndGetConditions() { - final TarantoolCriteria tarantoolCriteria = new TarantoolCriteria(); - final String identifier = "name"; - final Object value = "value"; - final String operator = "=="; - - final Condition condition = Condition.create(operator, identifier, value); - assertEquals(operator, condition.getOperator()); - assertEquals(identifier, condition.getFieldIdentifier()); - assertEquals(value, condition.getValue()); - - final Condition conditionConstructor = new Condition(operator, identifier, value); - assertEquals(operator, conditionConstructor.getOperator()); - assertEquals(identifier, conditionConstructor.getFieldIdentifier()); - assertEquals(value, conditionConstructor.getValue()); - - final Condition conditionFromBuilder = - Condition.builder() - .withOperator(operator) - .withValue(value) - .withFieldIdentifier(identifier) - .build(); - assertEquals(operator, conditionFromBuilder.getOperator()); - assertEquals(identifier, conditionFromBuilder.getFieldIdentifier()); - assertEquals(value, conditionFromBuilder.getValue()); - - final Condition conditionWithEnum = Condition.create(EQ, identifier, value); - assertEquals(operator, conditionWithEnum.getOperator()); - assertEquals(identifier, conditionWithEnum.getFieldIdentifier()); - assertEquals(value, conditionWithEnum.getValue()); - - final Condition conditionConstructorWithEnum = new Condition(EQ, identifier, value); - assertEquals(operator, conditionConstructorWithEnum.getOperator()); - assertEquals(identifier, conditionConstructorWithEnum.getFieldIdentifier()); - assertEquals(value, conditionConstructorWithEnum.getValue()); - - final Condition conditionFromBuilderWithEnum = - Condition.builder() - .withOperator(EQ) - .withValue(value) - .withFieldIdentifier(identifier) - .build(); - assertEquals(operator, conditionFromBuilderWithEnum.getOperator()); - assertEquals(identifier, conditionFromBuilderWithEnum.getFieldIdentifier()); - assertEquals(value, conditionFromBuilderWithEnum.getValue()); - - tarantoolCriteria.addCondition(condition); - tarantoolCriteria.addCondition(conditionConstructor); - tarantoolCriteria.addCondition(conditionFromBuilder); - - tarantoolCriteria.addCondition(conditionWithEnum); - tarantoolCriteria.addCondition(conditionConstructorWithEnum); - tarantoolCriteria.addCondition(conditionFromBuilderWithEnum); - - final Conditions expectedConditions = new Conditions(); - expectedConditions.addAll( - Arrays.asList( - condition, - conditionConstructor, - conditionFromBuilder, - conditionWithEnum, - conditionConstructorWithEnum, - conditionFromBuilderWithEnum)); - - assertEquals(expectedConditions, tarantoolCriteria.getConditions()); - } - - @Test - void testFirst() { - final TarantoolCriteria criteria = new TarantoolCriteria(); - criteria.withFirst(1); - - final String key = "first"; - SelectOptions options = criteria.getOptions(); - assertEquals(1, options.getOptions().get(key)); - - criteria.clear(); - criteria.withFirst(-1); - options = criteria.getOptions(); - assertEquals(-1, options.getOptions().get(key)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolKeysetScrollPositionTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolKeysetScrollPositionTest.java deleted file mode 100644 index ab6074bd..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolKeysetScrollPositionTest.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.UUID; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.function.Executable; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.ScrollPosition; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.Pair; - -class TarantoolKeysetScrollPositionTest { - - private static final Pair INDEX_KEY = Pair.of("pk", 123); - - private static final Pair INDEX_KEY_WITH_NULL_VALUE = Pair.of("pk", null); - - static Stream dataForTestTarantoolScrollPositionCreateDoesntThrow() { - return Stream.of( - () -> TarantoolScrollPosition.forward(INDEX_KEY), - () -> TarantoolScrollPosition.forward(INDEX_KEY_WITH_NULL_VALUE), - () -> TarantoolScrollPosition.backward(INDEX_KEY), - () -> TarantoolScrollPosition.backward(INDEX_KEY_WITH_NULL_VALUE)); - } - - @ParameterizedTest - @MethodSource("dataForTestTarantoolScrollPositionCreateDoesntThrow") - void testTarantoolScrollPositionCreateDoesntThrow(Executable scrollPositionCreateAction) { - assertDoesNotThrow(scrollPositionCreateAction); - } - - static Stream dataForTestTarantoolScrollPositionCreateThrows() { - return Stream.of( - () -> TarantoolScrollPosition.forward(null), () -> TarantoolScrollPosition.backward(null)); - } - - @ParameterizedTest - @MethodSource("dataForTestTarantoolScrollPositionCreateThrows") - void testTarantoolScrollPositionCreateThrows(Executable scrollPositionCreateAction) { - assertThrows(IllegalArgumentException.class, scrollPositionCreateAction); - } - - static Stream dataForTestEqualsAndHashCode() { - - List equalScrollPositionsWithKey = - Arrays.asList( - TarantoolScrollPosition.forward(INDEX_KEY), TarantoolScrollPosition.forward(INDEX_KEY)); - - TarantoolScrollPosition notEqualScrollPosition = - TarantoolScrollPosition.forward(INDEX_KEY_WITH_NULL_VALUE); - - final int ITERATION_COUNT = 100; - - return Stream.of( - Arguments.of(equalScrollPositionsWithKey, notEqualScrollPosition, ITERATION_COUNT), - Arguments.of(equalScrollPositionsWithKey, null, ITERATION_COUNT)); - } - - @ParameterizedTest - @MethodSource("dataForTestEqualsAndHashCode") - void testEqualsAndHashCode( - List scrollPositions, - ScrollPosition notEqualScrollPosition, - int iterationCount) { - for (int i = 0; i < iterationCount; i++) { - for (ScrollPosition scrollPosition : scrollPositions) { - for (ScrollPosition otherScrollPosition : scrollPositions) { - assertEquals(scrollPosition, otherScrollPosition); - assertEquals(scrollPosition.hashCode(), otherScrollPosition.hashCode()); - } - assertNotEquals(scrollPosition, notEqualScrollPosition); - if (notEqualScrollPosition != null) { - assertNotEquals(scrollPosition.hashCode(), notEqualScrollPosition.hashCode()); - } - } - } - } - - static Stream dataForTestIsInitial() { - var startingIndex = Pair.of("pk", Collections.emptyList()); - var complexIndex = Pair.of("pk", Arrays.asList(1, UUID.randomUUID())); - Object nonNullCursor = Arrays.asList(1, 2, 3, 4); - return Stream.of( - Arguments.of(TarantoolScrollPosition.backward(INDEX_KEY), false), - Arguments.of(TarantoolScrollPosition.forward(INDEX_KEY), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, null), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, nonNullCursor), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, nonNullCursor), false), - Arguments.of(TarantoolScrollPosition.backward(startingIndex), true), - Arguments.of(TarantoolScrollPosition.forward(startingIndex), true), - Arguments.of(new TarantoolKeysetScrollPosition(startingIndex, FORWARD, null), true), - Arguments.of(new TarantoolKeysetScrollPosition(startingIndex, BACKWARD, null), true), - Arguments.of( - new TarantoolKeysetScrollPosition(startingIndex, FORWARD, nonNullCursor), false), - Arguments.of( - new TarantoolKeysetScrollPosition(startingIndex, BACKWARD, nonNullCursor), false), - Arguments.of(TarantoolScrollPosition.backward(complexIndex), false), - Arguments.of(TarantoolScrollPosition.forward(complexIndex), false)); - } - - @ParameterizedTest - @MethodSource("dataForTestIsInitial") - void testIsInitial(ScrollPosition scrollPosition, boolean expectedIsInitial) { - assertEquals(scrollPosition.isInitial(), expectedIsInitial); - } - - static Stream dataForTestGetCursor() { - var cursor = String.valueOf(2); - return Stream.of( - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), null), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, cursor), cursor)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetCursor") - void testGetCursor(TarantoolKeysetScrollPosition scrollPosition, Object expectedCursor) { - assertEquals(expectedCursor, scrollPosition.getCursor()); - } - - static Stream dataForTestGetKeyIndex() { - return Stream.of( - Arguments.of(TarantoolScrollPosition.forward(INDEX_KEY), INDEX_KEY), - Arguments.of(TarantoolScrollPosition.backward(INDEX_KEY), INDEX_KEY)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetKeyIndex") - void testGetKeyIndex( - TarantoolKeysetScrollPosition scrollPosition, Pair expectedIndexKey) { - assertEquals(expectedIndexKey, scrollPosition.getIndexKey()); - } - - static Stream dataForTestGetDirection() { - return Stream.of( - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), FORWARD), - Arguments.of( - new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, String.valueOf(2)), BACKWARD)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetDirection") - void testGetDirection( - TarantoolKeysetScrollPosition scrollPosition, PaginationDirection expectedDirection) { - assertEquals(expectedDirection, scrollPosition.getDirection()); - } - - static Stream dataForTestReverse() { - Object someKey = String.valueOf(1); - var indexKeyAfterReverse = Pair.of(INDEX_KEY.getFirst(), INDEX_KEY.getSecond()); - - return Stream.of( - Arguments.of( - TarantoolScrollPosition.forward(INDEX_KEY), - TarantoolScrollPosition.backward(indexKeyAfterReverse)), - Arguments.of( - new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, someKey), - new TarantoolKeysetScrollPosition(indexKeyAfterReverse, BACKWARD, someKey))); - } - - @ParameterizedTest - @MethodSource("dataForTestReverse") - void testGetReverse( - TarantoolScrollPosition scrollPosition, - TarantoolKeysetScrollPosition expectedReversedPosition) { - assertEquals(expectedReversedPosition, scrollPosition.reverse()); - } - - static Stream dataForTestIsScrollsBackward() { - return Stream.of( - Arguments.of( - TarantoolScrollPosition.forward(Pair.of("pk", Collections.emptyList())), false), - Arguments.of( - TarantoolScrollPosition.backward(Pair.of("pk", Collections.emptyList())), true)); - } - - @ParameterizedTest - @MethodSource("dataForTestIsScrollsBackward") - void testIsScrollsBackward(TarantoolScrollPosition position, boolean expectedIsScrollsBackward) { - assertEquals(expectedIsScrollsBackward, position.isScrollsBackward()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolPageImplTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolPageImplTest.java deleted file mode 100644 index 55b77506..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolPageImplTest.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data35.utils.entity.Person; - -class TarantoolPageImplTest { - - private static final List PERSONS = generatePersons(PERSONS_COUNT); - - private static final int DEFAULT_PAGE_SIZE_PER_TEST_CLASS = 10; - - private static final int DEFAULT_PAGE_NUMBER_PER_TEST_CLASS = 0; - - private static final Pageable FIRST_PAGE_PAGEABLE_PER_TEST_CLASS = - new TarantoolPageRequest<>( - DEFAULT_PAGE_NUMBER_PER_TEST_CLASS, DEFAULT_PAGE_SIZE_PER_TEST_CLASS, null); - - private static final long MULTIPLIER = 2L; - - private static final BiFunction GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE = - (pageSize, operator) -> { - switch (operator) { - // pageSize > totalPageCount - case ">": - { - return pageSize / MULTIPLIER; - } - // pageSize < totalPageCount - case "<": - { - return MULTIPLIER * pageSize; - } - // pageSize == totalPageCount - case "==": - { - return Long.valueOf(pageSize); - } - default: - throw new IllegalArgumentException("The passed option isn't supported"); - } - }; - - private static final List EMPTY_CONTENT = Collections.emptyList(); - - protected static Stream dataForTestConstructors() { - TarantoolPageable> pageable = - new TarantoolPageRequest<>(0, DEFAULT_PAGE_SIZE_PER_TEST_CLASS, null); - - long personsSize = PERSONS.size(); - - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>(PERSONS, pageable, personsSize), - PERSONS.size() / DEFAULT_PAGE_SIZE_PER_TEST_CLASS, - personsSize), - Arguments.of(new TarantoolPageImpl<>(PERSONS), 1, personsSize), - Arguments.of(new TarantoolPageImpl<>(), 1, 0L)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructors") - void testConstructors(Page> page, int totalPages, long totalElements) { - assertEquals(totalPages, page.getTotalPages()); - assertEquals(totalElements, page.getTotalElements()); - } - - static Stream dataForTestConstructorsThrowsIllegalArgumentException() { - final class DummyTarantoolPageRequest implements Pageable { - - @Override - public int getPageNumber() { - return 0; - } - - @Override - public int getPageSize() { - return 0; - } - - @Override - public long getOffset() { - return 0L; - } - - @Override - public Sort getSort() { - return null; - } - - @Override - public Pageable next() { - return null; - } - - @Override - public Pageable previousOrFirst() { - return null; - } - - @Override - public Pageable first() { - return null; - } - - @Override - public Pageable withPage(int pageNumber) { - return null; - } - - @Override - public boolean hasPrevious() { - return false; - } - } - - Pageable dummyPageable = new DummyTarantoolPageRequest(); - - return Stream.of( - Arguments.of(null, null, "Content must not be null"), - Arguments.of(Collections.emptyList(), null, "Pageable must not be null"), - Arguments.of( - Collections.emptyList(), - dummyPageable, - "Pageable must be TarantoolPageable or Unpaged type")); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructorsThrowsIllegalArgumentException") - void testConstructors_throws_IllegalArgumentException( - List content, Pageable pageable, String errorMsg) { - assertThrows( - IllegalArgumentException.class, - () -> new TarantoolPageImpl<>(content, pageable, 0L), - errorMsg); - } - - static Stream dataForTestGetTotalPages() { - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, ">")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "<")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - Pageable.unpaged(), - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - PERSONS.size() / FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - 1), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, ">")), - 0), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "<")), - 0), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, Pageable.unpaged(), GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply(0, "==")), - 0)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTotalPages") - void testGetTotalPages(Page page, long totalPagesCount) { - assertEquals(totalPagesCount, page.getTotalPages()); - } - - static Stream dataForTestGetTotalElements() { - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() / MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() * MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - EMPTY_CONTENT, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), ">")), - PERSONS.size()), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "<")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize() * MULTIPLIER), - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - GET_TOTAL_ELEMENTS_FOR_TEST_DATA_CASE.apply( - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize(), "==")), - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTotalElements") - void testGetTotalElements(Page page, long totalElementCount) { - assertEquals(totalElementCount, page.getTotalElements()); - } - - static Stream dataForTestHasNext() { - return Stream.of( - Arguments.of( - false, - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())), - Arguments.of( - true, - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - MULTIPLIER * FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())), - Arguments.of( - false, - new TarantoolPageImpl<>( - PERSONS, - Pageable.unpaged(), - MULTIPLIER * FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()))); - } - - @ParameterizedTest - @MethodSource("dataForTestHasNext") - void testHasNext(boolean exceptedBool, Page page) { - assertEquals(exceptedBool, page.hasNext()); - } - - @ParameterizedTest - @MethodSource("dataForTestHasNext") - void testIsLast(boolean notEqualBool, Page page) { - assertNotEquals(notEqualBool, page.isLast()); - } - - static Stream dataForTestMap() { - List exceptedNames = PERSONS.stream().map(Person::getName).collect(Collectors.toList()); - return Stream.of( - Arguments.of( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - exceptedNames, - (Function) Person::getName)); - } - - @ParameterizedTest - @MethodSource("dataForTestMap") - void testMap(Page page, List exceptedNames, Function mapFunction) { - List names = page.map(mapFunction).toList(); - assertEquals(exceptedNames, names); - } - - static Stream dataForTestEqualsAndHashCode() { - List> equalPages = - Arrays.asList( - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize()), - new TarantoolPageImpl<>( - PERSONS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS, - FIRST_PAGE_PAGEABLE_PER_TEST_CLASS.getPageSize())); - - final int ITERATION_COUNT = 100; - - return Stream.of( - Arguments.of( - equalPages, - new TarantoolPageImpl<>(EMPTY_CONTENT, Pageable.unpaged(), 150), - ITERATION_COUNT), - Arguments.of(equalPages, null, ITERATION_COUNT)); - } - - @ParameterizedTest - @MethodSource("dataForTestEqualsAndHashCode") - void testEqualsAndHashCode(List> pages, Page notEqualPage, int iterationCount) { - for (int i = 0; i < iterationCount; i++) { - for (Page page : pages) { - for (Page otherPage : pages) { - assertEquals(page, otherPage); - assertEquals(page.hashCode(), otherPage.hashCode()); - } - assertNotEquals(page, notEqualPage); - if (notEqualPage != null) { - assertNotEquals(page.hashCode(), notEqualPage.hashCode()); - } - } - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolPageRequestTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolPageRequestTest.java deleted file mode 100644 index 2f075fca..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolPageRequestTest.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.util.Arrays; -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.AbstractPageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data35.utils.entity.Person; - -class TarantoolPageRequestTest { - - private static final int PAGE_SIZE = 10; - - private static final Person CURSOR = new Person(0, true, "0"); - - private static final int PAGE_NUMBER = 0; - - protected static Stream dataForTestConstructors() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - null, - FORWARD), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - CURSOR, - FORWARD), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, null), - PAGE_NUMBER, - PAGE_SIZE, - Sort.unsorted(), - null, - FORWARD)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructors") - void testConstructors( - Supplier>> constructorGenerator, - int pageNumber, - int size, - Sort sort, - GenericPerson cursor, - PaginationDirection direction) { - TarantoolPageable> pageable = constructorGenerator.get(); - - assertEquals(size, pageable.getPageSize()); - assertEquals(pageNumber, pageable.getPageNumber()); - assertEquals(sort, pageable.getSort()); - assertEquals(cursor, pageable.getTupleCursor()); - assertEquals(direction, pageable.getPaginationDirection()); - } - - protected static Stream dataTestGetSort() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - Sort.unsorted()), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - Sort.unsorted())); - } - - @ParameterizedTest - @MethodSource("dataTestGetSort") - void testGetSort(Supplier>> constructorGenerator, Sort sort) { - Pageable pageable = constructorGenerator.get(); - assertEquals(sort, pageable.getSort()); - } - - protected static Stream dataForTestGetTupleCursor() { - return Stream.of( - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_SIZE), - null), - Arguments.of( - (Supplier>>) - () -> new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetTupleCursor") - void testGetTupleCursor( - Supplier>> constructorGenerator, GenericPerson person) { - TarantoolPageable> pageable = constructorGenerator.get(); - assertEquals(person, pageable.getTupleCursor()); - } - - protected static Stream dataForTestNext() { - final Person NEXT_CURSOR = - new Person(CURSOR.getId() + PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), CURSOR, NEXT_CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataForTestNext") - void testNext( - TarantoolPageable> pageable, - GenericPerson cursor, - GenericPerson nextCursor) { - assertEquals(cursor, pageable.getTupleCursor()); - - TarantoolPageable> nextPageable = pageable.next(nextCursor); - assertEquals(nextCursor, nextPageable.getTupleCursor()); - - assertEquals(pageable.getPageSize(), nextPageable.getPageSize()); - assertEquals(pageable.getPageNumber() + 1, nextPageable.getPageNumber()); - assertEquals(pageable.getSort(), nextPageable.getSort()); - assertEquals(pageable.getOffset() + PAGE_SIZE, nextPageable.getOffset()); - } - - @Test - void testNextUnsupported() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::next); - } - - protected static Stream dataTestGetPaginationDirection() { - final Person PREV_CURSOR = new Person(CURSOR.getId(), CURSOR.getIsMarried(), CURSOR.getName()); - final Person NEXT_CURSOR = - new Person(PREV_CURSOR.getId() + PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, NEXT_CURSOR), NEXT_CURSOR, PREV_CURSOR)); - } - - @ParameterizedTest - @MethodSource("dataTestGetPaginationDirection") - void testGetPaginationDirection( - TarantoolPageable> pageable, - GenericPerson nextCursor, - GenericPerson prevCursor) { - - assertEquals(FORWARD, pageable.getPaginationDirection()); - - TarantoolPageable> prevPageable = pageable.previousOrFirst(prevCursor); - assertEquals(PaginationDirection.BACKWARD, prevPageable.getPaginationDirection()); - - TarantoolPageable> nextPageable = prevPageable.next(nextCursor); - assertEquals(FORWARD, nextPageable.getPaginationDirection()); - assertEquals(pageable, nextPageable); - } - - protected static Stream dataTestFirst() { - final Person CURSOR = new Person(2 * PAGE_SIZE, true, "name"); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(0, PAGE_SIZE, null))); - } - - @ParameterizedTest - @MethodSource("dataTestFirst") - void testFirst( - TarantoolPageable> pageable, - TarantoolPageable> exceptedFirstPageable) { - assertEquals(exceptedFirstPageable, pageable.first()); - } - - @Test - void testWithPage() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, () -> pageable.withPage(100)); - } - - protected static Stream dataTestPreviousOrFirst() { - final Person CURSOR = new Person(PAGE_SIZE, true, "name"); - return Stream.of( - Arguments.of( - new TarantoolPageRequest<>(1, PAGE_SIZE, CURSOR), - new Person(CURSOR.getId() - PAGE_SIZE, CURSOR.getIsMarried(), CURSOR.getName()))); - } - - @ParameterizedTest - @MethodSource("dataTestPreviousOrFirst") - void testPreviousOrFirst( - TarantoolPageable> pageable, GenericPerson prevCursor) { - - TarantoolPageable> prevPageable = pageable.previousOrFirst(prevCursor); - - assertNotEquals(pageable, prevPageable); - assertEquals(pageable.getPageSize(), prevPageable.getPageSize()); - assertEquals(pageable.getOffset() - PAGE_SIZE, prevPageable.getOffset()); - assertEquals(pageable.getSort(), prevPageable.getSort()); - assertEquals(pageable.getPageNumber() - 1, prevPageable.getPageNumber()); - - // here will be first with null cursor - TarantoolPageable> firstPageable = prevPageable.previousOrFirst(prevCursor); - assertNull(firstPageable.getTupleCursor()); - } - - @Test - void testPreviousOrFirstUnsupported() { - TarantoolPageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::previousOrFirst); - } - - @Test - void testPreviousUnsupported() { - AbstractPageRequest pageable = new TarantoolPageRequest<>(PAGE_SIZE); - assertThrows(UnsupportedOperationException.class, pageable::previous); - } - - protected static Stream dataForTestEquals() { - return Stream.of( - Arguments.of( - Arrays.asList( - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, CURSOR)), - new TarantoolPageRequest<>(PAGE_SIZE))); - } - - @ParameterizedTest - @MethodSource("dataForTestEquals") - void testEquals( - List>> equalPageableList, - TarantoolPageable> notEqualPageable) { - - assertTrue(equalPageableList.size() > 0); - final int COUNT = 10; - - for (int i = 0; i < COUNT; i++) { - for (TarantoolPageable> pageable : equalPageableList) { - for (TarantoolPageable> secondPageable : equalPageableList) { - assertEquals(pageable, secondPageable); - } - assertNotEquals(pageable, null); - assertNotEquals(pageable, notEqualPageable); - } - } - } - - @ParameterizedTest - @MethodSource("dataForTestEquals") - void testHashCode( - List>> equalPageableList, - TarantoolPageable> notEqualPageable) { - - for (TarantoolPageable> pageable : equalPageableList) { - for (TarantoolPageable> secondPageable : equalPageableList) { - assertEquals(pageable.hashCode(), secondPageable.hashCode()); - } - assertNotEquals(pageable.hashCode(), notEqualPageable.hashCode()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolSliceTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolSliceTest.java deleted file mode 100644 index a6578dcc..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/query/TarantoolSliceTest.java +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.function.Executable; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; - -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data35.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.spring.data35.utils.entity.Person; - -public class TarantoolSliceTest { - - private static final int PAGE_SIZE = 10; - - private static final int PAGE_NUMBER = 0; - - private static final Person SOME_CURSOR = new Person(0, true, "0"); - - private static List PERSONS; - - private static final Pageable SOME_PAGEABLE = - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR); - - @BeforeAll - static void setUp() { - PERSONS = generatePersons(PERSONS_COUNT); - } - - static Stream dataForTestConstructorsShouldThrow() { - Pageable tarantoolPageable = new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR); - Pageable notTarantoolPageable = Pageable.ofSize(PAGE_SIZE); - return Stream.of( - Arguments.of(null, tarantoolPageable, false), - Arguments.of(null, tarantoolPageable, true), - Arguments.of(PERSONS, null, false), - Arguments.of(PERSONS, null, true), - Arguments.of(PERSONS, notTarantoolPageable, false), - Arguments.of(PERSONS, notTarantoolPageable, true)); - } - - @ParameterizedTest - @MethodSource("dataForTestConstructorsShouldThrow") - public void testConstructorsShouldThrow(List content, Pageable pageable, boolean hasNext) { - assertThrows( - IllegalArgumentException.class, () -> new TarantoolSliceImpl<>(content, pageable, hasNext)); - } - - static Stream dataForTestConstructorsDoesntThrow() { - return Stream.of( - () -> new TarantoolSliceImpl<>(PERSONS), - () -> new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - () -> new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestConstructorsDoesntThrow") - public void testConstructorsDoesntThrow(Executable runTestCase) { - assertDoesNotThrow(runTestCase); - } - - static Stream dataForTestGetNumber() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getPageNumber()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetNumber") - public void testGetNumber(Slice slice, int expectedPageNumber) { - assertEquals(expectedPageNumber, slice.getNumber()); - } - - static Stream dataForTestGetSize() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getPageSize()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS.size()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), - SOME_PAGEABLE.getPageSize()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetSize") - public void testGetSize(Slice slice, int expectedSize) { - assertEquals(expectedSize, slice.getSize()); - } - - static Stream dataForTestGetNumberOfElements() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), PERSONS.size()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS.size()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), 0), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), 0)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetNumberOfElements") - public void testGetNumberOfElements(Slice slice, int expectedNumberOfElements) { - assertEquals(expectedNumberOfElements, slice.getNumberOfElements()); - } - - static Stream dataForTestGetContent() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), PERSONS), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), PERSONS), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), - Collections.emptyList()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Collections.emptyList())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetContent") - public void testGetContent(Slice slice, List expectedContent) { - assertEquals(expectedContent, slice.getContent()); - } - - static Stream dataForTestHasContent() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), true), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), false), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasContent") - void testHasContent(Slice slice, boolean expectedHasContent) { - assertEquals(expectedHasContent, slice.hasContent()); - } - - static Stream dataForTestGetSort() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), SOME_PAGEABLE.getSort()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Sort.unsorted())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetSort") - void testGetSort(Slice slice, Sort expectedSort) { - assertEquals(expectedSort, slice.getSort()); - } - - static Stream dataForTestIsFirst() { - final int MIDDLE_PAGE_NUMBER = 2; - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), true), - true), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), true), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - true), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - true), - true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), true)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestIsFirst") - void testIsFirst(Slice slice, boolean expectedIsFirst) { - assertEquals(expectedIsFirst, slice.isFirst()); - } - - static Stream dataForTestIsLast() { - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), false), - // last imitation - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, false), true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), true), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), true), - // last imitation - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, false), true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), true), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), true)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestIsLast") - void testIsLast(Slice slice, boolean expectedIsLast) { - assertEquals(expectedIsLast, slice.isLast()); - } - - static Stream dataForTestHasNext() { - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, new TarantoolPageRequest<>(PAGE_SIZE), true), true), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, new TarantoolPageRequest<>(PAGE_SIZE), false), false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), new TarantoolPageRequest<>(PAGE_SIZE), true), - false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), new TarantoolPageRequest<>(PAGE_SIZE), false), - false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasNext") - void testHasNext(Slice slice, boolean expectedHasNext) { - assertEquals(expectedHasNext, slice.hasNext()); - } - - static Stream dataForTestHasPrevious() { - final int MIDDLE_PAGE_NUMBER = 2; - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), false), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS, - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - false), - true), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), false), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), false), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true), false), - Arguments.of( - new TarantoolSliceImpl<>( - Collections.emptyList(), - new TarantoolPageRequest<>(MIDDLE_PAGE_NUMBER, PAGE_SIZE, SOME_CURSOR), - false), - false), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), false), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), false)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestHasPrevious") - void testHasPrevious(Slice slice, boolean expectedHasPrevious) { - assertEquals(expectedHasPrevious, slice.hasPrevious()); - } - - static Stream dataForTestGetPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS, pageable, true), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), pageable), - Arguments.of(new TarantoolSliceImpl<>(PERSONS, pageable, false), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), pageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), true), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, Pageable.unpaged(), false), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), Pageable.unpaged(), false), - Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged())); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestGetPageable") - void testGetPageable(Slice slice, Pageable expectedPageable) { - assertEquals(expectedPageable, slice.getPageable()); - } - - static Stream dataForTestNextPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, true), - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - new TarantoolPageRequest<>(5, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestNextPageable") - void testNextPageable(Slice slice, Pageable expectedNextPageable) { - assertEquals(expectedNextPageable, slice.nextPageable()); - } - - static Stream dataForTestPreviousPageable() { - Pageable firstPagePageable = new TarantoolPageRequest<>(PAGE_SIZE); - Pageable secondPagePageable = - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)); - - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, true), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, false), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, false), - Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(4, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(0)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPreviousPageable") - void testPreviousPageable(Slice slice, Pageable expectedPrevPageable) { - assertEquals(expectedPrevPageable, slice.previousPageable()); - } - - static Stream dataForTestNextOrLastPageable() { - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, true), - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, true), pageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), pageable, false), pageable), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList(), pageable, false), pageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - new TarantoolPageRequest<>(5, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1))), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - false), - new TarantoolPageRequest<>(4, PAGE_SIZE, null))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestNextOrLastPageable") - void testNextOrLastPageable(Slice slice, Pageable expectedNextOrLastPageable) { - assertEquals(expectedNextOrLastPageable, slice.nextOrLastPageable()); - } - - static Stream dataForTestPreviousOrFirstPageable() { - Pageable firstPagePageable = new TarantoolPageRequest<>(PAGE_SIZE); - Pageable secondPagePageable = - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE - 1)); - - return Stream.of( - Arguments.of(new TarantoolSliceImpl<>(PERSONS), Pageable.unpaged()), - Arguments.of(new TarantoolSliceImpl<>(Collections.emptyList()), Pageable.unpaged()), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, true), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, true), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(PERSONS.subList(0, PAGE_SIZE), firstPagePageable, false), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), firstPagePageable, false), - firstPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, true), - secondPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(PAGE_SIZE, 2 * PAGE_SIZE), secondPagePageable, false), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(1, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(PAGE_SIZE))), - Arguments.of( - new TarantoolSliceImpl<>(Collections.emptyList(), secondPagePageable, false), - secondPagePageable), - Arguments.of( - new TarantoolSliceImpl<>( - PERSONS.subList(0, PAGE_SIZE), - new TarantoolPageRequest<>(4, PAGE_SIZE, null), - true), - // to take into account the direction of pagination use previousOrFirst method - new TarantoolPageRequest<>(4, PAGE_SIZE, PERSONS.get(PAGE_SIZE)) - .previousOrFirst(PERSONS.get(0)))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPreviousOrFirstPageable") - void testPreviousOrFirstPageable(Slice slice, Pageable expectedPrevOrFirstPageable) { - assertEquals(expectedPrevOrFirstPageable, slice.previousOrFirstPageable()); - } - - static Stream dataForTestMap() { - - Pageable pageable = new TarantoolPageRequest<>(PAGE_SIZE); - List expectedNames = PERSONS.stream().map(Person::getName).collect(Collectors.toList()); - return Stream.of( - Arguments.of( - new TarantoolSliceImpl<>(PERSONS, pageable, true), - (Function) Person::getName, - expectedNames, - new TarantoolSliceImpl<>(expectedNames, pageable, true))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestMap") - void testMap( - Slice slice, - Function mapper, - List expectedMappedList, - Slice expectedMappedSlice) { - assertEquals(expectedMappedSlice, slice.map(mapper)); - assertEquals(expectedMappedList, slice.map(mapper).getContent()); - } - - protected static Stream dataForTestEquals() { - - return Stream.of( - Arguments.of( - Arrays.asList( - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true), - new TarantoolSliceImpl<>(PERSONS, SOME_PAGEABLE, true)), - new TarantoolSliceImpl<>(Collections.emptyList(), SOME_PAGEABLE, true))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestEquals") - void testEquals(List> equalPageableList, Slice notEqualPageable) { - - assertFalse(equalPageableList.isEmpty()); - final int COUNT = 10; - - for (int i = 0; i < COUNT; i++) { - for (Slice pageable : equalPageableList) { - for (Slice secondPageable : equalPageableList) { - assertEquals(pageable, secondPageable); - } - assertNotEquals(pageable, null); - assertNotEquals(pageable, notEqualPageable); - } - } - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestEquals") - void testHashCode(List> equalPageableList, Slice notEqualPageable) { - for (Slice pageable : equalPageableList) { - for (Slice secondPageable : equalPageableList) { - assertEquals(pageable.hashCode(), secondPageable.hashCode()); - } - assertNotEquals(pageable.hashCode(), notEqualPageable.hashCode()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/TarantoolTestSupport.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/TarantoolTestSupport.java deleted file mode 100644 index dcf7709a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/TarantoolTestSupport.java +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.UUID; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.Consumer; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.introspector.Property; -import org.yaml.snakeyaml.nodes.NodeTuple; -import org.yaml.snakeyaml.nodes.Tag; -import org.yaml.snakeyaml.representer.Representer; - -import static io.tarantool.balancer.BalancerMode.DEFAULT_BALANCER_MODE; -import static io.tarantool.client.TarantoolClient.DEFAULT_TAG; -import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_PASSWORD; -import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_USERNAME; -import static io.tarantool.core.protocol.requests.IProtoAuth.DEFAULT_AUTH_TYPE; -import static io.tarantool.pool.InstanceConnectionGroup.DEFAULT_HOST; -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import io.tarantool.balancer.BalancerMode; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.core.protocol.requests.IProtoAuth; -import io.tarantool.mapping.Tuple; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyFlushConsolidationHandler; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyHeartbeatOpts; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.spring.data35.config.properties.TarantoolProperties; -import io.tarantool.spring.data35.utils.entity.ComplexPerson; -import io.tarantool.spring.data35.utils.entity.Person; - -public class TarantoolTestSupport { - - private static final ThreadLocalRandom random = ThreadLocalRandom.current(); - private static final Map firstInternalMap = new HashMap<>(); - private static final Map secondInternalMap = new HashMap<>(); - private static final Map externalMap = new HashMap<>(); - private static final Representer representer; - public static final String PERSON_SPACE = "person"; - public static final String COMPLEX_PERSON_SPACE = "complex_person"; - public static final int PERSONS_COUNT = 100; - public static final Random RANDOMIZER = new Random(); - public static final Person UNKNOWN_PERSON = new Person(-1, true, "Alien"); - public static final ComplexPerson UNKNOWN_COMPLEX_PERSON = - new ComplexPerson(-1, new UUID(0, 0), true, "Alien"); - - public static final Path DEFAULT_TEST_PROPERTY_DIR = Paths.get("target", "test-classes"); - private static final Yaml yaml; - - static { - representer = - new Representer(new DumperOptions()) { - @Override - @Nullable - protected NodeTuple representJavaBeanProperty( - Object javaBean, Property property, @Nullable Object propertyValue, Tag customTag) { - if (propertyValue == null) { - return null; - } else { - return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag); - } - } - }; - representer.addClassTag(TarantoolProperties.class, Tag.MAP); - yaml = new Yaml(representer, new DumperOptions()); - } - - public static TarantoolProperties writeTestPropertiesYaml(@NonNull final String fileName) - throws IOException { - return writeTestPropertiesYaml(fileName, createRandomProperty()); - } - - public static TarantoolProperties writeTestPropertiesYaml( - final String fileName, final TarantoolProperties properties) throws IOException { - final File FILE = DEFAULT_TEST_PROPERTY_DIR.resolve(fileName).toFile().getAbsoluteFile(); - - try (Writer writer = new FileWriter(FILE)) { - firstInternalMap.put("tarantool", properties); - secondInternalMap.put("data", firstInternalMap); - externalMap.put("spring", secondInternalMap); - - yaml.dump(externalMap, writer); - replaceNullToDefault(properties); - return properties; - } - } - - public static void writeTestEmptyPropertiesYaml(@NonNull final String fileName) - throws IOException { - final File FILE = DEFAULT_TEST_PROPERTY_DIR.resolve(fileName).toFile().getAbsoluteFile(); - try (Writer writer = new FileWriter(FILE)) { - yaml.dump(Collections.emptyMap(), writer); - } - } - - private static void replaceNullToDefault(final TarantoolProperties result) { - - if (result.getHost() == null) { - result.setHost(DEFAULT_HOST); - } - - if (result.getUserName() == null) { - result.setUserName(DEFAULT_CRUD_USERNAME); - } - - if (result.getBalancerMode() == null) { - result.setBalancerMode(DEFAULT_BALANCER_MODE); - } - - if (result.getPassword() == null) { - result.setPassword(DEFAULT_CRUD_PASSWORD); - } - - if (result.getConnectionGroups() != null) { - for (PropertyInstanceConnectionGroup propertyInstanceConnectionGroup : - result.getConnectionGroups()) { - if (propertyInstanceConnectionGroup.getAuthType() == null) { - propertyInstanceConnectionGroup.setAuthType(DEFAULT_AUTH_TYPE); - } - - if (propertyInstanceConnectionGroup.getHost() == null) { - propertyInstanceConnectionGroup.setHost(DEFAULT_HOST); - } - - if (propertyInstanceConnectionGroup.getTag() == null) { - propertyInstanceConnectionGroup.setTag(DEFAULT_TAG); - } - - if (propertyInstanceConnectionGroup.getUserName() == null) { - propertyInstanceConnectionGroup.setUserName(DEFAULT_CRUD_USERNAME); - } - - if (propertyInstanceConnectionGroup.getUserName() == null) { - propertyInstanceConnectionGroup.setPassword(DEFAULT_CRUD_PASSWORD); - } - } - } - } - - private static TarantoolProperties createRandomProperty() { - final int intVar = 999; - final long longVar = 9999L; - final List booleanVar = Arrays.asList(true, false); - - PropertyHeartbeatOpts propertyHeartbeatOpts = - heartbeat( - choiceOrNull(longVar), - choiceOrNull(intVar), - choiceOrNull(intVar), - choiceOrNull(intVar)); - - PropertyFlushConsolidationHandler propertyFlushConsolidationHandler = - choiceOrNull(flushConsolidation(choiceOrNull(intVar), choiceOrNull(booleanVar))); - - PropertyInstanceConnectionGroup propertyInstanceConnectionGroup = - choiceOrNull( - connectionGroup( - choiceOrNull("host"), - "password", - choiceOrNull(intVar), - choiceOrNull(intVar), - choiceOrNull("tag"), - "user", - choiceOrNull(Arrays.asList(IProtoAuth.AuthType.values())), - propertyFlushConsolidationHandler)); - List propertyInstanceConnectionGroups = null; - if (propertyInstanceConnectionGroup != null) { - propertyInstanceConnectionGroups = new ArrayList<>(); - propertyInstanceConnectionGroups.add(propertyInstanceConnectionGroup); - } - - return tarantoolProperties( - choiceOrNull("host"), - choiceOrNull("password"), - choiceOrNull(intVar), - choiceOrNull("user"), - propertyInstanceConnectionGroups, - choiceOrNull(intVar), - choiceOrNull(booleanVar), - choiceOrNull(propertyHeartbeatOpts), - choiceOrNull(longVar), - choiceOrNull(longVar), - choiceOrNull(booleanVar), - choiceOrNull(booleanVar), - choiceOrNull(Arrays.asList(BalancerMode.values()))); - } - - @Nullable - public static T choiceOrNull(@Nullable T element) { - int rnd = random.nextInt(2); - if (rnd == 0 || element == null) { - return null; - } - return element; - } - - public static PropertyHeartbeatOpts heartbeat( - @Nullable Long pingInterval, - @Nullable Integer invalidationThreshold, - @Nullable Integer windowSize, - @Nullable Integer deathThreshold) { - - PropertyHeartbeatOpts propertyHeartbeatOpts = new PropertyHeartbeatOpts(); - if (invalidationThreshold != null) { - propertyHeartbeatOpts.setInvalidationThreshold(invalidationThreshold); - } - if (pingInterval != null) { - propertyHeartbeatOpts.setPingInterval(pingInterval); - } - if (deathThreshold != null) { - propertyHeartbeatOpts.setDeathThreshold(deathThreshold); - } - if (windowSize != null) { - propertyHeartbeatOpts.setWindowSize(windowSize); - } - - return propertyHeartbeatOpts; - } - - public static PropertyFlushConsolidationHandler flushConsolidation( - @Nullable Integer explicitFlushAfterFlushes, - @Nullable Boolean consolidateWhenNoReadInProgress) { - - PropertyFlushConsolidationHandler propertyFlushConsolidationHandler = - new PropertyFlushConsolidationHandler(); - if (explicitFlushAfterFlushes != null) { - propertyFlushConsolidationHandler.setExplicitFlushAfterFlushes(explicitFlushAfterFlushes); - } - - if (consolidateWhenNoReadInProgress != null) { - propertyFlushConsolidationHandler.setConsolidateWhenNoReadInProgress( - consolidateWhenNoReadInProgress); - } - return propertyFlushConsolidationHandler; - } - - @Nullable - public static T choiceOrNull(@Nullable List list) { - if (list == null || list.isEmpty()) { - return null; - } - int rnd = random.nextInt(list.size() + 1); - - if (rnd == list.size()) { - return null; - } - return list.get(rnd); - } - - @NonNull - public static PropertyInstanceConnectionGroup connectionGroup( - @Nullable String host, - @Nullable String password, - @Nullable Integer port, - @Nullable Integer connectionNumber, - @Nullable String tag, - @Nullable String user, - @Nullable IProtoAuth.AuthType type, - @Nullable PropertyFlushConsolidationHandler propertyFlushConsolidationHandler) { - - PropertyInstanceConnectionGroup propertyInstanceConnectionGroup = - new PropertyInstanceConnectionGroup(); - propertyInstanceConnectionGroup.setHost(host); - if (connectionNumber != null) { - propertyInstanceConnectionGroup.setConnectionGroupSize(connectionNumber); - } - propertyInstanceConnectionGroup.setAuthType(type); - propertyInstanceConnectionGroup.setPassword(password); - if (port != null) { - propertyInstanceConnectionGroup.setPort(port); - } - propertyInstanceConnectionGroup.setTag(tag); - propertyInstanceConnectionGroup.setUserName(user); - - propertyInstanceConnectionGroup.setFlushConsolidationHandler(propertyFlushConsolidationHandler); - return propertyInstanceConnectionGroup; - } - - @NonNull - public static TarantoolProperties tarantoolProperties( - @Nullable String host, - @Nullable String password, - @Nullable Integer port, - @Nullable String user, - @Nullable List propertyInstanceConnectionGroups, - @Nullable Integer eventLoopThreadsCount, - @Nullable Boolean enableGracefulShutdown, - @Nullable PropertyHeartbeatOpts propertyHeartbeatOptsOpts, - @Nullable Long connectTimeout, - @Nullable Long reconnectAfter, - @Nullable Boolean fetchSchema, - @Nullable Boolean ignoreOldSchemaVersion, - @Nullable BalancerMode balancerClass) { - - TarantoolProperties prop = new TarantoolProperties(); - prop.setHost(host); - prop.setPassword(password); - if (port != null) { - prop.setPort(port); - } - prop.setUserName(user); - prop.setConnectionGroups(propertyInstanceConnectionGroups); - if (eventLoopThreadsCount != null) { - prop.setEventLoopThreadsCount(eventLoopThreadsCount); - } - - if (enableGracefulShutdown != null) { - prop.setGracefulShutdownEnabled(enableGracefulShutdown); - } - prop.setHeartbeat(propertyHeartbeatOptsOpts); - if (connectTimeout != null) { - prop.setConnectTimeout(connectTimeout); - } - if (reconnectAfter != null) { - prop.setReconnectAfter(reconnectAfter); - } - if (fetchSchema != null) { - prop.setFetchSchema(fetchSchema); - } - if (ignoreOldSchemaVersion != null) { - prop.setIgnoreOldSchemaVersion(ignoreOldSchemaVersion); - } - prop.setBalancerMode(balancerClass); - return prop; - } - - public static List generatePersons(int count) { - List persons = new ArrayList<>(); - for (int i = 0; i < count; i++) { - persons.add(new Person(i, i % 3 == 0 ? null : i % 2 == 0, "User-" + i)); - } - return persons; - } - - public static List generatePersons(int count, Consumer actionAtPerson) { - List persons = generatePersons(count); - persons.forEach(actionAtPerson); - return persons; - } - - public static List generateComplexPersons(int count) { - List persons = new ArrayList<>(); - for (int i = 0; i < count; i++) { - persons.add( - new ComplexPerson(i, UUID.randomUUID(), i % 3 == 0 ? null : i % 2 == 0, "User-" + i)); - } - return persons; - } - - public static List generateComplexPersons( - int count, Consumer actionAtPerson) { - List persons = generateComplexPersons(count); - persons.forEach(actionAtPerson); - return persons; - } - - public static List generateAndInsertPersons(int count, TarantoolCrudClient client) { - final List persons = generatePersons(count); - final TarantoolCrudSpace space = client.space(PERSON_SPACE); - - List> insertedPersons = space.insertMany(persons, Person.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertPersons( - int count, TarantoolCrudClient client, Consumer action) { - final List persons = generatePersons(count, action); - final TarantoolCrudSpace space = client.space(PERSON_SPACE); - - List> insertedPersons = space.insertMany(persons, Person.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertComplexPersons( - int count, TarantoolCrudClient client) { - final List persons = generateComplexPersons(count); - final TarantoolCrudSpace space = client.space(COMPLEX_PERSON_SPACE); - - List> insertedPersons = - space.insertMany(persons, ComplexPerson.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } - - public static List generateAndInsertComplexPersons( - int count, TarantoolCrudClient client, Consumer action) { - - final List persons = generateComplexPersons(count, action); - final TarantoolCrudSpace space = client.space(COMPLEX_PERSON_SPACE); - - List> insertedPersons = - space.insertMany(persons, ComplexPerson.class).join().getRows(); - insertedPersons.sort(Comparator.comparing((p) -> p.get().getId())); - - assertEquals(persons, unwrapTuples(insertedPersons)); - - return persons; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/ComplexPersonListRepository.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/ComplexPersonListRepository.java deleted file mode 100644 index 116add00..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/ComplexPersonListRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.core; - -import org.springframework.data.repository.ListCrudRepository; - -import io.tarantool.spring.data.utils.GenericListRepositoryMethods; -import io.tarantool.spring.data35.utils.entity.ComplexPerson; -import io.tarantool.spring.data35.utils.entity.CompositePersonKey; - -public interface ComplexPersonListRepository - extends ListCrudRepository, - GenericListRepositoryMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/ComplexPersonRepository.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/ComplexPersonRepository.java deleted file mode 100644 index 9c0d5073..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/ComplexPersonRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.core; - -import org.springframework.data.repository.PagingAndSortingRepository; - -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data35.utils.entity.ComplexPerson; -import io.tarantool.spring.data35.utils.entity.CompositePersonKey; - -public interface ComplexPersonRepository - extends PagingAndSortingRepository, - GenericRepositoryMethods, - GenericPaginationMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/GenericPaginationMethods.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/GenericPaginationMethods.java deleted file mode 100644 index a400c701..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/GenericPaginationMethods.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.core; - -import java.util.List; - -import org.springframework.data.domain.Limit; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; - -public interface GenericPaginationMethods { - - Slice findAllByName(String name); - - Slice findAllByName(String name, Pageable pageable); - - Slice findAllByNameGreaterThanEqual(String name, Pageable pageable); - - Slice findAllByNameLessThanEqual(String name, Pageable pageable); - - Slice findAllByIdLessThanEqual(int id, Pageable pageable); - - Slice findAllByIdGreaterThanEqual(int id, Pageable pageable); - - Slice findAllByIsMarriedLessThanEqual(Boolean id, Pageable pageable); - - Slice findAllByIsMarriedGreaterThanEqual(Boolean id, Pageable pageable); - - Page findPersonByName(String name, Pageable pageable); - - Page findPersonByNameGreaterThanEqual(String name, Pageable pageable); - - Page findPersonByNameLessThanEqual(String name, Pageable pageable); - - Page findPersonByIdLessThanEqual(int id, Pageable pageable); - - Page findPersonByIdGreaterThanEqual(int id, Pageable pageable); - - Page findPersonByIsMarriedLessThanEqual(Boolean id, Pageable pageable); - - Page findPersonByIsMarriedGreaterThanEqual(Boolean id, Pageable pageable); - - Window findFirst5ByIsMarried(Boolean isMarried, ScrollPosition scrollPosition); - - Window findFirst10ByIsMarriedGreaterThanEqual( - Boolean isMarried, ScrollPosition scrollPosition); - - List findAll(Sort sort); - - Page findAll(Pageable pageable); - - List findAll(); - - List findPersonByIdGreaterThanEqual(int id, Limit limit); - - List findTop4ByIdGreaterThanEqual(int id, Limit limit); -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/PersonListRepository.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/PersonListRepository.java deleted file mode 100644 index 547f7d9d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/PersonListRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.core; - -import org.springframework.data.repository.ListCrudRepository; - -import io.tarantool.spring.data.utils.GenericListRepositoryMethods; -import io.tarantool.spring.data35.utils.entity.Person; - -public interface PersonListRepository - extends ListCrudRepository, GenericListRepositoryMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/PersonRepository.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/PersonRepository.java deleted file mode 100644 index 6d22822d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/core/PersonRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.core; - -import org.springframework.data.repository.PagingAndSortingRepository; - -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data35.utils.entity.Person; -import io.tarantool.spring.data35.utils.fragments.core.ReplaceManyFragment; - -public interface PersonRepository - extends PagingAndSortingRepository, - GenericRepositoryMethods, - GenericPaginationMethods, - ReplaceManyFragment {} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/ComplexPerson.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/ComplexPerson.java deleted file mode 100644 index ba4fecfb..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/ComplexPerson.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data35.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKey.class) -public class ComplexPerson implements GenericPerson { - - @Id - @Field("id") - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - protected Boolean isMarried; - - @Field("name") - @JsonProperty("name") - String name; - - @Override - public CompositePersonKey generateFullKey() { - return new CompositePersonKey(id, secondId); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/ComplexPersonWithIncorrectPK.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/ComplexPersonWithIncorrectPK.java deleted file mode 100644 index 2953b14e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/ComplexPersonWithIncorrectPK.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data35.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKeyWithoutJsonFormat.class) -public class ComplexPersonWithIncorrectPK { - - @Id - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/ComplexPersonWithJsonFormatVariantPK.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/ComplexPersonWithJsonFormatVariantPK.java deleted file mode 100644 index 55046625..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/ComplexPersonWithJsonFormatVariantPK.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data35.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKeyWithJsonFormat.class) -public class ComplexPersonWithJsonFormatVariantPK { - - @Id - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositeKeyWithWrongFieldCount.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositeKeyWithWrongFieldCount.java deleted file mode 100644 index 7e816eb7..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositeKeyWithWrongFieldCount.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -public class CompositeKeyWithWrongFieldCount implements CompositeKey { - - @JsonProperty("id") - private long id; -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositeKeyWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositeKeyWithWrongFieldTypes.java deleted file mode 100644 index dbdc7f20..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositeKeyWithWrongFieldTypes.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositeKeyWithWrongFieldTypes implements CompositeKey { - - @JsonProperty("id") - private long id; - - @JsonProperty("secondId") - private String secondId; - - @JsonProperty("thirdId") - private boolean thirdId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositePersonKey.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositePersonKey.java deleted file mode 100644 index 50c5efa6..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositePersonKey.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositePersonKey implements CompositeKey { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositePersonKeyWithJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositePersonKeyWithJsonFormat.java deleted file mode 100644 index b93f4dde..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositePersonKeyWithJsonFormat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -public class CompositePersonKeyWithJsonFormat { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositePersonKeyWithoutJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositePersonKeyWithoutJsonFormat.java deleted file mode 100644 index 3f9d7d98..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/CompositePersonKeyWithoutJsonFormat.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositePersonKeyWithoutJsonFormat { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/EntityWithAnnotationAsIdClass.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/EntityWithAnnotationAsIdClass.java deleted file mode 100644 index 2cc14a46..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/EntityWithAnnotationAsIdClass.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.entity; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@IdClass(IdClass.class) -public class EntityWithAnnotationAsIdClass {} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/EntityWithWrongCompositeKeyPartsCount.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/EntityWithWrongCompositeKeyPartsCount.java deleted file mode 100644 index 7bcc34a5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/EntityWithWrongCompositeKeyPartsCount.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@IdClass(CompositeKeyWithWrongFieldCount.class) -public class EntityWithWrongCompositeKeyPartsCount { - - @Id - @JsonProperty("id") - private long id; - - @Id - @JsonProperty("secondId") - private long secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/EntityWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/EntityWithWrongFieldTypes.java deleted file mode 100644 index f17cd636..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/EntityWithWrongFieldTypes.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@IdClass(CompositeKeyWithWrongFieldTypes.class) -public class EntityWithWrongFieldTypes { - - @Id - @JsonProperty("id") - private long id; - - @Id - @JsonProperty("secondId") - private String secondId; - - @Id - @JsonProperty("thirdId") - private int thirdId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/Person.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/Person.java deleted file mode 100644 index df6c372d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/entity/Person.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.entity; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data35.query.Field; - -/** - * @author Artyom Dubinin - */ -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("person") -public class Person implements GenericPerson { - - @Id - @Field("id") - @JsonProperty("id") - public Integer id; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; - - @Override - public Integer generateFullKey() { - return id; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/fragments/core/ReplaceManyFragment.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/fragments/core/ReplaceManyFragment.java deleted file mode 100644 index 066ccc25..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/fragments/core/ReplaceManyFragment.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.fragments.core; - -import java.util.List; - -public interface ReplaceManyFragment { - - List replaceMany(List tuples); -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/fragments/implementations/PersonReplaceManyFragment.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/fragments/implementations/PersonReplaceManyFragment.java deleted file mode 100644 index b31b338e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/utils/fragments/implementations/PersonReplaceManyFragment.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data35.utils.fragments.implementations; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.mapping.Tuple; -import io.tarantool.mapping.crud.CrudBatchResponse; -import io.tarantool.spring.data35.utils.entity.Person; -import io.tarantool.spring.data35.utils.fragments.core.ReplaceManyFragment; - -public class PersonReplaceManyFragment implements ReplaceManyFragment { - - private final TarantoolCrudClient client; - - public PersonReplaceManyFragment(TarantoolCrudClient client) { - this.client = client; - } - - @Override - public List replaceMany(List tuples) { - return getResults(this.client.space("person").replaceMany(tuples, Person.class)); - } - - private static List getResults( - CompletableFuture>>> tuples) { - return new ArrayList<>(tuples.join().getRows().stream().map(Tuple::get).toList()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/resources/META-INF/spring.factories b/tarantool-spring-data/tarantool-spring-data-35/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 8579575e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1 +0,0 @@ -io.tarantool.spring.data35.utils.fragments.core.ReplaceManyFragment=io.tarantool.spring.data35.utils.fragments.implementations.PersonReplaceManyFragment \ No newline at end of file diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/resources/application-crud-test.yaml b/tarantool-spring-data/tarantool-spring-data-35/src/test/resources/application-crud-test.yaml deleted file mode 100644 index 9bc8f9b2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/resources/application-crud-test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -spring: - data: - tarantool: - host: localhost - port: 3301 diff --git a/tarantool-spring-data/tarantool-spring-data-34/pom.xml b/tarantool-spring-data/tarantool-spring-data-4/pom.xml similarity index 76% rename from tarantool-spring-data/tarantool-spring-data-34/pom.xml rename to tarantool-spring-data/tarantool-spring-data-4/pom.xml index f6726874..636ae753 100644 --- a/tarantool-spring-data/tarantool-spring-data-34/pom.xml +++ b/tarantool-spring-data/tarantool-spring-data-4/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - tarantool-spring-data-34 + tarantool-spring-data-4 Minimalistic java connector for Tarantool versions 2.11+ based on Netty framework https://tarantool.io @@ -12,16 +12,16 @@ 2.0.0-SNAPSHOT - tarantool-spring-data-34 - 2.0.0-SNAPSHOT + tarantool-spring-data-4 jar - 17 - 17 - 3.4.13 + + 17 ${project.parent.parent.basedir}/tarantool-shared-resources/ ${project.parent.parent.basedir}/LICENSE_HEADER.txt + + 6.0.3 diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/TarantoolBoxKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/TarantoolBoxKeyValueAdapter.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/TarantoolBoxKeyValueAdapter.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/TarantoolBoxKeyValueAdapter.java index b95c4595..cb64cc6e 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/TarantoolBoxKeyValueAdapter.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/TarantoolBoxKeyValueAdapter.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40; +package io.tarantool.spring4.data; import java.util.Map; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/TarantoolCrudKeyValueAdapter.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/TarantoolCrudKeyValueAdapter.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/TarantoolCrudKeyValueAdapter.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/TarantoolCrudKeyValueAdapter.java index b404f940..74946b44 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/TarantoolCrudKeyValueAdapter.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/TarantoolCrudKeyValueAdapter.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40; +package io.tarantool.spring4.data; import java.util.Collections; import java.util.Map.Entry; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/TarantoolQueryEngine.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/TarantoolQueryEngine.java similarity index 93% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/TarantoolQueryEngine.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/TarantoolQueryEngine.java index 3d9ebab9..853c6cc2 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/TarantoolQueryEngine.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/TarantoolQueryEngine.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40; +package io.tarantool.spring4.data; import java.util.Collection; import java.util.Comparator; @@ -16,8 +16,8 @@ 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; +import io.tarantool.spring4.data.query.TarantoolCriteriaAccessor; +import io.tarantool.spring4.data.query.TarantoolSortAccessor; /** * Implementation of {@code findBy*()} and {@code countBy*{}} queries. diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/config/TarantoolBoxConfiguration.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/config/TarantoolBoxConfiguration.java similarity index 90% rename from tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/config/TarantoolBoxConfiguration.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/config/TarantoolBoxConfiguration.java index 7468810d..82046eb5 100644 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/config/TarantoolBoxConfiguration.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/config/TarantoolBoxConfiguration.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data27.config; +package io.tarantool.spring4.data.config; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -15,8 +15,8 @@ import io.tarantool.client.box.TarantoolBoxClient; import io.tarantool.client.factory.TarantoolBoxClientBuilder; import io.tarantool.spring.data.config.BaseTarantoolBoxConfiguration; -import io.tarantool.spring.data27.TarantoolBoxKeyValueAdapter; -import io.tarantool.spring.data27.config.properties.TarantoolProperties; +import io.tarantool.spring4.data.TarantoolBoxKeyValueAdapter; +import io.tarantool.spring4.data.config.properties.TarantoolProperties; @Configuration(proxyBeanMethods = false) public class TarantoolBoxConfiguration extends BaseTarantoolBoxConfiguration { diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/config/TarantoolCrudConfiguration.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/config/TarantoolCrudConfiguration.java similarity index 90% rename from tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/config/TarantoolCrudConfiguration.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/config/TarantoolCrudConfiguration.java index 617e9d10..81ffa252 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/config/TarantoolCrudConfiguration.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/config/TarantoolCrudConfiguration.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.config; +package io.tarantool.spring4.data.config; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -15,8 +15,8 @@ import io.tarantool.client.crud.TarantoolCrudClient; import io.tarantool.client.factory.TarantoolCrudClientBuilder; import io.tarantool.spring.data.config.BaseTarantoolCrudConfiguration; -import io.tarantool.spring.data32.TarantoolCrudKeyValueAdapter; -import io.tarantool.spring.data32.config.properties.TarantoolProperties; +import io.tarantool.spring4.data.TarantoolCrudKeyValueAdapter; +import io.tarantool.spring4.data.config.properties.TarantoolProperties; @Configuration(proxyBeanMethods = false) public class TarantoolCrudConfiguration extends BaseTarantoolCrudConfiguration { diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/config/package-info.java similarity index 58% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/config/package-info.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/config/package-info.java index 148b43d6..df648faa 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/config/package-info.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/config/package-info.java @@ -1,3 +1,3 @@ /** Config package. */ @org.jspecify.annotations.NullMarked -package io.tarantool.spring.data40.config; +package io.tarantool.spring4.data.config; diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/config/properties/TarantoolProperties.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/config/properties/TarantoolProperties.java similarity index 90% rename from tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/config/properties/TarantoolProperties.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/config/properties/TarantoolProperties.java index a14e09c6..e97b1fa1 100644 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/config/properties/TarantoolProperties.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/config/properties/TarantoolProperties.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data27.config.properties; +package io.tarantool.spring4.data.config.properties; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/TarantoolTemplate.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/TarantoolTemplate.java similarity index 91% rename from tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/TarantoolTemplate.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/TarantoolTemplate.java index 5529267f..bcf85f7c 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/TarantoolTemplate.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/TarantoolTemplate.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.core; +package io.tarantool.spring4.data.core; import org.springframework.data.keyvalue.core.IdentifierGenerator; import org.springframework.data.keyvalue.core.KeyValueAdapter; @@ -15,8 +15,8 @@ import org.springframework.data.mapping.context.MappingContext; import org.springframework.util.ClassUtils; -import io.tarantool.spring.data31.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data31.core.mapping.TarantoolMappingContext; +import io.tarantool.spring4.data.core.annotation.DefaultIdClassResolver; +import io.tarantool.spring4.data.core.mapping.TarantoolMappingContext; public class TarantoolTemplate extends KeyValueTemplate { diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/annotation/DefaultIdClassResolver.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/annotation/DefaultIdClassResolver.java similarity index 95% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/annotation/DefaultIdClassResolver.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/annotation/DefaultIdClassResolver.java index d9484191..91fbdb3e 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/annotation/DefaultIdClassResolver.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/annotation/DefaultIdClassResolver.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.core.annotation; +package io.tarantool.spring4.data.core.annotation; import org.jspecify.annotations.Nullable; import org.springframework.core.annotation.AnnotatedElementUtils; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/annotation/package-info.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/annotation/package-info.java similarity index 60% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/annotation/package-info.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/annotation/package-info.java index 0820747b..2d688d8b 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/annotation/package-info.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/annotation/package-info.java @@ -1,3 +1,3 @@ /** Core annotations of data mapping. */ @org.jspecify.annotations.NullMarked -package io.tarantool.spring.data40.core.annotation; +package io.tarantool.spring4.data.core.annotation; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/BasicKeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/BasicKeyValueCompositePersistentEntity.java similarity index 96% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/BasicKeyValueCompositePersistentEntity.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/BasicKeyValueCompositePersistentEntity.java index 2944c5b8..c201d3b7 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/BasicKeyValueCompositePersistentEntity.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/BasicKeyValueCompositePersistentEntity.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.core.mapping; +package io.tarantool.spring4.data.core.mapping; import java.lang.reflect.Field; import java.util.HashMap; @@ -22,8 +22,8 @@ import io.tarantool.spring.data.core.annotation.IdClass; import io.tarantool.spring.data.mapping.model.CompositeKey; -import io.tarantool.spring.data40.core.mapping.model.CompositeIdPropertyAccessor; -import io.tarantool.spring.data40.core.mapping.model.PersistentCompositeIdIsNewStrategy; +import io.tarantool.spring4.data.core.mapping.model.CompositeIdPropertyAccessor; +import io.tarantool.spring4.data.core.mapping.model.PersistentCompositeIdIsNewStrategy; public class BasicKeyValueCompositePersistentEntity> extends BasicKeyValuePersistentEntity implements KeyValueCompositePersistentEntity { diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/Identifier.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/Identifier.java similarity index 95% rename from tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/Identifier.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/Identifier.java index b57d7dbe..31714966 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/Identifier.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/Identifier.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.core.mapping; +package io.tarantool.spring4.data.core.mapping; import java.lang.reflect.Field; import java.util.Collection; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/KeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/KeyValueCompositePersistentEntity.java similarity index 96% rename from tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/KeyValueCompositePersistentEntity.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/KeyValueCompositePersistentEntity.java index 8a5ab2e9..154c42ae 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/KeyValueCompositePersistentEntity.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/KeyValueCompositePersistentEntity.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.core.mapping; +package io.tarantool.spring4.data.core.mapping; import java.lang.reflect.Field; import java.util.ArrayList; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/KeyValueCompositeProperty.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/KeyValueCompositeProperty.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/KeyValueCompositeProperty.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/KeyValueCompositeProperty.java index 8662fd71..d8c9304b 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/core/mapping/KeyValueCompositeProperty.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/KeyValueCompositeProperty.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.core.mapping; +package io.tarantool.spring4.data.core.mapping; import java.lang.reflect.Field; import java.util.ArrayList; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/TarantoolMappingContext.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/TarantoolMappingContext.java similarity index 94% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/TarantoolMappingContext.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/TarantoolMappingContext.java index a72deb74..16e402f4 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/TarantoolMappingContext.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/TarantoolMappingContext.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.core.mapping; +package io.tarantool.spring4.data.core.mapping; import org.jspecify.annotations.Nullable; import org.springframework.data.core.TypeInformation; @@ -16,7 +16,7 @@ import org.springframework.data.mapping.model.SimpleTypeHolder; import io.tarantool.spring.data.core.annotation.IdClassResolver; -import io.tarantool.spring.data40.core.annotation.DefaultIdClassResolver; +import io.tarantool.spring4.data.core.annotation.DefaultIdClassResolver; public class TarantoolMappingContext< E extends KeyValuePersistentEntity, P extends KeyValuePersistentProperty

> diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/model/CompositeIdPropertyAccessor.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/model/CompositeIdPropertyAccessor.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/model/CompositeIdPropertyAccessor.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/model/CompositeIdPropertyAccessor.java index 22354a1d..5af3800d 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/model/CompositeIdPropertyAccessor.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/model/CompositeIdPropertyAccessor.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.core.mapping.model; +package io.tarantool.spring4.data.core.mapping.model; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/model/PersistentCompositeIdIsNewStrategy.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/model/PersistentCompositeIdIsNewStrategy.java similarity index 97% rename from tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/model/PersistentCompositeIdIsNewStrategy.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/model/PersistentCompositeIdIsNewStrategy.java index dce709c4..f6bf774b 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/core/mapping/model/PersistentCompositeIdIsNewStrategy.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/model/PersistentCompositeIdIsNewStrategy.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.core.mapping.model; +package io.tarantool.spring4.data.core.mapping.model; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.support.IsNewStrategy; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/model/package-info.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/model/package-info.java similarity index 64% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/model/package-info.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/model/package-info.java index 87e03087..e5bc01e4 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/model/package-info.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/model/package-info.java @@ -1,3 +1,3 @@ /** Core implementation of the mapping subsystem's model. */ @org.jspecify.annotations.NullMarked -package io.tarantool.spring.data40.core.mapping.model; +package io.tarantool.spring4.data.core.mapping.model; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/package-info.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/package-info.java similarity index 63% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/package-info.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/package-info.java index bf6f8318..883d115b 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/package-info.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/mapping/package-info.java @@ -1,3 +1,3 @@ /** Base package for the mapping subsystem. */ @org.jspecify.annotations.NullMarked -package io.tarantool.spring.data40.core.mapping; +package io.tarantool.spring4.data.core.mapping; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/package-info.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/package-info.java similarity index 79% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/package-info.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/package-info.java index 7d651c8c..af6d8ac4 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/package-info.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/core/package-info.java @@ -3,4 +3,4 @@ * concepts. */ @org.jspecify.annotations.NullMarked -package io.tarantool.spring.data40.core; +package io.tarantool.spring4.data.core; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/Field.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/Field.java similarity index 96% rename from tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/Field.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/Field.java index 95896946..b2d7844f 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/Field.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/Field.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.query; +package io.tarantool.spring4.data.query; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/PaginationUtils.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/PaginationUtils.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/PaginationUtils.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/PaginationUtils.java index 2747ffb7..46992436 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/PaginationUtils.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/PaginationUtils.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.query; +package io.tarantool.spring4.data.query; import java.util.List; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolChunk.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolChunk.java similarity index 99% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolChunk.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolChunk.java index 2cec81df..e60a8588 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolChunk.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolChunk.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import java.io.Serial; import java.io.Serializable; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolCriteriaAccessor.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolCriteriaAccessor.java similarity index 94% rename from tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolCriteriaAccessor.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolCriteriaAccessor.java index 9785045f..fac31f69 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/query/TarantoolCriteriaAccessor.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolCriteriaAccessor.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.query; +package io.tarantool.spring4.data.query; import org.springframework.data.keyvalue.core.CriteriaAccessor; import org.springframework.data.keyvalue.core.query.KeyValueQuery; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolKeysetScrollPosition.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolKeysetScrollPosition.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolKeysetScrollPosition.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolKeysetScrollPosition.java index 63b7e1af..df287234 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolKeysetScrollPosition.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolKeysetScrollPosition.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import java.util.List; import java.util.Objects; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolPageImpl.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolPageImpl.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolPageImpl.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolPageImpl.java index 53939a58..c7730072 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolPageImpl.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolPageImpl.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import java.io.Serial; import java.util.Collections; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolPageRequest.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolPageRequest.java similarity index 99% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolPageRequest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolPageRequest.java index bfab9e62..eae69669 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolPageRequest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolPageRequest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import java.io.Serial; import java.util.Objects; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolPageable.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolPageable.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolPageable.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolPageable.java index 4c1ee813..4eb255bb 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolPageable.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolPageable.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolPartTreeQuery.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolPartTreeQuery.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolPartTreeQuery.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolPartTreeQuery.java index 350a7f9e..2c073109 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolPartTreeQuery.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolPartTreeQuery.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import java.util.ArrayList; import java.util.Collections; @@ -37,8 +37,8 @@ import static io.tarantool.client.crud.ConditionOperator.GREATER_EQ; import static io.tarantool.client.crud.ConditionOperator.LESS_EQ; import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import static io.tarantool.spring.data40.query.PaginationUtils.doPageQuery; -import static io.tarantool.spring.data40.query.PaginationUtils.doPaginationQuery; +import static io.tarantool.spring4.data.query.PaginationUtils.doPageQuery; +import static io.tarantool.spring4.data.query.PaginationUtils.doPaginationQuery; import io.tarantool.client.crud.Condition; import io.tarantool.client.crud.options.SelectOptions; import io.tarantool.spring.data.query.PaginationDirection; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolQueryCreator.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolQueryCreator.java similarity index 99% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolQueryCreator.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolQueryCreator.java index 71c09aff..a44c3e2a 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolQueryCreator.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolQueryCreator.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import java.util.Iterator; import java.util.Map; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolQueryMethodImpl.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolQueryMethodImpl.java similarity index 96% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolQueryMethodImpl.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolQueryMethodImpl.java index ec95242c..635781a0 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolQueryMethodImpl.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolQueryMethodImpl.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import java.lang.reflect.Method; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolRepositoryQuery.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolRepositoryQuery.java similarity index 96% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolRepositoryQuery.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolRepositoryQuery.java index b26ca5ca..52b8ff4c 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolRepositoryQuery.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolRepositoryQuery.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import org.jspecify.annotations.NonNull; import org.springframework.data.repository.query.QueryMethod; diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolScrollPosition.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolScrollPosition.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolScrollPosition.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolScrollPosition.java index fe15a3e1..106a0ff8 100644 --- a/tarantool-spring-data/tarantool-spring-data-33/src/main/java/io/tarantool/spring/data33/query/TarantoolScrollPosition.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolScrollPosition.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data33.query; +package io.tarantool.spring4.data.query; import org.springframework.data.domain.ScrollPosition; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolSliceImpl.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolSliceImpl.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolSliceImpl.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolSliceImpl.java index 49834a93..f0a52c42 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolSliceImpl.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolSliceImpl.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import java.io.Serial; import java.util.Collections; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolSortAccessor.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolSortAccessor.java similarity index 96% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolSortAccessor.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolSortAccessor.java index b9a6d382..b278ddcb 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolSortAccessor.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolSortAccessor.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import java.util.Comparator; import java.util.Map.Entry; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolWindowIterator.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolWindowIterator.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolWindowIterator.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolWindowIterator.java index 304077bf..dafd38de 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolWindowIterator.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/query/TarantoolWindowIterator.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import java.util.Iterator; import java.util.NoSuchElementException; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/TarantoolRepositoryFactory.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/TarantoolRepositoryFactory.java similarity index 91% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/TarantoolRepositoryFactory.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/TarantoolRepositoryFactory.java index 54f7381d..bf3c63e5 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/TarantoolRepositoryFactory.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/TarantoolRepositoryFactory.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.repository; +package io.tarantool.spring4.data.repository; import java.util.Optional; @@ -16,9 +16,9 @@ import org.springframework.data.repository.query.parser.AbstractQueryCreator; import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data40.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data40.repository.config.TarantoolQueryLookupStrategy; -import io.tarantool.spring.data40.repository.support.TarantoolSimpleRepository; +import io.tarantool.spring4.data.query.TarantoolPartTreeQuery; +import io.tarantool.spring4.data.repository.config.TarantoolQueryLookupStrategy; +import io.tarantool.spring4.data.repository.support.TarantoolSimpleRepository; /** * Tarantool version of {@link KeyValueRepositoryFactory}, a factory to build tarantool repository diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/EnableTarantoolRepositories.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/EnableTarantoolRepositories.java similarity index 94% rename from tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/EnableTarantoolRepositories.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/EnableTarantoolRepositories.java index 09c7807b..5e2de3ff 100644 --- a/tarantool-spring-data/tarantool-spring-data-27/src/main/java/io/tarantool/spring/data27/repository/config/EnableTarantoolRepositories.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/EnableTarantoolRepositories.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data27.repository.config; +package io.tarantool.spring4.data.repository.config; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -23,9 +23,9 @@ import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; import io.tarantool.client.ClientType; -import io.tarantool.spring.data27.config.properties.TarantoolProperties; -import io.tarantool.spring.data27.query.TarantoolQueryCreator; -import io.tarantool.spring.data27.repository.support.TarantoolRepositoryFactoryBean; +import io.tarantool.spring4.data.config.properties.TarantoolProperties; +import io.tarantool.spring4.data.query.TarantoolQueryCreator; +import io.tarantool.spring4.data.repository.support.TarantoolRepositoryFactoryBean; @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/TarantoolQueryLookupStrategy.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/TarantoolQueryLookupStrategy.java similarity index 92% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/TarantoolQueryLookupStrategy.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/TarantoolQueryLookupStrategy.java index c7e8fa56..f1b25c13 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/TarantoolQueryLookupStrategy.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/TarantoolQueryLookupStrategy.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.repository.config; +package io.tarantool.spring4.data.repository.config; import java.lang.reflect.Method; @@ -19,9 +19,9 @@ import org.springframework.util.Assert; import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data40.query.TarantoolPartTreeQuery; -import io.tarantool.spring.data40.query.TarantoolQueryMethodImpl; -import io.tarantool.spring.data40.query.TarantoolRepositoryQuery; +import io.tarantool.spring4.data.query.TarantoolPartTreeQuery; +import io.tarantool.spring4.data.query.TarantoolQueryMethodImpl; +import io.tarantool.spring4.data.query.TarantoolRepositoryQuery; /** * Ensures {@link TarantoolPartTreeQuery} is used for query preparation rather than {@link diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/TarantoolRepositoriesRegistrar.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/TarantoolRepositoriesRegistrar.java similarity index 94% rename from tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/TarantoolRepositoriesRegistrar.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/TarantoolRepositoriesRegistrar.java index 26d06bea..ab6da06d 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/TarantoolRepositoriesRegistrar.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/TarantoolRepositoriesRegistrar.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.repository.config; +package io.tarantool.spring4.data.repository.config; import java.lang.annotation.Annotation; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/TarantoolRepositoryConfigurationExtension.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/TarantoolRepositoryConfigurationExtension.java similarity index 94% rename from tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/TarantoolRepositoryConfigurationExtension.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/TarantoolRepositoryConfigurationExtension.java index 340b2e2e..16a135c9 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/config/TarantoolRepositoryConfigurationExtension.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/TarantoolRepositoryConfigurationExtension.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.repository.config; +package io.tarantool.spring4.data.repository.config; import org.springframework.beans.factory.config.ConstructorArgumentValues; import org.springframework.beans.factory.config.RuntimeBeanReference; @@ -16,9 +16,9 @@ import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; import io.tarantool.client.ClientType; -import io.tarantool.spring.data32.config.TarantoolCrudConfiguration; -import io.tarantool.spring.data32.core.TarantoolTemplate; -import io.tarantool.spring.data32.core.mapping.TarantoolMappingContext; +import io.tarantool.spring4.data.config.TarantoolCrudConfiguration; +import io.tarantool.spring4.data.core.TarantoolTemplate; +import io.tarantool.spring4.data.core.mapping.TarantoolMappingContext; public class TarantoolRepositoryConfigurationExtension extends KeyValueRepositoryConfigurationExtension { diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/package-info.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/package-info.java similarity index 56% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/package-info.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/package-info.java index 20682071..c37e2fd0 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/package-info.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/config/package-info.java @@ -1,3 +1,3 @@ /** Repository config package. */ @org.jspecify.annotations.NullMarked -package io.tarantool.spring.data40.repository.config; +package io.tarantool.spring4.data.repository.config; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/package-info.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/package-info.java similarity index 57% rename from tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/package-info.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/package-info.java index 29226478..f03d062b 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/package-info.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/package-info.java @@ -1,3 +1,3 @@ /** Repository package. */ @org.jspecify.annotations.NullMarked -package io.tarantool.spring.data40.repository; +package io.tarantool.spring4.data.repository; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/support/TarantoolRepositoryFactoryBean.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/support/TarantoolRepositoryFactoryBean.java similarity index 93% rename from tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/support/TarantoolRepositoryFactoryBean.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/support/TarantoolRepositoryFactoryBean.java index fcbc38cc..9179b914 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/support/TarantoolRepositoryFactoryBean.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/support/TarantoolRepositoryFactoryBean.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.repository.support; +package io.tarantool.spring4.data.repository.support; import java.io.Serializable; @@ -16,7 +16,7 @@ import org.springframework.data.repository.query.parser.AbstractQueryCreator; import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data32.repository.TarantoolRepositoryFactory; +import io.tarantool.spring4.data.repository.TarantoolRepositoryFactory; public class TarantoolRepositoryFactoryBean, S, ID extends Serializable> extends KeyValueRepositoryFactoryBean { diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/support/TarantoolSimpleRepository.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/support/TarantoolSimpleRepository.java similarity index 94% rename from tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/support/TarantoolSimpleRepository.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/support/TarantoolSimpleRepository.java index fb5e4bed..353bc32c 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/main/java/io/tarantool/spring/data32/repository/support/TarantoolSimpleRepository.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/support/TarantoolSimpleRepository.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.repository.support; +package io.tarantool.spring4.data.repository.support; import java.util.List; @@ -16,7 +16,7 @@ import org.springframework.data.repository.core.EntityInformation; import org.springframework.util.Assert; -import static io.tarantool.spring.data32.query.PaginationUtils.doPageQuery; +import static io.tarantool.spring4.data.query.PaginationUtils.doPageQuery; import io.tarantool.spring.data.query.TarantoolCriteria; public class TarantoolSimpleRepository extends SimpleKeyValueRepository { diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/support/package-info.java b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/support/package-info.java similarity index 56% rename from tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/support/package-info.java rename to tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/support/package-info.java index 989d6cbf..aa6ca3d3 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/main/java/io/tarantool/spring/data31/repository/support/package-info.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/main/java/io/tarantool/spring4/data/repository/support/package-info.java @@ -1,3 +1,3 @@ /** Repository support package. */ @org.springframework.lang.NonNullApi -package io.tarantool.spring.data31.repository.support; +package io.tarantool.spring4.data.repository.support; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/GenericTarantoolConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/GenericTarantoolConfigurationTest.java similarity index 89% rename from tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/GenericTarantoolConfigurationTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/GenericTarantoolConfigurationTest.java index 9643191b..139ff799 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/GenericTarantoolConfigurationTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/GenericTarantoolConfigurationTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.config; +package io.tarantool.spring4.data.config; import java.io.IOException; import java.nio.file.Files; @@ -18,8 +18,8 @@ import org.springframework.test.context.TestPropertySource; import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data40.config.properties.TarantoolProperties; -import io.tarantool.spring.data40.utils.TarantoolTestSupport; +import io.tarantool.spring4.data.config.properties.TarantoolProperties; +import io.tarantool.spring4.data.utils.TarantoolTestSupport; @TestPropertySource(properties = {Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) public abstract class GenericTarantoolConfigurationTest implements ApplicationContextAware { diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/TarantoolBoxConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/TarantoolBoxConfigurationTest.java similarity index 96% rename from tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/TarantoolBoxConfigurationTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/TarantoolBoxConfigurationTest.java index e7aa96d3..94fcf6da 100644 --- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/config/TarantoolBoxConfigurationTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/TarantoolBoxConfigurationTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data35.config; +package io.tarantool.spring4.data.config; import java.io.IOException; import java.util.List; @@ -26,8 +26,8 @@ import io.tarantool.pool.HeartbeatOpts; import io.tarantool.pool.InstanceConnectionGroup; import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data35.config.properties.TarantoolProperties; -import io.tarantool.spring.data35.utils.TarantoolTestSupport; +import io.tarantool.spring4.data.config.properties.TarantoolProperties; +import io.tarantool.spring4.data.utils.TarantoolTestSupport; @SpringBootTest(classes = {TarantoolBoxConfigurationTest.Config.class}) public class TarantoolBoxConfigurationTest extends GenericTarantoolConfigurationTest { diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/TarantoolCrudConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/TarantoolCrudConfigurationTest.java similarity index 96% rename from tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/TarantoolCrudConfigurationTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/TarantoolCrudConfigurationTest.java index 66171a95..a4496bea 100644 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/TarantoolCrudConfigurationTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/TarantoolCrudConfigurationTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data34.config; +package io.tarantool.spring4.data.config; import java.io.IOException; import java.util.Arrays; @@ -23,14 +23,14 @@ import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.writeTestPropertiesYaml; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.writeTestPropertiesYaml; import io.tarantool.client.crud.TarantoolCrudClient; import io.tarantool.client.factory.TarantoolCrudClientBuilder; import io.tarantool.pool.HeartbeatOpts; import io.tarantool.pool.InstanceConnectionGroup; import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyHeartbeatOpts; import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.spring.data34.repository.config.EnableTarantoolRepositories; +import io.tarantool.spring4.data.repository.config.EnableTarantoolRepositories; @SpringBootTest(classes = {TarantoolCrudConfigurationTest.Config.class}) public class TarantoolCrudConfigurationTest extends GenericTarantoolConfigurationTest { diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/TarantoolEmptyPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/TarantoolEmptyPropertiesTest.java similarity index 86% rename from tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/TarantoolEmptyPropertiesTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/TarantoolEmptyPropertiesTest.java index c54c905e..268f9b82 100644 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/config/TarantoolEmptyPropertiesTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/TarantoolEmptyPropertiesTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data33.config; +package io.tarantool.spring4.data.config; import java.io.IOException; import java.nio.file.Files; @@ -18,9 +18,9 @@ import org.springframework.test.context.TestPropertySource; import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data33.config.properties.TarantoolProperties; -import io.tarantool.spring.data33.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data33.utils.TarantoolTestSupport; +import io.tarantool.spring4.data.config.properties.TarantoolProperties; +import io.tarantool.spring4.data.repository.config.EnableTarantoolRepositories; +import io.tarantool.spring4.data.utils.TarantoolTestSupport; /** * @see TarantoolPropertiesTest diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/TarantoolPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/TarantoolPropertiesTest.java similarity index 92% rename from tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/TarantoolPropertiesTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/TarantoolPropertiesTest.java index 44522094..7be6c991 100644 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/config/TarantoolPropertiesTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/config/TarantoolPropertiesTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data34.config; +package io.tarantool.spring4.data.config; import java.io.IOException; import java.nio.file.Files; @@ -22,9 +22,9 @@ import io.tarantool.client.crud.TarantoolCrudClient; import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data34.config.properties.TarantoolProperties; -import io.tarantool.spring.data34.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data34.utils.TarantoolTestSupport; +import io.tarantool.spring4.data.config.properties.TarantoolProperties; +import io.tarantool.spring4.data.repository.config.EnableTarantoolRepositories; +import io.tarantool.spring4.data.utils.TarantoolTestSupport; /** * The test checks whether the Spring framework parses a file with the specified properties diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/core/annotation/IdClassResolverTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/annotation/IdClassResolverTest.java similarity index 83% rename from tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/core/annotation/IdClassResolverTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/annotation/IdClassResolverTest.java index 48d07933..ee787e05 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/core/annotation/IdClassResolverTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/annotation/IdClassResolverTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.core.annotation; +package io.tarantool.spring4.data.core.annotation; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -11,10 +11,10 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; -import io.tarantool.spring.data40.utils.entity.ComplexPerson; -import io.tarantool.spring.data40.utils.entity.CompositePersonKey; -import io.tarantool.spring.data40.utils.entity.EntityWithAnnotationAsIdClass; -import io.tarantool.spring.data40.utils.entity.Person; +import io.tarantool.spring4.data.utils.entity.ComplexPerson; +import io.tarantool.spring4.data.utils.entity.CompositePersonKey; +import io.tarantool.spring4.data.utils.entity.EntityWithAnnotationAsIdClass; +import io.tarantool.spring4.data.utils.entity.Person; @Timeout(5) class IdClassResolverTest { diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/core/mapping/KeyValueCompositePropertyTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/mapping/KeyValueCompositePropertyTest.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/core/mapping/KeyValueCompositePropertyTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/mapping/KeyValueCompositePropertyTest.java index bbab4eb9..8bd0ce04 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/core/mapping/KeyValueCompositePropertyTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/mapping/KeyValueCompositePropertyTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.core.mapping; +package io.tarantool.spring4.data.core.mapping; import java.lang.reflect.Field; import java.util.Arrays; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/core/mapping/TarantoolMappingContextTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/mapping/TarantoolMappingContextTest.java similarity index 85% rename from tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/core/mapping/TarantoolMappingContextTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/mapping/TarantoolMappingContextTest.java index 501f1cae..0f6af295 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/core/mapping/TarantoolMappingContextTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/mapping/TarantoolMappingContextTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.core.mapping; +package io.tarantool.spring4.data.core.mapping; import java.lang.reflect.Field; import java.util.HashSet; @@ -34,11 +34,12 @@ import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; -import io.tarantool.spring.data40.core.mapping.BasicKeyValueCompositePersistentEntity.KeyPartTypeChecker; -import io.tarantool.spring.data40.utils.entity.ComplexPerson; -import io.tarantool.spring.data40.utils.entity.EntityWithWrongCompositeKeyPartsCount; -import io.tarantool.spring.data40.utils.entity.EntityWithWrongFieldTypes; -import io.tarantool.spring.data40.utils.entity.Person; +import io.tarantool.spring4.data.core.mapping.BasicKeyValueCompositePersistentEntity.KeyPartTypeChecker; +import io.tarantool.spring4.data.utils.entity.ComplexPerson; +import io.tarantool.spring4.data.utils.entity.EntityWithInvalidKeyFieldsOrder; +import io.tarantool.spring4.data.utils.entity.EntityWithWrongCompositeKeyPartsCount; +import io.tarantool.spring4.data.utils.entity.EntityWithWrongFieldTypes; +import io.tarantool.spring4.data.utils.entity.Person; class TarantoolMappingContextTest { @@ -115,6 +116,21 @@ void testCreateEntityWithWrongCompositeKeyPartCount() { assertEquals(KeyPartTypeChecker.COMPOSITE_KEY_FIELDS_NUMBER_EXCEPTION, cause.getMessage()); } + @Test + void testCreateEntityWithCompositeKeyFieldsInvalidOrder() { + Set> initialSet = + new HashSet<>() { + { + add(EntityWithInvalidKeyFieldsOrder.class); + } + }; + MappingException exception = + assertThrows(MappingException.class, () -> initEntities(initialSet)); + final Throwable cause = exception.getCause(); + Assertions.assertInstanceOf(IllegalArgumentException.class, cause); + assertEquals(KeyPartTypeChecker.COMPOSITE_KEY_FIELD_DIFFERENT_EXCEPTION, cause.getMessage()); + } + /** * Create a mappingContext from the passed domain classes. After initialize - create for them * PersistentEntities and add PersistentProperties to them. diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/mapping/model/CompositeIdPropertyAccessorTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/mapping/model/CompositeIdPropertyAccessorTest.java similarity index 86% rename from tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/mapping/model/CompositeIdPropertyAccessorTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/mapping/model/CompositeIdPropertyAccessorTest.java index 018f433d..28e2d758 100644 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/core/mapping/model/CompositeIdPropertyAccessorTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/mapping/model/CompositeIdPropertyAccessorTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data27.core.mapping.model; +package io.tarantool.spring4.data.core.mapping.model; import java.util.HashSet; import java.util.Set; @@ -17,9 +17,9 @@ import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.context.AbstractMappingContext; -import io.tarantool.spring.data27.core.mapping.TarantoolMappingContext; -import io.tarantool.spring.data27.utils.entity.ComplexPerson; -import io.tarantool.spring.data27.utils.entity.CompositePersonKey; +import io.tarantool.spring4.data.core.mapping.TarantoolMappingContext; +import io.tarantool.spring4.data.utils.entity.ComplexPerson; +import io.tarantool.spring4.data.utils.entity.CompositePersonKey; class CompositeIdPropertyAccessorTest { diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java similarity index 87% rename from tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java index c14be221..62a0fc19 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/core/mapping/model/PersistentCompositeIdIsNewStrategyTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.core.mapping.model; +package io.tarantool.spring4.data.core.mapping.model; import java.lang.reflect.Field; @@ -15,10 +15,10 @@ import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.util.ReflectionUtils; -import io.tarantool.spring.data40.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data40.core.mapping.BasicKeyValueCompositePersistentEntity; -import io.tarantool.spring.data40.core.mapping.KeyValueCompositeProperty; -import io.tarantool.spring.data40.utils.entity.ComplexPerson; +import io.tarantool.spring4.data.core.annotation.DefaultIdClassResolver; +import io.tarantool.spring4.data.core.mapping.BasicKeyValueCompositePersistentEntity; +import io.tarantool.spring4.data.core.mapping.KeyValueCompositeProperty; +import io.tarantool.spring4.data.utils.entity.ComplexPerson; public class PersistentCompositeIdIsNewStrategyTest

> { diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/BaseIntegrationTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/BaseIntegrationTest.java similarity index 91% rename from tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/BaseIntegrationTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/BaseIntegrationTest.java index 8f125f66..1e007836 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/BaseIntegrationTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/BaseIntegrationTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.integration; +package io.tarantool.spring4.data.integration; import java.io.IOException; import java.nio.file.Files; @@ -19,9 +19,9 @@ import org.testcontainers.containers.output.Slf4jLogConsumer; import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.spring.data32.config.properties.TarantoolProperties; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.writeTestPropertiesYaml; +import io.tarantool.spring4.data.config.properties.TarantoolProperties; @Timeout(60) public abstract class BaseIntegrationTest { diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/CrudConfigurations.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/CrudConfigurations.java similarity index 87% rename from tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/CrudConfigurations.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/CrudConfigurations.java index 3c439926..3098ae5c 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/CrudConfigurations.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/CrudConfigurations.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.integration.crud; +package io.tarantool.spring4.data.integration.crud; import java.io.IOException; import java.util.Arrays; @@ -21,15 +21,15 @@ import static io.tarantool.client.TarantoolClient.DEFAULT_TAG; import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data31.utils.TarantoolTestSupport.PERSON_SPACE; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.PERSON_SPACE; import io.tarantool.client.crud.TarantoolCrudClient; import io.tarantool.client.crud.TarantoolCrudSpace; import io.tarantool.client.factory.TarantoolCrudClientBuilder; import io.tarantool.client.factory.TarantoolFactory; import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data31.integration.BaseIntegrationTest; -import io.tarantool.spring.data31.repository.config.EnableTarantoolRepositories; +import io.tarantool.spring4.data.integration.BaseIntegrationTest; +import io.tarantool.spring4.data.repository.config.EnableTarantoolRepositories; @TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) abstract class CrudConfigurations extends BaseIntegrationTest { @@ -38,7 +38,7 @@ abstract class CrudConfigurations extends BaseIntegrationTest { private static InstanceConnectionGroup groupFromJavaConfig; - private static final String PACKAGE_PATH = "io.tarantool.spring.data31.utils.core"; + private static final String PACKAGE_PATH = "io.tarantool.spring4.data.utils.core"; @BeforeAll protected static void beforeAll() throws IOException { diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/GenericRepositoryTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/GenericRepositoryTest.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/GenericRepositoryTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/GenericRepositoryTest.java index db582e30..435692bb 100644 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/GenericRepositoryTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/GenericRepositoryTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data34.integration.crud; +package io.tarantool.spring4.data.integration.crud; import java.util.ArrayList; import java.util.Arrays; @@ -47,13 +47,13 @@ import org.springframework.data.util.Streamable; import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data34.query.TarantoolQueryCreator.INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.UNKNOWN_PERSON; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data34.utils.TarantoolTestSupport.generateAndInsertPersons; +import static io.tarantool.spring4.data.query.TarantoolQueryCreator.INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.PERSONS_COUNT; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.PERSON_SPACE; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.UNKNOWN_PERSON; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.generateAndInsertComplexPersons; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.generateAndInsertPersons; import io.tarantool.client.crud.TarantoolCrudClient; import io.tarantool.client.crud.TarantoolCrudSpace; import io.tarantool.client.crud.options.SelectOptions; @@ -62,15 +62,15 @@ import io.tarantool.spring.data.utils.GenericPerson; import io.tarantool.spring.data.utils.GenericRepositoryMethods; import io.tarantool.spring.data.utils.Pair; -import io.tarantool.spring.data34.query.TarantoolPageRequest; -import io.tarantool.spring.data34.query.TarantoolScrollPosition; -import io.tarantool.spring.data34.query.TarantoolWindowIterator; -import io.tarantool.spring.data34.utils.TarantoolTestSupport; -import io.tarantool.spring.data34.utils.core.ComplexPersonRepository; -import io.tarantool.spring.data34.utils.core.GenericPaginationMethods; -import io.tarantool.spring.data34.utils.core.PersonRepository; -import io.tarantool.spring.data34.utils.entity.ComplexPerson; -import io.tarantool.spring.data34.utils.entity.Person; +import io.tarantool.spring4.data.query.TarantoolPageRequest; +import io.tarantool.spring4.data.query.TarantoolScrollPosition; +import io.tarantool.spring4.data.query.TarantoolWindowIterator; +import io.tarantool.spring4.data.utils.TarantoolTestSupport; +import io.tarantool.spring4.data.utils.core.ComplexPersonRepository; +import io.tarantool.spring4.data.utils.core.GenericPaginationMethods; +import io.tarantool.spring4.data.utils.core.PersonRepository; +import io.tarantool.spring4.data.utils.entity.ComplexPerson; +import io.tarantool.spring4.data.utils.entity.Person; abstract class GenericRepositoryTest extends CrudConfigurations { diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/GenericTarantoolTemplateTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/GenericTarantoolTemplateTest.java similarity index 94% rename from tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/GenericTarantoolTemplateTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/GenericTarantoolTemplateTest.java index 9ec5afc3..e38cd1c8 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/GenericTarantoolTemplateTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/GenericTarantoolTemplateTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.integration.crud; +package io.tarantool.spring4.data.integration.crud; import java.util.ArrayList; import java.util.Arrays; @@ -33,22 +33,22 @@ import static io.tarantool.spring.data.ProxyTarantoolCrudKeyValueAdapter.POTENTIAL_PERFORMANCE_ISSUES_EXCEPTION_MESSAGE; import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.generateAndInsertPersons; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.generateComplexPersons; -import static io.tarantool.spring.data32.utils.TarantoolTestSupport.generatePersons; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.PERSONS_COUNT; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.PERSON_SPACE; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.generateAndInsertComplexPersons; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.generateAndInsertPersons; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.generateComplexPersons; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.generatePersons; import io.tarantool.client.crud.TarantoolCrudClient; import io.tarantool.mapping.crud.CrudException; -import io.tarantool.spring.data32.core.TarantoolTemplate; -import io.tarantool.spring.data32.utils.entity.ComplexPerson; -import io.tarantool.spring.data32.utils.entity.ComplexPersonWithIncorrectPK; -import io.tarantool.spring.data32.utils.entity.ComplexPersonWithJsonFormatVariantPK; -import io.tarantool.spring.data32.utils.entity.CompositePersonKey; -import io.tarantool.spring.data32.utils.entity.CompositePersonKeyWithJsonFormat; -import io.tarantool.spring.data32.utils.entity.Person; +import io.tarantool.spring4.data.core.TarantoolTemplate; +import io.tarantool.spring4.data.utils.entity.ComplexPerson; +import io.tarantool.spring4.data.utils.entity.ComplexPersonWithIncorrectPK; +import io.tarantool.spring4.data.utils.entity.ComplexPersonWithJsonFormatVariantPK; +import io.tarantool.spring4.data.utils.entity.CompositePersonKey; +import io.tarantool.spring4.data.utils.entity.CompositePersonKeyWithJsonFormat; +import io.tarantool.spring4.data.utils.entity.Person; abstract class GenericTarantoolTemplateTest extends CrudConfigurations { diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/RepositoryConfigurationExtensionTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/RepositoryConfigurationExtensionTest.java similarity index 92% rename from tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/RepositoryConfigurationExtensionTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/RepositoryConfigurationExtensionTest.java index b13a9d90..a083df0f 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/RepositoryConfigurationExtensionTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/RepositoryConfigurationExtensionTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.integration.crud; +package io.tarantool.spring4.data.integration.crud; import java.io.IOException; @@ -23,9 +23,9 @@ import io.tarantool.client.factory.TarantoolBoxClientBuilder; import io.tarantool.client.factory.TarantoolCrudClientBuilder; import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.spring.data32.integration.BaseIntegrationTest; -import io.tarantool.spring.data32.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data32.repository.config.TarantoolRepositoryConfigurationExtension; +import io.tarantool.spring4.data.integration.BaseIntegrationTest; +import io.tarantool.spring4.data.repository.config.EnableTarantoolRepositories; +import io.tarantool.spring4.data.repository.config.TarantoolRepositoryConfigurationExtension; class RepositoryConfigurationExtensionTest extends BaseIntegrationTest { diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/RepositoryViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/RepositoryViaJavaConfigTest.java similarity index 66% rename from tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/RepositoryViaJavaConfigTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/RepositoryViaJavaConfigTest.java index b4c90dcc..0ed0056b 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/RepositoryViaJavaConfigTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/RepositoryViaJavaConfigTest.java @@ -3,11 +3,11 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.integration.crud; +package io.tarantool.spring4.data.integration.crud; import org.springframework.boot.test.context.SpringBootTest; -import io.tarantool.spring.data31.integration.crud.CrudConfigurations.JavaConfigConfiguration; +import io.tarantool.spring4.data.integration.crud.CrudConfigurations.JavaConfigConfiguration; @SpringBootTest(classes = {JavaConfigConfiguration.class}) class RepositoryViaJavaConfigTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/RepositoryViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/RepositoryViaPropertiesTest.java similarity index 66% rename from tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/RepositoryViaPropertiesTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/RepositoryViaPropertiesTest.java index d6b1492b..002fe534 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/RepositoryViaPropertiesTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/RepositoryViaPropertiesTest.java @@ -3,11 +3,11 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.integration.crud; +package io.tarantool.spring4.data.integration.crud; import org.springframework.boot.test.context.SpringBootTest; -import io.tarantool.spring.data32.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; +import io.tarantool.spring4.data.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; @SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) class RepositoryViaPropertiesTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/TarantoolTemplateViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/TarantoolTemplateViaJavaConfigTest.java similarity index 67% rename from tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/TarantoolTemplateViaJavaConfigTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/TarantoolTemplateViaJavaConfigTest.java index c5a152db..e2b7260c 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/TarantoolTemplateViaJavaConfigTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/TarantoolTemplateViaJavaConfigTest.java @@ -3,11 +3,11 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.integration.crud; +package io.tarantool.spring4.data.integration.crud; import org.springframework.boot.test.context.SpringBootTest; -import io.tarantool.spring.data31.integration.crud.CrudConfigurations.JavaConfigConfiguration; +import io.tarantool.spring4.data.integration.crud.CrudConfigurations.JavaConfigConfiguration; @SpringBootTest(classes = {JavaConfigConfiguration.class}) class TarantoolTemplateViaJavaConfigTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/TarantoolTemplateViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/TarantoolTemplateViaPropertiesTest.java similarity index 67% rename from tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/TarantoolTemplateViaPropertiesTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/TarantoolTemplateViaPropertiesTest.java index a7296ad3..be8b4219 100644 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/TarantoolTemplateViaPropertiesTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/integration/crud/TarantoolTemplateViaPropertiesTest.java @@ -3,11 +3,11 @@ * All Rights Reserved. */ -package io.tarantool.spring.data27.integration.crud; +package io.tarantool.spring4.data.integration.crud; import org.springframework.boot.test.context.SpringBootTest; -import io.tarantool.spring.data27.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; +import io.tarantool.spring4.data.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; @SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) class TarantoolTemplateViaPropertiesTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolCriteriaTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolCriteriaTest.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolCriteriaTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolCriteriaTest.java index 9d0d4763..165fa224 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/query/TarantoolCriteriaTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolCriteriaTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.query; +package io.tarantool.spring4.data.query; import java.util.Arrays; diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolKeysetScrollPositionTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolKeysetScrollPositionTest.java similarity index 99% rename from tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolKeysetScrollPositionTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolKeysetScrollPositionTest.java index 4b66dd92..89780b50 100644 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/query/TarantoolKeysetScrollPositionTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolKeysetScrollPositionTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data33.query; +package io.tarantool.spring4.data.query; import java.util.Arrays; import java.util.Collections; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolPageImplTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolPageImplTest.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolPageImplTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolPageImplTest.java index 156a3b30..736af309 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolPageImplTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolPageImplTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import java.util.Arrays; import java.util.Collections; @@ -23,10 +23,10 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.generatePersons; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.PERSONS_COUNT; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.generatePersons; import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data40.utils.entity.Person; +import io.tarantool.spring4.data.utils.entity.Person; class TarantoolPageImplTest { diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolPageRequestTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolPageRequestTest.java similarity index 99% rename from tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolPageRequestTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolPageRequestTest.java index d231905c..344d651f 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolPageRequestTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolPageRequestTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import java.util.Arrays; import java.util.List; @@ -26,7 +26,7 @@ import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; import io.tarantool.spring.data.query.PaginationDirection; import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data40.utils.entity.Person; +import io.tarantool.spring4.data.utils.entity.Person; class TarantoolPageRequestTest { diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolSliceTest.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolSliceTest.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolSliceTest.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolSliceTest.java index db948adc..19609946 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolSliceTest.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/query/TarantoolSliceTest.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.query; +package io.tarantool.spring4.data.query; import java.util.Arrays; import java.util.Collections; @@ -26,9 +26,9 @@ import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.spring.data40.utils.entity.Person; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.PERSONS_COUNT; +import static io.tarantool.spring4.data.utils.TarantoolTestSupport.generatePersons; +import io.tarantool.spring4.data.utils.entity.Person; public class TarantoolSliceTest { diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/TarantoolTestSupport.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/TarantoolTestSupport.java similarity index 98% rename from tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/TarantoolTestSupport.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/TarantoolTestSupport.java index 62fe0155..99fb7b4d 100644 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/TarantoolTestSupport.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/TarantoolTestSupport.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data40.utils; +package io.tarantool.spring4.data.utils; import java.io.File; import java.io.FileWriter; @@ -48,9 +48,9 @@ import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyFlushConsolidationHandler; import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyHeartbeatOpts; import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.spring.data40.config.properties.TarantoolProperties; -import io.tarantool.spring.data40.utils.entity.ComplexPerson; -import io.tarantool.spring.data40.utils.entity.Person; +import io.tarantool.spring4.data.config.properties.TarantoolProperties; +import io.tarantool.spring4.data.utils.entity.ComplexPerson; +import io.tarantool.spring4.data.utils.entity.Person; public class TarantoolTestSupport { diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/ComplexPersonListRepository.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/ComplexPersonListRepository.java similarity index 70% rename from tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/ComplexPersonListRepository.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/ComplexPersonListRepository.java index ffe7bd89..b94e621b 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/core/ComplexPersonListRepository.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/ComplexPersonListRepository.java @@ -3,13 +3,13 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.utils.core; +package io.tarantool.spring4.data.utils.core; import org.springframework.data.repository.ListCrudRepository; import io.tarantool.spring.data.utils.GenericListRepositoryMethods; -import io.tarantool.spring.data31.utils.entity.ComplexPerson; -import io.tarantool.spring.data31.utils.entity.CompositePersonKey; +import io.tarantool.spring4.data.utils.entity.ComplexPerson; +import io.tarantool.spring4.data.utils.entity.CompositePersonKey; public interface ComplexPersonListRepository extends ListCrudRepository, diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/core/ComplexPersonRepository.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/ComplexPersonRepository.java similarity index 73% rename from tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/core/ComplexPersonRepository.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/ComplexPersonRepository.java index 23172c65..3e8d4734 100644 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/core/ComplexPersonRepository.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/ComplexPersonRepository.java @@ -3,13 +3,13 @@ * All Rights Reserved. */ -package io.tarantool.spring.data27.utils.core; +package io.tarantool.spring4.data.utils.core; import org.springframework.data.repository.PagingAndSortingRepository; import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data27.utils.entity.ComplexPerson; -import io.tarantool.spring.data27.utils.entity.CompositePersonKey; +import io.tarantool.spring4.data.utils.entity.ComplexPerson; +import io.tarantool.spring4.data.utils.entity.CompositePersonKey; public interface ComplexPersonRepository extends PagingAndSortingRepository, diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/GenericPaginationMethods.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/GenericPaginationMethods.java similarity index 97% rename from tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/GenericPaginationMethods.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/GenericPaginationMethods.java index c65bcb58..77ea1129 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/core/GenericPaginationMethods.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/GenericPaginationMethods.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.utils.core; +package io.tarantool.spring4.data.utils.core; import java.util.List; diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/PersonListRepository.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/PersonListRepository.java similarity index 78% rename from tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/PersonListRepository.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/PersonListRepository.java index 658d9914..c72680c8 100644 --- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/utils/core/PersonListRepository.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/PersonListRepository.java @@ -3,12 +3,12 @@ * All Rights Reserved. */ -package io.tarantool.spring.data33.utils.core; +package io.tarantool.spring4.data.utils.core; import org.springframework.data.repository.ListCrudRepository; import io.tarantool.spring.data.utils.GenericListRepositoryMethods; -import io.tarantool.spring.data33.utils.entity.Person; +import io.tarantool.spring4.data.utils.entity.Person; public interface PersonListRepository extends ListCrudRepository, GenericListRepositoryMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/PersonRepository.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/PersonRepository.java similarity index 72% rename from tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/PersonRepository.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/PersonRepository.java index 8739b26b..e4ef2ad6 100644 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/core/PersonRepository.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/core/PersonRepository.java @@ -3,13 +3,13 @@ * All Rights Reserved. */ -package io.tarantool.spring.data34.utils.core; +package io.tarantool.spring4.data.utils.core; import org.springframework.data.repository.PagingAndSortingRepository; import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data34.utils.entity.Person; -import io.tarantool.spring.data34.utils.fragments.core.ReplaceManyFragment; +import io.tarantool.spring4.data.utils.entity.Person; +import io.tarantool.spring4.data.utils.fragments.core.ReplaceManyFragment; public interface PersonRepository extends PagingAndSortingRepository, diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/ComplexPerson.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/ComplexPerson.java similarity index 93% rename from tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/ComplexPerson.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/ComplexPerson.java index a096e57c..46646656 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/ComplexPerson.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/ComplexPerson.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.utils.entity; +package io.tarantool.spring4.data.utils.entity; import java.util.UUID; @@ -18,7 +18,7 @@ import io.tarantool.spring.data.core.annotation.IdClass; import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data31.query.Field; +import io.tarantool.spring4.data.query.Field; @NoArgsConstructor @AllArgsConstructor diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/ComplexPersonWithIncorrectPK.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/ComplexPersonWithIncorrectPK.java similarity index 91% rename from tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/ComplexPersonWithIncorrectPK.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/ComplexPersonWithIncorrectPK.java index 1250b387..90262e93 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/ComplexPersonWithIncorrectPK.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/ComplexPersonWithIncorrectPK.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.utils.entity; +package io.tarantool.spring4.data.utils.entity; import java.util.UUID; @@ -17,7 +17,7 @@ import org.springframework.data.keyvalue.annotation.KeySpace; import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data31.query.Field; +import io.tarantool.spring4.data.query.Field; @NoArgsConstructor @AllArgsConstructor diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/ComplexPersonWithJsonFormatVariantPK.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/ComplexPersonWithJsonFormatVariantPK.java similarity index 92% rename from tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/ComplexPersonWithJsonFormatVariantPK.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/ComplexPersonWithJsonFormatVariantPK.java index 26347f9c..24da449a 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/ComplexPersonWithJsonFormatVariantPK.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/ComplexPersonWithJsonFormatVariantPK.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.utils.entity; +package io.tarantool.spring4.data.utils.entity; import java.util.UUID; @@ -17,7 +17,7 @@ import org.springframework.data.keyvalue.annotation.KeySpace; import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data32.query.Field; +import io.tarantool.spring4.data.query.Field; @NoArgsConstructor @AllArgsConstructor diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositeKeyWithFieldInvalidOrder.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositeKeyWithFieldInvalidOrder.java similarity index 86% rename from tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositeKeyWithFieldInvalidOrder.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositeKeyWithFieldInvalidOrder.java index 6565a1f2..672b1a80 100644 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositeKeyWithFieldInvalidOrder.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositeKeyWithFieldInvalidOrder.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data27.utils.entity; +package io.tarantool.spring4.data.utils.entity; import java.util.UUID; diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositeKeyWithWrongFieldCount.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositeKeyWithWrongFieldCount.java similarity index 87% rename from tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositeKeyWithWrongFieldCount.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositeKeyWithWrongFieldCount.java index 98a7b1c2..4f8d9545 100644 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositeKeyWithWrongFieldCount.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositeKeyWithWrongFieldCount.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data27.utils.entity; +package io.tarantool.spring4.data.utils.entity; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositeKeyWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositeKeyWithWrongFieldTypes.java similarity index 92% rename from tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositeKeyWithWrongFieldTypes.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositeKeyWithWrongFieldTypes.java index d03a9d59..c87ccacb 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositeKeyWithWrongFieldTypes.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositeKeyWithWrongFieldTypes.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.utils.entity; +package io.tarantool.spring4.data.utils.entity; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositePersonKey.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositePersonKey.java similarity index 91% rename from tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositePersonKey.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositePersonKey.java index 14ce715d..77ef401c 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/CompositePersonKey.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositePersonKey.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.utils.entity; +package io.tarantool.spring4.data.utils.entity; import java.util.UUID; diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositePersonKeyWithJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositePersonKeyWithJsonFormat.java similarity index 91% rename from tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositePersonKeyWithJsonFormat.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositePersonKeyWithJsonFormat.java index 3b8c1a86..ec9d159c 100644 --- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/utils/entity/CompositePersonKeyWithJsonFormat.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositePersonKeyWithJsonFormat.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data31.utils.entity; +package io.tarantool.spring4.data.utils.entity; import java.util.UUID; diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositePersonKeyWithoutJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositePersonKeyWithoutJsonFormat.java similarity index 90% rename from tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositePersonKeyWithoutJsonFormat.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositePersonKeyWithoutJsonFormat.java index 6637f5a9..1427f103 100644 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/CompositePersonKeyWithoutJsonFormat.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/CompositePersonKeyWithoutJsonFormat.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data27.utils.entity; +package io.tarantool.spring4.data.utils.entity; import java.util.UUID; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/EntityWithAnnotationAsIdClass.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/EntityWithAnnotationAsIdClass.java similarity index 82% rename from tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/EntityWithAnnotationAsIdClass.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/EntityWithAnnotationAsIdClass.java index c5ef2cf6..c497b356 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/EntityWithAnnotationAsIdClass.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/EntityWithAnnotationAsIdClass.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.utils.entity; +package io.tarantool.spring4.data.utils.entity; import io.tarantool.spring.data.core.annotation.IdClass; diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/EntityWithInvalidKeyFieldsOrder.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/EntityWithInvalidKeyFieldsOrder.java similarity index 91% rename from tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/EntityWithInvalidKeyFieldsOrder.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/EntityWithInvalidKeyFieldsOrder.java index 959e9229..cad876e7 100644 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/EntityWithInvalidKeyFieldsOrder.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/EntityWithInvalidKeyFieldsOrder.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data27.utils.entity; +package io.tarantool.spring4.data.utils.entity; import java.util.UUID; @@ -17,7 +17,7 @@ import org.springframework.data.keyvalue.annotation.KeySpace; import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data27.query.Field; +import io.tarantool.spring4.data.query.Field; @NoArgsConstructor @AllArgsConstructor diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/EntityWithWrongCompositeKeyPartsCount.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/EntityWithWrongCompositeKeyPartsCount.java similarity index 92% rename from tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/EntityWithWrongCompositeKeyPartsCount.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/EntityWithWrongCompositeKeyPartsCount.java index f7d38cd5..1405f91f 100644 --- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/utils/entity/EntityWithWrongCompositeKeyPartsCount.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/EntityWithWrongCompositeKeyPartsCount.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data27.utils.entity; +package io.tarantool.spring4.data.utils.entity; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/EntityWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/EntityWithWrongFieldTypes.java similarity index 93% rename from tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/EntityWithWrongFieldTypes.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/EntityWithWrongFieldTypes.java index f389243e..d76de529 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/EntityWithWrongFieldTypes.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/EntityWithWrongFieldTypes.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.utils.entity; +package io.tarantool.spring4.data.utils.entity; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/Person.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/Person.java similarity index 91% rename from tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/Person.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/Person.java index 6ee34115..19c5b9f3 100644 --- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/utils/entity/Person.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/entity/Person.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data32.utils.entity; +package io.tarantool.spring4.data.utils.entity; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -15,7 +15,7 @@ import org.springframework.data.keyvalue.annotation.KeySpace; import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data32.query.Field; +import io.tarantool.spring4.data.query.Field; /** * @author Artyom Dubinin diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/fragments/core/ReplaceManyFragment.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/fragments/core/ReplaceManyFragment.java similarity index 78% rename from tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/fragments/core/ReplaceManyFragment.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/fragments/core/ReplaceManyFragment.java index 95e66833..cc9f79f7 100644 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/fragments/core/ReplaceManyFragment.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/fragments/core/ReplaceManyFragment.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data34.utils.fragments.core; +package io.tarantool.spring4.data.utils.fragments.core; import java.util.List; diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/fragments/implementations/PersonReplaceManyFragment.java b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/fragments/implementations/PersonReplaceManyFragment.java similarity index 82% rename from tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/fragments/implementations/PersonReplaceManyFragment.java rename to tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/fragments/implementations/PersonReplaceManyFragment.java index 7c847375..6ae1eec9 100644 --- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/utils/fragments/implementations/PersonReplaceManyFragment.java +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/java/io/tarantool/spring4/data/utils/fragments/implementations/PersonReplaceManyFragment.java @@ -3,7 +3,7 @@ * All Rights Reserved. */ -package io.tarantool.spring.data34.utils.fragments.implementations; +package io.tarantool.spring4.data.utils.fragments.implementations; import java.util.ArrayList; import java.util.List; @@ -12,8 +12,8 @@ import io.tarantool.client.crud.TarantoolCrudClient; import io.tarantool.mapping.Tuple; import io.tarantool.mapping.crud.CrudBatchResponse; -import io.tarantool.spring.data34.utils.entity.Person; -import io.tarantool.spring.data34.utils.fragments.core.ReplaceManyFragment; +import io.tarantool.spring4.data.utils.entity.Person; +import io.tarantool.spring4.data.utils.fragments.core.ReplaceManyFragment; public class PersonReplaceManyFragment implements ReplaceManyFragment { diff --git a/tarantool-spring-data/tarantool-spring-data-4/src/test/resources/META-INF/spring.factories b/tarantool-spring-data/tarantool-spring-data-4/src/test/resources/META-INF/spring.factories new file mode 100644 index 00000000..d35e941c --- /dev/null +++ b/tarantool-spring-data/tarantool-spring-data-4/src/test/resources/META-INF/spring.factories @@ -0,0 +1 @@ +io.tarantool.spring4.data.utils.fragments.core.ReplaceManyFragment=io.tarantool.spring4.data.utils.fragments.implementations.PersonReplaceManyFragment diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/resources/application-crud-test.yaml b/tarantool-spring-data/tarantool-spring-data-4/src/test/resources/application-crud-test.yaml similarity index 100% rename from tarantool-spring-data/tarantool-spring-data-27/src/test/resources/application-crud-test.yaml rename to tarantool-spring-data/tarantool-spring-data-4/src/test/resources/application-crud-test.yaml diff --git a/tarantool-spring-data/tarantool-spring-data-40/pom.xml b/tarantool-spring-data/tarantool-spring-data-40/pom.xml deleted file mode 100644 index e0598884..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/pom.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - 4.0.0 - - tarantool-spring-data-40 - Minimalistic java connector for Tarantool versions 2.11+ based on Netty framework - https://tarantool.io - - - io.tarantool - tarantool-spring-data - 2.0.0-SNAPSHOT - - - tarantool-spring-data-40 - jar - - - - 17 - 4.0.9 - - 4.0.8 - ${project.parent.parent.basedir}/tarantool-shared-resources/ - ${project.parent.parent.basedir}/LICENSE_HEADER.txt - - 6.0.3 - - - - - io.tarantool - tarantool-spring-data-core - - - org.springframework.data - spring-data-keyvalue - ${spring-data-keyvalue.version} - - - diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/config/TarantoolBoxConfiguration.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/config/TarantoolBoxConfiguration.java deleted file mode 100644 index fa264e8b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/config/TarantoolBoxConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2026 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 properties, - ObjectProvider 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(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/config/TarantoolCrudConfiguration.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/config/TarantoolCrudConfiguration.java deleted file mode 100644 index 08bdca46..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/config/TarantoolCrudConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 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_CRUD_CLIENT_BEAN_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.spring.data.config.BaseTarantoolCrudConfiguration; -import io.tarantool.spring.data40.TarantoolCrudKeyValueAdapter; -import io.tarantool.spring.data40.config.properties.TarantoolProperties; - -@Configuration(proxyBeanMethods = false) -public class TarantoolCrudConfiguration extends BaseTarantoolCrudConfiguration { - - public TarantoolCrudConfiguration( - ObjectProvider properties, - ObjectProvider tarantoolClientConfiguration) { - super(properties.getIfAvailable(), tarantoolClientConfiguration.getIfAvailable()); - } - - @Bean(name = DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF) - @ConditionalOnMissingBean(TarantoolCrudKeyValueAdapter.class) - public TarantoolCrudKeyValueAdapter tarantoolCrudKeyValueAdapter( - TarantoolCrudClient tarantoolCrudClient) { - return new TarantoolCrudKeyValueAdapter(tarantoolCrudClient); - } - - @Bean(name = DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF) - @ConditionalOnMissingBean(TarantoolCrudClient.class) - public TarantoolCrudClient tarantoolCrudClient() throws Exception { - return super.tarantoolCrudClient(); - } - - public TarantoolCrudClientBuilder getClientBuilder() { - return super.getClientBuilder(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/config/properties/TarantoolProperties.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/config/properties/TarantoolProperties.java deleted file mode 100644 index 59cdbac1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/config/properties/TarantoolProperties.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.config.properties; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties; - -/** - * Configuration properties for Tarantool. - * - * @author Nikolay Belonogov - */ -@ConfigurationProperties(prefix = "spring.data.tarantool") -public class TarantoolProperties extends BaseTarantoolProperties {} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/TarantoolTemplate.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/TarantoolTemplate.java deleted file mode 100644 index d081dc77..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/TarantoolTemplate.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.core; - -import org.springframework.data.keyvalue.core.IdentifierGenerator; -import org.springframework.data.keyvalue.core.KeyValueAdapter; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.util.ClassUtils; - -import io.tarantool.spring.data40.core.annotation.DefaultIdClassResolver; -import io.tarantool.spring.data40.core.mapping.TarantoolMappingContext; - -public class TarantoolTemplate extends KeyValueTemplate { - - public TarantoolTemplate(KeyValueAdapter adapter) { - super(adapter, new TarantoolMappingContext<>()); - } - - public TarantoolTemplate( - KeyValueAdapter adapter, - MappingContext< - ? extends KeyValuePersistentEntity, ? extends KeyValuePersistentProperty> - mappingContext) { - super(adapter, mappingContext); - } - - public TarantoolTemplate( - KeyValueAdapter adapter, - MappingContext< - ? extends KeyValuePersistentEntity, ? extends KeyValuePersistentProperty> - mappingContext, - IdentifierGenerator identifierGenerator) { - super(adapter, mappingContext, identifierGenerator); - } - - @Override - public T insert(T objectToInsert) { - if (DefaultIdClassResolver.INSTANCE.resolveIdClassType(objectToInsert.getClass()) == null) { - return super.insert(objectToInsert); - } - - PersistentEntity entity = - getMappingContext().getRequiredPersistentEntity(ClassUtils.getUserClass(objectToInsert)); - - IdentifierAccessor identifierAccessor = entity.getIdentifierAccessor(objectToInsert); - Object id = identifierAccessor.getRequiredIdentifier(); - return insert(id, objectToInsert); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/Identifier.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/Identifier.java deleted file mode 100644 index 8eb7a756..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/Identifier.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.core.mapping; - -import java.lang.reflect.Field; -import java.util.Collection; - -import org.springframework.data.mapping.PersistentProperty; - -/** The interface of the identifier class that will contain information about the composite key. */ -public interface Identifier

> { - - /** - * Add a {@link PersistentProperty} tagged with {@code Id}. - * - * @param property {@link PersistentProperty} tagged {@code Id} - */ - void addPart(P property); - - /** - * Return the parts of a composite key that are {@link PersistentProperty}. - * - * @return parts of a composite key - */ - Collection

getParts(); - - /** - * Return a list {@link Field} of fields that are annotated {@code @Id}. Unlike method {@link - * #getParts()} this method returns an array {@link Field}, where {@link Field} is taken from each - * element of the collection returned by the {@link #getParts()} method. Necessary in order not to - * write polluting code. - * - * @return fields of a composite key - */ - Field[] getFields(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/KeyValueCompositePersistentEntity.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/KeyValueCompositePersistentEntity.java deleted file mode 100644 index 62d67cb3..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/KeyValueCompositePersistentEntity.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.core.mapping; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.model.MutablePersistentEntity; - -import io.tarantool.spring.data.core.annotation.IdClass; - -/** - * An interface to enable {@link PersistentEntity}-specific operations with a composite key. - * - * @param domain class type - * @param

{@link PersistentProperty} type - */ -public interface KeyValueCompositePersistentEntity> - extends MutablePersistentEntity { - - /** - * Returns the fields of the class specified in the {@link IdClass} annotation. - * - * @return all fields that are in composite key class - */ - default List getIdClassTypeFields() { - List fields = new ArrayList<>(); - - for (Field field : getIdClassType().getDeclaredFields()) { - if (!field.isSynthetic()) { - fields.add(field); - } - } - return fields; - } - - /** - * Returns the type of the class specified in the {@link IdClass} annotation. - * - * @return class that specified in {@link IdClass} - */ - Class getIdClassType(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/KeyValueCompositeProperty.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/KeyValueCompositeProperty.java deleted file mode 100644 index 38731a42..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/KeyValueCompositeProperty.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.core.mapping; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; - -import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.model.Property; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.util.Assert; - -public class KeyValueCompositeProperty

> - extends KeyValuePersistentProperty

implements Identifier

{ - - private final List

identifierPartsWithoutFirst; - - public KeyValueCompositeProperty( - Property property, PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - super(property, owner, simpleTypeHolder); - this.identifierPartsWithoutFirst = new ArrayList<>(); - } - - @Override - public void addPart(P property) { - Assert.notNull(property, "property must be not null"); - - if (equals(property) || this.identifierPartsWithoutFirst.contains(property)) { - return; - } - this.identifierPartsWithoutFirst.add(property); - } - - @Override - @SuppressWarnings("unchecked") - public Collection

getParts() { - List

resultList = new ArrayList<>(this.identifierPartsWithoutFirst); - resultList.add(0, (P) this); - - return resultList; - } - - @Override - public Field[] getFields() { - int totalSize = this.identifierPartsWithoutFirst.size() + 1; - - final Field[] fields = new Field[totalSize]; - fields[0] = getField(); - - for (int i = 1; i < totalSize; i++) { - fields[i] = this.identifierPartsWithoutFirst.get(i - 1).getField(); - } - return fields; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - KeyValueCompositeProperty other = (KeyValueCompositeProperty) o; - - if (this.identifierPartsWithoutFirst.isEmpty() && other.identifierPartsWithoutFirst.isEmpty()) { - return super.equals(o); - } - - if (this.identifierPartsWithoutFirst.size() != other.identifierPartsWithoutFirst.size() - || !other.getProperty().equals(getProperty())) { - return false; - } - - for (int i = 0; i < this.identifierPartsWithoutFirst.size(); i++) { - // take Property from both parts - Property thisKeyPartProperty = - ((KeyValueCompositeProperty) this.identifierPartsWithoutFirst.get(i)).getProperty(); - Property otherKeyPartProperty = - ((KeyValueCompositeProperty) other.identifierPartsWithoutFirst.get(i)).getProperty(); - - if (!thisKeyPartProperty.equals(otherKeyPartProperty)) { - return false; - } - } - return true; - } - - @Override - public int hashCode() { - int hashCode = super.hashCode(); - - if (this.identifierPartsWithoutFirst.isEmpty()) { - return hashCode; - } - - // sublist to avoid endless recursion - return Objects.hash(hashCode, this.identifierPartsWithoutFirst); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/model/PersistentCompositeIdIsNewStrategy.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/model/PersistentCompositeIdIsNewStrategy.java deleted file mode 100644 index 16bc22d6..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/core/mapping/model/PersistentCompositeIdIsNewStrategy.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.core.mapping.model; - -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.support.IsNewStrategy; -import org.springframework.util.Assert; - -/** - * Strategy class for entity with composite key to determine whether a given entity is to be - * considered new. - */ -public class PersistentCompositeIdIsNewStrategy implements IsNewStrategy { - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} for the given entity. - * - * @param entity must not be {@literal null}. - * @param idOnly check only id to determine - */ - private PersistentCompositeIdIsNewStrategy(PersistentEntity entity, boolean idOnly) { - // TODO сделать реализацию версионирования - // TODO add idOnly support - Assert.notNull(entity, "PersistentEntity must not be null"); - } - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} to only consider the identifier of the - * given entity. - * - * @param entity must not be {@literal null}. - * @return strategy to determine whether entity is new or not - */ - public static PersistentCompositeIdIsNewStrategy forIdOnly(PersistentEntity entity) { - return new PersistentCompositeIdIsNewStrategy(entity, true); - } - - /** - * Create a new {@link PersistentCompositeIdIsNewStrategy} to consider version properties before - * falling back to the identifier. - * - * @param entity must not be {@literal null}. - * @return strategy to determine whether entity is new or not - */ - public static PersistentCompositeIdIsNewStrategy of(PersistentEntity entity) { - return new PersistentCompositeIdIsNewStrategy(entity, false); - } - - /** - * Determine whether the current domain entity type object is new. Currently stub and always - * returns false. - * - * @param entity must not be {@literal null}. - * @return result of the question of entity is new or not - */ - @Override - public boolean isNew(Object entity) { - return false; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/Field.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/Field.java deleted file mode 100644 index a5a30dab..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/Field.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.query; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.core.annotation.AliasFor; - -/** - * Allows adding some metadata to the class fields relevant for storing them in the Tarantool space - * - * @author Artyom Dubinin - */ -@Inherited -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) -public @interface Field { - - /** - * The target Tarantool space field for storing the marked class field. Alias for {@link #name()}. - * - * @return the name of a field in space - */ - @AliasFor("name") - String value() default ""; - - /** - * The target Tarantool space field for storing the marked class field. Alias for {@link - * #value()}. - * - * @return the name of a field in space - */ - @AliasFor("value") - String name() default ""; - - /** - * The order in which fields shall be stored in the tuple. Has to be a positive integer. - * - * @return the order the field shall have in the tuple or -1 if undefined. - */ - int order() default -1; -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/PaginationUtils.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/PaginationUtils.java deleted file mode 100644 index 0a7713fc..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/PaginationUtils.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.query; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.keyvalue.core.IterableConverter; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.util.Assert; - -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class PaginationUtils { - - private static final String CRITERIA_NULL_EXC_MSG = "TarantoolCriteria must be not null"; - - /** - * Returns {@link TarantoolPageable} cast from {@link Pageable} with type checking. - * - * @param sliceParams pageable - * @return {@link TarantoolPageable} - */ - public static TarantoolPageable castToTarantoolPageable(Pageable sliceParams) { - Assert.isInstanceOf(TarantoolPageable.class, sliceParams, "Pageable must be TarantoolPageable"); - return (TarantoolPageable) sliceParams; - } - - /** - * A general method for retrieving data for paginated queries. - * - * @param query query - * @param pageRequest {@link TarantoolPageable} - * @param pageSize page size - * @return selection result. - */ - public static List doPaginationQuery( - final KeyValueQuery query, - TarantoolPageable pageRequest, - int pageSize, - KeyValueOperations keyValueOperations, - Class targetType) { - - TarantoolCriteria criteria = (TarantoolCriteria) query.getCriteria(); - PaginationDirection paginationDirection = pageRequest.getPaginationDirection(); - - Assert.notNull(criteria, CRITERIA_NULL_EXC_MSG); - criteria.withAfter(pageRequest.getTupleCursor()); - - query.setRows(pageSize * paginationDirection.getMultiplier()); - - return IterableConverter.toList(keyValueOperations.find(query, targetType)); - } - - public static Page doPageQuery( - Pageable pageable, - KeyValueQuery query, - KeyValueOperations keyValueOperations, - Class targetType) { - if (pageable.isUnpaged()) { - return new TarantoolPageImpl<>(); - } - TarantoolPageable resultSliceParams = castToTarantoolPageable(pageable); - - int pageSize = resultSliceParams.getPageSize(); - - // non transactional calls - List content = - doPaginationQuery(query, resultSliceParams, pageSize, keyValueOperations, targetType); - - if (content.isEmpty()) { - return new TarantoolPageImpl<>(); - } - - long totalElements = keyValueOperations.count(query, targetType); - return new TarantoolPageImpl<>(content, resultSliceParams, totalElements); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolCriteriaAccessor.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolCriteriaAccessor.java deleted file mode 100644 index 8aae4502..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolCriteriaAccessor.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.query; - -import org.springframework.data.keyvalue.core.CriteriaAccessor; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -import io.tarantool.spring.data.query.TarantoolCriteria; - -/** - * Provide a mechanism to convert the abstract query into the direct implementation in Tarantool. - * - * @author Artyom Dubinin - */ -public class TarantoolCriteriaAccessor implements CriteriaAccessor { - - /** - * @param query in Spring form - * @return The same in Tarantool form - */ - public TarantoolCriteria resolve(KeyValueQuery query) { - return (TarantoolCriteria) query.getCriteria(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolScrollPosition.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolScrollPosition.java deleted file mode 100644 index fcd5e764..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/query/TarantoolScrollPosition.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.query; - -import org.springframework.data.domain.ScrollPosition; - -import io.tarantool.spring.data.utils.Pair; - -/** - * Use keyset pagination adapted for Tarantool crud module.. - * - * @author Nikolay Belonogov - * @see #forward(Pair) - * @see #backward(Pair) - * @see #reverse() - */ -public sealed interface TarantoolScrollPosition extends ScrollPosition - permits TarantoolKeysetScrollPosition { - - /** - * Creates a new {@link ScrollPosition} based on the key index scrolling forward. - * - * @param indexKey pair, where the first element is the name of the index on which you want to - * perform pagination. Second element is the value of the indexed field from which you want to - * paginate (exclusive). To perform pagination from the beginning of the index, pass an empty - * list as the second element of the pair. indexKey must be not {@code null}. - * @return new {@link TarantoolScrollPosition} instance. - */ - static TarantoolScrollPosition forward(Pair indexKey) { - return TarantoolKeysetScrollPosition.forward(indexKey); - } - - /** - * Creates a new {@link ScrollPosition} based on the key index scrolling backward. - * - * @param indexKey pair, where the first element is the name of the index on which you want to - * perform pagination. Second element is the value of the indexed field from which you want to - * paginate (exclusive). To perform pagination from the end of the index, pass an empty list - * as the second element of the pair. indexKey must be not {@code null}. - * @return new {@link TarantoolScrollPosition} instance. - */ - static TarantoolScrollPosition backward(Pair indexKey) { - return TarantoolKeysetScrollPosition.backward(indexKey); - } - - /** - * Return {@link TarantoolScrollPosition} with the same parameters, but with the opposite - * pagination direction. If the current {@link TarantoolScrollPosition} was set from the beginning - * of the index, the method will return the {@link TarantoolScrollPosition} set from the end of - * the index. Returns the {@link TarantoolScrollPosition} set from the beginning of the index if - * the current {@link TarantoolScrollPosition} is set from the end of the index. - * - *

Important: when this method is called, the condition specified by the index in - * the current {@link TarantoolScrollPosition} is overridden to unconditional (i.e. it will be - * searched to the end or beginning of the index) - * - * @return {@link TarantoolScrollPosition} instance. - */ - TarantoolScrollPosition reverse(); - - /** - * Return {@code true} if scrolling has backward motion. This means that the current {@link - * TarantoolScrollPosition} has the direction of movement {@link - * io.tarantool.spring.data.query.PaginationDirection#BACKWARD}. Return {@code false} if scrolling - * has forward motion ({@link io.tarantool.spring.data.query.PaginationDirection#FORWARD}). - * - * @return {@link Boolean} primitive. - */ - boolean isScrollsBackward(); -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/EnableTarantoolRepositories.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/EnableTarantoolRepositories.java deleted file mode 100644 index 544f24fc..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/EnableTarantoolRepositories.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.repository.config; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.ComponentScan.Filter; -import org.springframework.context.annotation.Import; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.config.QueryCreatorType; -import org.springframework.data.repository.config.DefaultRepositoryBaseClass; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryLookupStrategy.Key; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.spring.data40.config.properties.TarantoolProperties; -import io.tarantool.spring.data40.query.TarantoolQueryCreator; -import io.tarantool.spring.data40.repository.support.TarantoolRepositoryFactoryBean; - -@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@Import(TarantoolRepositoriesRegistrar.class) -@EnableConfigurationProperties(TarantoolProperties.class) -@QueryCreatorType(TarantoolQueryCreator.class) -public @interface EnableTarantoolRepositories { - - /** - * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation - * declarations e.g.: {@code @EnableJpaRepositories("org.my.pkg")} instead of - * {@code @EnableJpaRepositories(basePackages="org.my.pkg")}. - * - * @return value - */ - String[] value() default {}; - - /** - * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually - * exclusive with) this attribute. Use {@link #basePackageClasses()} for a type-safe alternative - * to String-based package names. - * - * @return base packages - */ - String[] basePackages() default {}; - - /** - * Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for - * annotated components. The package of each class specified will be scanned. Consider creating a - * special no-op marker class or interface in each package that serves no purpose other than being - * referenced by this attribute. - * - * @return classes - */ - Class[] basePackageClasses() default {}; - - /** - * Specifies which types are not eligible for component scanning. - * - * @return filters - */ - Filter[] excludeFilters() default {}; - - /** - * Specifies which types are eligible for component scanning. Further, narrows the set of - * candidate components from everything in {@link #basePackages()} to everything in the base - * packages that matches the given filter or filters. - * - * @return filters - */ - Filter[] includeFilters() default {}; - - /** - * Returns the postfix to be used when looking up custom repository implementations. Defaults to - * {@literal Impl}. So for a repository named {@code PersonRepository} the corresponding - * implementation class will be looked up scanning for {@code PersonRepositoryImpl}. - * - * @return postfix - */ - String repositoryImplementationPostfix() default "Impl"; - - /** - * Configures the location of where to find the Spring Data named queries properties file. - * - * @return location - */ - String namedQueriesLocation() default ""; - - /** - * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query - * methods. Defaults to {@link Key#CREATE_IF_NOT_FOUND}. - * - * @return strategy - */ - Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND; - - Class repositoryFactoryBeanClass() default TarantoolRepositoryFactoryBean.class; - - /** - * Allow custom base classes, for generic behavior shared amongst selected repositories. - * - * @return base class - */ - Class repositoryBaseClass() default DefaultRepositoryBaseClass.class; - - /** - * Configures the name of the {@link KeyValueOperations} bean to be used with the repositories - * detected. - * - * @return reference to {@link KeyValueOperations} bean. - */ - String keyValueTemplateRef() default DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; - - /** - * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be - * discovered by the repositories' infrastructure. - * - * @return result of consideration - */ - boolean considerNestedRepositories() default false; - - /** - * Configures the {@link ClientType} to be used as driver client type to connection to Tarantool. - * Must match the referenced type in {@link #keyValueTemplateRef()}} if these values differ from - * the default ones. - * - * @return the type of client through which communication with Tarantool will be made. - */ - ClientType clientType() default ClientType.CRUD; -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/TarantoolRepositoriesRegistrar.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/TarantoolRepositoriesRegistrar.java deleted file mode 100644 index 5d000912..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/TarantoolRepositoriesRegistrar.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.repository.config; - -import java.lang.annotation.Annotation; - -import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport; -import org.springframework.data.repository.config.RepositoryConfigurationExtension; - -class TarantoolRepositoriesRegistrar extends RepositoryBeanDefinitionRegistrarSupport { - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoriesRegistrar#getAnnotation() - */ - @Override - protected Class getAnnotation() { - return EnableTarantoolRepositories.class; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport#getExtension() - */ - @Override - protected RepositoryConfigurationExtension getExtension() { - return new TarantoolRepositoryConfigurationExtension(); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/TarantoolRepositoryConfigurationExtension.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/TarantoolRepositoryConfigurationExtension.java deleted file mode 100644 index 4921a86f..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/config/TarantoolRepositoryConfigurationExtension.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.repository.config; - -import org.springframework.beans.factory.config.ConstructorArgumentValues; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension; -import org.springframework.data.repository.config.RepositoryConfigurationSource; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.spring.data40.config.TarantoolCrudConfiguration; -import io.tarantool.spring.data40.core.TarantoolTemplate; -import io.tarantool.spring.data40.core.mapping.TarantoolMappingContext; - -public class TarantoolRepositoryConfigurationExtension - extends KeyValueRepositoryConfigurationExtension { - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getModuleName() - */ - @Override - public String getModuleName() { - return "Tarantool"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getModulePrefix() - */ - @Override - public String getModulePrefix() { - return "tarantool"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #getDefaultKeyValueTemplateRef() - */ - @Override - public String getDefaultKeyValueTemplateRef() { - return DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension - * #registerBeansForRoot() - */ - @Override - public void registerBeansForRoot( - BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) { - // register a default set of beans based on the passed annotation attributes. - final ClientType clientTypeAttribute = - configurationSource.getRequiredAttribute("clientType", ClientType.class); - - if (clientTypeAttribute == ClientType.CRUD) { - final String defaultCrudConfigurationBeanName = - TarantoolCrudConfiguration.class.getCanonicalName(); - registerIfNotAlreadyRegistered( - () -> new RootBeanDefinition(TarantoolCrudConfiguration.class), - registry, - defaultCrudConfigurationBeanName, - configurationSource); - } else { - throw new IllegalArgumentException("The Box client is not yet supported."); - } - super.registerBeansForRoot(registry, configurationSource); - - // remove KeyValueMappingContext to add TarantoolMappingContext - registry.removeBeanDefinition(getMappingContextBeanRef()); - registerIfNotAlreadyRegistered( - () -> { - RootBeanDefinition definition = new RootBeanDefinition(TarantoolMappingContext.class); - definition.setSource(configurationSource.getSource()); - - return definition; - }, - registry, - getMappingContextBeanRef(), - configurationSource); - } - - @Override - protected AbstractBeanDefinition getDefaultKeyValueTemplateBeanDefinition( - RepositoryConfigurationSource configurationSource) { - final RootBeanDefinition keyValueTemplateBeanDefinition = - new RootBeanDefinition(TarantoolTemplate.class); - - final ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); - constructorArgumentValues.addIndexedArgumentValue( - 0, new RuntimeBeanReference(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF)); - constructorArgumentValues.addIndexedArgumentValue( - 1, new RuntimeBeanReference(getMappingContextBeanRef())); - - keyValueTemplateBeanDefinition.setConstructorArgumentValues(constructorArgumentValues); - keyValueTemplateBeanDefinition.setSource(configurationSource); - keyValueTemplateBeanDefinition.setDependsOn(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF); - keyValueTemplateBeanDefinition.setDependsOn(getMappingContextBeanRef()); - - return keyValueTemplateBeanDefinition; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/support/TarantoolRepositoryFactoryBean.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/support/TarantoolRepositoryFactoryBean.java deleted file mode 100644 index 88e827f5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/support/TarantoolRepositoryFactoryBean.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.repository.support; - -import java.io.Serializable; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean; -import org.springframework.data.repository.Repository; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data40.repository.TarantoolRepositoryFactory; - -public class TarantoolRepositoryFactoryBean, S, ID extends Serializable> - extends KeyValueRepositoryFactoryBean { - - @Autowired private TarantoolCrudClient client; - - public TarantoolRepositoryFactoryBean(Class repositoryInterface) { - super(repositoryInterface); - } - - /** - * Return a {@link TarantoolRepositoryFactory}. - * - *

{@code super} would return {@link KeyValueRepositoryFactory} which in turn builds {@code - * KeyValueRepository} instances, and these have a private method that implement querying in a - * manner that does not fit with Tarantool. More details are in {@link - * TarantoolRepositoryFactory}. - * - * @param operations operations - * @param queryCreator creator - * @param repositoryQueryType, not used - * @return A {@link TarantoolRepositoryFactory} that creates tarantool repository instances. - */ - @Override - protected KeyValueRepositoryFactory createRepositoryFactory( - KeyValueOperations operations, - Class> queryCreator, - Class repositoryQueryType) { - return new TarantoolRepositoryFactory(client, operations, queryCreator); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/support/TarantoolSimpleRepository.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/support/TarantoolSimpleRepository.java deleted file mode 100644 index 58bc4374..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/support/TarantoolSimpleRepository.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.repository.support; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository; -import org.springframework.data.repository.core.EntityInformation; -import org.springframework.util.Assert; - -import static io.tarantool.spring.data40.query.PaginationUtils.doPageQuery; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolSimpleRepository extends SimpleKeyValueRepository { - - private static final String FIND_ALL_EXC_MSG = - "This method is not supported to avoid sampling huge data massive. " - + "Please use derived methods with scrolling or pagination to select all data."; - - private static final String FIND_ALL_SORT_EXC_MSG = - "This method is not supported because sorting is not supported " - + "in Tarantool. Organize sorting of results using Java tools."; - - private static final String PAGEABLE_NULL_EXC_MSG = "Pageable must be not null"; - - private final KeyValueOperations operations; - private final EntityInformation entityInformation; - - /** - * Creates a new {@link SimpleKeyValueRepository} for the given {@link EntityInformation} and - * {@link KeyValueOperations}. - * - * @param metadata must not be {@literal null}. - * @param operations must not be {@literal null}. - */ - public TarantoolSimpleRepository( - EntityInformation metadata, KeyValueOperations operations) { - super(metadata, operations); - this.entityInformation = metadata; - this.operations = operations; - } - - @Override - public List findAll() { - throw new UnsupportedOperationException(FIND_ALL_EXC_MSG); - } - - @Override - public List findAll(Sort sort) { - throw new UnsupportedOperationException(FIND_ALL_SORT_EXC_MSG); - } - - @Override - @SuppressWarnings("unchecked") - public Page findAll(Pageable pageable) { - Assert.notNull(pageable, PAGEABLE_NULL_EXC_MSG); - - KeyValueQuery query = new KeyValueQuery<>(new TarantoolCriteria()); - return (Page) - doPageQuery(pageable, query, this.operations, this.entityInformation.getJavaType()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/support/package-info.java b/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/support/package-info.java deleted file mode 100644 index 06a41396..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/main/java/io/tarantool/spring/data40/repository/support/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Repository support package. */ -@org.springframework.lang.NonNullApi -package io.tarantool.spring.data40.repository.support; diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/TarantoolBoxConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/TarantoolBoxConfigurationTest.java deleted file mode 100644 index a8171493..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/TarantoolBoxConfigurationTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.config; - -import java.io.IOException; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.RepeatedTest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.bean.override.mockito.MockitoBean; - -import io.tarantool.client.box.TarantoolBoxClient; -import io.tarantool.client.factory.TarantoolBoxClientBuilder; -import io.tarantool.pool.HeartbeatOpts; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data40.config.properties.TarantoolProperties; -import io.tarantool.spring.data40.utils.TarantoolTestSupport; - -@SpringBootTest(classes = {TarantoolBoxConfigurationTest.Config.class}) -public class TarantoolBoxConfigurationTest extends GenericTarantoolConfigurationTest { - - @MockitoBean TarantoolBoxClient client; - - @Autowired private TarantoolBoxConfiguration tarantoolBoxConfiguration; - - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testGetBoxClientBuilder() throws IOException { - assertEquals(properties, tarantoolBoxConfiguration.getProperties()); - - final TarantoolBoxClientBuilder boxClientBuilder = tarantoolBoxConfiguration.getClientBuilder(); - - if (properties.getConnectionGroups() == null) { - assertNull(boxClientBuilder.getGroups()); - } else { - Assertions.assertEquals( - properties.getConnectionGroups().size(), boxClientBuilder.getGroups().size()); - List connectionGroupsFromBuilder = boxClientBuilder.getGroups(); - List connectionGroupsFromProperty = - properties.getInstanceConnectionGroups(); - - assertNotNull(connectionGroupsFromBuilder); - assertNotNull(connectionGroupsFromProperty); - for (int i = 0; i < connectionGroupsFromBuilder.size(); i++) { - InstanceConnectionGroup groupFromBuilder = connectionGroupsFromBuilder.get(i); - InstanceConnectionGroup groupFromProperty = connectionGroupsFromProperty.get(i); - - assertEquals(groupFromProperty.getAuthType(), groupFromBuilder.getAuthType()); - assertEquals(groupFromProperty.getTag(), groupFromBuilder.getTag()); - assertEquals(groupFromProperty.getSize(), groupFromBuilder.getSize()); - assertEquals(groupFromProperty.getUser(), groupFromBuilder.getUser()); - assertEquals(groupFromProperty.getPassword(), groupFromBuilder.getPassword()); - assertEquals(groupFromProperty.getPort(), groupFromBuilder.getPort()); - assertEquals(groupFromProperty.getHost(), groupFromBuilder.getHost()); - } - } - - final HeartbeatOpts propertiesHeartbeatOpts = properties.getHeartbeatOpts(); - if (propertiesHeartbeatOpts == null) { - assertNull(boxClientBuilder.getHeartbeatOpts()); - } else { - HeartbeatOpts builderHeartbeatOpts = boxClientBuilder.getHeartbeatOpts(); - assertEquals( - propertiesHeartbeatOpts.getPingInterval(), builderHeartbeatOpts.getPingInterval()); - assertEquals( - propertiesHeartbeatOpts.getDeathThreshold(), builderHeartbeatOpts.getDeathThreshold()); - assertEquals( - propertiesHeartbeatOpts.getInvalidationThreshold(), - builderHeartbeatOpts.getInvalidationThreshold()); - assertEquals(propertiesHeartbeatOpts.getWindowSize(), builderHeartbeatOpts.getWindowSize()); - } - - Assertions.assertEquals(properties.getUserName(), boxClientBuilder.getUser()); - Assertions.assertEquals(properties.getPort(), boxClientBuilder.getPort()); - Assertions.assertEquals(properties.getEventLoopThreadsCount(), boxClientBuilder.getnThreads()); - Assertions.assertEquals(properties.getBalancerClass(), boxClientBuilder.getBalancerClass()); - Assertions.assertEquals( - properties.isGracefulShutdownEnabled(), boxClientBuilder.isGracefulShutdown()); - Assertions.assertEquals(properties.getConnectTimeout(), boxClientBuilder.getConnectTimeout()); - Assertions.assertEquals(properties.getReconnectAfter(), boxClientBuilder.getReconnectAfter()); - Assertions.assertEquals(properties.getHost(), boxClientBuilder.getHost()); - Assertions.assertEquals(properties.getPassword(), boxClientBuilder.getPassword()); - Assertions.assertEquals(properties.isFetchSchema(), boxClientBuilder.isFetchSchema()); - Assertions.assertEquals( - properties.isIgnoreOldSchemaVersion(), boxClientBuilder.isIgnoreOldSchemaVersion()); - - testProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @Configuration - @EnableConfigurationProperties(TarantoolProperties.class) - @Import(TarantoolBoxConfiguration.class) - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/TarantoolCrudConfigurationTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/TarantoolCrudConfigurationTest.java deleted file mode 100644 index 72cd790d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/TarantoolCrudConfigurationTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.config; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.bean.override.mockito.MockitoBean; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.pool.HeartbeatOpts; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyHeartbeatOpts; -import io.tarantool.spring.data.config.properties.BaseTarantoolProperties.PropertyInstanceConnectionGroup; -import io.tarantool.spring.data40.repository.config.EnableTarantoolRepositories; - -@SpringBootTest(classes = {TarantoolCrudConfigurationTest.Config.class}) -public class TarantoolCrudConfigurationTest extends GenericTarantoolConfigurationTest { - - @MockitoBean TarantoolCrudClient client; - - @Autowired private TarantoolCrudConfiguration tarantoolCrudConfiguration; - - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testGetCrudClientBuilder() throws IOException { - assertEquals(properties, tarantoolCrudConfiguration.getProperties()); - - final TarantoolCrudClientBuilder crudClientBuilder = - tarantoolCrudConfiguration.getClientBuilder(); - - if (properties.getConnectionGroups() == null) { - assertNull(crudClientBuilder.getGroups()); - } else { - assertEquals(properties.getConnectionGroups().size(), crudClientBuilder.getGroups().size()); - List connectionGroupsFromBuilder = crudClientBuilder.getGroups(); - List connectionGroupsFromProperty = - properties.getConnectionGroups(); - assertNotNull(connectionGroupsFromBuilder); - assertNotNull(connectionGroupsFromProperty); - for (int i = 0; i < connectionGroupsFromBuilder.size(); i++) { - InstanceConnectionGroup groupFromBuilder = connectionGroupsFromBuilder.get(i); - PropertyInstanceConnectionGroup groupFromProperty = connectionGroupsFromProperty.get(i); - - assertEquals(groupFromProperty.getAuthType(), groupFromBuilder.getAuthType()); - assertEquals(groupFromProperty.getTag(), groupFromBuilder.getTag()); - assertEquals(groupFromProperty.getConnectionGroupSize(), groupFromBuilder.getSize()); - assertEquals(groupFromProperty.getUserName(), groupFromBuilder.getUser()); - assertEquals(groupFromProperty.getPassword(), groupFromBuilder.getPassword()); - assertEquals(groupFromProperty.getPort(), groupFromBuilder.getPort()); - assertEquals(groupFromProperty.getHost(), groupFromBuilder.getHost()); - } - } - - final PropertyHeartbeatOpts propertiesHeartbeatOpts = properties.getHeartbeat(); - if (propertiesHeartbeatOpts == null) { - assertNull(crudClientBuilder.getHeartbeatOpts()); - } else { - HeartbeatOpts builderHeartbeatOpts = crudClientBuilder.getHeartbeatOpts(); - - assertEquals( - propertiesHeartbeatOpts.getPingInterval(), builderHeartbeatOpts.getPingInterval()); - assertEquals( - propertiesHeartbeatOpts.getDeathThreshold(), builderHeartbeatOpts.getDeathThreshold()); - assertEquals( - propertiesHeartbeatOpts.getInvalidationThreshold(), - builderHeartbeatOpts.getInvalidationThreshold()); - assertEquals(propertiesHeartbeatOpts.getWindowSize(), builderHeartbeatOpts.getWindowSize()); - } - - assertEquals(properties.getUserName(), crudClientBuilder.getUser()); - assertEquals(properties.getPort(), crudClientBuilder.getPort()); - assertEquals(properties.getEventLoopThreadsCount(), crudClientBuilder.getnThreads()); - assertEquals(properties.getBalancerClass(), crudClientBuilder.getBalancerClass()); - assertEquals(properties.isGracefulShutdownEnabled(), crudClientBuilder.isGracefulShutdown()); - assertEquals(properties.getConnectTimeout(), crudClientBuilder.getConnectTimeout()); - assertEquals(properties.getReconnectAfter(), crudClientBuilder.getReconnectAfter()); - assertEquals(properties.getHost(), crudClientBuilder.getHost()); - assertEquals(properties.getPassword(), crudClientBuilder.getPassword()); - - testProperties = writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME); - } - - @Test - void testKeyValueTemplate() { - final List beanDefinitions = Arrays.asList(applicationContext.getBeanDefinitionNames()); - assertTrue(beanDefinitions.contains(DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF)); - - final KeyValueTemplate keyValueTemplate = - applicationContext.getBean( - DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF, KeyValueTemplate.class); - assertNotNull(keyValueTemplate); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/TarantoolEmptyPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/TarantoolEmptyPropertiesTest.java deleted file mode 100644 index c816a1bd..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/TarantoolEmptyPropertiesTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.config; - -import java.io.IOException; -import java.nio.file.Files; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.TestPropertySource; - -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data40.config.properties.TarantoolProperties; -import io.tarantool.spring.data40.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data40.utils.TarantoolTestSupport; - -/** - * @see TarantoolPropertiesTest - */ -@SpringBootTest(classes = {TarantoolEmptyPropertiesTest.Config.class}) -@TestPropertySource(properties = {Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -@Timeout(5) -public class TarantoolEmptyPropertiesTest { - - @Autowired private TarantoolProperties springParsedProperties; - - @BeforeAll - static void beforeAll() throws IOException { - TarantoolTestSupport.writeTestEmptyPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - /* - * The test checks that if property processing is enabled via the @EnableConfigurationProperties annotation, then - * TarantoolProperty always exists and has default values. - */ - @Test - void testParseEmptyProperties() { - assertNotNull(springParsedProperties); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists( - TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR.resolve( - Constants.DEFAULT_PROPERTY_FILE_NAME)); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/TarantoolPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/TarantoolPropertiesTest.java deleted file mode 100644 index e79a9961..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/config/TarantoolPropertiesTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.config; - -import java.io.IOException; -import java.nio.file.Files; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Timeout; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.bean.override.mockito.MockitoBean; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.spring.data.utils.Constants; -import io.tarantool.spring.data40.config.properties.TarantoolProperties; -import io.tarantool.spring.data40.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data40.utils.TarantoolTestSupport; - -/** - * The test checks whether the Spring framework parses a file with the specified properties - * correctly. Before creating the test class, a random file with properties is written to the - * classpath:properties-test.yaml file. Next, when creating a test class the Spring context is - * raised and parses the file with properties. A test is launched to check the uniqueness of the - * current properties and properties that were specified in the previous iteration. It is checked - * that the generated Spring class TarantoolProperty is equal to the class written to the file. - * Next, the next entry to the file occurs, after which there is a forced reload of the Spring - * context -> the file with properties is parsed again and everything happens according to circle. - */ -@SpringBootTest(classes = {TarantoolPropertiesTest.Config.class}) -@TestPropertySource(properties = {Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -@Timeout(5) -public class TarantoolPropertiesTest { - - private static TarantoolProperties writtenToFileProperties; - private static TarantoolProperties prevSpringParsedProperties; - private static TarantoolProperties prevWrittenToFileProperties; - @Autowired private TarantoolProperties springParsedProperties; - - @MockitoBean private TarantoolCrudClient client; - - @BeforeAll - static void beforeAll() throws IOException { - writtenToFileProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @AfterAll - static void afterAll() throws IOException { - Files.deleteIfExists( - TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR.resolve( - Constants.DEFAULT_PROPERTY_FILE_NAME)); - } - - /** - * The annotation allows you to tell Spring that the context is dirty and needs to be reloaded - * after the test. - */ - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) - @RepeatedTest(10) - void testParseProperty() throws IOException { - assertNotEquals(prevWrittenToFileProperties, writtenToFileProperties); - assertNotEquals(prevSpringParsedProperties, springParsedProperties); - assertEquals(writtenToFileProperties, springParsedProperties); - - prevWrittenToFileProperties = writtenToFileProperties; - prevSpringParsedProperties = springParsedProperties; - - // Write the Properties class that will be parsed by Spring in the next iteration. - writtenToFileProperties = - TarantoolTestSupport.writeTestPropertiesYaml(Constants.DEFAULT_PROPERTY_FILE_NAME); - } - - @EnableTarantoolRepositories - static class Config {} -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/BaseIntegrationTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/BaseIntegrationTest.java deleted file mode 100644 index b46af069..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/BaseIntegrationTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.integration; - -import java.io.IOException; -import java.nio.file.Files; -import java.time.Duration; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Timeout; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.cluster.ClusterContainer; -import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer; -import org.testcontainers.containers.cluster.vshard.VshardClusterContainer; -import org.testcontainers.containers.output.Slf4jLogConsumer; - -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.DEFAULT_TEST_PROPERTY_DIR; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.writeTestPropertiesYaml; -import io.tarantool.spring.data40.config.properties.TarantoolProperties; - -@Timeout(60) -public abstract class BaseIntegrationTest { - - protected static ClusterContainer clusterContainer; - - private static final String dockerRegistry = - System.getenv().getOrDefault("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", ""); - - @BeforeAll - protected static void beforeAll() throws IOException { - configureContainer(); - writeConfigurationFile(); - } - - private static void configureContainer() { - if (!isCartridgeAvailable()) { - VshardClusterContainer vshardClusterContainer = - new VshardClusterContainer( - "vshard_cluster/Dockerfile", - dockerRegistry + "vshard-cluster-java", - "vshard_cluster/instances.yaml", - "vshard_cluster/config.yaml", - "tarantool/tarantool"); - - if (!vshardClusterContainer.isRunning()) { - vshardClusterContainer.withPrivilegedMode(true); - vshardClusterContainer.start(); - } - clusterContainer = vshardClusterContainer; - } else { - CartridgeClusterContainer cartridgeContainer = - new CartridgeClusterContainer( - "cartridge/Dockerfile", - dockerRegistry + "cartridge", - "cartridge/instances.yml", - "cartridge/replicasets.yml", - org.testcontainers.containers.Arguments.get("tarantool/tarantool")) - .withStartupTimeout(Duration.ofMinutes(5)) - .withLogConsumer( - new Slf4jLogConsumer(LoggerFactory.getLogger(BaseIntegrationTest.class))); - - if (!cartridgeContainer.isRunning()) { - cartridgeContainer.start(); - } - clusterContainer = cartridgeContainer; - } - } - - private static void writeConfigurationFile() throws IOException { - final TarantoolProperties properties = new TarantoolProperties(); - properties.setHost(clusterContainer.getHost()); - properties.setPort(clusterContainer.getPort()); - properties.setUserName(clusterContainer.getUsername()); - properties.setPassword(clusterContainer.getPassword()); - - writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME, properties); - } - - @AfterAll - protected static void afterAll() throws IOException { - Files.deleteIfExists(DEFAULT_TEST_PROPERTY_DIR.resolve(DEFAULT_PROPERTY_FILE_NAME)); - } - - protected static String getHost() { - return clusterContainer.getHost(); - } - - protected static int getPort() { - return clusterContainer.getPort(); - } - - protected static String getUsername() { - return clusterContainer.getUsername(); - } - - protected static String getPassword() { - return clusterContainer.getPassword(); - } - - protected static boolean isCartridgeAvailable() { - return System.getenv().getOrDefault("TARANTOOL_VERSION", "").matches("2.*"); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/CrudConfigurations.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/CrudConfigurations.java deleted file mode 100644 index 12faa20d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/CrudConfigurations.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.integration.crud; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.TestPropertySource; - -import static io.tarantool.client.TarantoolClient.DEFAULT_TAG; -import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.PERSON_SPACE; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.pool.InstanceConnectionGroup; -import io.tarantool.spring.data40.integration.BaseIntegrationTest; -import io.tarantool.spring.data40.repository.config.EnableTarantoolRepositories; - -@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH}) -abstract class CrudConfigurations extends BaseIntegrationTest { - - @Autowired protected TarantoolCrudClient client; - - private static InstanceConnectionGroup groupFromJavaConfig; - - private static final String PACKAGE_PATH = "io.tarantool.spring.data40.utils.core"; - - @BeforeAll - protected static void beforeAll() throws IOException { - BaseIntegrationTest.beforeAll(); - groupFromJavaConfig = - InstanceConnectionGroup.builder() - .withHost(clusterContainer.getHost()) - .withPort(clusterContainer.getPort()) - .withUser(getUsername()) - .withPassword(getPassword()) - .withTag(DEFAULT_TAG) - .withSize(4) - .build(); - } - - @BeforeEach - public void truncateSpaces() { - client.space(PERSON_SPACE).truncate().join(); - client.space(COMPLEX_PERSON_SPACE).truncate().join(); - } - - @EnableTarantoolRepositories(basePackages = {PACKAGE_PATH}) - @Configuration - static class JavaConfigConfiguration { - - @Bean - TarantoolCrudClientBuilder crudClientBuilder() { - return TarantoolFactory.crud().withGroups(Collections.singletonList(groupFromJavaConfig)); - } - } - - @EnableTarantoolRepositories(basePackages = {PACKAGE_PATH}) - @Configuration - static class ViaPropertyFileConfiguration {} - - @Test - void testSimpleClient() { - TarantoolCrudSpace space = client.space(PERSON_SPACE); - - assertEquals(0, space.select().join().size()); - - List tuple = Arrays.asList(0, true, "petya"); - List insertTuple = space.insert(tuple).join().get(); - - assertEquals(tuple, insertTuple.subList(0, insertTuple.size() - 1)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/GenericRepositoryTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/GenericRepositoryTest.java deleted file mode 100644 index 5de54a7b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/GenericRepositoryTest.java +++ /dev/null @@ -1,2095 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.integration.crud; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Limit; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.util.Streamable; - -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data40.query.TarantoolQueryCreator.INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.UNKNOWN_PERSON; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.generateAndInsertPersons; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.client.crud.TarantoolCrudSpace; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.mapping.Tuple; -import io.tarantool.spring.data.query.Conditions; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data.utils.Pair; -import io.tarantool.spring.data40.query.TarantoolPageRequest; -import io.tarantool.spring.data40.query.TarantoolScrollPosition; -import io.tarantool.spring.data40.query.TarantoolWindowIterator; -import io.tarantool.spring.data40.utils.TarantoolTestSupport; -import io.tarantool.spring.data40.utils.core.ComplexPersonRepository; -import io.tarantool.spring.data40.utils.core.GenericPaginationMethods; -import io.tarantool.spring.data40.utils.core.PersonRepository; -import io.tarantool.spring.data40.utils.entity.ComplexPerson; -import io.tarantool.spring.data40.utils.entity.Person; - -abstract class GenericRepositoryTest extends CrudConfigurations { - - @Autowired protected ApplicationContext context; - - protected static BiFunction> - complexPersonGenerateAndInsertFunction = - (context, personCount) -> - generateAndInsertComplexPersons( - personCount, context.getBean(TarantoolCrudClient.class)); - - protected static BiFunction> - personGenerateAndInsertFunction = - (context, personCount) -> - generateAndInsertPersons(personCount, context.getBean(TarantoolCrudClient.class)); - - protected static Function> complexPersonGenerateFunction = - TarantoolTestSupport::generateComplexPersons; - - protected static Function> personGenerateFunction = - TarantoolTestSupport::generatePersons; - - protected static final int INDEX_ID_VALUE = 50; - - protected static final Pair PERSON_INDEX_KEY = Pair.of("pk", INDEX_ID_VALUE); - - protected static final Pair PERSON_INITIAL_INDEX_KEY = - Pair.of("pk", Collections.emptyList()); - - protected static Stream dataForTestRepositoryWithFindByIs() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByIs") - , ID> void testRepositoryWithFindByIs( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - List foundPersons = repository.findByName(person.getName()); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(1, foundPersons.size()); - assertEquals(person, foundPersons.get(0)); - } - - protected static Stream dataForTestRepositoryWithFindById() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindById") - , ID> void testRepositoryWithFindById( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - Optional foundPerson = repository.findById(person.generateFullKey()); - - assertTrue(foundPerson.isPresent()); - assertEquals(person, foundPerson.get()); - } - - protected static Stream dataForTestRepositoryWithFindAllById() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllById") - , ID> void testRepositoryWithFindAllById( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - Iterable foundPersons = - repository.findAllById( - persons.stream().map(PERSON::generateFullKey).collect(Collectors.toList())); - List foundPersonsAsList = - StreamSupport.stream(foundPersons.spliterator(), false) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(persons, foundPersonsAsList); - } - - protected static Stream dataForTestRepositoryWithCount() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithCount") - , ID> void testRepositoryWithCount( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - assertEquals(PERSONS_COUNT, context.getBean(repositoryClass).count()); - } - - protected static Stream dataForTestRepositoryWithCountBy() { - return dataForTestRepositoryWithFindByIs(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithCountBy") - , ID> void testRepositoryWithCountBy( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(0); - assertEquals(1, repository.countByName(person.getName())); - } - - protected static Stream dataForTestRepositoryWithDelete() { - return Stream.of( - Arguments.of( - personGenerateFunction, - PersonRepository.class, - PERSON_SPACE, - (BiFunction>) - (space, key) -> { - Tuple tuple = - space.get(Collections.singletonList(key), Person.class).join(); - if (tuple != null) { - return tuple.get(); - } - return null; - }), - Arguments.of( - complexPersonGenerateFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (BiFunction>) - (space, key) -> { - Tuple tuple = space.get(key, ComplexPerson.class).join(); - if (tuple != null) { - return tuple.get(); - } - return null; - })); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithDelete") - , ID> void testRepositoryWithDelete( - Function> generateFunction, - Class> repositoryClass, - String spaceName, - BiFunction spaceGetFunction) { - - final List persons = generateFunction.apply(PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - space.insertMany(persons).join(); - - final PERSON deletingPerson = persons.get(0); - - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - // by object - repository.delete(deletingPerson); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - space.insert(deletingPerson).join(); - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - // by id - repository.deleteById(deletingPerson.generateFullKey()); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - space.insert(deletingPerson).join(); - assertEquals(deletingPerson, spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - - // by name - repository.deleteByName(deletingPerson.getName()); - assertNull(spaceGetFunction.apply(space, deletingPerson.generateFullKey())); - } - - protected static Stream dataForTestRepositoryWithExistId() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiConsumer) - (space, key) -> space.delete(Collections.singletonList(key)).join(), - PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - (BiConsumer) (space, key) -> space.delete(key).join(), - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithExistId") - , ID> void testRepositoryWithExistId( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - BiConsumer deleteConsumer, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final PERSON person = persons.get(0); - - assertTrue(repository.existsById(person.generateFullKey())); - deleteConsumer.accept(space, person.generateFullKey()); - assertFalse(repository.existsById(person.generateFullKey())); - } - - protected static Stream dataForTestQueryAnnotationAsCall() { - return Stream.of( - Arguments.of(PersonRepository.class), Arguments.of(ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsCall") - , ID> void testQueryAnnotationAsCall( - Class> repositoryClass) { - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - assertEquals(Arrays.asList(1, "hi", false), repository.getStatic().get()); - } - - protected static Stream dataForTestQueryAnnotationAsCallWithArgs() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsCallWithArgs") - , ID> void testQueryAnnotationAsCallWithArgs( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals(Arrays.asList("hello", true, 13), repository.echo("hello", true, 13).get()); - } - - protected static Stream dataForTestQueryAnnotationAsEval() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsEval") - , ID> void testQueryAnnotationAsEval( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals(Arrays.asList("hello", 123, true), repository.evalGetStatic().get()); - } - - protected static Stream dataForTestQueryAnnotationAsEvalWithArgs() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestQueryAnnotationAsEvalWithArgs") - , ID> void testQueryAnnotationAsEvalWithArgs( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertEquals( - Arrays.asList("hello", true, 13), repository.evalWithArgs("hello", true, 13).get()); - } - - protected static Stream dataForTestRepositoryWithExistName() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiConsumer) - (space, key) -> space.delete(Collections.singletonList(key)).join(), - PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - (BiConsumer) (space, key) -> space.delete(key).join(), - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithExistName") - , ID> void testRepositoryWithExistName( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - BiConsumer deleteConsumer, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final PERSON person = persons.get(0); - - assertTrue(repository.existsByName(person.getName())); - deleteConsumer.accept(space, person.generateFullKey()); - assertFalse(repository.existsByName(person.getName())); - } - - protected static Stream dataForTestRepositoryWithFindByLessThan() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByLessThan") - , ID> void testRepositoryWithFindByLessThan( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 10; - final List foundPersons = repository.findAllByIdIsLessThan(findLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(findLimiter, foundPersons.size()); - assertEquals(persons.subList(0, findLimiter), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsTrue() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsTrue") - , ID> void testRepositoryWithFindAllByIsMarriedIsTrue( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsTrue(); - assertEquals(PERSONS_COUNT / 3, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(GenericPerson::getIsMarried)); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsFalse() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsFalse") - , ID> void testRepositoryWithFindAllByIsMarriedIsFalse( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsFalse(); - assertEquals(PERSONS_COUNT / 3, foundPersons.size()); - assertTrue(foundPersons.stream().noneMatch(GenericPerson::getIsMarried)); - } - - protected static Stream dataForTestRepositoryWithFindAllByIsMarriedIsNull() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByIsMarriedIsNull") - , ID> void testRepositoryWithFindAllByIsMarriedIsNull( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List foundPersons = repository.findAllByIsMarriedIsNull(); - assertEquals(PERSONS_COUNT / 3 + 1, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(p -> p.getIsMarried() == null)); - } - - protected static Stream dataForTestRepositoryWithFindAllByNameIsEmpty() { - return Stream.of( - Arguments.of(personGenerateFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindAllByNameIsEmpty") - , ID> void testRepositoryWithFindAllByNameIsEmpty( - Function> generateFunction, - Class> repositoryClass) { - - List persons = generateFunction.apply(PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - PERSON person = persons.get(0); - person.setName(""); - persons.set(0, person); - - repository.saveAll(persons); - - final List foundPersons = repository.findAllByNameIsEmpty(); - assertEquals(1, foundPersons.size()); - assertTrue(foundPersons.stream().allMatch(p -> p.getName().isEmpty())); - } - - protected static Stream dataForTestRepositoryWithFindByLessThanEqual() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByLessThanEqual") - , ID> void testRepositoryWithFindByLessThanEqual( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 10; - final List foundPersonsWithEqual = repository.findAllByIdLessThanEqual(findLimiter); - - foundPersonsWithEqual.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(findLimiter + 1, foundPersonsWithEqual.size()); - assertEquals(persons.subList(0, findLimiter + 1), foundPersonsWithEqual); - } - - protected static Stream dataForTestRepositoryWithFindByGreaterThan() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByGreaterThan") - , ID> void testRepositoryWithFindByGreaterThan( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 90; - final List foundPersons = repository.findAllByIdIsGreaterThan(findLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(PERSONS_COUNT - findLimiter - 1, foundPersons.size()); - assertEquals(persons.subList(findLimiter + 1, PERSONS_COUNT), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindByGreaterThanEqual() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByGreaterThanEqual") - , ID> void testRepositoryWithFindByGreaterThanEqual( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int findLimiter = 90; - final List foundPersonsWithEqual = repository.findAllByIdGreaterThanEqual(findLimiter); - - foundPersonsWithEqual.sort(Comparator.comparing(PERSON::getId)); - - assertEquals(PERSONS_COUNT - findLimiter, foundPersonsWithEqual.size()); - assertEquals(persons.subList(findLimiter, PERSONS_COUNT), foundPersonsWithEqual); - } - - protected static Stream dataForTestRepositoryWithFindByBetween() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByBetween") - , ID> void testRepositoryWithFindByBetween( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int startFindLimiter = 50; - final int endFindLimiter = 90; - final List foundPersons = - repository.findAllByIdBetween(startFindLimiter, endFindLimiter); - - foundPersons.sort(Comparator.comparing(PERSON::getId)); - - final int foundPersonsCount = endFindLimiter - startFindLimiter - 1; - assertEquals(foundPersonsCount, foundPersons.size()); - assertEquals(persons.subList(startFindLimiter + 1, endFindLimiter), foundPersons); - } - - protected static Stream dataForTestRepositoryWithFindByBetweenNegativeInts() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithFindByBetweenNegativeInts") - , ID> void testRepositoryWithFindByBetweenNegativeInts( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int startFindLimiter = -1; - final int endFindLimiter = -10; - final List foundPersons = - repository.findAllByIdBetween(startFindLimiter, endFindLimiter); - assertTrue(foundPersons.isEmpty()); - } - - protected static Stream dataForTestRepositoryIgnoreCase() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryIgnoreCase") - , ID> void testRepositoryIgnoreCase( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - final String name = persons.get(0).getName(); - - final InvalidDataAccessApiUsageException exception = - assertThrows( - InvalidDataAccessApiUsageException.class, () -> repository.findByNameIgnoreCase(name)); - final String EXCEPTION_MESSAGE = - String.format( - INVALID_DATA_ACCESS_API_USAGE_EXCEPTION_MESSAGE_TEMPLATE - + "IgnoreCase isn't supported yet", - Part.Type.SIMPLE_PROPERTY); - assertEquals(EXCEPTION_MESSAGE, exception.getMessage()); - } - - protected static Stream dataForTestRepositoryWithTarantoolNamingNotation() { - return dataForTestRepositoryWithFindByLessThan(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryWithTarantoolNamingNotation") - , ID> void testRepositoryWithTarantoolNamingNotation( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final List marriedPersons = repository.findByIsMarried(true); - final List nonMarriedPersons = repository.findByIsMarried(false); - final int expectedCount = PERSONS_COUNT / 3; - assertEquals(expectedCount, marriedPersons.size()); - assertEquals(expectedCount, nonMarriedPersons.size()); - } - - protected static Stream dataForTestRepositoryNotEnoughArguments() { - return dataForTestQueryAnnotationAsCall(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryNotEnoughArguments") - , ID> void testRepositoryNotEnoughArguments( - Class> repositoryClass) { - - GenericRepositoryMethods repository = context.getBean(repositoryClass); - assertThrows(InvalidDataAccessApiUsageException.class, repository::findById); - } - - protected static Stream dataForTestRepositorySave() { - return dataForTestRepositoryWithDelete(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySave") - , ID> void testRepositorySave( - Function> generateFunction, - Class> repositoryClass, - String spaceName, - BiFunction getFunction) { - - List persons = generateFunction.apply(PERSONS_COUNT); - GenericRepositoryMethods repository = context.getBean(repositoryClass); - TarantoolCrudSpace space = client.space(spaceName); - final PERSON person = persons.get(0); - - repository.save(person); - - PERSON gotPerson = getFunction.apply(space, person.generateFullKey()); - assertEquals(person, gotPerson); - } - - protected static Stream dataForTestRepositorySaveAll() { - Conditions conditions = new Conditions(); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - PERSON_SPACE, - (Function>) - (space) -> unwrapTuples(space.select(conditions, Person.class).join())), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (Function>) - (space) -> unwrapTuples(space.select(conditions, ComplexPerson.class).join()))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySaveAll") - , ID> void testRepositorySaveAll( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - Function> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - repository.saveAll(persons); - - List selectedPersons = selectFunction.apply(space); - selectedPersons.sort(Comparator.comparing(GenericPerson::getId)); - - assertEquals(persons, selectedPersons); - } - - protected static Stream dataForTestDeleteAll() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class, PERSON_SPACE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteAll") - , ID> void testDeleteAll( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow(() -> repository.deleteAll()); - assertEquals(0, space.count(new Conditions()).join()); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow(() -> repository.deleteAll(persons)); - assertEquals(0, space.count(new Conditions()).join()); - - repository.saveAll(persons); - assertEquals(PERSONS_COUNT, space.count(new Conditions()).join()); - assertDoesNotThrow( - () -> - repository.deleteAllById( - persons.stream().map(PERSON::generateFullKey).collect(Collectors.toList()))); - assertEquals(0, space.count(new Conditions()).join()); - } - - protected static Stream dataForTestRepositoryFindByAfter() { - return Stream.of( - Arguments.of(personGenerateAndInsertFunction, PersonRepository.class), - Arguments.of(complexPersonGenerateAndInsertFunction, ComplexPersonRepository.class)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByAfter") - , ID> void testRepositoryFindByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - final List selectedPersons = repository.findByNameAfter(person.getName()); - selectedPersons.sort(Comparator.comparing(PERSON::getName)); - - final List expectedList = - persons.stream() - .filter(p -> p.getName().compareTo(person.getName()) > 0) - .limit(SelectOptions.DEFAULT_LIMIT) - .sorted(Comparator.comparing(PERSON::getName)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - } - - protected static Stream dataForTestRepositoryFindByAfterWithLimit() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByAfterWithLimit") - , ID> void testRepositoryFindByAfterWithLimit( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int LIMIT = 5; - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findFirst5ByIdAfter(person.getId()); - selectedPersons.sort(Comparator.comparing(PERSON::getId)); - - final List selectedPersonsWithTopKeyword = repository.findTop5ByIdAfter(person.getId()); - selectedPersonsWithTopKeyword.sort(Comparator.comparing(PERSON::getId)); - - final List expectedList = - persons.stream() - .filter(p -> p.getId().compareTo(person.getId()) > 0) - .limit(LIMIT) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - - assertEquals(expectedList.size(), selectedPersonsWithTopKeyword.size()); - assertEquals(expectedList, selectedPersonsWithTopKeyword); - } - - protected static Stream dataForTestRepositoryFindByBefore() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByBefore") - , ID> void testRepositoryFindByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findByNameBefore(person.getName()); - selectedPersons.sort(Comparator.comparing(PERSON::getName)); - - final List expectedList = - persons.stream() - .filter(p -> p.getName().compareTo(person.getName()) < 0) - .limit(SelectOptions.DEFAULT_LIMIT) - .sorted(Comparator.comparing(PERSON::getName)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - } - - protected static Stream dataForTestRepositoryFindByBeforeWithLimit() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryFindByBeforeWithLimit") - , ID> void testRepositoryFindByBeforeWithLimit( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int LIMIT = 5; - final PERSON person = persons.get(ThreadLocalRandom.current().nextInt(0, persons.size())); - - final List selectedPersons = repository.findFirst5ByIdBefore(person.getId()); - selectedPersons.sort(Comparator.comparing(PERSON::getId)); - - final List selectedPersonsWithTopKeyword = - repository.findTop5ByIdBefore(person.getId()); - selectedPersonsWithTopKeyword.sort(Comparator.comparing(PERSON::getId)); - - // Because id (not fullscan) - persons.sort(Comparator.comparing(PERSON::getId, (o1, o2) -> Integer.compare(o2, o1))); - - final List expectedList = - persons.stream() - .filter(p -> p.getId().compareTo(person.getId()) < 0) - .limit(LIMIT) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - - assertEquals(expectedList.size(), selectedPersons.size()); - assertEquals(expectedList, selectedPersons); - - assertEquals(expectedList.size(), selectedPersonsWithTopKeyword.size()); - assertEquals(expectedList, selectedPersonsWithTopKeyword); - } - - protected static Stream dataForTestDeleteByAfter() { - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - PERSON_SPACE, - (BiFunction>) - (space, options) -> - unwrapTuples( - space.select(Collections.emptyList(), options, Person.class).join())), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - COMPLEX_PERSON_SPACE, - (BiFunction>) - (space, options) -> - unwrapTuples( - space - .select(Collections.emptyList(), options, ComplexPerson.class) - .join()))); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteByAfter") - , ID> void testDeleteByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - BiFunction> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - persons.sort(Comparator.comparing(PERSON::getName)); - - final int RANDOM_INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final SelectOptions options = SelectOptions.builder().withFirst(PERSONS_COUNT).build(); - final PERSON deletingAfterPerson = persons.get(RANDOM_INDEX); - - final List deletedPersons = repository.deleteByNameAfter(deletingAfterPerson.getName()); - - List allPersonsInBaseAfterDeleted = selectFunction.apply(space, options); - assertEquals(PERSONS_COUNT - deletedPersons.size(), allPersonsInBaseAfterDeleted.size()); - - persons.removeAll(deletedPersons); - allPersonsInBaseAfterDeleted.sort(Comparator.comparing(PERSON::getId)); - persons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(persons, allPersonsInBaseAfterDeleted); - } - - protected static Stream dataForTestDeleteByBefore() { - return dataForTestDeleteByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestDeleteByBefore") - , ID> void testDeleteByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass, - String spaceName, - BiFunction> selectFunction) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - final TarantoolCrudSpace space = client.space(spaceName); - - final SelectOptions options = SelectOptions.builder().withFirst(PERSONS_COUNT).build(); - final int RANDOM_INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - - final PERSON deletingBeforePerson = persons.get(RANDOM_INDEX); - final List deletedPersons = - repository.deleteByNameBefore(deletingBeforePerson.getName()); - - List allPersonsInBaseAfterDeleted = selectFunction.apply(space, options); - - assertEquals(PERSONS_COUNT - deletedPersons.size(), allPersonsInBaseAfterDeleted.size()); - - persons.removeAll(deletedPersons); - allPersonsInBaseAfterDeleted.sort(Comparator.comparing(PERSON::getId)); - persons.sort(Comparator.comparing(PERSON::getId)); - assertEquals(persons, allPersonsInBaseAfterDeleted); - } - - protected static Stream dataForTestCountByAfter() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestCountByAfter") - , ID> void testCountByAfter( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - final int INDEX = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final int ID_AFTER = persons.get(INDEX).getId(); - - final long count = repository.countByIdAfter(ID_AFTER); - - final int EXPECTED_COUNT = PERSONS_COUNT - ID_AFTER - 1; - assertEquals(EXPECTED_COUNT, count); - } - - protected static Stream dataForTestCountByBefore() { - return dataForTestRepositoryFindByAfter(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestCountByBefore") - , ID> void testCountByBefore( - BiFunction> generateAndInsertFunction, - Class> repositoryClass) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - final GenericRepositoryMethods repository = context.getBean(repositoryClass); - - persons.sort(Comparator.comparing(PERSON::getName)); - - final int indexBefore = ThreadLocalRandom.current().nextInt(0, PERSONS_COUNT); - final String name = persons.get(indexBefore).getName(); - final long count = repository.countByNameBefore(name); - - assertEquals(indexBefore, count); - - final long unknownNameCount = repository.countByNameBefore(UNKNOWN_PERSON.getName()); - assertEquals(0, unknownNameCount); - } - - protected static < - REPO extends GenericPaginationMethods, PERSON extends GenericPerson, ID> - Stream dataForTestRepositorySlicePagePageableEqual() { - final int PAGE_SIZE = ThreadLocalRandom.current().nextInt(1, PERSONS_COUNT / 3 - 1); - final String NAME = "name"; - final Pageable beginPageable = new TarantoolPageRequest>(PAGE_SIZE); - - BiFunction> generatePersonAndInsertFunction = - (context, size) -> - generateAndInsertPersons( - size, context.getBean(TarantoolCrudClient.class), (person) -> person.setName(NAME)); - - BiFunction> - generateComplexPersonAndInsertFunction = - (context, size) -> - generateAndInsertComplexPersons( - size, - context.getBean(TarantoolCrudClient.class), - (person) -> person.setName(NAME)); - - Function personRepositoryFunc = - (context) -> context.getBean(PersonRepository.class); - - Function complexPersonRepositoryFunc = - (context) -> context.getBean(ComplexPersonRepository.class); - - BiFunction> executionForFindAllByName = - (repo, pageable) -> repo.findAllByName(NAME, pageable); - - Function, List> expectedListForFindAllByNameFunc = - (persons) -> - persons.stream() - .filter(person -> NAME.equals(person.getName())) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()) - .subList(0, PAGE_SIZE); - - BiFunction> executionForFindByName = - (repo, pageable) -> repo.findPersonByName(NAME, pageable); - - List> generateFunctionPairs = - Arrays.asList( - Arrays.asList(generatePersonAndInsertFunction, personRepositoryFunc), - Arrays.asList(generateComplexPersonAndInsertFunction, complexPersonRepositoryFunc)); - - List executionFunctions = Arrays.asList(executionForFindAllByName, executionForFindByName); - - // add arguments set - List arguments = new ArrayList<>(); - for (List generateFunctionPair : generateFunctionPairs) { - for (Object executionFunction : executionFunctions) { - arguments.add( - Arguments.of( - generateFunctionPair.get(0), - executionFunction, - generateFunctionPair.get(1), - expectedListForFindAllByNameFunc, - beginPageable)); - } - } - - return arguments.stream(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySlicePagePageableEqual") - , PERSON extends GenericPerson, ID> - void testRepositorySlicePagePageableEqual( - BiFunction> generateAndInsertFunction, - BiFunction> executingRepositoryMethod, - Function giveRepositoryFunction, - Function, List> expectedSlicePageContent, - Pageable beginPageable) { - - final List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - Slice slicePage = - executingRepositoryMethod.apply(giveRepositoryFunction.apply(context), beginPageable); - - assertEquals(beginPageable, slicePage.getPageable()); - assertEquals(expectedSlicePageContent.apply(persons), slicePage.getContent()); - } - - protected static Stream dataForTestRepositorySliceMethodWithoutPageable() { - final String NAME = "name"; - return Stream.of( - Arguments.of(PersonRepository.class, NAME), - Arguments.of(ComplexPersonRepository.class, NAME)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySliceMethodWithoutPageable") - , ID> void testRepositorySliceMethodWithoutPageable( - Class> repositoryClass, String name) { - GenericPaginationMethods repository = context.getBean(repositoryClass); - - assertEquals(Pageable.unpaged(), repository.findAllByName(name).getPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).nextPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).nextOrLastPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).previousPageable()); - assertEquals(Pageable.unpaged(), repository.findAllByName(name).previousOrFirstPageable()); - } - - @SuppressWarnings("unchecked") - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Stream dataForTestRepositorySliceWithDifferentFields() { - final int PAGE_SIZE = 10; - - Function, Pageable> nextPageableFunc = Slice::nextPageable; - Function, Pageable> prevPageableFunc = Slice::previousPageable; - Function, Pageable> nextOrLastPageableFunc = Slice::nextOrLastPageable; - Function, Pageable> prevOrFirstPageableFunc = Slice::previousOrFirstPageable; - BiFunction predicateForNextPageableFunc = - (currentPageable, nextPageable) -> nextPageable.isPaged(); - - BiFunction predicateForNextOrPageableFunc = - (currentPageable, nextPageable) -> !currentPageable.equals(nextPageable); - - Function personRepositoryFunc = - (context) -> context.getBean(PersonRepository.class); - - Function complexPersonRepositoryFunc = - (context) -> context.getBean(ComplexPersonRepository.class); - - Pageable beginPageable = new TarantoolPageRequest<>(PAGE_SIZE); - - BiFunction, Integer, Integer> idExtractionFunction = - (args, index) -> { - List persons = (List) args.get(0); - return persons.get(index).getId(); - }; - - BiFunction, Integer, String> nameExtractionFunction = - (args, index) -> { - List persons = (List) args.get(0); - return persons.get(index).getName(); - }; - - BiFunction, Slice> executionForFindAllByIdLessThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, PERSONS_COUNT - 1); - return repo.findAllByIdLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByIdLessThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, PERSONS_COUNT - 1); - return repo.findPersonByIdLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByIdGreaterThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, 0); - return repo.findAllByIdGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByIdGreaterThanEqualFunc = - (repo, arguments) -> { - int key = idExtractionFunction.apply(arguments, 0); - return repo.findPersonByIdGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByIsMarriedLessThanEqual = - (repo, arguments) -> - repo.findAllByIsMarriedLessThanEqual(false, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindPersonByIsMarriedLessThanEqual = - (repo, arguments) -> - repo.findPersonByIsMarriedLessThanEqual(false, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindAllByIsMarriedGreaterThanEqual = - (repo, arguments) -> - repo.findAllByIsMarriedGreaterThanEqual(null, (Pageable) arguments.get(1)); - - BiFunction, Slice> - executionForFindPersonByIsMarriedGreaterThanEqual = - (repo, arguments) -> - repo.findPersonByIsMarriedGreaterThanEqual(null, (Pageable) arguments.get(1)); - - BiFunction, Slice> executionForFindAllByNameLessThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findAllByNameLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByNameLessThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findPersonByNameLessThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAllByNameGreaterThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findAllByNameGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindPersonByNameGreaterThanEqual = - (repo, arguments) -> { - String key = nameExtractionFunction.apply(arguments, PERSONS_COUNT / 2); - return repo.findPersonByNameGreaterThanEqual(key, (Pageable) arguments.get(1)); - }; - - BiFunction, Slice> executionForFindAll = - (repo, arguments) -> repo.findAll((Pageable) arguments.get(1)); - - Function, List> expectedListForFindAllByIdLessThanEqualFunc = - (persons) -> - persons.stream() - .sorted(Comparator.comparing(PERSON::getId).reversed()) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByIdGreaterThanEqualFunc = - (persons) -> persons; - - Function, List> expectedListForFindAllByIsMarriedGreaterThanEqual = - (persons) -> - persons.stream() - .sorted( - Comparator.comparing( - PERSON::getIsMarried, Comparator.nullsFirst(Comparator.naturalOrder()))) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByIsMarriedLessThanEqual = - (persons) -> - persons.stream() - .filter(person -> person.getIsMarried() == null || !person.getIsMarried()) - .sorted( - Comparator.comparing( - PERSON::getIsMarried, Comparator.nullsLast(Comparator.naturalOrder())) - .thenComparing(Comparator.comparing(PERSON::getId).reversed())) - .collect(Collectors.toList()); - - Function, List> expectedListForFindAllByNameLessThanEqual = - (persons) -> { - String name = persons.get(persons.size() / 2).getName(); - return persons.stream() - .filter(person -> person.getName().compareTo(name) <= 0) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - }; - - Function, List> expectedListForFindAllByNameGreaterThanEqual = - (persons) -> { - String name = persons.get(persons.size() / 2).getName(); - return persons.stream() - .filter(person -> person.getName().compareTo(name) >= 0) - .sorted(Comparator.comparing(PERSON::getId)) - .collect(Collectors.toList()); - }; - - Function, List> expectedListForFindAll = (persons) -> persons; - - List> getNextPageableMethodFunctionPairs = - Arrays.asList( - Arrays.asList(nextPageableFunc, prevPageableFunc, predicateForNextPageableFunc), - Arrays.asList( - nextOrLastPageableFunc, prevOrFirstPageableFunc, predicateForNextOrPageableFunc)); - - List> generateFunctions = - Arrays.asList( - Arrays.asList(personGenerateAndInsertFunction, personRepositoryFunc), - Arrays.asList(complexPersonGenerateAndInsertFunction, complexPersonRepositoryFunc)); - - List> executeExpectedFunctionPairs = - Arrays.asList( - Arrays.asList( - executionForFindAllByIdLessThanEqualFunc, - expectedListForFindAllByIdLessThanEqualFunc), - Arrays.asList( - executionForFindAllByIdGreaterThanEqualFunc, - expectedListForFindAllByIdGreaterThanEqualFunc), - Arrays.asList( - executionForFindAllByIsMarriedGreaterThanEqual, - expectedListForFindAllByIsMarriedGreaterThanEqual), - Arrays.asList( - executionForFindAllByIsMarriedLessThanEqual, - expectedListForFindAllByIsMarriedLessThanEqual), - Arrays.asList( - executionForFindAllByNameLessThanEqual, expectedListForFindAllByNameLessThanEqual), - Arrays.asList( - executionForFindAllByNameGreaterThanEqual, - expectedListForFindAllByNameGreaterThanEqual), - Arrays.asList( - executionForFindPersonByIdLessThanEqualFunc, - expectedListForFindAllByIdLessThanEqualFunc), - Arrays.asList( - executionForFindPersonByIdGreaterThanEqualFunc, - expectedListForFindAllByIdGreaterThanEqualFunc), - Arrays.asList( - executionForFindPersonByIsMarriedGreaterThanEqual, - expectedListForFindAllByIsMarriedGreaterThanEqual), - Arrays.asList( - executionForFindPersonByIsMarriedLessThanEqual, - expectedListForFindAllByIsMarriedLessThanEqual), - Arrays.asList( - executionForFindPersonByNameLessThanEqual, - expectedListForFindAllByNameLessThanEqual), - Arrays.asList( - executionForFindPersonByNameGreaterThanEqual, - expectedListForFindAllByNameGreaterThanEqual), - Arrays.asList(executionForFindAll, expectedListForFindAll)); - - // add arguments set - List arguments = new ArrayList<>(); - for (List generateFunctionPair : generateFunctions) { - for (List getNextPrevPageableFuncTriple : getNextPageableMethodFunctionPairs) { - for (List executeExpectedFunctionPair : executeExpectedFunctionPairs) { - arguments.add( - Arguments.of( - generateFunctionPair.get(0), - generateFunctionPair.get(1), - executeExpectedFunctionPair.get(0), - getNextPrevPageableFuncTriple.get(0), - getNextPrevPageableFuncTriple.get(1), - getNextPrevPageableFuncTriple.get(2), - executeExpectedFunctionPair.get(1), - beginPageable)); - } - } - } - return arguments.stream(); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositorySliceWithDifferentFields") - , ID> void testRepositorySliceWithDifferentFields( - BiFunction> generateAndInsertFunction, - Function> giveRepositoryFunction, - BiFunction, List, Slice> - executingRepositoryMethod, - Function, Pageable> nextPageableMethod, - Function, Pageable> prevPageableMethod, - BiFunction stopPaginationPredicateFunction, - Function, List> expectedResultListMovingFunction, - Pageable beginPageable) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - - // moving forward - Pageable nextPageable = beginPageable; - List> forwardSlices = new ArrayList<>(); - Slice slice; - do { - slice = - executingRepositoryMethod.apply( - giveRepositoryFunction.apply(context), Arrays.asList(persons, nextPageable)); - forwardSlices.add(slice); - nextPageable = nextPageableMethod.apply(slice); - } while (stopPaginationPredicateFunction.apply(slice.getPageable(), nextPageable)); - - List forwardMovingResultList = - forwardSlices.stream().flatMap(Streamable::stream).collect(Collectors.toList()); - assertEquals(expectedResultListMovingFunction.apply(persons), forwardMovingResultList); - - // moving backward - List> reverseSlices = new ArrayList<>(); - nextPageable = forwardSlices.get(forwardSlices.size() - 1).getPageable(); - do { - slice = - executingRepositoryMethod.apply( - giveRepositoryFunction.apply(context), Arrays.asList(persons, nextPageable)); - reverseSlices.add(slice); - nextPageable = prevPageableMethod.apply(slice); - } while (stopPaginationPredicateFunction.apply(slice.getPageable(), nextPageable)); - - List backwardMovingResultList = - reverseSlices.stream() - .sorted(Comparator.comparing(Slice::getNumber)) - .flatMap(Streamable::stream) - .collect(Collectors.toList()); - - assertEquals(expectedResultListMovingFunction.apply(persons), backwardMovingResultList); - } - - protected static , ID> - List expectedForwardFuncForFindFirst5ByIsMarriedInitial(List persons) { - return persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst5ByIsMarriedInitial(List persons) { - List result = - new ArrayList<>(expectedForwardFuncForFindFirst5ByIsMarriedInitial(persons)); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial( - List persons) { - return persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial( - List persons) { - List result = - new ArrayList<>( - expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial(persons)); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst5ByIsMarriedIndexKey(List persons) { - return persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst5ByIsMarriedIndexKey(List persons) { - List result = - new ArrayList<>( - persons.stream() - .filter(person -> Objects.equals(person.getIsMarried(), false)) - .sorted(Comparator.comparing(PERSON::getId)) - .toList()); - Collections.reverse(result); - return result; - } - - protected static , ID> - List expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey( - List persons) { - return persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId)) - .toList(); - } - - protected static , ID> - List expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey( - List persons) { - List result = - new ArrayList<>( - persons.stream() - .filter( - person -> { - if (person.getIsMarried() == null) { - return false; - } - int compare = Boolean.compare(person.getIsMarried(), false); - return compare >= 0; - }) - .sorted(Comparator.comparing(PERSON::getId)) - .toList()); - Collections.reverse(result); - return result; - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Window executionFunctionForFindFirst5ByIsMarried(REPO repository, List args) { - ScrollPosition scrollPosition = (ScrollPosition) args.get(0); - return repository.findFirst5ByIsMarried(false, scrollPosition); - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Window executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual( - REPO repository, List args) { - ScrollPosition scrollPosition = (ScrollPosition) args.get(0); - return repository.findFirst10ByIsMarriedGreaterThanEqual(false, scrollPosition); - } - - protected static < - PERSON extends GenericPerson, REPO extends GenericPaginationMethods> - Stream dataForTestRepositoryScrollForwardAndBackwardMoving() { - - ScrollPosition beginScrollPositionInitial = - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY); - ScrollPosition beginScrollPositionIndexKey = TarantoolScrollPosition.forward(PERSON_INDEX_KEY); - - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst5ByIsMarried, - (Function, List>) - GenericRepositoryTest::expectedForwardFuncForFindFirst5ByIsMarriedInitial, - (Function, List>) - GenericRepositoryTest::expectedBackwardFuncForFindFirst5ByIsMarriedInitial, - beginScrollPositionInitial), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst5ByIsMarried, - (Function, List>) - GenericRepositoryTest::expectedForwardFuncForFindFirst5ByIsMarriedIndexKey, - (Function, List>) - GenericRepositoryTest::expectedBackwardFuncForFindFirst5ByIsMarriedIndexKey, - beginScrollPositionIndexKey), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual, - (Function, List>) - GenericRepositoryTest - ::expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial, - (Function, List>) - GenericRepositoryTest - ::expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualInitial, - beginScrollPositionInitial), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - (BiFunction, Window>) - GenericRepositoryTest::executionFunctionForFindFirst10ByIsMarriedGreaterThanEqual, - (Function, List>) - GenericRepositoryTest - ::expectedForwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey, - (Function, List>) - GenericRepositoryTest - ::expectedBackwardFuncForFindFirst10ByIsMarriedGreaterThanEqualIndexKey, - beginScrollPositionIndexKey)); - } - - @ParameterizedTest - @MethodSource("dataForTestRepositoryScrollForwardAndBackwardMoving") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryScrollForwardAndBackwardMoving( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - BiFunction, Window> executingRepositoryMethod, - Function, List> expectedForwardResultFunction, - Function, List> expectedBackwardResultFunction, - ScrollPosition beginScrollPosition) { - - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - Window personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(beginScrollPosition)); - List forwardResult = new ArrayList<>(); - - while (!personWindow.isEmpty() && personWindow.hasNext()) { - personWindow.forEach(forwardResult::add); - ScrollPosition nextPosition = personWindow.positionAt(personWindow.size() - 1); - personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(nextPosition)); - } - personWindow.forEach(forwardResult::add); - - assertEquals(expectedForwardResultFunction.apply(persons), forwardResult); - - TarantoolScrollPosition backwardScrollPosition = - ((TarantoolScrollPosition) personWindow.positionAt(0)).reverse(); - List backwardResult = personWindow.getContent(); - Collections.reverse(backwardResult); - - personWindow = - executingRepositoryMethod.apply( - repository, Collections.singletonList(backwardScrollPosition)); - while (!personWindow.isEmpty() && personWindow.hasNext()) { - personWindow.forEach(backwardResult::add); - ScrollPosition nextPosition = personWindow.positionAt(personWindow.size() - 1); - personWindow = - executingRepositoryMethod.apply(repository, Collections.singletonList(nextPosition)); - } - personWindow.forEach(backwardResult::add); - - assertEquals(expectedBackwardResultFunction.apply(persons), backwardResult); - } - - protected static > - Stream dataForTestWindowIterator() { - return Stream.of( - Arguments.of( - (BiFunction>) - (context, size) -> Collections.emptyList(), - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY), - (Function, List>) (persons) -> Collections.emptyList(), - (Function, List>) (persons) -> Collections.emptyList()), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INITIAL_INDEX_KEY), - (Function, List>) (persons) -> persons, - (Function, List>) - (persons) -> { - Collections.reverse(persons); - return persons; - }), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - TarantoolScrollPosition.forward(PERSON_INDEX_KEY), - (Function, List>) - GenericRepositoryTest::expectedWindowIteratorForwardFromSomeCursor, - (Function, List>) - GenericRepositoryTest::expectedWindowIteratorBackwardFromSomeCursor)); - } - - protected static , ID> - List expectedWindowIteratorForwardFromSomeCursor(List persons) { - return persons.stream() - .filter(person -> person.getId() >= (int) PERSON_INDEX_KEY.getSecond()) - .collect(Collectors.toList()); - } - - protected static , ID> - List expectedWindowIteratorBackwardFromSomeCursor(List persons) { - return persons.stream() - .filter(person -> person.getId() <= (int) PERSON_INDEX_KEY.getSecond()) - .sorted(Comparator.comparing(PERSON::getId).reversed()) - .collect(Collectors.toList()); - } - - @ParameterizedTest - @MethodSource("dataForTestWindowIterator") - , ID, REPO extends GenericPaginationMethods> - void testWithWindowIteratorMoving( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - TarantoolScrollPosition beginScrollPosition, - Function, List> expectedForwardResultFunction, - Function, List> expectedBackwardResultFunction) { - List persons = generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - TarantoolWindowIterator personForwardIterator = - TarantoolWindowIterator.of( - scrollPosition -> - repository.findFirst10ByIsMarriedGreaterThanEqual(null, scrollPosition)) - .startingAt(beginScrollPosition); - - List forwardResult = new ArrayList<>(); - - while (personForwardIterator.hasNext()) { - forwardResult.add(personForwardIterator.next()); - } - - forwardResult.sort(Comparator.comparing(PERSON::getId)); - assertEquals(expectedForwardResultFunction.apply(persons), forwardResult); - - // go back - List backwardResult = new ArrayList<>(); - - TarantoolWindowIterator personBackwardIterator = - TarantoolWindowIterator.of( - scrollPosition -> - repository.findFirst10ByIsMarriedGreaterThanEqual(null, scrollPosition)) - .startingAt(beginScrollPosition.reverse()); - - while (personBackwardIterator.hasNext()) { - backwardResult.add(personBackwardIterator.next()); - } - - assertEquals(expectedBackwardResultFunction.apply(persons), backwardResult); - } - - protected static Stream dataForTestUnsupportedRepositoryMethods() { - return Stream.of(PersonRepository.class, ComplexPersonRepository.class); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestUnsupportedRepositoryMethods") - , ID, REPO extends GenericPaginationMethods> - void testUnsupportedRepositoryMethods(Class repositoryClass) { - final REPO repository = context.getBean(repositoryClass); - - assertThrows(UnsupportedOperationException.class, repository::findAll); - assertThrows(UnsupportedOperationException.class, () -> repository.findAll(Sort.unsorted())); - } - - protected static Stream dataForTestPageableWithTrueCursorAndPageNumber() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(PAGE_SIZE), - PAGES_COUNT, - PAGES_COUNT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(1, PAGE_SIZE, new Person(9, null, "User-9")), - PAGES_COUNT - 1, - PAGES_COUNT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - new TarantoolPageRequest<>(2, PAGE_SIZE, new Person(19, null, "User-19")), - PAGES_COUNT - 2, - PAGES_COUNT)); - } - - private static void doTestPageableWithCursorAndPageNumber( - Pageable pageable, - BiFunction> repositoryFunction, - BiConsumer>, List>> assertionAction) { - List> forwardPages = new ArrayList<>(); - - Slice page = repositoryFunction.apply(0, pageable); - - forwardPages.add(page); - - while (page.hasNext()) { - page = repositoryFunction.apply(0, page.nextOrLastPageable()); - forwardPages.add(page); - } - - List> backwardPages = new ArrayList<>(); - for (int i = forwardPages.size() - 1; i >= 0; i--) { - Slice currentPage = forwardPages.get(i); - if (currentPage.getPageable().isPaged()) { - page = currentPage; - break; - } - } - backwardPages.add(page); - - page = repositoryFunction.apply(0, page.previousOrFirstPageable()); - backwardPages.add(page); - - while (page.hasPrevious()) { - page = repositoryFunction.apply(0, page.previousOrFirstPageable()); - backwardPages.add(page); - } - - assertionAction.accept(forwardPages, backwardPages); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageableWithTrueCursorAndPageNumber") - , ID, REPO extends GenericPaginationMethods> - void testPageableWithTrueCursorAndPageNumber( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCount, - int expectedBackwardPageCount) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - backwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestPageablePageNumberLessCursor() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // fourth page - new TarantoolPageRequest<>(0, PAGE_SIZE, new Person(29, null, "User-29")), - PAGES_COUNT - 2, - PAGES_COUNT - 3, - PAGES_COUNT - 3), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // third page - new TarantoolPageRequest<>(0, PAGE_SIZE, new Person(19, null, "User-19")), - PAGES_COUNT - 1, - PAGES_COUNT - 2, - PAGES_COUNT - 2)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageablePageNumberLessCursor") - , ID, REPO extends GenericPaginationMethods> - void testPageablePageNumberLessCursor( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCountForPage, - int expectedForwardPageCountForSlice, - int expectedBackwardPageCount) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - int expectedForwardPageCount = expectedForwardPageCountForSlice; - Slice firstPageable = forwardSlice.get(0); - if (firstPageable instanceof Page) { - expectedForwardPageCount = expectedForwardPageCountForPage; - } - - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - if (firstPageable instanceof Page) { - assertTrue(forwardSlice.get(forwardSlice.size() - 1).getPageable().isUnpaged()); - forwardSlice - .subList(0, forwardSlice.size() - 1) - .forEach(p -> assertTrue(p.getPageable().isPaged())); - } else { - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - } - backwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestPageablePageNumberGreaterCursor() { - final int PAGE_SIZE = 10; - final int PAGES_COUNT = PERSONS_COUNT / PAGE_SIZE; - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // second page - new TarantoolPageRequest<>(1, PAGE_SIZE, null), - PAGES_COUNT - 1, - PAGES_COUNT, - PAGES_COUNT, - PAGES_COUNT + 1), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - // fourth page - new TarantoolPageRequest<>(3, PAGE_SIZE, new Person(9, null, "User-9")), - PAGES_COUNT - 3, - PAGES_COUNT - 1, - PAGES_COUNT - 1, - PAGES_COUNT + 1)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestPageablePageNumberGreaterCursor") - , ID, REPO extends GenericPaginationMethods> - void testPageablePageNumberGreaterCursor( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Pageable pageable, - int expectedForwardPageCountForPage, - int expectedForwardPageCountForSlice, - int expectedBackwardPageCountForPage, - int expectedBackwardPageCountForSlice) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - - BiConsumer>, List>> assertAction = - (forwardSlice, backwardSlice) -> { - int expectedForwardPageCount = expectedForwardPageCountForPage; - int expectedBackwardPageCount = expectedBackwardPageCountForPage; - - Slice firstPageable = forwardSlice.get(0); - if (!(firstPageable instanceof Page)) { - expectedForwardPageCount = expectedForwardPageCountForSlice; - expectedBackwardPageCount = expectedBackwardPageCountForSlice; - } - - assertEquals(expectedForwardPageCount, forwardSlice.size()); - assertEquals(expectedBackwardPageCount, backwardSlice.size()); - - forwardSlice.forEach(p -> assertTrue(p.getPageable().isPaged())); - assertTrue(backwardSlice.get(backwardSlice.size() - 1).getPageable().isUnpaged()); - backwardSlice - .subList(0, backwardSlice.size() - 1) - .forEach(p -> assertTrue(p.getPageable().isPaged())); - }; - - doTestPageableWithCursorAndPageNumber( - pageable, repository::findPersonByIdGreaterThanEqual, assertAction); - doTestPageableWithCursorAndPageNumber( - pageable, repository::findAllByIdGreaterThanEqual, assertAction); - } - - protected static Stream dataForTestRepositoryLimit() { - final int LIMITED_SIZE = 10; - final Limit LIMITED = Limit.of(LIMITED_SIZE); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - null, - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - Limit.unlimited(), - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - personGenerateAndInsertFunction, PersonRepository.class, LIMITED, LIMITED_SIZE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - null, - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - Limit.unlimited(), - SelectOptions.DEFAULT_LIMIT), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - LIMITED, - LIMITED_SIZE)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryLimit") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryLimit( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Limit limit, - int expectedLimitSize) { - generateAndInsertFunction.apply(context, PERSONS_COUNT); - - REPO repository = context.getBean(repositoryClass); - - List selectedPersons = repository.findPersonByIdGreaterThanEqual(0, limit); - assertEquals(expectedLimitSize, selectedPersons.size()); - } - - protected static Stream dataForTestRepositoryLimitShouldThrow() { - final Limit BAD_LIMIT = Limit.of(-10); - return Stream.of( - Arguments.of(PersonRepository.class, BAD_LIMIT), - Arguments.of(ComplexPersonRepository.class, BAD_LIMIT)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryLimitShouldThrow") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryLimitShouldThrow(Class repositoryClass, Limit limit) { - REPO repository = context.getBean(repositoryClass); - assertThrows( - IllegalArgumentException.class, () -> repository.findPersonByIdGreaterThanEqual(0, limit)); - } - - protected static Stream dataForTestRepositoryLimitWithLimitInMethodName() { - final int LIMIT_FROM_METHOD_NAME = 4; - final int LIMITED_SIZE = 10; - final Limit LIMITED = Limit.of(LIMITED_SIZE); - return Stream.of( - Arguments.of( - personGenerateAndInsertFunction, PersonRepository.class, null, LIMIT_FROM_METHOD_NAME), - Arguments.of( - personGenerateAndInsertFunction, PersonRepository.class, LIMITED, LIMITED_SIZE), - Arguments.of( - personGenerateAndInsertFunction, - PersonRepository.class, - Limit.unlimited(), - LIMIT_FROM_METHOD_NAME), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - null, - LIMIT_FROM_METHOD_NAME), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - LIMITED, - LIMITED_SIZE), - Arguments.of( - complexPersonGenerateAndInsertFunction, - ComplexPersonRepository.class, - Limit.unlimited(), - LIMIT_FROM_METHOD_NAME)); - } - - @ParameterizedTest(autoCloseArguments = false) - @MethodSource("dataForTestRepositoryLimitWithLimitInMethodName") - , ID, REPO extends GenericPaginationMethods> - void testRepositoryLimitWithLimitInMethodName( - BiFunction> generateAndInsertFunction, - Class repositoryClass, - Limit limit, - int expectedLimitSize) { - - generateAndInsertFunction.apply(context, PERSONS_COUNT); - REPO repository = context.getBean(repositoryClass); - List selectedPersons = repository.findTop4ByIdGreaterThanEqual(0, limit); - - assertEquals(expectedLimitSize, selectedPersons.size()); - } - - @Test - void testConcurrentDerivedMethods() { - - final byte threadCount = 3; - final ExecutorService executor = Executors.newFixedThreadPool(threadCount); - final List>> futures = new ArrayList<>(threadCount); - final PersonRepository repository = context.getBean(PersonRepository.class); - - final List insertedPersons = - personGenerateAndInsertFunction.apply(context, (int) threadCount); - final Person firstPerson = insertedPersons.get(0); - final Person secondPerson = insertedPersons.get(1); - final Person thirdPerson = insertedPersons.get(2); - - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findPersonById(firstPerson.getId()), executor)); - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findByIsMarried(secondPerson.getIsMarried()), executor)); - futures.add( - CompletableFuture.supplyAsync( - () -> repository.findByName(thirdPerson.getName()), executor)); - - CompletableFuture.allOf(futures.toArray(new CompletableFuture[] {})).join(); - - assertEquals(firstPerson, futures.get(0).join().get(0)); - assertEquals(secondPerson, futures.get(1).join().get(0)); - assertEquals(thirdPerson, futures.get(2).join().get(0)); - } - - @Test - void testFragmentsSPI() { - final int tupleCount = 100; - final List tuples = personGenerateFunction.apply(tupleCount); - - final PersonRepository repository = context.getBean(PersonRepository.class); - - final List insertedTuples = repository.replaceMany(tuples); - assertEquals(tupleCount, insertedTuples.size()); - - tuples.sort(Comparator.comparing(Person::getName)); - insertedTuples.sort(Comparator.comparing(Person::getName)); - assertEquals(tuples, insertedTuples); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/GenericTarantoolTemplateTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/GenericTarantoolTemplateTest.java deleted file mode 100644 index 653e18b9..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/GenericTarantoolTemplateTest.java +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.integration.crud; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.core.UncategorizedKeyValueException; - -import static io.tarantool.spring.data.ProxyTarantoolCrudKeyValueAdapter.POTENTIAL_PERFORMANCE_ISSUES_EXCEPTION_MESSAGE; -import static io.tarantool.spring.data.ProxyTarantoolQueryEngine.unwrapTuples; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.PERSONS_COUNT; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.PERSON_SPACE; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.generateAndInsertComplexPersons; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.generateAndInsertPersons; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.generateComplexPersons; -import static io.tarantool.spring.data40.utils.TarantoolTestSupport.generatePersons; -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.mapping.crud.CrudException; -import io.tarantool.spring.data40.core.TarantoolTemplate; -import io.tarantool.spring.data40.utils.entity.ComplexPerson; -import io.tarantool.spring.data40.utils.entity.ComplexPersonWithIncorrectPK; -import io.tarantool.spring.data40.utils.entity.ComplexPersonWithJsonFormatVariantPK; -import io.tarantool.spring.data40.utils.entity.CompositePersonKey; -import io.tarantool.spring.data40.utils.entity.CompositePersonKeyWithJsonFormat; -import io.tarantool.spring.data40.utils.entity.Person; - -abstract class GenericTarantoolTemplateTest extends CrudConfigurations { - - @Autowired protected TarantoolTemplate tarantoolTemplate; - - @Test - void testGetAllOf() { - final Throwable throwable = - assertThrows( - UncategorizedKeyValueException.class, () -> tarantoolTemplate.findAll(Person.class)) - .getCause(); - - assertEquals(UnsupportedOperationException.class, throwable.getClass()); - assertEquals(POTENTIAL_PERFORMANCE_ISSUES_EXCEPTION_MESSAGE, throwable.getMessage()); - } - - static Stream dataForInsert() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - return Stream.of( - Arguments.of( - simpleKeyPerson, - (Function) (kv) -> kv.insert(simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - compositeKeyPerson, - (Function) (kv) -> kv.insert(compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForInsert") - void testKVTemplateInsert( - Object result, - Function callingMethod, - Function> selectAction) { - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForInsertById() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - return Stream.of( - Arguments.of( - simpleKeyPerson, - (Function) (kv) -> kv.insert(simpleKey, simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - compositeKeyPerson, - (Function) - (kv) -> kv.insert(compositeKey, compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForInsertById") - void testKVTemplateInsertById( - Object result, - Function callingMethod, - Function> selectAction) { - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForUpdate() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - Consumer prepareActionForSimpleKeyPerson = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer prepareActionForCompositeKeyPerson = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - return Stream.of( - Arguments.of( - prepareActionForSimpleKeyPerson, - simpleKeyPerson, - (Function) (kv) -> kv.update(simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - prepareActionForCompositeKeyPerson, - compositeKeyPerson, - (Function) (kv) -> kv.update(compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForUpdate") - void testKVTemplateUpdate( - Consumer prepareAction, - Object result, - Function callingMethod, - Function> selectAction) { - prepareAction.accept(client); - - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForUpdateById() { - - Person simpleKeyPerson = generatePersons(1).get(0); - ComplexPerson compositeKeyPerson = generateComplexPersons(1).get(0); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Function selectActionForSimpleKeyPerson = - (client) -> - unwrapTuples( - client.space(PERSON_SPACE).select(Collections.emptyList(), Person.class).join()); - - Function> selectActionForComplexKeyPerson = - (client) -> - unwrapTuples( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList(), ComplexPerson.class) - .join()); - - Consumer prepareActionForSimpleKeyPerson = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer prepareActionForCompositeKeyPerson = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - return Stream.of( - Arguments.of( - prepareActionForSimpleKeyPerson, - simpleKeyPerson, - (Function) (kv) -> kv.update(simpleKey, simpleKeyPerson), - selectActionForSimpleKeyPerson), - Arguments.of( - prepareActionForCompositeKeyPerson, - compositeKeyPerson, - (Function) - (kv) -> kv.update(compositeKey, compositeKeyPerson), - selectActionForComplexKeyPerson)); - } - - @ParameterizedTest - @MethodSource("dataForUpdateById") - void testKVTemplateUpdateById( - Consumer prepareAction, - Object result, - Function callingMethod, - Function> selectAction) { - prepareAction.accept(client); - - final int SIZE = 1; - assertEquals(result, callingMethod.apply(tarantoolTemplate)); - - List selectResult = selectAction.apply(client); - assertEquals(SIZE, selectResult.size()); - assertEquals(result, selectResult.get(0)); - } - - static Stream dataForDelete() { - - Runnable simpleKeyPrepareAction = () -> generatePersons(PERSONS_COUNT); - Runnable compositeKeyPrepareAction = () -> generateComplexPersons(PERSONS_COUNT); - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(Person.class), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(ComplexPerson.class), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDelete") - void testKVTemplateDelete( - Runnable prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.run(); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForDeleteEntities() { - - Person simpleKeyPerson = new Person(0, true, "0"); - ComplexPerson compositeKeyPerson = new ComplexPerson(0, UUID.randomUUID(), true, "0"); - - Consumer simpleKeyPrepareAction = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer compositeKeyPrepareAction = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(simpleKeyPerson), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(compositeKeyPerson), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDeleteEntities") - void testKVTemplateDeleteEntities( - Consumer prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.accept(client); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForDeleteEntitiesById() { - - Person simpleKeyPerson = new Person(0, true, "0"); - ComplexPerson compositeKeyPerson = new ComplexPerson(0, UUID.randomUUID(), true, "0"); - - Integer simpleKey = simpleKeyPerson.getId(); - CompositePersonKey compositeKey = - new CompositePersonKey(compositeKeyPerson.getId(), compositeKeyPerson.getSecondId()); - - Consumer simpleKeyPrepareAction = - (client) -> { - Person insertedPerson = - client.space(PERSON_SPACE).insert(simpleKeyPerson, Person.class).join().get(); - assertEquals(simpleKeyPerson, insertedPerson); - }; - - Consumer compositeKeyPrepareAction = - (client) -> { - ComplexPerson insertedPerson = - client - .space(COMPLEX_PERSON_SPACE) - .insert(compositeKeyPerson, ComplexPerson.class) - .join() - .get(); - assertEquals(compositeKeyPerson, insertedPerson); - }; - - Consumer simpleKeyFinalAction = - (client) -> - assertTrue(client.space(PERSON_SPACE).select(Collections.emptyList()).join().isEmpty()); - - Consumer compositeKeyFinalAction = - (client) -> - assertTrue( - client - .space(COMPLEX_PERSON_SPACE) - .select(Collections.emptyList()) - .join() - .isEmpty()); - - return Stream.of( - Arguments.of( - simpleKeyPrepareAction, - (Consumer) (kv) -> kv.delete(simpleKey, Person.class), - simpleKeyFinalAction), - Arguments.of( - compositeKeyPrepareAction, - (Consumer) (kv) -> kv.delete(compositeKey, ComplexPerson.class), - compositeKeyFinalAction)); - } - - @ParameterizedTest - @MethodSource("dataForDeleteEntitiesById") - void testKVTemplateDeleteEntitiesById( - Consumer prepareAction, - Consumer callingMethod, - Consumer finalAction) { - prepareAction.accept(client); - callingMethod.accept(tarantoolTemplate); - finalAction.accept(client); - } - - static Stream dataForCount() { - - Consumer simpleKeyPrepareAction = - (client) -> generateAndInsertPersons(PERSONS_COUNT, client); - - Consumer compositeKeyPrepareAction = - (client) -> generateAndInsertComplexPersons(PERSONS_COUNT, client); - - return Stream.of( - Arguments.of( - PERSONS_COUNT, - simpleKeyPrepareAction, - (Function) (kv) -> kv.count(Person.class)), - Arguments.of( - PERSONS_COUNT, - compositeKeyPrepareAction, - (Function) (kv) -> kv.count(ComplexPerson.class))); - } - - @ParameterizedTest - @MethodSource("dataForCount") - void testCount( - long expectedCount, - Consumer prepareAction, - Function callingMethod) { - prepareAction.accept(client); - assertEquals(expectedCount, callingMethod.apply(tarantoolTemplate)); - } - - @Test - void testCompositeKeyWithJsonFormat() { - ComplexPersonWithJsonFormatVariantPK complexPersonWithJsonFormatVariantPK = - new ComplexPersonWithJsonFormatVariantPK(0, UUID.randomUUID(), null, "0"); - - assertEquals( - complexPersonWithJsonFormatVariantPK, - tarantoolTemplate.insert(complexPersonWithJsonFormatVariantPK)); - - CompositePersonKeyWithJsonFormat key = - new CompositePersonKeyWithJsonFormat( - complexPersonWithJsonFormatVariantPK.getId(), - complexPersonWithJsonFormatVariantPK.getSecondId()); - Optional foundPerson = - tarantoolTemplate.findById(key, ComplexPersonWithJsonFormatVariantPK.class); - assertTrue(foundPerson.isPresent()); - assertEquals(complexPersonWithJsonFormatVariantPK, foundPerson.get()); - } - - @Test - void testCompositeKeyWithoutJsonFormat() { - ComplexPersonWithIncorrectPK complexPersonWithIncorrectPK = - new ComplexPersonWithIncorrectPK(0, UUID.randomUUID(), null, "0"); - - Throwable exception = - assertThrows( - UncategorizedKeyValueException.class, - () -> tarantoolTemplate.insert(complexPersonWithIncorrectPK)) - .getRootCause(); - assertInstanceOf(CrudException.class, exception); - } - - public static Stream dataForTestCompositeKeyWithConcurrency() { - final List threadsCount = Arrays.asList(1, 2, 3); - final List tuplesCount = Arrays.asList(20, 120, 360, 1200, 3000); - final List totalArguments = new ArrayList<>(); - - for (final Integer threadCount : threadsCount) { - for (final Integer tupleCount : tuplesCount) { - totalArguments.add(Arguments.of(threadCount, tupleCount)); - } - } - - return totalArguments.stream(); - } - - @DisplayName("Checking the insertion of an entity with a composite key") - @ParameterizedTest(autoCloseArguments = false, name = "thread count: {0}, tuples count: {1}") - @MethodSource("dataForTestCompositeKeyWithConcurrency") - void testCompositeKeyWithConcurrency(int threadsCount, int tuplesCount) { - final ExecutorService executor = Executors.newFixedThreadPool(threadsCount); - final List> futures = new ArrayList<>(); - final List tuples = generateComplexPersons(tuplesCount); - - for (final ComplexPerson tuple : tuples) { - futures.add( - CompletableFuture.supplyAsync(() -> this.tarantoolTemplate.insert(tuple), executor)); - } - - CompletableFuture.allOf(futures.toArray(new CompletableFuture[] {})).join(); - - for (int i = 0; i < tuplesCount; i++) { - assertEquals(tuples.get(i), futures.get(i).join()); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/RepositoryConfigurationExtensionTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/RepositoryConfigurationExtensionTest.java deleted file mode 100644 index 048661c5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/RepositoryConfigurationExtensionTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.integration.crud; - -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; - -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF; -import static io.tarantool.spring.data.TarantoolBeanNames.DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF; -import io.tarantool.client.ClientType; -import io.tarantool.client.factory.TarantoolBoxClientBuilder; -import io.tarantool.client.factory.TarantoolCrudClientBuilder; -import io.tarantool.client.factory.TarantoolFactory; -import io.tarantool.spring.data40.integration.BaseIntegrationTest; -import io.tarantool.spring.data40.repository.config.EnableTarantoolRepositories; -import io.tarantool.spring.data40.repository.config.TarantoolRepositoryConfigurationExtension; - -class RepositoryConfigurationExtensionTest extends BaseIntegrationTest { - - private static TarantoolRepositoryConfigurationExtension defaultExtension; - - @BeforeAll - static void setUp() throws IOException { - BaseIntegrationTest.beforeAll(); - defaultExtension = new TarantoolRepositoryConfigurationExtension(); - } - - @Test - void testGetModuleName() { - assertEquals("Tarantool", defaultExtension.getModuleName()); - } - - @Test - void testGetModulePrefix() { - assertEquals("tarantool", defaultExtension.getModulePrefix()); - } - - @Test - void testGetDefaultKeyValueTemplateRef() { - assertEquals( - DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF, defaultExtension.getDefaultKeyValueTemplateRef()); - } - - @Test - void testRegisterBeansForRootWithDefaultConfig() { - final ApplicationContext context = new AnnotationConfigApplicationContext(DefaultConfig.class); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_CRUD_CLIENT_BEAN_REF)); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_CRUD_KEY_VALUE_ADAPTER_REF)); - assertTrue(context.containsBean(DEFAULT_TARANTOOL_KEY_VALUE_TEMPLATE_REF)); - } - - @Test - void testRegisterBeansForRootWithCustomClientConfigShouldThrows() { - final Throwable throwable = - assertThrows( - IllegalArgumentException.class, - () -> new AnnotationConfigApplicationContext(BoxNonSupportConfig.class)); - - final String exceptionMessage = "The Box client is not yet supported."; - assertEquals(exceptionMessage, throwable.getMessage()); - } - - private static TarantoolCrudClientBuilder getCrudClientSettings() { - return TarantoolFactory.crud() - .withHost(getHost()) - .withPort(getPort()) - .withUser(getUsername()) - .withPassword(getPassword()); - } - - private static TarantoolBoxClientBuilder getBoxClientSettings() { - return TarantoolFactory.box().withHost(getHost()).withPort(getPort()); - } - - @EnableTarantoolRepositories - static class DefaultConfig { - - @Bean - public TarantoolCrudClientBuilder clientSettings() { - return getCrudClientSettings(); - } - } - - @EnableTarantoolRepositories(clientType = ClientType.BOX) - static class BoxNonSupportConfig { - - @Bean - public TarantoolBoxClientBuilder clientSettings() { - return getBoxClientSettings(); - } - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/RepositoryViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/RepositoryViaJavaConfigTest.java deleted file mode 100644 index 74377e40..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/RepositoryViaJavaConfigTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data40.integration.crud.CrudConfigurations.JavaConfigConfiguration; - -@SpringBootTest(classes = {JavaConfigConfiguration.class}) -class RepositoryViaJavaConfigTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/RepositoryViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/RepositoryViaPropertiesTest.java deleted file mode 100644 index e617f1e5..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/RepositoryViaPropertiesTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data40.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; - -@SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) -class RepositoryViaPropertiesTest extends GenericRepositoryTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/TarantoolTemplateViaJavaConfigTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/TarantoolTemplateViaJavaConfigTest.java deleted file mode 100644 index b4187f88..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/TarantoolTemplateViaJavaConfigTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data40.integration.crud.CrudConfigurations.JavaConfigConfiguration; - -@SpringBootTest(classes = {JavaConfigConfiguration.class}) -class TarantoolTemplateViaJavaConfigTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/TarantoolTemplateViaPropertiesTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/TarantoolTemplateViaPropertiesTest.java deleted file mode 100644 index b6c58301..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/integration/crud/TarantoolTemplateViaPropertiesTest.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.integration.crud; - -import org.springframework.boot.test.context.SpringBootTest; - -import io.tarantool.spring.data40.integration.crud.CrudConfigurations.ViaPropertyFileConfiguration; - -@SpringBootTest(classes = {ViaPropertyFileConfiguration.class}) -class TarantoolTemplateViaPropertiesTest extends GenericTarantoolTemplateTest {} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolCriteriaTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolCriteriaTest.java deleted file mode 100644 index 90c9a839..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolCriteriaTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.query; - -import java.util.Arrays; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; - -import static io.tarantool.client.crud.ConditionOperator.EQ; -import io.tarantool.client.crud.Condition; -import io.tarantool.client.crud.options.SelectOptions; -import io.tarantool.spring.data.query.Conditions; -import io.tarantool.spring.data.query.TarantoolCriteria; - -public class TarantoolCriteriaTest { - - @Test - void testAddAndGetConditions() { - final TarantoolCriteria tarantoolCriteria = new TarantoolCriteria(); - final String identifier = "name"; - final Object value = "value"; - final String operator = "=="; - - final Condition condition = Condition.create(operator, identifier, value); - assertEquals(operator, condition.getOperator()); - assertEquals(identifier, condition.getFieldIdentifier()); - assertEquals(value, condition.getValue()); - - final Condition conditionConstructor = new Condition(operator, identifier, value); - assertEquals(operator, conditionConstructor.getOperator()); - assertEquals(identifier, conditionConstructor.getFieldIdentifier()); - assertEquals(value, conditionConstructor.getValue()); - - final Condition conditionFromBuilder = - Condition.builder() - .withOperator(operator) - .withValue(value) - .withFieldIdentifier(identifier) - .build(); - assertEquals(operator, conditionFromBuilder.getOperator()); - assertEquals(identifier, conditionFromBuilder.getFieldIdentifier()); - assertEquals(value, conditionFromBuilder.getValue()); - - final Condition conditionWithEnum = Condition.create(EQ, identifier, value); - assertEquals(operator, conditionWithEnum.getOperator()); - assertEquals(identifier, conditionWithEnum.getFieldIdentifier()); - assertEquals(value, conditionWithEnum.getValue()); - - final Condition conditionConstructorWithEnum = new Condition(EQ, identifier, value); - assertEquals(operator, conditionConstructorWithEnum.getOperator()); - assertEquals(identifier, conditionConstructorWithEnum.getFieldIdentifier()); - assertEquals(value, conditionConstructorWithEnum.getValue()); - - final Condition conditionFromBuilderWithEnum = - Condition.builder() - .withOperator(EQ) - .withValue(value) - .withFieldIdentifier(identifier) - .build(); - assertEquals(operator, conditionFromBuilderWithEnum.getOperator()); - assertEquals(identifier, conditionFromBuilderWithEnum.getFieldIdentifier()); - assertEquals(value, conditionFromBuilderWithEnum.getValue()); - - tarantoolCriteria.addCondition(condition); - tarantoolCriteria.addCondition(conditionConstructor); - tarantoolCriteria.addCondition(conditionFromBuilder); - - tarantoolCriteria.addCondition(conditionWithEnum); - tarantoolCriteria.addCondition(conditionConstructorWithEnum); - tarantoolCriteria.addCondition(conditionFromBuilderWithEnum); - - final Conditions expectedConditions = new Conditions(); - expectedConditions.addAll( - Arrays.asList( - condition, - conditionConstructor, - conditionFromBuilder, - conditionWithEnum, - conditionConstructorWithEnum, - conditionFromBuilderWithEnum)); - - assertEquals(expectedConditions, tarantoolCriteria.getConditions()); - } - - @Test - void testFirst() { - final TarantoolCriteria criteria = new TarantoolCriteria(); - criteria.withFirst(1); - - final String key = "first"; - SelectOptions options = criteria.getOptions(); - assertEquals(1, options.getOptions().get(key)); - - criteria.clear(); - criteria.withFirst(-1); - options = criteria.getOptions(); - assertEquals(-1, options.getOptions().get(key)); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolKeysetScrollPositionTest.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolKeysetScrollPositionTest.java deleted file mode 100644 index a99f1714..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/query/TarantoolKeysetScrollPositionTest.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.query; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.UUID; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.function.Executable; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.data.domain.ScrollPosition; - -import static io.tarantool.spring.data.query.PaginationDirection.BACKWARD; -import static io.tarantool.spring.data.query.PaginationDirection.FORWARD; -import io.tarantool.spring.data.query.PaginationDirection; -import io.tarantool.spring.data.utils.Pair; - -class TarantoolKeysetScrollPositionTest { - - private static final Pair INDEX_KEY = Pair.of("pk", 123); - - private static final Pair INDEX_KEY_WITH_NULL_VALUE = Pair.of("pk", null); - - static Stream dataForTestTarantoolScrollPositionCreateDoesntThrow() { - return Stream.of( - () -> TarantoolScrollPosition.forward(INDEX_KEY), - () -> TarantoolScrollPosition.forward(INDEX_KEY_WITH_NULL_VALUE), - () -> TarantoolScrollPosition.backward(INDEX_KEY), - () -> TarantoolScrollPosition.backward(INDEX_KEY_WITH_NULL_VALUE)); - } - - @ParameterizedTest - @MethodSource("dataForTestTarantoolScrollPositionCreateDoesntThrow") - void testTarantoolScrollPositionCreateDoesntThrow(Executable scrollPositionCreateAction) { - assertDoesNotThrow(scrollPositionCreateAction); - } - - static Stream dataForTestTarantoolScrollPositionCreateThrows() { - return Stream.of( - () -> TarantoolScrollPosition.forward(null), () -> TarantoolScrollPosition.backward(null)); - } - - @ParameterizedTest - @MethodSource("dataForTestTarantoolScrollPositionCreateThrows") - void testTarantoolScrollPositionCreateThrows(Executable scrollPositionCreateAction) { - assertThrows(IllegalArgumentException.class, scrollPositionCreateAction); - } - - static Stream dataForTestEqualsAndHashCode() { - - List equalScrollPositionsWithKey = - Arrays.asList( - TarantoolScrollPosition.forward(INDEX_KEY), TarantoolScrollPosition.forward(INDEX_KEY)); - - TarantoolScrollPosition notEqualScrollPosition = - TarantoolScrollPosition.forward(INDEX_KEY_WITH_NULL_VALUE); - - final int ITERATION_COUNT = 100; - - return Stream.of( - Arguments.of(equalScrollPositionsWithKey, notEqualScrollPosition, ITERATION_COUNT), - Arguments.of(equalScrollPositionsWithKey, null, ITERATION_COUNT)); - } - - @ParameterizedTest - @MethodSource("dataForTestEqualsAndHashCode") - void testEqualsAndHashCode( - List scrollPositions, - ScrollPosition notEqualScrollPosition, - int iterationCount) { - for (int i = 0; i < iterationCount; i++) { - for (ScrollPosition scrollPosition : scrollPositions) { - for (ScrollPosition otherScrollPosition : scrollPositions) { - assertEquals(scrollPosition, otherScrollPosition); - assertEquals(scrollPosition.hashCode(), otherScrollPosition.hashCode()); - } - assertNotEquals(scrollPosition, notEqualScrollPosition); - if (notEqualScrollPosition != null) { - assertNotEquals(scrollPosition.hashCode(), notEqualScrollPosition.hashCode()); - } - } - } - } - - static Stream dataForTestIsInitial() { - var startingIndex = Pair.of("pk", Collections.emptyList()); - var complexIndex = Pair.of("pk", Arrays.asList(1, UUID.randomUUID())); - Object nonNullCursor = Arrays.asList(1, 2, 3, 4); - return Stream.of( - Arguments.of(TarantoolScrollPosition.backward(INDEX_KEY), false), - Arguments.of(TarantoolScrollPosition.forward(INDEX_KEY), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, null), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, nonNullCursor), false), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, nonNullCursor), false), - Arguments.of(TarantoolScrollPosition.backward(startingIndex), true), - Arguments.of(TarantoolScrollPosition.forward(startingIndex), true), - Arguments.of(new TarantoolKeysetScrollPosition(startingIndex, FORWARD, null), true), - Arguments.of(new TarantoolKeysetScrollPosition(startingIndex, BACKWARD, null), true), - Arguments.of( - new TarantoolKeysetScrollPosition(startingIndex, FORWARD, nonNullCursor), false), - Arguments.of( - new TarantoolKeysetScrollPosition(startingIndex, BACKWARD, nonNullCursor), false), - Arguments.of(TarantoolScrollPosition.backward(complexIndex), false), - Arguments.of(TarantoolScrollPosition.forward(complexIndex), false)); - } - - @ParameterizedTest - @MethodSource("dataForTestIsInitial") - void testIsInitial(ScrollPosition scrollPosition, boolean expectedIsInitial) { - assertEquals(scrollPosition.isInitial(), expectedIsInitial); - } - - static Stream dataForTestGetCursor() { - var cursor = String.valueOf(2); - return Stream.of( - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), null), - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, cursor), cursor)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetCursor") - void testGetCursor(TarantoolKeysetScrollPosition scrollPosition, Object expectedCursor) { - assertEquals(expectedCursor, scrollPosition.getCursor()); - } - - static Stream dataForTestGetKeyIndex() { - return Stream.of( - Arguments.of(TarantoolScrollPosition.forward(INDEX_KEY), INDEX_KEY), - Arguments.of(TarantoolScrollPosition.backward(INDEX_KEY), INDEX_KEY)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetKeyIndex") - void testGetKeyIndex( - TarantoolKeysetScrollPosition scrollPosition, Pair expectedIndexKey) { - assertEquals(expectedIndexKey, scrollPosition.getIndexKey()); - } - - static Stream dataForTestGetDirection() { - return Stream.of( - Arguments.of(new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, null), FORWARD), - Arguments.of( - new TarantoolKeysetScrollPosition(INDEX_KEY, BACKWARD, String.valueOf(2)), BACKWARD)); - } - - @ParameterizedTest - @MethodSource("dataForTestGetDirection") - void testGetDirection( - TarantoolKeysetScrollPosition scrollPosition, PaginationDirection expectedDirection) { - assertEquals(expectedDirection, scrollPosition.getDirection()); - } - - static Stream dataForTestReverse() { - Object someKey = String.valueOf(1); - var indexKeyAfterReverse = Pair.of(INDEX_KEY.getFirst(), INDEX_KEY.getSecond()); - - return Stream.of( - Arguments.of( - TarantoolScrollPosition.forward(INDEX_KEY), - TarantoolScrollPosition.backward(indexKeyAfterReverse)), - Arguments.of( - new TarantoolKeysetScrollPosition(INDEX_KEY, FORWARD, someKey), - new TarantoolKeysetScrollPosition(indexKeyAfterReverse, BACKWARD, someKey))); - } - - @ParameterizedTest - @MethodSource("dataForTestReverse") - void testGetReverse( - TarantoolScrollPosition scrollPosition, - TarantoolKeysetScrollPosition expectedReversedPosition) { - assertEquals(expectedReversedPosition, scrollPosition.reverse()); - } - - static Stream dataForTestIsScrollsBackward() { - return Stream.of( - Arguments.of( - TarantoolScrollPosition.forward(Pair.of("pk", Collections.emptyList())), false), - Arguments.of( - TarantoolScrollPosition.backward(Pair.of("pk", Collections.emptyList())), true)); - } - - @ParameterizedTest - @MethodSource("dataForTestIsScrollsBackward") - void testIsScrollsBackward(TarantoolScrollPosition position, boolean expectedIsScrollsBackward) { - assertEquals(expectedIsScrollsBackward, position.isScrollsBackward()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/ComplexPersonListRepository.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/ComplexPersonListRepository.java deleted file mode 100644 index 87747c0b..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/ComplexPersonListRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.core; - -import org.springframework.data.repository.ListCrudRepository; - -import io.tarantool.spring.data.utils.GenericListRepositoryMethods; -import io.tarantool.spring.data40.utils.entity.ComplexPerson; -import io.tarantool.spring.data40.utils.entity.CompositePersonKey; - -public interface ComplexPersonListRepository - extends ListCrudRepository, - GenericListRepositoryMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/ComplexPersonRepository.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/ComplexPersonRepository.java deleted file mode 100644 index 3aaa30a1..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/ComplexPersonRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.core; - -import org.springframework.data.repository.PagingAndSortingRepository; - -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data40.utils.entity.ComplexPerson; -import io.tarantool.spring.data40.utils.entity.CompositePersonKey; - -public interface ComplexPersonRepository - extends PagingAndSortingRepository, - GenericRepositoryMethods, - GenericPaginationMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/GenericPaginationMethods.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/GenericPaginationMethods.java deleted file mode 100644 index beb06c86..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/GenericPaginationMethods.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.core; - -import java.util.List; - -import org.springframework.data.domain.Limit; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Window; - -public interface GenericPaginationMethods { - - Slice findAllByName(String name); - - Slice findAllByName(String name, Pageable pageable); - - Slice findAllByNameGreaterThanEqual(String name, Pageable pageable); - - Slice findAllByNameLessThanEqual(String name, Pageable pageable); - - Slice findAllByIdLessThanEqual(int id, Pageable pageable); - - Slice findAllByIdGreaterThanEqual(int id, Pageable pageable); - - Slice findAllByIsMarriedLessThanEqual(Boolean id, Pageable pageable); - - Slice findAllByIsMarriedGreaterThanEqual(Boolean id, Pageable pageable); - - Page findPersonByName(String name, Pageable pageable); - - Page findPersonByNameGreaterThanEqual(String name, Pageable pageable); - - Page findPersonByNameLessThanEqual(String name, Pageable pageable); - - Page findPersonByIdLessThanEqual(int id, Pageable pageable); - - Page findPersonByIdGreaterThanEqual(int id, Pageable pageable); - - Page findPersonByIsMarriedLessThanEqual(Boolean id, Pageable pageable); - - Page findPersonByIsMarriedGreaterThanEqual(Boolean id, Pageable pageable); - - Window findFirst5ByIsMarried(Boolean isMarried, ScrollPosition scrollPosition); - - Window findFirst10ByIsMarriedGreaterThanEqual( - Boolean isMarried, ScrollPosition scrollPosition); - - List findAll(Sort sort); - - Page findAll(Pageable pageable); - - List findAll(); - - List findPersonByIdGreaterThanEqual(int id, Limit limit); - - List findTop4ByIdGreaterThanEqual(int id, Limit limit); -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/PersonListRepository.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/PersonListRepository.java deleted file mode 100644 index e32fe938..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/PersonListRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.core; - -import org.springframework.data.repository.ListCrudRepository; - -import io.tarantool.spring.data.utils.GenericListRepositoryMethods; -import io.tarantool.spring.data40.utils.entity.Person; - -public interface PersonListRepository - extends ListCrudRepository, GenericListRepositoryMethods {} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/PersonRepository.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/PersonRepository.java deleted file mode 100644 index 0ddbfbf7..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/core/PersonRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.core; - -import org.springframework.data.repository.PagingAndSortingRepository; - -import io.tarantool.spring.data.utils.GenericRepositoryMethods; -import io.tarantool.spring.data40.utils.entity.Person; -import io.tarantool.spring.data40.utils.fragments.core.ReplaceManyFragment; - -public interface PersonRepository - extends PagingAndSortingRepository, - GenericRepositoryMethods, - GenericPaginationMethods, - ReplaceManyFragment {} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/ComplexPerson.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/ComplexPerson.java deleted file mode 100644 index 9cd7722e..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/ComplexPerson.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data40.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKey.class) -public class ComplexPerson implements GenericPerson { - - @Id - @Field("id") - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - protected Boolean isMarried; - - @Field("name") - @JsonProperty("name") - String name; - - @Override - public CompositePersonKey generateFullKey() { - return new CompositePersonKey(id, secondId); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/ComplexPersonWithIncorrectPK.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/ComplexPersonWithIncorrectPK.java deleted file mode 100644 index 1abb1960..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/ComplexPersonWithIncorrectPK.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data40.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKeyWithoutJsonFormat.class) -public class ComplexPersonWithIncorrectPK { - - @Id - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/ComplexPersonWithJsonFormatVariantPK.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/ComplexPersonWithJsonFormatVariantPK.java deleted file mode 100644 index 6e619669..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/ComplexPersonWithJsonFormatVariantPK.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.core.annotation.IdClass; -import io.tarantool.spring.data40.query.Field; - -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("complex_person") -@IdClass(CompositePersonKeyWithJsonFormat.class) -public class ComplexPersonWithJsonFormatVariantPK { - - @Id - @JsonProperty("id") - private Integer id; - - @Id - @Field("second_id") - @JsonProperty("secondId") - private UUID secondId; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositeKeyWithWrongFieldCount.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositeKeyWithWrongFieldCount.java deleted file mode 100644 index 3c2803eb..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositeKeyWithWrongFieldCount.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -public class CompositeKeyWithWrongFieldCount implements CompositeKey { - - @JsonProperty("id") - private long id; -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositeKeyWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositeKeyWithWrongFieldTypes.java deleted file mode 100644 index cee21677..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositeKeyWithWrongFieldTypes.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositeKeyWithWrongFieldTypes implements CompositeKey { - - @JsonProperty("id") - private long id; - - @JsonProperty("secondId") - private String secondId; - - @JsonProperty("thirdId") - private boolean thirdId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositePersonKey.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositePersonKey.java deleted file mode 100644 index f62d41c0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositePersonKey.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import io.tarantool.spring.data.mapping.model.CompositeKey; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositePersonKey implements CompositeKey { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositePersonKeyWithJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositePersonKeyWithJsonFormat.java deleted file mode 100644 index a1899556..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositePersonKeyWithJsonFormat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -public class CompositePersonKeyWithJsonFormat { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositePersonKeyWithoutJsonFormat.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositePersonKeyWithoutJsonFormat.java deleted file mode 100644 index 90ccdf1d..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/CompositePersonKeyWithoutJsonFormat.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.entity; - -import java.util.UUID; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class CompositePersonKeyWithoutJsonFormat { - - @JsonProperty("id") - private Integer id; - - @JsonProperty("secondId") - private UUID secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/EntityWithAnnotationAsIdClass.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/EntityWithAnnotationAsIdClass.java deleted file mode 100644 index 62b8d075..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/EntityWithAnnotationAsIdClass.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.entity; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@IdClass(IdClass.class) -public class EntityWithAnnotationAsIdClass {} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/EntityWithWrongCompositeKeyPartsCount.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/EntityWithWrongCompositeKeyPartsCount.java deleted file mode 100644 index 2e0019b0..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/EntityWithWrongCompositeKeyPartsCount.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@IdClass(CompositeKeyWithWrongFieldCount.class) -public class EntityWithWrongCompositeKeyPartsCount { - - @Id - @JsonProperty("id") - private long id; - - @Id - @JsonProperty("secondId") - private long secondId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/EntityWithWrongFieldTypes.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/EntityWithWrongFieldTypes.java deleted file mode 100644 index 6a953a01..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/EntityWithWrongFieldTypes.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.entity; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; - -import io.tarantool.spring.data.core.annotation.IdClass; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@IdClass(CompositeKeyWithWrongFieldTypes.class) -public class EntityWithWrongFieldTypes { - - @Id - @JsonProperty("id") - private long id; - - @Id - @JsonProperty("secondId") - private String secondId; - - @Id - @JsonProperty("thirdId") - private int thirdId; -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/Person.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/Person.java deleted file mode 100644 index 9389de70..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/entity/Person.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.entity; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.annotation.KeySpace; - -import io.tarantool.spring.data.utils.GenericPerson; -import io.tarantool.spring.data40.query.Field; - -/** - * @author Artyom Dubinin - */ -@NoArgsConstructor -@AllArgsConstructor -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -@JsonIgnoreProperties(ignoreUnknown = true) // for example bucket_id -@Data -@KeySpace("person") -public class Person implements GenericPerson { - - @Id - @Field("id") - @JsonProperty("id") - public Integer id; - - @Field("is_married") - @JsonProperty("isMarried") - private Boolean isMarried; - - @JsonProperty("name") - private String name; - - @Override - public Integer generateFullKey() { - return id; - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/fragments/core/ReplaceManyFragment.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/fragments/core/ReplaceManyFragment.java deleted file mode 100644 index f5f67d4a..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/fragments/core/ReplaceManyFragment.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.fragments.core; - -import java.util.List; - -public interface ReplaceManyFragment { - - List replaceMany(List tuples); -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/fragments/implementations/PersonReplaceManyFragment.java b/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/fragments/implementations/PersonReplaceManyFragment.java deleted file mode 100644 index 4efa7067..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/java/io/tarantool/spring/data40/utils/fragments/implementations/PersonReplaceManyFragment.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2026 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY - * All Rights Reserved. - */ - -package io.tarantool.spring.data40.utils.fragments.implementations; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -import io.tarantool.client.crud.TarantoolCrudClient; -import io.tarantool.mapping.Tuple; -import io.tarantool.mapping.crud.CrudBatchResponse; -import io.tarantool.spring.data40.utils.entity.Person; -import io.tarantool.spring.data40.utils.fragments.core.ReplaceManyFragment; - -public class PersonReplaceManyFragment implements ReplaceManyFragment { - - private final TarantoolCrudClient client; - - public PersonReplaceManyFragment(TarantoolCrudClient client) { - this.client = client; - } - - @Override - public List replaceMany(List tuples) { - return getResults(this.client.space("person").replaceMany(tuples, Person.class)); - } - - private static List getResults( - CompletableFuture>>> tuples) { - return new ArrayList<>(tuples.join().getRows().stream().map(Tuple::get).toList()); - } -} diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/resources/META-INF/spring.factories b/tarantool-spring-data/tarantool-spring-data-40/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 82607e1c..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1 +0,0 @@ -io.tarantool.spring.data40.utils.fragments.core.ReplaceManyFragment=io.tarantool.spring.data40.utils.fragments.implementations.PersonReplaceManyFragment diff --git a/tarantool-spring-data/tarantool-spring-data-40/src/test/resources/application-crud-test.yaml b/tarantool-spring-data/tarantool-spring-data-40/src/test/resources/application-crud-test.yaml deleted file mode 100644 index 9bc8f9b2..00000000 --- a/tarantool-spring-data/tarantool-spring-data-40/src/test/resources/application-crud-test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -spring: - data: - tarantool: - host: localhost - port: 3301