diff --git a/pom.xml b/pom.xml index 3891e1d..0aa6dcd 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,7 @@ Arabba-M7 1.0.1 1.10.1 + 1.1.1 @@ -126,6 +127,32 @@ reactor-core + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin} + true + + + org.jetbrains.kotlin + kotlin-reflect + ${kotlin} + true + + + org.jetbrains.kotlinx + kotlinx-coroutines-core + ${coroutines.version} + true + + + org.jetbrains.kotlinx + kotlinx-coroutines-reactor + ${coroutines.version} + true + + org.assertj assertj-core @@ -198,6 +225,13 @@ test + + io.mockk + mockk + 1.9.1 + test + + diff --git a/src/main/kotlin/org/springframework/data/r2dbc/function/DatabaseClientExtensions.kt b/src/main/kotlin/org/springframework/data/r2dbc/function/DatabaseClientExtensions.kt new file mode 100644 index 0000000..7799e7c --- /dev/null +++ b/src/main/kotlin/org/springframework/data/r2dbc/function/DatabaseClientExtensions.kt @@ -0,0 +1,82 @@ +/* + * Copyright 2018-2019 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.springframework.data.r2dbc.function + +import kotlinx.coroutines.reactive.awaitFirstOrNull + +/** + * Coroutines variant of [DatabaseClient.GenericExecuteSpec.then]. + * + * @author Sebastien Deleuze + */ +suspend fun DatabaseClient.GenericExecuteSpec.await() { + then().awaitFirstOrNull() +} + +/** + * Extension for [DatabaseClient.GenericExecuteSpec.as] providing a + * `asType()` variant. + * + * @author Sebastien Deleuze + */ +inline fun DatabaseClient.GenericExecuteSpec.asType(): DatabaseClient.TypedExecuteSpec + = `as`(T::class.java) + +/** + * Extension for [DatabaseClient.GenericSelectSpec.as] providing a + * `asType()` variant. + * + * @author Sebastien Deleuze + */ +inline fun DatabaseClient.GenericSelectSpec.asType(): DatabaseClient.TypedSelectSpec + = `as`(T::class.java) + +/** + * Coroutines variant of [DatabaseClient.TypedExecuteSpec.then]. + * + * @author Sebastien Deleuze + */ +suspend fun DatabaseClient.TypedExecuteSpec.await() { + then().awaitFirstOrNull() +} + +/** + * Extension for [DatabaseClient.TypedExecuteSpec.as] providing a + * `asType()` variant. + * + * @author Sebastien Deleuze + */ +inline fun DatabaseClient.TypedExecuteSpec.asType(): DatabaseClient.TypedExecuteSpec + = `as`(T::class.java) + +/** + * Coroutines variant of [DatabaseClient.InsertSpec.then]. + * + * @author Sebastien Deleuze + */ +suspend fun DatabaseClient.InsertSpec.await() { + then().awaitFirstOrNull() +} + +/** + * Extension for [DatabaseClient.InsertIntoSpec.into] providing a + * `into()` variant. + * + * @author Sebastien Deleuze + */ +inline fun DatabaseClient.InsertIntoSpec.into(): DatabaseClient.TypedInsertSpec + = into(T::class.java) + diff --git a/src/main/kotlin/org/springframework/data/r2dbc/function/RowsFetchSpecExtensions.kt b/src/main/kotlin/org/springframework/data/r2dbc/function/RowsFetchSpecExtensions.kt new file mode 100644 index 0000000..8b11402 --- /dev/null +++ b/src/main/kotlin/org/springframework/data/r2dbc/function/RowsFetchSpecExtensions.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2018-2019 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.springframework.data.r2dbc.function + +import kotlinx.coroutines.reactive.awaitFirstOrNull + +/** + * Coroutines variant of [RowsFetchSpec.one]. + * + * @author Sebastien Deleuze + */ +suspend fun RowsFetchSpec.awaitOne(): T? + = one().awaitFirstOrNull() + +/** + * Coroutines variant of [RowsFetchSpec.first]. + * + * @author Sebastien Deleuze + */ +suspend fun RowsFetchSpec.awaitFirst(): T? + = first().awaitFirstOrNull() + +// TODO Coroutines variant of [RowsFetchSpec.all], depends on [kotlinx.coroutines#254](https://github.com/Kotlin/kotlinx.coroutines/issues/254). +// suspend fun RowsFetchSpec.awaitAll() = all()... diff --git a/src/test/kotlin/org/springframework/data/r2dbc/function/DatabaseClientExtensionsTests.kt b/src/test/kotlin/org/springframework/data/r2dbc/function/DatabaseClientExtensionsTests.kt new file mode 100644 index 0000000..62dc461 --- /dev/null +++ b/src/test/kotlin/org/springframework/data/r2dbc/function/DatabaseClientExtensionsTests.kt @@ -0,0 +1,114 @@ +/* + * Copyright 2018-2019 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.springframework.data.r2dbc.function + +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.runBlocking +import org.junit.Assert.assertEquals +import org.junit.Test +import reactor.core.publisher.Mono + +class DatabaseClientExtensionsTests { + + @Test + fun genericExecuteSpecAwait() { + val spec = mockk() + every { spec.then() } returns Mono.empty() + runBlocking { + spec.await() + } + verify { + spec.then() + } + } + + @Test + fun genericExecuteSpecAsType() { + val genericSpec = mockk() + val typedSpec: DatabaseClient.TypedExecuteSpec = mockk() + every { genericSpec.`as`(String::class.java) } returns typedSpec + runBlocking { + assertEquals(typedSpec, genericSpec.asType()) + } + verify { + genericSpec.`as`(String::class.java) + } + } + + @Test + fun genericSelectSpecAsType() { + val genericSpec = mockk() + val typedSpec: DatabaseClient.TypedSelectSpec = mockk() + every { genericSpec.`as`(String::class.java) } returns typedSpec + runBlocking { + assertEquals(typedSpec, genericSpec.asType()) + } + verify { + genericSpec.`as`(String::class.java) + } + } + + @Test + fun typedExecuteSpecAwait() { + val spec = mockk>() + every { spec.then() } returns Mono.empty() + runBlocking { + spec.await() + } + verify { + spec.then() + } + } + + @Test + fun typedExecuteSpecAsType() { + val spec: DatabaseClient.TypedExecuteSpec = mockk() + every { spec.`as`(String::class.java) } returns spec + runBlocking { + assertEquals(spec, spec.asType()) + } + verify { + spec.`as`(String::class.java) + } + } + + @Test + fun insertSpecAwait() { + val spec = mockk>() + every { spec.then() } returns Mono.empty() + runBlocking { + spec.await() + } + verify { + spec.then() + } + } + + @Test + fun insertIntoSpecInto() { + val spec = mockk() + val typedSpec: DatabaseClient.TypedInsertSpec = mockk() + every { spec.into(String::class.java) } returns typedSpec + runBlocking { + assertEquals(typedSpec, spec.into()) + } + verify { + spec.into(String::class.java) + } + } +} diff --git a/src/test/kotlin/org/springframework/data/r2dbc/function/RowsFetchSpecExtensionsTests.kt b/src/test/kotlin/org/springframework/data/r2dbc/function/RowsFetchSpecExtensionsTests.kt new file mode 100644 index 0000000..760e9ef --- /dev/null +++ b/src/test/kotlin/org/springframework/data/r2dbc/function/RowsFetchSpecExtensionsTests.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2018-2019 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.springframework.data.r2dbc.function + +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.runBlocking +import org.junit.Assert.assertEquals +import org.junit.Test +import reactor.core.publisher.Mono + +class RowsFetchSpecExtensionsTests { + + @Test + fun awaitOne() { + val spec = mockk>() + every { spec.one() } returns Mono.just("foo") + runBlocking { + assertEquals("foo", spec.awaitOne()) + } + verify { + spec.one() + } + } + + @Test + fun awaitFirst() { + val spec = mockk>() + every { spec.first() } returns Mono.just("foo") + runBlocking { + assertEquals("foo", spec.awaitFirst()) + } + verify { + spec.first() + } + } +}