diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index 73b1d2f7a0..78fcf41cdb 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -189,6 +189,13 @@ test + + io.mockk + mockk-jvm + ${mockk} + test + + @@ -239,6 +246,19 @@ ${hikari.version} test + + + + org.jetbrains.kotlin + kotlin-stdlib + true + + + + org.jetbrains.kotlin + kotlin-reflect + true + diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperationsExtensions.kt b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperationsExtensions.kt new file mode 100644 index 0000000000..4ac6033f4f --- /dev/null +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperationsExtensions.kt @@ -0,0 +1,120 @@ +/* + * Copyright 2017-2024 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 + * + * https://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.springframework.data.jdbc.core + +import org.springframework.data.domain.Page +import org.springframework.data.domain.Pageable +import org.springframework.data.domain.Sort +import org.springframework.data.relational.core.query.Query + +import java.util.Optional + +/** + * Extensions for [JdbcAggregateOperations]. + * + * @author Felix Desyatirikov + * @since 3.5 + */ + +/** + * Extension for [JdbcAggregateOperations.count]. + */ +inline fun JdbcAggregateOperations.count(): Long = + count(T::class.java) + +/** + * Extension for [JdbcAggregateOperations.count] with a query. + */ +inline fun JdbcAggregateOperations.count(query: Query): Long = + count(query, T::class.java) + +/** + * Extension for [JdbcAggregateOperations.exists]. + */ +inline fun JdbcAggregateOperations.exists(query: Query): Boolean = + exists(query, T::class.java) + +/** + * Extension for [JdbcAggregateOperations.existsById]. + */ +inline fun JdbcAggregateOperations.existsById(id: Any): Boolean = + existsById(id, T::class.java) + +/** + * Extension for [JdbcAggregateOperations.findById]. + */ +inline fun JdbcAggregateOperations.findById(id: Any): T? = + findById(id, T::class.java) + +/** + * Extension for [JdbcAggregateOperations.findAllById]. + */ +inline fun JdbcAggregateOperations.findAllById(ids: Iterable<*>): List = + findAllById(ids, T::class.java) + +/** + * Extension for [JdbcAggregateOperations.findAll]. + */ +inline fun JdbcAggregateOperations.findAll(): List = + findAll(T::class.java) + +/** + * Extension for [JdbcAggregateOperations.findAll] with sorting. + */ +inline fun JdbcAggregateOperations.findAll(sort: Sort): List = + findAll(T::class.java, sort) + +/** + * Extension for [JdbcAggregateOperations.findAll] with pagination. + */ +inline fun JdbcAggregateOperations.findAll(pageable: Pageable): Page = + findAll(T::class.java, pageable) + +/** + * Extension for [JdbcAggregateOperations.findOne] with a query. + */ +inline fun JdbcAggregateOperations.findOne(query: Query): Optional = + findOne(query, T::class.java) + +/** + * Extension for [JdbcAggregateOperations.findAll] with a query. + */ +inline fun JdbcAggregateOperations.findAll(query: Query): List = + findAll(query, T::class.java) + +/** + * Extension for [JdbcAggregateOperations.findAll] with query and pagination. + */ +inline fun JdbcAggregateOperations.findAll(query: Query, pageable: Pageable): Page = + findAll(query, T::class.java, pageable) + +/** + * Extension for [JdbcAggregateOperations.deleteById]. + */ +inline fun JdbcAggregateOperations.deleteById(id: Any): Unit = + deleteById(id, T::class.java) + +/** + * Extension for [JdbcAggregateOperations.deleteAllById]. + */ +inline fun JdbcAggregateOperations.deleteAllById(ids: Iterable<*>): Unit = + deleteAllById(ids, T::class.java) + +/** + * Extension for [JdbcAggregateOperations.deleteAll]. + */ +inline fun JdbcAggregateOperations.deleteAll(): Unit = + deleteAll(T::class.java) \ No newline at end of file diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateOperationsExtensionsTests.kt b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateOperationsExtensionsTests.kt new file mode 100644 index 0000000000..5acb2faea2 --- /dev/null +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateOperationsExtensionsTests.kt @@ -0,0 +1,167 @@ +/* + * Copyright 2020-2024 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 + * + * https://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.springframework.data.jdbc.core + +import io.mockk.mockk +import io.mockk.verify +import org.junit.Test +import org.springframework.data.domain.Pageable +import org.springframework.data.domain.Sort +import org.springframework.data.jdbc.testing.TestClass +import org.springframework.data.relational.core.query.Query + +/** + * Unit tests for [JdbcAggregateOperations]. + * + * @author Felix Desyatirikov + */ + +class JdbcAggregateOperationsExtensionsTests { + + val operations = mockk(relaxed = true) + + @Test // gh-1961 + fun `count with reified type parameter extension should call its Java counterpart`() { + operations.count() + verify { operations.count(TestClass::class.java) } + } + + @Test // gh-1961 + fun `count(Query) with reified type parameter extension should call its Java counterpart`() { + val query = mockk(relaxed = true) + operations.count(query) + verify { + operations.count(query, TestClass::class.java) + } + } + + @Test // gh-1961 + fun `exists(Query) with reified type parameter extension should call its Java counterpart`() { + val query = mockk(relaxed = true) + operations.exists(query) + verify { + operations.exists(query, TestClass::class.java) + } + } + + @Test // gh-1961 + fun `existsById(id) with reified type parameter extension should call its Java counterpart`() { + val id = 1L + operations.existsById(id) + verify { + operations.existsById(id, TestClass::class.java) + } + } + + @Test // gh-1961 + fun `findById(id) with reified type parameter extension should call its Java counterpart`() { + val id = 1L + operations.findById(id) + verify { + operations.findById(id, TestClass::class.java) + } + } + + @Test // gh-1961 + fun `findAllById(ids) with reified type parameter extension should call its Java counterpart`() { + val ids = listOf(1L, 2L) + operations.findAllById(ids) + verify { + operations.findAllById(ids, TestClass::class.java) + } + } + + @Test // gh-1961 + fun `findAll() with reified type parameter extension should call its Java counterpart`() { + operations.findAll() + verify { + operations.findAll(TestClass::class.java) + } + } + + @Test // gh-1961 + fun `findAll(Sort) with reified type parameter extension should call its Java counterpart`() { + val sort = mockk(relaxed = true) + operations.findAll(sort) + verify { + operations.findAll(TestClass::class.java, sort) + } + } + + @Test // gh-1961 + fun `findAll(Pageable) with reified type parameter extension should call its Java counterpart`() { + val pageable = mockk(relaxed = true) + operations.findAll(pageable) + verify { + operations.findAll(TestClass::class.java, pageable) + } + } + + @Test // gh-1961 + fun `findOne(Query) with reified type parameter extension should call its Java counterpart`() { + val query = mockk(relaxed = true) + operations.findOne(query) + verify { + operations.findOne(query, TestClass::class.java) + } + } + + @Test // gh-1961 + fun `findAll(Query) with reified type parameter extension should call its Java counterpart`() { + val query = mockk(relaxed = true) + operations.findAll(query) + verify { + operations.findAll(query, TestClass::class.java) + } + } + + + @Test // gh-1961 + fun `findAll(Query, Pageable) with reified type parameter extension should call its Java counterpart`() { + val query = mockk(relaxed = true) + val pageable = mockk(relaxed = true) + operations.findAll(query, pageable) + verify { + operations.findAll(query, TestClass::class.java, pageable) + } + } + + @Test // gh-1961 + fun `deleteById(id) with reified type parameter extension should call its Java counterpart`() { + val id = 1L + operations.deleteById(id) + verify { + operations.deleteById(id, TestClass::class.java) + } + } + + @Test // gh-1961 + fun `deleteAllById(ids) with reified type parameter extension should call its Java counterpart`() { + val ids = listOf(1L, 2L) + operations.deleteAllById(ids) + verify { + operations.deleteAllById(ids, TestClass::class.java) + } + } + + @Test // gh-1961 + fun `deleteAll(ids) with reified type parameter extension should call its Java counterpart`() { + operations.deleteAll() + verify { + operations.deleteAll(TestClass::class.java) + } + } +} \ No newline at end of file