Skip to content

Commit

Permalink
Merge pull request #612 from jbl428/feat/sqrt
Browse files Browse the repository at this point in the history
Support Arithmetic function SQRT
  • Loading branch information
shouwn authored Jan 31, 2024
2 parents 2f83bf5 + 968d838 commit 475f6b5
Show file tree
Hide file tree
Showing 10 changed files with 231 additions and 47 deletions.
4 changes: 3 additions & 1 deletion docs/en/jpql-with-kotlin-jdsl/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,14 @@ Use the following functions to build arithmetic functions:

* ABS (abs)
* CEILING (ceiling)
* SQRT (sqrt)

```kotlin
abs(path(Book::price))

ceiling(path(Book::price))

sqrt(path(Book::price))
```

| Function | DSL function |
Expand All @@ -241,7 +244,6 @@ ceiling(path(Book::price))
| POWER | not yet |
| ROUND | not yet |
| SIGN | not yet |
| SQRT | not yet |
| SIZE | not yet |
| INDEX | not yet |

Expand Down
5 changes: 3 additions & 2 deletions docs/ko/jpql-with-kotlin-jdsl/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ avg(path(FullTimeEmployee::annualSalary)(EmployeeSalary::value)).`as`(BigDecimal
* \- (minus)
* \* (times)
* / (div)
* ceiling

```kotlin
path(Book::price).plus(path(Book::salePrice))
Expand Down Expand Up @@ -222,11 +221,14 @@ locate("Book", path(Book::title))

* ABS (abs)
* CEILING (ceiling)
* SQRT (sqrt)

```kotlin
abs(path(Book::price))

ceiling(path(Book::price))

sqrt(path(Book::price))
```

| Function | DSL function |
Expand All @@ -238,7 +240,6 @@ ceiling(path(Book::price))
| POWER | not yet |
| ROUND | not yet |
| SIGN | not yet |
| SQRT | not yet |
| SIZE | not yet |
| INDEX | not yet |

Expand Down
20 changes: 18 additions & 2 deletions dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt
Original file line number Diff line number Diff line change
Expand Up @@ -553,21 +553,37 @@ open class Jpql : JpqlDsl {
}

/**
* Creates an expression that is enclosed in ceiling
* Creates an expression that is enclosed in ceiling.
*/
@SinceJdsl("3.4.0")
fun <T : Any, V : Number> ceiling(expr: KProperty1<T, @Exact V>): Expression<V> {
return Expressions.ceiling(Paths.path(expr))
}

/**
* Creates an expression that is enclosed in ceiling
* Creates an expression that is enclosed in ceiling.
*/
@SinceJdsl("3.4.0")
fun <T : Number> ceiling(value: Expressionable<T>): Expression<T> {
return Expressions.ceiling(value.toExpression())
}

/**
* Creates an expression that represents the square root of value.
*/
@SinceJdsl("3.4.0")
fun <T : Any, V : Number> sqrt(expr: KProperty1<T, @Exact V>): Expression<Double> {
return Expressions.sqrt(Paths.path(expr))
}

/**
* Creates an expression that represents the square root of value.
*/
@SinceJdsl("3.4.0")
fun <T : Number> sqrt(value: Expressionable<T>): Expression<Double> {
return Expressions.sqrt(value.toExpression())
}

/**
* Creates an expression that represents the count of non-null values.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -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 SqrtDslTest : WithAssertions {
private val expression1 = Paths.path(Book::salePrice)

@Test
fun `sqrt() with a property`() {
// when
val expression = queryPart {
sqrt(Book::price)
}.toExpression()

val actual: Expression<Double> = expression // for type check

// then
val expected = Expressions.sqrt(
value = Paths.path(Book::price),
)

assertThat(actual).isEqualTo(expected)
}

@Test
fun `sqrt() with a expression`() {
// when
val expression = queryPart {
sqrt(expression1)
}.toExpression()

val actual: Expression<Double> = expression // for type check

// then
val expected = Expressions.sqrt(
value = expression1,
)

assertThat(actual).isEqualTo(expected)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlNullIf
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.JpqlSqrt
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlSubquery
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlSubstring
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlSum
Expand Down Expand Up @@ -168,14 +169,6 @@ object Expressions {
return JpqlParam(name, value)
}

/**
* Creates an expression that represents the absolute value.
*/
@SinceJdsl("3.4.0")
fun <T : Number> abs(value: Expression<T>): Expression<T> {
return JpqlAbs(value)
}

/**
* Creates an expression that represents the plus of values.
*
Expand All @@ -196,14 +189,6 @@ object Expressions {
return JpqlMinus(value1, value2)
}

/**
* Creates an expression that is enclosed in ceiling
*/
@SinceJdsl("3.4.0")
fun <T : Number> ceiling(value: Expression<T>): Expression<T> {
return JpqlCeiling(value)
}

/**
* Creates an expression that represents the times of values.
*
Expand All @@ -224,6 +209,30 @@ object Expressions {
return JpqlDivide(value1, value2)
}

/**
* Creates an expression that represents the absolute value.
*/
@SinceJdsl("3.4.0")
fun <T : Number> abs(value: Expression<T>): Expression<T> {
return JpqlAbs(value)
}

/**
* Creates an expression that is enclosed in ceiling.
*/
@SinceJdsl("3.4.0")
fun <T : Number> ceiling(value: Expression<T>): Expression<T> {
return JpqlCeiling(value)
}

/**
* Creates an expression that represents the square root of the value.
*/
@SinceJdsl("3.4.0")
fun <T : Number> sqrt(value: Expression<T>): Expression<Double> {
return JpqlSqrt(value)
}

/**
* Creates an expression that represents the count of non-null values.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -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 calculates the square root of [value].
*/
@Internal
data class JpqlSqrt<T : Number> internal constructor(
val value: Expression<T>,
) : Expression<Double>
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlNullIf
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.JpqlSqrt
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlSubquery
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlSubstring
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlSum
Expand Down Expand Up @@ -278,19 +279,6 @@ class ExpressionsTest : WithAssertions {
assertThat(actual).isEqualTo(expected)
}

@Test
fun abs() {
// when
val actual = Expressions.abs(intExpression1)

// then
val expected = JpqlAbs<Int>(
intExpression1,
)

assertThat(actual).isEqualTo(expected)
}

@Test
fun plus() {
// when
Expand Down Expand Up @@ -347,6 +335,45 @@ class ExpressionsTest : WithAssertions {
assertThat(actual).isEqualTo(expected)
}

@Test
fun abs() {
// when
val actual = Expressions.abs(intExpression1)

// then
val expected = JpqlAbs<Int>(
intExpression1,
)

assertThat(actual).isEqualTo(expected)
}

@Test
fun ceiling() {
// when
val actual = Expressions.ceiling(doubleExpression1)

// then
val expected = JpqlCeiling(
doubleExpression1,
)

assertThat(actual).isEqualTo(expected)
}

@Test
fun sqrt() {
// when
val actual = Expressions.sqrt(intExpression1)

// then
val expected = JpqlSqrt(
intExpression1,
)

assertThat(actual).isEqualTo(expected)
}

@ParameterizedTest
@ValueSource(booleans = [true, false])
fun count(distinct: Boolean) {
Expand Down Expand Up @@ -902,17 +929,4 @@ class ExpressionsTest : WithAssertions {

assertThat(actual).isEqualTo(expected)
}

@Test
fun ceiling() {
// when
val actual = Expressions.ceiling(doubleExpression1)

// then
val expected = JpqlCeiling(
doubleExpression1,
)

assertThat(actual).isEqualTo(expected)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlPlusSerializer
import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlPredicateParenthesesSerializer
import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlSelectQuerySerializer
import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlSortSerializer
import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlSqrtSerializer
import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlSubquerySerializer
import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlSubstringSerializer
import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlSumSerializer
Expand Down Expand Up @@ -344,6 +345,7 @@ private class DefaultModule : JpqlRenderModule {
JpqlPredicateParenthesesSerializer(),
JpqlSelectQuerySerializer(),
JpqlSortSerializer(),
JpqlSqrtSerializer(),
JpqlSubquerySerializer(),
JpqlSubstringSerializer(),
JpqlSumSerializer(),
Expand Down
Original file line number Diff line number Diff line change
@@ -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.JpqlSqrt
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 JpqlSqrtSerializer : JpqlSerializer<JpqlSqrt<*>> {
override fun handledType(): KClass<JpqlSqrt<*>> {
return JpqlSqrt::class
}

override fun serialize(part: JpqlSqrt<*>, writer: JpqlWriter, context: RenderContext) {
val delegate = context.getValue(JpqlRenderSerializer)

writer.write("SQRT")

writer.writeParentheses {
delegate.serialize(part.value, writer, context)
}
}
}
Loading

0 comments on commit 475f6b5

Please sign in to comment.