Skip to content

Commit 413539e

Browse files
committed
fixes #137 Typed query isn't type-safe
1 parent 89481dd commit 413539e

File tree

8 files changed

+169
-40
lines changed

8 files changed

+169
-40
lines changed

kmongo-annotation-processor/src/test/kotlin/org/litote/kmongo/PathTest.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.litote.kmongo
1818

1919
import org.junit.Test
20+
import org.litote.kmongo.model.SimpleReferenced2Data
2021
import org.litote.kmongo.model.SubData2_
2122
import org.litote.kmongo.model.TestData_
2223
import org.litote.kmongo.model.other.SimpleReferencedData
@@ -73,7 +74,7 @@ class PathTest {
7374

7475
//check compilation
7576
if (false)
76-
(TestData_.Map2.keyProjection(Locale.ENGLISH) eq SimpleReferencedData()).json
77+
(TestData_.Map2.keyProjection(Locale.ENGLISH) eq SimpleReferenced2Data()).json
7778

7879
assertEquals(
7980
"set.$.labels.zh_CN",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright (C) 2017/2019 Litote
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package kotlin.internal
18+
19+
@Target(AnnotationTarget.TYPE_PARAMETER)
20+
@Retention(AnnotationRetention.BINARY)
21+
internal annotation class OnlyInputTypes

kmongo-property/src/main/kotlin/org/litote/kmongo/Filters.kt

+28-14
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import org.bson.BsonType
2525
import org.bson.Document
2626
import org.bson.conversions.Bson
2727
import java.util.regex.Pattern
28+
import kotlin.internal.OnlyInputTypes
2829
import kotlin.reflect.KProperty
2930

3031
/**
@@ -34,9 +35,9 @@ import kotlin.reflect.KProperty
3435
* @param value the value
3536
* @param <T> the value type
3637
* @return the filter
37-
* @mongodb.driver.manual reference/operator/query/eq $eq
38+
* @mongodb.driveDr.manual reference/operator/query/eq $eq
3839
*/
39-
infix fun <T> KProperty<T>.eq(value: T): Bson = Filters.eq(path(), value)
40+
infix fun <@OnlyInputTypes T, V : T> KProperty<T?>.eq(value: V): Bson = Filters.eq(path(), value)
4041

4142
/**
4243
* Creates a filter that matches all documents where the value of the property contains the specified value. Note that this doesn't
@@ -52,7 +53,7 @@ infix fun <T> KProperty<T>.eq(value: T): Bson = Filters.eq(path(), value)
5253
* @return the filter
5354
* @mongodb.driver.manual reference/operator/query/eq/#op._S_eq
5455
*/
55-
infix fun <T> KProperty<Collection<T>?>.contains(value: T): Bson = Filters.eq(path(), value)
56+
infix fun <@OnlyInputTypes T> KProperty<Iterable<T?>?>.contains(value: T): Bson = Filters.eq(path(), value)
5657

5758
/**
5859
* Creates a filter that matches all documents where the value of the field name does not equal the specified value.
@@ -62,7 +63,7 @@ infix fun <T> KProperty<Collection<T>?>.contains(value: T): Bson = Filters.eq(pa
6263
* @return the filter
6364
* @mongodb.driver.manual reference/operator/query/ne $ne
6465
*/
65-
infix fun <T> KProperty<T>.ne(value: T): Bson = Filters.ne(path(), value)
66+
infix fun <@OnlyInputTypes T> KProperty<T?>.ne(value: T): Bson = Filters.ne(path(), value)
6667

6768
/**
6869
* Creates a filter that matches all documents where the value of the given property is less than the specified value.
@@ -72,7 +73,7 @@ infix fun <T> KProperty<T>.ne(value: T): Bson = Filters.ne(path(), value)
7273
* @return the filter
7374
* @mongodb.driver.manual reference/operator/query/lt $lt
7475
*/
75-
infix fun <T> KProperty<T>.lt(item: T): Bson = Filters.lt(path(), item)
76+
infix fun <@OnlyInputTypes T> KProperty<T?>.lt(item: T): Bson = Filters.lt(path(), item)
7677

7778
/**
7879
* Creates a filter that matches all documents where the value of the given property is greater than the specified value.
@@ -82,7 +83,7 @@ infix fun <T> KProperty<T>.lt(item: T): Bson = Filters.lt(path(), item)
8283
* @return the filter
8384
* @mongodb.driver.manual reference/operator/query/gt $gt
8485
*/
85-
infix fun <T> KProperty<T>.gt(value: T): Bson = Filters.gt(path(), value)
86+
infix fun <@OnlyInputTypes T> KProperty<T?>.gt(value: T): Bson = Filters.gt(path(), value)
8687

8788
/**
8889
* Creates a filter that matches all documents where the value of the given property is less than or equal to the specified value.
@@ -92,7 +93,7 @@ infix fun <T> KProperty<T>.gt(value: T): Bson = Filters.gt(path(), value)
9293
* @return the filter
9394
* @mongodb.driver.manual reference/operator/query/lte $lte
9495
*/
95-
infix fun <T> KProperty<T>.lte(value: T): Bson = Filters.lte(path(), value)
96+
infix fun <@OnlyInputTypes T> KProperty<T?>.lte(value: T): Bson = Filters.lte(path(), value)
9697

9798
/**
9899
* Creates a filter that matches all documents where the value of the given property is greater than or equal to the specified value.
@@ -102,7 +103,7 @@ infix fun <T> KProperty<T>.lte(value: T): Bson = Filters.lte(path(), value)
102103
* @return the filter
103104
* @mongodb.driver.manual reference/operator/query/gte $gte
104105
*/
105-
infix fun <T> KProperty<T>.gte(value: T): Bson = Filters.gte(path(), value)
106+
infix fun <@OnlyInputTypes T> KProperty<T?>.gte(value: T): Bson = Filters.gte(path(), value)
106107

107108
/**
108109
* Creates a filter that matches all documents where the value of a property equals any value in the list of specified values.
@@ -112,7 +113,7 @@ infix fun <T> KProperty<T>.gte(value: T): Bson = Filters.gte(path(), value)
112113
* @return the filter
113114
* @mongodb.driver.manual reference/operator/query/in $in
114115
*/
115-
infix fun <T> KProperty<T>.`in`(values: Iterable<T>): Bson = Filters.`in`(path(), values)
116+
infix fun <@OnlyInputTypes T> KProperty<T?>.`in`(values: Iterable<T>): Bson = Filters.`in`(path(), values)
116117

117118
/**
118119
* Creates a filter that matches all documents where the value of a property equals any value in the list of specified values.
@@ -122,7 +123,8 @@ infix fun <T> KProperty<T>.`in`(values: Iterable<T>): Bson = Filters.`in`(path()
122123
* @return the filter
123124
* @mongodb.driver.manual reference/operator/query/in $in
124125
*/
125-
infix fun <T> KProperty<T>.contains(values: Iterable<T>): Bson = `in`(values)
126+
@JvmName("inArray")
127+
infix fun <@OnlyInputTypes T> KProperty<Iterable<T>?>.`in`(values: Iterable<T>): Bson = Filters.`in`(path(), values)
126128

127129
/**
128130
* Creates a filter that matches all documents where the value of a property does not equal any of the specified values or does not exist.
@@ -132,7 +134,19 @@ infix fun <T> KProperty<T>.contains(values: Iterable<T>): Bson = `in`(values)
132134
* @return the filter
133135
* @mongodb.driver.manual reference/operator/query/nin $nin
134136
*/
135-
infix fun <T> KProperty<T>.nin(values: Iterable<T>): Bson = Filters.nin(path(), values)
137+
infix fun <@OnlyInputTypes T> KProperty<T?>.nin(values: Iterable<T>): Bson = Filters.nin(path(), values)
138+
139+
/**
140+
* Creates a filter that matches all documents where the value of a property does not equal any of the specified values or does not exist.
141+
*
142+
* @param values the list of values
143+
* @param <T> the value type
144+
* @return the filter
145+
* @mongodb.driver.manual reference/operator/query/nin $nin
146+
*/
147+
@JvmName("ninArray")
148+
infix fun <@OnlyInputTypes T> KProperty<Iterable<T>?>.nin(values: Iterable<T>): Bson = Filters.nin(path(), values)
149+
136150

137151
/**
138152
* Creates a filter that performs a logical AND of the provided list of filters. Note that this will only generate a "$and"
@@ -355,7 +369,7 @@ fun <TExpression> expr(expression: TExpression): Bson = Filters.expr(expression)
355369
* @return the filter
356370
* @mongodb.driver.manual reference/operator/query/all $all
357371
*/
358-
infix fun <T> KProperty<T>.all(values: Iterable<T>): Bson = Filters.all(path(), values)
372+
infix fun <@OnlyInputTypes T> KProperty<Iterable<T>?>.all(values: Iterable<T>): Bson = Filters.all(path(), values)
359373

360374
/**
361375
* Creates a filter that matches all documents where the value of a property is an array that contains all the specified values.
@@ -365,7 +379,7 @@ infix fun <T> KProperty<T>.all(values: Iterable<T>): Bson = Filters.all(path(),
365379
* @return the filter
366380
* @mongodb.driver.manual reference/operator/query/all $all
367381
*/
368-
fun <T> KProperty<T>.all(vararg values: T): Bson = Filters.all(path(), *values)
382+
fun <@OnlyInputTypes T> KProperty<Iterable<T>?>.all(vararg values: T): Bson = Filters.all(path(), *values)
369383

370384
/**
371385
* Creates a filter that matches all documents containing a property that is an array where at least one member of the array matches the
@@ -375,7 +389,7 @@ fun <T> KProperty<T>.all(vararg values: T): Bson = Filters.all(path(), *values)
375389
* @return the filter
376390
* @mongodb.driver.manual reference/operator/query/elemMatch $elemMatch
377391
*/
378-
infix fun <T> KProperty<Collection<T>>.elemMatch(filter: Bson): Bson = Filters.elemMatch(path(), filter)
392+
infix fun <T> KProperty<Iterable<T>>.elemMatch(filter: Bson): Bson = Filters.elemMatch(path(), filter)
379393

380394
/**
381395
* Creates a filter that matches all documents where the value of a property is an array of the specified size.

kmongo-property/src/main/kotlin/org/litote/kmongo/Properties.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ operator fun <T0, T1, T2> KProperty1<T0, T1?>.div(p2: KProperty1<T1, T2?>): KPro
3333
* Returns a collection composed property. For example Friend.addresses / Address.postalCode = "addresses.postalCode".
3434
*/
3535
@JvmName("divCol")
36-
operator fun <T0, T1, T2> KProperty1<T0, Collection<T1>?>.div(p2: KProperty1<T1, T2?>): KProperty1<T0, T2?> =
36+
operator fun <T0, T1, T2> KProperty1<T0, Iterable<T1>?>.div(p2: KProperty1<T1, T2?>): KProperty1<T0, T2?> =
3737
KPropertyPath(this, p2)
3838

3939
/**
@@ -52,7 +52,7 @@ fun <T> KProperty<T>.path(): String =
5252
/**
5353
* Returns a collection property.
5454
*/
55-
val <T> KProperty1<out Any?, Collection<T>>.colProperty: KCollectionSimplePropertyPath<out Any?, T>
55+
val <T> KProperty1<out Any?, Iterable<T>>.colProperty: KCollectionSimplePropertyPath<out Any?, T>
5656
get() = KCollectionSimplePropertyPath(null, this)
5757

5858

0 commit comments

Comments
 (0)