From 008209dc6836ff9d7da467966f074a906ac3cfaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=E2=80=9CCLOVIS=E2=80=9D=20Canet?= Date: Mon, 1 Jun 2026 19:30:21 +0200 Subject: [PATCH] feat(driver-multiplatform): Add insertOne --- .../src/commonMain/kotlin/MongoCollection.kt | 13 ++++- .../commonMain/kotlin/MongoCollectionImpl.kt | 37 +++++++++++++++ .../kotlin/commands/MultiplatformInsert.kt | 47 +++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 driver-multiplatform/src/commonTest/kotlin/commands/MultiplatformInsert.kt diff --git a/driver-multiplatform/src/commonMain/kotlin/MongoCollection.kt b/driver-multiplatform/src/commonMain/kotlin/MongoCollection.kt index e25005ef..651e5344 100644 --- a/driver-multiplatform/src/commonMain/kotlin/MongoCollection.kt +++ b/driver-multiplatform/src/commonMain/kotlin/MongoCollection.kt @@ -16,7 +16,10 @@ package opensavvy.ktmongo.multiplatform +import opensavvy.ktmongo.bson.types.ObjectId +import opensavvy.ktmongo.bson.types.ObjectIdGenerator import opensavvy.ktmongo.dsl.LowLevelApi +import opensavvy.ktmongo.dsl.command.InsertOneOptions import kotlin.reflect.KType /** @@ -38,7 +41,7 @@ import kotlin.reflect.KType * You can measure the size of a document with [opensavvy.ktmongo.bson.BsonDocument.toByteArray] * followed by [ByteArray.size]. */ -interface MongoCollection { +interface MongoCollection : ObjectIdGenerator { /** * The [MongoDatabase] that contains this collection. @@ -58,6 +61,14 @@ interface MongoCollection { val fullyQualifiedName: String get() = "${database.name}.$name" + override fun newId(): ObjectId = + database.client.context.newId() + + suspend fun insertOne( + document: Document, + options: InsertOneOptions.() -> Unit = {}, + ) + /** * The [KType] instance that corresponds to the collection's document type. * diff --git a/driver-multiplatform/src/commonMain/kotlin/MongoCollectionImpl.kt b/driver-multiplatform/src/commonMain/kotlin/MongoCollectionImpl.kt index 53082e3a..455587b4 100644 --- a/driver-multiplatform/src/commonMain/kotlin/MongoCollectionImpl.kt +++ b/driver-multiplatform/src/commonMain/kotlin/MongoCollectionImpl.kt @@ -16,7 +16,12 @@ package opensavvy.ktmongo.multiplatform +import kotlinx.coroutines.CancellationException import opensavvy.ktmongo.dsl.LowLevelApi +import opensavvy.ktmongo.dsl.command.InsertOne +import opensavvy.ktmongo.dsl.command.InsertOneOptions +import opensavvy.ktmongo.multiplatform.wire.Message +import opensavvy.ktmongo.multiplatform.wire.MessageSection import kotlin.reflect.KType @OptIn(LowLevelApi::class) @@ -26,6 +31,38 @@ internal class MongoCollectionImpl( override val type: KType, ) : MongoCollection { + override suspend fun insertOne( + document: Document, + options: InsertOneOptions.() -> Unit, + ) { + val command = lazy { + database.client.factory.buildDocument { + writeString("insert", name) + writeString($$"$db", database.name) + + InsertOne( + context = database.client.context, + document = document, + documentType = type, + ).writeTo(this) + } + } + + val responses = database.client.wire.send( + Message.OpMsg( + body = MessageSection.Body( + command, + ) + ) + ) + + val message = responses.receive() + responses.cancel(CancellationException("insertOne expects a single response")) + + check(message is Message.OpMsg) + check(message.body.document["ok"]?.decodeDouble() == 1.0) + } + override fun toString(): String = "MongoCollection($fullyQualifiedName)" } diff --git a/driver-multiplatform/src/commonTest/kotlin/commands/MultiplatformInsert.kt b/driver-multiplatform/src/commonTest/kotlin/commands/MultiplatformInsert.kt new file mode 100644 index 00000000..0507ba1a --- /dev/null +++ b/driver-multiplatform/src/commonTest/kotlin/commands/MultiplatformInsert.kt @@ -0,0 +1,47 @@ +/* + * 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. + */ + +package opensavvy.ktmongo.multiplatform.commands + +import kotlinx.serialization.Serializable +import opensavvy.ktmongo.bson.types.ObjectId +import opensavvy.ktmongo.multiplatform.utils.MongoClient +import opensavvy.prepared.runner.testballoon.preparedSuite + +@Serializable +private data class User( + val _id: ObjectId, + val name: String, + val age: Int, +) + +val MultiplatformInsert by preparedSuite { + + test("Simple insert") { + val client = MongoClient() + val database = client.database("ktmongo-test-1") + val collection = database.collection("users") + + collection.insertOne( + User( + _id = collection.newId(), + name = "Patrick", + age = 42, + ) + ) + } + +} -- 2.51.2