diff --git a/CHANGELOG.md b/CHANGELOG.md index 8540619ec..04122d5f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/pom.xml b/pom.xml index c5b04639a..b17a77d72 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ org.mybatis.dynamic-sql mybatis-dynamic-sql - 1.6.0-SNAPSHOT + 1.5.2-SNAPSHOT MyBatis Dynamic SQL MyBatis framework for generating dynamic SQL diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt index 98653f434..027b5b187 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt @@ -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 } } @@ -53,7 +52,7 @@ class SearchedCaseCriteriaCollector : GroupingCriteriaCollector(), KThenDSL { field = value } - override fun then(column: BasicColumn) { + override infix fun then(column: BasicColumn) { thenValue = column } } @@ -66,88 +65,71 @@ class KSimpleCaseDSL : KElseDSL { } internal val whenConditions = mutableListOf>() - fun `when`(firstCondition: VisitableCondition, vararg subsequentConditions: VisitableCondition, - completer: SimpleCaseThenGatherer.() -> Unit) = - SimpleCaseThenGatherer().apply(completer).run { - val allConditions = buildList { - add(firstCondition) - addAll(subsequentConditions) - } - - whenConditions.add(ConditionBasedWhenCondition(allConditions, thenValue)) + fun `when`(vararg conditions: VisitableCondition) = + 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(value.toString())) } - fun then(value: Int) { + infix fun then(value: Int) { then(constant(value.toString())) } - fun then(value: Long) { + infix fun then(value: Long) { then(constant(value.toString())) } - fun then(value: Double) { + infix fun then(value: Double) { then(constant(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(value.toString())) } - fun `else`(value: Int) { + infix fun `else`(value: Int) { `else`(constant(value.toString())) } - fun `else`(value: Long) { + infix fun `else`(value: Long) { `else`(constant(value.toString())) } - fun `else`(value: Double) { + infix fun `else`(value: Double) { `else`(constant(value.toString())) } - fun `else`(column: BasicColumn) + infix fun `else`(column: BasicColumn) } diff --git a/src/site/markdown/docs/kotlinCaseExpressions.md b/src/site/markdown/docs/kotlinCaseExpressions.md index f35a298da..5366db40b 100644 --- a/src/site/markdown/docs/kotlinCaseExpressions.md +++ b/src/site/markdown/docs/kotlinCaseExpressions.md @@ -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" ) { @@ -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" ) { @@ -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" ) { @@ -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" ) { @@ -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" ) { diff --git a/src/test/kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt b/src/test/kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt index b86db19af..8f6eb7aa8 100644 --- a/src/test/kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt +++ b/src/test/kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt @@ -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" ) { @@ -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" ) { @@ -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" ) { @@ -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" ) { @@ -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) @@ -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" ) { @@ -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" ) { @@ -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" ) { @@ -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" ) { @@ -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")) @@ -928,8 +915,8 @@ class KCaseExpressionTest { case { `when` { id isEqualTo 22 - then("'yes'") - then("'no'") + then("yes") + then("no") } } }.withMessage(Messages.getString("ERROR.41"))