Skip to content

Commit a98c77e

Browse files
authored
Merge pull request #524 from jeffgbutler/improve-insert-select
[Kotlin] Improve insert select
2 parents 194e726 + 8ce0c38 commit a98c77e

File tree

11 files changed

+172
-19
lines changed

11 files changed

+172
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ For examples of global and statement configuration, see the "Configuration of th
4040
page for details. ([#515](https://github.com/mybatis/mybatis-dynamic-sql/pull/515))
4141
5. Added several checks for invalid SQL ([#516](https://github.com/mybatis/mybatis-dynamic-sql/pull/516))
4242
6. Added documentation for the various exceptions thrown by the library ([#517](https://github.com/mybatis/mybatis-dynamic-sql/pull/517))
43+
7. Update the "insertSelect" method in the Kotlin DSL to make it consistent with the other insert methods ([#524](https://github.com/mybatis/mybatis-dynamic-sql/pull/524))
4344

4445
## Release 1.4.0 - March 3, 2022
4546

src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSubQueryBuilders.kt

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ package org.mybatis.dynamic.sql.util.kotlin
1818
import org.mybatis.dynamic.sql.BasicColumn
1919
import org.mybatis.dynamic.sql.SqlBuilder
2020
import org.mybatis.dynamic.sql.SqlColumn
21+
import org.mybatis.dynamic.sql.SqlTable
22+
import org.mybatis.dynamic.sql.insert.InsertSelectModel
2123
import org.mybatis.dynamic.sql.select.SelectModel
2224
import org.mybatis.dynamic.sql.util.Buildable
2325
import org.mybatis.dynamic.sql.util.Messages
2426

2527
@MyBatisDslMarker
26-
sealed class KotlinBaseSubQueryBuilder : Buildable<SelectModel> {
28+
sealed class KotlinBaseSubQueryBuilder {
2729
private var selectBuilder: KotlinSelectBuilder? = null
2830

2931
fun select(vararg selectList: BasicColumn, completer: SelectCompleter): Unit =
@@ -40,28 +42,54 @@ sealed class KotlinBaseSubQueryBuilder : Buildable<SelectModel> {
4042
selectBuilder = KotlinSelectBuilder(SqlBuilder.selectDistinct(selectList)).apply(completer)
4143
}
4244

43-
override fun build(): SelectModel =
45+
internal fun buildSelectModel(): SelectModel =
4446
selectBuilder?.build()?: throw KInvalidSQLException(Messages.getString("ERROR.28")) //$NON-NLS-1$
4547
}
4648

47-
class KotlinSubQueryBuilder : KotlinBaseSubQueryBuilder()
49+
class KotlinSubQueryBuilder : KotlinBaseSubQueryBuilder(), Buildable<SelectModel> {
50+
override fun build(): SelectModel = buildSelectModel()
51+
}
4852

49-
class KotlinQualifiedSubQueryBuilder : KotlinBaseSubQueryBuilder() {
53+
class KotlinQualifiedSubQueryBuilder : KotlinBaseSubQueryBuilder(), Buildable<SelectModel> {
5054
var correlationName: String? = null
5155

5256
operator fun String.unaryPlus() {
5357
correlationName = this
5458
}
59+
60+
override fun build(): SelectModel = buildSelectModel()
5561
}
5662

5763
typealias InsertSelectCompleter = KotlinInsertSelectSubQueryBuilder.() -> Unit
5864

59-
class KotlinInsertSelectSubQueryBuilder : KotlinBaseSubQueryBuilder() {
60-
internal var columnList: List<SqlColumn<*>>? = null
65+
class KotlinInsertSelectSubQueryBuilder : KotlinBaseSubQueryBuilder(), Buildable<InsertSelectModel> {
66+
private var columnList: List<SqlColumn<*>>? = null
67+
private var table: SqlTable? = null
68+
69+
fun into(table: SqlTable) {
70+
this.table = table
71+
}
6172

6273
fun columns(vararg columnList: SqlColumn<*>): Unit = columns(columnList.asList())
6374

6475
fun columns(columnList: List<SqlColumn<*>>) {
6576
this.columnList = columnList
6677
}
78+
79+
override fun build(): InsertSelectModel {
80+
if (table == null) {
81+
throw KInvalidSQLException(Messages.getString("ERROR.29")) //$NON-NLS-1$
82+
}
83+
84+
return if (columnList == null) {
85+
SqlBuilder.insertInto(table)
86+
.withSelectStatement { buildSelectModel() }
87+
.build()
88+
} else {
89+
SqlBuilder.insertInto(table)
90+
.withColumnList(columnList)
91+
.withSelectStatement { buildSelectModel() }
92+
.build()
93+
}
94+
}
6795
}

src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderFunctions.kt

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,20 +77,17 @@ fun insertInto(table: SqlTable, completer: GeneralInsertCompleter): GeneralInser
7777
fun <T : Any> insertMultiple(rows: Collection<T>, completer: KotlinMultiRowInsertCompleter<T>): MultiRowInsertModel<T> =
7878
KotlinMultiRowInsertBuilder(rows).apply(completer).build()
7979

80+
@Deprecated("Please use the new form - move the table into the lambda with into(table)")
8081
fun insertSelect(table: SqlTable, completer: InsertSelectCompleter): InsertSelectModel =
81-
with(KotlinInsertSelectSubQueryBuilder().apply(completer)) {
82-
if (columnList == null) {
83-
SqlBuilder.insertInto(table)
84-
.withSelectStatement(this)
85-
.build()
86-
} else {
87-
SqlBuilder.insertInto(table)
88-
.withColumnList(columnList)
89-
.withSelectStatement(this)
90-
.build()
91-
}
82+
with(KotlinInsertSelectSubQueryBuilder()) {
83+
into(table)
84+
apply(completer)
85+
build()
9286
}
9387

88+
fun insertSelect(completer: InsertSelectCompleter): InsertSelectModel =
89+
KotlinInsertSelectSubQueryBuilder().apply(completer).build()
90+
9491
@Deprecated("Please switch to the insertBatch statement in the model package")
9592
fun <T> BatchInsertDSL.IntoGatherer<T>.into(
9693
table: SqlTable,

src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/mybatis3/MapperSupportFunctions.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,10 @@ fun insertSelect(
128128
table: SqlTable,
129129
completer: InsertSelectCompleter
130130
): Int =
131-
insertSelect(table, completer).run(mapper)
131+
insertSelect {
132+
into(table)
133+
run(completer)
134+
}.run(mapper)
132135

133136
fun <T> selectDistinct(
134137
mapper: (SelectStatementProvider) -> List<T>,

src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/mybatis3/ProviderBuilderFunctions.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,13 @@ fun <T : Any> insertMultiple(
8383
): MultiRowInsertStatementProvider<T> =
8484
insertMultiple(rows, completer).render(RenderingStrategies.MYBATIS3)
8585

86+
@Deprecated("Please use the new form - move the table into the lambda with into(table)")
8687
fun insertSelect(table: SqlTable, completer: InsertSelectCompleter): InsertSelectStatementProvider =
8788
insertSelect(table, completer).render(RenderingStrategies.MYBATIS3)
8889

90+
fun insertSelect(completer: InsertSelectCompleter): InsertSelectStatementProvider =
91+
insertSelect(completer).render(RenderingStrategies.MYBATIS3)
92+
8993
@Deprecated("Please switch to the insertBatch statement in the mybatis3 package")
9094
fun <T> BatchInsertDSL.IntoGatherer<T>.into(table: SqlTable, completer: BatchInsertDSL<T>.() -> Unit): BatchInsert<T> =
9195
into(table, completer).render(RenderingStrategies.MYBATIS3)

src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/NamedParameterJdbcTemplateExtensions.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,13 @@ fun <T> NamedParameterJdbcTemplate.insertMultiple(
148148
): Int =
149149
update(insertStatement.insertStatement, BeanPropertySqlParameterSource(insertStatement), keyHolder)
150150

151+
@Deprecated("Please use the new form - move the table into the lambda with into(table)")
151152
fun NamedParameterJdbcTemplate.insertSelect(table: SqlTable, completer: InsertSelectCompleter): Int =
152153
insertSelect(org.mybatis.dynamic.sql.util.kotlin.spring.insertSelect(table, completer))
153154

155+
fun NamedParameterJdbcTemplate.insertSelect(completer: InsertSelectCompleter): Int =
156+
insertSelect(org.mybatis.dynamic.sql.util.kotlin.spring.insertSelect(completer))
157+
154158
fun NamedParameterJdbcTemplate.insertSelect(insertStatement: InsertSelectStatementProvider): Int =
155159
update(insertStatement.insertStatement, MapSqlParameterSource(insertStatement.parameters))
156160

src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/ProviderBuilderFunctions.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,13 @@ fun <T : Any> insertMultiple(
8383
): MultiRowInsertStatementProvider<T> =
8484
insertMultiple(rows, completer).render(RenderingStrategies.SPRING_NAMED_PARAMETER)
8585

86+
@Deprecated("Please use the new form - move the table into the lambda with into(table)")
8687
fun insertSelect(table: SqlTable, completer: InsertSelectCompleter): InsertSelectStatementProvider =
8788
insertSelect(table, completer).render(RenderingStrategies.SPRING_NAMED_PARAMETER)
8889

90+
fun insertSelect(completer: InsertSelectCompleter): InsertSelectStatementProvider =
91+
insertSelect(completer).render(RenderingStrategies.SPRING_NAMED_PARAMETER)
92+
8993
@Deprecated("Please switch to the insertBatch statement in the spring package")
9094
fun <T> BatchInsertDSL.IntoGatherer<T>.into(table: SqlTable, completer: BatchInsertDSL<T>.() -> Unit): BatchInsert<T> =
9195
into(table, completer).render(RenderingStrategies.SPRING_NAMED_PARAMETER)

src/main/resources/org/mybatis/dynamic/sql/util/messages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@ ERROR.25=Insert Statements Must Contain an "into" phrase
4444
ERROR.26=Multiple Row Insert Statements Must Contain an "into" phrase
4545
ERROR.27=You must specify a "from" clause before any other clauses in a select statement
4646
ERROR.28=You must specify a select statement in a sub query
47+
ERROR.29=Insert Select Statements Must Contain an "into" phrase

src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import org.mybatis.dynamic.sql.util.kotlin.elements.add
3838
import org.mybatis.dynamic.sql.util.kotlin.elements.constant
3939
import org.mybatis.dynamic.sql.util.kotlin.elements.isIn
4040
import org.mybatis.dynamic.sql.util.kotlin.mybatis3.insertInto
41+
import org.mybatis.dynamic.sql.util.kotlin.mybatis3.insertSelect
4142
import org.mybatis.dynamic.sql.util.kotlin.mybatis3.select
4243
import java.io.InputStreamReader
4344
import java.sql.DriverManager
@@ -258,6 +259,32 @@ class PersonMapperTest {
258259
}
259260
}
260261

262+
@Test
263+
fun testDeprecatedInsertSelect() {
264+
newSession().use { session ->
265+
val mapper = session.getMapper(PersonMapper::class.java)
266+
267+
val insertStatement = insertSelect(person) {
268+
columns(id, firstName, lastName, employed, occupation, addressId, birthDate)
269+
select(add(id, constant<Int>("100")), firstName, lastName, employed, occupation, addressId, birthDate) {
270+
from(person)
271+
orderBy(id)
272+
}
273+
}
274+
275+
val expected = "insert into Person " +
276+
"(id, first_name, last_name, employed, occupation, address_id, birth_date) " +
277+
"select (id + 100), first_name, last_name, employed, occupation, address_id, birth_date " +
278+
"from Person order by id"
279+
280+
assertThat(insertStatement.insertStatement).isEqualTo(expected)
281+
282+
val rows = mapper.insertSelect(insertStatement)
283+
284+
assertThat(rows).isEqualTo(6)
285+
}
286+
}
287+
261288
@Test
262289
fun testInsertBatch() {
263290
newSession(ExecutorType.BATCH).use { session ->

src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTemplateDirectTest.kt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,39 @@ open class CanonicalSpringKotlinTemplateDirectTest {
303303

304304
@Test
305305
fun testInsertSelect() {
306+
val rows = template.insertSelect {
307+
into(person)
308+
columns(id, firstName, lastName, birthDate, employed, occupation, addressId)
309+
select(
310+
add(id, constant<Int>("100")), firstName, lastName, birthDate, employed, occupation, addressId
311+
) {
312+
from(person)
313+
orderBy(id)
314+
}
315+
}
316+
317+
assertThat(rows).isEqualTo(6)
318+
319+
val records = template.select(id, firstName, lastName, birthDate, employed, occupation, addressId) {
320+
from(person)
321+
where { id isGreaterThanOrEqualTo 100 }
322+
orderBy(id)
323+
}.withRowMapper(personRowMapper)
324+
325+
assertThat(records).hasSize(6)
326+
with(records[1]) {
327+
assertThat(id).isEqualTo(102)
328+
assertThat(firstName).isEqualTo("Wilma")
329+
assertThat(lastName).isEqualTo(LastName("Flintstone"))
330+
assertThat(birthDate).isNotNull
331+
assertThat(employed).isTrue
332+
assertThat(occupation).isEqualTo("Accountant")
333+
assertThat(addressId).isEqualTo(1)
334+
}
335+
}
336+
337+
@Test
338+
fun testDeprecatedInsertSelect() {
306339
val rows = template.insertSelect(person) {
307340
columns(id, firstName, lastName, birthDate, employed, occupation, addressId)
308341
select(

0 commit comments

Comments
 (0)