Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Kotlin CASE DSL #785

Merged
merged 5 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

This log will detail notable changes to MyBatis Dynamic SQL. Full details are available on the GitHub milestone pages.

## Release 1.5.1 - April 30, 2024
## Release 1.5.2 - Unreleased

This is a minor release with several enhancements.
This is a small maintenance release with improvements to the Kotlin DSL for CASE expressions.

**Important:** This is the last release that will be compatible with Java 8.

## Release 1.5.1 - April 30, 2024

This is a minor release with several enhancements.

GitHub milestone: [https://github.com/mybatis/mybatis-dynamic-sql/milestone/13?closed=1](https://github.com/mybatis/mybatis-dynamic-sql/milestone/13?closed=1)

### Case Expressions and Cast Function
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

<groupId>org.mybatis.dynamic-sql</groupId>
<artifactId>mybatis-dynamic-sql</artifactId>
<version>1.6.0-SNAPSHOT</version>
<version>1.5.2-SNAPSHOT</version>

<name>MyBatis Dynamic SQL</name>
<description>MyBatis framework for generating dynamic SQL</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ class KSearchedCaseDSL : KElseDSL {
.withSubCriteria(subCriteria)
.withThenValue(thenValue)
.build())

}

override fun `else`(column: BasicColumn) {
override infix fun `else`(column: BasicColumn) {
this.elseValue = column
}
}
Expand All @@ -53,7 +52,7 @@ class SearchedCaseCriteriaCollector : GroupingCriteriaCollector(), KThenDSL {
field = value
}

override fun then(column: BasicColumn) {
override infix fun then(column: BasicColumn) {
thenValue = column
}
}
Expand All @@ -66,88 +65,71 @@ class KSimpleCaseDSL<T : Any> : KElseDSL {
}
internal val whenConditions = mutableListOf<SimpleCaseWhenCondition<T>>()

