mirror of
https://github.com/tursom/TursomServer.git
synced 2025-03-14 03:40:06 +08:00
update ts-mongodb
This commit is contained in:
parent
40801d52fb
commit
657f1a31e6
@ -691,3 +691,9 @@ fun ByteArray.gz(): ByteArray {
|
||||
fun ByteArray.ungz(): ByteArray {
|
||||
return GZIPInputStream(ByteArrayInputStream(this)).readBytes()
|
||||
}
|
||||
|
||||
fun StringBuilder(vararg strings: String): StringBuilder {
|
||||
val builder = kotlin.text.StringBuilder(strings.sumOf { it.length })
|
||||
builder.append(value = strings)
|
||||
return builder
|
||||
}
|
||||
|
@ -7,7 +7,11 @@ plugins {
|
||||
dependencies {
|
||||
api(project(":"))
|
||||
implementation(project(":ts-core"))
|
||||
implementation(project(":ts-core:ts-clone"))
|
||||
compileOnly("org.mongodb:mongo-java-driver:3.12.10")
|
||||
compileOnly(group = "org.springframework.data", name = "spring-data-mongodb", version = "3.3.0")
|
||||
testApi(group = "junit", name = "junit", version = "4.13.2")
|
||||
testImplementation(group = "org.springframework.data", name = "spring-data-mongodb", version = "3.3.0")
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,5 +29,5 @@ interface BsonConverter {
|
||||
}
|
||||
}
|
||||
|
||||
fun Any.bsonValue(): Any = bsonValue(this)
|
||||
fun Any.bsonValue(): Any = Companion.bsonValue(this)
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package cn.tursom.database.mongodb.spring
|
||||
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationExpression
|
||||
import org.springframework.data.mongodb.core.aggregation.StringOperators
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class ConcatBuilder {
|
||||
companion object : MongoName, BsonConverter {
|
||||
inline infix operator fun invoke(operator: ConcatBuilder.() -> Unit): StringOperators.Concat {
|
||||
val setBuilder = ConcatBuilder()
|
||||
setBuilder.operator()
|
||||
return when (setBuilder.list.size) {
|
||||
0 -> StringOperators.Concat.stringValue("")
|
||||
1 -> getConcat(setBuilder.list[0])
|
||||
else -> {
|
||||
val iterator = setBuilder.list.iterator()
|
||||
var concat = getConcat(iterator.next())
|
||||
iterator.forEach {
|
||||
concat = when (it) {
|
||||
is KProperty<*> -> concat.concatValueOf(it.mongoName)
|
||||
is FieldReference -> concat.concatValueOf(it.field)
|
||||
is AggregationExpression -> concat.concatValueOf(it)
|
||||
else -> concat.concat(it.toString())
|
||||
}
|
||||
}
|
||||
concat
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getConcat(value: Any?) = when (value) {
|
||||
is KProperty<*> -> StringOperators.Concat.valueOf(value.mongoName)
|
||||
is FieldReference -> StringOperators.Concat.valueOf(value.field)
|
||||
is AggregationExpression -> StringOperators.Concat.valueOf(value)
|
||||
else -> StringOperators.Concat.stringValue(value.toString())
|
||||
}
|
||||
}
|
||||
|
||||
data class FieldReference(val field: String)
|
||||
|
||||
val list = ArrayList<Any?>()
|
||||
|
||||
operator fun Any?.unaryPlus() {
|
||||
list.add(this)
|
||||
}
|
||||
|
||||
operator fun AggregationExpression.unaryPlus() {
|
||||
list.add(this)
|
||||
}
|
||||
|
||||
fun field(field: String) {
|
||||
list.add(FieldReference(field))
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package cn.tursom.database.mongodb.spring
|
||||
|
||||
import org.bson.Document
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext
|
||||
import org.springframework.data.mongodb.core.aggregation.ExposedFields
|
||||
import org.springframework.data.mongodb.core.aggregation.Field
|
||||
|
||||
object DirectAggregationOperationContext : AggregationOperationContext {
|
||||
override fun getMappedObject(document: Document, type: Class<*>?): Document = document
|
||||
|
||||
private class DirectAggregationOperationReference(name: String) : ExposedFields.FieldReference {
|
||||
private val name = "$$name"
|
||||
override fun getRaw(): String? = null
|
||||
override fun getReferenceValue(): Any? = null
|
||||
override fun toString(): String = name
|
||||
}
|
||||
|
||||
override fun getReference(field: Field): ExposedFields.FieldReference =
|
||||
DirectAggregationOperationReference(field.name)
|
||||
|
||||
override fun getReference(name: String): ExposedFields.FieldReference =
|
||||
DirectAggregationOperationReference(name)
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package cn.tursom.database.mongodb.spring
|
||||
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import com.mongodb.client.model.FindOneAndUpdateOptions
|
||||
import org.bson.conversions.Bson
|
||||
|
||||
inline fun FindOneAndUpdateOptions.arrayFilter(builder: QueryBuilder.() -> Unit) {
|
||||
if (arrayFilters == null) {
|
||||
arrayFilters(ArrayList())
|
||||
}
|
||||
arrayFilters.uncheckedCast<MutableList<Bson>>()
|
||||
.add(QueryBuilder queryObject builder)
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package cn.tursom.database.mongodb.spring
|
||||
|
||||
import cn.tursom.core.StringBuilder
|
||||
import cn.tursom.database.mongodb.spring.function.Function1
|
||||
import cn.tursom.database.mongodb.spring.function.field
|
||||
import org.springframework.data.annotation.Id
|
||||
@ -8,9 +9,11 @@ import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.jvm.javaField
|
||||
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
interface MongoName {
|
||||
companion object {
|
||||
const val dollar = '$'
|
||||
const val dollar = "$"
|
||||
const val dotDollar = "$"
|
||||
inline operator fun <T> invoke(builder: Companion.() -> T) = this.builder()
|
||||
|
||||
inline val KProperty<*>.mongoName: String
|
||||
@ -19,7 +22,7 @@ interface MongoName {
|
||||
fun arrayElement(elementName: String = "") = if (elementName.isBlank()) {
|
||||
"$"
|
||||
} else {
|
||||
"$[$elementName]"
|
||||
"$.$elementName"
|
||||
}
|
||||
|
||||
fun mongoName(kProperty: KProperty<*>): String {
|
||||
@ -50,38 +53,103 @@ interface MongoName {
|
||||
|
||||
fun <T> mongoName(getter: Function1<*, T>): String = mongoName(getter.field!!)
|
||||
|
||||
infix operator fun KProperty<*>.plus(kProperty: KProperty<*>) = "$mongoName.${kProperty.mongoName}"
|
||||
infix operator fun KProperty<*>.plus(field: String) = "$mongoName.${field}"
|
||||
infix operator fun String.plus(kProperty: KProperty<*>) = "$this.${kProperty.mongoName}"
|
||||
infix operator fun String.plus(field: String) = "$this.${field}"
|
||||
infix operator fun KProperty<*>.plus(kProperty: KProperty<*>) =
|
||||
StringBuilder(mongoName, ".", kProperty.mongoName)
|
||||
|
||||
infix operator fun KProperty<*>.get(kProperty: KProperty<*>) = plus(kProperty)
|
||||
infix operator fun KProperty<*>.get(field: String) = plus(field)
|
||||
infix operator fun String.get(kProperty: KProperty<*>) = plus(kProperty)
|
||||
infix operator fun String.get(field: String) = plus(field)
|
||||
infix operator fun KProperty<*>.plus(field: String) = StringBuilder(mongoName, ".", field)
|
||||
infix operator fun KProperty<*>.plus(field: StringBuilder) = StringBuilder(mongoName, ".").append(field)
|
||||
|
||||
infix operator fun KProperty<*>.rem(kProperty: KProperty<*>) = plus(kProperty)
|
||||
infix operator fun KProperty<*>.rem(field: String) = plus(field)
|
||||
infix operator fun String.rem(kProperty: KProperty<*>) = plus(kProperty)
|
||||
infix operator fun String.rem(field: String) = plus(field)
|
||||
infix operator fun String.plus(kProperty: KProperty<*>) = StringBuilder(this, ".", kProperty.mongoName)
|
||||
infix operator fun String.plus(field: String) = StringBuilder(this, ".", field)
|
||||
infix operator fun String.plus(field: StringBuilder) = StringBuilder(this, ".").append(field)
|
||||
|
||||
infix operator fun StringBuilder.plus(kProperty: KProperty<*>) = append(".", kProperty.mongoName)
|
||||
infix operator fun StringBuilder.plus(field: String) = append(".", field)
|
||||
infix operator fun StringBuilder.plus(field: StringBuilder) = append(".", field)
|
||||
|
||||
fun KProperty<*>.arrayElement(kProperty: KProperty<*>) =
|
||||
StringBuilder(mongoName, ".", dollar, ".", kProperty.mongoName)
|
||||
|
||||
fun KProperty<*>.arrayElement(field: String) =
|
||||
StringBuilder(mongoName, ".", dollar, ".", field)
|
||||
|
||||
fun KProperty<*>.arrayElement(field: StringBuilder) =
|
||||
StringBuilder(mongoName, ".", dollar, ".").append(field)
|
||||
|
||||
fun String.arrayElement(kProperty: KProperty<*>) =
|
||||
StringBuilder(this, ".", dollar, ".", kProperty.mongoName)
|
||||
|
||||
fun String.arrayElement(field: String) =
|
||||
StringBuilder(this, ".", dollar, ".", field)
|
||||
|
||||
fun String.arrayElement(field: StringBuilder) =
|
||||
StringBuilder(this, ".", dollar, ".").append(field)
|
||||
|
||||
fun StringBuilder.arrayElement(kProperty: KProperty<*>) =
|
||||
append(".", dollar, ".", kProperty.mongoName)
|
||||
|
||||
fun StringBuilder.arrayElement(field: String) =
|
||||
append(".", dollar, ".", field)
|
||||
|
||||
fun StringBuilder.arrayElement(field: StringBuilder) =
|
||||
append(".", dollar, ".", field)
|
||||
|
||||
infix operator fun KProperty<*>.get(kProperty: KProperty<*>) = arrayElement(kProperty)
|
||||
infix operator fun KProperty<*>.get(field: String) = arrayElement(field)
|
||||
infix operator fun KProperty<*>.get(field: StringBuilder) = arrayElement(field)
|
||||
infix operator fun String.get(kProperty: KProperty<*>) = arrayElement(kProperty)
|
||||
infix operator fun String.get(field: String) = arrayElement(field)
|
||||
infix operator fun String.get(field: StringBuilder) = arrayElement(field)
|
||||
infix operator fun StringBuilder.get(kProperty: KProperty<*>) = arrayElement(kProperty)
|
||||
infix operator fun StringBuilder.get(field: String) = arrayElement(field)
|
||||
infix operator fun StringBuilder.get(field: StringBuilder) = arrayElement(field)
|
||||
|
||||
infix operator fun KProperty<*>.rem(kProperty: KProperty<*>) = this plus kProperty
|
||||
infix operator fun KProperty<*>.rem(field: String) = this plus field
|
||||
infix operator fun String.rem(kProperty: KProperty<*>) = this plus kProperty
|
||||
infix operator fun String.rem(field: String) = this plus field
|
||||
infix operator fun StringBuilder.rem(kProperty: KProperty<*>) = this plus kProperty
|
||||
infix operator fun StringBuilder.rem(field: String) = this plus field
|
||||
}
|
||||
|
||||
val dollar get() = Companion.dollar
|
||||
val dotDollar get() = Companion.dotDollar
|
||||
val KProperty<*>.mongoName: String
|
||||
get() = mongoName(this)
|
||||
val arrayElements: String get() = "$[]"
|
||||
|
||||
fun arrayElement(elementName: String = "") = Companion.arrayElement(elementName)
|
||||
fun arrayElement(kProperty: KProperty<*>) = Companion.arrayElement(kProperty.mongoName)
|
||||
fun mongoName(kProperty: KProperty<*>): String = Companion.mongoName(kProperty)
|
||||
fun mongoName(field: java.lang.reflect.Field): String = Companion.mongoName(field)
|
||||
fun <T> mongoName(getter: Function1<*, T>): String = Companion.mongoName(getter)
|
||||
|
||||
infix operator fun KProperty<*>.get(kProperty: KProperty<*>) = Companion { this@get plus kProperty }
|
||||
infix operator fun KProperty<*>.get(field: String) = Companion { this@get plus field }
|
||||
infix operator fun String.get(kProperty: KProperty<*>) = Companion { this@get plus kProperty }
|
||||
infix operator fun String.get(field: String) = Companion { this@get plus field }
|
||||
val KProperty<*>.arrayFilter: StringBuilder
|
||||
get() = Companion {
|
||||
StringBuilder(mongoName, ".$[", mongoName, "]")
|
||||
}
|
||||
|
||||
infix operator fun KProperty<*>.rem(kProperty: KProperty<*>) = Companion { this@rem plus kProperty }
|
||||
infix operator fun KProperty<*>.rem(field: String) = Companion { this@rem plus field }
|
||||
infix operator fun String.rem(kProperty: KProperty<*>) = Companion { this@rem plus kProperty }
|
||||
infix operator fun String.rem(field: String) = Companion { this@rem plus field }
|
||||
fun KProperty<*>.arrayFilter(field: String): StringBuilder = Companion {
|
||||
StringBuilder(mongoName, ".$[", field, "]")
|
||||
}
|
||||
|
||||
infix operator fun KProperty<*>.get(kProperty: KProperty<*>) = Companion { this@get get kProperty }
|
||||
infix operator fun KProperty<*>.get(field: String) = Companion { this@get get field }
|
||||
infix operator fun KProperty<*>.get(field: StringBuilder) = Companion { this@get get field }
|
||||
infix operator fun String.get(kProperty: KProperty<*>) = Companion { this@get get kProperty }
|
||||
infix operator fun String.get(field: String) = Companion { this@get get field }
|
||||
infix operator fun String.get(field: StringBuilder) = Companion { this@get get field }
|
||||
infix operator fun StringBuilder.get(kProperty: KProperty<*>) = Companion { this@get get kProperty }
|
||||
infix operator fun StringBuilder.get(field: String) = Companion { this@get get field }
|
||||
infix operator fun StringBuilder.get(field: StringBuilder) = Companion { this@get get field }
|
||||
|
||||
infix operator fun KProperty<*>.rem(kProperty: KProperty<*>) = Companion { this@rem % kProperty }
|
||||
infix operator fun KProperty<*>.rem(field: String) = Companion { this@rem % field }
|
||||
infix operator fun KProperty<*>.rem(field: StringBuilder) = Companion { this@rem % field.toString() }
|
||||
infix operator fun String.rem(kProperty: KProperty<*>) = Companion { this@rem % kProperty }
|
||||
infix operator fun String.rem(field: String) = Companion { this@rem % field }
|
||||
infix operator fun String.rem(field: StringBuilder) = Companion { this@rem % field.toString() }
|
||||
infix operator fun StringBuilder.rem(kProperty: KProperty<*>) = Companion { this@rem % kProperty }
|
||||
infix operator fun StringBuilder.rem(field: String) = Companion { this@rem % field }
|
||||
infix operator fun StringBuilder.rem(field: StringBuilder) = Companion { this@rem % field.toString() }
|
||||
}
|
@ -17,7 +17,7 @@ object MongoUtil {
|
||||
else -> null
|
||||
}
|
||||
} ?: clazz.simpleName.toCharArray().let {
|
||||
it[0] = it[0].toLowerCase()
|
||||
it[0] = it[0].lowercaseChar()
|
||||
it
|
||||
}.concatToString()
|
||||
|
||||
@ -30,9 +30,9 @@ object MongoUtil {
|
||||
entity.javaClass.declaredFields.filter {
|
||||
it.isAccessible = true
|
||||
!it.isStatic()
|
||||
&& !it.isTransient()
|
||||
//&& it.getAnnotation(Ignore::class.java) == null
|
||||
&& (it.type != Lazy::class.java || it.get(entity).uncheckedCast<Lazy<*>>().isInitialized())
|
||||
&& !it.isTransient()
|
||||
//&& it.getAnnotation(Ignore::class.java) == null
|
||||
&& (it.type != Lazy::class.java || it.get(entity).uncheckedCast<Lazy<*>>().isInitialized())
|
||||
}.forEach {
|
||||
injectValue(bson, it.get(entity) ?: return@forEach, it)
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import kotlin.reflect.KProperty
|
||||
@Suppress("unused", "MemberVisibilityCanBePrivate")
|
||||
object ProjectBuilder : MongoName, BsonConverter {
|
||||
inline infix operator fun invoke(
|
||||
operator: ProjectBuilder.() -> ProjectionOperation
|
||||
operator: ProjectBuilder.() -> ProjectionOperation,
|
||||
): ProjectionOperation = this.operator()
|
||||
|
||||
fun project(): ProjectionOperation = Aggregation.project()
|
||||
@ -19,6 +19,7 @@ object ProjectBuilder : MongoName, BsonConverter {
|
||||
Aggregation.project(*fields.map { it.mongoName }.toTypedArray())
|
||||
|
||||
infix fun ProjectionOperation.and(name: String): ProjectionOperationBuilder = and(name)
|
||||
infix fun ProjectionOperation.and(name: StringBuilder): ProjectionOperationBuilder = and(name.toString())
|
||||
infix fun ProjectionOperation.and(name: KProperty<*>): ProjectionOperationBuilder = and(name.mongoName)
|
||||
|
||||
infix fun ProjectionOperation.andExclude(fields: KProperty<*>): ProjectionOperation = andExclude(listOf(fields))
|
||||
@ -28,9 +29,15 @@ object ProjectBuilder : MongoName, BsonConverter {
|
||||
|
||||
infix fun ProjectionOperation.andInclude(fields: KProperty<*>): ProjectionOperation = andInclude(listOf(fields))
|
||||
fun ProjectionOperation.andInclude(vararg fields: KProperty<*>): ProjectionOperation = andInclude(fields.asList())
|
||||
|
||||
@JvmName("andIncludeKProperty")
|
||||
infix fun ProjectionOperation.andInclude(fields: Collection<KProperty<*>>): ProjectionOperation =
|
||||
andInclude(*fields.map { it.mongoName }.toTypedArray())
|
||||
|
||||
@JvmName("andIncludeString")
|
||||
infix fun ProjectionOperation.andInclude(fields: Collection<String>): ProjectionOperation =
|
||||
andInclude(*fields.toTypedArray())
|
||||
|
||||
|
||||
infix fun ProjectionOperationBuilder.nested(fields: Fields): ProjectionOperation = nested(fields)
|
||||
infix fun ProjectionOperationBuilder.`as`(alias: String): ProjectionOperation = `as`(alias)
|
||||
@ -106,7 +113,9 @@ object ProjectBuilder : MongoName, BsonConverter {
|
||||
|
||||
infix fun ProjectionOperationBuilder.log(base: Number): ProjectionOperationBuilder = log(base)
|
||||
|
||||
infix fun ProjectionOperationBuilder.pow(exponentFieldRef: String): ProjectionOperationBuilder = pow(exponentFieldRef)
|
||||
infix fun ProjectionOperationBuilder.pow(exponentFieldRef: String): ProjectionOperationBuilder =
|
||||
pow(exponentFieldRef)
|
||||
|
||||
infix fun ProjectionOperationBuilder.pow(exponentFieldRef: KProperty<*>): ProjectionOperationBuilder =
|
||||
pow(exponentFieldRef.mongoName)
|
||||
|
||||
@ -204,7 +213,9 @@ object ProjectBuilder : MongoName, BsonConverter {
|
||||
|
||||
infix fun String.log(base: Number): ProjectionOperationBuilder = project() and this log (base)
|
||||
|
||||
infix fun String.pow(exponentFieldRef: String): ProjectionOperationBuilder = project() and this pow (exponentFieldRef)
|
||||
infix fun String.pow(exponentFieldRef: String): ProjectionOperationBuilder =
|
||||
project() and this pow (exponentFieldRef)
|
||||
|
||||
infix fun String.pow(exponentFieldRef: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this pow (exponentFieldRef.mongoName)
|
||||
|
||||
@ -216,7 +227,6 @@ object ProjectBuilder : MongoName, BsonConverter {
|
||||
infix fun String.strCaseCmpValueOf(fieldRef: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this strCaseCmpValueOf (fieldRef.mongoName)
|
||||
|
||||
|
||||
infix fun KProperty<*>.nested(fields: Fields): ProjectionOperation = project() and this nested (fields)
|
||||
infix fun KProperty<*>.`as`(alias: String): ProjectionOperation = project() and this `as` (alias)
|
||||
infix fun KProperty<*>.alias(alias: String): ProjectionOperation = project() and this `as` (alias)
|
||||
@ -235,7 +245,9 @@ object ProjectBuilder : MongoName, BsonConverter {
|
||||
infix operator fun KProperty<*>.plus(fieldReference: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this plus (fieldReference.mongoName)
|
||||
|
||||
infix operator fun KProperty<*>.minus(number: Number): ProjectionOperationBuilder = project() and this minus (number)
|
||||
infix operator fun KProperty<*>.minus(number: Number): ProjectionOperationBuilder =
|
||||
project() and this minus (number)
|
||||
|
||||
infix operator fun KProperty<*>.minus(fieldReference: String): ProjectionOperationBuilder =
|
||||
project() and this minus (fieldReference)
|
||||
|
||||
@ -311,6 +323,102 @@ object ProjectBuilder : MongoName, BsonConverter {
|
||||
infix fun KProperty<*>.strCaseCmpValueOf(fieldRef: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this strCaseCmpValueOf (fieldRef.mongoName)
|
||||
|
||||
|
||||
infix fun StringBuilder.nested(fields: Fields): ProjectionOperation = project() and this nested fields
|
||||
infix fun StringBuilder.`as`(alias: String): ProjectionOperation = project() and this `as` alias
|
||||
infix fun StringBuilder.alias(alias: String): ProjectionOperation = project() and this `as` alias
|
||||
infix fun StringBuilder.`as`(alias: KProperty<*>): ProjectionOperation = project() and this `as` alias.mongoName
|
||||
infix fun StringBuilder.alias(alias: KProperty<*>): ProjectionOperation = project() and this `as` alias.mongoName
|
||||
infix fun StringBuilder.applyCondition(cond: ConditionalOperators.Cond): ProjectionOperation =
|
||||
project() and this applyCondition cond
|
||||
|
||||
infix fun StringBuilder.applyCondition(ifNull: ConditionalOperators.IfNull): ProjectionOperation =
|
||||
project() and this applyCondition ifNull
|
||||
|
||||
infix operator fun StringBuilder.plus(number: Number): ProjectionOperationBuilder = project() and this plus number
|
||||
infix operator fun StringBuilder.plus(fieldReference: String): ProjectionOperationBuilder =
|
||||
project() and this plus fieldReference
|
||||
|
||||
infix operator fun StringBuilder.plus(fieldReference: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this plus fieldReference.mongoName
|
||||
|
||||
infix operator fun StringBuilder.minus(number: Number): ProjectionOperationBuilder = project() and this minus number
|
||||
infix operator fun StringBuilder.minus(fieldReference: String): ProjectionOperationBuilder =
|
||||
project() and this minus fieldReference
|
||||
|
||||
infix operator fun StringBuilder.minus(fieldReference: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this minus fieldReference.mongoName
|
||||
|
||||
infix fun StringBuilder.multiply(number: Number): ProjectionOperationBuilder = project() and this multiply number
|
||||
infix fun StringBuilder.multiply(fieldReference: String): ProjectionOperationBuilder =
|
||||
project() and this multiply fieldReference
|
||||
|
||||
infix fun StringBuilder.multiply(fieldReference: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this multiply fieldReference.mongoName
|
||||
|
||||
infix operator fun StringBuilder.times(number: Number): ProjectionOperationBuilder =
|
||||
project() and this multiply number
|
||||
|
||||
infix operator fun StringBuilder.times(fieldReference: String): ProjectionOperationBuilder =
|
||||
project() and this multiply fieldReference
|
||||
|
||||
infix operator fun StringBuilder.times(fieldReference: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this multiply fieldReference.mongoName
|
||||
|
||||
infix fun StringBuilder.divide(number: Number): ProjectionOperationBuilder = project() and this divide number
|
||||
infix fun StringBuilder.divide(fieldReference: String): ProjectionOperationBuilder =
|
||||
project() and this divide fieldReference
|
||||
|
||||
infix fun StringBuilder.divide(fieldReference: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this divide fieldReference.mongoName
|
||||
|
||||
infix operator fun StringBuilder.div(number: Number): ProjectionOperationBuilder = project() and this divide number
|
||||
infix operator fun StringBuilder.div(fieldReference: String): ProjectionOperationBuilder =
|
||||
project() and this divide fieldReference
|
||||
|
||||
infix operator fun StringBuilder.div(fieldReference: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this divide fieldReference.mongoName
|
||||
|
||||
infix fun StringBuilder.mod(number: Number): ProjectionOperationBuilder = project() and this mod number
|
||||
infix fun StringBuilder.mod(fieldReference: String): ProjectionOperationBuilder =
|
||||
project() and this mod fieldReference
|
||||
|
||||
infix fun StringBuilder.mod(fieldReference: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this mod fieldReference.mongoName
|
||||
|
||||
infix fun StringBuilder.cmp(compareValue: Any): ProjectionOperationBuilder = project() and this cmp compareValue
|
||||
infix fun StringBuilder.eq(compareValue: Any): ProjectionOperationBuilder = project() and this eq compareValue
|
||||
infix fun StringBuilder.gt(compareValue: Any): ProjectionOperationBuilder = project() and this gt compareValue
|
||||
infix fun StringBuilder.gte(compareValue: Any): ProjectionOperationBuilder = project() and this gte compareValue
|
||||
infix fun StringBuilder.lt(compareValue: Any): ProjectionOperationBuilder = project() and this lt compareValue
|
||||
infix fun StringBuilder.lte(compareValue: Any): ProjectionOperationBuilder = project() and this lte compareValue
|
||||
infix fun StringBuilder.ne(compareValue: Any): ProjectionOperationBuilder = project() and this ne compareValue
|
||||
|
||||
infix fun StringBuilder.slice(count: Int): ProjectionOperationBuilder = project() and this slice count
|
||||
fun StringBuilder.slice(count: Int, offset: Int): ProjectionOperationBuilder =
|
||||
(project() and this).slice(count, offset)
|
||||
|
||||
infix fun StringBuilder.log(baseFieldRef: String): ProjectionOperationBuilder = project() and this log baseFieldRef
|
||||
infix fun StringBuilder.log(baseFieldRef: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this log baseFieldRef.mongoName
|
||||
|
||||
infix fun StringBuilder.log(base: Number): ProjectionOperationBuilder = project() and this log base
|
||||
|
||||
infix fun StringBuilder.pow(exponentFieldRef: String): ProjectionOperationBuilder =
|
||||
project() and this pow exponentFieldRef
|
||||
|
||||
infix fun StringBuilder.pow(exponentFieldRef: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this pow exponentFieldRef.mongoName
|
||||
|
||||
infix fun StringBuilder.pow(exponent: Number): ProjectionOperationBuilder = project() and this pow exponent
|
||||
|
||||
infix fun StringBuilder.strCaseCmpValueOf(fieldRef: String): ProjectionOperationBuilder =
|
||||
project() and this strCaseCmpValueOf fieldRef
|
||||
|
||||
infix fun StringBuilder.strCaseCmpValueOf(fieldRef: KProperty<*>): ProjectionOperationBuilder =
|
||||
project() and this strCaseCmpValueOf fieldRef.mongoName
|
||||
|
||||
|
||||
@JvmName("concatArrays_")
|
||||
fun String.concatArrays(fields: Collection<String>): ProjectionOperationBuilder =
|
||||
(project() and this).concatArrays(*fields.toTypedArray())
|
||||
|
@ -1,6 +1,5 @@
|
||||
package cn.tursom.database.mongodb.spring
|
||||
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import org.bson.BsonRegularExpression
|
||||
import org.bson.Document
|
||||
import org.bson.types.ObjectId
|
||||
@ -18,46 +17,27 @@ import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate", "unused")
|
||||
@Suppress("MemberVisibilityCanBePrivate", "unused", "HasPlatformType")
|
||||
class QueryBuilder : MongoName {
|
||||
companion object {
|
||||
const val where = "\$where"
|
||||
private val criteriaField: java.lang.reflect.Field? = try {
|
||||
Criteria::class.java.getDeclaredField("criteria")
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
private val isValueField: java.lang.reflect.Field? = try {
|
||||
Criteria::class.java.getDeclaredField("isValue")
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
private val criteriaChainField: java.lang.reflect.Field? = try {
|
||||
Criteria::class.java.getDeclaredField("criteriaChain")
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
init {
|
||||
criteriaField?.isAccessible = true
|
||||
isValueField?.isAccessible = true
|
||||
criteriaChainField?.isAccessible = true
|
||||
inline infix operator fun invoke(operator: QueryBuilder.() -> Unit): Query = QueryBuilder()(operator)
|
||||
|
||||
inline infix fun queryObject(operator: QueryBuilder.() -> Unit): Document = this(operator).queryObject
|
||||
inline infix fun fieldsObject(operator: QueryBuilder.() -> Unit): Document = this(operator).fieldsObject
|
||||
inline infix fun sortObject(operator: QueryBuilder.() -> Unit): Document = this(operator).sortObject
|
||||
|
||||
inline infix fun criteria(operator: QueryBuilder.() -> Unit): Criteria = QueryBuilder().apply(operator).and
|
||||
}
|
||||
|
||||
inline infix operator fun invoke(operator: QueryBuilder.() -> Unit): Query {
|
||||
this.operator()
|
||||
val query = Query(and)
|
||||
queryHandler.forEach { handler ->
|
||||
query.handler()
|
||||
}
|
||||
|
||||
inline infix operator fun invoke(operator: QueryBuilder.() -> Unit): Query = QueryBuilder().let { builder ->
|
||||
builder.operator()
|
||||
val query = Query(builder.and)
|
||||
builder.queryHandler.forEach { handler ->
|
||||
query.handler()
|
||||
}
|
||||
query
|
||||
}
|
||||
|
||||
infix fun queryObject(operator: QueryBuilder.() -> Unit): Document = this(operator).queryObject
|
||||
infix fun fieldsObject(operator: QueryBuilder.() -> Unit): Document = this(operator).fieldsObject
|
||||
infix fun sortObject(operator: QueryBuilder.() -> Unit): Document = this(operator).sortObject
|
||||
|
||||
infix fun criteria(operator: QueryBuilder.() -> Unit): Criteria = QueryBuilder().apply(operator).and
|
||||
return query
|
||||
}
|
||||
|
||||
val queryHandler = LinkedList<Query.() -> Unit>()
|
||||
@ -65,33 +45,10 @@ class QueryBuilder : MongoName {
|
||||
private val fieldSet = HashSet<String>()
|
||||
|
||||
val and: Criteria
|
||||
get() = when (criteriaList.size) {
|
||||
0 -> Criteria()
|
||||
1 -> criteriaList.first()
|
||||
else -> if (uniqueField && criteriaField != null && isValueField != null) {
|
||||
var base = Criteria()
|
||||
criteriaList.forEach {
|
||||
if (it.key != null) {
|
||||
base = base.and(it.key!!)
|
||||
criteriaField.set(base, criteriaField.get(it))
|
||||
isValueField.set(base, isValueField.get(it))
|
||||
} else {
|
||||
criteriaChainField?.get(base)?.uncheckedCast<MutableList<Any>>()
|
||||
?.addAll(criteriaChainField.get(it).uncheckedCast())
|
||||
}
|
||||
}
|
||||
base
|
||||
} else {
|
||||
Criteria().andOperator(*criteriaList.toTypedArray())
|
||||
}
|
||||
}
|
||||
get() = criteriaList.toAndCriteria(uniqueField)
|
||||
|
||||
val or: Criteria
|
||||
get() = when (criteriaList.size) {
|
||||
0 -> Criteria()
|
||||
1 -> criteriaList.first()
|
||||
else -> Criteria().orOperator(*criteriaList.toTypedArray())
|
||||
}
|
||||
get() = criteriaList.toOrCriteria()
|
||||
|
||||
private val criteriaList = ArrayList<Criteria>()
|
||||
|
||||
@ -103,8 +60,7 @@ class QueryBuilder : MongoName {
|
||||
fun String.asObjectId() = ObjectId(this)
|
||||
|
||||
private fun String.asWhere() = Criteria.where(this).also { uniqueField = uniqueField && fieldSet.add(this) }
|
||||
private fun KProperty<*>.asWhere() =
|
||||
mongoName.asWhere().also { uniqueField = uniqueField && fieldSet.add(mongoName) }
|
||||
private fun KProperty<*>.asWhere() = mongoName.asWhere()
|
||||
|
||||
//infix fun Criteria.or(operator: QueryBuilder.() -> Unit) {
|
||||
// criteriaList.add(QueryBuilder().also(operator).criteria)
|
||||
@ -122,6 +78,12 @@ class QueryBuilder : MongoName {
|
||||
infix fun KProperty<*>.gte(where: Any) = asWhere() gte where // >=
|
||||
fun KProperty<*>.`in`(vararg where: Any?) = asWhere() `in` where // contains
|
||||
infix fun KProperty<*>.`in`(where: Collection<Any?>) = asWhere() `in` (where) // contains
|
||||
|
||||
infix operator fun <T> Collection<T>.contains(p: KProperty<T>): Boolean {
|
||||
p `in` this
|
||||
return true
|
||||
}
|
||||
|
||||
infix fun KProperty<*>.`is`(where: Any?) = asWhere() `is` where // ==
|
||||
infix fun KProperty<*>.ne(where: Any?) = asWhere() ne where // !=
|
||||
infix fun KProperty<*>.lt(where: Any) = asWhere() lt where // <
|
||||
@ -134,7 +96,7 @@ class QueryBuilder : MongoName {
|
||||
infix fun KProperty<*>.size(s: Int) = asWhere() size s
|
||||
infix fun KProperty<*>.exists(b: Boolean) = asWhere() exists b
|
||||
infix fun KProperty<*>.type(t: Int) = asWhere() type t
|
||||
operator fun KProperty<*>.not() = asWhere().not().last(criteriaList::add)
|
||||
operator fun KProperty<*>.not() = asWhere().not().run(criteriaList::add)
|
||||
infix fun KProperty<*>.regex(re: String) = asWhere() regex re
|
||||
infix fun KProperty<*>.regex(pattern: Pattern) = asWhere() regex pattern
|
||||
infix fun KProperty<*>.regex(pattern: Regex) = asWhere() regex pattern
|
||||
@ -157,6 +119,45 @@ class QueryBuilder : MongoName {
|
||||
infix fun KProperty<*>.equal(where: QueryBuilder.() -> Unit) = asWhere() equal QueryBuilder(where).queryObject
|
||||
infix fun KProperty<*>.eq(where: QueryBuilder.() -> Unit) = asWhere() equal QueryBuilder(where).queryObject
|
||||
|
||||
infix fun StringBuilder.gt(where: Any) = toString() gt where // >
|
||||
infix fun StringBuilder.gte(where: Any) = toString() gte where // >=
|
||||
fun StringBuilder.`in`(vararg where: Any?) = toString().`in`(where = where) // contains
|
||||
infix fun StringBuilder.`in`(where: Collection<Any?>) = toString() `in` where // contains
|
||||
infix fun StringBuilder.`is`(where: Any?) = toString() `is` where // ==
|
||||
infix fun StringBuilder.ne(where: Any?) = toString() ne where // !=
|
||||
infix fun StringBuilder.lt(where: Any) = toString() lt where // <
|
||||
infix fun StringBuilder.lte(where: Any) = toString() lte where // <=
|
||||
fun StringBuilder.nin(vararg where: Any?) = toString().nin(where = where) // not contains
|
||||
infix fun StringBuilder.nin(where: Collection<Any?>) = toString() nin where // not contains
|
||||
|
||||
infix fun StringBuilder.all(where: Any?) = toString() all where
|
||||
infix fun StringBuilder.all(where: Collection<Any?>) = toString() all where
|
||||
infix fun StringBuilder.size(s: Int) = toString() size s
|
||||
infix fun StringBuilder.exists(b: Boolean) = toString() exists b
|
||||
infix fun StringBuilder.type(t: Int) = toString() type t
|
||||
operator fun StringBuilder.not() = toString().not()
|
||||
infix fun StringBuilder.regex(re: String) = toString() regex re
|
||||
infix fun StringBuilder.regex(pattern: Pattern) = toString() regex pattern
|
||||
infix fun StringBuilder.regex(pattern: Regex) = toString() regex pattern.toPattern()
|
||||
infix fun StringBuilder.regex(regex: BsonRegularExpression) = toString() regex regex
|
||||
infix fun StringBuilder.withinSphere(circle: Circle) = toString() withinSphere circle
|
||||
infix fun StringBuilder.within(shape: Shape) = toString() within shape
|
||||
infix fun StringBuilder.near(point: Point) = toString() near point
|
||||
infix fun StringBuilder.nearSphere(point: Point) = toString() nearSphere point
|
||||
infix fun StringBuilder.intersects(point: GeoJson<*>) = toString() intersects point
|
||||
infix fun StringBuilder.maxDistance(maxDistance: Double) = toString() maxDistance maxDistance
|
||||
infix fun StringBuilder.minDistance(maxDistance: Double) = toString() minDistance maxDistance
|
||||
infix fun StringBuilder.elemMatch(c: QueryBuilder.() -> Unit) = toString() elemMatch c
|
||||
infix fun StringBuilder.alike(sample: Example<*>) = toString() alike sample
|
||||
infix fun StringBuilder.andDocumentStructureMatches(schema: MongoJsonSchema) =
|
||||
toString() andDocumentStructureMatches schema
|
||||
|
||||
infix fun StringBuilder.equal(where: Any?) = toString() equal where
|
||||
infix fun StringBuilder.eq(where: Any?) = toString() equal where
|
||||
|
||||
infix fun StringBuilder.equal(where: QueryBuilder.() -> Unit) = toString() equal QueryBuilder(where).queryObject
|
||||
infix fun StringBuilder.eq(where: QueryBuilder.() -> Unit) = toString() equal QueryBuilder(where).queryObject
|
||||
|
||||
infix fun String.gt(where: Any) = asWhere() gt where // >
|
||||
infix fun String.gte(where: Any) = asWhere() gte where // >=
|
||||
fun String.`in`(vararg where: Any?) = asWhere() `in` where // contains
|
||||
@ -173,7 +174,7 @@ class QueryBuilder : MongoName {
|
||||
infix fun String.size(s: Int) = asWhere() size s
|
||||
infix fun String.exists(b: Boolean) = asWhere() exists b
|
||||
infix fun String.type(t: Int) = asWhere() type t
|
||||
operator fun String.not() = asWhere().not().last(criteriaList::add)
|
||||
operator fun String.not() = asWhere().not().run(criteriaList::add)
|
||||
infix fun String.regex(re: String) = asWhere() regex re
|
||||
infix fun String.regex(pattern: Pattern) = asWhere() regex pattern
|
||||
infix fun String.regex(pattern: Regex) = asWhere() regex pattern.toPattern()
|
||||
@ -195,46 +196,46 @@ class QueryBuilder : MongoName {
|
||||
infix fun String.equal(where: QueryBuilder.() -> Unit) = asWhere() equal QueryBuilder(where).queryObject
|
||||
infix fun String.eq(where: QueryBuilder.() -> Unit) = asWhere() equal QueryBuilder(where).queryObject
|
||||
|
||||
private infix fun Criteria.gt(where: Any) = gt(where).last(criteriaList::add)
|
||||
private infix fun Criteria.gt(where: Any) = gt(where).run(criteriaList::add)
|
||||
|
||||
private infix fun Criteria.gte(where: Any) = gte(where).last(criteriaList::add)
|
||||
private infix fun Criteria.gte(where: Any) = gte(where).run(criteriaList::add)
|
||||
|
||||
private infix fun Criteria.`in`(where: Array<out Any?>) = `in`(where).last(criteriaList::add)
|
||||
private infix fun Criteria.`in`(where: Collection<Any?>) = `in`(where).last(criteriaList::add)
|
||||
private infix fun Criteria.`in`(where: Array<out Any?>) = `in`(where).run(criteriaList::add)
|
||||
private infix fun Criteria.`in`(where: Collection<Any?>) = `in`(where).run(criteriaList::add)
|
||||
|
||||
private infix fun Criteria.`is`(where: Any?) = `is`(where).last(criteriaList::add)
|
||||
private infix fun Criteria.ne(where: Any?) = ne(where).last(criteriaList::add)
|
||||
private infix fun Criteria.lt(where: Any) = lt(where).last(criteriaList::add)
|
||||
private infix fun Criteria.lte(where: Any) = lte(where).last(criteriaList::add)
|
||||
private infix fun Criteria.nin(where: Array<out Any?>) = nin(where).last(criteriaList::add)
|
||||
private infix fun Criteria.nin(where: Collection<Any?>) = nin(where).last(criteriaList::add)
|
||||
private infix fun Criteria.`is`(where: Any?) = `is`(where).run(criteriaList::add)
|
||||
private infix fun Criteria.ne(where: Any?) = ne(where).run(criteriaList::add)
|
||||
private infix fun Criteria.lt(where: Any) = lt(where).run(criteriaList::add)
|
||||
private infix fun Criteria.lte(where: Any) = lte(where).run(criteriaList::add)
|
||||
private infix fun Criteria.nin(where: Array<out Any?>) = nin(where).run(criteriaList::add)
|
||||
private infix fun Criteria.nin(where: Collection<Any?>) = nin(where).run(criteriaList::add)
|
||||
|
||||
private infix fun Criteria.all(where: Any?) = all(where).last(criteriaList::add)
|
||||
private infix fun Criteria.all(where: Collection<Any?>) = all(where).last(criteriaList::add)
|
||||
private infix fun Criteria.size(s: Int) = size(s).last(criteriaList::add)
|
||||
private infix fun Criteria.exists(b: Boolean) = exists(b).last(criteriaList::add)
|
||||
private infix fun Criteria.type(t: Int) = type(t).last(criteriaList::add)
|
||||
private infix fun Criteria.all(where: Any?) = all(where).run(criteriaList::add)
|
||||
private infix fun Criteria.all(where: Collection<Any?>) = all(where).run(criteriaList::add)
|
||||
private infix fun Criteria.size(s: Int) = size(s).run(criteriaList::add)
|
||||
private infix fun Criteria.exists(b: Boolean) = exists(b).run(criteriaList::add)
|
||||
private infix fun Criteria.type(t: Int) = type(t).run(criteriaList::add)
|
||||
|
||||
//private operator fun Criteria.not() = not().last(criteriaList::add)
|
||||
private infix fun Criteria.regex(re: String) = regex(re).last(criteriaList::add)
|
||||
private infix fun Criteria.regex(pattern: Pattern) = regex(pattern).last(criteriaList::add)
|
||||
private infix fun Criteria.regex(pattern: Regex) = regex(pattern.toPattern()).last(criteriaList::add)
|
||||
private infix fun Criteria.regex(regex: BsonRegularExpression) = regex(regex).last(criteriaList::add)
|
||||
private infix fun Criteria.withinSphere(circle: Circle) = withinSphere(circle).last(criteriaList::add)
|
||||
private infix fun Criteria.within(shape: Shape) = within(shape).last(criteriaList::add)
|
||||
private infix fun Criteria.near(point: Point) = near(point).last(criteriaList::add)
|
||||
private infix fun Criteria.nearSphere(point: Point) = nearSphere(point).last(criteriaList::add)
|
||||
private infix fun Criteria.intersects(point: GeoJson<*>) = intersects(point).last(criteriaList::add)
|
||||
private infix fun Criteria.maxDistance(maxDistance: Double) = maxDistance(maxDistance).last(criteriaList::add)
|
||||
private infix fun Criteria.minDistance(maxDistance: Double) = minDistance(maxDistance).last(criteriaList::add)
|
||||
//private operator fun Criteria.not() = not().run(criteriaList::add)
|
||||
private infix fun Criteria.regex(re: String) = regex(re).run(criteriaList::add)
|
||||
private infix fun Criteria.regex(pattern: Pattern) = regex(pattern).run(criteriaList::add)
|
||||
private infix fun Criteria.regex(pattern: Regex) = regex(pattern.toPattern()).run(criteriaList::add)
|
||||
private infix fun Criteria.regex(regex: BsonRegularExpression) = regex(regex).run(criteriaList::add)
|
||||
private infix fun Criteria.withinSphere(circle: Circle) = withinSphere(circle).run(criteriaList::add)
|
||||
private infix fun Criteria.within(shape: Shape) = within(shape).run(criteriaList::add)
|
||||
private infix fun Criteria.near(point: Point) = near(point).run(criteriaList::add)
|
||||
private infix fun Criteria.nearSphere(point: Point) = nearSphere(point).run(criteriaList::add)
|
||||
private infix fun Criteria.intersects(point: GeoJson<*>) = intersects(point).run(criteriaList::add)
|
||||
private infix fun Criteria.maxDistance(maxDistance: Double) = maxDistance(maxDistance).run(criteriaList::add)
|
||||
private infix fun Criteria.minDistance(maxDistance: Double) = minDistance(maxDistance).run(criteriaList::add)
|
||||
private infix fun Criteria.elemMatch(c: QueryBuilder.() -> Unit) =
|
||||
elemMatch(QueryBuilder criteria c).last(criteriaList::add)
|
||||
elemMatch(QueryBuilder criteria c).run(criteriaList::add)
|
||||
|
||||
private infix fun Criteria.alike(sample: Example<*>) = alike(sample).last(criteriaList::add)
|
||||
private infix fun Criteria.alike(sample: Example<*>) = alike(sample).run(criteriaList::add)
|
||||
private infix fun Criteria.andDocumentStructureMatches(schema: MongoJsonSchema) =
|
||||
andDocumentStructureMatches(schema).last(criteriaList::add)
|
||||
andDocumentStructureMatches(schema).run(criteriaList::add)
|
||||
|
||||
private infix fun Criteria.equal(where: Any?) = `is`(where).last(criteriaList::add)
|
||||
private infix fun Criteria.equal(where: Any?) = `is`(where).run(criteriaList::add)
|
||||
|
||||
/**
|
||||
* 根据 builder 所指定的规则排序
|
||||
@ -244,7 +245,7 @@ class QueryBuilder : MongoName {
|
||||
/**
|
||||
* 取以 field 为基准逆序排序的第一个元素
|
||||
*/
|
||||
infix fun Query.last(field: KProperty<*>) = apply {
|
||||
infix fun Query.run(field: KProperty<*>) = apply {
|
||||
sort { field order Sort.Direction.DESC }
|
||||
limit(1)
|
||||
}
|
||||
@ -297,7 +298,7 @@ class QueryBuilder : MongoName {
|
||||
limit(1)
|
||||
}
|
||||
|
||||
infix fun Query.last(field: String) = apply {
|
||||
infix fun Query.run(field: String) = apply {
|
||||
sort { field order Sort.Direction.DESC }
|
||||
limit(1)
|
||||
}
|
||||
@ -321,11 +322,61 @@ class QueryBuilder : MongoName {
|
||||
limit(1)
|
||||
}
|
||||
|
||||
fun Query.page(page: Long = 0, pageSize: Int = 0, defaultPageSize: Int = 50) {
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val pageSize = if (pageSize > 0) pageSize else defaultPageSize
|
||||
if (page > 1) {
|
||||
skip((page - 1) * pageSize)
|
||||
}
|
||||
limit(pageSize)
|
||||
}
|
||||
|
||||
val Query.fields get() = fields()
|
||||
|
||||
fun Query.include(vararg keys: KProperty<*>): Field = fields.include(keys = keys)
|
||||
fun Query.exclude(vararg keys: KProperty<*>): Field = fields.exclude(keys = keys)
|
||||
fun Query.include(key: KProperty<*>) = fields.include(key.mongoName)
|
||||
fun Query.exclude(key: KProperty<*>) = fields.exclude(key.mongoName)
|
||||
fun Query.slice(key: KProperty<*>, size: Int) = fields.slice(key.mongoName, size)
|
||||
fun Query.slice(key: KProperty<*>, offset: Int, size: Int) = fields.slice(key.mongoName, offset, size)
|
||||
fun Query.position(field: KProperty<*>, value: Int) = fields.position(mongoName(field), value)
|
||||
fun Query.elemMatch(key: KProperty<*>, elemMatchCriteria: Criteria) =
|
||||
fields.elemMatch(key.mongoName, elemMatchCriteria)
|
||||
|
||||
fun Field.include(vararg keys: KProperty<*>): Field {
|
||||
keys.forEach { key ->
|
||||
include(key)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun Field.exclude(vararg keys: KProperty<*>): Field {
|
||||
keys.forEach { key ->
|
||||
exclude(key)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
infix fun Field.include(key: KProperty<*>) = include(key.mongoName)
|
||||
infix fun Field.exclude(key: KProperty<*>) = exclude(key.mongoName)
|
||||
fun Field.slice(key: KProperty<*>, size: Int) = slice(key.mongoName, size)
|
||||
fun Field.slice(key: KProperty<*>, offset: Int, size: Int) = slice(key.mongoName, offset, size)
|
||||
fun Field.elemMatch(key: KProperty<*>, elemMatchCriteria: Criteria) = elemMatch(key.mongoName, elemMatchCriteria)
|
||||
fun Field.position(field: KProperty<*>, value: Int) = position(mongoName(field), value)
|
||||
|
||||
infix fun KProperty<*>.regexIfNotBlank(re: String?) = mongoName regexIfNotEmpty re
|
||||
infix fun String.regexIfNotBlank(re: String?) = if (re != null && re.isNotBlank()) {
|
||||
this regex re
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
infix fun KProperty<*>.regexIfNotEmpty(re: String?) = mongoName regexIfNotEmpty re
|
||||
infix fun String.regexIfNotEmpty(re: String?) = if (re != null && re.isNotBlank()) {
|
||||
this regex re
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
@ -19,11 +19,12 @@ class SortBuilder : MongoName, BsonConverter {
|
||||
|
||||
operator fun invoke(action: SortBuilder.() -> Unit) = this.action()
|
||||
|
||||
infix fun String.order(direction: Sort.Direction): Sort = Sort.by(Sort.Order(direction, this)).apply {
|
||||
infix fun String.order(direction: Sort.Direction) = Sort.by(direction, this).apply {
|
||||
updateSort(this) { this.and(it) }
|
||||
}
|
||||
|
||||
infix fun KProperty<*>.order(direction: Sort.Direction) = mongoName order direction
|
||||
infix fun StringBuilder.order(direction: Sort.Direction) = toString() order direction
|
||||
|
||||
fun by(property: String) = Sort.by(property).apply {
|
||||
updateSort(this) { this.and(it) }
|
||||
@ -38,4 +39,4 @@ class SortBuilder : MongoName, BsonConverter {
|
||||
this.sort = action(this.sort!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.tursom.database.mongodb.spring
|
||||
|
||||
import cn.tursom.core.isNotNullOrEmpty
|
||||
import org.bson.Document
|
||||
import org.springframework.data.mongodb.core.query.Update
|
||||
import kotlin.reflect.KProperty
|
||||
@ -32,6 +33,21 @@ class UpdateBuilder(val update: Update = Update()) : MongoName, BsonConverter {
|
||||
infix fun String.set(value: Any?) = update.set(this, value?.bsonValue())
|
||||
infix fun String.setOnInsert(value: Any?) = update.setOnInsert(this, value?.bsonValue())
|
||||
|
||||
infix fun String.set(value: ConcatBuilder.() -> Unit) =
|
||||
update.set(this, ConcatBuilder(value).toDocument())
|
||||
|
||||
fun String.set(vararg value: Any?) = this set {
|
||||
for (any in value) {
|
||||
+any
|
||||
}
|
||||
}
|
||||
|
||||
fun String.set(value: Iterable<*>) = this set {
|
||||
for (any in value) {
|
||||
+any
|
||||
}
|
||||
}
|
||||
|
||||
fun String.unset() = update.unset(this)
|
||||
infix fun String.inc(inc: Number) = update.inc(this, inc)
|
||||
fun String.inc() = update.inc(this, 1)
|
||||
@ -44,6 +60,8 @@ class UpdateBuilder(val update: Update = Update()) : MongoName, BsonConverter {
|
||||
ReplaceWith("push")
|
||||
)
|
||||
infix fun String.pushAll(values: Array<out Any?>) = update.pushAll(this, values)
|
||||
infix fun String.pushAll(values: List<Any?>) = update.push(this).each(values.toTypedArray())
|
||||
infix fun String.pushAll(values: Sequence<Any?>) = this pushAll values.toList()
|
||||
|
||||
fun String.addToSet() = update.addToSet(this)
|
||||
infix fun String.addToSet(value: Any?) = update.addToSet(this, value?.bsonValue())
|
||||
@ -61,9 +79,75 @@ class UpdateBuilder(val update: Update = Update()) : MongoName, BsonConverter {
|
||||
fun String.bitwise() = update.bitwise(this)
|
||||
fun String.modifies() = update.modifies(this)
|
||||
|
||||
infix fun StringBuilder.set(value: Any?) = update.set(toString(), value?.bsonValue())
|
||||
infix fun StringBuilder.setOnInsert(value: Any?) = update.setOnInsert(toString(), value?.bsonValue())
|
||||
|
||||
infix fun StringBuilder.set(value: ConcatBuilder.() -> Unit) =
|
||||
update.set(toString(), ConcatBuilder(value).toDocument())
|
||||
|
||||
fun StringBuilder.set(vararg value: Any?) = this set {
|
||||
for (any in value) {
|
||||
+any
|
||||
}
|
||||
}
|
||||
|
||||
fun StringBuilder.set(value: Iterable<*>) = this set {
|
||||
for (any in value) {
|
||||
+any
|
||||
}
|
||||
}
|
||||
|
||||
fun StringBuilder.unset() = update.unset(toString())
|
||||
infix fun StringBuilder.inc(inc: Number) = update.inc(toString(), inc)
|
||||
fun StringBuilder.inc() = update.inc(toString(), 1)
|
||||
infix fun StringBuilder.push(value: Any?) = update.push(toString(), value?.bsonValue())
|
||||
fun StringBuilder.push() = update.push(toString())
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
@Deprecated(
|
||||
"as of MongoDB 2.4. Removed in MongoDB 3.6. Use {@link #push(String) \$push \$each} instead.",
|
||||
ReplaceWith("push")
|
||||
)
|
||||
infix fun StringBuilder.pushAll(values: Array<out Any?>) = update.pushAll(toString(), values)
|
||||
infix fun StringBuilder.pushAll(values: List<Any?>) = update.push(toString()).each(values.toTypedArray())
|
||||
infix fun StringBuilder.pushAll(values: Sequence<Any?>) = toString() pushAll values.toList()
|
||||
|
||||
fun StringBuilder.addToSet() = update.addToSet(toString())
|
||||
infix fun StringBuilder.addToSet(value: Any?) = update.addToSet(toString(), value?.bsonValue())
|
||||
infix fun StringBuilder.pop(pos: Update.Position) = update.pop(toString(), pos)
|
||||
infix fun StringBuilder.pull(value: Any?) = update.pull(toString(), value?.bsonValue())
|
||||
infix fun StringBuilder.pull(query: QueryBuilder.() -> Unit) =
|
||||
update.pull(toString(), QueryBuilder queryObject query)
|
||||
|
||||
infix fun StringBuilder.pullAll(values: Array<out Any?>) = update.pullAll(toString(), values)
|
||||
infix fun StringBuilder.pullAll(values: Iterable<Any?>) =
|
||||
update.addMultiFieldOperation("\$pullAll", toString(), values)
|
||||
|
||||
infix fun StringBuilder.rename(newName: String) = update.rename(toString(), newName)
|
||||
fun StringBuilder.currentDate() = update.currentDate(toString())
|
||||
fun StringBuilder.currentTimestamp() = update.currentTimestamp(toString())
|
||||
infix fun StringBuilder.multiply(multiplier: Number) = update.multiply(toString(), multiplier)
|
||||
infix fun StringBuilder.max(value: Any) = update.max(toString(), value.bsonValue())
|
||||
infix fun StringBuilder.min(value: Any) = update.min(toString(), value.bsonValue())
|
||||
fun StringBuilder.bitwise() = update.bitwise(toString())
|
||||
fun StringBuilder.modifies() = update.modifies(toString())
|
||||
|
||||
infix fun <T> KProperty<T?>.set(value: T) = mongoName set value
|
||||
infix fun <T> KProperty<T?>.update(value: T) = mongoName set value
|
||||
infix fun <T> KProperty<T?>.setOnInsert(value: T) = mongoName setOnInsert value
|
||||
infix fun KProperty<*>.set(value: ConcatBuilder.() -> Unit) = mongoName set value
|
||||
fun KProperty<*>.set(vararg value: Any?) = mongoName set {
|
||||
for (any in value) {
|
||||
+any
|
||||
}
|
||||
}
|
||||
|
||||
fun KProperty<*>.set(value: Iterable<*>) = mongoName set {
|
||||
for (any in value) {
|
||||
+any
|
||||
}
|
||||
}
|
||||
|
||||
fun KProperty<*>.unset() = mongoName.unset()
|
||||
infix fun KProperty<*>.inc(inc: Number) = mongoName inc inc
|
||||
fun KProperty<*>.inc() = mongoName inc (1)
|
||||
@ -76,6 +160,8 @@ class UpdateBuilder(val update: Update = Update()) : MongoName, BsonConverter {
|
||||
ReplaceWith("push")
|
||||
)
|
||||
infix fun <T> KProperty<T>.pushAll(values: Array<T>) = mongoName pushAll values
|
||||
inline infix fun <reified T> KProperty<T>.pushAll(values: List<T>) = mongoName.push().each(*values.toTypedArray())
|
||||
inline infix fun <reified T> KProperty<T>.pushAll(values: Sequence<T>) = mongoName pushAll values.toList()
|
||||
|
||||
fun KProperty<*>.addToSet() = mongoName.addToSet()
|
||||
infix fun <T : Any> KProperty<Iterable<T>>.addToSet(value: T) = mongoName addToSet value
|
||||
@ -106,4 +192,31 @@ class UpdateBuilder(val update: Update = Update()) : MongoName, BsonConverter {
|
||||
infix fun KProperty<*>.min(value: Any) = mongoName min value
|
||||
fun KProperty<*>.bitwise() = mongoName.bitwise()
|
||||
fun KProperty<*>.modifies() = mongoName.modifies()
|
||||
|
||||
infix fun KProperty<*>.setIfNotEmpty(value: String?) = mongoName setIfNotEmpty value
|
||||
infix fun String.setIfNotEmpty(value: String?): Update {
|
||||
return if (value.isNotNullOrEmpty()) {
|
||||
update.set(this, value)
|
||||
} else {
|
||||
update
|
||||
}
|
||||
}
|
||||
|
||||
infix fun KProperty<*>.setIfNotBlank(value: String?) = mongoName setIfNotBlank value
|
||||
infix fun String.setIfNotBlank(value: String?): Update {
|
||||
return if (value != null && value.isNotBlank()) {
|
||||
update.set(this, value)
|
||||
} else {
|
||||
update
|
||||
}
|
||||
}
|
||||
|
||||
infix fun KProperty<*>.setIfNotNull(value: Any?) = mongoName setIfNotNull value
|
||||
infix fun String.setIfNotNull(value: Any?): Update {
|
||||
return if (value != null) {
|
||||
this set value
|
||||
} else {
|
||||
update
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,8 @@ import org.bson.conversions.Bson
|
||||
@Suppress("MemberVisibilityCanBePrivate", "unused")
|
||||
class UpdateOption {
|
||||
companion object {
|
||||
operator fun invoke(builder: UpdateOption.() -> Unit): UpdateOptions = UpdateOption().apply(builder).updateOptions
|
||||
inline operator fun invoke(builder: UpdateOption.() -> Unit): UpdateOptions =
|
||||
UpdateOption().apply(builder).updateOptions
|
||||
}
|
||||
|
||||
val updateOptions = UpdateOptions()
|
||||
|
@ -2,77 +2,374 @@
|
||||
|
||||
package cn.tursom.database.mongodb.spring
|
||||
|
||||
import cn.tursom.core.clone.clone
|
||||
import cn.tursom.core.toSetNotNull
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import com.mongodb.client.model.FindOneAndUpdateOptions
|
||||
import com.mongodb.client.result.DeleteResult
|
||||
import com.mongodb.client.result.UpdateResult
|
||||
import org.bson.Document
|
||||
import org.bson.conversions.Bson
|
||||
import org.springframework.data.mongodb.core.FindAndModifyOptions
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationExpression
|
||||
import org.springframework.data.mongodb.core.getCollectionName
|
||||
import org.springframework.data.mongodb.core.query.Criteria
|
||||
import org.springframework.data.mongodb.core.query.Field
|
||||
import org.springframework.data.mongodb.core.query.Query
|
||||
import org.springframework.data.mongodb.core.query.Update
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
internal val criteriaField: java.lang.reflect.Field? = try {
|
||||
val field = Criteria::class.java.getDeclaredField("criteria")
|
||||
field.isAccessible = true
|
||||
field
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
internal val isValueField: java.lang.reflect.Field? = try {
|
||||
val field = Criteria::class.java.getDeclaredField("isValue")
|
||||
field.isAccessible = true
|
||||
field
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
internal val criteriaChainField: java.lang.reflect.Field? = try {
|
||||
val field = Criteria::class.java.getDeclaredField("criteriaChain")
|
||||
field.isAccessible = true
|
||||
field
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
fun List<Criteria>.toAndCriteria(
|
||||
uniqueField: Boolean = toSetNotNull { it.key }.size == size
|
||||
) = when (size) {
|
||||
0 -> Criteria()
|
||||
1 -> first()
|
||||
else -> if (uniqueField && criteriaField != null && isValueField != null) {
|
||||
var base = Criteria()
|
||||
forEach {
|
||||
if (it.key != null) {
|
||||
base = base.and(it.key!!)
|
||||
criteriaField.set(base, criteriaField.get(it))
|
||||
isValueField.set(base, isValueField.get(it))
|
||||
} else {
|
||||
criteriaChainField?.get(base)?.uncheckedCast<MutableList<Any>>()
|
||||
?.addAll(criteriaChainField.get(it).uncheckedCast())
|
||||
}
|
||||
}
|
||||
base
|
||||
} else {
|
||||
Criteria().andOperator(*toTypedArray())
|
||||
}
|
||||
}!!
|
||||
|
||||
fun List<Criteria>.toOrCriteria() = when (size) {
|
||||
0 -> Criteria()
|
||||
1 -> first()
|
||||
else -> Criteria().orOperator(*toTypedArray())
|
||||
}!!
|
||||
|
||||
fun AggregationExpression.toDocument(): Document = toDocument(DirectAggregationOperationContext)
|
||||
|
||||
fun <T : Any> MongoTemplate.read(bson: Bson, type: Class<T>): T = converter.read(type, bson)
|
||||
inline fun <reified T : Any> MongoTemplate.read(bson: Bson): T = read(bson, T::class.java)
|
||||
|
||||
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
|
||||
fun <T : Any> MongoTemplate.readNullable(bson: Bson?, type: Class<T>): T? = converter.read(type, bson)
|
||||
inline fun <reified T : Any> MongoTemplate.readNullable(bson: Bson?): T? = readNullable(bson, T::class.java)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.count(query: Query) = count(query, T::class.java)
|
||||
inline fun <reified T : Any> MongoTemplate.count(
|
||||
noinline operator: QueryBuilder.() -> Unit,
|
||||
operator: QueryBuilder.() -> Unit,
|
||||
) = count(QueryBuilder(operator), T::class.java)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.count(
|
||||
collectionName: String,
|
||||
operator: QueryBuilder.() -> Unit,
|
||||
) = count(QueryBuilder(operator), T::class.java, collectionName)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.find(query: Query): List<T> = find(query, T::class.java)
|
||||
inline fun <reified T : Any> MongoTemplate.find(
|
||||
noinline operator: QueryBuilder.() -> Unit,
|
||||
operator: QueryBuilder.() -> Unit,
|
||||
): List<T> = find(QueryBuilder(operator), T::class.java)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.find(
|
||||
collectionName: String,
|
||||
operator: QueryBuilder.() -> Unit,
|
||||
): List<T> = find(QueryBuilder(operator), T::class.java, collectionName)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.findOne(query: Query): T? = findOne(query, T::class.java)
|
||||
inline fun <reified T : Any> MongoTemplate.findOne(
|
||||
noinline operator: QueryBuilder.() -> Unit,
|
||||
operator: QueryBuilder.() -> Unit,
|
||||
): T? = findOne(QueryBuilder(operator), T::class.java)
|
||||
|
||||
//inline fun <T, R> T.use(action: (T) -> R): T {
|
||||
// action(this)
|
||||
// return this
|
||||
//}
|
||||
|
||||
inline fun <T, R> T.last(action: (T) -> R) {
|
||||
action(this)
|
||||
}
|
||||
inline fun <reified T : Any> MongoTemplate.findOne(
|
||||
collectionName: String,
|
||||
operator: QueryBuilder.() -> Unit,
|
||||
): T? = findOne(QueryBuilder(operator), T::class.java, collectionName)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.upsert(
|
||||
query: Query,
|
||||
update: Update,
|
||||
): UpdateResult = upsert(query, update, T::class.java)
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = upsert(QueryBuilder(query), UpdateBuilder(update), T::class.java)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.upsert(
|
||||
collectionName: String,
|
||||
query: Query,
|
||||
update: Update,
|
||||
): UpdateResult = upsert(query, update, T::class.java, collectionName)
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = upsert(QueryBuilder(query), UpdateBuilder(update), T::class.java, collectionName)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.updateFirst(
|
||||
query: Query,
|
||||
update: Update,
|
||||
): UpdateResult = updateFirst(query, update, T::class.java)
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = updateFirst(QueryBuilder(query), UpdateBuilder(update), T::class.java)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.updateFirst(
|
||||
collectionName: String,
|
||||
query: Query,
|
||||
update: Update,
|
||||
): UpdateResult = updateFirst(query, update, T::class.java, collectionName)
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = updateFirst(QueryBuilder(query), UpdateBuilder(update), T::class.java, collectionName)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.updateFirst(
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
options: UpdateOption.() -> Unit,
|
||||
): UpdateResult = updateFirst<T>(getCollectionName(T::class.java), query, update, options)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.updateFirst(
|
||||
collectionName: String,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
options: UpdateOption.() -> Unit,
|
||||
): UpdateResult = db.getCollection(collectionName).updateOne(
|
||||
QueryBuilder queryObject query,
|
||||
UpdateBuilder updateObject update,
|
||||
UpdateOption(options)
|
||||
)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.aggregationUpdateFirst(
|
||||
query: QueryBuilder.() -> Unit,
|
||||
vararg update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = aggregationUpdateFirst<T>(getCollectionName(T::class.java), query, update = update)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.aggregationUpdateFirst(
|
||||
collectionName: String,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
vararg update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = db.getCollection(collectionName).updateOne(
|
||||
QueryBuilder queryObject query,
|
||||
update.map { UpdateBuilder updateObject it },
|
||||
)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.aggregationUpdateFirst(
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = db.getCollection(getCollectionName(T::class.java)).updateOne(
|
||||
QueryBuilder queryObject query,
|
||||
listOf(UpdateBuilder updateObject update)
|
||||
)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.aggregationUpdateFirst(
|
||||
collectionName: String,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = db.getCollection(collectionName).updateOne(
|
||||
QueryBuilder queryObject query,
|
||||
listOf(UpdateBuilder updateObject update)
|
||||
)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.updateMulti(
|
||||
query: Query,
|
||||
update: Update,
|
||||
): UpdateResult = updateMulti(query, update, T::class.java)
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = updateMulti(QueryBuilder(query), UpdateBuilder(update), T::class.java)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.updateMulti(
|
||||
collectionName: String,
|
||||
query: Query,
|
||||
update: Update,
|
||||
): UpdateResult = updateMulti(query, update, T::class.java, collectionName)
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = updateMulti(QueryBuilder(query), UpdateBuilder(update), T::class.java, collectionName)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.updateMulti(
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
options: UpdateOption.() -> Unit,
|
||||
): UpdateResult = updateMulti<T>(getCollectionName(T::class.java), query, update, options)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.updateMulti(
|
||||
collectionName: String,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
options: UpdateOption.() -> Unit,
|
||||
): UpdateResult = db.getCollection(collectionName).updateMany(
|
||||
QueryBuilder queryObject query,
|
||||
UpdateBuilder updateObject update,
|
||||
UpdateOption(options)
|
||||
)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.aggregationUpdateMulti(
|
||||
query: QueryBuilder.() -> Unit,
|
||||
vararg update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = aggregationUpdateMulti<T>(getCollectionName<T>(), query, update = update)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.aggregationUpdateMulti(
|
||||
collectionName: String,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
vararg update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = db.getCollection(collectionName).updateMany(
|
||||
QueryBuilder queryObject query,
|
||||
update.map { UpdateBuilder updateObject it }
|
||||
)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.aggregationUpdateMulti(
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = db.getCollection(getCollectionName(T::class.java)).updateMany(
|
||||
QueryBuilder queryObject query,
|
||||
listOf(UpdateBuilder updateObject update)
|
||||
)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.aggregationUpdateMulti(
|
||||
collectionName: String,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): UpdateResult = db.getCollection(collectionName).updateMany(
|
||||
QueryBuilder queryObject query,
|
||||
listOf(UpdateBuilder updateObject update)
|
||||
)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.findAndModify(
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): T? = findAndModify(QueryBuilder(query), UpdateBuilder(update), T::class.java)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.findAndModify(
|
||||
collectionName: String,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): T? = findAndModify(QueryBuilder(query), UpdateBuilder(update), T::class.java, collectionName)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.findAndModify(
|
||||
collectionName: String,
|
||||
options: FindAndModifyOptions,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): T? = findAndModify(QueryBuilder(query), UpdateBuilder(update), options, T::class.java, collectionName)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.findAndModify(
|
||||
collectionName: String,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
options: FindAndModifyOptions.() -> Unit,
|
||||
): T? = findAndModify(
|
||||
QueryBuilder(query),
|
||||
UpdateBuilder(update),
|
||||
FindAndModifyOptions().apply(options),
|
||||
T::class.java,
|
||||
collectionName
|
||||
)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.findAndModify(
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
options: FindAndModifyOptions.() -> Unit,
|
||||
): T? = findAndModify(
|
||||
QueryBuilder(query),
|
||||
UpdateBuilder(update),
|
||||
FindAndModifyOptions().apply(options),
|
||||
T::class.java,
|
||||
getCollectionName(T::class.java)
|
||||
)
|
||||
|
||||
/**
|
||||
* 提供 spring data mongo 无法提供的某些功能,比如 arrayFilter
|
||||
*/
|
||||
inline fun <reified T : Any> MongoTemplate.findOneAndUpdate(
|
||||
collectionName: String,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
updateOption: FindOneAndUpdateOptions.() -> Unit,
|
||||
): T? = readNullable(
|
||||
db.getCollection(collectionName).findOneAndUpdate(
|
||||
QueryBuilder queryObject query,
|
||||
UpdateBuilder updateObject update,
|
||||
FindOneAndUpdateOptions().also(updateOption)
|
||||
)
|
||||
)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.findOneAndUpdate(
|
||||
collectionName: String,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
vararg update: UpdateBuilder.() -> Unit,
|
||||
updateOption: FindOneAndUpdateOptions.() -> Unit,
|
||||
): T? = readNullable(
|
||||
db.getCollection(collectionName).findOneAndUpdate(
|
||||
QueryBuilder queryObject query,
|
||||
update.map { UpdateBuilder updateObject it },
|
||||
FindOneAndUpdateOptions().also(updateOption)
|
||||
)
|
||||
)
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.aggregationFindAndModify(
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): T? = db.getCollection(getCollectionName(T::class.java)).findOneAndUpdate(
|
||||
QueryBuilder queryObject query,
|
||||
listOf(UpdateBuilder updateObject update)
|
||||
)?.clone()
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.aggregationFindAndModify(
|
||||
collectionName: String,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): T? = db.getCollection(collectionName).findOneAndUpdate(
|
||||
QueryBuilder queryObject query,
|
||||
listOf(UpdateBuilder updateObject update)
|
||||
)?.clone()
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.aggregationFindAndModify(
|
||||
collectionName: String,
|
||||
options: FindOneAndUpdateOptions,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
): T? = db.getCollection(collectionName).findOneAndUpdate(
|
||||
QueryBuilder queryObject query,
|
||||
listOf(UpdateBuilder updateObject update),
|
||||
options
|
||||
)?.clone()
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.aggregationFindAndModify(
|
||||
collectionName: String,
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
options: FindOneAndUpdateOptions.() -> Unit,
|
||||
): T? = db.getCollection(collectionName).findOneAndUpdate(
|
||||
QueryBuilder queryObject query,
|
||||
listOf(UpdateBuilder updateObject update),
|
||||
FindOneAndUpdateOptions().apply(options)
|
||||
)?.clone()
|
||||
|
||||
inline fun <reified T : Any> MongoTemplate.aggregationFindAndModify(
|
||||
query: QueryBuilder.() -> Unit,
|
||||
update: UpdateBuilder.() -> Unit,
|
||||
options: FindOneAndUpdateOptions.() -> Unit,
|
||||
): T? = db.getCollection(getCollectionName(T::class.java)).findOneAndUpdate(
|
||||
QueryBuilder queryObject query,
|
||||
listOf(UpdateBuilder updateObject update),
|
||||
FindOneAndUpdateOptions().apply(options)
|
||||
)?.clone()
|
||||
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
inline fun <reified T : Any> MongoTemplate.remove(
|
||||
queryBuilder: QueryBuilder.() -> Unit,
|
||||
): DeleteResult = remove(QueryBuilder(queryBuilder), T::class.java)
|
||||
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
fun MongoTemplate.remove(
|
||||
collectionName: String,
|
||||
queryBuilder: QueryBuilder.() -> Unit,
|
||||
): DeleteResult = remove(QueryBuilder(queryBuilder), collectionName)
|
||||
|
||||
infix fun Query.sort(builder: SortBuilder.() -> Unit) {
|
||||
with(SortBuilder(builder))
|
||||
}
|
||||
@ -84,4 +381,4 @@ fun Field.slice(key: KProperty<*>, offset: Int, size: Int) = slice(MongoName.mon
|
||||
fun Field.elemMatch(key: KProperty<*>, elemMatchCriteria: Criteria) =
|
||||
elemMatch(MongoName.mongoName(key), elemMatchCriteria)
|
||||
|
||||
fun Field.position(field: KProperty<*>, value: Int) = position(MongoName.mongoName(field), value)
|
||||
fun Field.position(field: KProperty<*>, value: Int) = position(MongoName.mongoName(field), value)
|
||||
|
@ -1,10 +1,23 @@
|
||||
package cn.tursom.database.mongodb.spring
|
||||
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
|
||||
class UpdateBuilderTest {
|
||||
data class Test(val a: String, val b: Int)
|
||||
|
||||
private lateinit var mongoTemplate: MongoTemplate
|
||||
|
||||
@org.junit.Test
|
||||
fun testPush() {
|
||||
mongoTemplate.updateMulti<Test>({
|
||||
or {
|
||||
Test::b eq 1
|
||||
Test::b eq 2
|
||||
}
|
||||
}) {
|
||||
Test::a push Test("a", 1)
|
||||
Test::b set 1
|
||||
}
|
||||
println(UpdateBuilder {
|
||||
Test::a push Test("a", 1)
|
||||
Test::b set 1
|
||||
|
Loading…
Reference in New Issue
Block a user