All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmMain.extensions.MongoCollection.kt Maven / Gradle / Ivy

There is a newer version: 0.27.0
Show newest version
package io.fluidsonic.raptor.mongo

import com.mongodb.client.model.*
import com.mongodb.client.model.Filters.*
import com.mongodb.client.result.*
import io.fluidsonic.mongo.*
import io.fluidsonic.stdlib.*
import kotlin.reflect.*
import kotlinx.coroutines.flow.*
import org.bson.*
import org.bson.codecs.*
import org.bson.conversions.*


private val bsonDecoderContext = DecoderContext.builder().build()!!

// TODO move to fluid-mongo?

public suspend fun MongoCollection<*>.deleteOneById(id: Any?, options: DeleteOptions = DeleteOptions()): DeleteResult =
	deleteOne(filter = eq("_id", id), options = options)


public fun  MongoCollection.findById(ids: Iterable<*>): FindFlow =
	findById(ids = ids, resultClass = documentClass)


public fun  MongoCollection<*>.findById(ids: Iterable<*>, resultClass: KClass): FindFlow {
	val collection = (ids as? Collection<*>) ?: ids.toList()
	if (collection.isEmpty())
		return FindFlow.empty()

	return find(filter = `in`("_id", collection), resultClass = resultClass)
}


public suspend fun  MongoCollection.findOneById(id: Any?): TDocument? =
	findOneById(id = id, resultClass = documentClass)


public suspend fun  MongoCollection<*>.findOneById(id: Any?, resultClass: KClass): TResult? =
	find(filter = eq(id), resultClass = resultClass).firstOrNull()


public inline fun  MongoCollection<*>.findOneField(fieldName: String): Flow =
	findOneField(fieldName = fieldName, resultClass = TResult::class)


public fun  MongoCollection<*>.findOneField(fieldName: String, resultClass: KClass): Flow =
	find(resultClass = RawBsonDocument::class)
		.projection(
			if (fieldName == "_id") Projections.include(fieldName)
			else Projections.fields(Projections.include(fieldName), Projections.excludeId())
		)
		.mapNotNull { document ->
			with(document.asBsonReader()) {
				readStartDocument()

				val result = (readBsonType() != BsonType.END_OF_DOCUMENT).thenTake {
					check(readName() == fieldName)

					codecRegistry.get(resultClass.java).decode(this, bsonDecoderContext)
				}

				readEndDocument()

				result
			}
		}


public suspend inline fun  MongoCollection<*>.findOneFieldById(id: Any?, fieldName: String): TResult? =
	findOneFieldById(id, fieldName = fieldName, resultClass = TResult::class)


public suspend fun  MongoCollection<*>.findOneFieldById(id: Any?, fieldName: String, resultClass: KClass): TResult? =
	find(
		filter = eq("_id", id),
		resultClass = RawBsonDocument::class
	)
		.projection(
			if (fieldName == "_id") Projections.include(fieldName)
			else Projections.fields(Projections.include(fieldName), Projections.excludeId())
		)
		.firstOrNull()
		?.let { document ->
			with(document.asBsonReader()) {
				readStartDocument()

				val result = (readBsonType() != BsonType.END_OF_DOCUMENT).thenTake {
					check(readName() == fieldName)

					codecRegistry.get(resultClass.java).decode(this, bsonDecoderContext)
				}

				readEndDocument()

				result
			}
		}


public suspend fun  MongoCollection.findOneByIdAndDelete(
	id: Any?,
	options: FindOneAndDeleteOptions = FindOneAndDeleteOptions(),
): TDocument? =
	findOneAndDelete(
		filter = eq("_id", id),
		options = options
	)


public suspend fun  MongoCollection.findOneByIdAndUpdate(
	id: Any?,
	update: Bson,
	options: FindOneAndUpdateOptions = FindOneAndUpdateOptions(),
): TDocument? =
	findOneAndUpdate(
		filter = eq("_id", id),
		update = update,
		options = options
	)


public suspend fun  MongoCollection.replaceOneById(
	id: Any?,
	replacement: TDocument,
	options: ReplaceOptions = ReplaceOptions(),
): UpdateResult =
	replaceOne(filter = eq("_id", id), replacement = replacement, options = options)


public suspend fun  MongoCollection.updateOneById(
	id: Any?,
	update: Bson,
	options: UpdateOptions = UpdateOptions(),
): UpdateResult =
	updateOne(filter = eq("_id", id), update = update, options = options)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy