From 61612ff5f525fa7ed5ad75b58dcf906654d1a33b Mon Sep 17 00:00:00 2001 From: Jake Son Date: Thu, 1 Feb 2024 07:06:13 +0900 Subject: [PATCH 1/3] feat: implement ln function --- .../com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt | 16 +++++++ .../dsl/jpql/expression/LnDslTest.kt | 47 +++++++++++++++++++ .../querymodel/jpql/expression/Expressions.kt | 9 ++++ .../querymodel/jpql/expression/impl/JpqlLn.kt | 12 +++++ .../jpql/expression/ExpressionsTest.kt | 14 ++++++ 5 files changed, 98 insertions(+) create mode 100644 dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/LnDslTest.kt create mode 100644 query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlLn.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 75b37025d..6dd8ed070 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 @@ -584,6 +584,22 @@ open class Jpql : JpqlDsl { return Expressions.floor(value.toExpression()) } + /** + * Creates an expression that represents the natural logarithm of value. + */ + @SinceJdsl("3.4.0") + fun ln(expr: KProperty1): Expression { + return Expressions.ln(Paths.path(expr)) + } + + /** + * Creates an expression that represents the natural logarithm of value. + */ + @SinceJdsl("3.4.0") + fun ln(value: Expressionable): Expression { + return Expressions.ln(value.toExpression()) + } + /** * Creates an expression that represents the rounding of the value to a specified scale. */ diff --git a/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/LnDslTest.kt b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/LnDslTest.kt new file mode 100644 index 000000000..ad5ea8750 --- /dev/null +++ b/dsl/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/expression/LnDslTest.kt @@ -0,0 +1,47 @@ +package com.linecorp.kotlinjdsl.dsl.jpql.expression + +import com.linecorp.kotlinjdsl.dsl.jpql.entity.book.Book +import com.linecorp.kotlinjdsl.dsl.jpql.queryPart +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import com.linecorp.kotlinjdsl.querymodel.jpql.path.Paths +import org.assertj.core.api.WithAssertions +import org.junit.jupiter.api.Test + +class LnDslTest : WithAssertions { + private val expression1 = Paths.path(Book::salePrice) + + @Test + fun `ln() with a property`() { + // when + val expression = queryPart { + ln(Book::price) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.ln( + value = Paths.path(Book::price), + ) + + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `ln() with a expression`() { + // when + val expression = queryPart { + ln(expression1) + }.toExpression() + + val actual: Expression = expression // for type check + + // then + val expected = Expressions.ln( + value = expression1, + ) + + 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 045d93ea7..590b914a4 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 @@ -20,6 +20,7 @@ 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.JpqlLength import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLiteral +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLn import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLocate import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLower import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlMax @@ -235,6 +236,14 @@ object Expressions { return JpqlFloor(value) } + /** + * Creates an expression that represents the natural logarithm of the value. + */ + @SinceJdsl("3.4.0") + fun ln(value: Expression): Expression { + return JpqlLn(value) + } + /** * Creates an expression that represents the rounding of the specified value to a specified scale. */ diff --git a/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlLn.kt b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlLn.kt new file mode 100644 index 000000000..36268c213 --- /dev/null +++ b/query-model/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/querymodel/jpql/expression/impl/JpqlLn.kt @@ -0,0 +1,12 @@ +package com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl + +import com.linecorp.kotlinjdsl.Internal +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression + +/** + * Expression that applies natural logarithm function to [value]. + */ +@Internal +data class JpqlLn internal constructor( + val value: Expression, +) : Expression 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 9fb1f6b87..69ee10a8d 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 @@ -22,6 +22,7 @@ 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.JpqlLength import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLiteral +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLn import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLocate import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLower import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlMax @@ -376,6 +377,19 @@ class ExpressionsTest : WithAssertions { assertThat(actual).isEqualTo(expected) } + @Test + fun ln() { + // when + val actual = Expressions.ln(doubleExpression1) + + // then + val expected = JpqlLn( + doubleExpression1, + ) + + assertThat(actual).isEqualTo(expected) + } + @Test fun round() { // when From 19aa609f03d7c6bffb6d91b373e7cf8dd8a61b98 Mon Sep 17 00:00:00 2001 From: Jake Son Date: Thu, 1 Feb 2024 07:08:34 +0900 Subject: [PATCH 2/3] feat: implement ln function serializer --- .../render/jpql/JpqlRenderContext.kt | 2 + .../jpql/serializer/impl/JpqlLnSerializer.kt | 26 +++++++++ .../serializer/impl/JpqlLnSerializerTest.kt | 55 +++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLnSerializer.kt create mode 100644 render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLnSerializerTest.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 094735378..e2a7df900 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 @@ -72,6 +72,7 @@ import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLessThanOrEqualTo import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLessThanSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLikeSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLiteralSerializer +import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLnSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLocateSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlLowerSerializer import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlMaxSerializer @@ -322,6 +323,7 @@ private class DefaultModule : JpqlRenderModule { JpqlLessThanSerializer(), JpqlLikeSerializer(), JpqlLiteralSerializer(), + JpqlLnSerializer(), JpqlLocateSerializer(), JpqlLowerSerializer(), JpqlMaxSerializer(), diff --git a/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLnSerializer.kt b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLnSerializer.kt new file mode 100644 index 000000000..0c8ded7b4 --- /dev/null +++ b/render/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLnSerializer.kt @@ -0,0 +1,26 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.Internal +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLn +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 JpqlLnSerializer : JpqlSerializer> { + override fun handledType(): KClass> { + return JpqlLn::class + } + + override fun serialize(part: JpqlLn<*>, writer: JpqlWriter, context: RenderContext) { + val delegate = context.getValue(JpqlRenderSerializer) + + writer.write("LN") + + writer.writeParentheses { + delegate.serialize(part.value, writer, context) + } + } +} diff --git a/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLnSerializerTest.kt b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLnSerializerTest.kt new file mode 100644 index 000000000..61f489b33 --- /dev/null +++ b/render/jpql/src/test/kotlin/com/linecorp/kotlinjdsl/render/jpql/serializer/impl/JpqlLnSerializerTest.kt @@ -0,0 +1,55 @@ +package com.linecorp.kotlinjdsl.render.jpql.serializer.impl + +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressions +import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlLn +import com.linecorp.kotlinjdsl.querymodel.jpql.path.Paths +import com.linecorp.kotlinjdsl.render.TestRenderContext +import com.linecorp.kotlinjdsl.render.jpql.entity.book.Book +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 JpqlLnSerializerTest : WithAssertions { + private val sut = JpqlLnSerializer() + + @MockK + private lateinit var writer: JpqlWriter + + @MockK + private lateinit var serializer: JpqlRenderSerializer + + private val expression1 = Paths.path(Book::price) + + @Test + fun handledType() { + // when + val actual = sut.handledType() + + // then + assertThat(actual).isEqualTo(JpqlLn::class) + } + + @Test + fun serialize() { + // given + val part = Expressions.ln( + value = expression1, + ) + val context = TestRenderContext(serializer) + + // when + sut.serialize(part as JpqlLn<*>, writer, context) + + // then + verifySequence { + writer.write("LN") + writer.writeParentheses(any()) + serializer.serialize(expression1, writer, context) + } + } +} From 3f049da2d86de34eddfa3dad19cb956d1c1716fa Mon Sep 17 00:00:00 2001 From: Jake Son Date: Thu, 1 Feb 2024 07:10:02 +0900 Subject: [PATCH 3/3] docs: add ln function description --- docs/en/jpql-with-kotlin-jdsl/expressions.md | 5 +++-- docs/ko/jpql-with-kotlin-jdsl/expressions.md | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/en/jpql-with-kotlin-jdsl/expressions.md b/docs/en/jpql-with-kotlin-jdsl/expressions.md index 287f4e195..e6f510b16 100644 --- a/docs/en/jpql-with-kotlin-jdsl/expressions.md +++ b/docs/en/jpql-with-kotlin-jdsl/expressions.md @@ -226,6 +226,7 @@ Use the following functions to build arithmetic functions: * ABS (abs) * CEILING (ceiling) * FLOOR (floor) +* LN (ln) * ROUND (round) * SQRT (sqrt) @@ -236,6 +237,8 @@ ceiling(path(Book::price)) floor(path(Book::price)) +ln(path(Book::price)) + round(path(Book::price), 2) sqrt(path(Book::price)) @@ -244,8 +247,6 @@ sqrt(path(Book::price)) | Function | DSL function | |----------|--------------| | EXP | not yet | -| FLOOR | not yet | -| LN | not yet | | MOD | not yet | | POWER | not yet | | SIGN | not yet | diff --git a/docs/ko/jpql-with-kotlin-jdsl/expressions.md b/docs/ko/jpql-with-kotlin-jdsl/expressions.md index 9c13e1c98..332568c5a 100644 --- a/docs/ko/jpql-with-kotlin-jdsl/expressions.md +++ b/docs/ko/jpql-with-kotlin-jdsl/expressions.md @@ -222,6 +222,7 @@ locate("Book", path(Book::title)) * ABS (abs) * CEILING (ceiling) * FLOOR (floor) +* LN (ln) * ROUND (round) * SQRT (sqrt) @@ -232,6 +233,8 @@ ceiling(path(Book::price)) floor(path(Book::price)) +ln(path(Book::price)) + round(path(Book::price), 2) sqrt(path(Book::price)) @@ -240,8 +243,6 @@ sqrt(path(Book::price)) | Function | DSL function | |----------|--------------| | EXP | not yet | -| FLOOR | not yet | -| LN | not yet | | MOD | not yet | | POWER | not yet | | SIGN | not yet |