Skip to content

Commit bc12a92

Browse files
committed
DATAMONGO-2138 - Lambda Syntax for Typed Queries
1 parent f6133be commit bc12a92

File tree

4 files changed

+48
-41
lines changed

4 files changed

+48
-41
lines changed

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

+25-18
Original file line numberDiff line numberDiff line change
@@ -33,23 +33,30 @@ class TypedCriteria(
3333
override fun getKey(): String? = criteria.key
3434
}
3535

36-
fun typedCriteria(vararg typedCriteria: TypedCriteria): CriteriaDefinition {
37-
return typedCriteria.fold(Criteria()) { chain, head -> head.operation(chain.and(head.name))}
36+
fun typedCriteria(criteria: TypedCriteriaBuilder.() -> Unit): CriteriaDefinition {
37+
val builder = TypedCriteriaBuilder().apply(criteria)
38+
return builder.chain.fold(Criteria()) { chain, head -> head.operation(chain.and(head.name)) }
3839
}
3940

40-
infix fun <T> KProperty<T>.isEqualTo(value: T) = buildCriteria { isEqualTo(value) }
41-
infix fun <T> KProperty<T>.ne(value: T) = buildCriteria { ne(value) }
42-
infix fun <T> KProperty<T>.lt(value: T) = buildCriteria { lt(value) }
43-
infix fun <T> KProperty<T>.lte(value: T) = buildCriteria { lte(value) }
44-
infix fun <T> KProperty<T>.gt(value: T) = buildCriteria { gt(value) }
45-
infix fun <T> KProperty<T>.gte(value: T) = buildCriteria { gte(value) }
46-
infix fun <T> KProperty<T>.inValues(value: Collection<T>) = buildCriteria { `in`(value) }
47-
fun <T> KProperty<T>.inValues(vararg o: Any) = buildCriteria { `in`(*o) }
48-
infix fun <T> KProperty<T>.nin(value: Collection<T>) = buildCriteria { nin(value) }
49-
fun <T> KProperty<T>.nin(vararg o: Any) = buildCriteria { nin(*o) }
50-
fun KProperty<Number>.mod(value: Number, remainder: Number) = buildCriteria { mod(value, remainder) }
51-
infix fun <T : Collection<*>> KProperty<T>.all(value: T) = buildCriteria { all(value) }
52-
fun <T> KProperty<T>.all(vararg o: Any) = buildCriteria { all(*o) }
53-
infix fun KProperty<Collection<*>>.size(s: Int) = buildCriteria { size(s) }
54-
55-
private fun <T> KProperty<T>.buildCriteria(operation: Criteria.() -> Criteria) = TypedCriteria(this, operation)
41+
class TypedCriteriaBuilder {
42+
val chain = mutableListOf<TypedCriteria>()
43+
44+
infix fun <T> KProperty<T>.isEqualTo(value: T) = buildCriteria { isEqualTo(value) }
45+
infix fun <T> KProperty<T>.ne(value: T) = buildCriteria { ne(value) }
46+
infix fun <T> KProperty<T>.lt(value: T) = buildCriteria { lt(value) }
47+
infix fun <T> KProperty<T>.lte(value: T) = buildCriteria { lte(value) }
48+
infix fun <T> KProperty<T>.gt(value: T) = buildCriteria { gt(value) }
49+
infix fun <T> KProperty<T>.gte(value: T) = buildCriteria { gte(value) }
50+
infix fun <T> KProperty<T>.inValues(value: Collection<T>) = buildCriteria { `in`(value) }
51+
fun <T> KProperty<T>.inValues(vararg o: Any) = buildCriteria { `in`(*o) }
52+
infix fun <T> KProperty<T>.nin(value: Collection<T>) = buildCriteria { nin(value) }
53+
fun <T> KProperty<T>.nin(vararg o: Any) = buildCriteria { nin(*o) }
54+
fun KProperty<Number>.mod(value: Number, remainder: Number) = buildCriteria { mod(value, remainder) }
55+
infix fun <T : Collection<*>> KProperty<T>.all(value: T) = buildCriteria { all(value) }
56+
fun <T> KProperty<T>.all(vararg o: Any) = buildCriteria { all(*o) }
57+
infix fun KProperty<Collection<*>>.size(s: Int) = buildCriteria { size(s) }
58+
59+
private fun <T> KProperty<T>.buildCriteria(operation: Criteria.() -> Criteria) {
60+
chain.add(TypedCriteria(this, operation))
61+
}
62+
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ package org.springframework.data.mongodb.core.query
1919
* Create a new Query with one or more TypedCriteria.
2020
* @author Tjeu Kayim
2121
*/
22-
fun typedQuery(vararg criteria: TypedCriteria): Query {
23-
return Query(typedCriteria(*criteria))
22+
fun typedQuery(criteria: TypedCriteriaBuilder.() -> Unit): Query {
23+
return Query(typedCriteria(criteria))
2424
}

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

+17-17
Original file line numberDiff line numberDiff line change
@@ -27,109 +27,109 @@ import org.springframework.data.mongodb.core.mapping.Document
2727
class TypedCriteriaExtensionsTest {
2828
@Test
2929
fun `Typed query gt and isEqualTo`() {
30-
val typed = typedCriteria(
31-
Book::price gt 1100,
30+
val typed = typedCriteria {
31+
Book::price gt 1100
3232
Book::available isEqualTo true
33-
)
33+
}
3434
val classic = Criteria("price").gt(1100)
3535
.and("available").isEqualTo(true)
3636
assertCriteriaEquals(classic, typed)
3737
}
3838

3939
@Test
4040
fun `Typed criteria isEqualTo`() {
41-
val typed = Book::name isEqualTo "Moby-Dick"
41+
val typed = typedCriteria {Book::name isEqualTo "Moby-Dick"}
4242
val classic = Criteria("name").isEqualTo("Moby-Dick")
4343
assertCriteriaEquals(classic, typed)
4444
}
4545

4646
@Test
4747
fun `Typed criteria ne`() {
48-
val typed = Book::name ne "Moby-Dick"
48+
val typed = typedCriteria {Book::name ne "Moby-Dick"}
4949
val classic = Criteria("name").ne("Moby-Dick")
5050
assertCriteriaEquals(classic, typed)
5151
}
5252

5353
@Test
5454
fun `Typed criteria lt`() {
55-
val typed = Book::price lt 100
55+
val typed = typedCriteria {Book::price lt 100}
5656
val classic = Criteria("price").lt(100)
5757
assertCriteriaEquals(classic, typed)
5858
}
5959

6060
@Test
6161
fun `Typed criteria lte`() {
62-
val typed = Book::price lte 100
62+
val typed = typedCriteria {Book::price lte 100}
6363
val classic = Criteria("price").lte(100)
6464
assertCriteriaEquals(classic, typed)
6565
}
6666

6767
@Test
6868
fun `Typed criteria gt`() {
69-
val typed = Book::price gt 100
69+
val typed = typedCriteria {Book::price gt 100}
7070
val classic = Criteria("price").gt(100)
7171
assertCriteriaEquals(classic, typed)
7272
}
7373

7474
@Test
7575
fun `Typed criteria gte`() {
76-
val typed = Book::price gte 100
76+
val typed = typedCriteria {Book::price gte 100}
7777
val classic = Criteria("price").gte(100)
7878
assertCriteriaEquals(classic, typed)
7979
}
8080

8181
@Test
8282
fun `Typed criteria inValues`() {
83-
val typed = Book::price.inValues(1, 2, 3)
83+
val typed = typedCriteria {Book::price.inValues(1, 2, 3)}
8484
val classic = Criteria("price").inValues(1, 2, 3)
8585
assertCriteriaEquals(classic, typed)
8686
}
8787

8888
@Test
8989
fun `Typed criteria inValues list`() {
90-
val typed = Book::price inValues listOf(1, 2, 3)
90+
val typed = typedCriteria {Book::price inValues listOf(1, 2, 3)}
9191
val classic = Criteria("price").inValues(listOf(1, 2, 3))
9292
assertCriteriaEquals(classic, typed)
9393
}
9494

9595
@Test
9696
fun `Typed criteria nin`() {
97-
val typed = Book::price.nin(1, 2, 3)
97+
val typed = typedCriteria {Book::price.nin(1, 2, 3)}
9898
val classic = Criteria("price").nin(1, 2, 3)
9999
assertCriteriaEquals(classic, typed)
100100
}
101101

102102
@Test
103103
fun `Typed criteria nin list`() {
104-
val typed = Book::price nin listOf(1, 2, 3)
104+
val typed = typedCriteria {Book::price nin listOf(1, 2, 3)}
105105
val classic = Criteria("price").nin(listOf(1, 2, 3))
106106
assertCriteriaEquals(classic, typed)
107107
}
108108

109109
@Test
110110
fun `Typed criteria mod`() {
111-
val typed = Book::price.mod(2, 3)
111+
val typed = typedCriteria {Book::price.mod(2, 3)}
112112
val classic = Criteria("price").mod(2, 3)
113113
assertCriteriaEquals(classic, typed)
114114
}
115115

116116
@Test
117117
fun `Typed criteria all`() {
118-
val typed = Book::authors.all(1, 2, 3)
118+
val typed = typedCriteria {Book::authors.all(1, 2, 3)}
119119
val classic = Criteria("authors").all(1, 2, 3)
120120
assertCriteriaEquals(classic, typed)
121121
}
122122

123123
@Test
124124
fun `Typed criteria all list`() {
125-
val typed = Book::authors all listOf(1, 2, 3)
125+
val typed = typedCriteria {Book::authors all listOf(1, 2, 3)}
126126
val classic = Criteria("authors").all(listOf(1, 2, 3))
127127
assertCriteriaEquals(classic, typed)
128128
}
129129

130130
@Test
131131
fun `Typed criteria size`() {
132-
val typed = Book::authors size 4
132+
val typed = typedCriteria {Book::authors size 4}
133133
val classic = Criteria("authors").size(4)
134134
assertCriteriaEquals(classic, typed)
135135
}

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ class TypedQueryExtensionsTest {
3232
.and("available").isEqualTo(true)
3333
)
3434

35-
val typed = typedQuery(
36-
Book::price gt 1100,
35+
val typed = typedQuery {
36+
Book::price gt 1100
3737
Book::available isEqualTo true
38-
)
38+
}
3939

4040
assertEquals(classic.queryObject, typed.queryObject)
4141
}
4242

4343
@Test
4444
fun `Typed Query`() {
45-
typedQuery(Book::name lte 123)
45+
typedQuery { Book::name lte 123 }
4646
}
4747
}

0 commit comments

Comments
 (0)