Skip to content

Commit 0102fdf

Browse files
committed
DATAMONGO-2138 - Change or/nor/and syntax
1 parent 5fd0ff9 commit 0102fdf

File tree

3 files changed

+26
-56
lines changed

3 files changed

+26
-56
lines changed

spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/query/TypedCriteriaBuilder.kt

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ typealias TypedCriteria = TypedCriteriaBuilder.() -> Unit
3838
* @author Tjeu Kayim
3939
*/
4040
class TypedCriteriaBuilder {
41-
private var criteria = Criteria()
42-
private val operations = mutableListOf<Operation>()
41+
internal var criteria: Criteria = Criteria()
42+
private set
4343

4444
/**
4545
* Creates a criterion using equality.
@@ -330,10 +330,8 @@ class TypedCriteriaBuilder {
330330
addOperation { bits().let(bitwiseCriteria) }
331331

332332

333-
private fun <T> KProperty<T>.addOperation(operation: Criteria.() -> Criteria): Operation {
334-
val typedOperation = Operation(this, operation)
335-
operations.add(typedOperation)
336-
return typedOperation
333+
private fun <T> KProperty<T>.addOperation(operation: Criteria.() -> Criteria) {
334+
criteria = criteria.and(nestedFieldName(this)).operation()
337335
}
338336

339337
/**
@@ -342,27 +340,26 @@ class TypedCriteriaBuilder {
342340
* Note that mongodb doesn't support an $or operator to be wrapped in a $not operator.
343341
* @see Criteria.orOperator
344342
*/
345-
fun or(builder: TypedCriteria) = addOperatorWithCriteria(builder, Criteria::orOperator)
343+
fun or(vararg builders: TypedCriteria) = addOperatorWithCriteria(builders, Criteria::orOperator)
346344

347345
/**
348346
* Creates a 'nor' criteria using the $nor operator for all of the provided criteria.
349347
*
350348
* Note that mongodb doesn't support an $nor operator to be wrapped in a $not operator.
351349
* @see Criteria.norOperator
352350
*/
353-
fun nor(builder: TypedCriteria) = addOperatorWithCriteria(builder, Criteria::norOperator)
351+
fun nor(vararg builders: TypedCriteria) = addOperatorWithCriteria(builders, Criteria::norOperator)
354352

355353
/**
356354
* Creates an 'and' criteria using the $and operator for all of the provided criteria.
357355
*
358356
* Note that mongodb doesn't support an $and operator to be wrapped in a $not operator.
359357
* @see Criteria.andOperator
360358
*/
361-
fun and(builder: TypedCriteria) = addOperatorWithCriteria(builder, Criteria::andOperator)
359+
fun and(vararg builders: TypedCriteria) = addOperatorWithCriteria(builders, Criteria::andOperator)
362360

363-
private fun addOperatorWithCriteria(builder: TypedCriteria, operation: Criteria.(Array<Criteria>) -> Criteria) {
364-
val otherCriteria = TypedCriteriaBuilder().apply(builder).listCriteria()
365-
chainCriteria()
361+
private fun addOperatorWithCriteria(builders: Array<out TypedCriteria>, operation: Criteria.(Array<Criteria>) -> Criteria) {
362+
val otherCriteria = builders.map { TypedCriteriaBuilder().apply(it) }.map { it.criteria }
366363
criteria.operation(otherCriteria.toTypedArray())
367364
}
368365

@@ -376,31 +373,4 @@ class TypedCriteriaBuilder {
376373
*/
377374
operator fun <T, U> KProperty<T>.div(other: KProperty1<T, U>) =
378375
NestedProperty(this, other)
379-
380-
/**
381-
* Apply all operations to one criteria.
382-
*/
383-
internal fun chainCriteria(): Criteria {
384-
criteria = operations.fold(criteria) { chain, head -> head.operation(chain.and(head.name)) }
385-
operations.clear()
386-
return criteria
387-
}
388-
389-
/**
390-
* Map each operation to a criteria.
391-
*/
392-
private fun listCriteria(): List<Criteria> {
393-
return operations.map { it.criteria }
394-
}
395-
396-
/**
397-
* Typed Operation, stores property and operation function.
398-
*/
399-
class Operation(
400-
property: KProperty<Any?>,
401-
val operation: Criteria.() -> Criteria
402-
) {
403-
val name = nestedFieldName(property)
404-
val criteria by lazy { Criteria(name).operation() }
405-
}
406376
}

spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/query/TypedCriteriaExtensions.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ package org.springframework.data.mongodb.core.query
2424
*/
2525
fun typedCriteria(criteria: TypedCriteria): Criteria {
2626
val builder = TypedCriteriaBuilder().apply(criteria)
27-
return builder.chainCriteria()
27+
return builder.criteria
2828
}
2929

3030
/**
@@ -48,10 +48,10 @@ private fun typedCriteriaSample() {
4848
// $or operator
4949
typedCriteria {
5050
Book::name isEqualTo "Moby-Dick"
51-
or {
52-
Book::price lt 1200
53-
Book::price gt 240
54-
}
51+
or(
52+
{ Book::price lt 1200 },
53+
{ Book::price gt 240 }
54+
)
5555
}
5656
// Nested properties
5757
typedCriteria {

spring-data-mongodb/src/test/kotlin/org/springframework/data/mongodb/core/query/TypedCriteriaExtensionsTest.kt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,10 @@ class TypedCriteriaExtensionsTest {
319319
fun `or operator() typed criteria should equal classic criteria`() {
320320
val typed = typedCriteria {
321321
Book::name isEqualTo "Moby-Dick"
322-
or {
323-
Book::price lt 1200
324-
Book::price gt 240
325-
}
322+
or(
323+
{ Book::price lt 1200 },
324+
{ Book::price gt 240 }
325+
)
326326
}
327327
val classic = Criteria("name").isEqualTo("Moby-Dick")
328328
.orOperator(
@@ -336,10 +336,10 @@ class TypedCriteriaExtensionsTest {
336336
fun `nor() typed criteria should equal classic criteria`() {
337337
val typed = typedCriteria {
338338
Book::name isEqualTo "Moby-Dick"
339-
nor {
340-
Book::price lt 1200
341-
Book::price gt 240
342-
}
339+
nor(
340+
{ Book::price lt 1200 },
341+
{ Book::price gt 240 }
342+
)
343343
}
344344
val classic = Criteria("name").isEqualTo("Moby-Dick")
345345
.norOperator(
@@ -353,10 +353,10 @@ class TypedCriteriaExtensionsTest {
353353
fun `and() typed criteria should equal classic criteria`() {
354354
val typed = typedCriteria {
355355
Book::name isEqualTo "Moby-Dick"
356-
and {
357-
Book::price lt 1200
358-
Book::price gt 240
359-
}
356+
and(
357+
{ Book::price lt 1200 },
358+
{ Book::price gt 240 }
359+
)
360360
}
361361
val classic = Criteria("name").isEqualTo("Moby-Dick")
362362
.andOperator(

0 commit comments

Comments
 (0)