Skip to content
This repository has been archived by the owner on Oct 2, 2024. It is now read-only.

Update operations #25

Merged
merged 16 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion demo/src/main/kotlin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package fr.qsh.ktmongo.demo

import com.mongodb.kotlin.client.MongoClient
import fr.qsh.ktmongo.sync.asKtMongo
import fr.qsh.ktmongo.sync.find
import fr.qsh.ktmongo.sync.filter

data class Jedi(
val name: String,
val age: Int,
val level: Int,
)

fun main() {
Expand All @@ -22,4 +23,11 @@ fun main() {
Jedi::age eq 18
}
}

collection.filter {
Jedi::name eq "foo"
}.upsertOne {
Jedi::age set 19
Jedi::level inc 1
}
}
62 changes: 0 additions & 62 deletions driver-sync/src/main/kotlin/Count.kt

This file was deleted.

105 changes: 105 additions & 0 deletions driver-sync/src/main/kotlin/FilteredMongoCollection.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package fr.qsh.ktmongo.sync

import com.mongodb.client.model.CountOptions
import com.mongodb.client.model.EstimatedDocumentCountOptions
import com.mongodb.client.model.FindOneAndUpdateOptions
import com.mongodb.client.model.UpdateOptions
import com.mongodb.client.result.UpdateResult
import com.mongodb.kotlin.client.FindIterable
import fr.qsh.ktmongo.dsl.expr.FilterExpression
import fr.qsh.ktmongo.dsl.expr.UpdateExpression
import java.util.concurrent.TimeUnit

private class FilteredMongoCollection<Document : Any>(
private val upstream: MongoCollection<Document>,
private val baseFilter: FilterExpression<Document>.() -> Unit,
) : MongoCollection<Document> {
override fun find(): FindIterable<Document> = upstream.find(baseFilter)

override fun count(options: CountOptions): Long = upstream.count(options, baseFilter)

// countEstimated is a real count when a filter is present, it's slower but at least it won't break the app
override fun countEstimated(options: EstimatedDocumentCountOptions): Long = upstream.count(
CountOptions().maxTime(options.getMaxTime(TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS).comment(options.comment),
baseFilter,
)

override fun findOneAndUpdate(
options: FindOneAndUpdateOptions,
filter: FilterExpression<Document>.() -> Unit,
update: UpdateExpression<Document>.() -> Unit
): Document? =
upstream.findOneAndUpdate(
options,
filter = { baseFilter(); filter() },
update = update,
)

override fun updateOne(
options: UpdateOptions,
filter: FilterExpression<Document>.() -> Unit,
update: UpdateExpression<Document>.() -> Unit,
): UpdateResult =
upstream.updateOne(
options,
filter = { baseFilter(); filter() },
update = update,
)

override fun updateMany(
options: UpdateOptions,
filter: FilterExpression<Document>.() -> Unit,
update: UpdateExpression<Document>.() -> Unit,
): UpdateResult =
upstream.updateMany(
options,
filter = { baseFilter(); filter() },
update = update,
)

override fun count(
options: CountOptions,
predicate: FilterExpression<Document>.() -> Unit,
): Long =
upstream.count(options) {
baseFilter()
predicate()
}

override fun find(predicate: FilterExpression<Document>.() -> Unit): FindIterable<Document> =
upstream.find {
baseFilter()
predicate()
}
}

/**
* Returns a filtered collection that only contains the elements that match [predicate].
*
* This function creates a logical view of the collection: by itself, this function does nothing, and MongoDB is never
* aware of the existence of this logical view. However, operations invoked on the returned collection will only affect
* elements from the original that match the [predicate].
*
* Unlike actual MongoDB views, which are read-only, collections returned by this function can also be used for write operations.
*
* ### Example
*
* A typical usage of this function is to reuse filters for multiple operations.
* For example, if you have a concept of logical deletion, this function can be used to hide deleted values.
*
* ```kotlin
* class Order(
* val id: String,
* val date: Instant,
* val deleted: Boolean,
* )
*
* val allOrders = database.getCollection<Order>("orders").asKtMongo()
* val activeOrders = allOrders.filter { Order::deleted ne true }
*
* allOrders.find() // Returns all orders, deleted or not
* activeOrders.find() // Only returns orders that are not logically deleted
* ```
*/
fun <Document : Any> MongoCollection<Document>.filter(predicate: FilterExpression<Document>.() -> Unit): MongoCollection<Document> =
FilteredMongoCollection(this, predicate)
82 changes: 0 additions & 82 deletions driver-sync/src/main/kotlin/Find.kt

This file was deleted.

Loading
Loading