From 763eeadf8b0d7967f98e0cd6b2eeacefdf7b6db2 Mon Sep 17 00:00:00 2001 From: waahhh Date: Wed, 22 Nov 2023 12:22:41 +0900 Subject: [PATCH 1/7] feat(query-model): add JpqlTrim(Leading, Trailing, Both) --- .../querymodel/jpql/expression/impl/JpqlTrim.kt | 10 ++++++++++ .../querymodel/jpql/expression/impl/JpqlTrimBoth.kt | 10 ++++++++++ .../querymodel/jpql/expression/impl/JpqlTrimLeading.kt | 10 ++++++++++ .../jpql/expression/impl/JpqlTrimTrailing.kt | 10 ++++++++++ 4 files changed, 40 insertions(+) create mode 100644 query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrim.kt create mode 100644 query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrimBoth.kt create mode 100644 query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrimLeading.kt create mode 100644 query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrimTrailing.kt diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrim.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrim.kt new file mode 100644 index 000000000..7fd8ee417 --- /dev/null +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrim.kt @@ -0,0 +1,10 @@ +package com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl + +import com.linecorp.kotlinjdsl.Internal +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression + +@Internal +data class JpqlTrim internal constructor( + val character: Expression?, + val value: Expression, +) : Expression diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrimBoth.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrimBoth.kt new file mode 100644 index 000000000..04fa1873b --- /dev/null +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrimBoth.kt @@ -0,0 +1,10 @@ +package com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl + +import com.linecorp.kotlinjdsl.Internal +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression + +@Internal +data class JpqlTrimBoth internal constructor( + val character: Expression?, + val value: Expression, +) : Expression diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrimLeading.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrimLeading.kt new file mode 100644 index 000000000..563b50e58 --- /dev/null +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrimLeading.kt @@ -0,0 +1,10 @@ +package com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl + +import com.linecorp.kotlinjdsl.Internal +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression + +@Internal +data class JpqlTrimLeading internal constructor( + val character: Expression?, + val value: Expression, +) : Expression diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrimTrailing.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrimTrailing.kt new file mode 100644 index 000000000..4966508cc --- /dev/null +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlTrimTrailing.kt @@ -0,0 +1,10 @@ +package com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl + +import com.linecorp.kotlinjdsl.Internal +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression + +@Internal +data class JpqlTrimTrailing internal constructor( + val character: Expression?, + val value: Expression, +) : Expression From 5fbdb9c9bc3e43aee48f1b8d97a7c59301460c74 Mon Sep 17 00:00:00 2001 From: waahhh Date: Wed, 22 Nov 2023 12:24:06 +0900 Subject: [PATCH 2/7] feat(query-model): add trim methods to Expressions --- .../querymodel/jpql/expression/Expressions.kt | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) 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 d8ce36e44..4d165a1c1 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 @@ -30,6 +30,10 @@ import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlPlus import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlSubquery import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlSum import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTimes +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrim +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrimBoth +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrimLeading +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrimTrailing import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlUpper import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlValue import com.linecorp.kotlinjdsl.querymodel.jpql.path.Path @@ -416,6 +420,58 @@ object Expressions { return JpqlPathType(path) } + /** + * Creates an expression that represents a string with the specified characters all trimmed + * from the both sides of the string. + * If the character is not specified, it will be assumed to be whitespace. + */ + @SinceJdsl("3.1.0") + fun trim( + character: Expression? = null, + value: Expression, + ): Expression { + return JpqlTrim(character, value) + } + + /** + * Creates an expression that represents a string with the specified characters all trimmed + * from the leading side of the string. + * If the character is not specified, it will be assumed to be whitespace. + */ + @SinceJdsl("3.1.0") + fun trimLeading( + character: Expression? = null, + value: Expression, + ): Expression { + return JpqlTrimLeading(character, value) + } + + /** + * Creates an expression that represents a string with the specified characters all trimmed + * from the trailing side of the string. + * If the character is not specified, it will be assumed to be whitespace. + */ + @SinceJdsl("3.1.0") + fun trimTrailing( + character: Expression? = null, + value: Expression, + ): Expression { + return JpqlTrimTrailing(character, value) + } + + /** + * Creates an expression that represents a string with the specified characters all trimmed + * from the both sides of the string. + * If the character is not specified, it will be assumed to be whitespace. + */ + @SinceJdsl("3.1.0") + fun trimBoth( + character: Expression? = null, + value: Expression, + ): Expression { + return JpqlTrimBoth(character, value) + } + /** * Creates an expression that represents the string in uppercase. */ From 5e9a790eff647c654605c19e1587da82be7e9520 Mon Sep 17 00:00:00 2001 From: waahhh Date: Wed, 22 Nov 2023 12:24:59 +0900 Subject: [PATCH 3/7] test(query-model): for trim methods in Expressions --- .../jpql/expression/ExpressionsTest.kt | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/query-model/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/ExpressionsTest.kt b/query-model/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/ExpressionsTest.kt index 980d7c71a..6f611ecf8 100644 --- a/query-model/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/ExpressionsTest.kt +++ b/query-model/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/ExpressionsTest.kt @@ -32,6 +32,10 @@ import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlPlus import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlSubquery import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlSum import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTimes +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrim +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrimBoth +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrimLeading +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrimTrailing import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlUpper import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlValue import com.linecorp.kotlinjdsl.querymodel.jpql.path.Paths @@ -58,6 +62,7 @@ class ExpressionsTest : WithAssertions { private val char1: Char = 'a' private val string1: String = "string1" + private val charExpression1: Expression = Expressions.value('c') private val stringExpression1: Expression = Expressions.value("string1") private val stringExpression2: Expression = Expressions.value("string2") private val intExpression1: Expression = Expressions.value(100) @@ -600,6 +605,74 @@ class ExpressionsTest : WithAssertions { assertThat(actual).isEqualTo(expected) } + @Test + fun trim() { + // when + val actual = Expressions.trim( + charExpression1, + stringExpression1, + ) + + // then + val expected = JpqlTrim( + charExpression1, + stringExpression1, + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun trimLeading() { + // when + val actual = Expressions.trimLeading( + charExpression1, + stringExpression1, + ) + + // then + val expected = JpqlTrimLeading( + charExpression1, + stringExpression1, + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun trimTrailing() { + // when + val actual = Expressions.trimTrailing( + charExpression1, + stringExpression1, + ) + + // then + val expected = JpqlTrimTrailing( + charExpression1, + stringExpression1, + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun trimBoth() { + // when + val actual = Expressions.trimBoth( + charExpression1, + stringExpression1, + ) + + // then + val expected = JpqlTrimBoth( + charExpression1, + stringExpression1, + ) + + assertThat(actual).isEqualTo(expected) + } + @Test fun upper() { // when From 997173d8f72eb76585fd4fd0c2f0000e96f436eb Mon Sep 17 00:00:00 2001 From: waahhh Date: Wed, 22 Nov 2023 12:31:16 +0900 Subject: [PATCH 4/7] feat(render): add JpqlTrim(Leading, Trailing, Both)Serializer --- .../render/jpql/JpqlRenderContext.kt | 8 ++++ .../serializer/impl/JpqlTrimBothSerializer.kt | 37 +++++++++++++++++++ .../impl/JpqlTrimLeadingSerializer.kt | 37 +++++++++++++++++++ .../serializer/impl/JpqlTrimSerializer.kt | 33 +++++++++++++++++ .../impl/JpqlTrimTrailingSerializer.kt | 37 +++++++++++++++++++ 5 files changed, 152 insertions(+) create mode 100644 render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimBothSerializer.kt create mode 100644 render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimLeadingSerializer.kt create mode 100644 render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimSerializer.kt create mode 100644 render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimTrailingSerializer.kt 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 422be8953..fa93b175c 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 @@ -95,6 +95,10 @@ import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlSortSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlSubquerySerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlSumSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlTimesSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlTrimBothSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlTrimLeadingSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlTrimSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlTrimTrailingSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlUpdateQuerySerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlUpperSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlValueSerializer @@ -332,6 +336,10 @@ private class DefaultModule : JpqlRenderModule { JpqlSubquerySerializer(), JpqlSumSerializer(), JpqlTimesSerializer(), + JpqlTrimBothSerializer(), + JpqlTrimLeadingSerializer(), + JpqlTrimSerializer(), + JpqlTrimTrailingSerializer(), JpqlUpdateQuerySerializer(), JpqlUpperSerializer(), JpqlValueSerializer(), diff --git a/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimBothSerializer.kt b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimBothSerializer.kt new file mode 100644 index 000000000..ce130277a --- /dev/null +++ b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimBothSerializer.kt @@ -0,0 +1,37 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.Internal +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrimBoth +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 + +@Internal +class JpqlTrimBothSerializer : JpqlSerializer { + override fun handledType(): KClass { + return JpqlTrimBoth::class + } + + override fun serialize(part: JpqlTrimBoth, writer: JpqlWriter, context: RenderContext) { + val delegate = context.getValue(JpqlRenderSerializer) + + writer.write("TRIM") + + writer.writeParentheses { + writer.write("BOTH") + writer.write(" ") + + part.character?.let { + delegate.serialize(it, writer, context) + writer.write(" ") + } + + writer.write("FROM") + writer.write(" ") + + delegate.serialize(part.value, writer, context) + } + } +} diff --git a/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimLeadingSerializer.kt b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimLeadingSerializer.kt new file mode 100644 index 000000000..086f047e4 --- /dev/null +++ b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimLeadingSerializer.kt @@ -0,0 +1,37 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.Internal +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrimLeading +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 + +@Internal +class JpqlTrimLeadingSerializer : JpqlSerializer { + override fun handledType(): KClass { + return JpqlTrimLeading::class + } + + override fun serialize(part: JpqlTrimLeading, writer: JpqlWriter, context: RenderContext) { + val delegate = context.getValue(JpqlRenderSerializer) + + writer.write("TRIM") + + writer.writeParentheses { + writer.write("LEADING") + writer.write(" ") + + part.character?.let { + delegate.serialize(it, writer, context) + writer.write(" ") + } + + writer.write("FROM") + writer.write(" ") + + delegate.serialize(part.value, writer, context) + } + } +} diff --git a/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimSerializer.kt b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimSerializer.kt new file mode 100644 index 000000000..4d044d586 --- /dev/null +++ b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimSerializer.kt @@ -0,0 +1,33 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.Internal +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrim +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 + +@Internal +class JpqlTrimSerializer : JpqlSerializer { + override fun handledType(): KClass { + return JpqlTrim::class + } + + override fun serialize(part: JpqlTrim, writer: JpqlWriter, context: RenderContext) { + val delegate = context.getValue(JpqlRenderSerializer) + + writer.write("TRIM") + + writer.writeParentheses { + part.character?.let { + delegate.serialize(it, writer, context) + writer.write(" ") + writer.write("FROM") + writer.write(" ") + } + + delegate.serialize(part.value, writer, context) + } + } +} diff --git a/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimTrailingSerializer.kt b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimTrailingSerializer.kt new file mode 100644 index 000000000..65ddeaf61 --- /dev/null +++ b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimTrailingSerializer.kt @@ -0,0 +1,37 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.Internal +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrimTrailing +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 + +@Internal +class JpqlTrimTrailingSerializer : JpqlSerializer { + override fun handledType(): KClass { + return JpqlTrimTrailing::class + } + + override fun serialize(part: JpqlTrimTrailing, writer: JpqlWriter, context: RenderContext) { + val delegate = context.getValue(JpqlRenderSerializer) + + writer.write("TRIM") + + writer.writeParentheses { + writer.write("TRAILING") + writer.write(" ") + + part.character?.let { + delegate.serialize(it, writer, context) + writer.write(" ") + } + + writer.write("FROM") + writer.write(" ") + + delegate.serialize(part.value, writer, context) + } + } +} From fea264cc2a4e1a9a61421f39b1d04ad0de2e1ff5 Mon Sep 17 00:00:00 2001 From: waahhh Date: Wed, 22 Nov 2023 12:32:48 +0900 Subject: [PATCH 5/7] test(render): for JpqlTrim(Leading, Trailing, Both)Serializer --- .../impl/JpqlTrimBothSerializerTest.kt | 84 +++++++++++++++++++ .../impl/JpqlTrimLeadingSerializerTest.kt | 84 +++++++++++++++++++ .../serializer/impl/JpqlTrimSerializerTest.kt | 78 +++++++++++++++++ .../impl/JpqlTrimTrailingSerializerTest.kt | 84 +++++++++++++++++++ 4 files changed, 330 insertions(+) create mode 100644 render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimBothSerializerTest.kt create mode 100644 render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimLeadingSerializerTest.kt create mode 100644 render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimSerializerTest.kt create mode 100644 render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimTrailingSerializerTest.kt diff --git a/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimBothSerializerTest.kt b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimBothSerializerTest.kt new file mode 100644 index 000000000..ccb1e230d --- /dev/null +++ b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimBothSerializerTest.kt @@ -0,0 +1,84 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrimBoth +import com.linecorp.kotlinjdsl.render.TestRenderContext +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.impl.annotations.MockK +import io.mockk.verifySequence +import org.assertj.core.api.WithAssertions +import org.junit.jupiter.api.Test + +@JpqlSerializerTest +class JpqlTrimBothSerializerTest : WithAssertions { + private val sut = JpqlTrimBothSerializer() + + @MockK + private lateinit var writer: JpqlWriter + + @MockK + private lateinit var serializer: JpqlRenderSerializer + + private val charExpression1 = Expressions.value('c') + private val stringExpression1 = Expressions.value("string1") + + @Test + fun handledType() { + // when + val actual = sut.handledType() + + // then + assertThat(actual).isEqualTo(JpqlTrimBoth::class) + } + + @Test + fun `serialize() draws the BOTH and the FROM, when the character is null`() { + // given + val part = Expressions.trimBoth( + value = stringExpression1, + ) + val context = TestRenderContext(serializer) + + // when + sut.serialize(part as JpqlTrimBoth, writer, context) + + // then + verifySequence { + writer.write("TRIM") + writer.writeParentheses(any()) + writer.write("BOTH") + writer.write(" ") + writer.write("FROM") + writer.write(" ") + serializer.serialize(stringExpression1, writer, context) + } + } + + @Test + fun `serialize() draws the BOTH, the character and the FROM, when the character is not null`() { + // given + val part = Expressions.trimBoth( + character = charExpression1, + value = stringExpression1, + ) + val context = TestRenderContext(serializer) + + // when + sut.serialize(part as JpqlTrimBoth, writer, context) + + // then + verifySequence { + writer.write("TRIM") + writer.writeParentheses(any()) + writer.write("BOTH") + writer.write(" ") + serializer.serialize(charExpression1, writer, context) + writer.write(" ") + writer.write("FROM") + writer.write(" ") + serializer.serialize(stringExpression1, writer, context) + } + } +} diff --git a/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimLeadingSerializerTest.kt b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimLeadingSerializerTest.kt new file mode 100644 index 000000000..f75065d92 --- /dev/null +++ b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimLeadingSerializerTest.kt @@ -0,0 +1,84 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrimLeading +import com.linecorp.kotlinjdsl.render.TestRenderContext +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.impl.annotations.MockK +import io.mockk.verifySequence +import org.assertj.core.api.WithAssertions +import org.junit.jupiter.api.Test + +@JpqlSerializerTest +class JpqlTrimLeadingSerializerTest : WithAssertions { + private val sut = JpqlTrimLeadingSerializer() + + @MockK + private lateinit var writer: JpqlWriter + + @MockK + private lateinit var serializer: JpqlRenderSerializer + + private val charExpression1 = Expressions.value('c') + private val stringExpression1 = Expressions.value("string1") + + @Test + fun handledType() { + // when + val actual = sut.handledType() + + // then + assertThat(actual).isEqualTo(JpqlTrimLeading::class) + } + + @Test + fun `serialize() draws the LEADING and the FROM, when the character is null`() { + // given + val part = Expressions.trimLeading( + value = stringExpression1, + ) + val context = TestRenderContext(serializer) + + // when + sut.serialize(part as JpqlTrimLeading, writer, context) + + // then + verifySequence { + writer.write("TRIM") + writer.writeParentheses(any()) + writer.write("LEADING") + writer.write(" ") + writer.write("FROM") + writer.write(" ") + serializer.serialize(stringExpression1, writer, context) + } + } + + @Test + fun `serialize() draws the LEADING, the character and the FROM, when the character is not null`() { + // given + val part = Expressions.trimLeading( + character = charExpression1, + value = stringExpression1, + ) + val context = TestRenderContext(serializer) + + // when + sut.serialize(part as JpqlTrimLeading, writer, context) + + // then + verifySequence { + writer.write("TRIM") + writer.writeParentheses(any()) + writer.write("LEADING") + writer.write(" ") + serializer.serialize(charExpression1, writer, context) + writer.write(" ") + writer.write("FROM") + writer.write(" ") + serializer.serialize(stringExpression1, writer, context) + } + } +} diff --git a/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimSerializerTest.kt b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimSerializerTest.kt new file mode 100644 index 000000000..236a8f4e5 --- /dev/null +++ b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimSerializerTest.kt @@ -0,0 +1,78 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrim +import com.linecorp.kotlinjdsl.render.TestRenderContext +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.impl.annotations.MockK +import io.mockk.verifySequence +import org.assertj.core.api.WithAssertions +import org.junit.jupiter.api.Test + +@JpqlSerializerTest +class JpqlTrimSerializerTest : WithAssertions { + private val sut = JpqlTrimSerializer() + + @MockK + private lateinit var writer: JpqlWriter + + @MockK + private lateinit var serializer: JpqlRenderSerializer + + private val charExpression1 = Expressions.value('c') + private val stringExpression1 = Expressions.value("string1") + + @Test + fun handledType() { + // when + val actual = sut.handledType() + + // then + assertThat(actual).isEqualTo(JpqlTrim::class) + } + + @Test + fun serialize() { + // given + val part = Expressions.trim( + value = stringExpression1, + ) + val context = TestRenderContext(serializer) + + // when + sut.serialize(part as JpqlTrim, writer, context) + + // then + verifySequence { + writer.write("TRIM") + writer.writeParentheses(any()) + serializer.serialize(stringExpression1, writer, context) + } + } + + @Test + fun `serialize() draws the character and the FROM, when the character is not null`() { + // given + val part = Expressions.trim( + character = charExpression1, + value = stringExpression1, + ) + val context = TestRenderContext(serializer) + + // when + sut.serialize(part as JpqlTrim, writer, context) + + // then + verifySequence { + writer.write("TRIM") + writer.writeParentheses(any()) + serializer.serialize(charExpression1, writer, context) + writer.write(" ") + writer.write("FROM") + writer.write(" ") + serializer.serialize(stringExpression1, writer, context) + } + } +} diff --git a/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimTrailingSerializerTest.kt b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimTrailingSerializerTest.kt new file mode 100644 index 000000000..a1a6dc34b --- /dev/null +++ b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlTrimTrailingSerializerTest.kt @@ -0,0 +1,84 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlTrimTrailing +import com.linecorp.kotlinjdsl.render.TestRenderContext +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.impl.annotations.MockK +import io.mockk.verifySequence +import org.assertj.core.api.WithAssertions +import org.junit.jupiter.api.Test + +@JpqlSerializerTest +class JpqlTrimTrailingSerializerTest : WithAssertions { + private val sut = JpqlTrimTrailingSerializer() + + @MockK + private lateinit var writer: JpqlWriter + + @MockK + private lateinit var serializer: JpqlRenderSerializer + + private val charExpression1 = Expressions.value('c') + private val stringExpression1 = Expressions.value("string1") + + @Test + fun handledType() { + // when + val actual = sut.handledType() + + // then + assertThat(actual).isEqualTo(JpqlTrimTrailing::class) + } + + @Test + fun `serialize() draws the TRAILING and the FROM, when the character is null`() { + // given + val part = Expressions.trimTrailing( + value = stringExpression1, + ) + val context = TestRenderContext(serializer) + + // when + sut.serialize(part as JpqlTrimTrailing, writer, context) + + // then + verifySequence { + writer.write("TRIM") + writer.writeParentheses(any()) + writer.write("TRAILING") + writer.write(" ") + writer.write("FROM") + writer.write(" ") + serializer.serialize(stringExpression1, writer, context) + } + } + + @Test + fun `serialize() draws the TRAILING, the character and the FROM, when the character is not null`() { + // given + val part = Expressions.trimTrailing( + character = charExpression1, + value = stringExpression1, + ) + val context = TestRenderContext(serializer) + + // when + sut.serialize(part as JpqlTrimTrailing, writer, context) + + // then + verifySequence { + writer.write("TRIM") + writer.writeParentheses(any()) + writer.write("TRAILING") + writer.write(" ") + serializer.serialize(charExpression1, writer, context) + writer.write(" ") + writer.write("FROM") + writer.write(" ") + serializer.serialize(stringExpression1, writer, context) + } + } +} From ee9e9fc32ae43150d4343c7e218afc735ef84077 Mon Sep 17 00:00:00 2001 From: waahhh Date: Wed, 22 Nov 2023 12:35:02 +0900 Subject: [PATCH 6/7] feat(dsl): add dsl for trim function support --- .../com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt | 108 ++++++++++++++++++ .../dsl/jpql/expression/TrimFromStep.kt | 19 +++ .../jpql/expression/impl/TrimBothBuilder.kt | 23 ++++ .../dsl/jpql/expression/impl/TrimBothDsl.kt | 31 +++++ .../dsl/jpql/expression/impl/TrimBuilder.kt | 23 ++++ .../dsl/jpql/expression/impl/TrimDsl.kt | 31 +++++ .../expression/impl/TrimLeadingBuilder.kt | 23 ++++ .../jpql/expression/impl/TrimLeadingDsl.kt | 31 +++++ .../expression/impl/TrimTrailingBuilder.kt | 23 ++++ .../jpql/expression/impl/TrimTrailingDsl.kt | 31 +++++ 10 files changed, 343 insertions(+) create mode 100644 dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimFromStep.kt create mode 100644 dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimBothBuilder.kt create mode 100644 dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimBothDsl.kt create mode 100644 dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimBuilder.kt create mode 100644 dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimDsl.kt create mode 100644 dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimLeadingBuilder.kt create mode 100644 dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimLeadingDsl.kt create mode 100644 dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimTrailingBuilder.kt create mode 100644 dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimTrailingDsl.kt 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 e680ff6f5..f0af2dd46 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,8 +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.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.TrimBothDsl +import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.TrimDsl +import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.TrimLeadingDsl +import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.TrimTrailingDsl import com.linecorp.kotlinjdsl.dsl.jpql.join.AssociationJoinOnStep import com.linecorp.kotlinjdsl.dsl.jpql.join.JoinOnStep import com.linecorp.kotlinjdsl.dsl.jpql.join.impl.AssociationFetchJoinDsl @@ -40,6 +45,7 @@ import com.linecorp.kotlinjdsl.querymodel.jpql.sort.Sort import java.math.BigDecimal import java.math.BigInteger import kotlin.internal.Exact +import kotlin.internal.LowPriorityInOverloadResolution import kotlin.reflect.KClass import kotlin.reflect.KFunction1 import kotlin.reflect.KProperty1 @@ -1084,6 +1090,108 @@ open class Jpql : JpqlDsl { return Expressions.type(path.toPath()) } + /** + * Creates an expression that represents a string with the whitespaces all trimmed + * from the both sides of the string. + */ + @SinceJdsl("3.1.0") + fun trim(value: String): Expression { + return Expressions.trim(value = Expressions.value(value)) + } + + /** + * Creates an expression that represents a string with the whitespaces all trimmed + * from the both sides of the string. + */ + @SinceJdsl("3.1.0") + fun trim(value: Expressionable): Expression { + return Expressions.trim(value = value.toExpression()) + } + + /** + * Creates an expression that represents a string with the specified characters all trimmed + * from the both sides of the string. + * If the character is not specified, it will be assumed to be whitespace. + */ + @LowPriorityInOverloadResolution + @SinceJdsl("3.1.0") + fun trim(character: Char? = null): TrimFromStep { + return TrimDsl(character?.let { Expressions.value(it) }) + } + + /** + * Creates an expression that represents a string with the specified characters all trimmed + * from the both sides of the string. + * If the character is not specified, it will be assumed to be whitespace. + */ + @SinceJdsl("3.1.0") + fun trim(character: Expressionable? = null): TrimFromStep { + return TrimDsl(character?.let { it.toExpression() }) + } + + /** + * Creates an expression that represents a string with the specified characters all trimmed + * from the leading side of the string. + * If the character is not specified, it will be assumed to be whitespace. + */ + @LowPriorityInOverloadResolution + @SinceJdsl("3.1.0") + fun trimLeading(character: Char? = null): TrimFromStep { + return TrimLeadingDsl(character?.let { Expressions.value(it) }) + } + + /** + * Creates an expression that represents a string with the specified characters all trimmed + * from the leading side of the string. + * If the character is not specified, it will be assumed to be whitespace. + */ + @SinceJdsl("3.1.0") + fun trimLeading(character: Expressionable? = null): TrimFromStep { + return TrimLeadingDsl(character?.let { it.toExpression() }) + } + + /** + * Creates an expression that represents a string with the specified characters all trimmed + * from the trailing side of the string. + * If the character is not specified, it will be assumed to be whitespace. + */ + @LowPriorityInOverloadResolution + @SinceJdsl("3.1.0") + fun trimTrailing(character: Char? = null): TrimFromStep { + return TrimTrailingDsl(character?.let { Expressions.value(it) }) + } + + /** + * Creates an expression that represents a string with the specified characters all trimmed + * from the trailing side of the string. + * If the character is not specified, it will be assumed to be whitespace. + */ + @SinceJdsl("3.1.0") + fun trimTrailing(character: Expressionable? = null): TrimFromStep { + return TrimTrailingDsl(character?.let { it.toExpression() }) + } + + /** + * Creates an expression that represents a string with the specified characters all trimmed + * from the both sides of the string. + * If the character is not specified, it will be assumed to be whitespace. + */ + @LowPriorityInOverloadResolution + @SinceJdsl("3.1.0") + fun trimBoth(character: Char? = null): TrimFromStep { + return TrimBothDsl(character?.let { Expressions.value(it) }) + } + + /** + * Creates an expression that represents a string with the specified characters all trimmed + * from the both sides of the string. + * If the character is not specified, it will be assumed to be whitespace. + */ + @SinceJdsl("3.1.0") + fun trimBoth(character: Expressionable? = null): TrimFromStep { + return TrimBothDsl(character?.let { it.toExpression() }) + } + /** * Creates an expression that represents the string in uppercase. */ diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimFromStep.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimFromStep.kt new file mode 100644 index 000000000..9403cac00 --- /dev/null +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimFromStep.kt @@ -0,0 +1,19 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression + +import com.linecorp.kotlinjdsl.SinceJdsl +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable + +@SinceJdsl("3.1.0") +interface TrimFromStep { + /** + * Creates a from in a trim expression. + */ + @SinceJdsl("3.1.0") + fun from(value: String): Expressionable + + /** + * Creates a from in a trim expression. + */ + @SinceJdsl("3.1.0") + fun from(value: Expressionable): Expressionable +} diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimBothBuilder.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimBothBuilder.kt new file mode 100644 index 000000000..1ded39b59 --- /dev/null +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimBothBuilder.kt @@ -0,0 +1,23 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression.impl + +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions + +internal data class TrimBothBuilder( + private val character: Expression? = null, +) { + private lateinit var value: Expression + + fun from(value: Expression): TrimBothBuilder { + this.value = value + + return this + } + + fun build(): Expression { + return Expressions.trimBoth( + character = character, + value = value, + ) + } +} diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimBothDsl.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimBothDsl.kt new file mode 100644 index 000000000..00a41af0e --- /dev/null +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimBothDsl.kt @@ -0,0 +1,31 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression.impl + +import com.linecorp.kotlinjdsl.dsl.jpql.expression.TrimFromStep +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions + +@PublishedApi +internal data class TrimBothDsl( + private val builder: TrimBothBuilder, +) : TrimFromStep, Expressionable { + constructor( + character: Expression? = null, + ) : this(TrimBothBuilder(character)) + + override fun from(value: String): Expressionable { + builder.from(Expressions.value(value)) + + return this + } + + override fun from(value: Expressionable): Expressionable { + builder.from(value.toExpression()) + + return this + } + + override fun toExpression(): Expression { + return builder.build() + } +} diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimBuilder.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimBuilder.kt new file mode 100644 index 000000000..4961d3c31 --- /dev/null +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimBuilder.kt @@ -0,0 +1,23 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression.impl + +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions + +internal data class TrimBuilder( + private val character: Expression? = null, +) { + private lateinit var value: Expression + + fun from(value: Expression): TrimBuilder { + this.value = value + + return this + } + + fun build(): Expression { + return Expressions.trim( + character = character, + value = value, + ) + } +} diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimDsl.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimDsl.kt new file mode 100644 index 000000000..4e7dd1f61 --- /dev/null +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimDsl.kt @@ -0,0 +1,31 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression.impl + +import com.linecorp.kotlinjdsl.dsl.jpql.expression.TrimFromStep +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions + +@PublishedApi +internal data class TrimDsl( + private val builder: TrimBuilder, +) : TrimFromStep, Expressionable { + constructor( + character: Expression? = null, + ) : this(TrimBuilder(character)) + + override fun from(value: String): Expressionable { + builder.from(Expressions.value(value)) + + return this + } + + override fun from(value: Expressionable): Expressionable { + builder.from(value.toExpression()) + + return this + } + + override fun toExpression(): Expression { + return builder.build() + } +} diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimLeadingBuilder.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimLeadingBuilder.kt new file mode 100644 index 000000000..e90b478fb --- /dev/null +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimLeadingBuilder.kt @@ -0,0 +1,23 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression.impl + +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions + +internal data class TrimLeadingBuilder( + private val character: Expression? = null, +) { + private lateinit var value: Expression + + fun from(value: Expression): TrimLeadingBuilder { + this.value = value + + return this + } + + fun build(): Expression { + return Expressions.trimLeading( + character = character, + value = value, + ) + } +} diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimLeadingDsl.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimLeadingDsl.kt new file mode 100644 index 000000000..269a399ee --- /dev/null +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimLeadingDsl.kt @@ -0,0 +1,31 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression.impl + +import com.linecorp.kotlinjdsl.dsl.jpql.expression.TrimFromStep +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions + +@PublishedApi +internal data class TrimLeadingDsl( + private val builder: TrimLeadingBuilder, +) : TrimFromStep, Expressionable { + constructor( + character: Expression? = null, + ) : this(TrimLeadingBuilder(character)) + + override fun from(value: String): Expressionable { + builder.from(Expressions.value(value)) + + return this + } + + override fun from(value: Expressionable): Expressionable { + builder.from(value.toExpression()) + + return this + } + + override fun toExpression(): Expression { + return builder.build() + } +} diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimTrailingBuilder.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimTrailingBuilder.kt new file mode 100644 index 000000000..5cf547710 --- /dev/null +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimTrailingBuilder.kt @@ -0,0 +1,23 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression.impl + +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions + +internal data class TrimTrailingBuilder( + private val character: Expression? = null, +) { + private lateinit var value: Expression + + fun from(value: Expression): TrimTrailingBuilder { + this.value = value + + return this + } + + fun build(): Expression { + return Expressions.trimTrailing( + character = character, + value = value, + ) + } +} diff --git a/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimTrailingDsl.kt b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimTrailingDsl.kt new file mode 100644 index 000000000..4faa24e99 --- /dev/null +++ b/dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/impl/TrimTrailingDsl.kt @@ -0,0 +1,31 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression.impl + +import com.linecorp.kotlinjdsl.dsl.jpql.expression.TrimFromStep +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions + +@PublishedApi +internal data class TrimTrailingDsl( + private val builder: TrimTrailingBuilder, +) : TrimFromStep, Expressionable { + constructor( + character: Expression? = null, + ) : this(TrimTrailingBuilder(character)) + + override fun from(value: String): Expressionable { + builder.from(Expressions.value(value)) + + return this + } + + override fun from(value: Expressionable): Expressionable { + builder.from(value.toExpression()) + + return this + } + + override fun toExpression(): Expression { + return builder.build() + } +} From 787893b6a1e6030b7a2bf6f1c35d88cbd4391565 Mon Sep 17 00:00:00 2001 From: waahhh Date: Wed, 22 Nov 2023 12:36:14 +0900 Subject: [PATCH 7/7] test(dsl): for Trim(Leading, Trailing, Both)Dsl --- .../dsl/jpql/expression/TrimBothDslTest.kt | 121 ++++++++++++++ .../dsl/jpql/expression/TrimDslTest.kt | 155 ++++++++++++++++++ .../dsl/jpql/expression/TrimLeadingDslTest.kt | 121 ++++++++++++++ .../jpql/expression/TrimTrailingDslTest.kt | 121 ++++++++++++++ 4 files changed, 518 insertions(+) create mode 100644 dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimBothDslTest.kt create mode 100644 dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimDslTest.kt create mode 100644 dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimLeadingDslTest.kt create mode 100644 dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimTrailingDslTest.kt diff --git a/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimBothDslTest.kt b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimBothDslTest.kt new file mode 100644 index 000000000..2c3c27f36 --- /dev/null +++ b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimBothDslTest.kt @@ -0,0 +1,121 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression + +import com.linecorp.kotlinjdsl.dsl.jpql.queryPart +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import org.assertj.core.api.WithAssertions +import org.junit.jupiter.api.Test + +class TrimBothDslTest : WithAssertions { + private val char1 = 'c' + private val string1 = "string1" + + private val charExpression1 = Expressions.value(char1) + private val stringExpression1 = Expressions.value(string1) + + @Test + fun `trimBoth() without a char, from() with a string`() { + // when + val expression = queryPart { + trimBoth().from(string1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimBoth( + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimBoth() without a char, from() with a string expression`() { + // when + val expression = queryPart { + trimBoth().from(stringExpression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimBoth( + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimBoth() with a char, from() with a string`() { + // when + val expression = queryPart { + trimBoth(char1).from(string1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimBoth( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimBoth() with a char, from() with a string expression`() { + // when + val expression = queryPart { + trimBoth(char1).from(stringExpression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimBoth( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimBoth() with a char expression, from() with a string`() { + // when + val expression = queryPart { + trimBoth(charExpression1).from(string1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimBoth( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimBoth() with a char expression, from() with a string expression`() { + // when + val expression = queryPart { + trimBoth(charExpression1).from(stringExpression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimBoth( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } +} diff --git a/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimDslTest.kt b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimDslTest.kt new file mode 100644 index 000000000..c632862ea --- /dev/null +++ b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimDslTest.kt @@ -0,0 +1,155 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression + +import com.linecorp.kotlinjdsl.dsl.jpql.queryPart +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import org.assertj.core.api.WithAssertions +import org.junit.jupiter.api.Test + +class TrimDslTest : WithAssertions { + private val char1 = 'c' + private val string1 = "string1" + + private val charExpression1 = Expressions.value(char1) + private val stringExpression1 = Expressions.value(string1) + + @Test + fun `trim() with a string`() { + // when + val expression = queryPart { + trim(string1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trim( + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trim() with a string expression`() { + // when + val expression = queryPart { + trim(stringExpression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trim( + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trim() without a char, from() with a string`() { + // when + val expression = queryPart { + trim().from(string1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trim( + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trim() without a char, from() with a string expression`() { + // when + val expression = queryPart { + trim().from(stringExpression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trim( + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trim() with a char, from() with a string`() { + // when + val expression = queryPart { + trim(char1).from(string1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trim( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trim() with a char, from() with a string expression`() { + // when + val expression = queryPart { + trim(char1).from(stringExpression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trim( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trim() with a char expression, from() with a string`() { + // when + val expression = queryPart { + trim(charExpression1).from(string1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trim( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trim() with a char expression, from() with a string expression`() { + // when + val expression = queryPart { + trim(charExpression1).from(stringExpression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trim( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } +} diff --git a/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimLeadingDslTest.kt b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimLeadingDslTest.kt new file mode 100644 index 000000000..be0eb2ee9 --- /dev/null +++ b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimLeadingDslTest.kt @@ -0,0 +1,121 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression + +import com.linecorp.kotlinjdsl.dsl.jpql.queryPart +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import org.assertj.core.api.WithAssertions +import org.junit.jupiter.api.Test + +class TrimLeadingDslTest : WithAssertions { + private val char1 = 'c' + private val string1 = "string1" + + private val charExpression1 = Expressions.value(char1) + private val stringExpression1 = Expressions.value(string1) + + @Test + fun `trimLeading() without a char, from() with a string`() { + // when + val expression = queryPart { + trimLeading().from(string1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimLeading( + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimLeading() without a char, from() with a string expression`() { + // when + val expression = queryPart { + trimLeading().from(stringExpression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimLeading( + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimLeading() with a char, from() with a string`() { + // when + val expression = queryPart { + trimLeading(char1).from(string1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimLeading( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimLeading() with a char, from() with a string expression`() { + // when + val expression = queryPart { + trimLeading(char1).from(stringExpression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimLeading( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimLeading() with a char expression, from() with a string`() { + // when + val expression = queryPart { + trimLeading(charExpression1).from(string1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimLeading( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimLeading() with a char expression, from() with a string expression`() { + // when + val expression = queryPart { + trimLeading(charExpression1).from(stringExpression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimLeading( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } +} diff --git a/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimTrailingDslTest.kt b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimTrailingDslTest.kt new file mode 100644 index 000000000..d152e738b --- /dev/null +++ b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/TrimTrailingDslTest.kt @@ -0,0 +1,121 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression + +import com.linecorp.kotlinjdsl.dsl.jpql.queryPart +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import org.assertj.core.api.WithAssertions +import org.junit.jupiter.api.Test + +class TrimTrailingDslTest : WithAssertions { + private val char1 = 'c' + private val string1 = "string1" + + private val charExpression1 = Expressions.value(char1) + private val stringExpression1 = Expressions.value(string1) + + @Test + fun `trimTrailing() without a char, from() with a string`() { + // when + val expression = queryPart { + trimTrailing().from(string1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimTrailing( + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimTrailing() without a char, from() with a string expression`() { + // when + val expression = queryPart { + trimTrailing().from(stringExpression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimTrailing( + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimTrailing() with a char, from() with a string`() { + // when + val expression = queryPart { + trimTrailing(char1).from(string1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimTrailing( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimTrailing() with a char, from() with a string expression`() { + // when + val expression = queryPart { + trimTrailing(char1).from(stringExpression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimTrailing( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimTrailing() with a char expression, from() with a string`() { + // when + val expression = queryPart { + trimTrailing(charExpression1).from(string1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimTrailing( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } + + @Test + fun `trimTrailing() with a char expression, from() with a string expression`() { + // when + val expression = queryPart { + trimTrailing(charExpression1).from(stringExpression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.trimTrailing( + character = charExpression1, + value = stringExpression1, + ) + + assertThat(actual.toExpression()).isEqualTo(expected) + } +}