From 1ccf93624c86bb9c09a163ad7d8e6f05421b75d7 Mon Sep 17 00:00:00 2001 From: Hyunsik Kang Date: Sat, 5 Jul 2025 10:00:28 +0900 Subject: [PATCH 1/4] feat: implement cast, right, left, replace expressions --- docs/en/jpql-with-kotlin-jdsl/expressions.md | 16 ++ docs/ko/jpql-with-kotlin-jdsl/expressions.md | 16 ++ .../com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt | 72 ++++++++ .../dsl/jpql/expression/ExpressionDslTest.kt | 154 ++++++++++++++++++ .../querymodel/jpql/expression/Expressions.kt | 40 +++++ .../jpql/expression/impl/JpqlCast.kt | 11 ++ .../jpql/expression/impl/JpqlLeft.kt | 10 ++ .../jpql/expression/impl/JpqlReplace.kt | 11 ++ .../jpql/expression/impl/JpqlRight.kt | 10 ++ .../render/jpql/JpqlRenderContext.kt | 8 + .../serializer/impl/JpqlCastSerializer.kt | 27 +++ .../serializer/impl/JpqlLeftSerializer.kt | 27 +++ .../serializer/impl/JpqlReplaceSerializer.kt | 29 ++++ .../serializer/impl/JpqlRightSerializer.kt | 27 +++ .../serializer/impl/JpqlCastSerializerTest.kt | 56 +++++++ .../serializer/impl/JpqlLeftSerializerTest.kt | 56 +++++++ .../impl/JpqlReplaceSerializerTest.kt | 62 +++++++ .../impl/JpqlRightSerializerTest.kt | 56 +++++++ 18 files changed, 688 insertions(+) create mode 100644 query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlCast.kt create mode 100644 query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlLeft.kt create mode 100644 query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlReplace.kt create mode 100644 query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlRight.kt create mode 100644 render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlCastSerializer.kt create mode 100644 render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLeftSerializer.kt create mode 100644 render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializer.kt create mode 100644 render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlRightSerializer.kt create mode 100644 render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlCastSerializerTest.kt create mode 100644 render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLeftSerializerTest.kt create mode 100644 render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializerTest.kt create mode 100644 render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlRightSerializerTest.kt diff --git a/docs/en/jpql-with-kotlin-jdsl/expressions.md b/docs/en/jpql-with-kotlin-jdsl/expressions.md index ac9dddb34..3b15c1d54 100644 --- a/docs/en/jpql-with-kotlin-jdsl/expressions.md +++ b/docs/en/jpql-with-kotlin-jdsl/expressions.md @@ -199,6 +199,10 @@ Kotlin JDSL provides a series of functions to support built-in functions in JPA. * UPPER (upper) * LENGTH (length) * LOCATE (locate) +* CAST (cast) - *Added in JPA 3.2* +* LEFT (left) - *Added in JPA 3.2* +* RIGHT (right) - *Added in JPA 3.2* +* REPLACE (replace) - *Added in JPA 3.2* ```kotlin concat(path(Book::title), literal(":"), path(Book::imageUrl)) @@ -215,6 +219,18 @@ upper(path(Book::title)) length(path(Book::title)) locate("Book", path(Book::title)) + +cast(path(Book::price), String::class) +cast(path(Book::price)) + +left(path(Book::title), 3) +left(path(Book::title), literal(3)) + +right(path(Book::title), 3) +right(path(Book::title), literal(3)) + +replace(path(Book::title), "old", "new") +replace(path(Book::title), literal("old"), literal("new")) ``` ### Arithmetic functions diff --git a/docs/ko/jpql-with-kotlin-jdsl/expressions.md b/docs/ko/jpql-with-kotlin-jdsl/expressions.md index 42f7d3bbf..64e395c87 100644 --- a/docs/ko/jpql-with-kotlin-jdsl/expressions.md +++ b/docs/ko/jpql-with-kotlin-jdsl/expressions.md @@ -197,6 +197,10 @@ Kotlin JDSL은 JPA에서 제공하는 여러 함수들을 지원하기 위한 * UPPER (upper) * LENGTH (length) * LOCATE (locate) +* CAST (cast) - *JPA 3.2에 추가됨* +* LEFT (left) - *JPA 3.2에 추가됨* +* RIGHT (right) - *JPA 3.2에 추가됨* +* REPLACE (replace) - *JPA 3.2에 추가됨* ```kotlin concat(path(Book::title), literal(":"), path(Book::imageUrl)) @@ -213,6 +217,18 @@ upper(path(Book::title)) length(path(Book::title)) locate("Book", path(Book::title)) + +cast(path(Book::price), String::class) +cast(path(Book::price)) + +left(path(Book::title), 3) +left(path(Book::title), literal(3)) + +right(path(Book::title), 3) +right(path(Book::title), literal(3)) + +replace(path(Book::title), "old", "new") +replace(path(Book::title), literal("old"), literal("new")) ``` ### Arithmetic functions diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt index d3c17d1f1..0045e6208 100644 --- a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt @@ -1705,6 +1705,78 @@ open class Jpql : JpqlDsl { ) } + /** + * Creates an expression that represents the casting of a value to a different type. + */ + @SinceJdsl("3.6.0") + fun cast(value: Expressionable<*>, type: KClass): Expression { + return Expressions.cast(value.toExpression(), type) + } + + /** + * Creates an expression that represents the casting of a value to a different type. + */ + @SinceJdsl("3.6.0") + inline fun cast(value: Expressionable<*>): Expression { + return Expressions.cast(value.toExpression(), T::class) + } + + /** + * Creates an expression that returns the leftmost count characters from a string. + */ + @SinceJdsl("3.6.0") + fun left(value: Expressionable, count: Expressionable): Expression { + return Expressions.left(value.toExpression(), count.toExpression()) + } + + /** + * Creates an expression that returns the leftmost count characters from a string. + */ + @SinceJdsl("3.6.0") + fun left(value: Expressionable, count: Int): Expression { + return Expressions.left(value.toExpression(), intLiteral(count)) + } + + /** + * Creates an expression that returns the rightmost count characters from a string. + */ + @SinceJdsl("3.6.0") + fun right(value: Expressionable, count: Expressionable): Expression { + return Expressions.right(value.toExpression(), count.toExpression()) + } + + /** + * Creates an expression that returns the rightmost count characters from a string. + */ + @SinceJdsl("3.6.0") + fun right(value: Expressionable, count: Int): Expression { + return Expressions.right(value.toExpression(), intLiteral(count)) + } + + /** + * Creates an expression that replaces all occurrences of a search string with a replacement string. + */ + @SinceJdsl("3.6.0") + fun replace( + value: Expressionable, + search: Expressionable, + replacement: Expressionable, + ): Expression { + return Expressions.replace(value.toExpression(), search.toExpression(), replacement.toExpression()) + } + + /** + * Creates an expression that replaces all occurrences of a search string with a replacement string. + */ + @SinceJdsl("3.6.0") + fun replace( + value: Expressionable, + search: String, + replacement: String, + ): Expression { + return Expressions.replace(value.toExpression(), stringLiteral(search), stringLiteral(replacement)) + } + /** * Creates an expression that represents predefined database functions and user-defined database functions. */ diff --git a/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/ExpressionDslTest.kt b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/ExpressionDslTest.kt index f7b18100a..1032eb2aa 100644 --- a/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/ExpressionDslTest.kt +++ b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/ExpressionDslTest.kt @@ -44,4 +44,158 @@ class ExpressionDslTest : WithAssertions { assertThat(actual).isEqualTo(expected) } + + @Test + fun `cast() with a expression and a class`() { + // when + val expression = queryPart { + cast(expression(String::class, alias1), Int::class) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.cast( + Expressions.expression(String::class, alias1), + Int::class, + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `inline cast() with a expression and a class`() { + // when + val expression = queryPart { + cast(expression(String::class, alias1)) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.cast( + Expressions.expression(String::class, alias1), + Int::class, + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `left() with two expressions`() { + // when + val expression = queryPart { + left(expression(String::class, alias1), expression(Int::class, "alias2")) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.left( + Expressions.expression(String::class, alias1), + Expressions.expression(Int::class, "alias2"), + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `left() literal with two expressions`() { + // when + val expression = queryPart { + left(expression(String::class, alias1), 1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.left( + Expressions.expression(String::class, alias1), + Expressions.intLiteral(1), + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `right() with two expressions`() { + // when + val expression = queryPart { + right(expression(String::class, alias1), expression(Int::class, "alias2")) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.right( + Expressions.expression(String::class, alias1), + Expressions.expression(Int::class, "alias2"), + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `right() literal with two expressions`() { + // when + val expression = queryPart { + right(expression(String::class, alias1), 1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.right( + Expressions.expression(String::class, alias1), + Expressions.intLiteral(1), + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `replace() with three expressions`() { + // when + val expression = queryPart { + replace( + expression(String::class, alias1), + expression(String::class, "alias2"), + expression(String::class, "alias3"), + ) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.replace( + Expressions.expression(String::class, alias1), + Expressions.expression(String::class, "alias2"), + Expressions.expression(String::class, "alias3"), + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `replace() literal with three expressions`() { + // when + val expression = queryPart { + replace( + expression(String::class, alias1), + "string1", + "string2", + ) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.replace( + Expressions.expression(String::class, alias1), + Expressions.stringLiteral("string1"), + Expressions.stringLiteral("string2"), + ) + + assertThat(actual).isEqualTo(expected) + } } diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/Expressions.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/Expressions.kt index 607e9684f..a16e9cb7c 100644 --- a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/Expressions.kt +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/Expressions.kt @@ -7,6 +7,7 @@ import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlAliasedExpres import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlAvg import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCaseValue import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCaseWhen +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCast import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCeiling import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCoalesce import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlConcat @@ -22,6 +23,7 @@ import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlExpression import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlExpressionParentheses import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlFloor import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlFunctionExpression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLeft import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLength import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLiteral import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLn @@ -41,6 +43,8 @@ import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlParam import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlPathType import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlPlus import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlPower +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlReplace +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlRight import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlRound import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlSign import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlSize @@ -723,6 +727,42 @@ object Expressions { return JpqlLocate(substring, string, start) } + /** + * Creates an expression that represents the casting of a value to a different type. + */ + @SinceJdsl("3.6.0") + fun cast(value: Expression<*>, type: KClass): Expression { + return JpqlCast(value, type) + } + + /** + * Creates an expression that returns the leftmost count characters from a string. + */ + @SinceJdsl("3.6.0") + fun left(value: Expression, count: Expression): Expression { + return JpqlLeft(value, count) + } + + /** + * Creates an expression that returns the rightmost count characters from a string. + */ + @SinceJdsl("3.6.0") + fun right(value: Expression, count: Expression): Expression { + return JpqlRight(value, count) + } + + /** + * Creates an expression that replaces all occurrences of a search string with a replacement string. + */ + @SinceJdsl("3.6.0") + fun replace( + value: Expression, + search: Expression, + replacement: Expression, + ): Expression { + return JpqlReplace(value, search, replacement) + } + /** * Creates an expression that represents predefined database functions and user-defined database functions. */ diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlCast.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlCast.kt new file mode 100644 index 000000000..d03a0bf44 --- /dev/null +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlCast.kt @@ -0,0 +1,11 @@ +package com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl + +import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import kotlin.reflect.KClass + +@SinceJdsl("3.6.0") +data class JpqlCast internal constructor( + val value: Expression<*>, + val type: KClass, +) : Expression diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlLeft.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlLeft.kt new file mode 100644 index 000000000..2d5f17cf9 --- /dev/null +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlLeft.kt @@ -0,0 +1,10 @@ +package com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl + +import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression + +@SinceJdsl("3.6.0") +data class JpqlLeft internal constructor( + val value: Expression, + val length: Expression, +) : Expression diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlReplace.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlReplace.kt new file mode 100644 index 000000000..f17c44645 --- /dev/null +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlReplace.kt @@ -0,0 +1,11 @@ +package com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl + +import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression + +@SinceJdsl("3.6.0") +data class JpqlReplace internal constructor( + val value: Expression, + val pattern: Expression, + val replacement: Expression, +) : Expression diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlRight.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlRight.kt new file mode 100644 index 000000000..2a3a078de --- /dev/null +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlRight.kt @@ -0,0 +1,10 @@ +package com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl + +import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression + +@SinceJdsl("3.6.0") +data class JpqlRight internal constructor( + val value: Expression, + val length: Expression, +) : Expression diff --git a/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/JpqlRenderContext.kt b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/JpqlRenderContext.kt index 9956b052a..ffd810720 100644 --- a/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/JpqlRenderContext.kt +++ b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/JpqlRenderContext.kt @@ -20,6 +20,7 @@ import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlAvgSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlBetweenSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlCaseValueSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlCaseWhenSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlCastSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlCeilingSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlCoalesceSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlConcatSerializer @@ -68,6 +69,7 @@ import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLeftAssociationFe import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLeftAssociationJoinSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLeftFetchJoinSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLeftJoinSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLeftSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLengthSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLessThanAllSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLessThanAnySerializer @@ -107,6 +109,8 @@ import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlPathTypeSerialize import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlPlusSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlPowerSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlPredicateParenthesesSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlReplaceSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlRightSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlRoundSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlSelectQuerySerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlSelectQueryUnionAllSerializer @@ -285,6 +289,7 @@ private class DefaultModule : JpqlRenderModule { JpqlBetweenSerializer(), JpqlCaseValueSerializer(), JpqlCaseWhenSerializer(), + JpqlCastSerializer(), JpqlCeilingSerializer(), JpqlCoalesceSerializer(), JpqlConcatSerializer(), @@ -333,6 +338,7 @@ private class DefaultModule : JpqlRenderModule { JpqlLeftAssociationJoinSerializer(), JpqlLeftFetchJoinSerializer(), JpqlLeftJoinSerializer(), + JpqlLeftSerializer(), JpqlLengthSerializer(), JpqlLessThanAllSerializer(), JpqlLessThanAnySerializer(), @@ -372,6 +378,8 @@ private class DefaultModule : JpqlRenderModule { JpqlPlusSerializer(), JpqlPowerSerializer(), JpqlPredicateParenthesesSerializer(), + JpqlRightSerializer(), + JpqlReplaceSerializer(), JpqlRoundSerializer(), JpqlSelectQuerySerializer(), JpqlSelectQueryUnionAllSerializer(), diff --git a/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlCastSerializer.kt b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlCastSerializer.kt new file mode 100644 index 000000000..f70d4f1af --- /dev/null +++ b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlCastSerializer.kt @@ -0,0 +1,27 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCast +import com.linecorp.kotlinjdsl.render.RenderContext +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlRenderSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlSerializer +import com.linecorp.kotlinjdsl.render.jpql.writer.JpqlWriter +import kotlin.reflect.KClass + +@SinceJdsl("3.6.0") +class JpqlCastSerializer : JpqlSerializer> { + override fun handledType(): KClass> { + return JpqlCast::class + } + + override fun serialize(part: JpqlCast<*>, writer: JpqlWriter, context: RenderContext) { + val delegate = context.getValue(JpqlRenderSerializer) + + writer.write("CAST") + writer.writeParentheses { + delegate.serialize(part.value, writer, context) + writer.write(" AS ") + writer.write(part.type.simpleName!!) + } + } +} diff --git a/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLeftSerializer.kt b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLeftSerializer.kt new file mode 100644 index 000000000..c4a0110d7 --- /dev/null +++ b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLeftSerializer.kt @@ -0,0 +1,27 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLeft +import com.linecorp.kotlinjdsl.render.RenderContext +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlRenderSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlSerializer +import com.linecorp.kotlinjdsl.render.jpql.writer.JpqlWriter +import kotlin.reflect.KClass + +@SinceJdsl("3.6.0") +class JpqlLeftSerializer : JpqlSerializer { + override fun handledType(): KClass { + return JpqlLeft::class + } + + override fun serialize(part: JpqlLeft, writer: JpqlWriter, context: RenderContext) { + val delegate = context.getValue(JpqlRenderSerializer) + + writer.write("LEFT") + writer.writeParentheses { + delegate.serialize(part.value, writer, context) + writer.write(", ") + delegate.serialize(part.length, writer, context) + } + } +} diff --git a/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializer.kt b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializer.kt new file mode 100644 index 000000000..c997d8490 --- /dev/null +++ b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializer.kt @@ -0,0 +1,29 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlReplace +import com.linecorp.kotlinjdsl.render.RenderContext +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlRenderSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlSerializer +import com.linecorp.kotlinjdsl.render.jpql.writer.JpqlWriter +import kotlin.reflect.KClass + +@SinceJdsl("3.6.0") +class JpqlReplaceSerializer : JpqlSerializer { + override fun handledType(): KClass { + return JpqlReplace::class + } + + override fun serialize(part: JpqlReplace, writer: JpqlWriter, context: RenderContext) { + val delegate = context.getValue(JpqlRenderSerializer) + + writer.write("REPLACE") + writer.writeParentheses { + delegate.serialize(part.value, writer, context) + writer.write(", ") + delegate.serialize(part.pattern, writer, context) + writer.write(", ") + delegate.serialize(part.replacement, writer, context) + } + } +} diff --git a/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlRightSerializer.kt b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlRightSerializer.kt new file mode 100644 index 000000000..887cd28d8 --- /dev/null +++ b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlRightSerializer.kt @@ -0,0 +1,27 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlRight +import com.linecorp.kotlinjdsl.render.RenderContext +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlRenderSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlSerializer +import com.linecorp.kotlinjdsl.render.jpql.writer.JpqlWriter +import kotlin.reflect.KClass + +@SinceJdsl("3.6.0") +class JpqlRightSerializer : JpqlSerializer { + override fun handledType(): KClass { + return JpqlRight::class + } + + override fun serialize(part: JpqlRight, writer: JpqlWriter, context: RenderContext) { + val delegate = context.getValue(JpqlRenderSerializer) + + writer.write("RIGHT") + writer.writeParentheses { + delegate.serialize(part.value, writer, context) + writer.write(", ") + delegate.serialize(part.length, writer, context) + } + } +} diff --git a/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlCastSerializerTest.kt b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlCastSerializerTest.kt new file mode 100644 index 000000000..749668b0b --- /dev/null +++ b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlCastSerializerTest.kt @@ -0,0 +1,56 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCast +import com.linecorp.kotlinjdsl.render.RenderContext +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlRenderSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlSerializerTest +import com.linecorp.kotlinjdsl.render.jpql.writer.JpqlWriter +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.verify +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +@JpqlSerializerTest +internal class JpqlCastSerializerTest { + private val sut = JpqlCastSerializer() + + @MockK + private lateinit var writer: JpqlWriter + + @MockK + private lateinit var serializer: JpqlRenderSerializer + + @MockK + private lateinit var context: RenderContext + + @Test + fun `handledType should return Expression`() { + // when + val actual = sut.handledType() + + // then + assertThat(actual).isEqualTo(JpqlCast::class) + } + + @Test + fun `serialize should write CAST`() { + // given + val expression = Expressions.cast(Expressions.value(1), String::class) + + every { context.getValue(JpqlRenderSerializer) } returns serializer + + // when + sut.serialize(expression as JpqlCast<*>, writer, context) + + // then + verify { + writer.write("CAST") + writer.writeParentheses(any()) + serializer.serialize(expression.value, writer, context) + writer.write(" AS ") + writer.write(String::class.simpleName!!) + } + } +} diff --git a/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLeftSerializerTest.kt b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLeftSerializerTest.kt new file mode 100644 index 000000000..2c24a8ef8 --- /dev/null +++ b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLeftSerializerTest.kt @@ -0,0 +1,56 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLeft +import com.linecorp.kotlinjdsl.render.RenderContext +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlRenderSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlSerializerTest +import com.linecorp.kotlinjdsl.render.jpql.writer.JpqlWriter +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.verify +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +@JpqlSerializerTest +internal class JpqlLeftSerializerTest { + private val sut = JpqlLeftSerializer() + + @MockK + private lateinit var writer: JpqlWriter + + @MockK + private lateinit var serializer: JpqlRenderSerializer + + @MockK + private lateinit var context: RenderContext + + @Test + fun `handledType should return Expression`() { + // when + val actual = sut.handledType() + + // then + assertThat(actual).isEqualTo(JpqlLeft::class) + } + + @Test + fun `serialize should write LEFT`() { + // given + val expression = Expressions.left(Expressions.value("abc"), Expressions.value(1)) as JpqlLeft + + every { context.getValue(JpqlRenderSerializer) } returns serializer + + // when + sut.serialize(expression, writer, context) + + // then + verify { + writer.write("LEFT") + writer.writeParentheses(any()) + serializer.serialize(expression.value, writer, context) + writer.write(", ") + serializer.serialize(expression.length, writer, context) + } + } +} diff --git a/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializerTest.kt b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializerTest.kt new file mode 100644 index 000000000..0d7b98c43 --- /dev/null +++ b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializerTest.kt @@ -0,0 +1,62 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlReplace +import com.linecorp.kotlinjdsl.render.RenderContext +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlRenderSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlSerializerTest +import com.linecorp.kotlinjdsl.render.jpql.writer.JpqlWriter +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.verify +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +@JpqlSerializerTest +internal class JpqlReplaceSerializerTest { + private val sut = JpqlReplaceSerializer() + + @MockK + private lateinit var writer: JpqlWriter + + @MockK + private lateinit var serializer: JpqlRenderSerializer + + @MockK + private lateinit var context: RenderContext + + @Test + fun `handledType should return Expression`() { + // when + val actual = sut.handledType() + + // then + assertThat(actual).isEqualTo(JpqlReplace::class) + } + + @Test + fun `serialize should write REPLACE`() { + // given + val expression = Expressions.replace( + Expressions.value("abc"), + Expressions.value("a"), + Expressions.value("b"), + ) as JpqlReplace + + every { context.getValue(JpqlRenderSerializer) } returns serializer + + // when + sut.serialize(expression, writer, context) + + // then + verify { + writer.write("REPLACE") + writer.writeParentheses(any()) + serializer.serialize(expression.value, writer, context) + writer.write(", ") + serializer.serialize(expression.pattern, writer, context) + writer.write(", ") + serializer.serialize(expression.replacement, writer, context) + } + } +} diff --git a/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlRightSerializerTest.kt b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlRightSerializerTest.kt new file mode 100644 index 000000000..b9e5c1500 --- /dev/null +++ b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlRightSerializerTest.kt @@ -0,0 +1,56 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlRight +import com.linecorp.kotlinjdsl.render.RenderContext +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlRenderSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlSerializerTest +import com.linecorp.kotlinjdsl.render.jpql.writer.JpqlWriter +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.verify +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +@JpqlSerializerTest +internal class JpqlRightSerializerTest { + private val sut = JpqlRightSerializer() + + @MockK + private lateinit var writer: JpqlWriter + + @MockK + private lateinit var serializer: JpqlRenderSerializer + + @MockK + private lateinit var context: RenderContext + + @Test + fun `handledType should return Expression`() { + // when + val actual = sut.handledType() + + // then + assertThat(actual).isEqualTo(JpqlRight::class) + } + + @Test + fun `serialize should write RIGHT`() { + // given + val expression = Expressions.right(Expressions.value("abc"), Expressions.value(1)) as JpqlRight + + every { context.getValue(JpqlRenderSerializer) } returns serializer + + // when + sut.serialize(expression, writer, context) + + // then + verify { + writer.write("RIGHT") + writer.writeParentheses(any()) + serializer.serialize(expression.value, writer, context) + writer.write(", ") + serializer.serialize(expression.length, writer, context) + } + } +} From bef613476b136e152b4ce5c09074f628861a5175 Mon Sep 17 00:00:00 2001 From: Hyunsik Kang Date: Sat, 19 Jul 2025 08:02:52 +0900 Subject: [PATCH 2/4] fix: apply reviews --- .../com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt | 48 ++++++++++++++----- .../querymodel/jpql/expression/Expressions.kt | 20 +++++--- .../jpql/expression/impl/JpqlCast.kt | 4 +- .../jpql/expression/impl/JpqlLeft.kt | 4 +- .../jpql/expression/impl/JpqlReplace.kt | 6 +-- .../jpql/expression/impl/JpqlRight.kt | 4 +- .../serializer/impl/JpqlReplaceSerializer.kt | 6 +-- .../impl/JpqlReplaceSerializerTest.kt | 2 +- 8 files changed, 63 insertions(+), 31 deletions(-) diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt index 0045e6208..5a5d557b8 100644 --- a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt @@ -1725,32 +1725,32 @@ open class Jpql : JpqlDsl { * Creates an expression that returns the leftmost count characters from a string. */ @SinceJdsl("3.6.0") - fun left(value: Expressionable, count: Expressionable): Expression { - return Expressions.left(value.toExpression(), count.toExpression()) + fun left(value: Expressionable, len: Expressionable): Expression { + return Expressions.left(value.toExpression(), len.toExpression()) } /** * Creates an expression that returns the leftmost count characters from a string. */ @SinceJdsl("3.6.0") - fun left(value: Expressionable, count: Int): Expression { - return Expressions.left(value.toExpression(), intLiteral(count)) + fun left(value: Expressionable, len: Int): Expression { + return left(value.toExpression(), intLiteral(len)) } /** * Creates an expression that returns the rightmost count characters from a string. */ @SinceJdsl("3.6.0") - fun right(value: Expressionable, count: Expressionable): Expression { - return Expressions.right(value.toExpression(), count.toExpression()) + fun right(value: Expressionable, len: Expressionable): Expression { + return Expressions.right(value.toExpression(), len.toExpression()) } /** * Creates an expression that returns the rightmost count characters from a string. */ @SinceJdsl("3.6.0") - fun right(value: Expressionable, count: Int): Expression { - return Expressions.right(value.toExpression(), intLiteral(count)) + fun right(value: Expressionable, len: Int): Expression { + return right(value.toExpression(), intLiteral(len)) } /** @@ -1759,10 +1759,22 @@ open class Jpql : JpqlDsl { @SinceJdsl("3.6.0") fun replace( value: Expressionable, - search: Expressionable, + substring: Expressionable, replacement: Expressionable, ): Expression { - return Expressions.replace(value.toExpression(), search.toExpression(), replacement.toExpression()) + return Expressions.replace(value.toExpression(), substring.toExpression(), replacement.toExpression()) + } + + /** + * Creates an expression that replaces all occurrences of a search string with a replacement string. + */ + @SinceJdsl("3.6.0") + fun replace( + value: Expressionable, + substring: String, + replacement: String, + ): Expression { + return replace(value.toExpression(), stringLiteral(substring), stringLiteral(replacement)) } /** @@ -1771,10 +1783,22 @@ open class Jpql : JpqlDsl { @SinceJdsl("3.6.0") fun replace( value: Expressionable, - search: String, + substring: Expressionable, replacement: String, ): Expression { - return Expressions.replace(value.toExpression(), stringLiteral(search), stringLiteral(replacement)) + return replace(value.toExpression(), substring, stringLiteral(replacement)) + } + + /** + * Creates an expression that replaces all occurrences of a search string with a replacement string. + */ + @SinceJdsl("3.6.0") + fun replace( + value: Expressionable, + substring: String, + replacement: Expressionable, + ): Expression { + return replace(value.toExpression(), substring, replacement) } /** diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/Expressions.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/Expressions.kt index a16e9cb7c..0773b1ceb 100644 --- a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/Expressions.kt +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/Expressions.kt @@ -739,16 +739,24 @@ object Expressions { * Creates an expression that returns the leftmost count characters from a string. */ @SinceJdsl("3.6.0") - fun left(value: Expression, count: Expression): Expression { - return JpqlLeft(value, count) + fun left(value: Expression, len: Expression): Expression { + return JpqlLeft(value, len) + } + + /** + * Creates an expression that returns the leftmost count characters from a string. + */ + @SinceJdsl("3.6.0") + fun left(value: Expression, len: Int): Expression { + return left(value, intLiteral(len)) } /** * Creates an expression that returns the rightmost count characters from a string. */ @SinceJdsl("3.6.0") - fun right(value: Expression, count: Expression): Expression { - return JpqlRight(value, count) + fun right(value: Expression, len: Expression): Expression { + return JpqlRight(value, len) } /** @@ -757,10 +765,10 @@ object Expressions { @SinceJdsl("3.6.0") fun replace( value: Expression, - search: Expression, + substring: Expression, replacement: Expression, ): Expression { - return JpqlReplace(value, search, replacement) + return JpqlReplace(value, substring, replacement) } /** diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlCast.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlCast.kt index d03a0bf44..56eb86f4f 100644 --- a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlCast.kt +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlCast.kt @@ -1,10 +1,10 @@ package com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl -import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.Internal import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression import kotlin.reflect.KClass -@SinceJdsl("3.6.0") +@Internal data class JpqlCast internal constructor( val value: Expression<*>, val type: KClass, diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlLeft.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlLeft.kt index 2d5f17cf9..4ddac9e23 100644 --- a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlLeft.kt +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlLeft.kt @@ -1,9 +1,9 @@ package com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl -import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.Internal import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression -@SinceJdsl("3.6.0") +@Internal data class JpqlLeft internal constructor( val value: Expression, val length: Expression, diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlReplace.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlReplace.kt index f17c44645..332533d2c 100644 --- a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlReplace.kt +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlReplace.kt @@ -1,11 +1,11 @@ package com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl -import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.Internal import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression -@SinceJdsl("3.6.0") +@Internal data class JpqlReplace internal constructor( val value: Expression, - val pattern: Expression, + val substring: Expression, val replacement: Expression, ) : Expression diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlRight.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlRight.kt index 2a3a078de..d92244bcc 100644 --- a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlRight.kt +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlRight.kt @@ -1,9 +1,9 @@ package com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl -import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.Internal import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression -@SinceJdsl("3.6.0") +@Internal data class JpqlRight internal constructor( val value: Expression, val length: Expression, diff --git a/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializer.kt b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializer.kt index c997d8490..5a3aa9013 100644 --- a/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializer.kt +++ b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializer.kt @@ -1,6 +1,6 @@ package com.linecorp.kotlinjdsl.render.jpql.serializer.impl -import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.Internal import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlReplace import com.linecorp.kotlinjdsl.render.RenderContext import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlRenderSerializer @@ -8,7 +8,7 @@ import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlSerializer import com.linecorp.kotlinjdsl.render.jpql.writer.JpqlWriter import kotlin.reflect.KClass -@SinceJdsl("3.6.0") +@Internal class JpqlReplaceSerializer : JpqlSerializer { override fun handledType(): KClass { return JpqlReplace::class @@ -21,7 +21,7 @@ class JpqlReplaceSerializer : JpqlSerializer { writer.writeParentheses { delegate.serialize(part.value, writer, context) writer.write(", ") - delegate.serialize(part.pattern, writer, context) + delegate.serialize(part.substring, writer, context) writer.write(", ") delegate.serialize(part.replacement, writer, context) } diff --git a/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializerTest.kt b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializerTest.kt index 0d7b98c43..39e715c20 100644 --- a/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializerTest.kt +++ b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlReplaceSerializerTest.kt @@ -54,7 +54,7 @@ internal class JpqlReplaceSerializerTest { writer.writeParentheses(any()) serializer.serialize(expression.value, writer, context) writer.write(", ") - serializer.serialize(expression.pattern, writer, context) + serializer.serialize(expression.substring, writer, context) writer.write(", ") serializer.serialize(expression.replacement, writer, context) } From 77cb87ffdc40a29d3f7d8a30c01cf08a5cb05093 Mon Sep 17 00:00:00 2001 From: Hyunsik Kang Date: Sat, 19 Jul 2025 19:10:14 +0900 Subject: [PATCH 3/4] fix: apply reviews --- docs/en/jpql-with-kotlin-jdsl/expressions.md | 11 +++- docs/ko/jpql-with-kotlin-jdsl/expressions.md | 11 +++- .../com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt | 16 +++-- .../dsl/jpql/expression/CastStep.kt | 35 ++++++++++ .../dsl/jpql/expression/StringCastStep.kt | 17 +++++ .../dsl/jpql/expression/impl/JpqlCastStep.kt | 27 ++++++++ .../expression/impl/JpqlStringCastStep.kt | 15 +++++ .../dsl/jpql/expression/ExpressionDslTest.kt | 66 +++++++++++++++++-- .../jpql/expression/impl/JpqlCast.kt | 2 +- 9 files changed, 183 insertions(+), 17 deletions(-) create mode 100644 dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/CastStep.kt create mode 100644 dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/StringCastStep.kt create mode 100644 dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlCastStep.kt create mode 100644 dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlStringCastStep.kt diff --git a/docs/en/jpql-with-kotlin-jdsl/expressions.md b/docs/en/jpql-with-kotlin-jdsl/expressions.md index 3b15c1d54..6bff93eb1 100644 --- a/docs/en/jpql-with-kotlin-jdsl/expressions.md +++ b/docs/en/jpql-with-kotlin-jdsl/expressions.md @@ -220,8 +220,11 @@ length(path(Book::title)) locate("Book", path(Book::title)) -cast(path(Book::price), String::class) -cast(path(Book::price)) +cast(path(Book::price)).asString() +cast(path(Book::authorId)).asInt() +cast(path(Book::authorId)).asLong() +cast(path(Book::authorId)).asDouble() +cast(path(Book::authorId)).asFloat() left(path(Book::title), 3) left(path(Book::title), literal(3)) @@ -230,6 +233,10 @@ right(path(Book::title), 3) right(path(Book::title), literal(3)) replace(path(Book::title), "old", "new") +replace(path(Book::title), stringLiteral("old"), "new") +replace(path(Book::title), path(Book::name), "new") +replace(path(Book::title), "old", stringLiteral("new")) +replace(path(Book::title), "old", path(Book::name)) replace(path(Book::title), literal("old"), literal("new")) ``` diff --git a/docs/ko/jpql-with-kotlin-jdsl/expressions.md b/docs/ko/jpql-with-kotlin-jdsl/expressions.md index 64e395c87..d04ca7d7b 100644 --- a/docs/ko/jpql-with-kotlin-jdsl/expressions.md +++ b/docs/ko/jpql-with-kotlin-jdsl/expressions.md @@ -218,8 +218,11 @@ length(path(Book::title)) locate("Book", path(Book::title)) -cast(path(Book::price), String::class) -cast(path(Book::price)) +cast(path(Book::price)).asString() +cast(path(Book::authorId)).asInt() +cast(path(Book::authorId)).asLong() +cast(path(Book::authorId)).asDouble() +cast(path(Book::authorId)).asFloat() left(path(Book::title), 3) left(path(Book::title), literal(3)) @@ -228,6 +231,10 @@ right(path(Book::title), 3) right(path(Book::title), literal(3)) replace(path(Book::title), "old", "new") +replace(path(Book::title), stringLiteral("old"), "new") +replace(path(Book::title), path(Book::name), "new") +replace(path(Book::title), "old", stringLiteral("new")) +replace(path(Book::title), "old", path(Book::name)) replace(path(Book::title), literal("old"), literal("new")) ``` diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt index 5a5d557b8..033029550 100644 --- a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt @@ -5,9 +5,13 @@ import com.linecorp.kotlinjdsl.dsl.jpql.delete.DeleteQueryWhereStep import com.linecorp.kotlinjdsl.dsl.jpql.delete.impl.DeleteQueryDsl import com.linecorp.kotlinjdsl.dsl.jpql.expression.CaseThenFirstStep import com.linecorp.kotlinjdsl.dsl.jpql.expression.CaseValueWhenFirstStep +import com.linecorp.kotlinjdsl.dsl.jpql.expression.CastStep +import com.linecorp.kotlinjdsl.dsl.jpql.expression.StringCastStep import com.linecorp.kotlinjdsl.dsl.jpql.expression.TrimFromStep import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.CaseThenFirstStepDsl import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.CaseValueWhenFirstStepDsl +import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.JpqlCastStep +import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.JpqlStringCastStep import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.TrimBothFromStepDsl import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.TrimFromStepDsl import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.TrimLeadingFromStepDsl @@ -1706,19 +1710,19 @@ open class Jpql : JpqlDsl { } /** - * Creates an expression that represents the casting of a value to a different type. + * Creates a step to cast a string expression to another type. */ @SinceJdsl("3.6.0") - fun cast(value: Expressionable<*>, type: KClass): Expression { - return Expressions.cast(value.toExpression(), type) + fun cast(value: Expressionable): CastStep { + return JpqlCastStep(value.toExpression()) } /** - * Creates an expression that represents the casting of a value to a different type. + * Creates a step to cast a scalar expression to a string. */ @SinceJdsl("3.6.0") - inline fun cast(value: Expressionable<*>): Expression { - return Expressions.cast(value.toExpression(), T::class) + fun cast(value: Expressionable): StringCastStep { + return JpqlStringCastStep(value.toExpression()) } /** diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/CastStep.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/CastStep.kt new file mode 100644 index 000000000..ce6f8fdd1 --- /dev/null +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/CastStep.kt @@ -0,0 +1,35 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression + +import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable + +/** + * A step to specify the target type for a cast from a string expression. + * This corresponds to the BNF: CAST(string_expression AS {type}) + */ +@SinceJdsl("3.6.0") +interface CastStep { + /** + * Casts the expression to an INTEGER. + */ + @SinceJdsl("3.6.0") + fun asInteger(): Expressionable + + /** + * Casts the expression to a LONG. + */ + @SinceJdsl("3.6.0") + fun asLong(): Expressionable + + /** + * Casts the expression to a FLOAT. + */ + @SinceJdsl("3.6.0") + fun asFloat(): Expressionable + + /** + * Casts the expression to a DOUBLE. + */ + @SinceJdsl("3.6.0") + fun asDouble(): Expressionable +} diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/StringCastStep.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/StringCastStep.kt new file mode 100644 index 000000000..6ce41b638 --- /dev/null +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/StringCastStep.kt @@ -0,0 +1,17 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression + +import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable + +/** + * A step to cast a scalar expression to a STRING. + * This corresponds to the BNF: CAST(scalar_expression AS STRING) + */ +@SinceJdsl("3.6.0") +interface StringCastStep { + /** + * Casts the expression to a STRING. + */ + @SinceJdsl("3.6.0") + fun asString(): Expressionable +} diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlCastStep.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlCastStep.kt new file mode 100644 index 000000000..67939bf23 --- /dev/null +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlCastStep.kt @@ -0,0 +1,27 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression.impl + +import com.linecorp.kotlinjdsl.dsl.jpql.expression.CastStep +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCast + +@PublishedApi +internal data class JpqlCastStep( + private val expression: Expression, +) : CastStep { + override fun asInteger(): Expressionable { + return JpqlCast(expression, Int::class) + } + + override fun asLong(): Expressionable { + return JpqlCast(expression, Long::class) + } + + override fun asFloat(): Expressionable { + return JpqlCast(expression, Float::class) + } + + override fun asDouble(): Expressionable { + return JpqlCast(expression, Double::class) + } +} diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlStringCastStep.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlStringCastStep.kt new file mode 100644 index 000000000..8fcbe681f --- /dev/null +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlStringCastStep.kt @@ -0,0 +1,15 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression.impl + +import com.linecorp.kotlinjdsl.dsl.jpql.expression.StringCastStep +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCast + +@PublishedApi +internal data class JpqlStringCastStep( + private val expression: Expression, +) : StringCastStep { + override fun asString(): Expressionable { + return JpqlCast(expression, String::class) + } +} diff --git a/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/ExpressionDslTest.kt b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/ExpressionDslTest.kt index 1032eb2aa..0d13fe122 100644 --- a/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/ExpressionDslTest.kt +++ b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/ExpressionDslTest.kt @@ -46,10 +46,10 @@ class ExpressionDslTest : WithAssertions { } @Test - fun `cast() with a expression and a class`() { + fun `cast() with a string expression as Integer`() { // when val expression = queryPart { - cast(expression(String::class, alias1), Int::class) + cast(expression(String::class, alias1)).asInteger() }.toExpression() val actual: Expression = expression // for type check @@ -64,18 +64,72 @@ class ExpressionDslTest : WithAssertions { } @Test - fun `inline cast() with a expression and a class`() { + fun `cast() with a string expression as Long`() { // when val expression = queryPart { - cast(expression(String::class, alias1)) + cast(expression(String::class, alias1)).asLong() }.toExpression() - val actual: Expression = expression // for type check + val actual: Expression = expression // for type check // then val expected = Expressions.cast( Expressions.expression(String::class, alias1), - Int::class, + Long::class, + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `cast() with a string expression as Float`() { + // when + val expression = queryPart { + cast(expression(String::class, alias1)).asFloat() + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.cast( + Expressions.expression(String::class, alias1), + Float::class, + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `cast() with a string expression as Double`() { + // when + val expression = queryPart { + cast(expression(String::class, alias1)).asDouble() + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.cast( + Expressions.expression(String::class, alias1), + Double::class, + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `cast() with scalar expression as String`() { + // when + val expression = queryPart { + cast(expression(Int::class, alias1)).asString() + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.cast( + Expressions.expression(Int::class, alias1), + String::class, ) assertThat(actual).isEqualTo(expected) diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlCast.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlCast.kt index 56eb86f4f..1127c5118 100644 --- a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlCast.kt +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlCast.kt @@ -5,7 +5,7 @@ import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression import kotlin.reflect.KClass @Internal -data class JpqlCast internal constructor( +data class JpqlCast( val value: Expression<*>, val type: KClass, ) : Expression From ff217480c104e65269853bf3cf60b2acac71a87e Mon Sep 17 00:00:00 2001 From: Hyunsik Kang Date: Thu, 24 Jul 2025 12:40:28 +0900 Subject: [PATCH 4/4] fix: apply review --- .../main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt | 8 ++++---- .../expression/{StringCastStep.kt => CastStepToString.kt} | 2 +- .../{JpqlStringCastStep.kt => JpqlCastStepToString.kt} | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) rename dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/{StringCastStep.kt => CastStepToString.kt} (93%) rename dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/{JpqlStringCastStep.kt => JpqlCastStepToString.kt} (75%) diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt index 033029550..be312c22a 100644 --- a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt @@ -6,12 +6,12 @@ import com.linecorp.kotlinjdsl.dsl.jpql.delete.impl.DeleteQueryDsl import com.linecorp.kotlinjdsl.dsl.jpql.expression.CaseThenFirstStep import com.linecorp.kotlinjdsl.dsl.jpql.expression.CaseValueWhenFirstStep import com.linecorp.kotlinjdsl.dsl.jpql.expression.CastStep -import com.linecorp.kotlinjdsl.dsl.jpql.expression.StringCastStep +import com.linecorp.kotlinjdsl.dsl.jpql.expression.CastStepToString import com.linecorp.kotlinjdsl.dsl.jpql.expression.TrimFromStep import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.CaseThenFirstStepDsl import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.CaseValueWhenFirstStepDsl import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.JpqlCastStep -import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.JpqlStringCastStep +import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.JpqlCastStepToString import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.TrimBothFromStepDsl import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.TrimFromStepDsl import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.TrimLeadingFromStepDsl @@ -1721,8 +1721,8 @@ open class Jpql : JpqlDsl { * Creates a step to cast a scalar expression to a string. */ @SinceJdsl("3.6.0") - fun cast(value: Expressionable): StringCastStep { - return JpqlStringCastStep(value.toExpression()) + fun cast(value: Expressionable): CastStepToString { + return JpqlCastStepToString(value.toExpression()) } /** diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/StringCastStep.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/CastStepToString.kt similarity index 93% rename from dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/StringCastStep.kt rename to dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/CastStepToString.kt index 6ce41b638..dcf25d4d5 100644 --- a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/StringCastStep.kt +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/CastStepToString.kt @@ -8,7 +8,7 @@ import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable * This corresponds to the BNF: CAST(scalar_expression AS STRING) */ @SinceJdsl("3.6.0") -interface StringCastStep { +interface CastStepToString { /** * Casts the expression to a STRING. */ diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlStringCastStep.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlCastStepToString.kt similarity index 75% rename from dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlStringCastStep.kt rename to dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlCastStepToString.kt index 8fcbe681f..1812e689a 100644 --- a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlStringCastStep.kt +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/JpqlCastStepToString.kt @@ -1,14 +1,14 @@ package com.linecorp.kotlinjdsl.dsl.jpql.expression.impl -import com.linecorp.kotlinjdsl.dsl.jpql.expression.StringCastStep +import com.linecorp.kotlinjdsl.dsl.jpql.expression.CastStepToString import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCast @PublishedApi -internal data class JpqlStringCastStep( +internal data class JpqlCastStepToString( private val expression: Expression, -) : StringCastStep { +) : CastStepToString { override fun asString(): Expressionable { return JpqlCast(expression, String::class) }