Skip to content

Commit

Permalink
Merge pull request #785 from jeffgbutler/improve-kotlin-case-dsl
Browse files Browse the repository at this point in the history
Improve Kotlin CASE DSL
  • Loading branch information
jeffgbutler authored May 1, 2024
2 parents ecf4bc3 + 15d258e commit e8f1890
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 79 deletions.
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

0 comments on commit e8f1890

Please sign in to comment.