diff --git a/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt b/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt index c0435de5..ae067ee6 100644 --- a/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt +++ b/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt @@ -22,6 +22,7 @@ import opensavvy.ktmongo.dsl.expr.FilterOperators import opensavvy.ktmongo.dsl.expr.UpdateOperators import opensavvy.ktmongo.dsl.expr.UpsertOperators import opensavvy.ktmongo.dsl.models.Count +import opensavvy.ktmongo.dsl.models.Find private class FilteredCollection( private val upstream: MongoCollection, @@ -31,7 +32,7 @@ private class FilteredCollection( override fun find(): MongoIterable = upstream.find(globalFilter) - override fun find(predicate: FilterOperators.() -> Unit): MongoIterable = + override fun find(predicate: Find.() -> Unit): MongoIterable = upstream.find { globalFilter() predicate() diff --git a/driver-coroutines/src/commonMain/kotlin/operations/FindOperations.kt b/driver-coroutines/src/commonMain/kotlin/operations/FindOperations.kt index c8480147..58ab05f6 100644 --- a/driver-coroutines/src/commonMain/kotlin/operations/FindOperations.kt +++ b/driver-coroutines/src/commonMain/kotlin/operations/FindOperations.kt @@ -18,7 +18,7 @@ package opensavvy.ktmongo.coroutines.operations import opensavvy.ktmongo.coroutines.MongoIterable import opensavvy.ktmongo.dsl.expr.FilterExpression -import opensavvy.ktmongo.dsl.expr.FilterOperators +import opensavvy.ktmongo.dsl.models.Find /** * Interface grouping MongoDB operations allowing to search for information. @@ -59,7 +59,7 @@ interface FindOperations : BaseOperations { * * @see findOne When only one result is expected. */ - fun find(predicate: FilterOperators.() -> Unit): MongoIterable + fun find(predicate: Find.() -> Unit): MongoIterable /** * Finds a document in this collection that satisfies [predicate]. @@ -85,7 +85,7 @@ interface FindOperations : BaseOperations { * * @see find When multiple results are expected. */ - suspend fun findOne(predicate: FilterOperators.() -> Unit): Document? = + suspend fun findOne(predicate: Find.() -> Unit): Document? = find(predicate).firstOrNull() } diff --git a/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt b/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt index 241410c5..02708fbb 100644 --- a/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt +++ b/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt @@ -23,7 +23,11 @@ import opensavvy.ktmongo.dsl.LowLevelApi import opensavvy.ktmongo.dsl.expr.* import opensavvy.ktmongo.dsl.expr.common.Expression import opensavvy.ktmongo.dsl.models.Count +import opensavvy.ktmongo.dsl.models.Find import opensavvy.ktmongo.dsl.options.CountOptions +import opensavvy.ktmongo.dsl.options.FindOptions +import opensavvy.ktmongo.dsl.options.common.LimitOption +import opensavvy.ktmongo.dsl.options.common.option import opensavvy.ktmongo.dsl.options.toJava import org.bson.BsonDocument @@ -51,12 +55,15 @@ class JvmMongoCollection internal constructor( JvmMongoIterable(inner.find()) @OptIn(LowLevelApi::class) - override fun find(predicate: FilterOperators.() -> Unit): JvmMongoIterable { - val filter = FilterExpression(context) + override fun find(predicate: Find.() -> Unit): JvmMongoIterable { + val options = FindOptions(context) + val model = Find(context, options) .apply(predicate) - .toBsonDocument() - return JvmMongoIterable(inner.find(filter)) + return JvmMongoIterable( + inner.find(model.toBsonDocument()) + .limit(options.option()?.toInt() ?: 0) + ) } // endregion diff --git a/driver-sync/src/commonMain/kotlin/FilteredCollection.kt b/driver-sync/src/commonMain/kotlin/FilteredCollection.kt index 77d23778..2115bd3b 100644 --- a/driver-sync/src/commonMain/kotlin/FilteredCollection.kt +++ b/driver-sync/src/commonMain/kotlin/FilteredCollection.kt @@ -22,6 +22,7 @@ import opensavvy.ktmongo.dsl.expr.FilterOperators import opensavvy.ktmongo.dsl.expr.UpdateOperators import opensavvy.ktmongo.dsl.expr.UpsertOperators import opensavvy.ktmongo.dsl.models.Count +import opensavvy.ktmongo.dsl.models.Find private class FilteredCollection( private val upstream: MongoCollection, @@ -31,7 +32,7 @@ private class FilteredCollection( override fun find(): MongoIterable = upstream.find(globalFilter) - override fun find(predicate: FilterOperators.() -> Unit): MongoIterable = + override fun find(predicate: Find.() -> Unit): MongoIterable = upstream.find { globalFilter() predicate() diff --git a/driver-sync/src/commonMain/kotlin/operations/FindOperations.kt b/driver-sync/src/commonMain/kotlin/operations/FindOperations.kt index e5aa7e25..987736cd 100644 --- a/driver-sync/src/commonMain/kotlin/operations/FindOperations.kt +++ b/driver-sync/src/commonMain/kotlin/operations/FindOperations.kt @@ -17,7 +17,7 @@ package opensavvy.ktmongo.sync.operations import opensavvy.ktmongo.dsl.expr.FilterExpression -import opensavvy.ktmongo.dsl.expr.FilterOperators +import opensavvy.ktmongo.dsl.models.Find import opensavvy.ktmongo.sync.MongoIterable /** @@ -59,7 +59,7 @@ interface FindOperations : BaseOperations { * * @see findOne When only one result is expected. */ - fun find(predicate: FilterOperators.() -> Unit): MongoIterable + fun find(predicate: Find.() -> Unit): MongoIterable /** * Finds a document in this collection that satisfies [predicate]. @@ -85,7 +85,7 @@ interface FindOperations : BaseOperations { * * @see find When multiple results are expected. */ - fun findOne(predicate: FilterOperators.() -> Unit): Document? = + fun findOne(predicate: Find.() -> Unit): Document? = find(predicate).firstOrNull() } diff --git a/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt b/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt index 300dcc91..83b3cc22 100644 --- a/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt +++ b/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt @@ -23,7 +23,11 @@ import opensavvy.ktmongo.dsl.LowLevelApi import opensavvy.ktmongo.dsl.expr.* import opensavvy.ktmongo.dsl.expr.common.Expression import opensavvy.ktmongo.dsl.models.Count +import opensavvy.ktmongo.dsl.models.Find import opensavvy.ktmongo.dsl.options.CountOptions +import opensavvy.ktmongo.dsl.options.FindOptions +import opensavvy.ktmongo.dsl.options.common.LimitOption +import opensavvy.ktmongo.dsl.options.common.option import opensavvy.ktmongo.dsl.options.toJava import org.bson.BsonDocument @@ -51,12 +55,15 @@ class JvmMongoCollection internal constructor( JvmMongoIterable(inner.find()) @OptIn(LowLevelApi::class) - override fun find(predicate: FilterOperators.() -> Unit): JvmMongoIterable { - val filter = FilterExpression(context) + override fun find(predicate: Find.() -> Unit): JvmMongoIterable { + val options = FindOptions(context) + val model = Find(context, options) .apply(predicate) - .toBsonDocument() - return JvmMongoIterable(inner.find(filter)) + return JvmMongoIterable( + inner.find(model.toBsonDocument()) + .limit(options.option()?.toInt() ?: 0) + ) } // endregion diff --git a/dsl/src/commonMain/kotlin/models/Find.kt b/dsl/src/commonMain/kotlin/models/Find.kt new file mode 100644 index 00000000..c3a1017c --- /dev/null +++ b/dsl/src/commonMain/kotlin/models/Find.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024, OpenSavvy and contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package opensavvy.ktmongo.dsl.models + +import opensavvy.ktmongo.bson.BsonContext +import opensavvy.ktmongo.dsl.KtMongoDsl +import opensavvy.ktmongo.dsl.expr.FilterExpression +import opensavvy.ktmongo.dsl.expr.FilterOperators +import opensavvy.ktmongo.dsl.options.FindOptions + +/** + * Searching for documents in a collection. + * + * ### Example + * + * ```kotlin + * users.find { + * options { + * limit(12) + * } + * + * User::age lt 18 + * } + * ``` + * + * @see FilterOperators Filter operators + * @see FindOptions Options + */ +@KtMongoDsl +class Find( + context: BsonContext, + val options: FindOptions, +) : FilterOperators by FilterExpression(context) { + + @KtMongoDsl + fun options(block: FindOptions.() -> Unit) { + options.block() + } +} diff --git a/dsl/src/commonMain/kotlin/options/FindOptions.kt b/dsl/src/commonMain/kotlin/options/FindOptions.kt new file mode 100644 index 00000000..d4a02a3d --- /dev/null +++ b/dsl/src/commonMain/kotlin/options/FindOptions.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024, OpenSavvy and contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package opensavvy.ktmongo.dsl.options + +import opensavvy.ktmongo.bson.BsonContext +import opensavvy.ktmongo.dsl.LowLevelApi +import opensavvy.ktmongo.dsl.options.common.Options +import opensavvy.ktmongo.dsl.options.common.OptionsHolder +import opensavvy.ktmongo.dsl.options.common.WithLimit + +/** + * The options for a `collection.find` operation. + */ +@OptIn(LowLevelApi::class) +class FindOptions(context: BsonContext) : + Options by OptionsHolder(context), + WithLimit diff --git a/dsl/src/jvmMain/kotlin/options/CountOptions.jvm.kt b/dsl/src/jvmMain/kotlin/options/Options.jvm.kt similarity index 100% rename from dsl/src/jvmMain/kotlin/options/CountOptions.jvm.kt rename to dsl/src/jvmMain/kotlin/options/Options.jvm.kt -- 2.51.2 From 373ef462cc33cdc445d8726604db30a3fe8219ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=E2=80=9CCLOVIS=E2=80=9D=20Canet?= Date: Sun, 10 Nov 2024 18:38:43 +0100 Subject: [PATCH 2/5] feat: Remove explicit model usage and nested clauses syntax for Count --- .../commonMain/kotlin/FilteredCollection.kt | 20 ++++++++++++------- .../kotlin/operations/CountOperations.kt | 8 +++++--- .../src/jvmMain/kotlin/JvmMongoCollection.kt | 18 ++++++++++------- .../commonMain/kotlin/FilteredCollection.kt | 20 ++++++++++++------- .../kotlin/operations/CountOperations.kt | 8 +++++--- .../src/jvmMain/kotlin/JvmMongoCollection.kt | 18 ++++++++++------- dsl/src/commonMain/kotlin/models/Count.kt | 19 +++++++----------- 7 files changed, 65 insertions(+), 46 deletions(-) diff --git a/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt b/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt index ae067ee6..702cc803 100644 --- a/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt +++ b/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt @@ -21,8 +21,8 @@ import opensavvy.ktmongo.dsl.LowLevelApi import opensavvy.ktmongo.dsl.expr.FilterOperators import opensavvy.ktmongo.dsl.expr.UpdateOperators import opensavvy.ktmongo.dsl.expr.UpsertOperators -import opensavvy.ktmongo.dsl.models.Count import opensavvy.ktmongo.dsl.models.Find +import opensavvy.ktmongo.dsl.options.CountOptions private class FilteredCollection( private val upstream: MongoCollection, @@ -43,13 +43,19 @@ private class FilteredCollection( get() = upstream.context override suspend fun count(): Long = - upstream.count(globalFilter) + upstream.count(predicate = globalFilter) - override suspend fun count(predicate: Count.() -> Unit): Long = - upstream.count { - globalFilter() - predicate() - } + override suspend fun count( + options: CountOptions.() -> Unit, + predicate: FilterOperators.() -> Unit, + ): Long = + upstream.count( + options = options, + predicate = { + globalFilter() + predicate() + } + ) override suspend fun countEstimated(): Long = count() diff --git a/driver-coroutines/src/commonMain/kotlin/operations/CountOperations.kt b/driver-coroutines/src/commonMain/kotlin/operations/CountOperations.kt index 72169743..1a68e369 100644 --- a/driver-coroutines/src/commonMain/kotlin/operations/CountOperations.kt +++ b/driver-coroutines/src/commonMain/kotlin/operations/CountOperations.kt @@ -16,7 +16,8 @@ package opensavvy.ktmongo.coroutines.operations -import opensavvy.ktmongo.dsl.models.Count +import opensavvy.ktmongo.dsl.expr.FilterOperators +import opensavvy.ktmongo.dsl.options.CountOptions /** * Interface grouping MongoDB operations relating to counting documents. @@ -45,7 +46,7 @@ interface CountOperations : BaseOperations { * val age: Int, * ) * - * collection.countDocuments { + * collection.count { * User::name eq "foo" * User::age eq 10 * } @@ -56,7 +57,8 @@ interface CountOperations : BaseOperations { * - [Official documentation](https://www.mongodb.com/docs/manual/reference/method/db.collection.countDocuments/) */ suspend fun count( - predicate: Count.() -> Unit + options: CountOptions.() -> Unit = {}, + predicate: FilterOperators.() -> Unit ): Long /** diff --git a/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt b/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt index 02708fbb..d087adbf 100644 --- a/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt +++ b/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt @@ -39,7 +39,7 @@ import org.bson.BsonDocument * To convert an existing MongoDB iterable into an instance of this class, see [asKtMongo]. */ class JvmMongoCollection internal constructor( - private val inner: com.mongodb.kotlin.client.coroutine.MongoCollection + private val inner: com.mongodb.kotlin.client.coroutine.MongoCollection, ) : MongoCollection { @LowLevelApi @@ -73,14 +73,18 @@ class JvmMongoCollection internal constructor( inner.countDocuments() @OptIn(LowLevelApi::class) - override suspend fun count(predicate: Count.() -> Unit): Long { - val options = CountOptions(context) - val model = Count(context, options) - .apply(predicate) + override suspend fun count( + options: CountOptions.() -> Unit, + predicate: FilterOperators.() -> Unit, + ): Long { + val model = Count(context) + + model.options.options() + model.filter.predicate() return inner.countDocuments( - model.toBsonDocument(), - options.toJava(), + model.filter.toBsonDocument(), + model.options.toJava() ) } diff --git a/driver-sync/src/commonMain/kotlin/FilteredCollection.kt b/driver-sync/src/commonMain/kotlin/FilteredCollection.kt index 2115bd3b..0981da0a 100644 --- a/driver-sync/src/commonMain/kotlin/FilteredCollection.kt +++ b/driver-sync/src/commonMain/kotlin/FilteredCollection.kt @@ -21,8 +21,8 @@ import opensavvy.ktmongo.dsl.LowLevelApi import opensavvy.ktmongo.dsl.expr.FilterOperators import opensavvy.ktmongo.dsl.expr.UpdateOperators import opensavvy.ktmongo.dsl.expr.UpsertOperators -import opensavvy.ktmongo.dsl.models.Count import opensavvy.ktmongo.dsl.models.Find +import opensavvy.ktmongo.dsl.options.CountOptions private class FilteredCollection( private val upstream: MongoCollection, @@ -43,13 +43,19 @@ private class FilteredCollection( get() = upstream.context override fun count(): Long = - upstream.count(globalFilter) + upstream.count(predicate = globalFilter) - override fun count(predicate: Count.() -> Unit): Long = - upstream.count { - globalFilter() - predicate() - } + override fun count( + options: CountOptions.() -> Unit, + predicate: FilterOperators.() -> Unit, + ): Long = + upstream.count( + options = options, + predicate = { + globalFilter() + predicate() + } + ) override fun countEstimated(): Long = count() diff --git a/driver-sync/src/commonMain/kotlin/operations/CountOperations.kt b/driver-sync/src/commonMain/kotlin/operations/CountOperations.kt index 4ce55937..56897cb5 100644 --- a/driver-sync/src/commonMain/kotlin/operations/CountOperations.kt +++ b/driver-sync/src/commonMain/kotlin/operations/CountOperations.kt @@ -16,7 +16,8 @@ package opensavvy.ktmongo.sync.operations -import opensavvy.ktmongo.dsl.models.Count +import opensavvy.ktmongo.dsl.expr.FilterOperators +import opensavvy.ktmongo.dsl.options.CountOptions /** * Interface grouping MongoDB operations relating to counting documents. @@ -45,7 +46,7 @@ interface CountOperations : BaseOperations { * val age: Int, * ) * - * collection.countDocuments { + * collection.count { * User::name eq "foo" * User::age eq 10 * } @@ -56,7 +57,8 @@ interface CountOperations : BaseOperations { * - [Official documentation](https://www.mongodb.com/docs/manual/reference/method/db.collection.countDocuments/) */ fun count( - predicate: Count.() -> Unit + options: CountOptions.() -> Unit = {}, + predicate: FilterOperators.() -> Unit ): Long /** diff --git a/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt b/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt index 83b3cc22..e9caff81 100644 --- a/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt +++ b/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt @@ -39,7 +39,7 @@ import org.bson.BsonDocument * To convert an existing MongoDB iterable into an instance of this class, see [asKtMongo]. */ class JvmMongoCollection internal constructor( - private val inner: com.mongodb.kotlin.client.MongoCollection + private val inner: com.mongodb.kotlin.client.MongoCollection, ) : MongoCollection { @LowLevelApi @@ -73,14 +73,18 @@ class JvmMongoCollection internal constructor( inner.countDocuments() @OptIn(LowLevelApi::class) - override fun count(predicate: Count.() -> Unit): Long { - val options = CountOptions(context) - val model = Count(context, options) - .apply(predicate) + override fun count( + options: CountOptions.() -> Unit, + predicate: FilterOperators.() -> Unit, + ): Long { + val model = Count(context) + + model.options.options() + model.filter.predicate() return inner.countDocuments( - model.toBsonDocument(), - options.toJava(), + model.filter.toBsonDocument(), + model.options.toJava() ) } diff --git a/dsl/src/commonMain/kotlin/models/Count.kt b/dsl/src/commonMain/kotlin/models/Count.kt index 1cb633b1..662085c7 100644 --- a/dsl/src/commonMain/kotlin/models/Count.kt +++ b/dsl/src/commonMain/kotlin/models/Count.kt @@ -28,11 +28,7 @@ import opensavvy.ktmongo.dsl.options.CountOptions * ### Example * * ```kotlin - * users.count { - * options { - * limit(99) - * } - * + * users.count({ limit(99) }) { * User::age lt 18 * } * ``` @@ -41,13 +37,12 @@ import opensavvy.ktmongo.dsl.options.CountOptions * @see CountOptions Options */ @KtMongoDsl -class Count( - context: BsonContext, +class Count private constructor( + val context: BsonContext, val options: CountOptions, -) : FilterOperators by FilterExpression(context) { + val filter: FilterOperators, +) { + + constructor(context: BsonContext) : this(context, CountOptions(context), FilterExpression(context)) - @KtMongoDsl - fun options(block: CountOptions.() -> Unit) { - options.block() - } } -- 2.51.2 From bd43c25ed4ecfac0930d489940b3a9ae88a12b1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=E2=80=9CCLOVIS=E2=80=9D=20Canet?= Date: Sun, 10 Nov 2024 19:28:52 +0100 Subject: [PATCH 3/5] feat: Remove explicit model usage and nested clauses syntax for Find --- .../commonMain/kotlin/FilteredCollection.kt | 11 +++++++---- .../kotlin/operations/FindOperations.kt | 15 +++++++++++---- .../src/jvmMain/kotlin/JvmMongoCollection.kt | 16 ++++++++++------ .../commonMain/kotlin/FilteredCollection.kt | 11 +++++++---- .../kotlin/operations/FindOperations.kt | 15 +++++++++++---- .../src/jvmMain/kotlin/JvmMongoCollection.kt | 16 ++++++++++------ dsl/src/commonMain/kotlin/models/Find.kt | 18 ++++++------------ 7 files changed, 62 insertions(+), 40 deletions(-) diff --git a/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt b/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt index 702cc803..17592ef3 100644 --- a/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt +++ b/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt @@ -21,8 +21,8 @@ import opensavvy.ktmongo.dsl.LowLevelApi import opensavvy.ktmongo.dsl.expr.FilterOperators import opensavvy.ktmongo.dsl.expr.UpdateOperators import opensavvy.ktmongo.dsl.expr.UpsertOperators -import opensavvy.ktmongo.dsl.models.Find import opensavvy.ktmongo.dsl.options.CountOptions +import opensavvy.ktmongo.dsl.options.FindOptions private class FilteredCollection( private val upstream: MongoCollection, @@ -30,10 +30,13 @@ private class FilteredCollection( ) : MongoCollection { override fun find(): MongoIterable = - upstream.find(globalFilter) + upstream.find(predicate = globalFilter) - override fun find(predicate: Find.() -> Unit): MongoIterable = - upstream.find { + override fun find( + options: FindOptions.() -> Unit, + predicate: FilterOperators.() -> Unit, + ): MongoIterable = + upstream.find(options) { globalFilter() predicate() } diff --git a/driver-coroutines/src/commonMain/kotlin/operations/FindOperations.kt b/driver-coroutines/src/commonMain/kotlin/operations/FindOperations.kt index 58ab05f6..345e9bb7 100644 --- a/driver-coroutines/src/commonMain/kotlin/operations/FindOperations.kt +++ b/driver-coroutines/src/commonMain/kotlin/operations/FindOperations.kt @@ -18,7 +18,8 @@ package opensavvy.ktmongo.coroutines.operations import opensavvy.ktmongo.coroutines.MongoIterable import opensavvy.ktmongo.dsl.expr.FilterExpression -import opensavvy.ktmongo.dsl.models.Find +import opensavvy.ktmongo.dsl.expr.FilterOperators +import opensavvy.ktmongo.dsl.options.FindOptions /** * Interface grouping MongoDB operations allowing to search for information. @@ -59,7 +60,10 @@ interface FindOperations : BaseOperations { * * @see findOne When only one result is expected. */ - fun find(predicate: Find.() -> Unit): MongoIterable + fun find( + options: FindOptions.() -> Unit = {}, + predicate: FilterOperators.() -> Unit, + ): MongoIterable /** * Finds a document in this collection that satisfies [predicate]. @@ -85,7 +89,10 @@ interface FindOperations : BaseOperations { * * @see find When multiple results are expected. */ - suspend fun findOne(predicate: Find.() -> Unit): Document? = - find(predicate).firstOrNull() + suspend fun findOne( + options: FindOptions.() -> Unit = {}, + predicate: FilterOperators.() -> Unit, + ): Document? = + find(options, predicate).firstOrNull() } diff --git a/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt b/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt index d087adbf..be8182b0 100644 --- a/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt +++ b/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt @@ -55,14 +55,18 @@ class JvmMongoCollection internal constructor( JvmMongoIterable(inner.find()) @OptIn(LowLevelApi::class) - override fun find(predicate: Find.() -> Unit): JvmMongoIterable { - val options = FindOptions(context) - val model = Find(context, options) - .apply(predicate) + override fun find( + options: FindOptions.() -> Unit, + predicate: FilterOperators.() -> Unit, + ): MongoIterable { + val model = Find(context) + + model.options.options() + model.filter.predicate() return JvmMongoIterable( - inner.find(model.toBsonDocument()) - .limit(options.option()?.toInt() ?: 0) + inner.find(model.filter.toBsonDocument()) + .limit(model.options.option()?.toInt() ?: 0) ) } diff --git a/driver-sync/src/commonMain/kotlin/FilteredCollection.kt b/driver-sync/src/commonMain/kotlin/FilteredCollection.kt index 0981da0a..55430ca3 100644 --- a/driver-sync/src/commonMain/kotlin/FilteredCollection.kt +++ b/driver-sync/src/commonMain/kotlin/FilteredCollection.kt @@ -21,8 +21,8 @@ import opensavvy.ktmongo.dsl.LowLevelApi import opensavvy.ktmongo.dsl.expr.FilterOperators import opensavvy.ktmongo.dsl.expr.UpdateOperators import opensavvy.ktmongo.dsl.expr.UpsertOperators -import opensavvy.ktmongo.dsl.models.Find import opensavvy.ktmongo.dsl.options.CountOptions +import opensavvy.ktmongo.dsl.options.FindOptions private class FilteredCollection( private val upstream: MongoCollection, @@ -30,10 +30,13 @@ private class FilteredCollection( ) : MongoCollection { override fun find(): MongoIterable = - upstream.find(globalFilter) + upstream.find(predicate = globalFilter) - override fun find(predicate: Find.() -> Unit): MongoIterable = - upstream.find { + override fun find( + options: FindOptions.() -> Unit, + predicate: FilterOperators.() -> Unit, + ): MongoIterable = + upstream.find(options) { globalFilter() predicate() } diff --git a/driver-sync/src/commonMain/kotlin/operations/FindOperations.kt b/driver-sync/src/commonMain/kotlin/operations/FindOperations.kt index 987736cd..c199d946 100644 --- a/driver-sync/src/commonMain/kotlin/operations/FindOperations.kt +++ b/driver-sync/src/commonMain/kotlin/operations/FindOperations.kt @@ -17,7 +17,8 @@ package opensavvy.ktmongo.sync.operations import opensavvy.ktmongo.dsl.expr.FilterExpression -import opensavvy.ktmongo.dsl.models.Find +import opensavvy.ktmongo.dsl.expr.FilterOperators +import opensavvy.ktmongo.dsl.options.FindOptions import opensavvy.ktmongo.sync.MongoIterable /** @@ -59,7 +60,10 @@ interface FindOperations : BaseOperations { * * @see findOne When only one result is expected. */ - fun find(predicate: Find.() -> Unit): MongoIterable + fun find( + options: FindOptions.() -> Unit = {}, + predicate: FilterOperators.() -> Unit, + ): MongoIterable /** * Finds a document in this collection that satisfies [predicate]. @@ -85,7 +89,10 @@ interface FindOperations : BaseOperations { * * @see find When multiple results are expected. */ - fun findOne(predicate: Find.() -> Unit): Document? = - find(predicate).firstOrNull() + fun findOne( + options: FindOptions.() -> Unit = {}, + predicate: FilterOperators.() -> Unit, + ): Document? = + find(options, predicate).firstOrNull() } diff --git a/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt b/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt index e9caff81..d4dd9a75 100644 --- a/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt +++ b/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt @@ -55,14 +55,18 @@ class JvmMongoCollection internal constructor( JvmMongoIterable(inner.find()) @OptIn(LowLevelApi::class) - override fun find(predicate: Find.() -> Unit): JvmMongoIterable { - val options = FindOptions(context) - val model = Find(context, options) - .apply(predicate) + override fun find( + options: FindOptions.() -> Unit, + predicate: FilterOperators.() -> Unit, + ): MongoIterable { + val model = Find(context) + + model.options.options() + model.filter.predicate() return JvmMongoIterable( - inner.find(model.toBsonDocument()) - .limit(options.option()?.toInt() ?: 0) + inner.find(model.filter.toBsonDocument()) + .limit(model.options.option()?.toInt() ?: 0) ) } diff --git a/dsl/src/commonMain/kotlin/models/Find.kt b/dsl/src/commonMain/kotlin/models/Find.kt index c3a1017c..90d26d49 100644 --- a/dsl/src/commonMain/kotlin/models/Find.kt +++ b/dsl/src/commonMain/kotlin/models/Find.kt @@ -28,11 +28,7 @@ import opensavvy.ktmongo.dsl.options.FindOptions * ### Example * * ```kotlin - * users.find { - * options { - * limit(12) - * } - * + * users.find({ limit(12) }) { * User::age lt 18 * } * ``` @@ -41,13 +37,11 @@ import opensavvy.ktmongo.dsl.options.FindOptions * @see FindOptions Options */ @KtMongoDsl -class Find( - context: BsonContext, +class Find private constructor( + val context: BsonContext, val options: FindOptions, -) : FilterOperators by FilterExpression(context) { + val filter: FilterOperators, +) { - @KtMongoDsl - fun options(block: FindOptions.() -> Unit) { - options.block() - } + constructor(context: BsonContext) : this(context, FindOptions(context), FilterExpression(context)) } -- 2.51.2 From 78451c74931c7c5cdc5eec0a50f874c169f63514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=E2=80=9CCLOVIS=E2=80=9D=20Canet?= Date: Sun, 10 Nov 2024 19:44:17 +0100 Subject: [PATCH 4/5] feat: Remove explicit model usage and nested clauses syntax for Update --- .../commonMain/kotlin/FilteredCollection.kt | 32 +++++- .../kotlin/operations/UpdateOperations.kt | 5 + .../src/jvmMain/kotlin/JvmMongoCollection.kt | 76 ++++++++------- .../commonMain/kotlin/FilteredCollection.kt | 32 +++++- .../kotlin/operations/UpdateOperations.kt | 5 + .../src/jvmMain/kotlin/JvmMongoCollection.kt | 76 ++++++++------- dsl/src/commonMain/kotlin/models/Update.kt | 97 +++++++++++++++++++ .../kotlin/options/UpdateOptions.kt | 27 ++++++ 8 files changed, 274 insertions(+), 76 deletions(-) create mode 100644 dsl/src/commonMain/kotlin/models/Update.kt create mode 100644 dsl/src/commonMain/kotlin/options/UpdateOptions.kt diff --git a/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt b/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt index 17592ef3..b9efea4e 100644 --- a/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt +++ b/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt @@ -23,6 +23,7 @@ import opensavvy.ktmongo.dsl.expr.UpdateOperators import opensavvy.ktmongo.dsl.expr.UpsertOperators import opensavvy.ktmongo.dsl.options.CountOptions import opensavvy.ktmongo.dsl.options.FindOptions +import opensavvy.ktmongo.dsl.options.UpdateOptions private class FilteredCollection( private val upstream: MongoCollection, @@ -63,35 +64,58 @@ private class FilteredCollection( override suspend fun countEstimated(): Long = count() - override suspend fun updateMany(filter: FilterOperators.() -> Unit, update: UpdateOperators.() -> Unit) = + override suspend fun updateMany( + options: UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpdateOperators.() -> Unit, + ) { upstream.updateMany( + options = options, filter = { globalFilter() filter() }, update = update, ) + } - override suspend fun updateOne(filter: FilterOperators.() -> Unit, update: UpdateOperators.() -> Unit) = + override suspend fun updateOne( + options: UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpdateOperators.() -> Unit, + ) { upstream.updateOne( + options = options, filter = { globalFilter() filter() }, update = update, ) + } - override suspend fun upsertOne(filter: FilterOperators.() -> Unit, update: UpsertOperators.() -> Unit) = + override suspend fun upsertOne( + options: UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpsertOperators.() -> Unit, + ) { upstream.upsertOne( + options = options, filter = { globalFilter() filter() }, update = update, ) + } - override suspend fun findOneAndUpdate(filter: FilterOperators.() -> Unit, update: UpdateOperators.() -> Unit): Document? = + override suspend fun findOneAndUpdate( + options: UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpdateOperators.() -> Unit, + ): Document? = upstream.findOneAndUpdate( + options = options, filter = { globalFilter() filter() diff --git a/driver-coroutines/src/commonMain/kotlin/operations/UpdateOperations.kt b/driver-coroutines/src/commonMain/kotlin/operations/UpdateOperations.kt index 53314172..1de90cee 100644 --- a/driver-coroutines/src/commonMain/kotlin/operations/UpdateOperations.kt +++ b/driver-coroutines/src/commonMain/kotlin/operations/UpdateOperations.kt @@ -21,6 +21,7 @@ import opensavvy.ktmongo.coroutines.filter import opensavvy.ktmongo.dsl.expr.FilterOperators import opensavvy.ktmongo.dsl.expr.UpdateOperators import opensavvy.ktmongo.dsl.expr.UpsertOperators +import opensavvy.ktmongo.dsl.options.UpdateOptions /** * Interface grouping MongoDB operations allowing to update existing information. @@ -70,6 +71,7 @@ interface UpdateOperations : BaseOperations { * @see updateOne */ suspend fun updateMany( + options: UpdateOptions.() -> Unit = {}, filter: FilterOperators.() -> Unit = {}, update: UpdateOperators.() -> Unit, ) @@ -120,6 +122,7 @@ interface UpdateOperations : BaseOperations { * @see findOneAndUpdate Also returns the result of the update. */ suspend fun updateOne( + options: UpdateOptions.() -> Unit = {}, filter: FilterOperators.() -> Unit = {}, update: UpdateOperators.() -> Unit, ) @@ -173,6 +176,7 @@ interface UpdateOperations : BaseOperations { * @see updateOne */ suspend fun upsertOne( + options: UpdateOptions.() -> Unit = {}, filter: FilterOperators.() -> Unit = {}, update: UpsertOperators.() -> Unit, ) @@ -221,6 +225,7 @@ interface UpdateOperations : BaseOperations { * @see updateOne Do not return the value. */ suspend fun findOneAndUpdate( + options: UpdateOptions.() -> Unit = {}, filter: FilterOperators.() -> Unit = {}, update: UpdateOperators.() -> Unit, ): Document? diff --git a/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt b/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt index be8182b0..57ce78e6 100644 --- a/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt +++ b/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt @@ -16,14 +16,14 @@ package opensavvy.ktmongo.coroutines +import com.mongodb.client.model.FindOneAndUpdateOptions import com.mongodb.client.model.UpdateOptions import opensavvy.ktmongo.bson.BsonContext import opensavvy.ktmongo.bson.buildBsonDocument import opensavvy.ktmongo.dsl.LowLevelApi import opensavvy.ktmongo.dsl.expr.* import opensavvy.ktmongo.dsl.expr.common.Expression -import opensavvy.ktmongo.dsl.models.Count -import opensavvy.ktmongo.dsl.models.Find +import opensavvy.ktmongo.dsl.models.* import opensavvy.ktmongo.dsl.options.CountOptions import opensavvy.ktmongo.dsl.options.FindOptions import opensavvy.ktmongo.dsl.options.common.LimitOption @@ -99,55 +99,63 @@ class JvmMongoCollection internal constructor( // region Update @OptIn(LowLevelApi::class) - override suspend fun updateMany(filter: FilterOperators.() -> Unit, update: UpdateOperators.() -> Unit) { - val filter = FilterExpression(context) - .apply(filter) - .toBsonDocument() + override suspend fun updateMany( + options: opensavvy.ktmongo.dsl.options.UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpdateOperators.() -> Unit, + ) { + val model = UpdateMany(context) - val update = UpdateExpression(context) - .apply(update) - .toBsonDocument() + model.options.options() + model.filter.filter() + model.update.update() - inner.updateMany(filter, update) + inner.updateMany(model.filter.toBsonDocument(), model.update.toBsonDocument(), UpdateOptions()) } @OptIn(LowLevelApi::class) - override suspend fun updateOne(filter: FilterOperators.() -> Unit, update: UpdateOperators.() -> Unit) { - val filter = FilterExpression(context) - .apply(filter) - .toBsonDocument() + override suspend fun updateOne( + options: opensavvy.ktmongo.dsl.options.UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpdateOperators.() -> Unit, + ) { + val model = UpdateOne(context) - val update = UpdateExpression(context) - .apply(update) - .toBsonDocument() + model.options.options() + model.filter.filter() + model.update.update() - inner.updateOne(filter, update) + inner.updateOne(model.filter.toBsonDocument(), model.update.toBsonDocument(), UpdateOptions()) } @OptIn(LowLevelApi::class) - override suspend fun upsertOne(filter: FilterOperators.() -> Unit, update: UpsertOperators.() -> Unit) { - val filter = FilterExpression(context) - .apply(filter) - .toBsonDocument() + override suspend fun upsertOne( + options: opensavvy.ktmongo.dsl.options.UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpsertOperators.() -> Unit, + ) { + val model = UpsertOne(context) - val update = UpdateExpression(context) - .apply(update) - .toBsonDocument() + model.options.options() + model.filter.filter() + model.update.update() - inner.updateOne(filter, update, UpdateOptions().upsert(true)) + inner.updateOne(model.filter.toBsonDocument(), model.update.toBsonDocument(), UpdateOptions().upsert(true)) } @OptIn(LowLevelApi::class) - override suspend fun findOneAndUpdate(filter: FilterOperators.() -> Unit, update: UpdateOperators.() -> Unit): Document? { - val filter = FilterExpression(context) - .apply(filter) - .toBsonDocument() + override suspend fun findOneAndUpdate( + options: opensavvy.ktmongo.dsl.options.UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpdateOperators.() -> Unit, + ): Document? { + val model = UpdateOne(context) - val update = UpdateExpression(context) - .apply(update) - .toBsonDocument() + model.options.options() + model.filter.filter() + model.update.update() - return inner.findOneAndUpdate(filter, update) + return inner.findOneAndUpdate(model.filter.toBsonDocument(), model.update.toBsonDocument(), FindOneAndUpdateOptions()) } // endregion diff --git a/driver-sync/src/commonMain/kotlin/FilteredCollection.kt b/driver-sync/src/commonMain/kotlin/FilteredCollection.kt index 55430ca3..0c85cc51 100644 --- a/driver-sync/src/commonMain/kotlin/FilteredCollection.kt +++ b/driver-sync/src/commonMain/kotlin/FilteredCollection.kt @@ -23,6 +23,7 @@ import opensavvy.ktmongo.dsl.expr.UpdateOperators import opensavvy.ktmongo.dsl.expr.UpsertOperators import opensavvy.ktmongo.dsl.options.CountOptions import opensavvy.ktmongo.dsl.options.FindOptions +import opensavvy.ktmongo.dsl.options.UpdateOptions private class FilteredCollection( private val upstream: MongoCollection, @@ -63,35 +64,58 @@ private class FilteredCollection( override fun countEstimated(): Long = count() - override fun updateMany(filter: FilterOperators.() -> Unit, update: UpdateOperators.() -> Unit) = + override fun updateMany( + options: UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpdateOperators.() -> Unit, + ) { upstream.updateMany( + options = options, filter = { globalFilter() filter() }, update = update, ) + } - override fun updateOne(filter: FilterOperators.() -> Unit, update: UpdateOperators.() -> Unit) = + override fun updateOne( + options: UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpdateOperators.() -> Unit, + ) { upstream.updateOne( + options = options, filter = { globalFilter() filter() }, update = update, ) + } - override fun upsertOne(filter: FilterOperators.() -> Unit, update: UpsertOperators.() -> Unit) = + override fun upsertOne( + options: UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpsertOperators.() -> Unit, + ) { upstream.upsertOne( + options = options, filter = { globalFilter() filter() }, update = update, ) + } - override fun findOneAndUpdate(filter: FilterOperators.() -> Unit, update: UpdateOperators.() -> Unit): Document? = + override fun findOneAndUpdate( + options: UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpdateOperators.() -> Unit, + ): Document? = upstream.findOneAndUpdate( + options = options, filter = { globalFilter() filter() diff --git a/driver-sync/src/commonMain/kotlin/operations/UpdateOperations.kt b/driver-sync/src/commonMain/kotlin/operations/UpdateOperations.kt index 35682d1e..8390bb08 100644 --- a/driver-sync/src/commonMain/kotlin/operations/UpdateOperations.kt +++ b/driver-sync/src/commonMain/kotlin/operations/UpdateOperations.kt @@ -19,6 +19,7 @@ package opensavvy.ktmongo.sync.operations import opensavvy.ktmongo.dsl.expr.FilterOperators import opensavvy.ktmongo.dsl.expr.UpdateOperators import opensavvy.ktmongo.dsl.expr.UpsertOperators +import opensavvy.ktmongo.dsl.options.UpdateOptions import opensavvy.ktmongo.sync.MongoCollection import opensavvy.ktmongo.sync.filter @@ -70,6 +71,7 @@ interface UpdateOperations : BaseOperations { * @see updateOne */ fun updateMany( + options: UpdateOptions.() -> Unit = {}, filter: FilterOperators.() -> Unit = {}, update: UpdateOperators.() -> Unit, ) @@ -120,6 +122,7 @@ interface UpdateOperations : BaseOperations { * @see findOneAndUpdate Also returns the result of the update. */ fun updateOne( + options: UpdateOptions.() -> Unit = {}, filter: FilterOperators.() -> Unit = {}, update: UpdateOperators.() -> Unit, ) @@ -173,6 +176,7 @@ interface UpdateOperations : BaseOperations { * @see updateOne */ fun upsertOne( + options: UpdateOptions.() -> Unit = {}, filter: FilterOperators.() -> Unit = {}, update: UpsertOperators.() -> Unit, ) @@ -221,6 +225,7 @@ interface UpdateOperations : BaseOperations { * @see updateOne Do not return the value. */ fun findOneAndUpdate( + options: UpdateOptions.() -> Unit = {}, filter: FilterOperators.() -> Unit = {}, update: UpdateOperators.() -> Unit, ): Document? diff --git a/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt b/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt index d4dd9a75..f046a95d 100644 --- a/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt +++ b/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt @@ -16,14 +16,14 @@ package opensavvy.ktmongo.sync +import com.mongodb.client.model.FindOneAndUpdateOptions import com.mongodb.client.model.UpdateOptions import opensavvy.ktmongo.bson.BsonContext import opensavvy.ktmongo.bson.buildBsonDocument import opensavvy.ktmongo.dsl.LowLevelApi import opensavvy.ktmongo.dsl.expr.* import opensavvy.ktmongo.dsl.expr.common.Expression -import opensavvy.ktmongo.dsl.models.Count -import opensavvy.ktmongo.dsl.models.Find +import opensavvy.ktmongo.dsl.models.* import opensavvy.ktmongo.dsl.options.CountOptions import opensavvy.ktmongo.dsl.options.FindOptions import opensavvy.ktmongo.dsl.options.common.LimitOption @@ -99,55 +99,63 @@ class JvmMongoCollection internal constructor( // region Update @OptIn(LowLevelApi::class) - override fun updateMany(filter: FilterOperators.() -> Unit, update: UpdateOperators.() -> Unit) { - val filter = FilterExpression(context) - .apply(filter) - .toBsonDocument() + override fun updateMany( + options: opensavvy.ktmongo.dsl.options.UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpdateOperators.() -> Unit, + ) { + val model = UpdateMany(context) - val update = UpdateExpression(context) - .apply(update) - .toBsonDocument() + model.options.options() + model.filter.filter() + model.update.update() - inner.updateMany(filter, update) + inner.updateMany(model.filter.toBsonDocument(), model.update.toBsonDocument(), UpdateOptions()) } @OptIn(LowLevelApi::class) - override fun updateOne(filter: FilterOperators.() -> Unit, update: UpdateOperators.() -> Unit) { - val filter = FilterExpression(context) - .apply(filter) - .toBsonDocument() + override fun updateOne( + options: opensavvy.ktmongo.dsl.options.UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpdateOperators.() -> Unit, + ) { + val model = UpdateOne(context) - val update = UpdateExpression(context) - .apply(update) - .toBsonDocument() + model.options.options() + model.filter.filter() + model.update.update() - inner.updateOne(filter, update) + inner.updateOne(model.filter.toBsonDocument(), model.update.toBsonDocument(), UpdateOptions()) } @OptIn(LowLevelApi::class) - override fun upsertOne(filter: FilterOperators.() -> Unit, update: UpsertOperators.() -> Unit) { - val filter = FilterExpression(context) - .apply(filter) - .toBsonDocument() + override fun upsertOne( + options: opensavvy.ktmongo.dsl.options.UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpsertOperators.() -> Unit, + ) { + val model = UpsertOne(context) - val update = UpdateExpression(context) - .apply(update) - .toBsonDocument() + model.options.options() + model.filter.filter() + model.update.update() - inner.updateOne(filter, update, UpdateOptions().upsert(true)) + inner.updateOne(model.filter.toBsonDocument(), model.update.toBsonDocument(), UpdateOptions().upsert(true)) } @OptIn(LowLevelApi::class) - override fun findOneAndUpdate(filter: FilterOperators.() -> Unit, update: UpdateOperators.() -> Unit): Document? { - val filter = FilterExpression(context) - .apply(filter) - .toBsonDocument() + override fun findOneAndUpdate( + options: opensavvy.ktmongo.dsl.options.UpdateOptions.() -> Unit, + filter: FilterOperators.() -> Unit, + update: UpdateOperators.() -> Unit, + ): Document? { + val model = UpdateOne(context) - val update = UpdateExpression(context) - .apply(update) - .toBsonDocument() + model.options.options() + model.filter.filter() + model.update.update() - return inner.findOneAndUpdate(filter, update) + return inner.findOneAndUpdate(model.filter.toBsonDocument(), model.update.toBsonDocument(), FindOneAndUpdateOptions()) } // endregion diff --git a/dsl/src/commonMain/kotlin/models/Update.kt b/dsl/src/commonMain/kotlin/models/Update.kt new file mode 100644 index 00000000..34a0d855 --- /dev/null +++ b/dsl/src/commonMain/kotlin/models/Update.kt @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2024, OpenSavvy and contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package opensavvy.ktmongo.dsl.models + +import opensavvy.ktmongo.bson.BsonContext +import opensavvy.ktmongo.dsl.KtMongoDsl +import opensavvy.ktmongo.dsl.expr.* +import opensavvy.ktmongo.dsl.options.UpdateOptions + +/** + * Updating a single element in a collection. + * + * ### Example + * + * ```kotlin + * users.updateOne({ User::name eq "foo" }) { + * User::age set 18 + * } + * ``` + * + * @see FilterOperators Filter operators + * @see UpdateOperators Update operators + */ +@KtMongoDsl +class UpdateOne private constructor( + val context: BsonContext, + val options: UpdateOptions, + val filter: FilterOperators, + val update: UpdateOperators, +) { + + constructor(context: BsonContext) : this(context, UpdateOptions(context), FilterExpression(context), UpdateExpression(context)) +} + +/** + * Updating a single element in a collection, creating it if it doesn't exist. + * + * ### Example + * + * ```kotlin + * users.upsertOne({ User::name eq "foo" }) { + * User::age set 18 + * } + * ``` + * + * @see FilterOperators Filter operators + * @see UpdateOperators Update operators + */ +@KtMongoDsl +class UpsertOne private constructor( + val context: BsonContext, + val options: UpdateOptions, + val filter: FilterOperators, + val update: UpsertOperators, +) { + + constructor(context: BsonContext) : this(context, UpdateOptions(context), FilterExpression(context), UpdateExpression(context)) +} + +/** + * Updating multiple elements in a collection. + * + * ### Example + * + * ```kotlin + * users.updateMany({ User::name eq "foo" }) { + * User::age set 18 + * } + * ``` + * + * @see FilterOperators Filter operators + * @see UpdateOperators Update operators + */ +@KtMongoDsl +class UpdateMany private constructor( + val context: BsonContext, + val options: UpdateOptions, + val filter: FilterOperators, + val update: UpdateOperators, +) { + + constructor(context: BsonContext) : this(context, UpdateOptions(context), FilterExpression(context), UpdateExpression(context)) +} diff --git a/dsl/src/commonMain/kotlin/options/UpdateOptions.kt b/dsl/src/commonMain/kotlin/options/UpdateOptions.kt new file mode 100644 index 00000000..831c411c --- /dev/null +++ b/dsl/src/commonMain/kotlin/options/UpdateOptions.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024, OpenSavvy and contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package opensavvy.ktmongo.dsl.options + +import opensavvy.ktmongo.bson.BsonContext +import opensavvy.ktmongo.dsl.options.common.Options +import opensavvy.ktmongo.dsl.options.common.OptionsHolder + +/** + * The options for a `collection.updateOne`, `collection.upsertOne`, `collection.updateMany` operation. + */ +class UpdateOptions(context: BsonContext) : + Options by OptionsHolder(context) -- 2.51.2 From 5602b053823f3228092233e2cb35a40044e85e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=E2=80=9CCLOVIS=E2=80=9D=20Canet?= Date: Sun, 10 Nov 2024 19:46:48 +0100 Subject: [PATCH 5/5] feat: Rename Find's filter from 'predicate' to 'filter' since it uses FilterOperators and not PredicateOperators --- .../src/commonMain/kotlin/FilteredCollection.kt | 6 +++--- .../src/commonMain/kotlin/operations/FindOperations.kt | 10 +++++----- .../src/jvmMain/kotlin/JvmMongoCollection.kt | 4 ++-- .../src/commonMain/kotlin/FilteredCollection.kt | 6 +++--- .../src/commonMain/kotlin/operations/FindOperations.kt | 10 +++++----- driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt | 4 ++-- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt b/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt index b9efea4e..54554bd3 100644 --- a/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt +++ b/driver-coroutines/src/commonMain/kotlin/FilteredCollection.kt @@ -31,15 +31,15 @@ private class FilteredCollection( ) : MongoCollection { override fun find(): MongoIterable = - upstream.find(predicate = globalFilter) + upstream.find(filter = globalFilter) override fun find( options: FindOptions.() -> Unit, - predicate: FilterOperators.() -> Unit, + filter: FilterOperators.() -> Unit, ): MongoIterable = upstream.find(options) { globalFilter() - predicate() + filter() } @LowLevelApi diff --git a/driver-coroutines/src/commonMain/kotlin/operations/FindOperations.kt b/driver-coroutines/src/commonMain/kotlin/operations/FindOperations.kt index 345e9bb7..8490c452 100644 --- a/driver-coroutines/src/commonMain/kotlin/operations/FindOperations.kt +++ b/driver-coroutines/src/commonMain/kotlin/operations/FindOperations.kt @@ -36,7 +36,7 @@ interface FindOperations : BaseOperations { fun find(): MongoIterable /** - * Finds all documents in this collection that satisfy [predicate]. + * Finds all documents in this collection that satisfy [filter]. * * If multiple predicates are specified, an [and][opensavvy.ktmongo.dsl.expr.FilterExpression.and] operator is implied. * @@ -62,11 +62,11 @@ interface FindOperations : BaseOperations { */ fun find( options: FindOptions.() -> Unit = {}, - predicate: FilterOperators.() -> Unit, + filter: FilterOperators.() -> Unit, ): MongoIterable /** - * Finds a document in this collection that satisfies [predicate]. + * Finds a document in this collection that satisfies [filter]. * * If multiple predicates are specified, and [and][FilterExpression.and] operator is implied. * @@ -91,8 +91,8 @@ interface FindOperations : BaseOperations { */ suspend fun findOne( options: FindOptions.() -> Unit = {}, - predicate: FilterOperators.() -> Unit, + filter: FilterOperators.() -> Unit, ): Document? = - find(options, predicate).firstOrNull() + find(options, filter).firstOrNull() } diff --git a/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt b/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt index 57ce78e6..eda40a29 100644 --- a/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt +++ b/driver-coroutines/src/jvmMain/kotlin/JvmMongoCollection.kt @@ -57,12 +57,12 @@ class JvmMongoCollection internal constructor( @OptIn(LowLevelApi::class) override fun find( options: FindOptions.() -> Unit, - predicate: FilterOperators.() -> Unit, + filter: FilterOperators.() -> Unit, ): MongoIterable { val model = Find(context) model.options.options() - model.filter.predicate() + model.filter.filter() return JvmMongoIterable( inner.find(model.filter.toBsonDocument()) diff --git a/driver-sync/src/commonMain/kotlin/FilteredCollection.kt b/driver-sync/src/commonMain/kotlin/FilteredCollection.kt index 0c85cc51..4fced667 100644 --- a/driver-sync/src/commonMain/kotlin/FilteredCollection.kt +++ b/driver-sync/src/commonMain/kotlin/FilteredCollection.kt @@ -31,15 +31,15 @@ private class FilteredCollection( ) : MongoCollection { override fun find(): MongoIterable = - upstream.find(predicate = globalFilter) + upstream.find(filter = globalFilter) override fun find( options: FindOptions.() -> Unit, - predicate: FilterOperators.() -> Unit, + filter: FilterOperators.() -> Unit, ): MongoIterable = upstream.find(options) { globalFilter() - predicate() + filter() } @LowLevelApi diff --git a/driver-sync/src/commonMain/kotlin/operations/FindOperations.kt b/driver-sync/src/commonMain/kotlin/operations/FindOperations.kt index c199d946..4574bf2e 100644 --- a/driver-sync/src/commonMain/kotlin/operations/FindOperations.kt +++ b/driver-sync/src/commonMain/kotlin/operations/FindOperations.kt @@ -36,7 +36,7 @@ interface FindOperations : BaseOperations { fun find(): MongoIterable /** - * Finds all documents in this collection that satisfy [predicate]. + * Finds all documents in this collection that satisfy [filter]. * * If multiple predicates are specified, an [and][FilterExpression.and] operator is implied. * @@ -62,11 +62,11 @@ interface FindOperations : BaseOperations { */ fun find( options: FindOptions.() -> Unit = {}, - predicate: FilterOperators.() -> Unit, + filter: FilterOperators.() -> Unit, ): MongoIterable /** - * Finds a document in this collection that satisfies [predicate]. + * Finds a document in this collection that satisfies [filter]. * * If multiple predicates are specified, and [and][FilterExpression.and] operator is implied. * @@ -91,8 +91,8 @@ interface FindOperations : BaseOperations { */ fun findOne( options: FindOptions.() -> Unit = {}, - predicate: FilterOperators.() -> Unit, + filter: FilterOperators.() -> Unit, ): Document? = - find(options, predicate).firstOrNull() + find(options, filter).firstOrNull() } diff --git a/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt b/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt index f046a95d..119cbdd6 100644 --- a/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt +++ b/driver-sync/src/jvmMain/kotlin/JvmMongoCollection.kt @@ -57,12 +57,12 @@ class JvmMongoCollection internal constructor( @OptIn(LowLevelApi::class) override fun find( options: FindOptions.() -> Unit, - predicate: FilterOperators.() -> Unit, + filter: FilterOperators.() -> Unit, ): MongoIterable { val model = Find(context) model.options.options() - model.filter.predicate() + model.filter.filter() return JvmMongoIterable( inner.find(model.filter.toBsonDocument())