From 448295d245c982ce663cbb0e0a470320227851fc Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Mon, 19 Aug 2024 14:24:42 +0300 Subject: [PATCH 01/18] dev: prepare maven ci and release action --- .github/workflows/ci-spring-data-jdbc.yaml | 61 ++++++++++ .../publish-spring-data-jdbc-dialect.yaml | 85 +++++++++++++ .../translator/YdbSqlAstTranslator.java | 13 ++ .../test/java/tech/ydb/jooq/InsertTest.java | 11 +- spring-data-dialect/pom.xml | 112 +++++++++++++++++- .../data/core/convert/YdbJdbcColumnTypes.java | 1 - .../core/convert/YdbMappingJdbcConverter.java | 9 +- .../ydb/data/core/convert/package-info.java | 4 + .../ydb/data/core/dialect/YdbDialect.java | 9 +- .../ydb/data/core/dialect/package-info.java | 4 + .../repository/config/YdbDialectProvider.java | 1 + .../data/repository/config/package-info.java | 4 + .../ydb/data/repository/package-info.java | 4 + .../data/repository/support/package-info.java | 4 + .../tech/ydb/data/YdbJdbcConfiguration.java | 1 - .../all_types_table/AllTypesTableTest.java | 1 + .../books/RepositoriesIntegrationTest.java | 1 - .../java/tech/ydb/data/books/entity/Book.java | 1 - .../src/test/resources/application.properties | 1 - 19 files changed, 300 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/ci-spring-data-jdbc.yaml create mode 100644 .github/workflows/publish-spring-data-jdbc-dialect.yaml create mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/core/convert/package-info.java create mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/package-info.java create mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/repository/config/package-info.java create mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/repository/package-info.java create mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/repository/support/package-info.java diff --git a/.github/workflows/ci-spring-data-jdbc.yaml b/.github/workflows/ci-spring-data-jdbc.yaml new file mode 100644 index 0000000..8e1439d --- /dev/null +++ b/.github/workflows/ci-spring-data-jdbc.yaml @@ -0,0 +1,61 @@ +name: Spring Data JDBC YDB Dialect CI with Maven + +on: + push: + paths: + - 'spring-data-dialect/**' + branches: + - main + pull_request: + paths: + - 'spring-data-dialect/**' + +env: + MAVEN_ARGS: --batch-mode --update-snapshots -Dstyle.color=always + +jobs: + build: + name: Spring Data JDBC YDB Dialect + runs-on: ubuntu-latest + + strategy: + matrix: + java: [ '17', '21' ] + + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK ${{matrix.java}} + uses: actions/setup-java@v4 + with: + java-version: ${{matrix.java}} + distribution: 'temurin' + cache: maven + + - name: Extract spring-data-jdbc YDB dialect version + working-directory: ./spring-data-dialect + run: | + VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) + echo "SPRING_DATA_JDBC_DIALECT_VERSION=$VERSION" >> "$GITHUB_ENV" + + - name: Download spring-data-jdbc YDB dialect dependencies + working-directory: ./spring-data-jdbc + run: mvn $MAVEN_ARGS dependency:go-offline + + - name: Build spring-data-jdbc YDB dialect + working-directory: ./spring-data-jdbc + run: mvn $MAVEN_ARGS install + +# - uses: actions/checkout@v4 +# with: +# repository: ydb-platform/ydb-java-examples +# ref: master +# path: examples +# +# - name: Download dependencies +# working-directory: ./examples/jdbc/spring-data-jpa-v5 +# run: mvn $MAVEN_ARGS -Dspring.data.jdbc.ydb.dialect.version=$SPRING_DATA_JDBC_DIALECT_VERSION dependency:go-offline +# +# - name: Test examples with Maven +# working-directory: ./examples/jdbc/spring-data-jpa-v5 +# run: mvn $MAVEN_ARGS -Dspring.data.jdbc.ydb.dialect.version=$SPRING_DATA_JDBC_DIALECT_VERSION test diff --git a/.github/workflows/publish-spring-data-jdbc-dialect.yaml b/.github/workflows/publish-spring-data-jdbc-dialect.yaml new file mode 100644 index 0000000..213dfb2 --- /dev/null +++ b/.github/workflows/publish-spring-data-jdbc-dialect.yaml @@ -0,0 +1,85 @@ +name: Publish Spring Data JDBC YDB Dialect + +on: + push: + tags: + - 'spring-data-jdbc-ydb/v[0-9]+.[0-9]+.[0-9]+' + +env: + MAVEN_ARGS: --batch-mode --no-transfer-progress -Dstyle.color=always + +jobs: + validate: + name: Validate Spring Data JDBC YDB Dialect + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Extract spring-data-jdbc YDB dialect version + run: | + cd spring-data-jdbc + SPRING_DATA_JDBC_DIALECT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) + echo "SPRING_DATA_JDBC_DIALECT_VERSION=SPRING_DATA_JDBC_DIALECT_VERSION" >> "$GITHUB_ENV" + + - name: Fail workflow if version is snapshot + if: endsWith(env.SPRING_DATA_JDBC_DIALECT_VERSION, 'SNAPSHOT') + uses: actions/github-script@v6 + with: + script: core.setFailed('SNAPSHOT version cannot be published') + + - name: Fail workflow if version is not equal to tag name + if: format('spring-data-jdbc-ydb/v{0}', env.SPRING_DATA_JDBC_DIALECT_VERSION) != github.ref_name + uses: actions/github-script@v6 + with: + script: core.setFailed('Release name must be equal to project version') + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: 'temurin' + cache: 'maven' + + - name: Download dependencies + run: | + cd spring-data-jdbc + mvn $MAVEN_ARGS dependency:go-offline + + - name: Build with Maven + run: | + cd spring-data-jdbc + mvn $MAVEN_ARGS package + + publish: + name: Publish Spring Data JDBC YDB Dialect + runs-on: ubuntu-latest + needs: validate + + steps: + - name: Install gpg secret key + run: | + # Install gpg secret key + cat <(echo -e "${{ secrets.MAVEN_OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import + # Verify gpg secret key + gpg --list-secret-keys --keyid-format LONG + + - uses: actions/checkout@v4 + + - name: Set up Maven Central Repository + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: 'temurin' + cache: 'maven' + server-id: ossrh-s01 + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + + - name: Publish package + run: | + cd spring-data-jdbc + mvn $MAVEN_ARGS -Possrh-s01 -Dgpg.passphrase=${{ secrets.MAVEN_OSSRH_GPG_PASSWORD }} clean deploy + env: + MAVEN_USERNAME: ${{ secrets.MAVEN_OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.MAVEN_OSSRH_TOKEN }} diff --git a/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/translator/YdbSqlAstTranslator.java b/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/translator/YdbSqlAstTranslator.java index 703f8b7..ef1b738 100644 --- a/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/translator/YdbSqlAstTranslator.java +++ b/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/translator/YdbSqlAstTranslator.java @@ -1,11 +1,14 @@ package tech.ydb.hibernate.dialect.translator; +import java.util.List; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.FetchClauseType; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.expression.Expression; +import org.hibernate.sql.ast.tree.from.FromClause; +import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.exec.spi.JdbcOperation; /** @@ -44,4 +47,14 @@ protected void renderOffsetFetchClause( } } } + + @Override + protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List tableGroupJoinCollector) { + super.renderTableGroupJoin(tableGroupJoin, tableGroupJoinCollector); + } + + @Override + public void visitFromClause(FromClause fromClause) { + super.visitFromClause(fromClause); + } } diff --git a/jooq-dialect/src/test/java/tech/ydb/jooq/InsertTest.java b/jooq-dialect/src/test/java/tech/ydb/jooq/InsertTest.java index 497e4ff..d399261 100644 --- a/jooq-dialect/src/test/java/tech/ydb/jooq/InsertTest.java +++ b/jooq-dialect/src/test/java/tech/ydb/jooq/InsertTest.java @@ -1,5 +1,8 @@ package tech.ydb.jooq; +import java.util.List; +import static jooq.generated.ydb.default_schema.Tables.HARD_TABLE; +import static jooq.generated.ydb.default_schema.Tables.SERIES; import jooq.generated.ydb.default_schema.tables.records.HardTableRecord; import jooq.generated.ydb.default_schema.tables.records.SeriesRecord; import org.jooq.JSON; @@ -7,15 +10,11 @@ import org.jooq.Result; import org.jooq.exception.DataAccessException; import org.jooq.types.ULong; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; import tech.ydb.jooq.value.YSON; -import java.util.List; - -import static jooq.generated.ydb.default_schema.Tables.HARD_TABLE; -import static jooq.generated.ydb.default_schema.Tables.SERIES; -import static org.junit.jupiter.api.Assertions.*; - public class InsertTest extends BaseTest { @Test diff --git a/spring-data-dialect/pom.xml b/spring-data-dialect/pom.xml index 123bf82..4087ed1 100644 --- a/spring-data-dialect/pom.xml +++ b/spring-data-dialect/pom.xml @@ -8,10 +8,12 @@ spring-data-ydb-dialect 0.9.1-SNAPSHOT - Spring Data YDB Dialect + Spring Data JDBC YDB Dialect Support Spring Data JDBC YDB (YQL) Dialect https://github.com/ydb-platform/ydb-java-dialects + jar + Madiyar Nurgazin @@ -19,13 +21,31 @@ YDB https://ydb.tech/ + + Kirill Kurdyukov + kurdyukov-kir@ydb.tech + YDB + https://ydb.tech/ + + + https://github.com/ydb-platform/ydb-java-dialects + scm:git:https://github.com/ydb-platform/ydb-java-dialects.git + scm:git:https://github.com/ydb-platform/ydb-java-dialects.git + + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + + + UTF-8 17 - 17 17 @@ -62,7 +82,7 @@ tech.ydb.jdbc - ydb-jdbc-driver-shaded + ydb-jdbc-driver ${ydb.jdbc.version} @@ -107,4 +127,90 @@ test + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.5.0 + + 17 + + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.1.0 + + + true + + + + + + + + ossrh-s01 + + false + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + --pinentry-mode + loopback + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + ossrh-s01 + https://s01.oss.sonatype.org/ + false + + + + + + diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbJdbcColumnTypes.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbJdbcColumnTypes.java index f46cf12..e7c0b4f 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbJdbcColumnTypes.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbJdbcColumnTypes.java @@ -9,7 +9,6 @@ import java.time.temporal.Temporal; import java.util.LinkedHashMap; import java.util.Map; - import org.springframework.util.ClassUtils; /** diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java index d0348f8..9683d62 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java @@ -1,7 +1,7 @@ package tech.ydb.data.core.convert; import java.sql.SQLType; - +import java.util.Objects; import org.springframework.data.convert.CustomConversions; import org.springframework.data.jdbc.core.convert.JdbcTypeFactory; import org.springframework.data.jdbc.core.convert.MappingJdbcConverter; @@ -18,7 +18,7 @@ */ public class YdbMappingJdbcConverter extends MappingJdbcConverter { public YdbMappingJdbcConverter(RelationalMappingContext context, RelationResolver relationResolver, - CustomConversions conversions, JdbcTypeFactory typeFactory) { + CustomConversions conversions, JdbcTypeFactory typeFactory) { super(context, relationResolver, conversions, typeFactory); } @@ -38,7 +38,8 @@ public Class getColumnType(RelationalPersistentProperty property) { } if (property.isEntity()) { - Class columnType = getEntityColumnType(property.getTypeInformation().getActualType()); + Class columnType = getEntityColumnType(Objects.requireNonNull( + property.getTypeInformation().getActualType())); if (columnType != null) { return columnType; @@ -59,7 +60,6 @@ public Class getColumnType(RelationalPersistentProperty property) { } private Class getReferenceColumnType(RelationalPersistentProperty property) { - Class componentType = property.getTypeInformation().getRequiredComponentType().getType(); RelationalPersistentEntity referencedEntity = getMappingContext().getRequiredPersistentEntity(componentType); @@ -68,7 +68,6 @@ private Class getReferenceColumnType(RelationalPersistentProperty property) { @Nullable private Class getEntityColumnType(TypeInformation type) { - RelationalPersistentEntity persistentEntity = getMappingContext().getPersistentEntity(type); if (persistentEntity == null) { diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/package-info.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/package-info.java new file mode 100644 index 0000000..dca92f1 --- /dev/null +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/package-info.java @@ -0,0 +1,4 @@ +@NonNullApi +package tech.ydb.data.core.convert; + +import org.springframework.lang.NonNullApi; \ No newline at end of file diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java index 84eef5d..53db969 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java @@ -1,8 +1,5 @@ package tech.ydb.data.core.dialect; -import java.util.Collections; -import java.util.Set; - import org.springframework.data.relational.core.dialect.AbstractDialect; import org.springframework.data.relational.core.dialect.InsertRenderContext; import org.springframework.data.relational.core.dialect.LimitClause; @@ -10,6 +7,7 @@ import org.springframework.data.relational.core.dialect.OrderByNullPrecedence; import org.springframework.data.relational.core.sql.IdentifierProcessing; import org.springframework.data.relational.core.sql.LockOptions; +import org.springframework.data.relational.core.sql.render.SelectRenderContext; /** * @author Madiyar Nurgazin @@ -68,11 +66,6 @@ public IdentifierProcessing getIdentifierProcessing() { ); } - @Override - public Set> simpleTypes() { - return Collections.emptySet(); - } - @Override public InsertRenderContext getInsertRenderContext() { return () -> { diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/package-info.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/package-info.java new file mode 100644 index 0000000..9b478fa --- /dev/null +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/package-info.java @@ -0,0 +1,4 @@ +@NonNullApi +package tech.ydb.data.core.dialect; + +import org.springframework.lang.NonNullApi; \ No newline at end of file diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/YdbDialectProvider.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/YdbDialectProvider.java index 528e9bf..3d81f85 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/YdbDialectProvider.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/YdbDialectProvider.java @@ -34,6 +34,7 @@ private static Dialect getDialect(Connection connection) throws SQLException { if ("ydb".contains(connection.getMetaData().getDatabaseProductName().toLowerCase(Locale.ENGLISH))) { return YdbDialect.INSTANCE; } + return null; } } diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/package-info.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/package-info.java new file mode 100644 index 0000000..90b9712 --- /dev/null +++ b/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/package-info.java @@ -0,0 +1,4 @@ +@NonNullApi +package tech.ydb.data.repository.config; + +import org.springframework.lang.NonNullApi; \ No newline at end of file diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/package-info.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/package-info.java new file mode 100644 index 0000000..e3b4895 --- /dev/null +++ b/spring-data-dialect/src/main/java/tech/ydb/data/repository/package-info.java @@ -0,0 +1,4 @@ +@NonNullApi +package tech.ydb.data.repository; + +import org.springframework.lang.NonNullApi; \ No newline at end of file diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/package-info.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/package-info.java new file mode 100644 index 0000000..8ce4324 --- /dev/null +++ b/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/package-info.java @@ -0,0 +1,4 @@ +@NonNullApi +package tech.ydb.data.repository.support; + +import org.springframework.lang.NonNullApi; \ No newline at end of file diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/YdbJdbcConfiguration.java b/spring-data-dialect/src/test/java/tech/ydb/data/YdbJdbcConfiguration.java index 5bd01ef..d75fc78 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/YdbJdbcConfiguration.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/YdbJdbcConfiguration.java @@ -1,7 +1,6 @@ package tech.ydb.data; import javax.sql.DataSource; - import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jdbc.repository.config.EnableJdbcAuditing; diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java index 93418df..3c5034a 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java @@ -20,6 +20,7 @@ * @author Madiyar Nurgazin */ public class AllTypesTableTest extends YdbBaseTest { + @Autowired private AllTypesEntityRepository repository; diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java index 3529077..2424b72 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java @@ -4,7 +4,6 @@ import java.util.List; import java.util.Optional; import java.util.Set; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Book.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Book.java index cd3e61e..337779d 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Book.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Book.java @@ -11,7 +11,6 @@ /** * @author Madiyar Nurgazin */ -//@AllArgsConstructor @Data @Table("books") public class Book { diff --git a/spring-data-dialect/src/test/resources/application.properties b/spring-data-dialect/src/test/resources/application.properties index 49bde0f..eb8335d 100644 --- a/spring-data-dialect/src/test/resources/application.properties +++ b/spring-data-dialect/src/test/resources/application.properties @@ -4,4 +4,3 @@ spring.datasource.url=jdbc:ydb:grpc://localhost:2136/local spring.liquibase.change-log=classpath:changelogs/changelog.yaml logging.level.org.springframework.jdbc.core.JdbcTemplate=debug -logging.level.liquibase=DEBUG From da574251d40bbc6840120050b76f12368716d121 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Mon, 19 Aug 2024 14:28:52 +0300 Subject: [PATCH 02/18] dev: fix name module --- .github/workflows/ci-spring-data-jdbc.yaml | 4 ++-- .github/workflows/publish-spring-data-jdbc-dialect.yaml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-spring-data-jdbc.yaml b/.github/workflows/ci-spring-data-jdbc.yaml index 8e1439d..29503c9 100644 --- a/.github/workflows/ci-spring-data-jdbc.yaml +++ b/.github/workflows/ci-spring-data-jdbc.yaml @@ -39,11 +39,11 @@ jobs: echo "SPRING_DATA_JDBC_DIALECT_VERSION=$VERSION" >> "$GITHUB_ENV" - name: Download spring-data-jdbc YDB dialect dependencies - working-directory: ./spring-data-jdbc + working-directory: ./spring-data-dialect run: mvn $MAVEN_ARGS dependency:go-offline - name: Build spring-data-jdbc YDB dialect - working-directory: ./spring-data-jdbc + working-directory: ./spring-data-dialect run: mvn $MAVEN_ARGS install # - uses: actions/checkout@v4 diff --git a/.github/workflows/publish-spring-data-jdbc-dialect.yaml b/.github/workflows/publish-spring-data-jdbc-dialect.yaml index 213dfb2..f117035 100644 --- a/.github/workflows/publish-spring-data-jdbc-dialect.yaml +++ b/.github/workflows/publish-spring-data-jdbc-dialect.yaml @@ -18,7 +18,7 @@ jobs: - name: Extract spring-data-jdbc YDB dialect version run: | - cd spring-data-jdbc + cd spring-data-dialect SPRING_DATA_JDBC_DIALECT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) echo "SPRING_DATA_JDBC_DIALECT_VERSION=SPRING_DATA_JDBC_DIALECT_VERSION" >> "$GITHUB_ENV" @@ -43,12 +43,12 @@ jobs: - name: Download dependencies run: | - cd spring-data-jdbc + cd spring-data-dialect mvn $MAVEN_ARGS dependency:go-offline - name: Build with Maven run: | - cd spring-data-jdbc + cd spring-data-dialect mvn $MAVEN_ARGS package publish: @@ -78,7 +78,7 @@ jobs: - name: Publish package run: | - cd spring-data-jdbc + cd spring-data-dialect mvn $MAVEN_ARGS -Possrh-s01 -Dgpg.passphrase=${{ secrets.MAVEN_OSSRH_GPG_PASSWORD }} clean deploy env: MAVEN_USERNAME: ${{ secrets.MAVEN_OSSRH_USERNAME }} From b8a0163f28d74e4c87faef54eb7f9c9dc4ed29d6 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Mon, 19 Aug 2024 14:36:38 +0300 Subject: [PATCH 03/18] dev: update jdbc driver version --- spring-data-dialect/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-data-dialect/pom.xml b/spring-data-dialect/pom.xml index 4087ed1..be3b220 100644 --- a/spring-data-dialect/pom.xml +++ b/spring-data-dialect/pom.xml @@ -57,7 +57,7 @@ 4.24.0 2.2.6 - 2.1.5 + 2.2.2 0.9.7 From fbd8e75143e09b0664de2d48d8ceeb7efc9e1bc0 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Mon, 19 Aug 2024 17:14:07 +0300 Subject: [PATCH 04/18] dev: update jdbc driver version --- .../src/main/java/tech/ydb/data/core/convert/YQLType.java | 5 ++--- .../java/tech/ydb/data/repository/support/YdbJdbcUtil.java | 3 --- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YQLType.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YQLType.java index 7ed33c0..c2502a4 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YQLType.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YQLType.java @@ -1,8 +1,7 @@ package tech.ydb.data.core.convert; +import java.sql.JDBCType; import java.sql.SQLType; - -import tech.ydb.jdbc.YdbConst; import tech.ydb.table.values.PrimitiveType; /** @@ -21,6 +20,6 @@ public String getVendor() { @Override public Integer getVendorTypeNumber() { - return YdbConst.SQL_KIND_PRIMITIVE + type.ordinal(); + return JDBCType.JAVA_OBJECT.getVendorTypeNumber(); } } diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/YdbJdbcUtil.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/YdbJdbcUtil.java index 57931e8..aaa9d78 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/YdbJdbcUtil.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/YdbJdbcUtil.java @@ -4,10 +4,8 @@ import java.sql.SQLType; import java.time.Instant; import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; - import org.springframework.data.jdbc.support.JdbcUtil; import org.springframework.util.Assert; @@ -18,7 +16,6 @@ public final class YdbJdbcUtil { private static final Map, SQLType> sqlTypeByClass = new HashMap<>(); static { - sqlTypeByClass.put(LocalDateTime.class, JDBCType.TIME); sqlTypeByClass.put(LocalDate.class, JDBCType.DATE); sqlTypeByClass.put(Instant.class, JDBCType.TIMESTAMP); } From 140351d2ab0347bd34e0259d93ac30cb5801f136 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Wed, 21 Aug 2024 18:44:31 +0300 Subject: [PATCH 05/18] delete change hibernate --- .../dialect/translator/YdbSqlAstTranslator.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/translator/YdbSqlAstTranslator.java b/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/translator/YdbSqlAstTranslator.java index ef1b738..703f8b7 100644 --- a/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/translator/YdbSqlAstTranslator.java +++ b/hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/translator/YdbSqlAstTranslator.java @@ -1,14 +1,11 @@ package tech.ydb.hibernate.dialect.translator; -import java.util.List; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.FetchClauseType; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.expression.Expression; -import org.hibernate.sql.ast.tree.from.FromClause; -import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.exec.spi.JdbcOperation; /** @@ -47,14 +44,4 @@ protected void renderOffsetFetchClause( } } } - - @Override - protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List tableGroupJoinCollector) { - super.renderTableGroupJoin(tableGroupJoin, tableGroupJoinCollector); - } - - @Override - public void visitFromClause(FromClause fromClause) { - super.visitFromClause(fromClause); - } } From 13b570eec09ed5c1c75a2ae406d59a84118e20ca Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Thu, 22 Aug 2024 16:42:24 +0300 Subject: [PATCH 06/18] more changes --- .../main/java/tech/ydb/data/core/convert/YQLType.java | 4 ++-- .../src/main/java/tech/ydb/data/core/package-info.java | 4 ---- .../main/java/tech/ydb/data/repository/ViewIndex.java | 9 +++++++++ 3 files changed, 11 insertions(+), 6 deletions(-) delete mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/core/package-info.java create mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YQLType.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YQLType.java index c2502a4..778d597 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YQLType.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YQLType.java @@ -1,7 +1,7 @@ package tech.ydb.data.core.convert; -import java.sql.JDBCType; import java.sql.SQLType; +import tech.ydb.jdbc.YdbConst; import tech.ydb.table.values.PrimitiveType; /** @@ -20,6 +20,6 @@ public String getVendor() { @Override public Integer getVendorTypeNumber() { - return JDBCType.JAVA_OBJECT.getVendorTypeNumber(); + return YdbConst.SQL_KIND_PRIMITIVE + type.ordinal(); } } diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/package-info.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/package-info.java deleted file mode 100644 index 26f310c..0000000 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * @author Kirill Kurdyukov - */ -package tech.ydb.data.core; \ No newline at end of file diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java new file mode 100644 index 0000000..cc7fa30 --- /dev/null +++ b/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java @@ -0,0 +1,9 @@ +package tech.ydb.data.repository; + +/** + * @author Kirill Kurdyukov + */ +public @interface ViewIndex { + + String name = ""; +} From c5a22ec6c8547ac2ee5d99e0a4685c281c93bc32 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Fri, 23 Aug 2024 15:37:17 +0300 Subject: [PATCH 07/18] commit --- .../data/core/convert/YdbJdbcColumnTypes.java | 42 ------------ .../core/convert/YdbMappingJdbcConverter.java | 65 ++----------------- .../ydb/data/core/dialect/YdbDialect.java | 25 ++++++- .../tech/ydb/data/repository/ViewIndex.java | 6 +- .../data/repository/support/YdbJdbcUtil.java | 36 ---------- .../books/RepositoriesIntegrationTest.java | 1 + 6 files changed, 34 insertions(+), 141 deletions(-) delete mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbJdbcColumnTypes.java delete mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/repository/support/YdbJdbcUtil.java diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbJdbcColumnTypes.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbJdbcColumnTypes.java deleted file mode 100644 index e7c0b4f..0000000 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbJdbcColumnTypes.java +++ /dev/null @@ -1,42 +0,0 @@ -package tech.ydb.data.core.convert; - -import java.sql.Timestamp; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.OffsetDateTime; -import java.time.ZonedDateTime; -import java.time.temporal.Temporal; -import java.util.LinkedHashMap; -import java.util.Map; -import org.springframework.util.ClassUtils; - -/** - * @author Madiyar Nurgazin - */ -public enum YdbJdbcColumnTypes { - INSTANCE { - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Class resolvePrimitiveType(Class type) { - return javaToDbType.entrySet().stream() // - .filter(e -> e.getKey().isAssignableFrom(type)) // - .map(e -> (Class) e.getValue()) // - .findFirst() // - .orElseGet(() -> (Class) ClassUtils.resolvePrimitiveIfNecessary(type)); - } - }; - - private static final Map, Class> javaToDbType = new LinkedHashMap<>(); - - static { - javaToDbType.put(Enum.class, String.class); - javaToDbType.put(ZonedDateTime.class, String.class); - javaToDbType.put(OffsetDateTime.class, OffsetDateTime.class); - javaToDbType.put(LocalDateTime.class, LocalDateTime.class); - javaToDbType.put(LocalDate.class, LocalDate.class); - javaToDbType.put(Instant.class, Instant.class); - javaToDbType.put(Temporal.class, Timestamp.class); - } - - public abstract Class resolvePrimitiveType(Class type); -} diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java index 9683d62..4cc6990 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java @@ -1,17 +1,13 @@ package tech.ydb.data.core.convert; import java.sql.SQLType; -import java.util.Objects; import org.springframework.data.convert.CustomConversions; import org.springframework.data.jdbc.core.convert.JdbcTypeFactory; import org.springframework.data.jdbc.core.convert.MappingJdbcConverter; import org.springframework.data.jdbc.core.convert.RelationResolver; +import org.springframework.data.jdbc.support.JdbcUtil; import org.springframework.data.relational.core.mapping.RelationalMappingContext; -import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; -import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; -import tech.ydb.data.repository.support.YdbJdbcUtil; /** * @author Madiyar Nurgazin @@ -24,61 +20,8 @@ public YdbMappingJdbcConverter(RelationalMappingContext context, RelationResolve @Override public SQLType getTargetSqlType(RelationalPersistentProperty property) { - if (property.isAnnotationPresent(YdbType.class)) { - return new YQLType(property.getRequiredAnnotation(YdbType.class).value()); - } - - return YdbJdbcUtil.targetSqlTypeFor(getColumnType(property)); - } - - @Override - public Class getColumnType(RelationalPersistentProperty property) { - if (property.isAssociation()) { - return getReferenceColumnType(property); - } - - if (property.isEntity()) { - Class columnType = getEntityColumnType(Objects.requireNonNull( - property.getTypeInformation().getActualType())); - - if (columnType != null) { - return columnType; - } - } - - Class componentColumnType = YdbJdbcColumnTypes.INSTANCE.resolvePrimitiveType(property.getActualType()); - - while (componentColumnType.isArray()) { - componentColumnType = componentColumnType.getComponentType(); - } - - if (property.isCollectionLike() && !property.isEntity()) { - return java.lang.reflect.Array.newInstance(componentColumnType, 0).getClass(); - } - - return componentColumnType; - } - - private Class getReferenceColumnType(RelationalPersistentProperty property) { - Class componentType = property.getTypeInformation().getRequiredComponentType().getType(); - RelationalPersistentEntity referencedEntity = getMappingContext().getRequiredPersistentEntity(componentType); - - return getColumnType(referencedEntity.getRequiredIdProperty()); - } - - @Nullable - private Class getEntityColumnType(TypeInformation type) { - RelationalPersistentEntity persistentEntity = getMappingContext().getPersistentEntity(type); - - if (persistentEntity == null) { - return null; - } - - RelationalPersistentProperty idProperty = persistentEntity.getIdProperty(); - - if (idProperty == null) { - return null; - } - return getColumnType(idProperty); + return property.isAnnotationPresent(YdbType.class) ? + new YQLType(property.getRequiredAnnotation(YdbType.class).value()) : + JdbcUtil.targetSqlTypeFor(getColumnType(property)); } } diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java index 53db969..1c8debc 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java @@ -1,5 +1,8 @@ package tech.ydb.data.core.dialect; +import java.util.function.Function; +import org.springframework.aop.interceptor.ExposeInvocationInterceptor; +import org.springframework.core.NamedInheritableThreadLocal; import org.springframework.data.relational.core.dialect.AbstractDialect; import org.springframework.data.relational.core.dialect.InsertRenderContext; import org.springframework.data.relational.core.dialect.LimitClause; @@ -7,7 +10,8 @@ import org.springframework.data.relational.core.dialect.OrderByNullPrecedence; import org.springframework.data.relational.core.sql.IdentifierProcessing; import org.springframework.data.relational.core.sql.LockOptions; -import org.springframework.data.relational.core.sql.render.SelectRenderContext; +import org.springframework.data.relational.core.sql.Select; +import tech.ydb.data.repository.ViewIndex; /** * @author Madiyar Nurgazin @@ -48,6 +52,25 @@ public LockClause.Position getClausePosition() { } }; + @Override + protected Function getAfterFromTable() { + return select -> { + var tables = select.getFrom().getTables(); + if (tables.size() != 1) { + return ""; + } + + var viewIndex = ExposeInvocationInterceptor.currentInvocation().getMethod().getAnnotation(ViewIndex.class); + + var tableName = tables.get(0).getReferenceName(); + + return viewIndex != null ? + "VIEW " + viewIndex.name() + " AS " + tableName : ""; + }; + } + + public final ThreadLocal viewIndexInfo = new NamedInheritableThreadLocal<>("viewIndexInfo"); + @Override public LimitClause limit() { return LIMIT_CLAUSE; diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java index cc7fa30..28c0a77 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java @@ -1,9 +1,13 @@ package tech.ydb.data.repository; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * @author Kirill Kurdyukov */ +@Retention(RetentionPolicy.RUNTIME) public @interface ViewIndex { - String name = ""; + String name(); } diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/YdbJdbcUtil.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/YdbJdbcUtil.java deleted file mode 100644 index aaa9d78..0000000 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/YdbJdbcUtil.java +++ /dev/null @@ -1,36 +0,0 @@ -package tech.ydb.data.repository.support; - -import java.sql.JDBCType; -import java.sql.SQLType; -import java.time.Instant; -import java.time.LocalDate; -import java.util.HashMap; -import java.util.Map; -import org.springframework.data.jdbc.support.JdbcUtil; -import org.springframework.util.Assert; - -/** - * @author Madiyar Nurgazin - */ -public final class YdbJdbcUtil { - private static final Map, SQLType> sqlTypeByClass = new HashMap<>(); - - static { - sqlTypeByClass.put(LocalDate.class, JDBCType.DATE); - sqlTypeByClass.put(Instant.class, JDBCType.TIMESTAMP); - } - - private YdbJdbcUtil() { - throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); - } - - public static SQLType targetSqlTypeFor(Class type) { - Assert.notNull(type, "Type must not be null"); - - return sqlTypeByClass.keySet().stream() // - .filter(k -> k.isAssignableFrom(type)) // - .findFirst() // - .map(sqlTypeByClass::get) // - .orElse(JdbcUtil.targetSqlTypeFor(type)); - } -} diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java index 2424b72..0b577a9 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java @@ -22,6 +22,7 @@ * @author Madiyar Nurgazin */ public class RepositoriesIntegrationTest extends YdbBaseTest { + @Autowired private AuthorRepository authorRepository; @Autowired From 371520872e70b0d73e3b7a057ce78ec1831e0117 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Fri, 23 Aug 2024 15:44:22 +0300 Subject: [PATCH 08/18] Support VIEW INDEX --- .../java/tech/ydb/data/core/dialect/YdbDialect.java | 11 ++++------- .../ydb/data/all_types_table/AllTypesTableTest.java | 4 +--- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java index 1c8debc..6d71aaf 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java @@ -2,7 +2,6 @@ import java.util.function.Function; import org.springframework.aop.interceptor.ExposeInvocationInterceptor; -import org.springframework.core.NamedInheritableThreadLocal; import org.springframework.data.relational.core.dialect.AbstractDialect; import org.springframework.data.relational.core.dialect.InsertRenderContext; import org.springframework.data.relational.core.dialect.LimitClause; @@ -60,17 +59,15 @@ protected Function getAfterFromTable() { return ""; } - var viewIndex = ExposeInvocationInterceptor.currentInvocation().getMethod().getAnnotation(ViewIndex.class); - - var tableName = tables.get(0).getReferenceName(); + var viewIndex = ExposeInvocationInterceptor.currentInvocation() + .getMethod() + .getAnnotation(ViewIndex.class); return viewIndex != null ? - "VIEW " + viewIndex.name() + " AS " + tableName : ""; + "VIEW " + viewIndex.name() + " AS " + tables.get(0).getReferenceName() : ""; }; } - public final ThreadLocal viewIndexInfo = new NamedInheritableThreadLocal<>("viewIndexInfo"); - @Override public LimitClause limit() { return LIMIT_CLAUSE; diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java index 3c5034a..f7d093c 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java @@ -7,9 +7,7 @@ import java.time.temporal.ChronoUnit; import java.util.List; import java.util.Optional; - import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.relational.core.conversion.DbActionExecutionException; import tech.ydb.data.YdbBaseTest; @@ -24,7 +22,7 @@ public class AllTypesTableTest extends YdbBaseTest { @Autowired private AllTypesEntityRepository repository; - @Test +// @Test public void allTypesTableCrudTest() { Assertions.assertEquals(3, repository.count()); From f721d07a10f8a4c49cc53a67a281d3b5acefd0e0 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Fri, 23 Aug 2024 17:02:42 +0300 Subject: [PATCH 09/18] Support VIEW INDEX --- .../java/tech/ydb/data/core/dialect/YdbDialect.java | 12 ++++++++++-- .../java/tech/ydb/data/repository/ViewIndex.java | 5 ++++- ...ositories.java => EnableYdbJdbcRepositories.java} | 5 ++++- .../java/tech/ydb/data/YdbJdbcConfiguration.java | 4 ++-- .../ydb/data/books/RepositoriesIntegrationTest.java | 3 ++- .../ydb/data/books/repository/BookRepository.java | 5 ++++- .../src/test/resources/changelogs/books.yaml | 6 ++++++ 7 files changed, 32 insertions(+), 8 deletions(-) rename spring-data-dialect/src/main/java/tech/ydb/data/repository/config/{EnableYdbRepositories.java => EnableYdbJdbcRepositories.java} (75%) diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java index 6d71aaf..b31cd7d 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java @@ -1,5 +1,6 @@ package tech.ydb.data.core.dialect; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; import org.springframework.aop.interceptor.ExposeInvocationInterceptor; import org.springframework.data.relational.core.dialect.AbstractDialect; @@ -53,7 +54,12 @@ public LockClause.Position getClausePosition() { @Override protected Function getAfterFromTable() { + final var invokeMethod = new AtomicBoolean(); return select -> { + if (invokeMethod.get()) { // @MappedCollection without VIEW INDEX! + return ""; + } + var tables = select.getFrom().getTables(); if (tables.size() != 1) { return ""; @@ -63,8 +69,10 @@ protected Function getAfterFromTable() { .getMethod() .getAnnotation(ViewIndex.class); - return viewIndex != null ? - "VIEW " + viewIndex.name() + " AS " + tables.get(0).getReferenceName() : ""; + invokeMethod.set(true); + + return viewIndex != null ? " VIEW " + viewIndex.value() + " AS " + tables.get(0).getReferenceName() + .toSql(INSTANCE.getIdentifierProcessing()) : ""; }; } diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java index 28c0a77..b1994dc 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java @@ -1,13 +1,16 @@ package tech.ydb.data.repository; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * @author Kirill Kurdyukov */ @Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) public @interface ViewIndex { - String name(); + String value() default ""; } diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/EnableYdbRepositories.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/EnableYdbJdbcRepositories.java similarity index 75% rename from spring-data-dialect/src/main/java/tech/ydb/data/repository/config/EnableYdbRepositories.java rename to spring-data-dialect/src/main/java/tech/ydb/data/repository/config/EnableYdbJdbcRepositories.java index 29d6722..461459b 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/EnableYdbRepositories.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/EnableYdbJdbcRepositories.java @@ -5,14 +5,17 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.context.annotation.Import; import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; import tech.ydb.data.repository.support.SimpleYdbJdbcRepository; /** * @author Madiyar Nurgazin + * @author Kirill Kurdyukov */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) +@Import(AbstractYdbJdbcConfiguration.class) @EnableJdbcRepositories(repositoryBaseClass = SimpleYdbJdbcRepository.class) -public @interface EnableYdbRepositories { +public @interface EnableYdbJdbcRepositories { } diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/YdbJdbcConfiguration.java b/spring-data-dialect/src/test/java/tech/ydb/data/YdbJdbcConfiguration.java index d75fc78..341af93 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/YdbJdbcConfiguration.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/YdbJdbcConfiguration.java @@ -7,13 +7,13 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import tech.ydb.data.repository.config.AbstractYdbJdbcConfiguration; -import tech.ydb.data.repository.config.EnableYdbRepositories; +import tech.ydb.data.repository.config.EnableYdbJdbcRepositories; /** * @author Madiyar Nurgazin */ @Configuration -@EnableYdbRepositories +@EnableYdbJdbcRepositories @EnableJdbcAuditing public class YdbJdbcConfiguration extends AbstractYdbJdbcConfiguration { @Bean diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java index 0b577a9..df30c1e 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java @@ -81,7 +81,6 @@ public void crudTest() { book = createBook(3, "Title", "Isbn", 2024, Set.of(), Set.of(new BookAuthor(2, 3), new BookAuthor(3, 3))); bookRepository.insert(book); - expected.get(0).setReviews(Set.of(review1, review2, review3)); books = bookRepository.findBooksByAuthorName("Leo Tolstoy"); Assertions.assertEquals(expected, books); @@ -103,6 +102,8 @@ public void crudTest() { Optional author = authorRepository.findById(author2.getId()); Assertions.assertTrue(author.isPresent()); Assertions.assertTrue(author.get().getBooks().isEmpty()); + + Assertions.assertEquals(expected.get(0), bookRepository.findBookByIsbn("1234").get(0)); } @Test diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/BookRepository.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/BookRepository.java index 1f7b9f4..71cf6d8 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/BookRepository.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/BookRepository.java @@ -2,10 +2,10 @@ import java.util.List; import java.util.Optional; - import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.repository.query.Param; import tech.ydb.data.books.entity.Book; +import tech.ydb.data.repository.ViewIndex; import tech.ydb.data.repository.YdbCrudRepository; /** @@ -16,5 +16,8 @@ public interface BookRepository extends YdbCrudRepository { " join authors on authors.id = books_authors.author_id where name = :author") List findBooksByAuthorName(@Param("author") String author); + @ViewIndex("isbn_books_index") + List findBookByIsbn(String isbn); + Optional findBookByTitle(String title); } diff --git a/spring-data-dialect/src/test/resources/changelogs/books.yaml b/spring-data-dialect/src/test/resources/changelogs/books.yaml index eaf4633..1e2ff86 100644 --- a/spring-data-dialect/src/test/resources/changelogs/books.yaml +++ b/spring-data-dialect/src/test/resources/changelogs/books.yaml @@ -49,6 +49,12 @@ databaseChangeLog: - column: name: year type: bigint + - createIndex: + indexName: isbn_books_index + tableName: books + columns: + - column: + name: isbn - insert: tableName: books columns: From 4ef3c02c5da377be4cff73423466456f9993f5e2 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Fri, 23 Aug 2024 19:24:42 +0300 Subject: [PATCH 10/18] delete extend interfaces --- .../data/repository/YdbCrudRepository.java | 14 ------ .../repository/YdbListCrudRepository.java | 16 ------ .../YdbListPagingAndSortingRepository.java | 12 ----- .../YdbPagingAndSortingRepository.java | 11 ----- .../ydb/data/repository/YdbRepository.java | 14 ------ .../config/EnableYdbJdbcRepositories.java | 21 -------- .../support/SimpleYdbJdbcRepository.java | 49 ------------------- .../data/repository/support/package-info.java | 4 -- .../tech/ydb/data/YdbJdbcConfiguration.java | 13 +---- .../all_types_table/AllTypesTableTest.java | 12 +++-- .../entity/AllTypesEntity.java | 10 ++-- .../repository/AllTypesEntityRepository.java | 5 +- .../books/RepositoriesIntegrationTest.java | 18 ++++--- .../tech/ydb/data/books/entity/Author.java | 21 ++++++-- .../java/tech/ydb/data/books/entity/Book.java | 20 +++++++- .../tech/ydb/data/books/entity/Review.java | 20 +++++++- .../books/repository/AuthorRepository.java | 5 +- .../data/books/repository/BookRepository.java | 4 +- .../books/repository/ReviewRepository.java | 10 ++-- 19 files changed, 93 insertions(+), 186 deletions(-) delete mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbCrudRepository.java delete mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbListCrudRepository.java delete mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbListPagingAndSortingRepository.java delete mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbPagingAndSortingRepository.java delete mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbRepository.java delete mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/repository/config/EnableYdbJdbcRepositories.java delete mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/repository/support/SimpleYdbJdbcRepository.java delete mode 100644 spring-data-dialect/src/main/java/tech/ydb/data/repository/support/package-info.java diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbCrudRepository.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbCrudRepository.java deleted file mode 100644 index 84dd708..0000000 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbCrudRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package tech.ydb.data.repository; - -import org.springframework.data.repository.CrudRepository; -import org.springframework.data.repository.NoRepositoryBean; - -/** - * @author Madiyar Nurgazin - */ -@NoRepositoryBean -public interface YdbCrudRepository extends YdbRepository, CrudRepository { - Iterable insertAll(Iterable entities); - - Iterable updateAll(Iterable entities); -} diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbListCrudRepository.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbListCrudRepository.java deleted file mode 100644 index 4b58a83..0000000 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbListCrudRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package tech.ydb.data.repository; - -import java.util.List; - -import org.springframework.data.repository.ListCrudRepository; -import org.springframework.data.repository.NoRepositoryBean; - -/** - * @author Madiyar Nurgazin - */ -@NoRepositoryBean -public interface YdbListCrudRepository extends YdbRepository, ListCrudRepository { - List insertAll(Iterable entities); - - List updateAll(Iterable entities); -} diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbListPagingAndSortingRepository.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbListPagingAndSortingRepository.java deleted file mode 100644 index 8b75dfc..0000000 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbListPagingAndSortingRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package tech.ydb.data.repository; - -import org.springframework.data.repository.ListPagingAndSortingRepository; -import org.springframework.data.repository.NoRepositoryBean; - -/** - * @author Madiyar Nurgazin - */ -@NoRepositoryBean -public interface YdbListPagingAndSortingRepository extends YdbRepository, - ListPagingAndSortingRepository { -} diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbPagingAndSortingRepository.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbPagingAndSortingRepository.java deleted file mode 100644 index e453ff9..0000000 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbPagingAndSortingRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package tech.ydb.data.repository; - -import org.springframework.data.repository.NoRepositoryBean; -import org.springframework.data.repository.PagingAndSortingRepository; - -/** - * @author Madiyar Nurgazin - */ -@NoRepositoryBean -public interface YdbPagingAndSortingRepository extends YdbRepository, PagingAndSortingRepository { -} diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbRepository.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbRepository.java deleted file mode 100644 index fbfdc91..0000000 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/YdbRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package tech.ydb.data.repository; - -import org.springframework.data.repository.NoRepositoryBean; -import org.springframework.data.repository.Repository; - -/** - * @author Madiyar Nurgazin - */ -@NoRepositoryBean -public interface YdbRepository extends Repository { - S insert(S entity); - - S update(S entity); -} diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/EnableYdbJdbcRepositories.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/EnableYdbJdbcRepositories.java deleted file mode 100644 index 461459b..0000000 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/config/EnableYdbJdbcRepositories.java +++ /dev/null @@ -1,21 +0,0 @@ -package tech.ydb.data.repository.config; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Import; -import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; -import tech.ydb.data.repository.support.SimpleYdbJdbcRepository; - -/** - * @author Madiyar Nurgazin - * @author Kirill Kurdyukov - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Import(AbstractYdbJdbcConfiguration.class) -@EnableJdbcRepositories(repositoryBaseClass = SimpleYdbJdbcRepository.class) -public @interface EnableYdbJdbcRepositories { -} diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/SimpleYdbJdbcRepository.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/SimpleYdbJdbcRepository.java deleted file mode 100644 index 9f83e79..0000000 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/SimpleYdbJdbcRepository.java +++ /dev/null @@ -1,49 +0,0 @@ -package tech.ydb.data.repository.support; - -import org.springframework.data.jdbc.core.JdbcAggregateOperations; -import org.springframework.data.jdbc.core.convert.JdbcConverter; -import org.springframework.data.jdbc.repository.support.SimpleJdbcRepository; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.transaction.annotation.Transactional; -import tech.ydb.data.repository.YdbCrudRepository; -import tech.ydb.data.repository.YdbPagingAndSortingRepository; - -/** - * @author Madiyar Nurgazin - */ -@Transactional(readOnly = true) -public class SimpleYdbJdbcRepository extends SimpleJdbcRepository - implements YdbCrudRepository, YdbPagingAndSortingRepository { - private final JdbcAggregateOperations entityOperations; - - public SimpleYdbJdbcRepository( - JdbcAggregateOperations entityOperations, PersistentEntity entity, JdbcConverter converter - ) { - super(entityOperations, entity, converter); - this.entityOperations = entityOperations; - } - - @Transactional - @Override - public S insert(S entity) { - return entityOperations.insert(entity); - } - - @Transactional - @Override - public S update(S entity) { - return entityOperations.update(entity); - } - - @Transactional - @Override - public Iterable insertAll(Iterable entities) { - return entityOperations.insertAll(entities); - } - - @Transactional - @Override - public Iterable updateAll(Iterable entities) { - return entityOperations.updateAll(entities); - } -} diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/package-info.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/package-info.java deleted file mode 100644 index 8ce4324..0000000 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/support/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@NonNullApi -package tech.ydb.data.repository.support; - -import org.springframework.lang.NonNullApi; \ No newline at end of file diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/YdbJdbcConfiguration.java b/spring-data-dialect/src/test/java/tech/ydb/data/YdbJdbcConfiguration.java index 341af93..eb94106 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/YdbJdbcConfiguration.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/YdbJdbcConfiguration.java @@ -1,24 +1,15 @@ package tech.ydb.data; -import javax.sql.DataSource; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jdbc.repository.config.EnableJdbcAuditing; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; import tech.ydb.data.repository.config.AbstractYdbJdbcConfiguration; -import tech.ydb.data.repository.config.EnableYdbJdbcRepositories; /** * @author Madiyar Nurgazin */ @Configuration -@EnableYdbJdbcRepositories +@EnableJdbcRepositories @EnableJdbcAuditing public class YdbJdbcConfiguration extends AbstractYdbJdbcConfiguration { - @Bean - public NamedParameterJdbcTemplate namedParameterJdbcTemplate(DataSource dataSource) { - JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); - return new NamedParameterJdbcTemplate(jdbcTemplate); - } } diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java index f7d093c..94e7de0 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java @@ -28,7 +28,6 @@ public void allTypesTableCrudTest() { Optional entity1 = repository.findById(1); Assertions.assertTrue(entity1.isPresent()); - AllTypesEntity expected = new AllTypesEntity( 1, "Madiyar Nurgazin", true, (byte) 1, (short) 2, 123123L, 1.123f, 1.123123d, new BigDecimal("1.123123000"), "binary".getBytes(), LocalDate.parse("2024-03-19"), @@ -36,6 +35,8 @@ public void allTypesTableCrudTest() { LocalDateTime.parse("2024-03-20T10:30:00"), "{\"a\" : \"b\"}", "{\"c\":\"d\"}", (byte) 3, (short) 4, 5, 12341234L ); + repository.save(expected); + Assertions.assertEquals(expected, entity1.get()); AllTypesEntity entity2 = new AllTypesEntity( @@ -45,7 +46,7 @@ public void allTypesTableCrudTest() { "{}", "{}", (byte) 3, (short) 4, 5, 12341234L ); - repository.insert(entity2); + repository.save(entity2); Assertions.assertEquals(2, repository.countDistinctTextColumn()); List entities = repository.findAll(); @@ -59,17 +60,18 @@ public void allTypesTableCrudTest() { 5, "text", true, (byte) 0, (short) 0, 0L, 0.0f, 0.0d, BigDecimal.ZERO, "".getBytes(), null, null, null, null, null, null, (byte) 0, (short) 0, 0, 0L ); - repository.insert(entity3); + + repository.save(entity3); entities = repository.findAllByDateColumnAfterNow(); Assertions.assertEquals(1, entities.size()); Assertions.assertEquals(4, entities.get(0).getId()); entity3.setJsonColumn("Not json"); - Assertions.assertThrows(DbActionExecutionException.class, () -> repository.update(entity3)); + Assertions.assertThrows(DbActionExecutionException.class, () -> repository.save(entity3)); entity3.setJsonColumn("{\"values\": [1, 2, 3]}"); - AllTypesEntity updated = repository.update(entity3); + AllTypesEntity updated = repository.save(entity3); Assertions.assertEquals(entity3, updated); Assertions.assertTrue(LocalDateTime.now().isAfter(entity3.getModified())); Assertions.assertTrue(LocalDateTime.now().minusSeconds(1).isBefore(entity3.getModified())); diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java index fc3f648..b2e5834 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java @@ -4,11 +4,11 @@ import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; - import lombok.AllArgsConstructor; import lombok.Data; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.domain.Persistable; import org.springframework.data.relational.core.mapping.Table; import tech.ydb.data.core.convert.YdbType; import tech.ydb.table.values.PrimitiveType; @@ -19,9 +19,9 @@ @AllArgsConstructor @Data @Table("all_types_table") -public class AllTypesEntity { +public class AllTypesEntity implements Persistable { @Id - private int id; + private Integer id; private String textColumn; private boolean boolColumn; private byte tinyintColumn; @@ -51,4 +51,8 @@ public class AllTypesEntity { public AllTypesEntity() { } + @Override + public boolean isNew() { + return false; + } } diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/repository/AllTypesEntityRepository.java b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/repository/AllTypesEntityRepository.java index b14ea67..2e39981 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/repository/AllTypesEntityRepository.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/repository/AllTypesEntityRepository.java @@ -1,15 +1,14 @@ package tech.ydb.data.all_types_table.repository; import java.util.List; - import org.springframework.data.jdbc.repository.query.Query; +import org.springframework.data.repository.ListCrudRepository; import tech.ydb.data.all_types_table.entity.AllTypesEntity; -import tech.ydb.data.repository.YdbListCrudRepository; /** * @author Madiyar Nurgazin */ -public interface AllTypesEntityRepository extends YdbListCrudRepository { +public interface AllTypesEntityRepository extends ListCrudRepository { @Query("select count(distinct text_column) from all_types_table") long countDistinctTextColumn(); diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java index df30c1e..e8b9bf3 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java @@ -55,16 +55,19 @@ public void crudTest() { Book book = bookO.get(); book.getReviews().add(review3); - bookRepository.update(book); + bookRepository.save(book); Assertions.assertEquals(3, reviewRepository.count()); review1.setRating(100); + review1.setNew(false); review2.setRating(90); + review2.setNew(false); review3.setRating(80); + review3.setNew(false); Set reviews = Set.of(review1, review2, review3); - reviewRepository.updateAll(reviews); + reviewRepository.saveAll(reviews); bookO = bookRepository.findById(1L); Assertions.assertTrue(bookO.isPresent()); @@ -75,11 +78,11 @@ public void crudTest() { Author author1 = createAuthor(2, "Author 1"); Author author2 = createAuthor(3, "Author 2"); - authorRepository.insertAll(List.of(author1, author2)); + authorRepository.saveAll(List.of(author1, author2)); Assertions.assertEquals(3, authorRepository.count()); book = createBook(3, "Title", "Isbn", 2024, Set.of(), Set.of(new BookAuthor(2, 3), new BookAuthor(3, 3))); - bookRepository.insert(book); + bookRepository.save(book); expected.get(0).setReviews(Set.of(review1, review2, review3)); books = bookRepository.findBooksByAuthorName("Leo Tolstoy"); @@ -92,7 +95,7 @@ public void crudTest() { Assertions.assertEquals(Set.of(author1, author2), Set.copyOf(authors)); Review review = createReview(4, 3, "Reader", "Text", 5, LocalDateTime.now()); - reviewRepository.insert(review); + reviewRepository.save(review); bookRepository.deleteById(3L); @@ -118,7 +121,7 @@ public void pagingAndSortingTest() { Review review4 = createReview(4, 1, "Reader", "Text2", 80, LocalDateTime.parse("2024-03-19T22:00:00")); Review review5 = createReview(5, 1, "Reader", "Text3", 75, LocalDateTime.parse("2024-03-19T23:00:00")); Review review6 = createReview(6, 1, "Reader", "Text4", 50, LocalDateTime.parse("2024-03-20T00:00:00")); - reviewRepository.insertAll(List.of(review3, review4, review5, review6)); + reviewRepository.saveAll(List.of(review3, review4, review5, review6)); Iterable reviews = reviewRepository.findByReader( "Reader", PageRequest.of(0, 2, Sort.by("rating").descending()) @@ -151,6 +154,7 @@ private Review createReview(long id, long bookId, String reader, String text, lo review.setText(text); review.setRating(rating); review.setCreated(created); + review.setNew(true); return review; } @@ -164,6 +168,7 @@ private Book createBook( book.setYear(year); book.setReviews(reviews); book.setAuthors(authors); + book.setNew(true); return book; } @@ -171,6 +176,7 @@ private Author createAuthor(long id, String name) { Author author = new Author(); author.setId(id); author.setName(name); + author.setNew(true); return author; } } diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Author.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Author.java index 50ff5da..7f8e15b 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Author.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Author.java @@ -2,9 +2,11 @@ import java.util.HashSet; import java.util.Set; - import lombok.Data; +import lombok.EqualsAndHashCode; import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.Transient; +import org.springframework.data.domain.Persistable; import org.springframework.data.relational.core.mapping.MappedCollection; import org.springframework.data.relational.core.mapping.Table; @@ -13,14 +15,27 @@ */ @Data @Table("authors") -public class Author { +public class Author implements Persistable { @Id - private long id; + private Long id; private String name; @MappedCollection(idColumn = "author_id") private Set books; + @Transient + @EqualsAndHashCode.Exclude + private boolean isNew; + public Author() { this.books = new HashSet<>(); } + + @Override + public boolean isNew() { + return isNew; + } + + public void setNew(boolean isNew) { + this.isNew = isNew; + } } diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Book.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Book.java index 337779d..cd9b89e 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Book.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Book.java @@ -4,7 +4,10 @@ import java.util.Set; import lombok.Data; +import lombok.EqualsAndHashCode; import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.Transient; +import org.springframework.data.domain.Persistable; import org.springframework.data.relational.core.mapping.MappedCollection; import org.springframework.data.relational.core.mapping.Table; @@ -13,9 +16,9 @@ */ @Data @Table("books") -public class Book { +public class Book implements Persistable { @Id - private long id; + private Long id; private String title; private String isbn; private long year; @@ -25,8 +28,21 @@ public class Book { @MappedCollection(idColumn = "book_id") private Set authors; + @Transient + @EqualsAndHashCode.Exclude + private boolean isNew; + + @Override + public boolean isNew() { + return isNew; + } + public Book() { this.reviews = new HashSet<>(); this.authors = new HashSet<>(); } + + public void setNew(boolean isNew) { + this.isNew = isNew; + } } diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Review.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Review.java index 25e90fd..e0e04e5 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Review.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Review.java @@ -3,7 +3,10 @@ import java.time.LocalDateTime; import lombok.Data; +import lombok.EqualsAndHashCode; import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.Transient; +import org.springframework.data.domain.Persistable; import org.springframework.data.relational.core.mapping.Table; /** @@ -11,9 +14,9 @@ */ @Data @Table("reviews") -public class Review { +public class Review implements Persistable { @Id - private long id; + private Long id; private long bookId; private String reader; private String text; @@ -23,4 +26,17 @@ public class Review { public Review() { this.created = LocalDateTime.now(); } + + @Transient + @EqualsAndHashCode.Exclude + private boolean isNew; + + @Override + public boolean isNew() { + return isNew; + } + + public void setNew(boolean isNew) { + this.isNew = isNew; + } } diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/AuthorRepository.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/AuthorRepository.java index d21f4a8..65bb851 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/AuthorRepository.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/AuthorRepository.java @@ -1,16 +1,15 @@ package tech.ydb.data.books.repository; import java.util.List; - import org.springframework.data.jdbc.repository.query.Query; +import org.springframework.data.repository.ListCrudRepository; import org.springframework.data.repository.query.Param; import tech.ydb.data.books.entity.Author; -import tech.ydb.data.repository.YdbListCrudRepository; /** * @author Madiyar Nurgazin */ -public interface AuthorRepository extends YdbListCrudRepository { +public interface AuthorRepository extends ListCrudRepository { @Query("select authors.* from authors join books_authors on authors.id = books_authors.author_id" + " where books_authors.book_id = :bookId") List findAuthorsByBookId(@Param("bookId") long bookId); diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/BookRepository.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/BookRepository.java index 71cf6d8..1ad319e 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/BookRepository.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/BookRepository.java @@ -3,15 +3,15 @@ import java.util.List; import java.util.Optional; import org.springframework.data.jdbc.repository.query.Query; +import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import tech.ydb.data.books.entity.Book; import tech.ydb.data.repository.ViewIndex; -import tech.ydb.data.repository.YdbCrudRepository; /** * @author Madiyar Nurgazin */ -public interface BookRepository extends YdbCrudRepository { +public interface BookRepository extends CrudRepository { @Query("select books.* from books join books_authors on books.id = books_authors.book_id" + " join authors on authors.id = books_authors.author_id where name = :author") List findBooksByAuthorName(@Param("author") String author); diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/ReviewRepository.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/ReviewRepository.java index 5c660e0..2644ce1 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/ReviewRepository.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/ReviewRepository.java @@ -1,16 +1,16 @@ package tech.ydb.data.books.repository; import java.util.List; - import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.ListCrudRepository; +import org.springframework.data.repository.PagingAndSortingRepository; import tech.ydb.data.books.entity.Review; -import tech.ydb.data.repository.YdbListCrudRepository; -import tech.ydb.data.repository.YdbPagingAndSortingRepository; /** * @author Madiyar Nurgazin */ -public interface ReviewRepository extends YdbListCrudRepository, - YdbPagingAndSortingRepository { +public interface ReviewRepository extends ListCrudRepository, + CrudRepository, PagingAndSortingRepository { List findByReader(String reader, Pageable pageable); } From 832723aad4b01b240fca5354d0e0454481e1e714 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Mon, 26 Aug 2024 17:41:25 +0300 Subject: [PATCH 11/18] update --- spring-data-dialect/pom.xml | 21 ++++++++------ .../core/convert/YdbMappingJdbcConverter.java | 6 ++-- .../tech/ydb/data/core/convert/YdbType.java | 4 +-- .../ydb/data/core/dialect/YdbDialect.java | 15 ++++------ .../tech/ydb/data/repository/ViewIndex.java | 4 ++- .../all_types_table/AllTypesTableTest.java | 28 ++++++++++--------- .../entity/AllTypesEntity.java | 18 ++++++------ .../repository/AllTypesEntityRepository.java | 5 ++++ .../books/RepositoriesIntegrationTest.java | 3 ++ .../books/repository/AuthorRepository.java | 4 +++ .../data/books/repository/BookRepository.java | 2 +- .../books/repository/ReviewRepository.java | 1 + .../resources/changelogs/all_types_table.yaml | 9 ++++-- .../src/test/resources/changelogs/books.yaml | 6 ++++ .../changelogs/insert_all_types_table.csv | 8 +++--- 15 files changed, 78 insertions(+), 56 deletions(-) diff --git a/spring-data-dialect/pom.xml b/spring-data-dialect/pom.xml index be3b220..51a5652 100644 --- a/spring-data-dialect/pom.xml +++ b/spring-data-dialect/pom.xml @@ -49,15 +49,13 @@ 17 17 - 3.2.4 - 5.10.2 1.18.30 - 3.2.3 + 3.3.3 4.24.0 - 2.2.6 - 2.2.2 + 2.2.9 + 2.2.3 0.9.7 @@ -70,6 +68,13 @@ pom import + + org.springframework.boot + spring-boot-dependencies + ${spring.version} + import + pom + @@ -77,14 +82,15 @@ org.springframework.data spring-data-jdbc - ${springdata.jdbc.version} provided tech.ydb.jdbc ydb-jdbc-driver ${ydb.jdbc.version} + provided + tech.ydb.test ydb-junit5-support @@ -93,7 +99,6 @@ org.junit.jupiter junit-jupiter-api - ${junit5.version} test @@ -105,13 +110,11 @@ org.springframework.boot spring-boot-starter-test - ${spring.boot.version} test org.springframework.boot spring-boot-starter-jdbc - ${spring.boot.version} test diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java index 4cc6990..7d8c8ea 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbMappingJdbcConverter.java @@ -5,9 +5,9 @@ import org.springframework.data.jdbc.core.convert.JdbcTypeFactory; import org.springframework.data.jdbc.core.convert.MappingJdbcConverter; import org.springframework.data.jdbc.core.convert.RelationResolver; -import org.springframework.data.jdbc.support.JdbcUtil; import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; +import tech.ydb.table.values.PrimitiveType; /** * @author Madiyar Nurgazin @@ -21,7 +21,7 @@ public YdbMappingJdbcConverter(RelationalMappingContext context, RelationResolve @Override public SQLType getTargetSqlType(RelationalPersistentProperty property) { return property.isAnnotationPresent(YdbType.class) ? - new YQLType(property.getRequiredAnnotation(YdbType.class).value()) : - JdbcUtil.targetSqlTypeFor(getColumnType(property)); + new YQLType(PrimitiveType.valueOf(property.getRequiredAnnotation(YdbType.class).value())) : + super.getTargetSqlType(property); } } diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbType.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbType.java index a700cb5..1bdeafc 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbType.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/convert/YdbType.java @@ -5,13 +5,11 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import tech.ydb.table.values.PrimitiveType; - /** * @author Madiyar Nurgazin */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface YdbType { - PrimitiveType value(); + String value(); } diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java b/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java index b31cd7d..3dd1738 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/core/dialect/YdbDialect.java @@ -1,6 +1,5 @@ package tech.ydb.data.core.dialect; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; import org.springframework.aop.interceptor.ExposeInvocationInterceptor; import org.springframework.data.relational.core.dialect.AbstractDialect; @@ -54,12 +53,7 @@ public LockClause.Position getClausePosition() { @Override protected Function getAfterFromTable() { - final var invokeMethod = new AtomicBoolean(); return select -> { - if (invokeMethod.get()) { // @MappedCollection without VIEW INDEX! - return ""; - } - var tables = select.getFrom().getTables(); if (tables.size() != 1) { return ""; @@ -69,10 +63,13 @@ protected Function getAfterFromTable() { .getMethod() .getAnnotation(ViewIndex.class); - invokeMethod.set(true); + if (viewIndex != null && (viewIndex.tableName().isEmpty() || + viewIndex.tableName().equals(tables.get(0).getName().toSql(IdentifierProcessing.NONE)))) { + return " VIEW " + viewIndex.indexName() + " AS " + tables.get(0).getReferenceName() + .toSql(INSTANCE.getIdentifierProcessing()); + } - return viewIndex != null ? " VIEW " + viewIndex.value() + " AS " + tables.get(0).getReferenceName() - .toSql(INSTANCE.getIdentifierProcessing()) : ""; + return ""; }; } diff --git a/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java b/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java index b1994dc..51257ee 100644 --- a/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java +++ b/spring-data-dialect/src/main/java/tech/ydb/data/repository/ViewIndex.java @@ -12,5 +12,7 @@ @Target(ElementType.METHOD) public @interface ViewIndex { - String value() default ""; + String indexName() default ""; + + String tableName() default ""; } diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java index 94e7de0..ea1e98b 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/AllTypesTableTest.java @@ -8,7 +8,9 @@ import java.util.List; import java.util.Optional; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jdbc.core.JdbcAggregateOperations; import org.springframework.data.relational.core.conversion.DbActionExecutionException; import tech.ydb.data.YdbBaseTest; import tech.ydb.data.all_types_table.entity.AllTypesEntity; @@ -22,7 +24,10 @@ public class AllTypesTableTest extends YdbBaseTest { @Autowired private AllTypesEntityRepository repository; -// @Test + @Autowired + private JdbcAggregateOperations aggregateOperations; + + @Test public void allTypesTableCrudTest() { Assertions.assertEquals(3, repository.count()); @@ -31,22 +36,22 @@ public void allTypesTableCrudTest() { AllTypesEntity expected = new AllTypesEntity( 1, "Madiyar Nurgazin", true, (byte) 1, (short) 2, 123123L, 1.123f, 1.123123d, new BigDecimal("1.123123000"), "binary".getBytes(), LocalDate.parse("2024-03-19"), - LocalDateTime.parse("2024-03-20T10:30:12"), Instant.parse("2024-07-21T17:00:00Z"), - LocalDateTime.parse("2024-03-20T10:30:00"), "{\"a\" : \"b\"}", "{\"c\":\"d\"}", - (byte) 3, (short) 4, 5, 12341234L + LocalDateTime.parse("2024-03-20T10:30"), Instant.parse("2024-07-21T17:00:00Z"), + "{\"a\" : \"b\"}", "{\"c\":\"d\"}", (byte) 3, (short) 4, 5, 12341234L ); repository.save(expected); Assertions.assertEquals(expected, entity1.get()); + Assertions.assertEquals(expected.getTextColumn(), + repository.findAllByTextColumn("Madiyar Nurgazin").get(0).getTextColumn()); AllTypesEntity entity2 = new AllTypesEntity( 4, "text", false, (byte) 255, (short) 256, 1L, 1.0f, 123.123d, new BigDecimal("12.345678900"), "text".getBytes(), LocalDate.now().plusDays(2), - LocalDateTime.now().minusDays(1), Instant.now().minus(10, ChronoUnit.HOURS), LocalDateTime.now(), - "{}", "{}", (byte) 3, (short) 4, 5, - 12341234L + LocalDateTime.now().minusDays(1), Instant.now().minus(10, ChronoUnit.HOURS), + "{}", "{}", (byte) 3, (short) 4, 5, 12341234L ); - repository.save(entity2); + aggregateOperations.insert(entity2); Assertions.assertEquals(2, repository.countDistinctTextColumn()); List entities = repository.findAll(); @@ -58,10 +63,9 @@ public void allTypesTableCrudTest() { AllTypesEntity entity3 = new AllTypesEntity( 5, "text", true, (byte) 0, (short) 0, 0L, 0.0f, 0.0d, - BigDecimal.ZERO, "".getBytes(), null, null, null, null, null, null, (byte) 0, (short) 0, 0, 0L + BigDecimal.ZERO, "".getBytes(), null, null, null, null, null, (byte) 0, (short) 0, 0, 0L ); - - repository.save(entity3); + aggregateOperations.insert(entity3); entities = repository.findAllByDateColumnAfterNow(); Assertions.assertEquals(1, entities.size()); @@ -73,8 +77,6 @@ public void allTypesTableCrudTest() { entity3.setJsonColumn("{\"values\": [1, 2, 3]}"); AllTypesEntity updated = repository.save(entity3); Assertions.assertEquals(entity3, updated); - Assertions.assertTrue(LocalDateTime.now().isAfter(entity3.getModified())); - Assertions.assertTrue(LocalDateTime.now().minusSeconds(1).isBefore(entity3.getModified())); entity3.setJsonDocumentColumn("{\"value\" : 5}"); AllTypesEntity saved = repository.save(entity3); diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java index b2e5834..f1caa6b 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java @@ -7,11 +7,9 @@ import lombok.AllArgsConstructor; import lombok.Data; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.domain.Persistable; import org.springframework.data.relational.core.mapping.Table; import tech.ydb.data.core.convert.YdbType; -import tech.ydb.table.values.PrimitiveType; /** * @author Madiyar Nurgazin @@ -31,22 +29,22 @@ public class AllTypesEntity implements Persistable { private double doubleColumn; private BigDecimal decimalColumn; private byte[] binaryColumn; + @YdbType("Date") private LocalDate dateColumn; + @YdbType("Datetime") private LocalDateTime datetimeColumn; private Instant timestampColumn; - @LastModifiedDate - private LocalDateTime modified; - @YdbType(PrimitiveType.Json) + @YdbType("Json") private String jsonColumn; - @YdbType(PrimitiveType.JsonDocument) + @YdbType("JsonDocument") private String jsonDocumentColumn; - @YdbType(PrimitiveType.Uint8) + @YdbType("Uint8") private byte uint8Column; - @YdbType(PrimitiveType.Uint16) + @YdbType("Uint16") private short uint16Column; - @YdbType(PrimitiveType.Uint32) + @YdbType("Uint32") private int uint32Column; - @YdbType(PrimitiveType.Uint64) + @YdbType("Uint64") private long uint64Column; public AllTypesEntity() { diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/repository/AllTypesEntityRepository.java b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/repository/AllTypesEntityRepository.java index 2e39981..a267e81 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/repository/AllTypesEntityRepository.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/repository/AllTypesEntityRepository.java @@ -3,7 +3,9 @@ import java.util.List; import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.repository.ListCrudRepository; +import org.springframework.data.repository.query.Param; import tech.ydb.data.all_types_table.entity.AllTypesEntity; +import tech.ydb.data.repository.ViewIndex; /** * @author Madiyar Nurgazin @@ -14,4 +16,7 @@ public interface AllTypesEntityRepository extends ListCrudRepository CurrentUtcDate()") List findAllByDateColumnAfterNow(); + + @ViewIndex(indexName = "text_column_index") + List findAllByTextColumn(@Param("textColumn") String textColumn); } diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java index e8b9bf3..88e3ae1 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java @@ -32,9 +32,12 @@ public class RepositoriesIntegrationTest extends YdbBaseTest { @Test public void crudTest() { + Assertions.assertEquals(1, authorRepository.findAuthorByName("Leo Tolstoy").get(0).getId()); + Review review1 = createReview( 1, 1, "Ivan Ivanov", "Masterpiece!", 10, LocalDateTime.parse("2024-03-19T15:52:26") ); + Review review2 = createReview( 2, 1, "Sergey Petrov", "Complex work, but I liked it", 9, LocalDateTime.parse("2024-03-19T16:14:05") ); diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/AuthorRepository.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/AuthorRepository.java index 65bb851..86582a4 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/AuthorRepository.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/AuthorRepository.java @@ -5,6 +5,7 @@ import org.springframework.data.repository.ListCrudRepository; import org.springframework.data.repository.query.Param; import tech.ydb.data.books.entity.Author; +import tech.ydb.data.repository.ViewIndex; /** * @author Madiyar Nurgazin @@ -13,4 +14,7 @@ public interface AuthorRepository extends ListCrudRepository { @Query("select authors.* from authors join books_authors on authors.id = books_authors.author_id" + " where books_authors.book_id = :bookId") List findAuthorsByBookId(@Param("bookId") long bookId); + + @ViewIndex(indexName = "name_authors_index", tableName = "authors") + List findAuthorByName(@Param("name") String name); } diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/BookRepository.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/BookRepository.java index 1ad319e..e35c163 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/BookRepository.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/BookRepository.java @@ -16,7 +16,7 @@ public interface BookRepository extends CrudRepository { " join authors on authors.id = books_authors.author_id where name = :author") List findBooksByAuthorName(@Param("author") String author); - @ViewIndex("isbn_books_index") + @ViewIndex(indexName = "isbn_books_index", tableName = "books") List findBookByIsbn(String isbn); Optional findBookByTitle(String title); diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/ReviewRepository.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/ReviewRepository.java index 2644ce1..dae7191 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/ReviewRepository.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/repository/ReviewRepository.java @@ -12,5 +12,6 @@ */ public interface ReviewRepository extends ListCrudRepository, CrudRepository, PagingAndSortingRepository { + List findByReader(String reader, Pageable pageable); } diff --git a/spring-data-dialect/src/test/resources/changelogs/all_types_table.yaml b/spring-data-dialect/src/test/resources/changelogs/all_types_table.yaml index 360f84f..812b86d 100644 --- a/spring-data-dialect/src/test/resources/changelogs/all_types_table.yaml +++ b/spring-data-dialect/src/test/resources/changelogs/all_types_table.yaml @@ -45,9 +45,6 @@ databaseChangeLog: - column: name: datetime_column type: datetime - - column: - name: modified - type: datetime - column: name: timestamp_column type: timestamp @@ -69,6 +66,12 @@ databaseChangeLog: - column: name: uint64_column type: uint64 + - createIndex: + indexName: text_column_index + tableName: all_types_table + columns: + - column: + name: text_column rollback: - dropTable: tableName: all_types_table diff --git a/spring-data-dialect/src/test/resources/changelogs/books.yaml b/spring-data-dialect/src/test/resources/changelogs/books.yaml index 1e2ff86..cc46a6d 100644 --- a/spring-data-dialect/src/test/resources/changelogs/books.yaml +++ b/spring-data-dialect/src/test/resources/changelogs/books.yaml @@ -24,6 +24,12 @@ databaseChangeLog: - column: name: name value: "Leo Tolstoy" + - createIndex: + indexName: name_authors_index + tableName: authors + columns: + - column: + name: name rollback: - dropTable: tableName: authors diff --git a/spring-data-dialect/src/test/resources/changelogs/insert_all_types_table.csv b/spring-data-dialect/src/test/resources/changelogs/insert_all_types_table.csv index 0e06baf..60b1b06 100644 --- a/spring-data-dialect/src/test/resources/changelogs/insert_all_types_table.csv +++ b/spring-data-dialect/src/test/resources/changelogs/insert_all_types_table.csv @@ -1,4 +1,4 @@ -id,text_column,bool_column,tinyint_column,smallint_column,bigint_column,float_column,double_column,decimal_column,binary_column,date_column,datetime_column,timestamp_column,modified,json_column,json_document_column,uint8_column,uint16_column,uint32_column,uint64_column -1,Madiyar Nurgazin,true,1,2,123123,1.123,1.123123,1.123123,binary,2024-03-19,2024-03-20T10:30:12,2024-07-21T17:00:00.000000Z,2024-03-20T10:30:00,{"a" : "b"},{"c" : "d"},3,4,5,12341234 -2,Madiyar Nurgazin,true,1,2,123123,1.123,1.123123,1.123123,binary,2024-03-19,2024-03-20T10:30:12,2024-02-21T17:00:00.000000Z,2024-03-20T10:30:00,{"a" : "b"},{"c" : "d"},3,4,5,12341234 -3,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null +id,text_column,bool_column,tinyint_column,smallint_column,bigint_column,float_column,double_column,decimal_column,binary_column,date_column,datetime_column,timestamp_column,json_column,json_document_column,uint8_column,uint16_column,uint32_column,uint64_column +1,Madiyar Nurgazin,true,1,2,123123,1.123,1.123123,1.123123,binary,2024-03-19,2024-03-20T10:30,2024-07-21T17:00:00.000000Z,{"a" : "b"},{"c" : "d"},3,4,5,12341234 +2,Madiyar Nurgazin,true,1,2,123123,1.123,1.123123,1.123123,binary,2024-03-19,2024-03-20T10:30,2024-02-21T17:00:00.000000Z,{"a" : "b"},{"c" : "d"},3,4,5,12341234 +3,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null From 1dc25054cc3aed924b8c9339df9df8ec6b46d704 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Mon, 26 Aug 2024 17:46:54 +0300 Subject: [PATCH 12/18] update --- .../entity/AllTypesEntity.java | 2 +- .../books/RepositoriesIntegrationTest.java | 24 +++++++++---------- .../tech/ydb/data/books/entity/Review.java | 7 +++--- .../src/test/resources/changelogs/books.yaml | 2 +- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java index f1caa6b..d413c72 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java @@ -29,7 +29,7 @@ public class AllTypesEntity implements Persistable { private double doubleColumn; private BigDecimal decimalColumn; private byte[] binaryColumn; - @YdbType("Date") +// @YdbType("Date") private LocalDate dateColumn; @YdbType("Datetime") private LocalDateTime datetimeColumn; diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java index 88e3ae1..1608a7f 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/RepositoriesIntegrationTest.java @@ -1,6 +1,6 @@ package tech.ydb.data.books; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.List; import java.util.Optional; import java.util.Set; @@ -35,11 +35,11 @@ public void crudTest() { Assertions.assertEquals(1, authorRepository.findAuthorByName("Leo Tolstoy").get(0).getId()); Review review1 = createReview( - 1, 1, "Ivan Ivanov", "Masterpiece!", 10, LocalDateTime.parse("2024-03-19T15:52:26") + 1, 1, "Ivan Ivanov", "Masterpiece!", 10, Instant.parse("2024-03-19T15:52:26Z") ); Review review2 = createReview( - 2, 1, "Sergey Petrov", "Complex work, but I liked it", 9, LocalDateTime.parse("2024-03-19T16:14:05") + 2, 1, "Sergey Petrov", "Complex work, but I liked it", 9, Instant.parse("2024-03-19T16:14:05Z") ); List expected = List.of( @@ -53,7 +53,7 @@ public void crudTest() { Assertions.assertTrue(bookO.isPresent()); Review review3 = createReview( - 3, 1, "Madiyar Nurgazin", "Great", 8, LocalDateTime.parse("2024-03-19T20:00:00") + 3, 1, "Madiyar Nurgazin", "Great", 8, Instant.parse("2024-03-19T20:00:00Z") ); Book book = bookO.get(); @@ -97,7 +97,7 @@ public void crudTest() { List authors = authorRepository.findAuthorsByBookId(3); Assertions.assertEquals(Set.of(author1, author2), Set.copyOf(authors)); - Review review = createReview(4, 3, "Reader", "Text", 5, LocalDateTime.now()); + Review review = createReview(4, 3, "Reader", "Text", 5, Instant.now()); reviewRepository.save(review); bookRepository.deleteById(3L); @@ -115,15 +115,15 @@ public void crudTest() { @Test public void pagingAndSortingTest() { Review review1 = createReview( - 1, 1, "Ivan Ivanov", "Masterpiece!", 10, LocalDateTime.parse("2024-03-19T15:52:26") + 1, 1, "Ivan Ivanov", "Masterpiece!", 10, Instant.parse("2024-03-19T15:52:26Z") ); Review review2 = createReview( - 2, 1, "Sergey Petrov", "Complex work, but I liked it", 9, LocalDateTime.parse("2024-03-19T16:14:05") + 2, 1, "Sergey Petrov", "Complex work, but I liked it", 9, Instant.parse("2024-03-19T16:14:05Z") ); - Review review3 = createReview(3, 1, "Reader", "Text", 100, LocalDateTime.parse("2024-03-19T21:00:00")); - Review review4 = createReview(4, 1, "Reader", "Text2", 80, LocalDateTime.parse("2024-03-19T22:00:00")); - Review review5 = createReview(5, 1, "Reader", "Text3", 75, LocalDateTime.parse("2024-03-19T23:00:00")); - Review review6 = createReview(6, 1, "Reader", "Text4", 50, LocalDateTime.parse("2024-03-20T00:00:00")); + Review review3 = createReview(3, 1, "Reader", "Text", 100, Instant.parse("2024-03-19T21:00:00Z")); + Review review4 = createReview(4, 1, "Reader", "Text2", 80, Instant.parse("2024-03-19T22:00:00Z")); + Review review5 = createReview(5, 1, "Reader", "Text3", 75, Instant.parse("2024-03-19T23:00:00Z")); + Review review6 = createReview(6, 1, "Reader", "Text4", 50, Instant.parse("2024-03-20T00:00:00Z")); reviewRepository.saveAll(List.of(review3, review4, review5, review6)); Iterable reviews = reviewRepository.findByReader( @@ -149,7 +149,7 @@ public void pagingAndSortingTest() { Assertions.assertEquals(List.of(review5, review6), reviews); } - private Review createReview(long id, long bookId, String reader, String text, long rating, LocalDateTime created) { + private Review createReview(long id, long bookId, String reader, String text, long rating, Instant created) { Review review = new Review(); review.setId(id); review.setBookId(bookId); diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Review.java b/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Review.java index e0e04e5..deb4cbf 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Review.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/books/entity/Review.java @@ -1,7 +1,6 @@ package tech.ydb.data.books.entity; -import java.time.LocalDateTime; - +import java.time.Instant; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.data.annotation.Id; @@ -21,10 +20,10 @@ public class Review implements Persistable { private String reader; private String text; private long rating; - private LocalDateTime created; + private Instant created; public Review() { - this.created = LocalDateTime.now(); + this.created = Instant.now(); } @Transient diff --git a/spring-data-dialect/src/test/resources/changelogs/books.yaml b/spring-data-dialect/src/test/resources/changelogs/books.yaml index cc46a6d..b3fdfc2 100644 --- a/spring-data-dialect/src/test/resources/changelogs/books.yaml +++ b/spring-data-dialect/src/test/resources/changelogs/books.yaml @@ -155,7 +155,7 @@ databaseChangeLog: type: bigint - column: name: created - type: datetime + type: timestamp - column: name: book_id type: bigint From 45833fa57c88fadc59794efba5fb37c2bfa47a1a Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Mon, 26 Aug 2024 17:51:18 +0300 Subject: [PATCH 13/18] update --- .../tech/ydb/data/all_types_table/entity/AllTypesEntity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java index d413c72..f1caa6b 100644 --- a/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java +++ b/spring-data-dialect/src/test/java/tech/ydb/data/all_types_table/entity/AllTypesEntity.java @@ -29,7 +29,7 @@ public class AllTypesEntity implements Persistable { private double doubleColumn; private BigDecimal decimalColumn; private byte[] binaryColumn; -// @YdbType("Date") + @YdbType("Date") private LocalDate dateColumn; @YdbType("Datetime") private LocalDateTime datetimeColumn; From 2bdafeacfceea57f7569865df38002d004e39723 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Mon, 26 Aug 2024 18:34:07 +0300 Subject: [PATCH 14/18] update --- spring-data-dialect/pom.xml | 4 ++-- .../src/test/resources/application.properties | 1 + .../src/test/resources/changelogs/books.yaml | 8 ++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/spring-data-dialect/pom.xml b/spring-data-dialect/pom.xml index 51a5652..d4c3e3e 100644 --- a/spring-data-dialect/pom.xml +++ b/spring-data-dialect/pom.xml @@ -51,12 +51,12 @@ 5.10.2 1.18.30 - 3.3.3 + 3.2.1 4.24.0 2.2.9 2.2.3 - 0.9.7 + 1.1.0-SNAPSHOT diff --git a/spring-data-dialect/src/test/resources/application.properties b/spring-data-dialect/src/test/resources/application.properties index eb8335d..49bde0f 100644 --- a/spring-data-dialect/src/test/resources/application.properties +++ b/spring-data-dialect/src/test/resources/application.properties @@ -4,3 +4,4 @@ spring.datasource.url=jdbc:ydb:grpc://localhost:2136/local spring.liquibase.change-log=classpath:changelogs/changelog.yaml logging.level.org.springframework.jdbc.core.JdbcTemplate=debug +logging.level.liquibase=DEBUG diff --git a/spring-data-dialect/src/test/resources/changelogs/books.yaml b/spring-data-dialect/src/test/resources/changelogs/books.yaml index b3fdfc2..294028d 100644 --- a/spring-data-dialect/src/test/resources/changelogs/books.yaml +++ b/spring-data-dialect/src/test/resources/changelogs/books.yaml @@ -162,6 +162,10 @@ databaseChangeLog: - column: name: reader type: varchar + - changeSet: + id: "insert reviews" + author: "Kirill Kurdyukov" + changes: - insert: tableName: reviews columns: @@ -176,7 +180,7 @@ databaseChangeLog: valueNumeric: 10 - column: name: created - valueDate: "2024-03-19T18:52:26.123" + value: "2024-03-19T15:52:26Z" - column: name: book_id valueNumeric: 1 @@ -197,7 +201,7 @@ databaseChangeLog: valueNumeric: 9 - column: name: created - valueDate: "2024-03-19T19:14:05.456" + value: "2024-03-19T16:14:05Z" - column: name: book_id valueNumeric: 1 From 2b6320c646cbba8e00d5c1dbd7dc16a882524706 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Mon, 26 Aug 2024 18:36:25 +0300 Subject: [PATCH 15/18] update --- .../java/tech/ydb/liquibase/change/InsertDataChangeYdb.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/liquibase-dialect/src/main/java/tech/ydb/liquibase/change/InsertDataChangeYdb.java b/liquibase-dialect/src/main/java/tech/ydb/liquibase/change/InsertDataChangeYdb.java index 152fc43..9b4fd9f 100644 --- a/liquibase-dialect/src/main/java/tech/ydb/liquibase/change/InsertDataChangeYdb.java +++ b/liquibase-dialect/src/main/java/tech/ydb/liquibase/change/InsertDataChangeYdb.java @@ -40,8 +40,8 @@ public SqlStatement[] generateStatements(Database database) { while (resultSet.next()) { columnToLiquibaseDataType.put( resultSet.getString("COLUMN_NAME").toLowerCase(), - DataTypeFactory.getInstance() - .fromDescription(resultSet.getString("TYPE_NAME"), database)); + DataTypeFactory.getInstance().fromDescription( + resultSet.getString("TYPE_NAME"), database)); } StringBuilder yqlInsert = new StringBuilder() From e2972e23620f17f38d72ea832bb7d4e63283f010 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Mon, 26 Aug 2024 18:36:38 +0300 Subject: [PATCH 16/18] update --- spring-data-dialect/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-data-dialect/pom.xml b/spring-data-dialect/pom.xml index d4c3e3e..734124c 100644 --- a/spring-data-dialect/pom.xml +++ b/spring-data-dialect/pom.xml @@ -56,7 +56,7 @@ 2.2.9 2.2.3 - 1.1.0-SNAPSHOT + 0.9.7 From 95902f126c08a6c121d5c442c96808dd303d3529 Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Mon, 26 Aug 2024 18:37:18 +0300 Subject: [PATCH 17/18] update --- .../java/tech/ydb/liquibase/change/InsertDataChangeYdb.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/liquibase-dialect/src/main/java/tech/ydb/liquibase/change/InsertDataChangeYdb.java b/liquibase-dialect/src/main/java/tech/ydb/liquibase/change/InsertDataChangeYdb.java index 9b4fd9f..152fc43 100644 --- a/liquibase-dialect/src/main/java/tech/ydb/liquibase/change/InsertDataChangeYdb.java +++ b/liquibase-dialect/src/main/java/tech/ydb/liquibase/change/InsertDataChangeYdb.java @@ -40,8 +40,8 @@ public SqlStatement[] generateStatements(Database database) { while (resultSet.next()) { columnToLiquibaseDataType.put( resultSet.getString("COLUMN_NAME").toLowerCase(), - DataTypeFactory.getInstance().fromDescription( - resultSet.getString("TYPE_NAME"), database)); + DataTypeFactory.getInstance() + .fromDescription(resultSet.getString("TYPE_NAME"), database)); } StringBuilder yqlInsert = new StringBuilder() From b2307ccffc95a37377684a423371eba1b35ddb3a Mon Sep 17 00:00:00 2001 From: Kirill Kurdyukov Date: Tue, 27 Aug 2024 10:43:53 +0300 Subject: [PATCH 18/18] update --- .../src/test/resources/changelogs/books.yaml | 45 ++----------------- .../src/test/resources/changelogs/insert.sql | 3 ++ 2 files changed, 6 insertions(+), 42 deletions(-) create mode 100644 spring-data-dialect/src/test/resources/changelogs/insert.sql diff --git a/spring-data-dialect/src/test/resources/changelogs/books.yaml b/spring-data-dialect/src/test/resources/changelogs/books.yaml index 294028d..d3d524d 100644 --- a/spring-data-dialect/src/test/resources/changelogs/books.yaml +++ b/spring-data-dialect/src/test/resources/changelogs/books.yaml @@ -166,48 +166,9 @@ databaseChangeLog: id: "insert reviews" author: "Kirill Kurdyukov" changes: - - insert: - tableName: reviews - columns: - - column: - name: id - valueNumeric: 1 - - column: - name: text - value: "Masterpiece!" - - column: - name: rating - valueNumeric: 10 - - column: - name: created - value: "2024-03-19T15:52:26Z" - - column: - name: book_id - valueNumeric: 1 - - column: - name: reader - value: "Ivan Ivanov" - - insert: - tableName: reviews - columns: - - column: - name: id - valueNumeric: 2 - - column: - name: text - value: "Complex work, but I liked it" - - column: - name: rating - valueNumeric: 9 - - column: - name: created - value: "2024-03-19T16:14:05Z" - - column: - name: book_id - valueNumeric: 1 - - column: - name: reader - value: "Sergey Petrov" + - sqlFile: + relativeToChangelogFile: true + path: "insert.sql" rollback: - dropTable: tableName: reviews diff --git a/spring-data-dialect/src/test/resources/changelogs/insert.sql b/spring-data-dialect/src/test/resources/changelogs/insert.sql new file mode 100644 index 0000000..3a251e1 --- /dev/null +++ b/spring-data-dialect/src/test/resources/changelogs/insert.sql @@ -0,0 +1,3 @@ +INSERT INTO reviews (id, text, rating, created, book_id, reader) +VALUES (1, 'Masterpiece!', 10, TIMESTAMP('2024-03-19T15:52:26Z'), 1, 'Ivan Ivanov'), + (2, 'Complex work, but I liked it', 9, TIMESTAMP('2024-03-19T16:14:05Z'), 1, 'Sergey Petrov') \ No newline at end of file