From a42436af569eb885c122fe6a01c35770bfcf5621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=E2=80=9CCLOVIS=E2=80=9D=20Canet?= Date: Mon, 22 Jun 2026 20:26:31 +0200 Subject: [PATCH] feat(driver-coroutines): Implement CoroutineMongoCollection --- .../kotlin/CoroutineMongoCollection.kt | 5 + .../kotlin/CoroutineMongoCollectionImpl.kt | 121 ++++++++++++++++++ .../kotlin/CoroutineMongoDatabaseImpl.kt | 8 +- 3 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 driver-coroutines/src/jvmMain/kotlin/CoroutineMongoCollectionImpl.kt diff --git a/driver-coroutines/src/jvmMain/kotlin/CoroutineMongoCollection.kt b/driver-coroutines/src/jvmMain/kotlin/CoroutineMongoCollection.kt index a2fda928..83ac0d7e 100644 --- a/driver-coroutines/src/jvmMain/kotlin/CoroutineMongoCollection.kt +++ b/driver-coroutines/src/jvmMain/kotlin/CoroutineMongoCollection.kt @@ -14,6 +14,9 @@ * limitations under the License. */ +@file:JvmMultifileClass +@file:JvmName("KtMongo") + package opensavvy.ktmongo.coroutines import opensavvy.ktmongo.api.MongoCollection @@ -49,6 +52,8 @@ import opensavvy.ktmongo.bson.official.BsonFactory * * - [Official documentation](https://www.mongodb.com/docs/manual/core/databases-and-collections/) * - [Size limits](https://www.mongodb.com/docs/manual/reference/limits/#bson-documents) + * + * @see asKtMongo Convert an existing instance from the official Kotlin driver. */ interface CoroutineMongoCollection : MongoCollection { diff --git a/driver-coroutines/src/jvmMain/kotlin/CoroutineMongoCollectionImpl.kt b/driver-coroutines/src/jvmMain/kotlin/CoroutineMongoCollectionImpl.kt new file mode 100644 index 00000000..accdcde1 --- /dev/null +++ b/driver-coroutines/src/jvmMain/kotlin/CoroutineMongoCollectionImpl.kt @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2026, 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. + */ + +@file:JvmMultifileClass +@file:JvmName("KtMongo") + +package opensavvy.ktmongo.coroutines + +import com.mongodb.kotlin.client.coroutine.MongoCollection +import opensavvy.ktmongo.bson.official.BsonFactory +import opensavvy.ktmongo.bson.official.types.Jvm +import opensavvy.ktmongo.bson.types.ObjectIdGenerator +import opensavvy.ktmongo.dsl.BsonContext +import opensavvy.ktmongo.dsl.LowLevelApi +import opensavvy.ktmongo.dsl.path.PropertyNameStrategy +import kotlin.reflect.KType +import kotlin.reflect.typeOf + +private class CoroutineMongoCollectionImpl( + private val inner: MongoCollection, + override val factory: BsonFactory, + override val propertyNameStrategy: PropertyNameStrategy, + override val objectIdGenerator: ObjectIdGenerator, + @property:LowLevelApi + override val type: KType, +) : CoroutineMongoCollection { + + override fun asOfficial(): MongoCollection = + inner + + override val name: String + get() = inner.namespace.collectionName + + override val fullyQualifiedName: String + get() = inner.namespace.fullName + + private inner class CoroutineBsonContext : BsonContext, + opensavvy.ktmongo.bson.BsonFactory by factory, + ObjectIdGenerator by objectIdGenerator, + PropertyNameStrategy by propertyNameStrategy + + override val context: BsonContext = CoroutineBsonContext() + + override fun toString(): String = + "CoroutineMongoCollection($fullyQualifiedName)" +} + +/** + * Instantiates a KtMongo [CoroutineMongoCollection] using an existing collection from the official Kotlin driver. + * + * ### Example + * + * ```kotlin + * import com.mongodb.kotlin.client.coroutine.MongoClient + * + * fun main() = runBlocking { + * val client = MongoClient.create(/* … */) + * val database = client.database("my-app") + * val users = database.collection("users") + * .asKtMongo() + * + * println("Users: ${users.count()}") + * } + * ``` + */ +fun MongoCollection.asKtMongo( + factory: BsonFactory = BsonFactory(this.codecRegistry), + propertyNameStrategy: PropertyNameStrategy = PropertyNameStrategy.Default, + objectIdGenerator: ObjectIdGenerator = ObjectIdGenerator.Jvm(), + type: KType, +): CoroutineMongoCollection = + CoroutineMongoCollectionImpl( + inner = this, + factory = factory, + propertyNameStrategy = propertyNameStrategy, + objectIdGenerator = objectIdGenerator, + type = type, + ) + +/** + * Instantiates a KtMongo [CoroutineMongoCollection] using an existing collection from the official Kotlin driver. + * + * ### Example + * + * ```kotlin + * import com.mongodb.kotlin.client.coroutine.MongoClient + * + * fun main() = runBlocking { + * val client = MongoClient.create(/* … */) + * val database = client.database("my-app") + * val users = database.collection("users") + * .asKtMongo() + * + * println("Users: ${users.count()}") + * } + * ``` + */ +inline fun MongoCollection.asKtMongo( + factory: BsonFactory = BsonFactory(this.codecRegistry), + propertyNameStrategy: PropertyNameStrategy = PropertyNameStrategy.Default, + objectIdGenerator: ObjectIdGenerator = ObjectIdGenerator.Jvm(), +): CoroutineMongoCollection = + asKtMongo( + factory = factory, + propertyNameStrategy = propertyNameStrategy, + objectIdGenerator = objectIdGenerator, + type = typeOf(), + ) diff --git a/driver-coroutines/src/jvmMain/kotlin/CoroutineMongoDatabaseImpl.kt b/driver-coroutines/src/jvmMain/kotlin/CoroutineMongoDatabaseImpl.kt index 3bfe6f11..854ba10e 100644 --- a/driver-coroutines/src/jvmMain/kotlin/CoroutineMongoDatabaseImpl.kt +++ b/driver-coroutines/src/jvmMain/kotlin/CoroutineMongoDatabaseImpl.kt @@ -21,6 +21,7 @@ package opensavvy.ktmongo.coroutines import com.mongodb.kotlin.client.coroutine.MongoDatabase import opensavvy.ktmongo.dsl.LowLevelApi +import kotlin.reflect.KClass import kotlin.reflect.KType private class CoroutineMongoDatabaseImpl( @@ -31,9 +32,10 @@ private class CoroutineMongoDatabaseImpl( inner @LowLevelApi - override fun collection(name: String, type: KType): CoroutineMongoCollection { - TODO("Not yet implemented") - } + @Suppress("UNCHECKED_CAST") + override fun collection(name: String, type: KType): CoroutineMongoCollection = + inner.getCollection(name, (type.classifier as KClass).java) + .asKtMongo(type = type) override val name: String get() = inner.name -- 2.51.2