diff --git a/spring-jdbc/src/main/kotlin/org/springframework/jdbc/core/JdbcOperationsExtensions.kt b/spring-jdbc/src/main/kotlin/org/springframework/jdbc/core/JdbcOperationsExtensions.kt index 0e8f4aaf88d..f1772b0cf4f 100644 --- a/spring-jdbc/src/main/kotlin/org/springframework/jdbc/core/JdbcOperationsExtensions.kt +++ b/spring-jdbc/src/main/kotlin/org/springframework/jdbc/core/JdbcOperationsExtensions.kt @@ -24,8 +24,8 @@ import java.sql.ResultSet * @author Mario Arias * @since 5.0 */ -inline fun JdbcOperations.queryForObject(sql: String): T = - queryForObject(sql, T::class.java as Class<*>) as T +inline fun JdbcOperations.queryForObject(sql: String): T? = + queryForObject(sql, T::class.java) /** * Extensions for [JdbcOperations.queryForObject] providing a RowMapper-like function @@ -34,7 +34,7 @@ inline fun JdbcOperations.queryForObject(sql: String): T = * @author Mario Arias * @since 5.0 */ -inline fun JdbcOperations.queryForObject(sql: String, vararg args: Any, crossinline function: (ResultSet, Int) -> T): T = +inline fun JdbcOperations.queryForObject(sql: String, vararg args: Any?, crossinline function: (ResultSet, Int) -> T): T = queryForObject(sql, { resultSet, i -> function(resultSet, i) }, *args) /** @@ -44,18 +44,18 @@ inline fun JdbcOperations.queryForObject(sql: String, vararg args: A * @author Mario Arias * @since 5.0 */ -inline fun JdbcOperations.queryForObject(sql: String, args: Array, argTypes: IntArray): T = - queryForObject(sql, args, argTypes, T::class.java as Class<*>) as T +inline fun JdbcOperations.queryForObject(sql: String, args: Array, argTypes: IntArray): T? = + queryForObject(sql, args, argTypes, T::class.java) /** * Extension for [JdbcOperations.queryForObject] providing a - * `queryForObject("...", arrayOf(arg1, argN))` variant. + * `queryForObject("...", arg1, argN)` variant. * - * @author Mario Arias - * @since 5.0 + * @author Sébastien Deleuze + * @since 7.0 */ -inline fun JdbcOperations.queryForObject(sql: String, args: Array): T = - queryForObject(sql, T::class.java as Class<*>, args) as T +inline fun JdbcOperations.queryForObject(sql: String, vararg args: Any?): T? = + queryForObject(sql, T::class.java, *args) /** * Extension for [JdbcOperations.queryForList] providing a `queryForList("...")` variant. @@ -63,9 +63,8 @@ inline fun JdbcOperations.queryForObject(sql: String, args: Array JdbcOperations.queryForList(sql: String): List = - queryForList(sql, T::class.java) as List +inline fun JdbcOperations.queryForList(sql: String): List = + queryForList(sql, T::class.java) /** * Extension for [JdbcOperations.queryForList] providing a @@ -74,21 +73,19 @@ inline fun JdbcOperations.queryForList(sql: String): List = * @author Mario Arias * @since 5.0 */ -@Suppress("UNCHECKED_CAST") -inline fun JdbcOperations.queryForList(sql: String, args: Array, - argTypes: IntArray): List = - queryForList(sql, args, argTypes, T::class.java) as List +inline fun JdbcOperations.queryForList(sql: String, args: Array, + argTypes: IntArray): List = + queryForList(sql, args, argTypes, T::class.java) /** * Extension for [JdbcOperations.queryForList] providing a - * `queryForList("...", arrayOf(arg1, argN))` variant. + * `queryForList("...", arg1, argN)` variant. * - * @author Mario Arias - * @since 5.0 + * @author Sebastien Deleuze + * @since 7.0 */ -@Suppress("UNCHECKED_CAST") -inline fun JdbcOperations.queryForList(sql: String, args: Array): List = - queryForList(sql, T::class.java, args) as List +inline fun JdbcOperations.queryForList(sql: String, vararg args: Any?): List = + queryForList(sql, T::class.java, *args) /** @@ -98,7 +95,7 @@ inline fun JdbcOperations.queryForList(sql: String, args: Array JdbcOperations.query(sql: String, vararg args: Any, +fun JdbcOperations.query(sql: String, vararg args: Any?, function: (ResultSet) -> T): T = query(sql, ResultSetExtractor { function(it) }, *args) @@ -109,7 +106,7 @@ fun JdbcOperations.query(sql: String, vararg args: Any, * @author Mario Arias * @since 5.0 */ -fun JdbcOperations.query(sql: String, vararg args: Any, function: (ResultSet) -> Unit): Unit = +fun JdbcOperations.query(sql: String, vararg args: Any?, function: (ResultSet) -> Unit): Unit = query(sql, { function(it) }, *args) /** @@ -119,5 +116,5 @@ fun JdbcOperations.query(sql: String, vararg args: Any, function: (ResultSet) -> * @author Mario Arias * @since 5.0 */ -fun JdbcOperations.query(sql: String, vararg args: Any, function: (ResultSet, Int) -> T): List = +fun JdbcOperations.query(sql: String, vararg args: Any?, function: (ResultSet, Int) -> T): List = query(sql, { rs, i -> function(rs, i) }, *args) diff --git a/spring-jdbc/src/test/kotlin/org/springframework/jdbc/core/JdbcOperationsExtensionsTests.kt b/spring-jdbc/src/test/kotlin/org/springframework/jdbc/core/JdbcOperationsExtensionsTests.kt index d26f3ce63bd..91c2c55092b 100644 --- a/spring-jdbc/src/test/kotlin/org/springframework/jdbc/core/JdbcOperationsExtensionsTests.kt +++ b/spring-jdbc/src/test/kotlin/org/springframework/jdbc/core/JdbcOperationsExtensionsTests.kt @@ -46,7 +46,7 @@ class JdbcOperationsExtensionsTests { @Test fun `queryForObject with nullable reified type parameters`() { every { template.queryForObject(sql, any>()) } returns null - assertThat(template.queryForObject(sql)).isNull() + assertThat(template.queryForObject(sql)).isNull() verify { template.queryForObject(sql, any>()) } } @@ -65,8 +65,17 @@ class JdbcOperationsExtensionsTests { } @Test - fun `queryForObject with reified type parameters and argTypes`() { - val args = arrayOf(3) + fun `queryForObject with reified type parameters, non-null args array and argTypes`() { + val args = arrayOf(3, 4) + val argTypes = intArrayOf(JDBCType.INTEGER.vendorTypeNumber) + every { template.queryForObject(sql, args, argTypes, any>()) } returns 2 + assertThat(template.queryForObject(sql, args, argTypes)).isEqualTo(2) + verify { template.queryForObject(sql, args, argTypes, any>()) } + } + + @Test + fun `queryForObject with reified type parameters, nullable args array and argTypes`() { + val args = arrayOf(3, null) val argTypes = intArrayOf(JDBCType.INTEGER.vendorTypeNumber) every { template.queryForObject(sql, args, argTypes, any>()) } returns 2 assertThat(template.queryForObject(sql, args, argTypes)).isEqualTo(2) @@ -78,24 +87,22 @@ class JdbcOperationsExtensionsTests { val args = arrayOf(3) val argTypes = intArrayOf(JDBCType.INTEGER.vendorTypeNumber) every { template.queryForObject(sql, args, argTypes, any>()) } returns null - assertThat(template.queryForObject(sql, args, argTypes)).isNull() + assertThat(template.queryForObject(sql, args, argTypes)).isNull() verify { template.queryForObject(sql, args, argTypes, any>()) } } @Test fun `queryForObject with reified type parameters and args`() { - val args = arrayOf(3, 4) - every { template.queryForObject(sql, any>(), args) } returns 2 - assertThat(template.queryForObject(sql, args)).isEqualTo(2) - verify { template.queryForObject(sql, any>(), args) } + every { template.queryForObject(sql, any>(), 3, null) } returns 2 + assertThat(template.queryForObject(sql, 3, null)).isEqualTo(2) + verify { template.queryForObject(sql, any>(), 3, null) } } @Test fun `queryForObject with nullable reified type parameters and args`() { - val args = arrayOf(3, 4) - every { template.queryForObject(sql, any>(), args) } returns null - assertThat(template.queryForObject(sql, args)).isNull() - verify { template.queryForObject(sql, any>(), args) } + every { template.queryForObject(sql, any>(), 3, 4) } returns null + assertThat(template.queryForObject(sql, 3, 4)).isNull() + verify { template.queryForObject(sql, any>(), 3, 4) } } @Test @@ -110,12 +117,12 @@ class JdbcOperationsExtensionsTests { fun `queryForList with nullable reified type parameters`() { val list = listOf(1, null, 3) every { template.queryForList(sql, any>()) } returns list - assertThat(template.queryForList(sql)).isEqualTo(list) + assertThat(template.queryForList(sql)).isEqualTo(list) verify { template.queryForList(sql, any>()) } } @Test - fun `queryForList with reified type parameters and argTypes`() { + fun `queryForList with reified type parameters, non-null args and argTypes`() { val list = listOf(1, 2, 3) val args = arrayOf(3) val argTypes = intArrayOf(JDBCType.INTEGER.vendorTypeNumber) @@ -125,31 +132,49 @@ class JdbcOperationsExtensionsTests { } @Test - fun `queryForList with nullable reified type parameters and argTypes`() { + fun `queryForList with reified type parameters, nullable args and argTypes`() { + val list = listOf(1, 2, 3) + val args = arrayOf("foo", null) + val argTypes = intArrayOf(JDBCType.VARCHAR.vendorTypeNumber) + every { template.queryForList(sql, args, argTypes, any>()) } returns list + assertThat(template.queryForList(sql, args, argTypes)).isEqualTo(list) + verify { template.queryForList(sql, args, argTypes, any>()) } + } + + @Test + fun `queryForList with nullable reified type parameters, non-null args and argTypes`() { val list = listOf(1, null, 3) val args = arrayOf(3) val argTypes = intArrayOf(JDBCType.INTEGER.vendorTypeNumber) every { template.queryForList(sql, args, argTypes, any>()) } returns list - assertThat(template.queryForList(sql, args, argTypes)).isEqualTo(list) + assertThat(template.queryForList(sql, args, argTypes)).isEqualTo(list) + verify { template.queryForList(sql, args, argTypes, any>()) } + } + + @Test + fun `queryForList with nullable reified type parameters, nullable args and argTypes`() { + val list = listOf(1, null, 3) + val args = arrayOf("foo", null) + val argTypes = intArrayOf(JDBCType.VARCHAR.vendorTypeNumber) + every { template.queryForList(sql, args, argTypes, any>()) } returns list + assertThat(template.queryForList(sql, args, argTypes)).isEqualTo(list) verify { template.queryForList(sql, args, argTypes, any>()) } } @Test fun `queryForList with reified type parameters and args`() { val list = listOf(1, 2, 3) - val args = arrayOf(3, 4) - every { template.queryForList(sql, any>(), args) } returns list - template.queryForList(sql, args) - verify { template.queryForList(sql, any>(), args) } + every { template.queryForList(sql, any>(), 3, null) } returns list + template.queryForList(sql, 3, null) + verify { template.queryForList(sql, any>(), 3, null) } } @Test fun `queryForList with nullable reified type parameters and args`() { val list = listOf(1, null, 3) - val args = arrayOf(3, 4) - every { template.queryForList(sql, any>(), args) } returns list - template.queryForList(sql, args) - verify { template.queryForList(sql, any>(), args) } + every { template.queryForList(sql, any>(), 3, null) } returns list + template.queryForList(sql, 3, null) + verify { template.queryForList(sql, any>(), 3, null) } } @Test