Skip to content

Commit

Permalink
Merge pull request #614 from esperar/feature/ceiling
Browse files Browse the repository at this point in the history
Support Arithmetic function CEILING
  • Loading branch information
shouwn authored Jan 30, 2024
2 parents a52c502 + 50a8ab4 commit 9570d83
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 1 deletion.
6 changes: 5 additions & 1 deletion docs/en/jpql-with-kotlin-jdsl/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ minDistinct(path(Book::price))

sum(path(Book::price))
sumDistinct(path(Book::price))

ceiling(path(Book::price))
```

### Sum
Expand Down Expand Up @@ -202,19 +204,21 @@ Kotlin JDSL provides a series of functions to support built-in functions in JPA.
| LENGTH | support |
| LOCATE | support |


### Arithmetic functions

Use the following functions to build arithmetic functions:

* ceiling
* abs

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

| Function | DSL function |
|----------|--------------|
| CEILING | not yet |
| EXP | not yet |
| FLOOR | not yet |
| LN | not yet |
Expand Down
5 changes: 5 additions & 0 deletions docs/ko/jpql-with-kotlin-jdsl/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ avg(path(FullTimeEmployee::annualSalary)(EmployeeSalary::value)).`as`(BigDecimal
* \- (minus)
* \* (times)
* / (div)
* ceiling

```kotlin
path(Book::price).plus(path(Book::salePrice))
Expand Down Expand Up @@ -204,14 +205,18 @@ Kotlin JDSL은 JPA에서 제공하는 여러 함수들을 지원하기 위함

산술 함수를 만들기 위해서는 다음 함수들을 사용할 수 있습니다.


* ceiling
* abs

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

| Function | DSL function |
|----------|--------------|
| ABS | not yet |
| CEILING | not yet |
| EXP | not yet |
| FLOOR | not yet |
Expand Down
16 changes: 16 additions & 0 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 @@ -552,6 +552,22 @@ open class Jpql : JpqlDsl {
return Expressions.abs(expr.toExpression())
}

/**
* 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 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 represents the count of non-null values.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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
import java.math.BigDecimal

class CeilingDslTest : WithAssertions {
private val expression1 = Paths.path(Book::price)

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

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

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

assertThat(actual).isEqualTo(expected)
}

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

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

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

assertThat(actual).isEqualTo(expected)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.JpqlCeiling
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCoalesce
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlConcat
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCount
Expand Down Expand Up @@ -195,6 +196,14 @@ 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 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 ceiling of [value].
*/
@Internal
data class JpqlCeiling<T : Number> internal constructor(
val value: Expression<T>,
) : Expression<T>
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,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.JpqlCeiling
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCoalesce
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlConcat
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCount
Expand Down Expand Up @@ -901,4 +902,17 @@ 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 @@ -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.JpqlCeilingSerializer
import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlCoalesceSerializer
import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlConcatSerializer
import com.linecorp.kotlinjdsl.render.jpql.serializer.impl.JpqlCountSerializer
Expand Down Expand Up @@ -353,6 +354,7 @@ private class DefaultModule : JpqlRenderModule {
JpqlUpdateQuerySerializer(),
JpqlUpperSerializer(),
JpqlValueSerializer(),
JpqlCeilingSerializer(),
)
}
}
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.JpqlCeiling
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 JpqlCeilingSerializer : JpqlSerializer<JpqlCeiling<*>> {
override fun handledType(): KClass<JpqlCeiling<*>> {
return JpqlCeiling::class
}

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

writer.write("CEILING")

writer.writeParentheses {
delegate.serialize(part.value, writer, context)
}
}
}
Original file line number Diff line number Diff line change
@@ -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.JpqlCeiling
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 JpqlCeilingSerializerTest : WithAssertions {
private val sut = JpqlCeilingSerializer()

@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(JpqlCeiling::class)
}

@Test
fun serialize() {
// given
val part = Expressions.ceiling(
value = expression1,
)
val context = TestRenderContext(serializer)

// when
sut.serialize(part as JpqlCeiling<*>, writer, context)

// then
verifySequence {
writer.write("CEILING")
writer.writeParentheses(any())
serializer.serialize(expression1, writer, context)
}
}
}

0 comments on commit 9570d83

Please sign in to comment.