mirror of
https://github.com/tursom/TursomServer.git
synced 2025-01-04 09:20:50 +08:00
impl mongo module
This commit is contained in:
parent
655e698eb2
commit
fc8cd49841
@ -1,16 +0,0 @@
|
|||||||
package cn.tursom.mongodb
|
|
||||||
|
|
||||||
import cn.tursom.mongodb.annotation.Collection
|
|
||||||
import com.mongodb.MongoClient
|
|
||||||
|
|
||||||
interface MongoConnection {
|
|
||||||
val client: MongoClient
|
|
||||||
|
|
||||||
fun <T> createTemplate(clazz: Class<T>): MongoTemplate<T>
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun collectionName(clazz: Class<*>): String {
|
|
||||||
return clazz.getAnnotation(Collection::class.java)?.name ?: clazz.simpleName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,74 @@
|
|||||||
|
package cn.tursom.mongodb
|
||||||
|
|
||||||
|
import cn.tursom.core.isTransient
|
||||||
|
import cn.tursom.mongodb.annotation.Ignore
|
||||||
|
import com.mongodb.client.MongoCollection
|
||||||
|
import com.mongodb.client.MongoDatabase
|
||||||
|
import com.mongodb.client.model.InsertManyOptions
|
||||||
|
import com.mongodb.client.model.InsertOneOptions
|
||||||
|
import com.mongodb.client.model.UpdateOptions
|
||||||
|
import com.mongodb.client.result.UpdateResult
|
||||||
|
import org.bson.Document
|
||||||
|
import org.bson.conversions.Bson
|
||||||
|
import kotlin.reflect.KProperty1
|
||||||
|
|
||||||
|
@Suppress("MemberVisibilityCanBePrivate", "CanBeParameter", "unused")
|
||||||
|
class MongoOperator<T : Any>(
|
||||||
|
val collection: MongoCollection<T>,
|
||||||
|
val clazz: Class<T>
|
||||||
|
) {
|
||||||
|
constructor(clazz: Class<T>, database: MongoDatabase) : this(database.getCollection(MongoUtil.collectionName(clazz), clazz), clazz)
|
||||||
|
|
||||||
|
private val fields = clazz.declaredFields.filter {
|
||||||
|
!it.isTransient() && it.getAnnotation(Ignore::class.java) == null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun save(entity: T, options: InsertOneOptions = InsertOneOptions()) {
|
||||||
|
collection.insertOne(entity, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun save(entities: Collection<T>, options: InsertManyOptions = InsertManyOptions()) {
|
||||||
|
collection.insertMany(when (entities) {
|
||||||
|
is List<T> -> entities
|
||||||
|
else -> entities.toList()
|
||||||
|
}, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun update(update: Bson, where: Bson, options: UpdateOptions = UpdateOptions()): UpdateResult {
|
||||||
|
return collection.updateOne(where, update, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun update(entity: T, where: Bson, options: UpdateOptions = UpdateOptions()): UpdateResult {
|
||||||
|
return update(convertToBson(entity), where, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("SpellCheckingInspection")
|
||||||
|
fun upsert(entity: T, where: Bson, options: UpdateOptions = UpdateOptions()): UpdateResult {
|
||||||
|
return update(entity, where, options.upsert(true))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("SpellCheckingInspection")
|
||||||
|
fun upsert(update: Bson, where: Bson, options: UpdateOptions = UpdateOptions()): UpdateResult {
|
||||||
|
return update(convertToBson(update), where, options.upsert(true))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(field: KProperty1<T, Number>, value: Number, where: Bson, options: UpdateOptions = UpdateOptions()): UpdateResult {
|
||||||
|
return upsert(
|
||||||
|
Update { field inc value },
|
||||||
|
where, options
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun inc(field: KProperty1<T, Number>, where: Bson): UpdateResult {
|
||||||
|
return add(field, 1, where)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun convertToBson(entity: Any): Bson {
|
||||||
|
val bson = Document()
|
||||||
|
fields.forEach {
|
||||||
|
val value = it.get(entity) ?: return@forEach
|
||||||
|
bson[MongoUtil.fieldName(it)] = value
|
||||||
|
}
|
||||||
|
return bson
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,51 @@
|
|||||||
package cn.tursom.mongodb
|
package cn.tursom.mongodb
|
||||||
|
|
||||||
interface MongoTemplate<T> {
|
import cn.tursom.core.cast
|
||||||
fun save(entity: T)
|
import com.mongodb.MongoClient
|
||||||
}
|
import com.mongodb.client.MongoDatabase
|
||||||
|
import com.mongodb.client.model.InsertManyOptions
|
||||||
|
import com.mongodb.client.model.InsertOneOptions
|
||||||
|
import com.mongodb.client.model.UpdateOptions
|
||||||
|
import org.bson.conversions.Bson
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
@Suppress("CanBeParameter", "MemberVisibilityCanBePrivate", "unused")
|
||||||
|
class MongoTemplate(
|
||||||
|
db: String,
|
||||||
|
val host: String = "127.0.0.1",
|
||||||
|
val port: Int = 27017
|
||||||
|
) {
|
||||||
|
val client = MongoClient(host, port)
|
||||||
|
|
||||||
|
val db: MongoDatabase = client.getDatabase(db)
|
||||||
|
|
||||||
|
private val operatorMap = ConcurrentHashMap<Class<*>, MongoOperator<*>>()
|
||||||
|
|
||||||
|
fun <T : Any> save(entity: T, options: InsertOneOptions = InsertOneOptions()) {
|
||||||
|
getCollection(entity.javaClass).save(entity, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : Any> save(entities: Collection<T>, options: InsertManyOptions = InsertManyOptions()) {
|
||||||
|
getCollection<T>().save(entities, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : Any> update(entity: T, where: Bson, options: UpdateOptions = UpdateOptions()) {
|
||||||
|
getCollection(entity.javaClass).update(entity, where, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("SpellCheckingInspection")
|
||||||
|
fun <T : Any> upsert(entity: T, where: Bson, options: UpdateOptions = UpdateOptions()) {
|
||||||
|
getCollection(entity.javaClass).upsert(entity, where, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : Any> getCollection(): MongoOperator<T> = getCollection(T::class.java)
|
||||||
|
|
||||||
|
fun <T : Any> getCollection(clazz: Class<T>): MongoOperator<T> {
|
||||||
|
return operatorMap[clazz]?.cast() ?: run {
|
||||||
|
val operator = MongoOperator(clazz, db)
|
||||||
|
operatorMap[clazz] = operator
|
||||||
|
operator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package cn.tursom.mongodb
|
||||||
|
|
||||||
|
import cn.tursom.core.isTransient
|
||||||
|
import cn.tursom.mongodb.annotation.Collection
|
||||||
|
import cn.tursom.mongodb.annotation.Ignore
|
||||||
|
import org.bson.Document
|
||||||
|
import org.bson.conversions.Bson
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
import kotlin.reflect.full.findAnnotation
|
||||||
|
import kotlin.reflect.jvm.javaField
|
||||||
|
|
||||||
|
object MongoUtil {
|
||||||
|
fun collectionName(clazz: Class<*>): String {
|
||||||
|
return clazz.getAnnotation(Collection::class.java)?.name ?: clazz.simpleName
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fieldName(field: Field): String {
|
||||||
|
return field.getAnnotation(cn.tursom.mongodb.annotation.Field::class.java)?.name ?: field.name
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fieldName(property: KProperty<*>): String {
|
||||||
|
return property.findAnnotation<cn.tursom.mongodb.annotation.Field>()?.name
|
||||||
|
?: property.javaField?.getAnnotation(cn.tursom.mongodb.annotation.Field::class.java)?.name
|
||||||
|
?: property.name
|
||||||
|
}
|
||||||
|
|
||||||
|
fun convertToBson(entity: Any): Bson {
|
||||||
|
val bson = Document()
|
||||||
|
entity.javaClass.declaredFields.filter {
|
||||||
|
!it.isTransient() && it.getAnnotation(Ignore::class.java) == null
|
||||||
|
}.forEach {
|
||||||
|
val value = it.get(entity) ?: return@forEach
|
||||||
|
bson[MongoUtil.fieldName(it)] = value
|
||||||
|
}
|
||||||
|
return bson
|
||||||
|
}
|
||||||
|
}
|
22
database/mongodb/src/main/kotlin/cn/tursom/mongodb/Update.kt
Normal file
22
database/mongodb/src/main/kotlin/cn/tursom/mongodb/Update.kt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package cn.tursom.mongodb
|
||||||
|
|
||||||
|
import com.mongodb.client.model.Updates
|
||||||
|
import org.bson.conversions.Bson
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
object Update {
|
||||||
|
operator fun invoke(action: Update.() -> Bson) = this.action()
|
||||||
|
|
||||||
|
|
||||||
|
infix fun KProperty<*>.set(value: Any): Bson = Updates.set(MongoUtil.fieldName(this), value)
|
||||||
|
fun KProperty<*>.unset(): Bson = Updates.unset(MongoUtil.fieldName(this))
|
||||||
|
fun setOnInsert(value: Bson): Bson = Updates.setOnInsert(value)
|
||||||
|
fun setOnInsert(value: Any): Bson = Updates.setOnInsert(MongoUtil.convertToBson(value))
|
||||||
|
infix fun KProperty<*>.setOnInsert(value: Any): Bson = Updates.setOnInsert(MongoUtil.fieldName(this), value)
|
||||||
|
infix fun KProperty<*>.rename(value: String): Bson = Updates.rename(MongoUtil.fieldName(this), value)
|
||||||
|
infix fun String.rename(value: String): Bson = Updates.rename(this, value)
|
||||||
|
infix fun KProperty<*>.inc(value: Number): Bson = Updates.inc(MongoUtil.fieldName(this), value)
|
||||||
|
infix fun KProperty<*>.mul(value: Number): Bson = Updates.mul(MongoUtil.fieldName(this), value)
|
||||||
|
infix fun KProperty<*>.min(value: Any): Bson = Updates.min(MongoUtil.fieldName(this), value)
|
||||||
|
infix fun KProperty<*>.max(value: Any): Bson = Updates.max(MongoUtil.fieldName(this), value)
|
||||||
|
}
|
44
database/mongodb/src/main/kotlin/cn/tursom/mongodb/Where.kt
Normal file
44
database/mongodb/src/main/kotlin/cn/tursom/mongodb/Where.kt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package cn.tursom.mongodb
|
||||||
|
|
||||||
|
import com.mongodb.client.model.Filters
|
||||||
|
import com.mongodb.client.model.TextSearchOptions
|
||||||
|
import org.bson.BsonType
|
||||||
|
import org.bson.conversions.Bson
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
object Where {
|
||||||
|
operator fun invoke(action: Where.() -> Bson) = this.action()
|
||||||
|
|
||||||
|
infix fun KProperty<*>.eq(value: Any): Bson = Filters.eq(MongoUtil.fieldName(this), value)
|
||||||
|
infix fun KProperty<*>.ne(value: Any): Bson = Filters.ne(MongoUtil.fieldName(this), value)
|
||||||
|
infix fun KProperty<*>.gt(value: Any): Bson = Filters.gt(MongoUtil.fieldName(this), value)
|
||||||
|
infix fun KProperty<*>.lt(value: Any): Bson = Filters.lt(MongoUtil.fieldName(this), value)
|
||||||
|
infix fun KProperty<*>.gte(value: Any): Bson = Filters.gte(MongoUtil.fieldName(this), value)
|
||||||
|
infix fun KProperty<*>.lte(value: Any): Bson = Filters.lte(MongoUtil.fieldName(this), value)
|
||||||
|
fun KProperty<*>.`in`(vararg value: Any): Bson = Filters.`in`(MongoUtil.fieldName(this), *value)
|
||||||
|
fun KProperty<*>.nin(vararg value: Any): Bson = Filters.nin(MongoUtil.fieldName(this), *value)
|
||||||
|
fun KProperty<*>.all(vararg value: Any): Bson = Filters.all(MongoUtil.fieldName(this), *value)
|
||||||
|
fun KProperty<*>.exists(exists: Boolean = true): Bson = Filters.exists(MongoUtil.fieldName(this), exists)
|
||||||
|
|
||||||
|
infix fun KProperty<*>.type(type: String): Bson = Filters.type(MongoUtil.fieldName(this), type)
|
||||||
|
infix fun KProperty<*>.type(type: BsonType): Bson = Filters.type(MongoUtil.fieldName(this), type)
|
||||||
|
fun KProperty<*>.mod(divisor: Long, remainder: Long): Bson = Filters.mod(MongoUtil.fieldName(this), divisor, remainder)
|
||||||
|
infix fun KProperty<*>.regex(regex: String): Bson = Filters.regex(MongoUtil.fieldName(this), regex)
|
||||||
|
infix fun KProperty<*>.regex(regex: Regex): Bson = Filters.regex(MongoUtil.fieldName(this), regex.pattern)
|
||||||
|
fun KProperty<*>.regex(regex: String, option: String): Bson = Filters.regex(MongoUtil.fieldName(this), regex, option)
|
||||||
|
fun KProperty<*>.regex(regex: Regex, option: String): Bson = Filters.regex(MongoUtil.fieldName(this), regex.pattern, option)
|
||||||
|
fun text(search: String): Bson = Filters.text(search)
|
||||||
|
fun text(search: String, option: TextSearchOptions): Bson = Filters.text(search, option)
|
||||||
|
fun where(javaScriptExpression: String): Bson = Filters.where(javaScriptExpression)
|
||||||
|
fun expr(expression: Any): Bson = Filters.expr(expression)
|
||||||
|
|
||||||
|
fun and(vararg bson: Bson): Bson = Filters.and(*bson)
|
||||||
|
infix fun Bson.and(bson: Bson): Bson = Filters.and(this, bson)
|
||||||
|
fun or(vararg bson: Bson): Bson = Filters.or(*bson)
|
||||||
|
infix fun Bson.or(bson: Bson): Bson = Filters.or(this, bson)
|
||||||
|
fun nor(vararg bson: Bson): Bson = Filters.or(*bson)
|
||||||
|
infix fun Bson.nor(bson: Bson): Bson = Filters.nor(this, bson)
|
||||||
|
|
||||||
|
operator fun Bson.not(): Bson = Filters.not(this)
|
||||||
|
}
|
@ -2,4 +2,5 @@ package cn.tursom.mongodb.annotation
|
|||||||
|
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
annotation class Collection(val name: String)
|
annotation class Collection(val name: String)
|
||||||
|
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
package cn.tursom.mongodb.annotation
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)
|
||||||
|
annotation class Field(val name: String)
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
package cn.tursom.mongodb.annotation
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)
|
||||||
|
annotation class Ignore(val name: String)
|
@ -1,21 +0,0 @@
|
|||||||
package cn.tursom.mongodb.impl
|
|
||||||
|
|
||||||
import cn.tursom.mongodb.MongoConnection
|
|
||||||
import cn.tursom.mongodb.MongoTemplate
|
|
||||||
import com.mongodb.MongoClient
|
|
||||||
|
|
||||||
class MongoConnectionImpl(
|
|
||||||
db: String,
|
|
||||||
val host: String = "127.0.0.1",
|
|
||||||
val port: Int = 27017
|
|
||||||
) : MongoConnection {
|
|
||||||
override val client: MongoClient = MongoClient(host, port)
|
|
||||||
|
|
||||||
val db = client.getDatabase(db)
|
|
||||||
|
|
||||||
override fun <T> createTemplate(clazz: Class<T>): MongoTemplate<T> {
|
|
||||||
db.createCollection(MongoConnection.collectionName(clazz))
|
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
package cn.tursom.mongodb.impl
|
|
||||||
|
|
||||||
import cn.tursom.mongodb.MongoTemplate
|
|
||||||
|
|
||||||
class MongoTemplateImpl<T>(
|
|
||||||
|
|
||||||
) : MongoTemplate<T> {
|
|
||||||
override fun save(entity: T) {
|
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user