From ca7d55bed0c77a868ba96f757d29ad5fa3b71614 Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Mon, 27 Jul 2020 17:18:00 -0400 Subject: [PATCH 1/9] Remove Buildable from the base class We'll want to use this class for the union builder, but we won't implement builder in that class --- .../mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt | 5 ++--- .../mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt | 2 +- .../mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt | 2 +- .../mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt | 2 +- .../mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt index 77d3135c4..870246476 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt @@ -20,10 +20,9 @@ import org.mybatis.dynamic.sql.SqlTable import org.mybatis.dynamic.sql.VisitableCondition import org.mybatis.dynamic.sql.select.AbstractQueryExpressionDSL import org.mybatis.dynamic.sql.select.SelectModel -import org.mybatis.dynamic.sql.util.Buildable import org.mybatis.dynamic.sql.where.AbstractWhereDSL -abstract class KotlinBaseBuilder, B : KotlinBaseBuilder> : Buildable { +abstract class KotlinBaseBuilder, B : KotlinBaseBuilder> { fun where(column: BindableColumn, condition: VisitableCondition): B = applySelf { getWhere().where(column, condition) @@ -69,7 +68,7 @@ abstract class KotlinBaseBuilder, B : KotlinBaseBuild abstract class KotlinBaseJoiningBuilder, W : AbstractWhereDSL, B : KotlinBaseJoiningBuilder>( private val dsl: AbstractQueryExpressionDSL -) : KotlinBaseBuilder() { +) : KotlinBaseBuilder() { fun join(table: SqlTable, receiver: JoinReceiver): B = applySelf { diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt index eed0caeaa..044356d6e 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt @@ -22,7 +22,7 @@ import org.mybatis.dynamic.sql.util.Buildable typealias CountCompleter = KotlinCountBuilder.() -> Buildable class KotlinCountBuilder(private val dsl: CountDSL) : - KotlinBaseJoiningBuilder, CountDSL.CountWhereBuilder, KotlinCountBuilder>(dsl) { + KotlinBaseJoiningBuilder, CountDSL.CountWhereBuilder, KotlinCountBuilder>(dsl), Buildable { fun allRows() = this diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt index a986596bb..94c175a8a 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt @@ -22,7 +22,7 @@ import org.mybatis.dynamic.sql.util.Buildable typealias DeleteCompleter = KotlinDeleteBuilder.() -> Buildable class KotlinDeleteBuilder(private val dsl: DeleteDSL) : - KotlinBaseBuilder.DeleteWhereBuilder, KotlinDeleteBuilder>() { + KotlinBaseBuilder.DeleteWhereBuilder, KotlinDeleteBuilder>(), Buildable { fun allRows() = this diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt index 60976a20d..46903f98f 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt @@ -24,7 +24,7 @@ import org.mybatis.dynamic.sql.util.Buildable typealias SelectCompleter = KotlinQueryBuilder.() -> Buildable class KotlinQueryBuilder(private val dsl: QueryExpressionDSL) : - KotlinBaseJoiningBuilder, QueryExpressionDSL.QueryExpressionWhereBuilder, KotlinQueryBuilder>(dsl) { + KotlinBaseJoiningBuilder, QueryExpressionDSL.QueryExpressionWhereBuilder, KotlinQueryBuilder>(dsl), Buildable { fun groupBy(vararg columns: BasicColumn) = apply { diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt index 836e20cc3..78214158f 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt @@ -33,7 +33,7 @@ typealias MultiRowInsertCompleter = MultiRowInsertDSL.() -> MultiRowInsert typealias UpdateCompleter = KotlinUpdateBuilder.() -> Buildable class KotlinUpdateBuilder(private val dsl: UpdateDSL) : - KotlinBaseBuilder.UpdateWhereBuilder, KotlinUpdateBuilder>() { + KotlinBaseBuilder.UpdateWhereBuilder, KotlinUpdateBuilder>(), Buildable { fun set(column: SqlColumn): UpdateDSL.SetClauseFinisher = dsl.set(column) From 70b2833ace51d3d9872115ce9ef944db06faedd6 Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Mon, 27 Jul 2020 18:20:38 -0400 Subject: [PATCH 2/9] Support for basic union queries in Kotlin --- .../sql/util/kotlin/KotlinBaseBuilders.kt | 2 +- .../sql/util/kotlin/KotlinCountBuilder.kt | 2 +- .../sql/util/kotlin/KotlinDeleteBuilder.kt | 2 +- .../sql/util/kotlin/KotlinQueryBuilder.kt | 7 ++- .../sql/util/kotlin/KotlinUnionBuilders.kt | 51 +++++++++++++++ .../canonical/CanonicalSpringKotlinTest.kt | 63 +++++++++++++++++++ 6 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt index 870246476..ed9b1922d 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt @@ -1,5 +1,5 @@ /** - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt index 044356d6e..5164c4ad5 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt @@ -1,5 +1,5 @@ /** - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt index 94c175a8a..61053e0f8 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt @@ -1,5 +1,5 @@ /** - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt index 46903f98f..6c633b79b 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt @@ -1,5 +1,5 @@ /** - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,6 +50,11 @@ class KotlinQueryBuilder(private val dsl: QueryExpressionDSL) : fun allRows() = this + fun union(union: KotlinUnionBuilder.() -> QueryExpressionDSL) = + apply { + union(KotlinUnionBuilder(dsl)) + } + override fun build(): SelectModel = dsl.build() override fun getWhere(): QueryExpressionDSL.QueryExpressionWhereBuilder = dsl.where() diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt new file mode 100644 index 000000000..13cdf9926 --- /dev/null +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt @@ -0,0 +1,51 @@ +/** + * Copyright 2016-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mybatis.dynamic.sql.util.kotlin + +import org.mybatis.dynamic.sql.BasicColumn +import org.mybatis.dynamic.sql.SqlTable +import org.mybatis.dynamic.sql.select.QueryExpressionDSL +import org.mybatis.dynamic.sql.select.SelectModel + +class KotlinUnionBuilder(private val dsl: QueryExpressionDSL) { + fun select(vararg selectList: BasicColumn) = + select(listOf(*selectList)) + + fun select(selectList: List) = + KotlinUnionFromGatherer(dsl, selectList) +} + +class KotlinUnionFromGatherer( + private val dsl: QueryExpressionDSL, + private val selectList: List +) { + fun from( + table: SqlTable, + enhance: KotlinUnionQueryBuilder.() -> KotlinUnionQueryBuilder + ): QueryExpressionDSL { + val unionBuilder = KotlinUnionQueryBuilder(dsl.union().select(selectList).from(table)) + enhance(unionBuilder) + return dsl + } +} + +class KotlinUnionQueryBuilder(private val dsl: QueryExpressionDSL) : + KotlinBaseJoiningBuilder, QueryExpressionDSL.QueryExpressionWhereBuilder, + KotlinUnionQueryBuilder>(dsl) { + override fun self() = this + + override fun getWhere(): QueryExpressionDSL.QueryExpressionWhereBuilder = dsl.where() +} diff --git a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt index fb1eb9c03..9a07bb92b 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt @@ -360,6 +360,69 @@ class CanonicalSpringKotlinTest { } } + @Test + fun testRawSelectWithUnion() { + val selectStatement = select( + id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, + addressId + ).from(Person) { + where(id, isEqualTo(1)) + union { + select( + id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, + addressId + ).from(Person) { + where(id, isEqualTo(2)) + } + } + union { + select( + id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, + addressId + ).from(Person) { + where(id, isEqualTo(3)) + } + } + } + + val expected = "select id as A_ID, first_name, last_name, birth_date, employed, occupation, address_id " + + "from Person " + + "where id = :p1 " + + "union " + + "select id as A_ID, first_name, last_name, birth_date, employed, occupation, address_id " + + "from Person " + + "where id = :p2 " + + "union " + + "select id as A_ID, first_name, last_name, birth_date, employed, occupation, address_id " + + "from Person " + + "where id = :p3" + + assertThat(selectStatement.selectStatement).isEqualTo(expected) + + val records = template.selectList(selectStatement) { rs, _ -> + val record = PersonRecord() + record.id = rs.getInt(1) + record.firstName = rs.getString(2) + record.lastName = rs.getString(3) + record.birthDate = rs.getTimestamp(4) + record.employed = rs.getString(5) + record.occupation = rs.getString(6) + record.addressId = rs.getInt(7) + record + } + + assertThat(records).hasSize(3) + with(records[0]!!) { + assertThat(id).isEqualTo(1) + assertThat(firstName).isEqualTo("Fred") + assertThat(lastName).isEqualTo("Flintstone") + assertThat(birthDate).isNotNull() + assertThat(employed).isEqualTo("Yes") + assertThat(occupation).isEqualTo("Brontosaurus Operator") + assertThat(addressId).isEqualTo(1) + } + } + @Test fun testRawSelectWithJoin() { val selectStatement = select( From f07e5049a5d5fed19e311f4a520c30f5cf2b93f3 Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Mon, 27 Jul 2020 18:29:25 -0400 Subject: [PATCH 3/9] Add support for table aliases in union queries --- .../sql/util/kotlin/KotlinUnionBuilders.kt | 10 +++ .../canonical/CanonicalSpringKotlinTest.kt | 83 +++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt index 13cdf9926..41715cf13 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt @@ -40,6 +40,16 @@ class KotlinUnionFromGatherer( enhance(unionBuilder) return dsl } + + fun from( + table: SqlTable, + alias: String, + enhance: KotlinUnionQueryBuilder.() -> KotlinUnionQueryBuilder + ): QueryExpressionDSL { + val unionBuilder = KotlinUnionQueryBuilder(dsl.union().select(selectList).from(table, alias)) + enhance(unionBuilder) + return dsl + } } class KotlinUnionQueryBuilder(private val dsl: QueryExpressionDSL) : diff --git a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt index 9a07bb92b..d5b30561d 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt @@ -421,6 +421,89 @@ class CanonicalSpringKotlinTest { assertThat(occupation).isEqualTo("Brontosaurus Operator") assertThat(addressId).isEqualTo(1) } + + with(records[2]!!) { + assertThat(id).isEqualTo(3) + assertThat(firstName).isEqualTo("Pebbles") + assertThat(lastName).isEqualTo("Flintstone") + assertThat(birthDate).isNotNull() + assertThat(employed).isEqualTo("No") + assertThat(occupation).isNull() + assertThat(addressId).isEqualTo(1) + } + } + + @Test + fun testRawSelectWithUnionAndAlias() { + val selectStatement = select( + id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, + addressId + ).from(Person) { + where(id, isEqualTo(1)) + union { + select( + id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, + addressId + ).from(Person) { + where(id, isEqualTo(2)) + } + } + union { + select( + id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, + addressId + ).from(Person, "p") { + where(id, isEqualTo(3)) + } + } + } + + val expected = "select id as A_ID, first_name, last_name, birth_date, employed, occupation, address_id " + + "from Person " + + "where id = :p1 " + + "union " + + "select id as A_ID, first_name, last_name, birth_date, employed, occupation, address_id " + + "from Person " + + "where id = :p2 " + + "union " + + "select p.id as A_ID, p.first_name, p.last_name, p.birth_date, p.employed, p.occupation, p.address_id " + + "from Person p " + + "where p.id = :p3" + + assertThat(selectStatement.selectStatement).isEqualTo(expected) + + val records = template.selectList(selectStatement) { rs, _ -> + val record = PersonRecord() + record.id = rs.getInt(1) + record.firstName = rs.getString(2) + record.lastName = rs.getString(3) + record.birthDate = rs.getTimestamp(4) + record.employed = rs.getString(5) + record.occupation = rs.getString(6) + record.addressId = rs.getInt(7) + record + } + + assertThat(records).hasSize(3) + with(records[0]!!) { + assertThat(id).isEqualTo(1) + assertThat(firstName).isEqualTo("Fred") + assertThat(lastName).isEqualTo("Flintstone") + assertThat(birthDate).isNotNull() + assertThat(employed).isEqualTo("Yes") + assertThat(occupation).isEqualTo("Brontosaurus Operator") + assertThat(addressId).isEqualTo(1) + } + + with(records[2]!!) { + assertThat(id).isEqualTo(3) + assertThat(firstName).isEqualTo("Pebbles") + assertThat(lastName).isEqualTo("Flintstone") + assertThat(birthDate).isNotNull() + assertThat(employed).isEqualTo("No") + assertThat(occupation).isNull() + assertThat(addressId).isEqualTo(1) + } } @Test From 0d89029b02385511fac0b0bea3a65e9c23745d52 Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Mon, 27 Jul 2020 18:41:28 -0400 Subject: [PATCH 4/9] Add support for selectDistinct in union queries --- .../sql/util/kotlin/KotlinUnionBuilders.kt | 16 ++-- .../canonical/CanonicalSpringKotlinTest.kt | 73 +++++++++++++++++++ 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt index 41715cf13..aae7bbcfa 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt @@ -22,21 +22,27 @@ import org.mybatis.dynamic.sql.select.SelectModel class KotlinUnionBuilder(private val dsl: QueryExpressionDSL) { fun select(vararg selectList: BasicColumn) = - select(listOf(*selectList)) + select(selectList.toList()) fun select(selectList: List) = - KotlinUnionFromGatherer(dsl, selectList) + KotlinUnionFromGatherer(dsl, dsl.union().select(selectList)) + + fun selectDistinct(vararg selectList: BasicColumn) = + selectDistinct(selectList.toList()) + + fun selectDistinct(selectList: List) = + KotlinUnionFromGatherer(dsl, dsl.union().selectDistinct(selectList)) } class KotlinUnionFromGatherer( private val dsl: QueryExpressionDSL, - private val selectList: List + private val fromGatherer: QueryExpressionDSL.FromGatherer ) { fun from( table: SqlTable, enhance: KotlinUnionQueryBuilder.() -> KotlinUnionQueryBuilder ): QueryExpressionDSL { - val unionBuilder = KotlinUnionQueryBuilder(dsl.union().select(selectList).from(table)) + val unionBuilder = KotlinUnionQueryBuilder(fromGatherer.from(table)) enhance(unionBuilder) return dsl } @@ -46,7 +52,7 @@ class KotlinUnionFromGatherer( alias: String, enhance: KotlinUnionQueryBuilder.() -> KotlinUnionQueryBuilder ): QueryExpressionDSL { - val unionBuilder = KotlinUnionQueryBuilder(dsl.union().select(selectList).from(table, alias)) + val unionBuilder = KotlinUnionQueryBuilder(fromGatherer.from(table, alias)) enhance(unionBuilder) return dsl } diff --git a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt index d5b30561d..7b35a0434 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt @@ -506,6 +506,79 @@ class CanonicalSpringKotlinTest { } } + @Test + fun testRawSelectWithUnionAndDistinct() { + val selectStatement = select( + id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, + addressId + ).from(Person) { + where(id, isEqualTo(1)) + union { + select( + id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, + addressId + ).from(Person) { + where(id, isEqualTo(2)) + } + } + union { + selectDistinct( + id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, + addressId + ).from(Person, "p") { + where(id, isEqualTo(3)) + } + } + } + + val expected = "select id as A_ID, first_name, last_name, birth_date, employed, occupation, address_id " + + "from Person " + + "where id = :p1 " + + "union " + + "select id as A_ID, first_name, last_name, birth_date, employed, occupation, address_id " + + "from Person " + + "where id = :p2 " + + "union " + + "select distinct p.id as A_ID, p.first_name, p.last_name, p.birth_date, p.employed, p.occupation, p.address_id " + + "from Person p " + + "where p.id = :p3" + + assertThat(selectStatement.selectStatement).isEqualTo(expected) + + val records = template.selectList(selectStatement) { rs, _ -> + val record = PersonRecord() + record.id = rs.getInt(1) + record.firstName = rs.getString(2) + record.lastName = rs.getString(3) + record.birthDate = rs.getTimestamp(4) + record.employed = rs.getString(5) + record.occupation = rs.getString(6) + record.addressId = rs.getInt(7) + record + } + + assertThat(records).hasSize(3) + with(records[0]!!) { + assertThat(id).isEqualTo(1) + assertThat(firstName).isEqualTo("Fred") + assertThat(lastName).isEqualTo("Flintstone") + assertThat(birthDate).isNotNull() + assertThat(employed).isEqualTo("Yes") + assertThat(occupation).isEqualTo("Brontosaurus Operator") + assertThat(addressId).isEqualTo(1) + } + + with(records[2]!!) { + assertThat(id).isEqualTo(3) + assertThat(firstName).isEqualTo("Pebbles") + assertThat(lastName).isEqualTo("Flintstone") + assertThat(birthDate).isNotNull() + assertThat(employed).isEqualTo("No") + assertThat(occupation).isNull() + assertThat(addressId).isEqualTo(1) + } + } + @Test fun testRawSelectWithJoin() { val selectStatement = select( From e966810a5d738a6293d54115527f967a5a8f94c8 Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Mon, 27 Jul 2020 18:52:46 -0400 Subject: [PATCH 5/9] Add support for union all Kotlin queries --- .../sql/util/kotlin/KotlinQueryBuilder.kt | 7 +- .../sql/util/kotlin/KotlinUnionBuilders.kt | 21 +++-- .../canonical/CanonicalSpringKotlinTest.kt | 85 +++++++++++++++++-- 3 files changed, 97 insertions(+), 16 deletions(-) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt index 6c633b79b..ab135236b 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt @@ -52,7 +52,12 @@ class KotlinQueryBuilder(private val dsl: QueryExpressionDSL) : fun union(union: KotlinUnionBuilder.() -> QueryExpressionDSL) = apply { - union(KotlinUnionBuilder(dsl)) + union(KotlinUnionBuilder(dsl, dsl.union())) + } + + fun unionAll(unionAll: KotlinUnionBuilder.() -> QueryExpressionDSL) = + apply { + unionAll(KotlinUnionBuilder(dsl, dsl.unionAll())) } override fun build(): SelectModel = dsl.build() diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt index aae7bbcfa..c4a0ccb8d 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt @@ -20,22 +20,25 @@ import org.mybatis.dynamic.sql.SqlTable import org.mybatis.dynamic.sql.select.QueryExpressionDSL import org.mybatis.dynamic.sql.select.SelectModel -class KotlinUnionBuilder(private val dsl: QueryExpressionDSL) { +class KotlinUnionBuilder( + private val outerDsl: QueryExpressionDSL, + private val unionBuilder: QueryExpressionDSL.UnionBuilder +) { fun select(vararg selectList: BasicColumn) = select(selectList.toList()) fun select(selectList: List) = - KotlinUnionFromGatherer(dsl, dsl.union().select(selectList)) + KotlinUnionFromGatherer(outerDsl, unionBuilder.select(selectList)) fun selectDistinct(vararg selectList: BasicColumn) = selectDistinct(selectList.toList()) fun selectDistinct(selectList: List) = - KotlinUnionFromGatherer(dsl, dsl.union().selectDistinct(selectList)) + KotlinUnionFromGatherer(outerDsl, unionBuilder.selectDistinct(selectList)) } class KotlinUnionFromGatherer( - private val dsl: QueryExpressionDSL, + private val outerDsl: QueryExpressionDSL, private val fromGatherer: QueryExpressionDSL.FromGatherer ) { fun from( @@ -44,7 +47,7 @@ class KotlinUnionFromGatherer( ): QueryExpressionDSL { val unionBuilder = KotlinUnionQueryBuilder(fromGatherer.from(table)) enhance(unionBuilder) - return dsl + return outerDsl } fun from( @@ -54,14 +57,14 @@ class KotlinUnionFromGatherer( ): QueryExpressionDSL { val unionBuilder = KotlinUnionQueryBuilder(fromGatherer.from(table, alias)) enhance(unionBuilder) - return dsl + return outerDsl } } -class KotlinUnionQueryBuilder(private val dsl: QueryExpressionDSL) : +class KotlinUnionQueryBuilder(private val unionDsl: QueryExpressionDSL) : KotlinBaseJoiningBuilder, QueryExpressionDSL.QueryExpressionWhereBuilder, - KotlinUnionQueryBuilder>(dsl) { + KotlinUnionQueryBuilder>(unionDsl) { override fun self() = this - override fun getWhere(): QueryExpressionDSL.QueryExpressionWhereBuilder = dsl.where() + override fun getWhere(): QueryExpressionDSL.QueryExpressionWhereBuilder = unionDsl.where() } diff --git a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt index 7b35a0434..d750f5b15 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt @@ -412,7 +412,7 @@ class CanonicalSpringKotlinTest { } assertThat(records).hasSize(3) - with(records[0]!!) { + with(records[0]) { assertThat(id).isEqualTo(1) assertThat(firstName).isEqualTo("Fred") assertThat(lastName).isEqualTo("Flintstone") @@ -422,7 +422,7 @@ class CanonicalSpringKotlinTest { assertThat(addressId).isEqualTo(1) } - with(records[2]!!) { + with(records[2]) { assertThat(id).isEqualTo(3) assertThat(firstName).isEqualTo("Pebbles") assertThat(lastName).isEqualTo("Flintstone") @@ -485,7 +485,7 @@ class CanonicalSpringKotlinTest { } assertThat(records).hasSize(3) - with(records[0]!!) { + with(records[0]) { assertThat(id).isEqualTo(1) assertThat(firstName).isEqualTo("Fred") assertThat(lastName).isEqualTo("Flintstone") @@ -495,7 +495,7 @@ class CanonicalSpringKotlinTest { assertThat(addressId).isEqualTo(1) } - with(records[2]!!) { + with(records[2]) { assertThat(id).isEqualTo(3) assertThat(firstName).isEqualTo("Pebbles") assertThat(lastName).isEqualTo("Flintstone") @@ -558,7 +558,7 @@ class CanonicalSpringKotlinTest { } assertThat(records).hasSize(3) - with(records[0]!!) { + with(records[0]) { assertThat(id).isEqualTo(1) assertThat(firstName).isEqualTo("Fred") assertThat(lastName).isEqualTo("Flintstone") @@ -568,7 +568,80 @@ class CanonicalSpringKotlinTest { assertThat(addressId).isEqualTo(1) } - with(records[2]!!) { + with(records[2]) { + assertThat(id).isEqualTo(3) + assertThat(firstName).isEqualTo("Pebbles") + assertThat(lastName).isEqualTo("Flintstone") + assertThat(birthDate).isNotNull() + assertThat(employed).isEqualTo("No") + assertThat(occupation).isNull() + assertThat(addressId).isEqualTo(1) + } + } + + @Test + fun testRawSelectWithUnionAllAndDistinct() { + val selectStatement = select( + id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, + addressId + ).from(Person) { + where(id, isEqualTo(1)) + union { + select( + id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, + addressId + ).from(Person) { + where(id, isEqualTo(2)) + } + } + unionAll { + selectDistinct( + id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, + addressId + ).from(Person, "p") { + where(id, isEqualTo(3)) + } + } + } + + val expected = "select id as A_ID, first_name, last_name, birth_date, employed, occupation, address_id " + + "from Person " + + "where id = :p1 " + + "union " + + "select id as A_ID, first_name, last_name, birth_date, employed, occupation, address_id " + + "from Person " + + "where id = :p2 " + + "union all " + + "select distinct p.id as A_ID, p.first_name, p.last_name, p.birth_date, p.employed, p.occupation, p.address_id " + + "from Person p " + + "where p.id = :p3" + + assertThat(selectStatement.selectStatement).isEqualTo(expected) + + val records = template.selectList(selectStatement) { rs, _ -> + val record = PersonRecord() + record.id = rs.getInt(1) + record.firstName = rs.getString(2) + record.lastName = rs.getString(3) + record.birthDate = rs.getTimestamp(4) + record.employed = rs.getString(5) + record.occupation = rs.getString(6) + record.addressId = rs.getInt(7) + record + } + + assertThat(records).hasSize(3) + with(records[0]) { + assertThat(id).isEqualTo(1) + assertThat(firstName).isEqualTo("Fred") + assertThat(lastName).isEqualTo("Flintstone") + assertThat(birthDate).isNotNull() + assertThat(employed).isEqualTo("Yes") + assertThat(occupation).isEqualTo("Brontosaurus Operator") + assertThat(addressId).isEqualTo(1) + } + + with(records[2]) { assertThat(id).isEqualTo(3) assertThat(firstName).isEqualTo("Pebbles") assertThat(lastName).isEqualTo("Flintstone") From bfbc7cef4f7a54d4f442f86e148532ea073efaef Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Mon, 27 Jul 2020 19:06:41 -0400 Subject: [PATCH 6/9] Simplify the Union Builders --- .../sql/util/kotlin/KotlinQueryBuilder.kt | 8 ++--- .../sql/util/kotlin/KotlinUnionBuilders.kt | 35 +++++-------------- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt index ab135236b..2a2ad07b0 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinQueryBuilder.kt @@ -50,14 +50,14 @@ class KotlinQueryBuilder(private val dsl: QueryExpressionDSL) : fun allRows() = this - fun union(union: KotlinUnionBuilder.() -> QueryExpressionDSL) = + fun union(union: KotlinUnionBuilder.() -> Unit) = apply { - union(KotlinUnionBuilder(dsl, dsl.union())) + union(KotlinUnionBuilder(dsl.union())) } - fun unionAll(unionAll: KotlinUnionBuilder.() -> QueryExpressionDSL) = + fun unionAll(unionAll: KotlinUnionBuilder.() -> Unit) = apply { - unionAll(KotlinUnionBuilder(dsl, dsl.unionAll())) + unionAll(KotlinUnionBuilder(dsl.unionAll())) } override fun build(): SelectModel = dsl.build() diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt index c4a0ccb8d..ccd4c4e27 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt @@ -20,45 +20,26 @@ import org.mybatis.dynamic.sql.SqlTable import org.mybatis.dynamic.sql.select.QueryExpressionDSL import org.mybatis.dynamic.sql.select.SelectModel -class KotlinUnionBuilder( - private val outerDsl: QueryExpressionDSL, - private val unionBuilder: QueryExpressionDSL.UnionBuilder -) { +class KotlinUnionBuilder(private val unionBuilder: QueryExpressionDSL.UnionBuilder) { fun select(vararg selectList: BasicColumn) = select(selectList.toList()) fun select(selectList: List) = - KotlinUnionFromGatherer(outerDsl, unionBuilder.select(selectList)) + KotlinUnionFromGatherer(unionBuilder.select(selectList)) fun selectDistinct(vararg selectList: BasicColumn) = selectDistinct(selectList.toList()) fun selectDistinct(selectList: List) = - KotlinUnionFromGatherer(outerDsl, unionBuilder.selectDistinct(selectList)) + KotlinUnionFromGatherer(unionBuilder.selectDistinct(selectList)) } -class KotlinUnionFromGatherer( - private val outerDsl: QueryExpressionDSL, - private val fromGatherer: QueryExpressionDSL.FromGatherer -) { - fun from( - table: SqlTable, - enhance: KotlinUnionQueryBuilder.() -> KotlinUnionQueryBuilder - ): QueryExpressionDSL { - val unionBuilder = KotlinUnionQueryBuilder(fromGatherer.from(table)) - enhance(unionBuilder) - return outerDsl - } +class KotlinUnionFromGatherer(private val fromGatherer: QueryExpressionDSL.FromGatherer) { + fun from(table: SqlTable, enhance: KotlinUnionQueryBuilder.() -> Unit) = + enhance(KotlinUnionQueryBuilder(fromGatherer.from(table))) - fun from( - table: SqlTable, - alias: String, - enhance: KotlinUnionQueryBuilder.() -> KotlinUnionQueryBuilder - ): QueryExpressionDSL { - val unionBuilder = KotlinUnionQueryBuilder(fromGatherer.from(table, alias)) - enhance(unionBuilder) - return outerDsl - } + fun from(table: SqlTable, alias: String, enhance: KotlinUnionQueryBuilder.() -> Unit) = + enhance(KotlinUnionQueryBuilder(fromGatherer.from(table, alias))) } class KotlinUnionQueryBuilder(private val unionDsl: QueryExpressionDSL) : From 971f2fc5d898742c4d8df5c744322db0d65b748d Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Mon, 27 Jul 2020 21:35:55 -0400 Subject: [PATCH 7/9] Add DslMarker to control receiver scoping --- .../org/mybatis/dynamic/sql/util/kotlin/CriteriaCollector.kt | 1 + .../org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt | 1 + .../org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt | 3 +++ .../org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt | 1 + 4 files changed, 6 insertions(+) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/CriteriaCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/CriteriaCollector.kt index 14b342824..1b773b2e3 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/CriteriaCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/CriteriaCollector.kt @@ -21,6 +21,7 @@ import org.mybatis.dynamic.sql.VisitableCondition typealias CriteriaReceiver = CriteriaCollector.() -> CriteriaCollector +@MyBatisDslMarker class CriteriaCollector { val criteria = mutableListOf>() diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt index 78f0aef5d..a853f713d 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt @@ -21,6 +21,7 @@ import org.mybatis.dynamic.sql.select.join.JoinCriterion typealias JoinReceiver = JoinCollector.() -> JoinCollector +@MyBatisDslMarker class JoinCollector { val onJoinCriterion: JoinCriterion by lazy { internalOnCriterion } val andJoinCriteria = mutableListOf() diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt index ed9b1922d..c4c1785fd 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt @@ -22,6 +22,9 @@ import org.mybatis.dynamic.sql.select.AbstractQueryExpressionDSL import org.mybatis.dynamic.sql.select.SelectModel import org.mybatis.dynamic.sql.where.AbstractWhereDSL +@DslMarker annotation class MyBatisDslMarker + +@MyBatisDslMarker abstract class KotlinBaseBuilder, B : KotlinBaseBuilder> { fun where(column: BindableColumn, condition: VisitableCondition): B = applySelf { diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt index ccd4c4e27..1e6a1853f 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt @@ -20,6 +20,7 @@ import org.mybatis.dynamic.sql.SqlTable import org.mybatis.dynamic.sql.select.QueryExpressionDSL import org.mybatis.dynamic.sql.select.SelectModel +@MyBatisDslMarker class KotlinUnionBuilder(private val unionBuilder: QueryExpressionDSL.UnionBuilder) { fun select(vararg selectList: BasicColumn) = select(selectList.toList()) From f7b77410ae2a82f3c293691e57e7c5edae36f01c Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Tue, 28 Jul 2020 08:14:56 -0400 Subject: [PATCH 8/9] Documentation --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13fab73d8..513bc8d72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ If you have written your own set of functions to extend the library, you will no - Added the ability to write a function that will change the column data type ([#197](https://github.com/mybatis/mybatis-dynamic-sql/issues/197)) - Added the `applyOperator` function to make it easy to use non-standard database operators in expressions ([#220](https://github.com/mybatis/mybatis-dynamic-sql/issues/220)) - Added convenience methods for count(column) and count(distinct column)([#221](https://github.com/mybatis/mybatis-dynamic-sql/issues/221)) +- Added support for union queries in Kotlin([#187](https://github.com/mybatis/mybatis-dynamic-sql/issues/187)) ## Release 1.1.4 - November 23, 2019 From ec6656271a1584fc558d0cf18a791a9b41b7a894 Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Tue, 28 Jul 2020 08:55:35 -0400 Subject: [PATCH 9/9] Add missing allRows convenience method --- .../dynamic/sql/util/kotlin/CriteriaCollector.kt | 2 +- .../dynamic/sql/util/kotlin/JoinCollector.kt | 2 +- .../sql/util/kotlin/KotlinUnionBuilders.kt | 2 ++ .../spring/canonical/CanonicalSpringKotlinTest.kt | 15 ++++++++------- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/CriteriaCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/CriteriaCollector.kt index 1b773b2e3..6f4e4c16a 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/CriteriaCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/CriteriaCollector.kt @@ -1,5 +1,5 @@ /** - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt index a853f713d..3524f417f 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt @@ -1,5 +1,5 @@ /** - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt index 1e6a1853f..b9d541b75 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilders.kt @@ -46,6 +46,8 @@ class KotlinUnionFromGatherer(private val fromGatherer: QueryExpressionDSL.FromG class KotlinUnionQueryBuilder(private val unionDsl: QueryExpressionDSL) : KotlinBaseJoiningBuilder, QueryExpressionDSL.QueryExpressionWhereBuilder, KotlinUnionQueryBuilder>(unionDsl) { + fun allRows() = this + override fun self() = this override fun getWhere(): QueryExpressionDSL.QueryExpressionWhereBuilder = unionDsl.where() diff --git a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt index d750f5b15..5da44740d 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt @@ -599,9 +599,10 @@ class CanonicalSpringKotlinTest { id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, addressId ).from(Person, "p") { - where(id, isEqualTo(3)) + allRows() } } + orderBy(sortColumn("A_ID")) } val expected = "select id as A_ID, first_name, last_name, birth_date, employed, occupation, address_id " + @@ -614,7 +615,7 @@ class CanonicalSpringKotlinTest { "union all " + "select distinct p.id as A_ID, p.first_name, p.last_name, p.birth_date, p.employed, p.occupation, p.address_id " + "from Person p " + - "where p.id = :p3" + "order by A_ID" assertThat(selectStatement.selectStatement).isEqualTo(expected) @@ -630,7 +631,7 @@ class CanonicalSpringKotlinTest { record } - assertThat(records).hasSize(3) + assertThat(records).hasSize(8) with(records[0]) { assertThat(id).isEqualTo(1) assertThat(firstName).isEqualTo("Fred") @@ -642,12 +643,12 @@ class CanonicalSpringKotlinTest { } with(records[2]) { - assertThat(id).isEqualTo(3) - assertThat(firstName).isEqualTo("Pebbles") + assertThat(id).isEqualTo(2) + assertThat(firstName).isEqualTo("Wilma") assertThat(lastName).isEqualTo("Flintstone") assertThat(birthDate).isNotNull() - assertThat(employed).isEqualTo("No") - assertThat(occupation).isNull() + assertThat(employed).isEqualTo("Yes") + assertThat(occupation).isEqualTo("Accountant") assertThat(addressId).isEqualTo(1) } }