fun `when`(firstCondition: VisitableCondition<T>, vararg subsequentConditions: VisitableCondition<T>,
completer: SimpleCaseThenGatherer.() -> Unit) =
SimpleCaseThenGatherer().apply(completer).run {
val allConditions = buildList {
add(firstCondition)
addAll(subsequentConditions)
}

whenConditions.add(ConditionBasedWhenCondition(allConditions, thenValue))
fun `when`(vararg conditions: VisitableCondition<T>) =
SimpleCaseThenGatherer { thenValue ->
whenConditions.add(ConditionBasedWhenCondition(conditions.asList(), thenValue))
}

fun `when`(firstValue: T, vararg subsequentValues: T, completer: SimpleCaseThenGatherer.() -> Unit) =
SimpleCaseThenGatherer().apply(completer).run {
val allConditions = buildList {
add(firstValue)
addAll(subsequentValues)
}

whenConditions.add(BasicWhenCondition(allConditions, thenValue))
fun `when`(vararg values: T) =
SimpleCaseThenGatherer { thenValue ->
whenConditions.add(BasicWhenCondition(values.asList(), thenValue))
}

override fun `else`(column: BasicColumn) {
override infix fun `else`(column: BasicColumn) {
this.elseValue = column
}
}

class SimpleCaseThenGatherer: KThenDSL {
internal var thenValue: BasicColumn? = null
private set(value) {
assertNull(field, "ERROR.41") //$NON-NLS-1$
field = value
}

override fun then(column: BasicColumn) {
thenValue = column
class SimpleCaseThenGatherer(private val consumer: (BasicColumn) -> Unit): KThenDSL {
override infix fun then(column: BasicColumn) {
consumer.invoke(column)
}
}

interface KThenDSL {
fun then(value: String) {
infix fun then(value: String) {
then(stringConstant(value))
}

fun then(value: Boolean) {
infix fun then(value: Boolean) {
then(constant<String>(value.toString()))
}

fun then(value: Int) {
infix fun then(value: Int) {
then(constant<String>(value.toString()))
}

fun then(value: Long) {
infix fun then(value: Long) {
then(constant<String>(value.toString()))
}

fun then(value: Double) {
infix fun then(value: Double) {
then(constant<String>(value.toString()))
}

fun then(column: BasicColumn)
infix fun then(column: BasicColumn)
}

interface KElseDSL {
fun `else`(value: String) {
infix fun `else`(value: String) {
`else`(stringConstant(value))
}

fun `else`(value: Boolean) {
infix fun `else`(value: Boolean) {
`else`(constant<String>(value.toString()))
}

fun `else`(value: Int) {
infix fun `else`(value: Int) {
`else`(constant<String>(value.toString()))
}

fun `else`(value: Long) {
infix fun `else`(value: Long) {
`else`(constant<String>(value.toString()))
}

fun `else`(value: Double) {
infix fun `else`(value: Double) {
`else`(constant<String>(value.toString()))
}

fun `else`(column: BasicColumn)
infix fun `else`(column: BasicColumn)
}
14 changes: 7 additions & 7 deletions src/site/markdown/docs/kotlinCaseExpressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ A simple case expression can be coded like the following in the Kotlin DSL:

```kotlin
select(case(id) {
`when`(1, 2, 3) { then(true) }
`when`(1, 2, 3) then true
`else`(false)
} `as` "small_id"
) {
Expand All @@ -91,7 +91,7 @@ you can write the query as follows:

```kotlin
select(case(id) {
`when`(1, 2, 3) { then(value(true)) }
`when`(1, 2, 3) then value(true)
`else`(value(false))
} `as` "small_id"
) {
Expand All @@ -111,7 +111,7 @@ expected data type. Here's an example of using the `cast` function:

```kotlin
select(case(id) {
`when`(1, 2, 3) { then(value(true)) }
`when`(1, 2, 3) then value(true)
`else`(cast { value(false) `as` "BOOLEAN" })
} `as` "small_id"
) {
Expand All @@ -134,8 +134,8 @@ A simple case expression can be coded like the following in the Kotlin DSL:

```kotlin
select(case(total_length) {
`when`(isLessThan(10)) { then("small") }
`when`(isGreaterThan(20)) { then("large") }
`when`(isLessThan(10)) then "small"
`when`(isGreaterThan(20)) then "large"
`else`("medium")
} `as` "tshirt_size"
) {
Expand All @@ -158,8 +158,8 @@ VARCHAR, you can use the `cast` function as follows:

```kotlin
select(case(total_length) {
`when`(isLessThan(10)) { then("small") }
`when`(isGreaterThan(20)) { then("large") }
`when`(isLessThan(10)) then "small"
`when`(isGreaterThan(20)) then "large"
`else`(cast { "medium" `as` "VARCHAR(6)" })
} `as` "tshirt_size"
) {
Expand Down
41 changes: 14 additions & 27 deletions src/test/kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ class KCaseExpressionTest {
val selectStatement = select(
animalName,
case(animalName) {
`when` (isEqualTo("Artic fox"), isEqualTo("Red fox")) { then("yes") }
`when` (isEqualTo("Artic fox"), isEqualTo("Red fox")) then "yes"
`else`("no")
} `as` "IsAFox"
) {
Expand Down Expand Up @@ -511,7 +511,7 @@ class KCaseExpressionTest {
val selectStatement = select(
animalName,
case(animalName) {
`when` ("Artic fox", "Red fox") { then("yes") }
`when` ("Artic fox", "Red fox") then "yes"
`else`("no")
} `as` "IsAFox"
) {
Expand Down Expand Up @@ -565,7 +565,7 @@ class KCaseExpressionTest {
val selectStatement = select(
animalName,
case(animalName) {
`when` (isEqualTo("Artic fox"), isEqualTo("Red fox")) { then(true) }
`when` (isEqualTo("Artic fox"), isEqualTo("Red fox")) then true
`else`(false)
} `as` "IsAFox"
) {
Expand Down Expand Up @@ -619,7 +619,7 @@ class KCaseExpressionTest {
val selectStatement = select(
animalName,
case(animalName) {
`when` ("Artic fox", "Red fox") { then(true) }
`when` ("Artic fox", "Red fox") then true
`else`(false)
} `as` "IsAFox"
) {
Expand Down Expand Up @@ -673,7 +673,7 @@ class KCaseExpressionTest {
val selectStatement = select(
animalName,
case(animalName) {
`when`(isEqualTo("Artic fox"), isEqualTo("Red fox")) { then("yes") }
`when`(isEqualTo("Artic fox"), isEqualTo("Red fox")) then "yes"
} `as` "IsAFox"
) {
from(animalData)
Expand Down Expand Up @@ -720,7 +720,7 @@ class KCaseExpressionTest {
val selectStatement = select(
animalName,
case(animalName) {
`when`(isEqualTo("Artic fox"), isEqualTo("Red fox")) { then(cast { "It's a fox" `as` "VARCHAR(30)" })}
`when`(isEqualTo("Artic fox"), isEqualTo("Red fox")) then cast { "It's a fox" `as` "VARCHAR(30)" }
`else`("It's not a fox")
} `as` "IsAFox"
) {
Expand Down Expand Up @@ -763,7 +763,7 @@ class KCaseExpressionTest {
val selectStatement = select(
animalName,
case(animalName) {
`when`(isEqualTo("Artic fox"), isEqualTo("Red fox")) { then( 1L) }
`when`(isEqualTo("Artic fox"), isEqualTo("Red fox")) then 1L
`else`(2L)
} `as` "IsAFox"
) {
Expand Down Expand Up @@ -806,7 +806,7 @@ class KCaseExpressionTest {
val selectStatement = select(
animalName,
case(animalName) {
`when`(isEqualTo("Artic fox"), isEqualTo("Red fox")) { then( 1.1) }
`when`(isEqualTo("Artic fox"), isEqualTo("Red fox")) then 1.1
`else`(2.2)
} `as` "IsAFox"
) {
Expand Down Expand Up @@ -849,7 +849,7 @@ class KCaseExpressionTest {
val selectStatement = select(
animalName,
case(animalName) {
`when`(isEqualTo("Artic fox"), isEqualTo("Red fox")) { then( 1.1) }
`when`(isEqualTo("Artic fox"), isEqualTo("Red fox")) then 1.1
`else`(cast { 2.2 `as` "DOUBLE" })
} `as` "IsAFox"
) {
Expand Down Expand Up @@ -888,35 +888,22 @@ class KCaseExpressionTest {
fun testInvalidDoubleElseSimple() {
assertThatExceptionOfType(KInvalidSQLException::class.java).isThrownBy {
case(animalName) {
`when`(isEqualTo("Artic fox"), isEqualTo("Red fox")) { then("'yes'") }
`when`(isEqualTo("Artic fox"), isEqualTo("Red fox")) then "yes"
`else`("Fred")
`else`("Wilma")
}
}.withMessage(Messages.getString("ERROR.42"))
}

@Test
fun testInvalidDoubleThenSimple() {
assertThatExceptionOfType(KInvalidSQLException::class.java).isThrownBy {
case(animalName) {
`when`(isEqualTo("Artic fox"), isEqualTo("Red fox")) {
then("'yes'")
then("no")
}
`else`("Fred")
}
}.withMessage(Messages.getString("ERROR.41"))
}

@Test
fun testInvalidDoubleElseSearched() {
assertThatExceptionOfType(KInvalidSQLException::class.java).isThrownBy {
case {
`when` {
id isEqualTo 22
then("'yes'")
this then "yes"
}
`else`("Fred")
this `else` "Fred"
`else`("Wilma")
}
}.withMessage(Messages.getString("ERROR.42"))
Expand All @@ -928,8 +915,8 @@ class KCaseExpressionTest {
case {
`when` {
id isEqualTo 22
then("'yes'")
then("'no'")
then("yes")
then("no")
}
}
}.withMessage(Messages.getString("ERROR.41"))
Expand Down
Loading