mirror of
https://github.com/tursom/TursomServer.git
synced 2025-01-01 07:50:47 +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
|
||||
|
||||
interface MongoTemplate<T> {
|
||||
fun save(entity: T)
|
||||
}
|
||||
import cn.tursom.core.cast
|
||||
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)
|
||||
@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