Skip to content

Commit 22a686c

Browse files
committed
Adding extension methods for Sorts
1 parent adc970e commit 22a686c

File tree

4 files changed

+159
-0
lines changed

4 files changed

+159
-0
lines changed

config/spotbugs/exclude.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,12 @@
241241
<Method name="~ascending|descending|geo2dsphere"/>
242242
<Bug pattern="BC_BAD_CAST_TO_ABSTRACT_COLLECTION"/>
243243
</Match>
244+
<Match>
245+
<!-- MongoDB status: "False Positive", SpotBugs rank: 17 -->
246+
<Class name="com.mongodb.kotlin.client.model.Sorts"/>
247+
<Method name="~ascending|descending"/>
248+
<Bug pattern="BC_BAD_CAST_TO_ABSTRACT_COLLECTION"/>
249+
</Match>
244250

245251
<!-- Spotbugs reports false positives for suspendable operations with default params
246252
see: https://github.com/Kotlin/kotlinx.coroutines/issues/3099
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
* Copyright (C) 2016/2022 Litote
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
* @custom-license-header
18+
*/
19+
package com.mongodb.kotlin.client.model
20+
21+
import com.mongodb.client.model.Sorts
22+
import kotlin.reflect.KProperty
23+
import org.bson.conversions.Bson
24+
25+
/**
26+
* Sorts extension methods to improve Kotlin interop
27+
*
28+
* @since 5.3
29+
*/
30+
public object Sorts {
31+
32+
/**
33+
* Create a sort specification for an ascending sort on the given properties.
34+
*
35+
* @param properties the properties, which must contain at least one
36+
* @return the sort specification @mongodb.driver.manual reference/operator/meta/orderby Sort
37+
*/
38+
public fun ascending(vararg properties: KProperty<*>): Bson = ascending(properties.asList())
39+
40+
/**
41+
* Create a sort specification for an ascending sort on the given properties.
42+
*
43+
* @param properties the properties, which must contain at least one
44+
* @return the sort specification @mongodb.driver.manual reference/operator/meta/orderby Sort
45+
*/
46+
public fun ascending(properties: List<KProperty<*>>): Bson = Sorts.ascending(properties.map { it.path() })
47+
48+
/**
49+
* Create a sort specification for a descending sort on the given properties.
50+
*
51+
* @param properties the properties, which must contain at least one
52+
* @return the sort specification @mongodb.driver.manual reference/operator/meta/orderby Sort
53+
*/
54+
public fun descending(vararg properties: KProperty<*>): Bson = descending(properties.asList())
55+
56+
/**
57+
* Create a sort specification for a descending sort on the given properties.
58+
*
59+
* @param properties the properties, which must contain at least one
60+
* @return the sort specification @mongodb.driver.manual reference/operator/meta/orderby Sort
61+
*/
62+
public fun descending(properties: List<KProperty<*>>): Bson = Sorts.descending(properties.map { it.path() })
63+
64+
/**
65+
* Create a sort specification for the text score meta projection on the given property.
66+
*
67+
* @param property the data class property
68+
* @return the sort specification @mongodb.driver.manual reference/operator/getProjection/meta/#sort textScore
69+
*/
70+
public fun <T> metaTextScore(property: KProperty<T>): Bson = Sorts.metaTextScore(property.path())
71+
}

driver-kotlin-extensions/src/test/kotlin/com/mongodb/kotlin/client/model/ExtensionsApiTest.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ class ExtensionsApiTest {
5656
assertTrue(notImplemented.isEmpty(), "Some possible Indexes were not implemented: $notImplemented")
5757
}
5858

59+
@Test
60+
fun shouldHaveAllSortsExtensions() {
61+
val kotlinExtensions: Set<String> = getKotlinExtensions("Sorts")
62+
val javaMethods: Set<String> = getJavaMethods("Sorts")
63+
64+
val notImplemented = javaMethods subtract kotlinExtensions
65+
assertTrue(notImplemented.isEmpty(), "Some possible Sorts were not implemented: $notImplemented")
66+
}
67+
5968
private fun getKotlinExtensions(className: String): Set<String> {
6069
return ClassGraph()
6170
.enableClassInfo()
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
* Copyright (C) 2016/2022 Litote
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
* @custom-license-header
18+
*/
19+
package com.mongodb.kotlin.client.model
20+
21+
import com.mongodb.client.model.Sorts.orderBy
22+
import com.mongodb.kotlin.client.model.Sorts.ascending
23+
import com.mongodb.kotlin.client.model.Sorts.descending
24+
import com.mongodb.kotlin.client.model.Sorts.metaTextScore
25+
import kotlin.test.assertEquals
26+
import org.bson.BsonDocument
27+
import org.bson.conversions.Bson
28+
import org.junit.Test
29+
30+
class SortsTest {
31+
32+
@Test
33+
fun ascending() {
34+
assertEquals(""" {name : 1} """, ascending(Person::name))
35+
assertEquals(""" {name : 1, age: 1} """, ascending(Person::name, Person::age))
36+
assertEquals(""" {name : 1, age: 1} """, ascending(listOf(Person::name, Person::age)))
37+
}
38+
39+
@Test
40+
fun descending() {
41+
assertEquals(""" {name : -1} """, descending(Person::name))
42+
assertEquals(""" {name : -1, age: -1} """, descending(Person::name, Person::age))
43+
assertEquals(""" {name : -1, age: -1} """, descending(listOf(Person::name, Person::age)))
44+
}
45+
46+
@Test
47+
fun metaTextScore() {
48+
assertEquals(""" {name : {${'$'}meta : "textScore"}} """, metaTextScore(Person::name))
49+
}
50+
51+
@Test
52+
fun orderBy() {
53+
assertEquals(""" {name : 1, age : -1} """, orderBy(ascending(Person::name), descending(Person::age)))
54+
assertEquals(""" {name : 1, age : -1} """, orderBy(listOf(ascending(Person::name), descending(Person::age))))
55+
assertEquals(
56+
""" {name : -1, age : -1} """,
57+
orderBy(ascending(Person::name), descending(Person::age), descending(Person::name)))
58+
assertEquals(
59+
""" {name : 1, age : 1, results: -1, address: -1} """,
60+
orderBy(ascending(Person::name, Person::age), descending(Person::results, Person::address)))
61+
}
62+
63+
@Test
64+
fun `should create string representation for compound sorts`() {
65+
assertEquals(
66+
"""Compound Sort{sorts=[{"name": 1, "age": 1}, {"results": -1, "address": -1}]}""",
67+
orderBy(ascending(Person::name, Person::age), descending(Person::results, Person::address)).toString())
68+
}
69+
70+
private data class Person(val name: String, val age: Int, val address: List<String>, val results: List<Int>)
71+
private fun assertEquals(expected: String, result: Bson) =
72+
assertEquals(BsonDocument.parse(expected), result.toBsonDocument())
73+
}

0 commit comments

Comments
 (0)