nbcp.myoql.db.mongo.component.MongoUpdateClip.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ktmyoql Show documentation
Show all versions of ktmyoql Show documentation
kotlin orm -- mysql,mongo , just like ktorm
The newest version!
package nbcp.myoql.db.mongo
import nbcp.base.extend.HasValue
import nbcp.base.extend.minus
import nbcp.base.extend.usingScope
import nbcp.myoql.db.comm.DbIncData
import nbcp.myoql.db.db
import nbcp.myoql.db.enums.MyOqlDbScopeEnum
import nbcp.myoql.db.mongo.base.MongoColumnName
import nbcp.myoql.db.mongo.component.MongoBaseMetaCollection
import nbcp.myoql.db.mongo.component.MongoBaseUpdateClip
import nbcp.myoql.db.mongo.logger.logUpdate
import org.bson.Document
import org.slf4j.LoggerFactory
import org.springframework.data.mongodb.core.FindAndModifyOptions
import org.springframework.data.mongodb.core.query.Criteria
import org.springframework.data.mongodb.core.query.Query
import java.time.LocalDateTime
/**
* Created by udi on 17-4-7.
*/
//根据Id,更新Mongo的一个键。
/**
* MongoUpdate
*/
class MongoUpdateClip, E : Any>(var moerEntity: M) :
MongoBaseUpdateClip(moerEntity.tableName) {
companion object {
private val logger = LoggerFactory.getLogger(this::class.java.declaringClass)
}
fun where(whereData: Criteria): MongoUpdateClip {
this.whereData.putAll(whereData.criteriaObject);
return this;
}
fun removeWhereColumn(where: (M) -> MongoColumnName): MongoUpdateClip {
var item = where(moerEntity).toString()
var items = mutableListOf(item);
items.forEach { key ->
this.setData.remove(key);
this.setData.remove(db.mongo.getMongoColumnName(key));
}
return this;
}
fun where(where: (M) -> Criteria): MongoUpdateClip {
this.whereData.putAll(where(moerEntity).criteriaObject);
return this;
}
fun whereOr(vararg wheres: (M) -> Criteria): MongoUpdateClip {
whereOr(*wheres.map { it(moerEntity) }.toTypedArray())
return this;
}
/**
* 对同一个字段多个条件时使用。
*/
fun whereAnd(vararg wheres: (M) -> Criteria): MongoUpdateClip {
whereAnd(*wheres.map { it(moerEntity) }.toTypedArray())
return this;
}
/**
* 如果条件成立,则使用 where
*/
fun whereIf(whereIf: Boolean, where: ((M) -> Criteria)): MongoUpdateClip {
if (whereIf == false) return this;
this.whereData.putAll(where(moerEntity).criteriaObject);
return this;
}
/**
* 如果条件成立,则使用 set
*/
fun setIf(setIf: Boolean, valuePair: (M) -> Pair): MongoUpdateClip {
if (setIf == false) return this;
return set(valuePair);
}
fun set(key: String, value: Any?): MongoUpdateClip {
return set { MongoColumnName(key) to value }
}
fun set(func: (M) -> Pair): MongoUpdateClip {
var p = func(moerEntity);
val key = p.first.toString();
if (key == "id") {
throw RuntimeException("不允许更新 id/_id 列")
} else if (key == "_id") {
throw RuntimeException("不允许更新 id/_id 列")
}
this.setData.put(key, p.second);
return this;
}
fun unset(key: String): MongoUpdateClip {
if (key == "id") {
throw RuntimeException("不允许更新 id/_id 列")
} else if (key == "_id") {
throw RuntimeException("不允许更新 id/_id 列")
}
this.unsetColumns.add(key);
return this;
}
fun unset(keyFunc: (M) -> MongoColumnName): MongoUpdateClip {
return unset(keyFunc(this.moerEntity).toString());
}
/**
* 数据加法
* .inc{ it.incField to 1 }
*/
fun inc(incData: (M) -> DbIncData): MongoUpdateClip {
var kv = incData(this.moerEntity)
var key = kv.column;
if (key == "id") {
throw RuntimeException("不允许更新 id/_id 列")
} else if (key == "_id") {
throw RuntimeException("不允许更新 id/_id 列")
}
this.incData.put(key, kv.incValue);
this.removeWhereColumn { MongoColumnName(key) }
return this;
}
/**
* 向数组中添加一条。
* @param pair:
* key:是实体的属性,内容是数组,如 roles。
* value是要插入实体值。如: UserRole
*/
fun push(pair: (M) -> Pair): MongoUpdateClip {
var pairObject = pair(this.moerEntity);
this.pushData.put(pairObject.first.toString(), pairObject.second);
return this;
}
/**
* 从数组中删除一条。
* key:是实体的属性,内容是数组,如 roles。
* pullWhere 是要删除实体的条件。
* 如:
* .pull( it.menus, "id" mongoEquals "ab")
* .pull( it.roles, "id" mongoEquals "def")
* ==>
* { $pull: { "menus":{"id:"ab"} , "roles":{"id:"def"} } }
*
* @param key , 移除的数组列。
* @param pullWhere , where条件的列,是从 @key 字段开始的列。
*/
fun pull(key: (M) -> MongoColumnName, pullWhere: Criteria): MongoUpdateClip {
this.pullData.put(key(this.moerEntity).toString(), pullWhere);
return this;
}
/**
* 删除数组中的单个值.
* @param pair key=删除的数组列表达式, value=删除该列的值。
* 如:
* .pull( it.menus to "1")
* ==>
* { $pull :{ "menus": "1" } }
*/
fun pull(pair: (M) -> Pair): MongoUpdateClip {
var pairObject = pair(this.moerEntity);
this.pullData.put(pairObject.first.toString(), pairObject.second);
return this;
}
/**
*@param define: 更新的参数,应该使用 Where 表达式子类 Criteria 传递
*/
fun arrayFilter(define: Criteria): MongoUpdateClip {
this.arrayFilters.add(define)
return this;
}
fun saveAndReturnNew(mapFunc: ((Document) -> Unit)? = null): E? {
return saveAndReturnNew(this.moerEntity.entityClass, mapFunc)
}
/**
* 执行更新并返回更新后的数据(适用于更新一条的情况)
*/
fun saveAndReturnNew(type: Class, mapFunc: ((Document) -> Unit)? = null): T? {
db.affectRowCount = -1;
var settingResult = db.mongo.mongoEvents.onUpdating(this)
if (settingResult.any { it.result.result == false }) {
return null;
}
var criteria = db.mongo.getMergedMongoCriteria(whereData);
var update = getUpdateSetSect();
//如果没有要更新的列.
if (update.updateObject.keys.size == 0) {
logger.warn("没有要更新的列,忽略更新!")
return null;
}
var ret = -1;
var startAt = LocalDateTime.now()
var error: Exception? = null
var query = Query.query(criteria)
var resultDocument: Document? = null;
var result: T? = null;
var updateOption = FindAndModifyOptions();
updateOption.returnNew(true)
updateOption.upsert(true);
try {
this.script = getUpdateScript(criteria, update)
resultDocument =
getMongoTemplate(settingResult.lastOrNull { it.result.dataSource.HasValue }?.result?.dataSource)
.findAndModify(
query,
update,
updateOption,
Document::class.java,
actualTableName
);
this.executeTime = LocalDateTime.now() - startAt
if (resultDocument != null) {
result = db.mongo.proc_mongo_doc_to_entity(resultDocument, type, "", mapFunc)
usingScope(
arrayOf(
MyOqlDbScopeEnum.IGNORE_AFFECT_ROW,
MyOqlDbScopeEnum.IGNORE_EXECUTE_TIME,
MyOqlDbScopeEnum.IGNORE_UPDATE_AT
)
) {
settingResult.forEach {
it.event.update(this, it.result)
}
}
}
if (resultDocument != null) {
ret = 1
} else {
ret = 0;
}
this.affectRowCount = ret
} catch (e: Exception) {
error = e;
throw e;
} finally {
logger.logUpdate(error, actualTableName, query, update, null)
}
return result;
}
}