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

Commit

Permalink
merge: Update operations
Browse files Browse the repository at this point in the history
  • Loading branch information
CLOVIS-AI authored Jul 19, 2024
2 parents 2c24601 + 9a7ff2e commit c060055
Show file tree
Hide file tree
Showing 12 changed files with 1,297 additions and 158 deletions.
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

0 comments on commit c060055

Please sign in to comment.