diff --git a/README.md b/README.md index fb2dadd97..d4f4f6099 100644 --- a/README.md +++ b/README.md @@ -90,11 +90,11 @@ val books: List = queryFactory.listQuery { } ``` -### Update +### Update & Delete -Users can perform bulk update through update query. -* kotlin-jdsl's update does not require from clause. Type T given as generic handles from automatically. -* According to the JPA specification, update does not support join, fetch, group by, order by, limit. +Users can perform bulk update/delete through update/delete query. +* kotlin-jdsl's update/delete does not require from clause. Type T given as generic handles from automatically. +* According to the JPA specification, update/delete does not support join, fetch, group by, order by, limit. * If you want to use an association mapping as a where condition, you must use [associate](#associate). ```kotlin @@ -103,9 +103,16 @@ val query: Query = queryFactory.updateQuery { setParams(col(Order::purchaserId) to 3000) } -val udpatedRowsCount: Int = query.executeUpdate() +val updatedRowsCount: Int = query.executeUpdate() + +val deleteQuery: Query = queryFactory.deleteQuery { + where(col(Order::purchaserId).`in`(1000, 2000)) +} + +val deletedRowsCount: Int = deleteQuery.executeUpdate() ``` + ### Expression Kotlin JDSL supports various expressions. @@ -226,12 +233,17 @@ val query = queryFactory.selectQuery { associate(OrderAddress::class, Address::class, on(OrderAddress::address)) } -queryFactory.updateQuery { +val updatedRowCount = queryFactory.updateQuery { where(col(OrderAddress::id).equal(address1.id)) associate(OrderAddress::class, Address::class, on(OrderAddress::address)) set(col(Address::zipCode), "test") set(col(Address::baseAddress), "base") }.executeUpdate() + +val deletedRowCount = queryFactory.deleteQuery { + where(col(OrderAddress::id).equal(address1.id)) + associate(OrderAddress::class, Address::class, on(OrderAddress::address)) +}.executeUpdate() ``` diff --git a/core/src/main/kotlin/com/linecorp/kotlinjdsl/QueryFactory.kt b/core/src/main/kotlin/com/linecorp/kotlinjdsl/QueryFactory.kt index 0bc1ef530..25587d1b9 100644 --- a/core/src/main/kotlin/com/linecorp/kotlinjdsl/QueryFactory.kt +++ b/core/src/main/kotlin/com/linecorp/kotlinjdsl/QueryFactory.kt @@ -1,6 +1,7 @@ package com.linecorp.kotlinjdsl import com.linecorp.kotlinjdsl.query.spec.expression.SubqueryExpressionSpec +import com.linecorp.kotlinjdsl.querydsl.CriteriaDeleteQueryDsl import com.linecorp.kotlinjdsl.querydsl.CriteriaQueryDsl import com.linecorp.kotlinjdsl.querydsl.SubqueryDsl import com.linecorp.kotlinjdsl.querydsl.CriteriaUpdateQueryDsl @@ -13,5 +14,6 @@ interface QueryFactory { fun typedQuery(returnType: Class, dsl: CriteriaQueryDsl.() -> Unit) = selectQuery(returnType, dsl) fun selectQuery(returnType: Class, dsl: CriteriaQueryDsl.() -> Unit): TypedQuery fun updateQuery(target: KClass, dsl: CriteriaUpdateQueryDsl.() -> Unit): Query + fun deleteQuery(target: KClass, dsl: CriteriaDeleteQueryDsl.() -> Unit): Query fun subquery(returnType: Class, dsl: SubqueryDsl.() -> Unit): SubqueryExpressionSpec } diff --git a/core/src/main/kotlin/com/linecorp/kotlinjdsl/QueryFactoryExtensions.kt b/core/src/main/kotlin/com/linecorp/kotlinjdsl/QueryFactoryExtensions.kt index d57408168..e0d47319b 100644 --- a/core/src/main/kotlin/com/linecorp/kotlinjdsl/QueryFactoryExtensions.kt +++ b/core/src/main/kotlin/com/linecorp/kotlinjdsl/QueryFactoryExtensions.kt @@ -1,5 +1,6 @@ package com.linecorp.kotlinjdsl +import com.linecorp.kotlinjdsl.querydsl.CriteriaDeleteQueryDsl import com.linecorp.kotlinjdsl.querydsl.CriteriaQueryDsl import com.linecorp.kotlinjdsl.querydsl.CriteriaUpdateQueryDsl import com.linecorp.kotlinjdsl.querydsl.SubqueryDsl @@ -27,5 +28,8 @@ inline fun QueryFactory.selectQuery(noinline dsl: CriteriaQueryDsl QueryFactory.updateQuery(noinline dsl: CriteriaUpdateQueryDsl.() -> Unit) = updateQuery(T::class, dsl) +inline fun QueryFactory.deleteQuery(noinline dsl: CriteriaDeleteQueryDsl.() -> Unit) = + deleteQuery(T::class, dsl) + inline fun QueryFactory.subquery(noinline dsl: SubqueryDsl.() -> Unit) = subquery(T::class.java, dsl) diff --git a/core/src/main/kotlin/com/linecorp/kotlinjdsl/QueryFactoryImpl.kt b/core/src/main/kotlin/com/linecorp/kotlinjdsl/QueryFactoryImpl.kt index a2759e890..8ba9885a7 100644 --- a/core/src/main/kotlin/com/linecorp/kotlinjdsl/QueryFactoryImpl.kt +++ b/core/src/main/kotlin/com/linecorp/kotlinjdsl/QueryFactoryImpl.kt @@ -3,10 +3,7 @@ package com.linecorp.kotlinjdsl import com.linecorp.kotlinjdsl.query.creator.CriteriaQueryCreator import com.linecorp.kotlinjdsl.query.creator.SubqueryCreator import com.linecorp.kotlinjdsl.query.spec.expression.SubqueryExpressionSpec -import com.linecorp.kotlinjdsl.querydsl.CriteriaQueryDsl -import com.linecorp.kotlinjdsl.querydsl.QueryDslImpl -import com.linecorp.kotlinjdsl.querydsl.SubqueryDsl -import com.linecorp.kotlinjdsl.querydsl.CriteriaUpdateQueryDsl +import com.linecorp.kotlinjdsl.querydsl.* import javax.persistence.Query import javax.persistence.TypedQuery import kotlin.reflect.KClass @@ -30,6 +27,12 @@ class QueryFactoryImpl( ) } + override fun deleteQuery(target: KClass, dsl: CriteriaDeleteQueryDsl.() -> Unit): Query { + return criteriaQueryCreator.createQuery( + QueryDslImpl(target.java).apply(dsl).apply { from(target) }.createCriteriaDeleteQuerySpec() + ) + } + override fun subquery( returnType: Class, dsl: SubqueryDsl.() -> Unit diff --git a/core/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/CriteriaQueryCreator.kt b/core/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/CriteriaQueryCreator.kt index 053afac72..8548b17db 100644 --- a/core/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/CriteriaQueryCreator.kt +++ b/core/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/CriteriaQueryCreator.kt @@ -1,5 +1,6 @@ package com.linecorp.kotlinjdsl.query.creator +import com.linecorp.kotlinjdsl.query.CriteriaDeleteQuerySpec import com.linecorp.kotlinjdsl.query.CriteriaQuerySpec import com.linecorp.kotlinjdsl.query.CriteriaUpdateQuerySpec import javax.persistence.Query @@ -8,4 +9,5 @@ import javax.persistence.TypedQuery interface CriteriaQueryCreator { fun createQuery(spec: CriteriaQuerySpec): TypedQuery fun createQuery(spec: CriteriaUpdateQuerySpec): Query + fun createQuery(spec: CriteriaDeleteQuerySpec): Query } diff --git a/core/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/CriteriaQueryCreatorImpl.kt b/core/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/CriteriaQueryCreatorImpl.kt index ea116156e..2e7dd85f6 100644 --- a/core/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/CriteriaQueryCreatorImpl.kt +++ b/core/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/CriteriaQueryCreatorImpl.kt @@ -1,10 +1,12 @@ package com.linecorp.kotlinjdsl.query.creator +import com.linecorp.kotlinjdsl.query.CriteriaDeleteQuerySpec import com.linecorp.kotlinjdsl.query.CriteriaQuerySpec import com.linecorp.kotlinjdsl.query.CriteriaUpdateQuerySpec import javax.persistence.EntityManager import javax.persistence.Query import javax.persistence.TypedQuery +import javax.persistence.criteria.CriteriaDelete import javax.persistence.criteria.CriteriaUpdate class CriteriaQueryCreatorImpl( @@ -43,4 +45,17 @@ class CriteriaQueryCreatorImpl( } } + @Suppress("UNCHECKED_CAST") + override fun createQuery(spec: CriteriaDeleteQuerySpec): Query { + val criteriaBuilder = em.criteriaBuilder + val query = criteriaBuilder.createCriteriaDelete(spec.targetEntity) as CriteriaDelete + val froms = spec.from.associate(spec.associate, query, spec.targetEntity) + + spec.where.apply(froms, query, criteriaBuilder) + + return em.createQuery(query).apply { + spec.jpaHint.apply(this) + spec.sqlHint.apply(this) + } + } } diff --git a/core/src/test/kotlin/com/linecorp/kotlinjdsl/QueryFactoryExtensionsTest.kt b/core/src/test/kotlin/com/linecorp/kotlinjdsl/QueryFactoryExtensionsTest.kt index b48838b2a..a2b7d0e46 100644 --- a/core/src/test/kotlin/com/linecorp/kotlinjdsl/QueryFactoryExtensionsTest.kt +++ b/core/src/test/kotlin/com/linecorp/kotlinjdsl/QueryFactoryExtensionsTest.kt @@ -1,8 +1,11 @@ package com.linecorp.kotlinjdsl import com.linecorp.kotlinjdsl.query.spec.expression.SubqueryExpressionSpec +import com.linecorp.kotlinjdsl.querydsl.CriteriaDeleteQueryDsl import com.linecorp.kotlinjdsl.querydsl.CriteriaQueryDsl +import com.linecorp.kotlinjdsl.querydsl.CriteriaUpdateQueryDsl import com.linecorp.kotlinjdsl.querydsl.SubqueryDsl +import com.linecorp.kotlinjdsl.querydsl.expression.col import com.linecorp.kotlinjdsl.test.WithKotlinJdslAssertions import io.mockk.confirmVerified import io.mockk.every @@ -12,6 +15,7 @@ import io.mockk.verify import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import java.util.stream.Stream +import javax.persistence.Query import javax.persistence.TypedQuery @ExtendWith(MockKExtension::class) @@ -125,6 +129,52 @@ internal class QueryFactoryExtensionsTest : WithKotlinJdslAssertions { confirmVerified(queryFactory) } + @Test + fun updateQuery() { + // given + every { queryFactory.updateQuery(any(), any()) } returns typedQuery + + val dsl: CriteriaUpdateQueryDsl.() -> Unit = { + set(col(Data1::id), 1) + where(col(Data1::id).equal(2)) + } + + // when + val actual: Query = queryFactory.updateQuery(dsl) + + // then + assertThat(actual).isEqualTo(typedQuery) + + verify(exactly = 1) { + queryFactory.updateQuery(Data1::class, dsl) + } + + confirmVerified(queryFactory) + } + + @Test + fun deleteQuery() { + // given + every { queryFactory.deleteQuery(any(), any()) } returns typedQuery + + val dsl: CriteriaDeleteQueryDsl.() -> Unit = { + where(col(Data1::id).equal(1)) + } + + // when + val actual: Query = queryFactory.deleteQuery(dsl) + + // then + assertThat(actual).isEqualTo(typedQuery) + + verify(exactly = 1) { + queryFactory.deleteQuery(Data1::class, dsl) + } + + confirmVerified(queryFactory) + } + + @Test fun subquery() { // given diff --git a/core/src/test/kotlin/com/linecorp/kotlinjdsl/QueryFactoryImplTest.kt b/core/src/test/kotlin/com/linecorp/kotlinjdsl/QueryFactoryImplTest.kt index 540283e68..8629b0b34 100644 --- a/core/src/test/kotlin/com/linecorp/kotlinjdsl/QueryFactoryImplTest.kt +++ b/core/src/test/kotlin/com/linecorp/kotlinjdsl/QueryFactoryImplTest.kt @@ -125,6 +125,38 @@ internal class QueryFactoryImplTest : WithKotlinJdslAssertions { confirmVerified(criteriaQueryCreator) } + @Test + fun deleteQuery() { + // given + val query: Query = mockk() + + every { criteriaQueryCreator.createQuery(any>()) } returns query + + // when + val actual = sut.deleteQuery(Data1::class) { + where(col(Data1::id).equal(1)) + } + + // then + assertThat(actual).isEqualTo(query) + + verify(exactly = 1) { + val columnSpec = ColumnSpec(EntitySpec(Data1::class.java), Data1::id.name) + criteriaQueryCreator.createQuery( + QueryDslImpl.CriteriaDeleteQuerySpecImpl( + from = FromClause(EntitySpec(Data1::class.java)), + associate = SimpleAssociatedJoinClause(emptyList()), + where = WhereClause(EqualValueSpec(columnSpec, 1)), + jpaHint = JpaQueryHintClauseImpl(emptyMap()), + sqlHint = EmptySqlQueryHintClause, + targetEntity = Data1::class.java + ) + ) + } + + confirmVerified(criteriaQueryCreator) + } + @Test fun subquery() { // when diff --git a/core/src/test/kotlin/com/linecorp/kotlinjdsl/query/creator/CriteriaQueryCreatorImplTest.kt b/core/src/test/kotlin/com/linecorp/kotlinjdsl/query/creator/CriteriaQueryCreatorImplTest.kt index 07ee98ee0..8d8d1c884 100644 --- a/core/src/test/kotlin/com/linecorp/kotlinjdsl/query/creator/CriteriaQueryCreatorImplTest.kt +++ b/core/src/test/kotlin/com/linecorp/kotlinjdsl/query/creator/CriteriaQueryCreatorImplTest.kt @@ -1,5 +1,6 @@ package com.linecorp.kotlinjdsl.query.creator +import com.linecorp.kotlinjdsl.query.CriteriaDeleteQuerySpec import com.linecorp.kotlinjdsl.query.CriteriaQuerySpec import com.linecorp.kotlinjdsl.query.CriteriaUpdateQuerySpec import com.linecorp.kotlinjdsl.query.clause.from.FromClause @@ -25,11 +26,9 @@ import org.junit.jupiter.api.extension.ExtendWith import javax.persistence.EntityManager import javax.persistence.Query import javax.persistence.TypedQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaQuery -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Path +import javax.persistence.criteria.* +@Suppress("UnusedEquals") @ExtendWith(MockKExtension::class) internal class CriteriaQueryCreatorImplTest : WithKotlinJdslAssertions { @InjectMockKs @@ -200,4 +199,67 @@ internal class CriteriaQueryCreatorImplTest : WithKotlinJdslAssertions { em, froms, criteriaBuilder ) } + + @Suppress("UNCHECKED_CAST") + @Test + fun createDeleteQuery() { + data class TestCriteriaDeleteQuerySpec( + override val targetEntity: Class, + override val from: FromClause, + override val associate: SimpleAssociatedJoinClause, + override val where: CriteriaQueryWhereClause, + override val jpaHint: JpaQueryHintClause, + override val sqlHint: SqlQueryHintClause, + ) : CriteriaDeleteQuerySpec + // given + val createdQuery: CriteriaDelete = mockk() + val query: Query = mockk() + + val from: FromClause = mockk() + val associate = SimpleAssociatedJoinClause(emptyList()) + val where: CriteriaQueryWhereClause = mockk() + val jpaHint: JpaQueryHintClause = mockk() + val sqlHint: SqlQueryHintClause = mockk() + val set: SetClause = mockk() + + val spec: CriteriaDeleteQuerySpec = TestCriteriaDeleteQuerySpec( + from = from, + associate = associate, + where = where, + jpaHint = jpaHint, + sqlHint = sqlHint, + targetEntity = Int::class.java + ) + + every { em.criteriaBuilder } returns criteriaBuilder + every { em.createQuery(createdQuery) } returns query + every { criteriaBuilder.createCriteriaDelete(Int::class.java) } returns createdQuery + every { from.associate(associate, createdQuery as CriteriaDelete, Int::class.java) } returns froms + every { where.apply(froms, createdQuery, criteriaBuilder) } just runs + every { jpaHint.apply(query) } just runs + every { sqlHint.apply(query) } just runs + + // when + val actual = sut.createQuery(spec) + + // then + assertThat(actual).isEqualTo(query) + + verify(exactly = 1) { + em.criteriaBuilder + em.createQuery(createdQuery) + criteriaBuilder.createCriteriaDelete(Int::class.java) + from.associate(associate, createdQuery as CriteriaDelete, Int::class.java) + where.apply(froms, createdQuery, criteriaBuilder) + jpaHint.apply(query) + sqlHint.apply(query) + query == query + } + + confirmVerified( + from, where, jpaHint, sqlHint, set, + createdQuery, query, + em, froms, criteriaBuilder + ) + } } diff --git a/eclipselink/src/test/kotlin/com/linecorp/kotlinjdsl/eclipselink/integration/criteriaquery/EclipselinkCriteriaDeleteIntegrationTest.kt b/eclipselink/src/test/kotlin/com/linecorp/kotlinjdsl/eclipselink/integration/criteriaquery/EclipselinkCriteriaDeleteIntegrationTest.kt new file mode 100644 index 000000000..76bc3ee81 --- /dev/null +++ b/eclipselink/src/test/kotlin/com/linecorp/kotlinjdsl/eclipselink/integration/criteriaquery/EclipselinkCriteriaDeleteIntegrationTest.kt @@ -0,0 +1,11 @@ +package com.linecorp.kotlinjdsl.eclipselink.integration.criteriaquery + +import com.linecorp.kotlinjdsl.test.integration.EntityManagerExtension +import com.linecorp.kotlinjdsl.test.integration.criteriaquery.AbstractCriteriaDeleteIntegrationTest +import org.junit.jupiter.api.extension.ExtendWith +import javax.persistence.EntityManager + +@ExtendWith(EntityManagerExtension::class) +class EclipselinkCriteriaDeleteIntegrationTest : AbstractCriteriaDeleteIntegrationTest() { + override lateinit var entityManager: EntityManager +} diff --git a/hibernate/src/test/kotlin/com/linecorp/kotlinjdsl/hibernate/criteriaquery/HibernateCriteriaDeleteIntegrationTest.kt b/hibernate/src/test/kotlin/com/linecorp/kotlinjdsl/hibernate/criteriaquery/HibernateCriteriaDeleteIntegrationTest.kt new file mode 100644 index 000000000..275fa1f1a --- /dev/null +++ b/hibernate/src/test/kotlin/com/linecorp/kotlinjdsl/hibernate/criteriaquery/HibernateCriteriaDeleteIntegrationTest.kt @@ -0,0 +1,11 @@ +package com.linecorp.kotlinjdsl.hibernate.criteriaquery + +import com.linecorp.kotlinjdsl.test.integration.EntityManagerExtension +import com.linecorp.kotlinjdsl.test.integration.criteriaquery.AbstractCriteriaDeleteIntegrationTest +import org.junit.jupiter.api.extension.ExtendWith +import javax.persistence.EntityManager + +@ExtendWith(EntityManagerExtension::class) +class HibernateCriteriaDeleteIntegrationTest : AbstractCriteriaDeleteIntegrationTest() { + override lateinit var entityManager: EntityManager +} diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/CriteriaDeleteQuerySpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/CriteriaDeleteQuerySpec.kt new file mode 100644 index 000000000..f00606ea1 --- /dev/null +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/CriteriaDeleteQuerySpec.kt @@ -0,0 +1,16 @@ +package com.linecorp.kotlinjdsl.query + +import com.linecorp.kotlinjdsl.query.clause.from.FromClause +import com.linecorp.kotlinjdsl.query.clause.from.SimpleAssociatedJoinClause +import com.linecorp.kotlinjdsl.query.clause.hint.JpaQueryHintClause +import com.linecorp.kotlinjdsl.query.clause.hint.SqlQueryHintClause +import com.linecorp.kotlinjdsl.query.clause.where.CriteriaQueryWhereClause + +interface CriteriaDeleteQuerySpec { + val targetEntity: Class + val from: FromClause + val associate: SimpleAssociatedJoinClause + val where: CriteriaQueryWhereClause + val jpaHint: JpaQueryHintClause + val sqlHint: SqlQueryHintClause +} diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/from/FromClause.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/from/FromClause.kt index b83b3a324..d22b4f851 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/from/FromClause.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/from/FromClause.kt @@ -3,6 +3,7 @@ package com.linecorp.kotlinjdsl.query.clause.from import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.query.spec.expression.EntitySpec import javax.persistence.criteria.AbstractQuery +import javax.persistence.criteria.CriteriaDelete import javax.persistence.criteria.CriteriaUpdate data class FromClause( @@ -15,4 +16,8 @@ data class FromClause( fun associate(joinClause: SimpleAssociatedJoinClause, query: CriteriaUpdate, targetEntity: Class<*>): Froms { return SimpleAssociator(entity, joinClause.joins, query.from(targetEntity)).associateAll() } + + fun associate(joinClause: SimpleAssociatedJoinClause, query: CriteriaDelete, targetEntity: Class<*>): Froms { + return SimpleAssociator(entity, joinClause.joins, query.from(targetEntity)).associateAll() + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/from/SimpleAssociator.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/from/SimpleAssociator.kt index 0c5bc246e..f0669c2b6 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/from/SimpleAssociator.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/from/SimpleAssociator.kt @@ -20,7 +20,6 @@ class SimpleAssociator( associates.asSequence() .filter { !realized.contains(it.entity) } .forEach { - it as SimpleAssociatedJoinSpec<*, *> if (!realized.contains(it.left)) { realizeLazy(it) } else { diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/where/CriteriaQueryWhereClause.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/where/CriteriaQueryWhereClause.kt index 8e8a1e0bd..2c9e80e42 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/where/CriteriaQueryWhereClause.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/where/CriteriaQueryWhereClause.kt @@ -2,10 +2,12 @@ package com.linecorp.kotlinjdsl.query.clause.where import com.linecorp.kotlinjdsl.query.spec.Froms import javax.persistence.criteria.CriteriaBuilder +import javax.persistence.criteria.CriteriaDelete import javax.persistence.criteria.CriteriaQuery import javax.persistence.criteria.CriteriaUpdate interface CriteriaQueryWhereClause { fun apply(froms: Froms, query: CriteriaQuery<*>, criteriaBuilder: CriteriaBuilder) fun apply(froms: Froms, query: CriteriaUpdate<*>, criteriaBuilder: CriteriaBuilder) + fun apply(froms: Froms, query: CriteriaDelete<*>, criteriaBuilder: CriteriaBuilder) } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/where/WhereClause.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/where/WhereClause.kt index 18f232fcd..d8f8823ba 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/where/WhereClause.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/clause/where/WhereClause.kt @@ -17,6 +17,12 @@ data class WhereClause( query.where(predicate.toCriteriaPredicate(froms, query, criteriaBuilder)) } + override fun apply(froms: Froms, query: CriteriaDelete<*>, criteriaBuilder: CriteriaBuilder) { + if (predicate.isEmpty()) return + + query.where(predicate.toCriteriaPredicate(froms, query, criteriaBuilder)) + } + override fun apply(froms: Froms, query: Subquery<*>, criteriaBuilder: CriteriaBuilder) { applyInternally(froms, query, criteriaBuilder) } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/SubqueryCreator.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/SubqueryCreator.kt index 2616515d3..a60326b2e 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/SubqueryCreator.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/SubqueryCreator.kt @@ -2,30 +2,15 @@ package com.linecorp.kotlinjdsl.query.creator import com.linecorp.kotlinjdsl.query.SubquerySpec import com.linecorp.kotlinjdsl.query.spec.Froms +import javax.persistence.criteria.CommonAbstractCriteria import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaQuery -import javax.persistence.criteria.CriteriaUpdate import javax.persistence.criteria.Subquery interface SubqueryCreator { fun createQuery( spec: SubquerySpec, froms: Froms, - criteriaQuery: CriteriaQuery<*>, - criteriaBuilder: CriteriaBuilder - ): Subquery - - fun createQuery( - spec: SubquerySpec, - froms: Froms, - criteriaQuery: CriteriaUpdate<*>, - criteriaBuilder: CriteriaBuilder - ): Subquery - - fun createQuery( - spec: SubquerySpec, - froms: Froms, - subquery: Subquery<*>, + criteria: CommonAbstractCriteria, criteriaBuilder: CriteriaBuilder ): Subquery } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/SubqueryCreatorImpl.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/SubqueryCreatorImpl.kt index db05ced7c..520d4218d 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/SubqueryCreatorImpl.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/creator/SubqueryCreatorImpl.kt @@ -2,58 +2,23 @@ package com.linecorp.kotlinjdsl.query.creator import com.linecorp.kotlinjdsl.query.SubquerySpec import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaQuery -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Subquery +import javax.persistence.criteria.* class SubqueryCreatorImpl : SubqueryCreator { override fun createQuery( spec: SubquerySpec, froms: Froms, - criteriaQuery: CriteriaQuery<*>, + criteria: CommonAbstractCriteria, criteriaBuilder: CriteriaBuilder ): Subquery { - val query = criteriaQuery.subquery(spec.select.returnType) + val subquery = criteria.subquery(spec.select.returnType) + val subqueryFroms = spec.from.join(spec.join, subquery) + froms - return apply(spec, froms, query, criteriaBuilder) - } - - override fun createQuery( - spec: SubquerySpec, - froms: Froms, - criteriaQuery: CriteriaUpdate<*>, - criteriaBuilder: CriteriaBuilder - ): Subquery { - val query = criteriaQuery.subquery(spec.select.returnType) - - return apply(spec, froms, query, criteriaBuilder) - } - - override fun createQuery( - spec: SubquerySpec, - froms: Froms, - subquery: Subquery<*>, - criteriaBuilder: CriteriaBuilder - ): Subquery { - val query = subquery.subquery(spec.select.returnType) - - return apply(spec, froms, query, criteriaBuilder) - } - - private fun apply( - spec: SubquerySpec, - froms: Froms, - query: Subquery, - criteriaBuilder: CriteriaBuilder - ): Subquery { - val subqueryFroms = spec.from.join(spec.join, query) + froms - - spec.select.apply(subqueryFroms, query, criteriaBuilder) - spec.where.apply(subqueryFroms, query, criteriaBuilder) - spec.groupBy.apply(subqueryFroms, query, criteriaBuilder) - spec.having.apply(subqueryFroms, query, criteriaBuilder) + spec.select.apply(subqueryFroms, subquery, criteriaBuilder) + spec.where.apply(subqueryFroms, subquery, criteriaBuilder) + spec.groupBy.apply(subqueryFroms, subquery, criteriaBuilder) + spec.having.apply(subqueryFroms, subquery, criteriaBuilder) - return query + return subquery } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/AvgSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/AvgSpec.kt index 197875153..c812776e4 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/AvgSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/AvgSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.expression import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* data class AvgSpec( val column: ColumnSpec @@ -28,4 +25,14 @@ data class AvgSpec( return criteriaBuilder.avg(expression) } + + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression { + val expression = column.toCriteriaExpression(froms, query, criteriaBuilder) + + return criteriaBuilder.avg(expression) + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CaseSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CaseSpec.kt index 3e2bb8269..977c7fe8a 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CaseSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CaseSpec.kt @@ -2,10 +2,7 @@ package com.linecorp.kotlinjdsl.query.spec.expression import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.query.spec.predicate.PredicateSpec -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* data class CaseSpec( val whens: List>, @@ -41,6 +38,21 @@ data class CaseSpec( }.otherwise(`else`.toCriteriaExpression(froms, query, criteriaBuilder)) } + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression { + return criteriaBuilder.selectCase().apply { + whens.forEach { + `when`( + it.predicate.toCriteriaPredicate(froms, query, criteriaBuilder), + it.result.toCriteriaExpression(froms, query, criteriaBuilder), + ) + } + }.otherwise(`else`.toCriteriaExpression(froms, query, criteriaBuilder)) + } + data class WhenSpec( val predicate: PredicateSpec, val result: ExpressionSpec, diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/ColumnSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/ColumnSpec.kt index 9b4c0f752..3e5f8e0f5 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/ColumnSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/ColumnSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.expression import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* data class ColumnSpec( val entity: EntitySpec<*>, @@ -15,7 +12,7 @@ data class ColumnSpec( query: AbstractQuery<*>, criteriaBuilder: CriteriaBuilder ): Expression { - return froms[entity].get(path) + return path(froms) } override fun toCriteriaExpression( @@ -23,6 +20,17 @@ data class ColumnSpec( query: CriteriaUpdate<*>, criteriaBuilder: CriteriaBuilder ): Expression { - return froms[entity].get(path) + return path(froms) } + + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression { + return path(froms) + } + + private fun path(froms: Froms): Path = + froms[entity].get(path) } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CountSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CountSpec.kt index ea1574c57..abc0e7cb7 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CountSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CountSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.expression import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* data class CountSpec( val distinct: Boolean = false, @@ -30,6 +27,16 @@ data class CountSpec( return toCriteriaExpression(criteriaBuilder, jpaExpression) } + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression { + val jpaExpression = column.toCriteriaExpression(froms, query, criteriaBuilder) + + return toCriteriaExpression(criteriaBuilder, jpaExpression) + } + private fun toCriteriaExpression( criteriaBuilder: CriteriaBuilder, jpaExpression: Expression diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/EntitySpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/EntitySpec.kt index 5d33c4edd..74ce7e88f 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/EntitySpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/EntitySpec.kt @@ -14,13 +14,21 @@ data class EntitySpec( froms: Froms, query: AbstractQuery<*>, criteriaBuilder: CriteriaBuilder - ): Expression = froms[this].apply { applyAlias() } + ): Expression = path(froms) override fun toCriteriaExpression( froms: Froms, query: CriteriaUpdate<*>, criteriaBuilder: CriteriaBuilder - ): Expression = froms[this].apply { applyAlias() } + ): Expression = path(froms) + + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression = path(froms) + + private fun path(froms: Froms) = froms[this].apply { applyAlias() } private fun Path.applyAlias() { this@EntitySpec.alias.takeIf { !it.startsWith(DEFAULT_ALIAS_TOKEN) }?.run { alias(this) } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/ExpressionSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/ExpressionSpec.kt index 9d6a5e19f..92ec84c0b 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/ExpressionSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/ExpressionSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.expression import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* interface ExpressionSpec { fun toCriteriaExpression( @@ -18,4 +15,10 @@ interface ExpressionSpec { query: CriteriaUpdate<*>, criteriaBuilder: CriteriaBuilder ): Expression + + fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/FunctionSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/FunctionSpec.kt index 05ea6a527..a52a40c4e 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/FunctionSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/FunctionSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.expression import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* data class FunctionSpec( val name: String, @@ -18,7 +15,7 @@ data class FunctionSpec( ): Expression { return toCriteriaExpression( criteriaBuilder = criteriaBuilder, - expressions = expressions.map { it.toCriteriaExpression(froms, query, criteriaBuilder) }.toTypedArray() + expressions = expressions.map { it.toCriteriaExpression(froms, query, criteriaBuilder) } ) } @@ -29,18 +26,29 @@ data class FunctionSpec( ): Expression { return toCriteriaExpression( criteriaBuilder = criteriaBuilder, - expressions = expressions.map { it.toCriteriaExpression(froms, query, criteriaBuilder) }.toTypedArray() + expressions = expressions.map { it.toCriteriaExpression(froms, query, criteriaBuilder) } + ) + } + + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression { + return toCriteriaExpression( + criteriaBuilder = criteriaBuilder, + expressions = expressions.map { it.toCriteriaExpression(froms, query, criteriaBuilder) } ) } private fun toCriteriaExpression( criteriaBuilder: CriteriaBuilder, - expressions: Array> + expressions: List> ): Expression { return criteriaBuilder.function( name, returnType, - *expressions + *expressions.toTypedArray() ) } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/GreatestSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/GreatestSpec.kt index 84970f3ec..e7ea11308 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/GreatestSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/GreatestSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.expression import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* data class GreatestSpec?>( val column: ColumnSpec @@ -28,4 +25,14 @@ data class GreatestSpec?>( return criteriaBuilder.greatest(expression) } + + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression { + val expression = column.toCriteriaExpression(froms, query, criteriaBuilder) + + return criteriaBuilder.greatest(expression) + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LeastSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LeastSpec.kt index a871ffd2c..7a33261e5 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LeastSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LeastSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.expression import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* data class LeastSpec?>( val column: ColumnSpec @@ -28,4 +25,14 @@ data class LeastSpec?>( return criteriaBuilder.least(expression) } + + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression { + val expression = column.toCriteriaExpression(froms, query, criteriaBuilder) + + return criteriaBuilder.least(expression) + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LiteralSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LiteralSpec.kt index ad16cc76e..f1a34b107 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LiteralSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LiteralSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.expression import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* data class LiteralSpec( val value: T, @@ -20,4 +17,10 @@ data class LiteralSpec( query: CriteriaUpdate<*>, criteriaBuilder: CriteriaBuilder ): Expression = criteriaBuilder.literal(value) + + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression = criteriaBuilder.literal(value) } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MaxSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MaxSpec.kt index de283c6b2..87f244078 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MaxSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MaxSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.expression import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* data class MaxSpec( val column: ColumnSpec @@ -28,4 +25,14 @@ data class MaxSpec( return criteriaBuilder.max(expression) } + + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression { + val expression = column.toCriteriaExpression(froms, query, criteriaBuilder) + + return criteriaBuilder.max(expression) + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MinSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MinSpec.kt index cbc477747..2f445247c 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MinSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MinSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.expression import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* data class MinSpec( val column: ColumnSpec @@ -28,4 +25,14 @@ data class MinSpec( return criteriaBuilder.min(expression) } + + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression { + val expression = column.toCriteriaExpression(froms, query, criteriaBuilder) + + return criteriaBuilder.min(expression) + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/NullLiteralSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/NullLiteralSpec.kt index 239d0383a..6f655b49d 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/NullLiteralSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/NullLiteralSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.expression import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* data class NullLiteralSpec( val type: Class, @@ -20,4 +17,10 @@ data class NullLiteralSpec( query: CriteriaUpdate<*>, criteriaBuilder: CriteriaBuilder ): Expression = criteriaBuilder.nullLiteral(type) + + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression = criteriaBuilder.nullLiteral(type) } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SubqueryExpressionSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SubqueryExpressionSpec.kt index 12a96c67e..76f99b736 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SubqueryExpressionSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SubqueryExpressionSpec.kt @@ -14,11 +14,7 @@ data class SubqueryExpressionSpec( query: AbstractQuery<*>, criteriaBuilder: CriteriaBuilder ): Expression { - return when (query) { - is CriteriaQuery -> subqueryCreator.createQuery(spec, froms, query, criteriaBuilder) - is Subquery -> subqueryCreator.createQuery(spec, froms, query, criteriaBuilder) - else -> throw IllegalStateException("${query::class.qualifiedName} could not create Subquery") - } + return subqueryCreator.createQuery(spec, froms, query, criteriaBuilder) } override fun toCriteriaExpression( @@ -28,4 +24,12 @@ data class SubqueryExpressionSpec( ): Expression { return subqueryCreator.createQuery(spec, froms, query, criteriaBuilder) } + + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression { + return subqueryCreator.createQuery(spec, froms, query, criteriaBuilder) + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SumSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SumSpec.kt index 94f6192d1..3bc660810 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SumSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SumSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.expression import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* data class SumSpec( val column: ColumnSpec @@ -28,4 +25,14 @@ data class SumSpec( return criteriaBuilder.sum(expression) } + + override fun toCriteriaExpression( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Expression { + val expression = column.toCriteriaExpression(froms, query, criteriaBuilder) + + return criteriaBuilder.sum(expression) + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/AndSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/AndSpec.kt index 97a9d4845..65c101e66 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/AndSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/AndSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.predicate import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* data class AndSpec( val predicates: List, @@ -25,7 +22,15 @@ data class AndSpec( return toCriteriaPredicate(criteriaBuilder) { it.toCriteriaPredicate(froms, query, criteriaBuilder) } } - fun toCriteriaPredicate(criteriaBuilder: CriteriaBuilder, predicate: (PredicateSpec) -> Predicate): Predicate { + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + return toCriteriaPredicate(criteriaBuilder) { it.toCriteriaPredicate(froms, query, criteriaBuilder) } + } + + private fun toCriteriaPredicate(criteriaBuilder: CriteriaBuilder, predicate: (PredicateSpec) -> Predicate): Predicate { return predicates.asSequence() .filterNotNull() .map { predicate(it) } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenExpressionSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenExpressionSpec.kt index 31eccd910..6d4e2a8e6 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenExpressionSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenExpressionSpec.kt @@ -2,10 +2,7 @@ package com.linecorp.kotlinjdsl.query.spec.predicate import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.query.spec.expression.ExpressionSpec -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* data class BetweenExpressionSpec>( val left: ExpressionSpec, @@ -35,4 +32,16 @@ data class BetweenExpressionSpec>( right2.toCriteriaExpression(froms, query, criteriaBuilder), ) } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + return criteriaBuilder.between( + left.toCriteriaExpression(froms, query, criteriaBuilder), + right1.toCriteriaExpression(froms, query, criteriaBuilder), + right2.toCriteriaExpression(froms, query, criteriaBuilder), + ) + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenValueSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenValueSpec.kt index e7b537c56..e2cf8ec56 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenValueSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenValueSpec.kt @@ -2,17 +2,14 @@ package com.linecorp.kotlinjdsl.query.spec.predicate import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.query.spec.expression.ExpressionSpec -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* +@Suppress("TYPE_MISMATCH_WARNING") data class BetweenValueSpec( val left: ExpressionSpec, val right1: R, val right2: R, ) : PredicateSpec where R : Comparable, R : Any, T : R? { - @Suppress("TYPE_MISMATCH_WARNING") override fun toCriteriaPredicate( froms: Froms, query: AbstractQuery<*>, @@ -21,7 +18,6 @@ data class BetweenValueSpec( return criteriaBuilder.between(left.toCriteriaExpression(froms, query, criteriaBuilder), right1, right2) } - @Suppress("TYPE_MISMATCH_WARNING") override fun toCriteriaPredicate( froms: Froms, query: CriteriaUpdate<*>, @@ -29,4 +25,12 @@ data class BetweenValueSpec( ): Predicate { return criteriaBuilder.between(left.toCriteriaExpression(froms, query, criteriaBuilder), right1, right2) } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + return criteriaBuilder.between(left.toCriteriaExpression(froms, query, criteriaBuilder), right1, right2) + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EmptyPredicateSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EmptyPredicateSpec.kt index fc5ce1b3f..a402d2726 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EmptyPredicateSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EmptyPredicateSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.predicate import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* object EmptyPredicateSpec : PredicateSpec { override fun toCriteriaPredicate( @@ -22,4 +19,12 @@ object EmptyPredicateSpec : PredicateSpec { ): Predicate { return criteriaBuilder.conjunction() } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + return criteriaBuilder.conjunction() + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualExpressionSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualExpressionSpec.kt index 37a36dc43..a23108514 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualExpressionSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualExpressionSpec.kt @@ -2,10 +2,7 @@ package com.linecorp.kotlinjdsl.query.spec.predicate import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.query.spec.expression.ExpressionSpec -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* data class EqualExpressionSpec( val left: ExpressionSpec, @@ -32,4 +29,15 @@ data class EqualExpressionSpec( right.toCriteriaExpression(froms, query, criteriaBuilder), ) } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + return criteriaBuilder.equal( + left.toCriteriaExpression(froms, query, criteriaBuilder), + right.toCriteriaExpression(froms, query, criteriaBuilder), + ) + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualValueSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualValueSpec.kt index 886f8b0c1..a1333b445 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualValueSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualValueSpec.kt @@ -2,10 +2,7 @@ package com.linecorp.kotlinjdsl.query.spec.predicate import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.query.spec.expression.ExpressionSpec -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* data class EqualValueSpec( val left: ExpressionSpec, @@ -26,4 +23,12 @@ data class EqualValueSpec( ): Predicate { return criteriaBuilder.equal(left.toCriteriaExpression(froms, query, criteriaBuilder), right) } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + return criteriaBuilder.equal(left.toCriteriaExpression(froms, query, criteriaBuilder), right) + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanExpressionSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanExpressionSpec.kt index 16c1df25c..93e8f6877 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanExpressionSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanExpressionSpec.kt @@ -31,6 +31,17 @@ data class GreaterThanExpressionSpec>( return toCriteriaPredicate(criteriaBuilder, leftExpression, rightExpression) } + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + val leftExpression = left.toCriteriaExpression(froms, query, criteriaBuilder) + val rightExpression = right.toCriteriaExpression(froms, query, criteriaBuilder) + + return toCriteriaPredicate(criteriaBuilder, leftExpression, rightExpression) + } + private fun toCriteriaPredicate( criteriaBuilder: CriteriaBuilder, leftExpression: Expression, diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanValueSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanValueSpec.kt index 2126056d7..fd344d64f 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanValueSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanValueSpec.kt @@ -9,7 +9,6 @@ data class GreaterThanValueSpec( val right: R, val inclusive: Boolean, ) : PredicateSpec where R : Comparable, R : Any, T : R? { - @Suppress("TYPE_MISMATCH_WARNING") override fun toCriteriaPredicate( froms: Froms, query: AbstractQuery<*>, @@ -30,6 +29,17 @@ data class GreaterThanValueSpec( return toCriteriaPredicate(criteriaBuilder, leftExpression) } + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + val leftExpression = left.toCriteriaExpression(froms, query, criteriaBuilder) + + return toCriteriaPredicate(criteriaBuilder, leftExpression) + } + + @Suppress("TYPE_MISMATCH_WARNING") private fun toCriteriaPredicate( criteriaBuilder: CriteriaBuilder, leftExpression: Expression diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InExpressionSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InExpressionSpec.kt index 62188883e..d88f7b40f 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InExpressionSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InExpressionSpec.kt @@ -2,10 +2,7 @@ package com.linecorp.kotlinjdsl.query.spec.predicate import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.query.spec.expression.ExpressionSpec -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* data class InExpressionSpec( val left: ExpressionSpec, @@ -34,4 +31,16 @@ data class InExpressionSpec( rights.forEach { value(it.toCriteriaExpression(froms, query, criteriaBuilder)) } } } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + if (rights.isEmpty()) return criteriaBuilder.conjunction() + + return criteriaBuilder.`in`(left.toCriteriaExpression(froms, query, criteriaBuilder)).apply { + rights.forEach { value(it.toCriteriaExpression(froms, query, criteriaBuilder)) } + } + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InValueSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InValueSpec.kt index 370da7983..816ba2edc 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InValueSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InValueSpec.kt @@ -2,10 +2,7 @@ package com.linecorp.kotlinjdsl.query.spec.predicate import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.query.spec.expression.ExpressionSpec -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* data class InValueSpec( val left: ExpressionSpec, @@ -34,4 +31,16 @@ data class InValueSpec( rights.forEach { value(it) } } } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + if (rights.isEmpty()) return criteriaBuilder.conjunction() + + return criteriaBuilder.`in`(left.toCriteriaExpression(froms, query, criteriaBuilder)).apply { + rights.forEach { value(it) } + } + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsFalseSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsFalseSpec.kt index 74011e992..6e0d0f435 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsFalseSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsFalseSpec.kt @@ -4,6 +4,7 @@ import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.query.spec.expression.ExpressionSpec import javax.persistence.criteria.* +@Suppress("UNCHECKED_CAST") data class IsFalseSpec( val expression: ExpressionSpec ) : PredicateSpec { @@ -12,7 +13,6 @@ data class IsFalseSpec( query: AbstractQuery<*>, criteriaBuilder: CriteriaBuilder ): Predicate { - @Suppress("UNCHECKED_CAST") return criteriaBuilder.isFalse( expression.toCriteriaExpression(froms, query, criteriaBuilder) as Expression ) @@ -23,7 +23,16 @@ data class IsFalseSpec( query: CriteriaUpdate<*>, criteriaBuilder: CriteriaBuilder ): Predicate { - @Suppress("UNCHECKED_CAST") + return criteriaBuilder.isFalse( + expression.toCriteriaExpression(froms, query, criteriaBuilder) as Expression + ) + } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { return criteriaBuilder.isFalse( expression.toCriteriaExpression(froms, query, criteriaBuilder) as Expression ) diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsNullSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsNullSpec.kt index 3cb24509b..55578b7f3 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsNullSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsNullSpec.kt @@ -2,10 +2,7 @@ package com.linecorp.kotlinjdsl.query.spec.predicate import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.query.spec.expression.ExpressionSpec -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* data class IsNullSpec( val expression: ExpressionSpec @@ -25,4 +22,12 @@ data class IsNullSpec( ): Predicate { return criteriaBuilder.isNull(expression.toCriteriaExpression(froms, query, criteriaBuilder)) } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + return criteriaBuilder.isNull(expression.toCriteriaExpression(froms, query, criteriaBuilder)) + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsTrueSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsTrueSpec.kt index 77e0f3223..437a335ca 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsTrueSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsTrueSpec.kt @@ -4,6 +4,7 @@ import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.query.spec.expression.ExpressionSpec import javax.persistence.criteria.* +@Suppress("UNCHECKED_CAST") data class IsTrueSpec( val expression: ExpressionSpec ) : PredicateSpec { @@ -12,7 +13,6 @@ data class IsTrueSpec( query: AbstractQuery<*>, criteriaBuilder: CriteriaBuilder ): Predicate { - @Suppress("UNCHECKED_CAST") return criteriaBuilder.isTrue( expression.toCriteriaExpression(froms, query, criteriaBuilder) as Expression ) @@ -23,7 +23,16 @@ data class IsTrueSpec( query: CriteriaUpdate<*>, criteriaBuilder: CriteriaBuilder ): Predicate { - @Suppress("UNCHECKED_CAST") + return criteriaBuilder.isTrue( + expression.toCriteriaExpression(froms, query, criteriaBuilder) as Expression + ) + } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { return criteriaBuilder.isTrue( expression.toCriteriaExpression(froms, query, criteriaBuilder) as Expression ) diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanExpressionSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanExpressionSpec.kt index b936ce38a..cf463bb53 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanExpressionSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanExpressionSpec.kt @@ -31,6 +31,17 @@ data class LessThanExpressionSpec>( return toCriteriaPredicate(criteriaBuilder, leftExpression, rightExpression) } + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + val leftExpression = left.toCriteriaExpression(froms, query, criteriaBuilder) + val rightExpression = right.toCriteriaExpression(froms, query, criteriaBuilder) + + return toCriteriaPredicate(criteriaBuilder, leftExpression, rightExpression) + } + private fun toCriteriaPredicate( criteriaBuilder: CriteriaBuilder, leftExpression: Expression, diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanValueSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanValueSpec.kt index dd731d606..61e1245e5 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanValueSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanValueSpec.kt @@ -4,12 +4,12 @@ import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.query.spec.expression.ExpressionSpec import javax.persistence.criteria.* +@Suppress("TYPE_MISMATCH_WARNING") data class LessThanValueSpec( val left: ExpressionSpec, val right: R, val inclusive: Boolean, ) : PredicateSpec where R : Comparable, R : Any, T : R? { - @Suppress("TYPE_MISMATCH_WARNING") override fun toCriteriaPredicate( froms: Froms, query: AbstractQuery<*>, @@ -20,7 +20,6 @@ data class LessThanValueSpec( return toCriteriaPredicate(criteriaBuilder, leftExpression) } - @Suppress("TYPE_MISMATCH_WARNING") override fun toCriteriaPredicate( froms: Froms, query: CriteriaUpdate<*>, @@ -31,6 +30,16 @@ data class LessThanValueSpec( return toCriteriaPredicate(criteriaBuilder, leftExpression) } + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + val leftExpression: Expression = left.toCriteriaExpression(froms, query, criteriaBuilder) + + return toCriteriaPredicate(criteriaBuilder, leftExpression) + } + private fun toCriteriaPredicate( criteriaBuilder: CriteriaBuilder, leftExpression: Expression diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LikeSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LikeSpec.kt index 32d9595e6..5585afdfd 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LikeSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LikeSpec.kt @@ -4,6 +4,7 @@ import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.query.spec.expression.ExpressionSpec import javax.persistence.criteria.* +@Suppress("UNCHECKED_CAST") data class LikeSpec( val left: ExpressionSpec, val right: String @@ -13,7 +14,6 @@ data class LikeSpec( query: AbstractQuery<*>, criteriaBuilder: CriteriaBuilder ): Predicate { - @Suppress("UNCHECKED_CAST") return criteriaBuilder.like( left.toCriteriaExpression(froms, query, criteriaBuilder) as Expression, right @@ -25,7 +25,17 @@ data class LikeSpec( query: CriteriaUpdate<*>, criteriaBuilder: CriteriaBuilder ): Predicate { - @Suppress("UNCHECKED_CAST") + return criteriaBuilder.like( + left.toCriteriaExpression(froms, query, criteriaBuilder) as Expression, + right + ) + } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { return criteriaBuilder.like( left.toCriteriaExpression(froms, query, criteriaBuilder) as Expression, right diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/NotSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/NotSpec.kt index 4ccc39a44..1e0ca3eda 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/NotSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/NotSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.predicate import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* data class NotSpec( val predicate: PredicateSpec, @@ -24,4 +21,12 @@ data class NotSpec( ): Predicate { return criteriaBuilder.not(predicate.toCriteriaPredicate(froms, query, criteriaBuilder)) } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + return criteriaBuilder.not(predicate.toCriteriaPredicate(froms, query, criteriaBuilder)) + } } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/OrSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/OrSpec.kt index f94307f22..c60814609 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/OrSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/OrSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.predicate import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* data class OrSpec( val predicates: List, @@ -42,6 +39,22 @@ data class OrSpec( } } + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + return toCriteriaPredicate( + criteriaBuilder = criteriaBuilder, + empty = { EmptyPredicateSpec.toCriteriaPredicate(froms, query, criteriaBuilder) }) { + it.toCriteriaPredicate( + froms, + query, + criteriaBuilder + ) + } + } + fun toCriteriaPredicate( criteriaBuilder: CriteriaBuilder, empty: () -> Predicate, diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/PredicateSpec.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/PredicateSpec.kt index 06af262cc..e45245cf9 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/PredicateSpec.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/PredicateSpec.kt @@ -1,10 +1,7 @@ package com.linecorp.kotlinjdsl.query.spec.predicate import com.linecorp.kotlinjdsl.query.spec.Froms -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* interface PredicateSpec { companion object { @@ -20,4 +17,5 @@ interface PredicateSpec { fun toCriteriaPredicate(froms: Froms, query: AbstractQuery<*>, criteriaBuilder: CriteriaBuilder): Predicate fun toCriteriaPredicate(froms: Froms, query: CriteriaUpdate<*>, criteriaBuilder: CriteriaBuilder): Predicate + fun toCriteriaPredicate(froms: Froms, query: CriteriaDelete<*>, criteriaBuilder: CriteriaBuilder): Predicate } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/CriteriaDeleteQueryDsl.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/CriteriaDeleteQueryDsl.kt new file mode 100644 index 000000000..00da5ad83 --- /dev/null +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/CriteriaDeleteQueryDsl.kt @@ -0,0 +1,12 @@ +package com.linecorp.kotlinjdsl.querydsl + +import com.linecorp.kotlinjdsl.querydsl.from.AssociateDsl +import com.linecorp.kotlinjdsl.querydsl.from.RelationDsl +import com.linecorp.kotlinjdsl.querydsl.hint.HintDsl +import com.linecorp.kotlinjdsl.querydsl.where.WhereDsl + +interface CriteriaDeleteQueryDsl : + AssociateDsl, + RelationDsl, + WhereDsl, + HintDsl diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/CriteriaQueryDsl.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/CriteriaQueryDsl.kt index 2e0a7af47..10154d715 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/CriteriaQueryDsl.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/CriteriaQueryDsl.kt @@ -1,6 +1,5 @@ package com.linecorp.kotlinjdsl.querydsl -import com.linecorp.kotlinjdsl.querydsl.expression.ExpressionDsl import com.linecorp.kotlinjdsl.querydsl.from.FetchDsl import com.linecorp.kotlinjdsl.querydsl.from.FromDsl import com.linecorp.kotlinjdsl.querydsl.from.JoinDsl @@ -10,14 +9,11 @@ import com.linecorp.kotlinjdsl.querydsl.having.HavingDsl import com.linecorp.kotlinjdsl.querydsl.hint.HintDsl import com.linecorp.kotlinjdsl.querydsl.limit.LimitDsl import com.linecorp.kotlinjdsl.querydsl.orderby.OrderByDsl -import com.linecorp.kotlinjdsl.querydsl.predicate.PredicateDsl import com.linecorp.kotlinjdsl.querydsl.select.MultiSelectDsl import com.linecorp.kotlinjdsl.querydsl.select.SingleSelectDsl import com.linecorp.kotlinjdsl.querydsl.where.WhereDsl interface CriteriaQueryDsl : - ExpressionDsl, - PredicateDsl, SingleSelectDsl, MultiSelectDsl, FromDsl, diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/CriteriaUpdateQueryDsl.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/CriteriaUpdateQueryDsl.kt index a81b05ce7..1e7303d78 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/CriteriaUpdateQueryDsl.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/CriteriaUpdateQueryDsl.kt @@ -1,16 +1,12 @@ package com.linecorp.kotlinjdsl.querydsl -import com.linecorp.kotlinjdsl.querydsl.expression.ExpressionDsl import com.linecorp.kotlinjdsl.querydsl.from.AssociateDsl import com.linecorp.kotlinjdsl.querydsl.from.RelationDsl import com.linecorp.kotlinjdsl.querydsl.hint.HintDsl -import com.linecorp.kotlinjdsl.querydsl.predicate.PredicateDsl import com.linecorp.kotlinjdsl.querydsl.set.SetParameterDsl import com.linecorp.kotlinjdsl.querydsl.where.WhereDsl interface CriteriaUpdateQueryDsl : - ExpressionDsl, - PredicateDsl, AssociateDsl, RelationDsl, WhereDsl, diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/QueryDslImpl.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/QueryDslImpl.kt index b7b004e85..e1c3bfc7a 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/QueryDslImpl.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/QueryDslImpl.kt @@ -1,5 +1,6 @@ package com.linecorp.kotlinjdsl.querydsl +import com.linecorp.kotlinjdsl.query.CriteriaDeleteQuerySpec import com.linecorp.kotlinjdsl.query.CriteriaQuerySpec import com.linecorp.kotlinjdsl.query.CriteriaUpdateQuerySpec import com.linecorp.kotlinjdsl.query.SubquerySpec @@ -45,7 +46,7 @@ import javax.persistence.criteria.JoinType */ open class QueryDslImpl( private val returnType: Class, -) : CriteriaQueryDsl, SubqueryDsl, CriteriaUpdateQueryDsl { +) : CriteriaQueryDsl, SubqueryDsl, CriteriaUpdateQueryDsl, CriteriaDeleteQueryDsl { private var singleSelectClause: SingleSelectClause? = null private var multiSelectClause: MultiSelectClause? = null private var fromClause: FromClause? = null @@ -174,6 +175,17 @@ open class QueryDslImpl( ) } + fun createCriteriaDeleteQuerySpec(): CriteriaDeleteQuerySpec { + return CriteriaDeleteQuerySpecImpl( + targetEntity = returnType, + from = getFromClause(), + associate = getSimpleAssociatedJoinClauseOnly(), + where = getWhereClause(), + sqlHint = getSqlQueryHintClause(), + jpaHint = getJpaQueryHintClause() + ) + } + fun createSubquerySpec(): SubquerySpec { return SubquerySpecImpl( select = getSubquerySelectClause(), @@ -312,6 +324,14 @@ open class QueryDslImpl( override val set: SetClause ) : CriteriaUpdateQuerySpec + data class CriteriaDeleteQuerySpecImpl( + override val targetEntity: Class, + override val from: FromClause, + override val associate: SimpleAssociatedJoinClause, + override val where: CriteriaQueryWhereClause, + override val jpaHint: JpaQueryHintClause, + override val sqlHint: SqlQueryHintClause + ) : CriteriaDeleteQuerySpec data class SubquerySpecImpl( override val select: SubquerySelectClause, @@ -320,14 +340,5 @@ open class QueryDslImpl( override val where: SubqueryWhereClause, override val groupBy: SubqueryGroupByClause, override val having: SubqueryHavingClause - ) : SubquerySpec { - constructor(spec: SubquerySpec) : this( - select = spec.select, - from = spec.from, - join = spec.join, - where = spec.where, - groupBy = spec.groupBy, - having = spec.having, - ) - } + ) : SubquerySpec } diff --git a/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/SubqueryDsl.kt b/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/SubqueryDsl.kt index 4d3342201..610c4539e 100644 --- a/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/SubqueryDsl.kt +++ b/query/src/main/kotlin/com/linecorp/kotlinjdsl/querydsl/SubqueryDsl.kt @@ -1,22 +1,18 @@ package com.linecorp.kotlinjdsl.querydsl -import com.linecorp.kotlinjdsl.querydsl.expression.ExpressionDsl import com.linecorp.kotlinjdsl.querydsl.from.FromDsl import com.linecorp.kotlinjdsl.querydsl.from.JoinDsl import com.linecorp.kotlinjdsl.querydsl.from.RelationDsl import com.linecorp.kotlinjdsl.querydsl.groupby.GroupByDsl import com.linecorp.kotlinjdsl.querydsl.having.HavingDsl -import com.linecorp.kotlinjdsl.querydsl.predicate.PredicateDsl import com.linecorp.kotlinjdsl.querydsl.select.SingleSelectDsl import com.linecorp.kotlinjdsl.querydsl.where.WhereDsl interface SubqueryDsl : - ExpressionDsl, - PredicateDsl, SingleSelectDsl, FromDsl, JoinDsl, RelationDsl, WhereDsl, GroupByDsl, - HavingDsl \ No newline at end of file + HavingDsl diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/clause/from/FromClauseTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/clause/from/FromClauseTest.kt index 14b89d9a6..c928b428e 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/clause/from/FromClauseTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/clause/from/FromClauseTest.kt @@ -21,6 +21,9 @@ internal class FromClauseTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate + @MockK + private lateinit var deleteQuery: CriteriaDelete + private val entitySpec1 = EntitySpec(Data1::class.java) private val entitySpec2 = EntitySpec(Data2::class.java) private val entitySpec3 = EntitySpec(Data3::class.java) @@ -127,11 +130,13 @@ internal class FromClauseTest : WithKotlinJdslAssertions { val join2 = mockk>() every { updateQuery.from(Data1::class.java) } returns root + every { deleteQuery.from(Data1::class.java) } returns root every { root.get(joinSpec1.path) } returns join1 every { join1.get(joinSpec2.path) } returns join2 // when val actual = fromClause.associate(joinClause, updateQuery as CriteriaUpdate, Data1::class.java) + val deleteActual = fromClause.associate(joinClause, deleteQuery as CriteriaDelete, Data1::class.java) // then assertThat(actual).usingRecursiveComparison().isEqualTo( @@ -144,9 +149,23 @@ internal class FromClauseTest : WithKotlinJdslAssertions { ) ) ) + assertThat(deleteActual).usingRecursiveComparison().isEqualTo( + Froms( + root = root, + map = mapOf( + entitySpec1 to root, + entitySpec2 to join1, + entitySpec3 to join2, + ) + ) + ) verify(exactly = 1) { updateQuery.from(Data1::class.java) + deleteQuery.from(Data1::class.java) + } + + verify(exactly = 2) { root.get(joinSpec1.path) join1.get(joinSpec2.path) } @@ -157,7 +176,7 @@ internal class FromClauseTest : WithKotlinJdslAssertions { join2.hashCode() } - confirmVerified(root, join1, join2, updateQuery) + confirmVerified(root, join1, join2, updateQuery, deleteQuery) } @Suppress("UNCHECKED_CAST") @@ -173,21 +192,30 @@ internal class FromClauseTest : WithKotlinJdslAssertions { val root = mockk>() every { updateQuery.from(Data1::class.java) } returns root + every { deleteQuery.from(Data1::class.java) } returns root // when val exception = catchThrowable(IllegalStateException::class) { fromClause.associate(joinClause, updateQuery as CriteriaUpdate, Data1::class.java) } + val deleteException = catchThrowable(IllegalStateException::class) { + fromClause.associate(joinClause, deleteQuery as CriteriaDelete, Data1::class.java) + } + // then assertThat(exception) .hasMessageContaining("Associate clause is incomplete. Please check if the following Entities are associated") + assertThat(deleteException) + .hasMessageContaining("Associate clause is incomplete. Please check if the following Entities are associated") + verify(exactly = 1) { updateQuery.from(Data1::class.java) + deleteQuery.from(Data1::class.java) } - confirmVerified(root, updateQuery) + confirmVerified(root, updateQuery, deleteQuery) } private class Data1 diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/clause/where/WhereClauseTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/clause/where/WhereClauseTest.kt index ef3adde38..e41ede29f 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/clause/where/WhereClauseTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/clause/where/WhereClauseTest.kt @@ -27,6 +27,9 @@ internal class WhereClauseTest : WithKotlinJdslAssertions { @MockK private lateinit var criteriaUpdateQuery: CriteriaUpdate + @MockK + private lateinit var criteriaDeleteQuery: CriteriaDelete + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -98,6 +101,40 @@ internal class WhereClauseTest : WithKotlinJdslAssertions { confirmVerified(froms, subquery, criteriaUpdateQuery, criteriaBuilder) } + @Test + fun `apply criteria delete query`() { + // given + val predicateSpec: PredicateSpec = mockk() + val predicate: Predicate = mockk() + + every { predicateSpec.isEmpty() } returns false + every { predicateSpec.toCriteriaPredicate(froms, criteriaDeleteQuery, criteriaBuilder) } returns predicate + every { criteriaDeleteQuery.where(predicate) } returns criteriaDeleteQuery + + // when + WhereClause(predicateSpec).apply(froms, criteriaDeleteQuery, criteriaBuilder) + + // then + verify(exactly = 1) { + predicateSpec.isEmpty() + predicateSpec.toCriteriaPredicate(froms, criteriaDeleteQuery, criteriaBuilder) + criteriaDeleteQuery.where(predicate) + + criteriaDeleteQuery.where(predicate) + } + + confirmVerified(predicateSpec, froms, subquery, criteriaDeleteQuery, criteriaBuilder) + } + + @Test + fun `apply criteria delete query - if predicate is empty then do nothing`() { + // when + WhereClause(PredicateSpec.empty).apply(froms, criteriaDeleteQuery, criteriaBuilder) + + // then + confirmVerified(froms, subquery, criteriaDeleteQuery, criteriaBuilder) + } + @Test fun `apply subquery`() { // given diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/creator/SubqueryCreatorImplTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/creator/SubqueryCreatorImplTest.kt index 9add8b23f..be7b6c059 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/creator/SubqueryCreatorImplTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/creator/SubqueryCreatorImplTest.kt @@ -14,9 +14,7 @@ import io.mockk.junit5.MockKExtension import org.assertj.core.api.WithAssertions import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaQuery -import javax.persistence.criteria.Subquery +import javax.persistence.criteria.* @ExtendWith(MockKExtension::class) internal class SubqueryCreatorImplTest : WithAssertions { @@ -31,9 +29,24 @@ internal class SubqueryCreatorImplTest : WithAssertions { @MockK private lateinit var criteriaQuery: CriteriaQuery + @MockK + private lateinit var criteriaUpdate: CriteriaUpdate + + @MockK + private lateinit var criteriaDelete: CriteriaDelete + @MockK private lateinit var subquery: Subquery + data class TestSubquerySpec( + override val select: SubquerySelectClause, + override val from: FromClause, + override val join: JoinClause, + override val where: SubqueryWhereClause, + override val groupBy: SubqueryGroupByClause, + override val having: SubqueryHavingClause + ) : SubquerySpec + @Test fun createQuery() { // given @@ -51,14 +64,14 @@ internal class SubqueryCreatorImplTest : WithAssertions { val groupBy: SubqueryGroupByClause = mockk() val having: SubqueryHavingClause = mockk() - val spec: SubquerySpec = mockk { - every { this@mockk.select } returns select - every { this@mockk.from } returns from - every { this@mockk.join } returns join - every { this@mockk.where } returns where - every { this@mockk.groupBy } returns groupBy - every { this@mockk.having } returns having - } + val spec: SubquerySpec = TestSubquerySpec( + select = select, + from = from, + join = join, + where = where, + groupBy = groupBy, + having = having + ) every { criteriaQuery.subquery(Int::class.java) } returns createdQuery every { from.join(join, createdQuery) } returns createdFroms @@ -74,17 +87,7 @@ internal class SubqueryCreatorImplTest : WithAssertions { // then assertThat(actual).isEqualTo(createdQuery) - verify(exactly = 2) { - spec.select - } - verify(exactly = 1) { - spec.from - spec.join - spec.where - spec.groupBy - spec.having - criteriaQuery.subquery(Int::class.java) from.join(join, createdQuery) createdFroms + froms @@ -97,9 +100,68 @@ internal class SubqueryCreatorImplTest : WithAssertions { } confirmVerified( - spec, select, from, join, where, groupBy, having, + select, from, join, where, groupBy, having, createdFroms, mergedFroms, createdQuery, criteriaQuery, subquery, criteriaBuilder ) } -} \ No newline at end of file + + @Test + fun createUpdateQuery() { + // given + val createdQuery: Subquery = mockk() + + val createdFroms: Froms = mockk() + val mergedFroms: Froms = mockk() + + val select: SubquerySelectClause = mockk { + every { returnType } returns Int::class.java + } + val from: FromClause = mockk() + val join: JoinClause = mockk() + val where: SubqueryWhereClause = mockk() + val groupBy: SubqueryGroupByClause = mockk() + val having: SubqueryHavingClause = mockk() + + val spec: SubquerySpec = TestSubquerySpec( + select = select, + from = from, + join = join, + where = where, + groupBy = groupBy, + having = having + ) + + every { criteriaUpdate.subquery(Int::class.java) } returns createdQuery + every { from.join(join, createdQuery) } returns createdFroms + every { createdFroms + froms } returns mergedFroms + every { select.apply(mergedFroms, createdQuery, criteriaBuilder) } just runs + every { where.apply(mergedFroms, createdQuery, criteriaBuilder) } just runs + every { groupBy.apply(mergedFroms, createdQuery, criteriaBuilder) } just runs + every { having.apply(mergedFroms, createdQuery, criteriaBuilder) } just runs + + // when + val actual = sut.createQuery(spec, froms, criteriaUpdate, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(createdQuery) + + verify(exactly = 1) { + criteriaUpdate.subquery(Int::class.java) + from.join(join, createdQuery) + createdFroms + froms + select.returnType + select.apply(mergedFroms, createdQuery, criteriaBuilder) + where.apply(mergedFroms, createdQuery, criteriaBuilder) + groupBy.apply(mergedFroms, createdQuery, criteriaBuilder) + having.apply(mergedFroms, createdQuery, criteriaBuilder) + createdQuery == createdQuery + } + + confirmVerified( + select, from, join, where, groupBy, having, + createdFroms, mergedFroms, createdQuery, + criteriaUpdate, subquery, criteriaBuilder + ) + } +} diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/FromsTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/FromsTest.kt index d8d252ab6..4d2fa0f0a 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/FromsTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/FromsTest.kt @@ -7,6 +7,7 @@ import io.mockk.mockk import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import javax.persistence.criteria.From +import javax.persistence.criteria.Path import javax.persistence.criteria.Root @ExtendWith(MockKExtension::class) @@ -17,7 +18,7 @@ internal class FromsTest : WithKotlinJdslAssertions { val root: Root<*> = mockk() val entitySpec1 = EntitySpec(Data1::class.java) - val from1: From<*, *> = mockk() + val from1: Path<*> = mockk() val entitySpec2 = EntitySpec(Data2::class.java) val from2: From<*, *> = mockk() @@ -126,4 +127,4 @@ internal class FromsTest : WithKotlinJdslAssertions { data class Data3( val id: Long ) -} \ No newline at end of file +} diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/AvgSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/AvgSpecTest.kt index 409ffad4e..197ebb43e 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/AvgSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/AvgSpecTest.kt @@ -23,6 +23,9 @@ internal class AvgSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -79,4 +82,31 @@ internal class AvgSpecTest : WithKotlinJdslAssertions { confirmVerified(column, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaExpression`() { + // given + val column = mockk>() + val columnExpression = mockk>() + + val avgExpression = mockk>() + + every { column.toCriteriaExpression(any(), any>(), any()) } returns columnExpression + every { criteriaBuilder.avg(any>()) } returns avgExpression + + // when + val spec = AvgSpec(column) + + val actual = spec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(avgExpression) + + verify(exactly = 1) { + column.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.avg(columnExpression) + } + + confirmVerified(column, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CaseSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CaseSpecTest.kt index be46601a7..8a5554f16 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CaseSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CaseSpecTest.kt @@ -24,6 +24,9 @@ internal class CaseSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -160,4 +163,71 @@ internal class CaseSpecTest : WithKotlinJdslAssertions { froms, updateQuery, criteriaBuilder ) } + + @Test + fun `delete toCriteriaExpression`() { + // given + val predicateSpec1 = mockk() + val predicateSpec2 = mockk() + + val predicate1 = mockk() + val predicate2 = mockk() + + val resultSpec1 = mockk>() + val resultSpec2 = mockk>() + + val result1 = mockk>() + val result2 = mockk>() + + val when1 = CaseSpec.WhenSpec(predicateSpec1, resultSpec1) + val when2 = CaseSpec.WhenSpec(predicateSpec2, resultSpec2) + + val otherwise1 = mockk>() + val otherwise1Expression = mockk>() + + val case = mockk>() + val caseExpression = mockk>() + + every { predicateSpec1.toCriteriaPredicate(any(), any>(), any()) } returns predicate1 + every { predicateSpec2.toCriteriaPredicate(any(), any>(), any()) } returns predicate2 + + every { resultSpec1.toCriteriaExpression(any(), any>(), any()) } returns result1 + every { resultSpec2.toCriteriaExpression(any(), any>(), any()) } returns result2 + + every { otherwise1.toCriteriaExpression(any(), any>(), any()) } returns otherwise1Expression + + every { criteriaBuilder.selectCase() } returns case + every { case.`when`(any(), any>()) } returns case + every { case.otherwise(any>()) } returns caseExpression + + // when + val spec = CaseSpec(listOf(when1, when2), otherwise1) + + val actual = spec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(caseExpression) + + verify(exactly = 1) { + predicateSpec1.toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + predicateSpec2.toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + resultSpec1.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + resultSpec2.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + otherwise1.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + criteriaBuilder.selectCase() + case.`when`(predicate1, result1) + case.`when`(predicate2, result2) + case.otherwise(otherwise1Expression) + } + + confirmVerified( + predicateSpec1, predicateSpec2, + resultSpec1, resultSpec2, + otherwise1, case, + froms, deleteQuery, criteriaBuilder + ) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/ColumnSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/ColumnSpecTest.kt index 4e9188e37..61c1f3e45 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/ColumnSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/ColumnSpecTest.kt @@ -23,6 +23,9 @@ internal class ColumnSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -76,6 +79,30 @@ internal class ColumnSpecTest : WithKotlinJdslAssertions { confirmVerified(from, froms, updateQuery, criteriaBuilder) } + @Test + fun `delete toCriteriaExpression`() { + // given + val from = mockk>() + val path = mockk>() + + every { froms[any>()] } returns from + every { from.get(any()) } returns path + + // when + val spec = ColumnSpec(EntitySpec(Data::class.java), "name") + + val actual = spec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(path) + + verify { + froms[EntitySpec(Data::class.java)] + from.get("name") + } + + confirmVerified(from, froms, deleteQuery, criteriaBuilder) + } private class Data { val name = "name" diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CountSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CountSpecTest.kt index 945746752..b14040679 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CountSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/CountSpecTest.kt @@ -23,6 +23,9 @@ internal class CountSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -133,4 +136,58 @@ internal class CountSpecTest : WithKotlinJdslAssertions { confirmVerified(column, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaExpression - distinct`() { + // given + val column = mockk>() + val columnExpression = mockk>() + + val countExpression = mockk>() + + every { column.toCriteriaExpression(any(), any>(), any()) } returns columnExpression + every { criteriaBuilder.countDistinct(any>()) } returns countExpression + + // when + val spec = CountSpec(distinct = true, column) + + val actual = spec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(countExpression) + + verify(exactly = 1) { + column.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.countDistinct(columnExpression) + } + + confirmVerified(column, froms, deleteQuery, criteriaBuilder) + } + + @Test + fun `delete toCriteriaExpression - non distinct`() { + // given + val column = mockk>() + val columnExpression = mockk>() + + val countExpression = mockk>() + + every { column.toCriteriaExpression(any(), any>(), any()) } returns columnExpression + every { criteriaBuilder.count(any>()) } returns countExpression + + // when + val spec = CountSpec(distinct = false, column) + + val actual = spec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(countExpression) + + verify(exactly = 1) { + column.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.count(columnExpression) + } + + confirmVerified(column, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/EntitySpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/EntitySpecTest.kt index c44ff8a1d..382bd9a1e 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/EntitySpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/EntitySpecTest.kt @@ -10,10 +10,7 @@ import io.mockk.mockk import io.mockk.verify import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.From +import javax.persistence.criteria.* @ExtendWith(MockKExtension::class) internal class EntitySpecTest : WithKotlinJdslAssertions { @@ -24,7 +21,10 @@ internal class EntitySpecTest : WithKotlinJdslAssertions { private lateinit var query: AbstractQuery<*> @MockK - private lateinit var updateQUery: CriteriaUpdate<*> + private lateinit var updateQuery: CriteriaUpdate<*> + + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -85,7 +85,7 @@ internal class EntitySpecTest : WithKotlinJdslAssertions { // when val spec = EntitySpec(Data::class.java) - val actual = spec.toCriteriaExpression(froms, updateQUery, criteriaBuilder) + val actual = spec.toCriteriaExpression(froms, updateQuery, criteriaBuilder) // then assertThat(actual).isEqualTo(from) @@ -94,7 +94,7 @@ internal class EntitySpecTest : WithKotlinJdslAssertions { froms[spec] } - confirmVerified(froms, updateQUery, criteriaBuilder) + confirmVerified(froms, updateQuery, criteriaBuilder) } @Test @@ -108,7 +108,53 @@ internal class EntitySpecTest : WithKotlinJdslAssertions { // when val spec = EntitySpec(Data::class.java, "data1") - val actual = spec.toCriteriaExpression(froms, updateQUery, criteriaBuilder) + val actual = spec.toCriteriaExpression(froms, updateQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(from) + + verify(exactly = 1) { + froms[spec] + from.alias("data1") + } + + confirmVerified(froms, updateQuery, criteriaBuilder) + } + + @Test + fun `delete toCriteriaExpression`() { + // given + val from = mockk>() + + every { froms[any>()] } returns from + + // when + val spec = EntitySpec(Data::class.java) + + val actual = spec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(from) + + verify(exactly = 1) { + froms[spec] + } + + confirmVerified(froms, deleteQuery, criteriaBuilder) + } + + @Test + fun `delete toCriteriaExpression with alias`() { + // given + val from = mockk>() + + every { froms[any>()] } returns from + every { from.alias("data1") } returns mockk() + + // when + val spec = EntitySpec(Data::class.java, "data1") + + val actual = spec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) // then assertThat(actual).isEqualTo(from) @@ -118,7 +164,7 @@ internal class EntitySpecTest : WithKotlinJdslAssertions { from.alias("data1") } - confirmVerified(froms, updateQUery, criteriaBuilder) + confirmVerified(froms, deleteQuery, criteriaBuilder) } private class Data diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/GreatestSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/GreatestSpecTest.kt index 5549cf95b..8b0e26c80 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/GreatestSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/GreatestSpecTest.kt @@ -23,6 +23,9 @@ internal class GreatestSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -79,4 +82,31 @@ internal class GreatestSpecTest : WithKotlinJdslAssertions { confirmVerified(column, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaExpression`() { + // given + val column = mockk>() + val columnExpression = mockk>() + + val greatestExpression = mockk>() + + every { column.toCriteriaExpression(any(), any>(), any()) } returns columnExpression + every { criteriaBuilder.greatest(any>()) } returns greatestExpression + + // when + val spec = GreatestSpec(column) + + val actual = spec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(greatestExpression) + + verify(exactly = 1) { + column.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.greatest(columnExpression) + } + + confirmVerified(column, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LeastSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LeastSpecTest.kt index 5f7daf50e..e0a3c0bda 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LeastSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LeastSpecTest.kt @@ -23,6 +23,9 @@ internal class LeastSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -79,4 +82,31 @@ internal class LeastSpecTest : WithKotlinJdslAssertions { confirmVerified(column, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaExpression`() { + // given + val column = mockk>() + val columnExpression = mockk>() + + val leastExpression = mockk>() + + every { column.toCriteriaExpression(any(), any>(), any()) } returns columnExpression + every { criteriaBuilder.least(any>()) } returns leastExpression + + // when + val spec = LeastSpec(column) + + val actual = spec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(leastExpression) + + verify(exactly = 1) { + column.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.least(columnExpression) + } + + confirmVerified(column, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LiteralSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LiteralSpecTest.kt index de058e72c..597f56a4f 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LiteralSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/LiteralSpecTest.kt @@ -10,10 +10,7 @@ import io.mockk.mockk import io.mockk.verify import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* @ExtendWith(MockKExtension::class) internal class LiteralSpecTest : WithKotlinJdslAssertions { @@ -26,6 +23,9 @@ internal class LiteralSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -72,4 +72,26 @@ internal class LiteralSpecTest : WithKotlinJdslAssertions { confirmVerified(froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaExpression`() { + // given + val expression = mockk>() + + every { criteriaBuilder.literal(any()) } returns expression + + // when + val spec = LiteralSpec("TEST") + + val actual = spec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(expression) + + verify(exactly = 1) { + criteriaBuilder.literal("TEST") + } + + confirmVerified(froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MaxSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MaxSpecTest.kt index 7dc77cbc7..75fa35530 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MaxSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MaxSpecTest.kt @@ -23,6 +23,9 @@ internal class MaxSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -79,4 +82,31 @@ internal class MaxSpecTest : WithKotlinJdslAssertions { confirmVerified(column, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaExpression`() { + // given + val column = mockk>() + val columnExpression = mockk>() + + val maxExpression = mockk>() + + every { column.toCriteriaExpression(any(), any>(), any()) } returns columnExpression + every { criteriaBuilder.max(any>()) } returns maxExpression + + // when + val spec = MaxSpec(column) + + val actual = spec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(maxExpression) + + verify(exactly = 1) { + column.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.max(columnExpression) + } + + confirmVerified(column, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MinSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MinSpecTest.kt index b0302dd99..65c79162f 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MinSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/MinSpecTest.kt @@ -23,6 +23,9 @@ internal class MinSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -79,4 +82,31 @@ internal class MinSpecTest : WithKotlinJdslAssertions { confirmVerified(column, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaExpression`() { + // given + val column = mockk>() + val columnExpression = mockk>() + + val minExpression = mockk>() + + every { column.toCriteriaExpression(any(), any>(), any()) } returns columnExpression + every { criteriaBuilder.min(any>()) } returns minExpression + + // when + val spec = MinSpec(column) + + val actual = spec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(minExpression) + + verify(exactly = 1) { + column.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.min(columnExpression) + } + + confirmVerified(column, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/NullLiteralSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/NullLiteralSpecTest.kt index 87eff9fe1..7247ee998 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/NullLiteralSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/NullLiteralSpecTest.kt @@ -10,10 +10,7 @@ import io.mockk.mockk import io.mockk.verify import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Expression +import javax.persistence.criteria.* @ExtendWith(MockKExtension::class) internal class NullLiteralSpecTest : WithKotlinJdslAssertions { @@ -26,33 +23,28 @@ internal class NullLiteralSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @Test fun toCriteriaExpression() { - // given - val expression = mockk>() - - every { criteriaBuilder.nullLiteral(any()) } returns expression - - // when - val spec = NullLiteralSpec(String::class.java) - - val actual = spec.toCriteriaExpression(froms, query, criteriaBuilder) - - // then - assertThat(actual).isEqualTo(expression) - - verify(exactly = 1) { - criteriaBuilder.nullLiteral(String::class.java) - } - - confirmVerified(froms, query, criteriaBuilder) + toCriteriaExpression { it.toCriteriaExpression(froms, query, criteriaBuilder) } } @Test fun `update toCriteriaExpression`() { + toCriteriaExpression { it.toCriteriaExpression(froms, updateQuery, criteriaBuilder) } + } + + @Test + fun `delete toCriteriaExpression`() { + toCriteriaExpression { it.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) } + } + + private fun toCriteriaExpression(predicate: (NullLiteralSpec) -> Expression) { // given val expression = mockk>() @@ -61,7 +53,7 @@ internal class NullLiteralSpecTest : WithKotlinJdslAssertions { // when val spec = NullLiteralSpec(String::class.java) - val actual = spec.toCriteriaExpression(froms, updateQuery, criteriaBuilder) + val actual = predicate(spec) // then assertThat(actual).isEqualTo(expression) @@ -70,6 +62,6 @@ internal class NullLiteralSpecTest : WithKotlinJdslAssertions { criteriaBuilder.nullLiteral(String::class.java) } - confirmVerified(froms, updateQuery, criteriaBuilder) + confirmVerified(froms, query, criteriaBuilder) } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SubqueryExpressionSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SubqueryExpressionSpecTest.kt index 1de79dc35..79fcd0fe6 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SubqueryExpressionSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SubqueryExpressionSpecTest.kt @@ -12,10 +12,7 @@ import io.mockk.mockk import io.mockk.verify import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaQuery -import javax.persistence.criteria.Subquery +import javax.persistence.criteria.* @ExtendWith(MockKExtension::class) internal class SubqueryExpressionSpecTest : WithKotlinJdslAssertions { @@ -28,6 +25,12 @@ internal class SubqueryExpressionSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var criteriaQuery: CriteriaQuery<*> + @MockK + private lateinit var criteriaDelete: CriteriaDelete<*> + + @MockK + private lateinit var criteriaUpdate: CriteriaUpdate<*> + @MockK private lateinit var subquery: Subquery<*> @@ -38,7 +41,7 @@ internal class SubqueryExpressionSpecTest : WithKotlinJdslAssertions { private lateinit var subqueryCreator: SubqueryCreator @Test - fun `toCriteriaExpression - by criteria query`() { + fun toCriteriaExpression() { // given val spec: SubquerySpec = mockk() val createdSubquery: Subquery = mockk() @@ -60,39 +63,68 @@ internal class SubqueryExpressionSpecTest : WithKotlinJdslAssertions { } @Test - fun `toCriteriaExpression - by subquery`() { + fun `toCriteriaExpression - by criteria update query`() { // given val spec: SubquerySpec = mockk() val createdSubquery: Subquery = mockk() - every { subqueryCreator.createQuery(spec, froms, subquery, criteriaBuilder) } returns createdSubquery + every { subqueryCreator.createQuery(spec, froms, criteriaUpdate, criteriaBuilder) } returns createdSubquery // when val actual = SubqueryExpressionSpec(spec, subqueryCreator) - .toCriteriaExpression(froms, subquery, criteriaBuilder) + .toCriteriaExpression(froms, criteriaUpdate, criteriaBuilder) // then assertThat(actual).isEqualTo(createdSubquery) verify(exactly = 1) { - subqueryCreator.createQuery(spec, froms, subquery, criteriaBuilder) + subqueryCreator.createQuery(spec, froms, criteriaUpdate, criteriaBuilder) } - confirmVerified(froms, abstractQuery, criteriaQuery, subquery, criteriaBuilder, subqueryCreator) + confirmVerified(froms, abstractQuery, criteriaUpdate, subquery, criteriaBuilder, subqueryCreator) } @Test - fun `toCriteriaExpression - if query is not instance of CriteriaQuery or Subquery then throw exception`() { + fun `toCriteriaExpression - by criteria delete query`() { // given val spec: SubquerySpec = mockk() + val createdSubquery: Subquery = mockk() + + every { subqueryCreator.createQuery(spec, froms, criteriaDelete, criteriaBuilder) } returns createdSubquery // when - val exception = catchThrowable(IllegalStateException::class) { - SubqueryExpressionSpec(spec, subqueryCreator) - .toCriteriaExpression(froms, abstractQuery, criteriaBuilder) + val actual = SubqueryExpressionSpec(spec, subqueryCreator) + .toCriteriaExpression(froms, criteriaDelete, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(createdSubquery) + + verify(exactly = 1) { + subqueryCreator.createQuery(spec, froms, criteriaDelete, criteriaBuilder) } + confirmVerified(froms, abstractQuery, criteriaDelete, subquery, criteriaBuilder, subqueryCreator) + } + + @Test + fun `toCriteriaExpression - by subquery`() { + // given + val spec: SubquerySpec = mockk() + val createdSubquery: Subquery = mockk() + + every { subqueryCreator.createQuery(spec, froms, subquery, criteriaBuilder) } returns createdSubquery + + // when + val actual = SubqueryExpressionSpec(spec, subqueryCreator) + .toCriteriaExpression(froms, subquery, criteriaBuilder) + // then - assertThat(exception).hasMessageContaining("could not create Subquery") + assertThat(actual).isEqualTo(createdSubquery) + + verify(exactly = 1) { + subqueryCreator.createQuery(spec, froms, subquery, criteriaBuilder) + } + + confirmVerified(froms, abstractQuery, criteriaQuery, subquery, criteriaBuilder, subqueryCreator) } -} \ No newline at end of file +} diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SumSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SumSpecTest.kt index 998eda4fb..26f10e866 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SumSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/expression/SumSpecTest.kt @@ -23,6 +23,9 @@ internal class SumSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -79,4 +82,31 @@ internal class SumSpecTest : WithKotlinJdslAssertions { confirmVerified(column, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaExpression`() { + // given + val column = mockk>() + val columnExpression = mockk>() + + val sumExpression = mockk>() + + every { column.toCriteriaExpression(any(), any>(), any()) } returns columnExpression + every { criteriaBuilder.sum(any>()) } returns sumExpression + + // when + val spec = SumSpec(column) + + val actual = spec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(sumExpression) + + verify(exactly = 1) { + column.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.sum(columnExpression) + } + + confirmVerified(column, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/AndSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/AndSpecTest.kt index 9ed13a898..24d7af223 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/AndSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/AndSpecTest.kt @@ -23,6 +23,9 @@ internal class AndSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -135,4 +138,59 @@ internal class AndSpecTest : WithKotlinJdslAssertions { confirmVerified(froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaPredicate`() { + // given + val predicateSpec1: PredicateSpec = mockk() + val predicateSpec2: PredicateSpec = mockk() + val predicateSpec3: PredicateSpec? = null + + val predicate1: Predicate = mockk() + val predicate2: Predicate = mockk() + val andPredicate: Predicate = mockk() + + every { predicateSpec1.toCriteriaPredicate(any(), any>(), any()) } returns predicate1 + every { predicateSpec2.toCriteriaPredicate(any(), any>(), any()) } returns predicate2 + + every { criteriaBuilder.and(any(), any()) } returns andPredicate + + // when + val actual = AndSpec(listOf(predicateSpec1, predicateSpec2, predicateSpec3)) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(andPredicate) + + verify(exactly = 1) { + predicateSpec1.toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + predicateSpec2.toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.and(predicate1, predicate2) + } + + confirmVerified(predicateSpec1, predicateSpec2, froms, deleteQuery, criteriaBuilder) + } + + @Test + fun `delete toCriteriaPredicate - if predicate is empty then return conjunction`() { + // given + val predicateSpec1: PredicateSpec? = null + val predicateSpec2: PredicateSpec? = null + + val andPredicate: Predicate = mockk() + + every { criteriaBuilder.conjunction() } returns andPredicate + + // when + val actual = AndSpec(listOf(predicateSpec1, predicateSpec2)).toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(andPredicate) + + verify(exactly = 1) { + criteriaBuilder.conjunction() + } + + confirmVerified(froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenExpressionSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenExpressionSpecTest.kt index cca8d563c..f236d3651 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenExpressionSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenExpressionSpecTest.kt @@ -24,6 +24,9 @@ internal class BetweenExpressionSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -116,4 +119,49 @@ internal class BetweenExpressionSpecTest : WithKotlinJdslAssertions { froms, updateQuery, criteriaBuilder ) } + + @Test + fun `delete toCriteriaPredicate`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val rightExpressionSpec1: ExpressionSpec = mockk() + val rightExpressionSpec2: ExpressionSpec = mockk() + + val leftExpression: Expression = mockk() + val rightExpression1: Expression = mockk() + val rightExpression2: Expression = mockk() + + val betweenPredicate: Predicate = mockk() + + every { leftExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns leftExpression + every { rightExpressionSpec1.toCriteriaExpression(any(), any>(), any()) } returns rightExpression1 + every { rightExpressionSpec2.toCriteriaExpression(any(), any>(), any()) } returns rightExpression2 + + every { criteriaBuilder.between(any(), any>(), any()) } returns betweenPredicate + + // when + val actual = BetweenExpressionSpec( + leftExpressionSpec, + rightExpressionSpec1, + rightExpressionSpec2 + ).toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(betweenPredicate) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + rightExpressionSpec1.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + rightExpressionSpec2.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + criteriaBuilder.between(leftExpression, rightExpression1, rightExpression2) + } + + confirmVerified( + leftExpressionSpec, + rightExpressionSpec1, + rightExpressionSpec2, + froms, deleteQuery, criteriaBuilder + ) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenValueSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenValueSpecTest.kt index 1d318834c..a4378a11e 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenValueSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/BetweenValueSpecTest.kt @@ -24,6 +24,9 @@ internal class BetweenValueSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -90,4 +93,36 @@ internal class BetweenValueSpecTest : WithKotlinJdslAssertions { confirmVerified(leftExpressionSpec, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaPredicate`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val right1 = 10 + val right2 = 20 + + val leftExpression: Expression = mockk() + + val betweenPredicate: Predicate = mockk() + + every { leftExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns leftExpression + + every { criteriaBuilder.between(any(), any(), any()) } returns betweenPredicate + + // when + val actual = BetweenValueSpec(leftExpressionSpec, right1, right2) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(betweenPredicate) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + @Suppress("TYPE_MISMATCH_WARNING") + criteriaBuilder.between(leftExpression, right1, right2) + } + + confirmVerified(leftExpressionSpec, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EmptyPredicateSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EmptyPredicateSpecTest.kt index 421429d24..fe3efa6bf 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EmptyPredicateSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EmptyPredicateSpecTest.kt @@ -10,10 +10,7 @@ import io.mockk.mockk import io.mockk.verify import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* @ExtendWith(MockKExtension::class) internal class EmptyPredicateSpecTest : WithKotlinJdslAssertions { @@ -26,38 +23,35 @@ internal class EmptyPredicateSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @Test fun toCriteriaPredicate() { - // given - val emptyPredicate: Predicate = mockk() - - every { criteriaBuilder.conjunction() } returns emptyPredicate - - // when - val actual = EmptyPredicateSpec.toCriteriaPredicate(froms, query, criteriaBuilder) - - // then - assertThat(actual).isEqualTo(emptyPredicate) - - verify(exactly = 1) { - criteriaBuilder.conjunction() - } - - confirmVerified(froms, query, criteriaBuilder) + toCriteriaPredicate { EmptyPredicateSpec.toCriteriaPredicate(froms, query, criteriaBuilder) } } @Test fun `update toCriteriaPredicate`() { + toCriteriaPredicate { EmptyPredicateSpec.toCriteriaPredicate(froms, updateQuery, criteriaBuilder) } + } + + @Test + fun `delete toCriteriaPredicate`() { + toCriteriaPredicate { EmptyPredicateSpec.toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) } + } + + private fun toCriteriaPredicate(predicate: () -> Predicate) { // given val emptyPredicate: Predicate = mockk() every { criteriaBuilder.conjunction() } returns emptyPredicate // when - val actual = EmptyPredicateSpec.toCriteriaPredicate(froms, updateQuery, criteriaBuilder) + val actual = predicate() // then assertThat(actual).isEqualTo(emptyPredicate) @@ -66,6 +60,6 @@ internal class EmptyPredicateSpecTest : WithKotlinJdslAssertions { criteriaBuilder.conjunction() } - confirmVerified(froms, updateQuery, criteriaBuilder) + confirmVerified(froms, query, criteriaBuilder) } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualExpressionSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualExpressionSpecTest.kt index 74c84d967..75f49eab7 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualExpressionSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualExpressionSpecTest.kt @@ -23,6 +23,9 @@ internal class EqualExpressionSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -87,4 +90,35 @@ internal class EqualExpressionSpecTest : WithKotlinJdslAssertions { criteriaBuilder.equal(leftExpression, rightExpression) } } + + @Test + fun `delete toCriteriaPredicate`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val rightExpressionSpec: ExpressionSpec = mockk() + + val leftExpression: Expression = mockk() + val rightExpression: Expression = mockk() + + val equalPredicate: Predicate = mockk() + + every { leftExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns leftExpression + every { rightExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns rightExpression + + every { criteriaBuilder.equal(leftExpression, rightExpression) } returns equalPredicate + + // when + val actual = EqualExpressionSpec(leftExpressionSpec, rightExpressionSpec) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(equalPredicate) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + rightExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + criteriaBuilder.equal(leftExpression, rightExpression) + } + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualValueSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualValueSpecTest.kt index abb290906..c86de420d 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualValueSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/EqualValueSpecTest.kt @@ -24,6 +24,9 @@ internal class EqualValueSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -82,4 +85,32 @@ internal class EqualValueSpecTest : WithKotlinJdslAssertions { confirmVerified(leftExpressionSpec, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaPredicate`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val right = 10 + + val leftExpression: Expression = mockk() + + val equalPredicate: Predicate = mockk() + + every { leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) } returns leftExpression + + every { criteriaBuilder.equal(any(), any()) } returns equalPredicate + + // when + val actual = EqualValueSpec(leftExpressionSpec, right).toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(equalPredicate) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.equal(leftExpression, right) + } + + confirmVerified(leftExpressionSpec, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanExpressionSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanExpressionSpecTest.kt index 0a01a77d6..62592d5a9 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanExpressionSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanExpressionSpecTest.kt @@ -24,6 +24,9 @@ internal class GreaterThanExpressionSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -178,4 +181,80 @@ internal class GreaterThanExpressionSpecTest : WithKotlinJdslAssertions { froms, updateQuery, criteriaBuilder ) } + + @Test + fun `delete toCriteriaPredicate - inclusive`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val rightExpressionSpec: ExpressionSpec = mockk() + + val leftExpression: Expression = mockk() + val rightExpression: Expression = mockk() + + val greaterThanOrEqualToPredicate: Predicate = mockk() + + every { leftExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns leftExpression + every { rightExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns rightExpression + + every { + criteriaBuilder.greaterThanOrEqualTo(any(), any>()) + } returns greaterThanOrEqualToPredicate + + // when + val actual = GreaterThanExpressionSpec(leftExpressionSpec, rightExpressionSpec, true) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(greaterThanOrEqualToPredicate) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + rightExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + criteriaBuilder.greaterThanOrEqualTo(leftExpression, rightExpression) + } + + confirmVerified( + leftExpressionSpec, + rightExpressionSpec, + froms, deleteQuery, criteriaBuilder + ) + } + + @Test + fun `delete toCriteriaPredicate - not inclusive`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val rightExpressionSpec: ExpressionSpec = mockk() + + val leftExpression: Expression = mockk() + val rightExpression: Expression = mockk() + + val greaterThanPredicate: Predicate = mockk() + + every { leftExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns leftExpression + every { rightExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns rightExpression + + every { criteriaBuilder.greaterThan(any(), any>()) } returns greaterThanPredicate + + // when + val actual = GreaterThanExpressionSpec(leftExpressionSpec, rightExpressionSpec, false) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(greaterThanPredicate) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + rightExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + criteriaBuilder.greaterThan(leftExpression, rightExpression) + } + + confirmVerified( + leftExpressionSpec, + rightExpressionSpec, + froms, deleteQuery, criteriaBuilder + ) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanValueSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanValueSpecTest.kt index b43ad6253..b014cd907 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanValueSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/GreaterThanValueSpecTest.kt @@ -24,6 +24,9 @@ internal class GreaterThanValueSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -142,4 +145,62 @@ internal class GreaterThanValueSpecTest : WithKotlinJdslAssertions { confirmVerified(froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaPredicate - inclusive`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val right = 10 + + val leftExpression: Expression = mockk() + + val greaterThanEqualToPredicate: Predicate = mockk() + + every { leftExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns leftExpression + + every { criteriaBuilder.greaterThanOrEqualTo(any(), any()) } returns greaterThanEqualToPredicate + + // when + val actual = GreaterThanValueSpec(leftExpressionSpec, right, true) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(greaterThanEqualToPredicate) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.greaterThanOrEqualTo(leftExpression, right) + } + + confirmVerified(froms, deleteQuery, criteriaBuilder) + } + + @Test + fun `delete toCriteriaPredicate - not inclusive`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val right = 10 + + val leftExpression: Expression = mockk() + + val greaterThanPredicate: Predicate = mockk() + + every { leftExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns leftExpression + + every { criteriaBuilder.greaterThan(any(), any()) } returns greaterThanPredicate + + // when + val actual = GreaterThanValueSpec(leftExpressionSpec, right, false) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(greaterThanPredicate) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.greaterThan(leftExpression, right) + } + + confirmVerified(froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InExpressionSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InExpressionSpecTest.kt index 996ecc1fe..39ec3af2f 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InExpressionSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InExpressionSpecTest.kt @@ -24,6 +24,9 @@ internal class InExpressionSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -164,6 +167,76 @@ internal class InExpressionSpecTest : WithKotlinJdslAssertions { criteriaBuilder.conjunction() } - confirmVerified(leftExpressionSpec, froms, query, criteriaBuilder) + confirmVerified(leftExpressionSpec, froms, updateQuery, criteriaBuilder) + } + + @Test + fun `delete toCriteriaPredicate`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val rightExpressionSpec1: ExpressionSpec = mockk() + val rightExpressionSpec2: ExpressionSpec = mockk() + + val leftExpression: Expression = mockk() + val rightExpression1: Expression = mockk() + val rightExpression2: Expression = mockk() + + val `in`: CriteriaBuilder.In = mockk() + + every { criteriaBuilder.`in`(any>()) } returns `in` + every { leftExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns leftExpression + every { rightExpressionSpec1.toCriteriaExpression(any(), any>(), any()) } returns rightExpression1 + every { rightExpressionSpec2.toCriteriaExpression(any(), any>(), any()) } returns rightExpression2 + + every { `in`.value(rightExpression1) } returns `in` + every { `in`.value(rightExpression2) } returns `in` + + // when + val actual = InExpressionSpec( + leftExpressionSpec, + listOf(rightExpressionSpec1, rightExpressionSpec2) + ).toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(`in`) + + verify(exactly = 1) { + criteriaBuilder.`in`(leftExpression) + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + rightExpressionSpec1.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + rightExpressionSpec2.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + `in`.value(rightExpression1) + `in`.value(rightExpression2) + } + + confirmVerified( + leftExpressionSpec, rightExpressionSpec1, rightExpressionSpec2, + froms, deleteQuery, criteriaBuilder, + ) + } + + @Test + fun `delete toCriteriaPredicate - empty rights`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + + val emptyPredicate: Predicate = mockk() + + every { criteriaBuilder.conjunction() } returns emptyPredicate + + // when + val actual = InExpressionSpec( + leftExpressionSpec, emptyList() + ).toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(emptyPredicate) + + verify(exactly = 1) { + criteriaBuilder.conjunction() + } + + confirmVerified(leftExpressionSpec, froms, deleteQuery, criteriaBuilder) } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InValueSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InValueSpecTest.kt index 570fec7c9..a9b2af4d0 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InValueSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/InValueSpecTest.kt @@ -24,6 +24,9 @@ internal class InValueSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -140,4 +143,61 @@ internal class InValueSpecTest : WithKotlinJdslAssertions { confirmVerified(froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaPredicate`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val right1 = 10 + val right2 = 20 + + val leftExpression: Expression = mockk() + + val `in`: CriteriaBuilder.In = mockk() + + every { leftExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns leftExpression + + every { criteriaBuilder.`in`(any>()) } returns `in` + every { `in`.value(right1) } returns `in` + every { `in`.value(right2) } returns `in` + + // when + val actual = InValueSpec(leftExpressionSpec, listOf(right1, right2)) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(`in`) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.`in`(leftExpression) + `in`(right1) + `in`(right2) + } + + confirmVerified(leftExpressionSpec, froms, deleteQuery, criteriaBuilder) + } + + @Test + fun `delete toCriteriaPredicate - empty rights`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + + val emptyPredicate: Predicate = mockk() + + every { criteriaBuilder.conjunction() } returns emptyPredicate + + // when + val actual = InValueSpec(leftExpressionSpec, emptyList()) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(emptyPredicate) + + verify(exactly = 1) { + criteriaBuilder.conjunction() + } + + confirmVerified(froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsFalseSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsFalseSpecTest.kt index 2ad5e2026..89602a075 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsFalseSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsFalseSpecTest.kt @@ -24,6 +24,9 @@ internal class IsFalseSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -78,4 +81,30 @@ internal class IsFalseSpecTest : WithKotlinJdslAssertions { confirmVerified(expressionSpec, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaPredicate`() { + // given + val expressionSpec: ExpressionSpec = mockk() + + val expression: Expression = mockk() + + val isFalsePredicate: Predicate = mockk() + + every { expressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) } returns expression + every { criteriaBuilder.isFalse(expression) } returns isFalsePredicate + + // when + val actual = IsFalseSpec(expressionSpec).toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(isFalsePredicate) + + verify(exactly = 1) { + expressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.isFalse(expression) + } + + confirmVerified(expressionSpec, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsNullSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsNullSpecTest.kt index 14dd4e0d3..eddbf8a70 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsNullSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsNullSpecTest.kt @@ -24,6 +24,9 @@ internal class IsNullSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -78,4 +81,30 @@ internal class IsNullSpecTest : WithKotlinJdslAssertions { confirmVerified(expressionSpec, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaPredicate`() { + // given + val expressionSpec: ExpressionSpec = mockk() + + val expression: Expression = mockk() + + val isNullPredicate: Predicate = mockk() + + every { expressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) } returns expression + every { criteriaBuilder.isNull(expression) } returns isNullPredicate + + // when + val actual = IsNullSpec(expressionSpec).toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(isNullPredicate) + + verify(exactly = 1) { + expressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.isNull(expression) + } + + confirmVerified(expressionSpec, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsTrueSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsTrueSpecTest.kt index 2b4bbb3c8..eb5291065 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsTrueSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/IsTrueSpecTest.kt @@ -24,6 +24,9 @@ internal class IsTrueSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -78,4 +81,30 @@ internal class IsTrueSpecTest : WithKotlinJdslAssertions { confirmVerified(expressionSpec, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaPredicate`() { + // given + val expressionSpec: ExpressionSpec = mockk() + + val expression: Expression = mockk() + + val isTruePredicate: Predicate = mockk() + + every { expressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) } returns expression + every { criteriaBuilder.isTrue(expression) } returns isTruePredicate + + // when + val actual = IsTrueSpec(expressionSpec).toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(isTruePredicate) + + verify(exactly = 1) { + expressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.isTrue(expression) + } + + confirmVerified(expressionSpec, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanExpressionSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanExpressionSpecTest.kt index 770a28c28..8ef78724b 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanExpressionSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanExpressionSpecTest.kt @@ -24,6 +24,9 @@ internal class LessThanExpressionSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -178,4 +181,80 @@ internal class LessThanExpressionSpecTest : WithKotlinJdslAssertions { froms, updateQuery, criteriaBuilder ) } + + @Test + fun `delete toCriteriaPredicate - inclusive`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val rightExpressionSpec: ExpressionSpec = mockk() + + val leftExpression: Expression = mockk() + val rightExpression: Expression = mockk() + + val lessThanOrEqualToPredicate: Predicate = mockk() + + every { leftExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns leftExpression + every { rightExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns rightExpression + + every { + criteriaBuilder.lessThanOrEqualTo(any(), any>()) + } returns lessThanOrEqualToPredicate + + // when + val actual = LessThanExpressionSpec(leftExpressionSpec, rightExpressionSpec, true) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(lessThanOrEqualToPredicate) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + rightExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + criteriaBuilder.lessThanOrEqualTo(leftExpression, rightExpression) + } + + confirmVerified( + leftExpressionSpec, + rightExpressionSpec, + froms, deleteQuery, criteriaBuilder + ) + } + + @Test + fun `delete toCriteriaPredicate - not inclusive`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val rightExpressionSpec: ExpressionSpec = mockk() + + val leftExpression: Expression = mockk() + val rightExpression: Expression = mockk() + + val lessThanPredicate: Predicate = mockk() + + every { leftExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns leftExpression + every { rightExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns rightExpression + + every { criteriaBuilder.lessThan(any(), any>()) } returns lessThanPredicate + + // when + val actual = LessThanExpressionSpec(leftExpressionSpec, rightExpressionSpec, false) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(lessThanPredicate) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + rightExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + + criteriaBuilder.lessThan(leftExpression, rightExpression) + } + + confirmVerified( + leftExpressionSpec, + rightExpressionSpec, + froms, deleteQuery, criteriaBuilder + ) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanValueSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanValueSpecTest.kt index e2678f2a0..820b815d2 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanValueSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LessThanValueSpecTest.kt @@ -24,6 +24,9 @@ internal class LessThanValueSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -142,4 +145,62 @@ internal class LessThanValueSpecTest : WithKotlinJdslAssertions { confirmVerified(froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaPredicate - inclusive`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val right = 10 + + val leftExpression: Expression = mockk() + + val lessThanEqualToPredicate: Predicate = mockk() + + every { leftExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns leftExpression + + every { criteriaBuilder.lessThanOrEqualTo(any(), any()) } returns lessThanEqualToPredicate + + // when + val actual = LessThanValueSpec(leftExpressionSpec, right, true) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(lessThanEqualToPredicate) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.lessThanOrEqualTo(leftExpression, right) + } + + confirmVerified(froms, deleteQuery, criteriaBuilder) + } + + @Test + fun `delete toCriteriaPredicate - not inclusive`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val right = 10 + + val leftExpression: Expression = mockk() + + val lessThanPredicate: Predicate = mockk() + + every { leftExpressionSpec.toCriteriaExpression(any(), any>(), any()) } returns leftExpression + + every { criteriaBuilder.lessThan(any(), any()) } returns lessThanPredicate + + // when + val actual = LessThanValueSpec(leftExpressionSpec, right, false) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(lessThanPredicate) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.lessThan(leftExpression, right) + } + + confirmVerified(froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LikeSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LikeSpecTest.kt index 1895a7b38..c75f90e93 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LikeSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/LikeSpecTest.kt @@ -24,6 +24,9 @@ internal class LikeSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -80,4 +83,31 @@ internal class LikeSpecTest : WithKotlinJdslAssertions { confirmVerified(leftExpressionSpec, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaPredicate`() { + // given + val leftExpressionSpec: ExpressionSpec = mockk() + val right = "%test%" + + val likeExpression: Expression = mockk() + + val likePredicate: Predicate = mockk() + + every { leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) } returns likeExpression + every { criteriaBuilder.like(likeExpression, right) } returns likePredicate + + // when + val actual = LikeSpec(leftExpressionSpec, right).toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(likePredicate) + + verify(exactly = 1) { + leftExpressionSpec.toCriteriaExpression(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.like(likeExpression, right) + } + + confirmVerified(leftExpressionSpec, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/NotSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/NotSpecTest.kt index d368800e4..a1715da50 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/NotSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/NotSpecTest.kt @@ -10,10 +10,7 @@ import io.mockk.mockk import io.mockk.verify import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* @ExtendWith(MockKExtension::class) internal class NotSpecTest : WithKotlinJdslAssertions { @@ -26,6 +23,9 @@ internal class NotSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -78,4 +78,29 @@ internal class NotSpecTest : WithKotlinJdslAssertions { confirmVerified(predicateSpec, froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaPredicate`() { + // given + val predicateSpec: PredicateSpec = mockk() + val predicate: Predicate = mockk() + + val notPredicate: Predicate = mockk() + + every { predicateSpec.toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) } returns predicate + every { criteriaBuilder.not(predicate) } returns notPredicate + + // when + val actual = NotSpec(predicateSpec).toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(notPredicate) + + verify(exactly = 1) { + predicateSpec.toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.not(predicate) + } + + confirmVerified(predicateSpec, froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/OrSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/OrSpecTest.kt index a6c9083db..f3c011d18 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/OrSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/OrSpecTest.kt @@ -23,6 +23,9 @@ internal class OrSpecTest : WithKotlinJdslAssertions { @MockK private lateinit var updateQuery: CriteriaUpdate<*> + @MockK + private lateinit var deleteQuery: CriteriaDelete<*> + @MockK private lateinit var criteriaBuilder: CriteriaBuilder @@ -135,4 +138,59 @@ internal class OrSpecTest : WithKotlinJdslAssertions { confirmVerified(froms, updateQuery, criteriaBuilder) } + + @Test + fun `delete toCriteriaPredicate`() { + // given + val predicateSpec1: PredicateSpec = mockk() + val predicateSpec2: PredicateSpec = mockk() + val predicateSpec3: PredicateSpec? = null + + val predicate1: Predicate = mockk() + val predicate2: Predicate = mockk() + val orPredicate: Predicate = mockk() + + every { predicateSpec1.toCriteriaPredicate(any(), any>(), any()) } returns predicate1 + every { predicateSpec2.toCriteriaPredicate(any(), any>(), any()) } returns predicate2 + + every { criteriaBuilder.or(any(), any()) } returns orPredicate + + // when + val actual = OrSpec(listOf(predicateSpec1, predicateSpec2, predicateSpec3)) + .toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(orPredicate) + + verify(exactly = 1) { + predicateSpec1.toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + predicateSpec2.toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + criteriaBuilder.or(predicate1, predicate2) + } + + confirmVerified(predicateSpec1, predicateSpec2, froms, deleteQuery, criteriaBuilder) + } + + @Test + fun `delete toCriteriaPredicate - if predicate is empty then return conjunction`() { + // given + val predicateSpec1: PredicateSpec? = null + val predicateSpec2: PredicateSpec? = null + + val andPredicate: Predicate = mockk() + + every { criteriaBuilder.conjunction() } returns andPredicate + + // when + val actual = OrSpec(listOf(predicateSpec1, predicateSpec2)).toCriteriaPredicate(froms, deleteQuery, criteriaBuilder) + + // then + assertThat(actual).isEqualTo(andPredicate) + + verify(exactly = 1) { + criteriaBuilder.conjunction() + } + + confirmVerified(froms, deleteQuery, criteriaBuilder) + } } diff --git a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/PredicateSpecTest.kt b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/PredicateSpecTest.kt index 265630fcc..1f8baed91 100644 --- a/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/PredicateSpecTest.kt +++ b/query/src/test/kotlin/com/linecorp/kotlinjdsl/query/spec/predicate/PredicateSpecTest.kt @@ -3,10 +3,7 @@ package com.linecorp.kotlinjdsl.query.spec.predicate import com.linecorp.kotlinjdsl.query.spec.Froms import com.linecorp.kotlinjdsl.test.WithKotlinJdslAssertions import org.junit.jupiter.api.Test -import javax.persistence.criteria.AbstractQuery -import javax.persistence.criteria.CriteriaBuilder -import javax.persistence.criteria.CriteriaUpdate -import javax.persistence.criteria.Predicate +import javax.persistence.criteria.* internal class PredicateSpecTest : WithKotlinJdslAssertions { private val predicateSpec1: PredicateSpec = object : PredicateSpec { @@ -25,6 +22,14 @@ internal class PredicateSpecTest : WithKotlinJdslAssertions { ): Predicate { return criteriaBuilder.conjunction() } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + return criteriaBuilder.conjunction() + } } private val predicateSpec2: PredicateSpec = object : PredicateSpec { @@ -43,6 +48,14 @@ internal class PredicateSpecTest : WithKotlinJdslAssertions { ): Predicate { return criteriaBuilder.conjunction() } + + override fun toCriteriaPredicate( + froms: Froms, + query: CriteriaDelete<*>, + criteriaBuilder: CriteriaBuilder + ): Predicate { + return criteriaBuilder.conjunction() + } } @Test diff --git a/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactory.kt b/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactory.kt index 4e5b0de63..80ada1371 100644 --- a/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactory.kt +++ b/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactory.kt @@ -2,10 +2,7 @@ package com.linecorp.kotlinjdsl.spring.data import com.linecorp.kotlinjdsl.query.clause.select.SingleSelectClause import com.linecorp.kotlinjdsl.query.spec.expression.SubqueryExpressionSpec -import com.linecorp.kotlinjdsl.querydsl.CriteriaUpdateQueryDsl -import com.linecorp.kotlinjdsl.spring.data.querydsl.SpringDataCriteriaQueryDsl -import com.linecorp.kotlinjdsl.spring.data.querydsl.SpringDataPageableQueryDsl -import com.linecorp.kotlinjdsl.spring.data.querydsl.SpringDataSubqueryDsl +import com.linecorp.kotlinjdsl.spring.data.querydsl.* import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable import javax.persistence.Query @@ -18,7 +15,8 @@ interface SpringDataQueryFactory { selectQuery(returnType, dsl) fun selectQuery(returnType: Class, dsl: SpringDataCriteriaQueryDsl.() -> Unit): TypedQuery - fun updateQuery(returnType: KClass, dsl: CriteriaUpdateQueryDsl.() -> Unit): Query + fun updateQuery(target: KClass, dsl: SpringDataCriteriaUpdateQueryDsl.() -> Unit): Query + fun deleteQuery(target: KClass, dsl: SpringDataCriteriaDeleteQueryDsl.() -> Unit): Query fun subquery(returnType: Class, dsl: SpringDataSubqueryDsl.() -> Unit): SubqueryExpressionSpec fun pageQuery(returnType: Class, pageable: Pageable, dsl: SpringDataPageableQueryDsl.() -> Unit): Page fun pageQuery( diff --git a/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryExtensions.kt b/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryExtensions.kt index a0c963de9..9e1b344d8 100644 --- a/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryExtensions.kt +++ b/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryExtensions.kt @@ -1,9 +1,10 @@ package com.linecorp.kotlinjdsl.spring.data +import com.linecorp.kotlinjdsl.QueryFactory import com.linecorp.kotlinjdsl.query.clause.select.SingleSelectClause -import com.linecorp.kotlinjdsl.spring.data.querydsl.SpringDataCriteriaQueryDsl -import com.linecorp.kotlinjdsl.spring.data.querydsl.SpringDataPageableQueryDsl -import com.linecorp.kotlinjdsl.spring.data.querydsl.SpringDataSubqueryDsl +import com.linecorp.kotlinjdsl.querydsl.CriteriaDeleteQueryDsl +import com.linecorp.kotlinjdsl.querydsl.CriteriaUpdateQueryDsl +import com.linecorp.kotlinjdsl.spring.data.querydsl.* import org.springframework.data.domain.Pageable import java.util.stream.Stream @@ -26,6 +27,12 @@ inline fun SpringDataQueryFactory.typedQuery(noinline dsl: SpringDat inline fun SpringDataQueryFactory.selectQuery(noinline dsl: SpringDataCriteriaQueryDsl.() -> Unit) = selectQuery(T::class.java, dsl) +inline fun SpringDataQueryFactory.updateQuery(noinline dsl: SpringDataCriteriaUpdateQueryDsl.() -> Unit) = + updateQuery(T::class, dsl) + +inline fun SpringDataQueryFactory.deleteQuery(noinline dsl: SpringDataCriteriaDeleteQueryDsl.() -> Unit) = + deleteQuery(T::class, dsl) + inline fun SpringDataQueryFactory.subquery(noinline dsl: SpringDataSubqueryDsl.() -> Unit) = subquery(T::class.java, dsl) diff --git a/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryImpl.kt b/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryImpl.kt index e27636b01..2fb7803fc 100644 --- a/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryImpl.kt +++ b/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryImpl.kt @@ -5,10 +5,7 @@ import com.linecorp.kotlinjdsl.query.creator.CriteriaQueryCreator import com.linecorp.kotlinjdsl.query.creator.SubqueryCreator import com.linecorp.kotlinjdsl.query.spec.expression.SubqueryExpressionSpec import com.linecorp.kotlinjdsl.querydsl.CriteriaUpdateQueryDsl -import com.linecorp.kotlinjdsl.spring.data.querydsl.SpringDataCriteriaQueryDsl -import com.linecorp.kotlinjdsl.spring.data.querydsl.SpringDataPageableQueryDsl -import com.linecorp.kotlinjdsl.spring.data.querydsl.SpringDataQueryDslImpl -import com.linecorp.kotlinjdsl.spring.data.querydsl.SpringDataSubqueryDsl +import com.linecorp.kotlinjdsl.spring.data.querydsl.* import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable import org.springframework.data.support.PageableExecutionUtils @@ -29,14 +26,20 @@ class SpringDataQueryFactoryImpl( return criteriaQueryCreator.createQuery(criteriaQuerySpec) } - override fun updateQuery(returnType: KClass, dsl: CriteriaUpdateQueryDsl.() -> Unit): Query { - val criteriaQuerySpec = SpringDataQueryDslImpl(returnType.java).apply(dsl).apply { - from(returnType) + override fun updateQuery(target: KClass, dsl: SpringDataCriteriaUpdateQueryDsl.() -> Unit): Query { + val criteriaQuerySpec = SpringDataQueryDslImpl(target.java).apply(dsl).apply { + from(target) }.createCriteriaUpdateQuerySpec() return criteriaQueryCreator.createQuery(criteriaQuerySpec) } + override fun deleteQuery(target: KClass, dsl: SpringDataCriteriaDeleteQueryDsl.() -> Unit): Query { + return criteriaQueryCreator.createQuery( + SpringDataQueryDslImpl(target.java).apply(dsl).apply { from(target) }.createCriteriaDeleteQuerySpec() + ) + } + override fun subquery( returnType: Class, dsl: SpringDataSubqueryDsl.() -> Unit diff --git a/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/querydsl/SpringDataCriteriaDeleteQueryDsl.kt b/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/querydsl/SpringDataCriteriaDeleteQueryDsl.kt new file mode 100644 index 000000000..e32900beb --- /dev/null +++ b/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/querydsl/SpringDataCriteriaDeleteQueryDsl.kt @@ -0,0 +1,6 @@ +package com.linecorp.kotlinjdsl.spring.data.querydsl + +import com.linecorp.kotlinjdsl.querydsl.CriteriaDeleteQueryDsl +import com.linecorp.kotlinjdsl.spring.data.querydsl.predicate.SpringDataPredicateDsl + +interface SpringDataCriteriaDeleteQueryDsl : CriteriaDeleteQueryDsl, SpringDataPredicateDsl diff --git a/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/querydsl/SpringDataCriteriaUpdateQueryDsl.kt b/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/querydsl/SpringDataCriteriaUpdateQueryDsl.kt new file mode 100644 index 000000000..913e9bfd2 --- /dev/null +++ b/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/querydsl/SpringDataCriteriaUpdateQueryDsl.kt @@ -0,0 +1,8 @@ +package com.linecorp.kotlinjdsl.spring.data.querydsl + +import com.linecorp.kotlinjdsl.querydsl.CriteriaUpdateQueryDsl +import com.linecorp.kotlinjdsl.spring.data.querydsl.predicate.SpringDataPredicateDsl + +interface SpringDataCriteriaUpdateQueryDsl : + CriteriaUpdateQueryDsl, + SpringDataPredicateDsl diff --git a/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/querydsl/SpringDataQueryDslImpl.kt b/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/querydsl/SpringDataQueryDslImpl.kt index a1258bb23..16e5fab50 100644 --- a/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/querydsl/SpringDataQueryDslImpl.kt +++ b/spring/data-core/src/main/kotlin/com/linecorp/kotlinjdsl/spring/data/querydsl/SpringDataQueryDslImpl.kt @@ -18,7 +18,7 @@ import org.springframework.data.domain.Pageable class SpringDataQueryDslImpl( returnType: Class, ) : QueryDslImpl(returnType), - SpringDataCriteriaQueryDsl, SpringDataSubqueryDsl, SpringDataPageableQueryDsl { + SpringDataCriteriaQueryDsl, SpringDataSubqueryDsl, SpringDataPageableQueryDsl, SpringDataCriteriaUpdateQueryDsl, SpringDataCriteriaDeleteQueryDsl { var pageable: Pageable = Pageable.unpaged() fun createPageableQuerySpec(): CriteriaQuerySpec { diff --git a/spring/data-core/src/test/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryExtensionsTest.kt b/spring/data-core/src/test/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryExtensionsTest.kt index a48bdca99..cfe0a00e5 100644 --- a/spring/data-core/src/test/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryExtensionsTest.kt +++ b/spring/data-core/src/test/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryExtensionsTest.kt @@ -4,9 +4,7 @@ import com.linecorp.kotlinjdsl.query.clause.select.SingleSelectClause import com.linecorp.kotlinjdsl.query.spec.expression.SubqueryExpressionSpec import com.linecorp.kotlinjdsl.querydsl.expression.col import com.linecorp.kotlinjdsl.querydsl.expression.column -import com.linecorp.kotlinjdsl.spring.data.querydsl.SpringDataCriteriaQueryDsl -import com.linecorp.kotlinjdsl.spring.data.querydsl.SpringDataPageableQueryDsl -import com.linecorp.kotlinjdsl.spring.data.querydsl.SpringDataSubqueryDsl +import com.linecorp.kotlinjdsl.spring.data.querydsl.* import com.linecorp.kotlinjdsl.test.WithKotlinJdslAssertions import com.linecorp.kotlinjdsl.test.entity.order.Order import io.mockk.confirmVerified @@ -19,6 +17,7 @@ import org.junit.jupiter.api.extension.ExtendWith import org.springframework.data.domain.Page import org.springframework.data.domain.PageRequest import java.util.stream.Stream +import javax.persistence.Query import javax.persistence.TypedQuery import kotlin.streams.toList @@ -87,7 +86,7 @@ internal class SpringDataQueryFactoryExtensionsTest : WithKotlinJdslAssertions { } @Test - fun typedQuery() { + fun selectQuery() { // given every { queryFactory.selectQuery(any(), any()) } returns typedQuery @@ -97,7 +96,7 @@ internal class SpringDataQueryFactoryExtensionsTest : WithKotlinJdslAssertions { } // when - val actual: TypedQuery = queryFactory.typedQuery(dsl) + val actual: TypedQuery = queryFactory.selectQuery(dsl) // then assertThat(actual).isEqualTo(typedQuery) @@ -109,6 +108,51 @@ internal class SpringDataQueryFactoryExtensionsTest : WithKotlinJdslAssertions { confirmVerified(queryFactory) } + @Test + fun updateQuery() { + // given + every { queryFactory.updateQuery(any(), any()) } returns typedQuery + + val dsl: SpringDataCriteriaUpdateQueryDsl.() -> Unit = { + set(col(Data1::id), 1) + where(col(Data1::id).equal(2)) + } + + // when + val actual: Query = queryFactory.updateQuery(dsl) + + // then + assertThat(actual).isEqualTo(typedQuery) + + verify(exactly = 1) { + queryFactory.updateQuery(Data1::class, dsl) + } + + confirmVerified(queryFactory) + } + + @Test + fun deleteQuery() { + // given + every { queryFactory.deleteQuery(any(), any()) } returns typedQuery + + val dsl: SpringDataCriteriaDeleteQueryDsl.() -> Unit = { + where(col(Data1::id).equal(1)) + } + + // when + val actual: Query = queryFactory.deleteQuery(dsl) + + // then + assertThat(actual).isEqualTo(typedQuery) + + verify(exactly = 1) { + queryFactory.deleteQuery(Data1::class, dsl) + } + + confirmVerified(queryFactory) + } + @Test fun subquery() { // given diff --git a/spring/data-core/src/test/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryImplTest.kt b/spring/data-core/src/test/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryImplTest.kt index e990b18a8..8b0acabc5 100644 --- a/spring/data-core/src/test/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryImplTest.kt +++ b/spring/data-core/src/test/kotlin/com/linecorp/kotlinjdsl/spring/data/SpringDataQueryFactoryImplTest.kt @@ -132,6 +132,38 @@ internal class SpringDataQueryFactoryImplTest : WithKotlinJdslAssertions { confirmVerified(criteriaQueryCreator) } + @Test + fun deleteQuery() { + // given + val query: Query = mockk() + + every { criteriaQueryCreator.createQuery(any>()) } returns query + + // when + val actual = sut.deleteQuery(Data1::class) { + where(col(Data1::id).equal(1)) + } + + // then + assertThat(actual).isEqualTo(query) + + verify(exactly = 1) { + val columnSpec = ColumnSpec(EntitySpec(Data1::class.java), Data1::id.name) + criteriaQueryCreator.createQuery( + QueryDslImpl.CriteriaDeleteQuerySpecImpl( + from = FromClause(EntitySpec(Data1::class.java)), + associate = SimpleAssociatedJoinClause(emptyList()), + where = WhereClause(EqualValueSpec(columnSpec, 1)), + jpaHint = JpaQueryHintClauseImpl(emptyMap()), + sqlHint = EmptySqlQueryHintClause, + targetEntity = Data1::class.java + ) + ) + } + + confirmVerified(criteriaQueryCreator) + } + @Test fun subquery() { // when diff --git a/test-fixture/integration/src/main/kotlin/com/linecorp/kotlinjdsl/test/integration/criteriaquery/AbstractCriteriaDeleteIntegrationTest.kt b/test-fixture/integration/src/main/kotlin/com/linecorp/kotlinjdsl/test/integration/criteriaquery/AbstractCriteriaDeleteIntegrationTest.kt new file mode 100644 index 000000000..d00ffdfb6 --- /dev/null +++ b/test-fixture/integration/src/main/kotlin/com/linecorp/kotlinjdsl/test/integration/criteriaquery/AbstractCriteriaDeleteIntegrationTest.kt @@ -0,0 +1,75 @@ +package com.linecorp.kotlinjdsl.test.integration.criteriaquery + +import com.linecorp.kotlinjdsl.deleteQuery +import com.linecorp.kotlinjdsl.querydsl.expression.col +import com.linecorp.kotlinjdsl.selectQuery +import com.linecorp.kotlinjdsl.test.entity.Address +import com.linecorp.kotlinjdsl.test.entity.order.OrderAddress +import com.linecorp.kotlinjdsl.test.integration.AbstractCriteriaQueryDslIntegrationTest +import org.junit.jupiter.api.Test + +abstract class AbstractCriteriaDeleteIntegrationTest : AbstractCriteriaQueryDslIntegrationTest() { + @Test + fun delete() { + // when + val address1 = orderAddress { } + + entityManager.run { + persist(address1) + flush(); clear() + } + + queryFactory.deleteQuery { + where(col(OrderAddress::id).equal(address1.id)) + }.executeUpdate() + + // when + val query = queryFactory.selectQuery { + select(entity(OrderAddress::class)) + from(entity(OrderAddress::class)) + where(col(OrderAddress::id).equal(address1.id),) + associate(OrderAddress::class, Address::class, on(OrderAddress::address)) + } + + // then + assertThat(query.resultList).isEmpty() + } + + @Test + fun deleteEmbedded() { + // given + val address1 = orderAddress { } + + entityManager.run { + persist(address1) + flush(); clear() + } + + queryFactory.deleteQuery { + where( + and( + col(OrderAddress::id).equal(address1.id), + col(Address::zipCode).equal(address1.address.zipCode), + ) + ) + associate(OrderAddress::class, Address::class, on(OrderAddress::address)) + }.executeUpdate() + + // when + val query = queryFactory.selectQuery { + select(entity(OrderAddress::class)) + from(entity(OrderAddress::class)) + where( + and( + col(OrderAddress::id).equal(address1.id), + col(Address::zipCode).equal(address1.address.zipCode), + ) + ) + associate(OrderAddress::class, Address::class, on(OrderAddress::address)) + } + + // then + assertThat(query.resultList).isEmpty() + + } +}