DATAMONGO-2417 - Typesafe Kotlin Extension for distinct queries.
We now provide extensions for imperative and reactive distinct queries accepting Kotlin's KProperty and KProperty1 to express type-safe queries: mongo.query<Customer>().distinct(Customer::name) mongo.distinct(Customer::name) Original Pull Request: #809
This commit is contained in:
committed by
Christoph Strobl
parent
d0c2c820d7
commit
2c9956723e
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core
|
||||
|
||||
import org.springframework.data.mongodb.core.query.asString
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
/**
|
||||
* Extension for [ExecutableFindOperation.query] providing a [KClass] based variant.
|
||||
@@ -38,6 +41,15 @@ fun <T : Any> ExecutableFindOperation.query(entityClass: KClass<T>): ExecutableF
|
||||
inline fun <reified T : Any> ExecutableFindOperation.query(): ExecutableFindOperation.ExecutableFind<T> =
|
||||
query(T::class.java)
|
||||
|
||||
/**
|
||||
* Extension for [ExecutableFindOperation.query] for a type-safe projection of distinct values.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.3
|
||||
*/
|
||||
inline fun <reified T : Any> ExecutableFindOperation.distinct(field : KProperty1<T, *>): ExecutableFindOperation.TerminatingDistinct<Any> =
|
||||
query(T::class.java).distinct(field.name)
|
||||
|
||||
/**
|
||||
* Extension for [ExecutableFindOperation.FindWithProjection.as] providing a [KClass] based variant.
|
||||
*
|
||||
@@ -78,3 +90,12 @@ fun <T : Any> ExecutableFindOperation.DistinctWithProjection.asType(resultType:
|
||||
*/
|
||||
inline fun <reified T : Any> ExecutableFindOperation.DistinctWithProjection.asType(): ExecutableFindOperation.TerminatingDistinct<T> =
|
||||
`as`(T::class.java)
|
||||
|
||||
/**
|
||||
* Extension for [ExecutableFindOperation.FindDistinct.distinct] leveraging KProperty.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.3
|
||||
*/
|
||||
fun ExecutableFindOperation.FindDistinct.distinct(key: KProperty<*>): ExecutableFindOperation.TerminatingDistinct<Any> =
|
||||
distinct(asString(key))
|
||||
|
||||
@@ -20,7 +20,10 @@ import kotlinx.coroutines.reactive.asFlow
|
||||
import kotlinx.coroutines.reactive.awaitFirstOrNull
|
||||
import kotlinx.coroutines.reactive.awaitSingle
|
||||
import org.springframework.data.geo.GeoResult
|
||||
import org.springframework.data.mongodb.core.query.asString
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
/**
|
||||
* Extension for [ReactiveFindOperation.query] providing a [KClass] based variant.
|
||||
@@ -41,6 +44,15 @@ fun <T : Any> ReactiveFindOperation.query(entityClass: KClass<T>): ReactiveFindO
|
||||
inline fun <reified T : Any> ReactiveFindOperation.query(): ReactiveFindOperation.ReactiveFind<T> =
|
||||
query(T::class.java)
|
||||
|
||||
/**
|
||||
* Extension for [ReactiveFindOperation.query] for a type-safe projection of distinct values.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.3
|
||||
*/
|
||||
inline fun <reified T : Any> ReactiveFindOperation.distinct(field : KProperty1<T, *>): ReactiveFindOperation.TerminatingDistinct<Any> =
|
||||
query(T::class.java).distinct(field.name)
|
||||
|
||||
/**
|
||||
* Extension for [ReactiveFindOperation.FindWithProjection.as] providing a [KClass] based variant.
|
||||
*
|
||||
@@ -79,6 +91,15 @@ fun <T : Any> ReactiveFindOperation.DistinctWithProjection.asType(resultType: KC
|
||||
inline fun <reified T : Any> ReactiveFindOperation.DistinctWithProjection.asType(): ReactiveFindOperation.TerminatingDistinct<T> =
|
||||
`as`(T::class.java)
|
||||
|
||||
/**
|
||||
* Extension for [ReactiveFindOperation.FindDistinct.distinct] leveraging KProperty.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.3
|
||||
*/
|
||||
fun ReactiveFindOperation.FindDistinct.distinct(key: KProperty<*>): ReactiveFindOperation.TerminatingDistinct<Any> =
|
||||
distinct(asString(key))
|
||||
|
||||
/**
|
||||
* Non-nullable Coroutines variant of [ReactiveFindOperation.TerminatingFind.one].
|
||||
*
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.mongodb.core
|
||||
|
||||
import example.first.First
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import org.junit.Test
|
||||
@@ -32,6 +33,10 @@ class ExecutableFindOperationExtensionsTests {
|
||||
|
||||
val distinctWithProjection = mockk<ExecutableFindOperation.DistinctWithProjection>(relaxed = true)
|
||||
|
||||
val findDistinct = mockk<ExecutableFindOperation.FindDistinct>(relaxed = true)
|
||||
|
||||
val executableFind = mockk<ExecutableFindOperation.ExecutableFind<KotlinUser>>(relaxed = true)
|
||||
|
||||
@Test // DATAMONGO-1689
|
||||
@Suppress("DEPRECATION")
|
||||
fun `ExecutableFindOperation#query(KClass) extension should call its Java counterpart`() {
|
||||
@@ -76,4 +81,25 @@ class ExecutableFindOperationExtensionsTests {
|
||||
distinctWithProjection.asType<User>()
|
||||
verify { distinctWithProjection.`as`(User::class.java) }
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2417
|
||||
fun `ExecutableFindOperation#distrinct() using KProperty1 should call its Java counterpart`() {
|
||||
|
||||
every { operation.query(KotlinUser::class.java) } returns executableFind
|
||||
|
||||
operation.distinct(KotlinUser::username)
|
||||
verify {
|
||||
operation.query(KotlinUser::class.java)
|
||||
executableFind.distinct("username")
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2417
|
||||
fun `ExecutableFindOperation#FindDistinct#field() using KProperty should call its Java counterpart`() {
|
||||
|
||||
findDistinct.distinct(KotlinUser::username)
|
||||
verify { findDistinct.distinct("username") }
|
||||
}
|
||||
|
||||
data class KotlinUser(val username: String)
|
||||
}
|
||||
|
||||
@@ -42,6 +42,10 @@ class ReactiveFindOperationExtensionsTests {
|
||||
|
||||
val distinctWithProjection = mockk<ReactiveFindOperation.DistinctWithProjection>(relaxed = true)
|
||||
|
||||
val findDistinct = mockk<ReactiveFindOperation.FindDistinct>(relaxed = true)
|
||||
|
||||
val reactiveFind = mockk<ReactiveFindOperation.ReactiveFind<KotlinUser>>(relaxed = true)
|
||||
|
||||
@Test // DATAMONGO-1719
|
||||
@Suppress("DEPRECATION")
|
||||
fun `ReactiveFind#query(KClass) extension should call its Java counterpart`() {
|
||||
@@ -87,6 +91,25 @@ class ReactiveFindOperationExtensionsTests {
|
||||
verify { distinctWithProjection.`as`(User::class.java) }
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2417
|
||||
fun `ReactiveFind#distrinct() using KProperty1 should call its Java counterpart`() {
|
||||
|
||||
every { operation.query(KotlinUser::class.java) } returns reactiveFind
|
||||
|
||||
operation.distinct(KotlinUser::username)
|
||||
verify {
|
||||
operation.query(KotlinUser::class.java)
|
||||
reactiveFind.distinct("username")
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2417
|
||||
fun `ReactiveFind#FindDistinct#field() using KProperty should call its Java counterpart`() {
|
||||
|
||||
findDistinct.distinct(KotlinUser::username)
|
||||
verify { findDistinct.distinct("username") }
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2209
|
||||
fun terminatingFindAwaitOneWithValue() {
|
||||
|
||||
@@ -299,4 +322,6 @@ class ReactiveFindOperationExtensionsTests {
|
||||
spec.all()
|
||||
}
|
||||
}
|
||||
|
||||
data class KotlinUser(val username: String)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user