210 lines
4.4 KiB
Go
210 lines
4.4 KiB
Go
package engine
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
"git.kingecg.top/kingecg/gomog/pkg/types"
|
|
)
|
|
|
|
// applyUpdate 应用更新操作到文档数据
|
|
func applyUpdate(data map[string]interface{}, update types.Update) map[string]interface{} {
|
|
// 深拷贝原数据
|
|
result := deepCopyMap(data)
|
|
|
|
// 处理 $set
|
|
for field, value := range update.Set {
|
|
setNestedValue(result, field, value)
|
|
}
|
|
|
|
// 处理 $unset
|
|
for field := range update.Unset {
|
|
removeNestedValue(result, field)
|
|
}
|
|
|
|
// 处理 $inc
|
|
for field, value := range update.Inc {
|
|
incNestedValue(result, field, value)
|
|
}
|
|
|
|
// 处理 $mul
|
|
for field, value := range update.Mul {
|
|
mulNestedValue(result, field, value)
|
|
}
|
|
|
|
// 处理 $push
|
|
for field, value := range update.Push {
|
|
pushNestedValue(result, field, value)
|
|
}
|
|
|
|
// 处理 $pull
|
|
for field, value := range update.Pull {
|
|
pullNestedValue(result, field, value)
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// deepCopyMap 深拷贝 map
|
|
func deepCopyMap(m map[string]interface{}) map[string]interface{} {
|
|
if m == nil {
|
|
return nil
|
|
}
|
|
|
|
result := make(map[string]interface{})
|
|
for k, v := range m {
|
|
switch val := v.(type) {
|
|
case map[string]interface{}:
|
|
result[k] = deepCopyMap(val)
|
|
case []interface{}:
|
|
result[k] = deepCopySlice(val)
|
|
default:
|
|
result[k] = v
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// deepCopySlice 深拷贝 slice
|
|
func deepCopySlice(s []interface{}) []interface{} {
|
|
if s == nil {
|
|
return nil
|
|
}
|
|
|
|
result := make([]interface{}, len(s))
|
|
for i, v := range s {
|
|
switch val := v.(type) {
|
|
case map[string]interface{}:
|
|
result[i] = deepCopyMap(val)
|
|
case []interface{}:
|
|
result[i] = deepCopySlice(val)
|
|
default:
|
|
result[i] = v
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// setNestedValue 设置嵌套字段值
|
|
func setNestedValue(data map[string]interface{}, field string, value interface{}) {
|
|
parts := splitFieldPath(field)
|
|
|
|
current := data
|
|
for i, part := range parts {
|
|
if i == len(parts)-1 {
|
|
// 最后一个部分,设置值
|
|
current[part] = value
|
|
return
|
|
}
|
|
|
|
// 中间部分,确保是 map
|
|
if current[part] == nil {
|
|
current[part] = make(map[string]interface{})
|
|
}
|
|
|
|
if m, ok := current[part].(map[string]interface{}); ok {
|
|
current = m
|
|
} else {
|
|
// 类型不匹配,创建新 map
|
|
newMap := make(map[string]interface{})
|
|
current[part] = newMap
|
|
current = newMap
|
|
}
|
|
}
|
|
}
|
|
|
|
// removeNestedValue 删除嵌套字段
|
|
func removeNestedValue(data map[string]interface{}, field string) {
|
|
parts := splitFieldPath(field)
|
|
|
|
current := data
|
|
for i, part := range parts {
|
|
if i == len(parts)-1 {
|
|
delete(current, part)
|
|
return
|
|
}
|
|
|
|
if m, ok := current[part].(map[string]interface{}); ok {
|
|
current = m
|
|
} else {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// incNestedValue 递增嵌套字段值
|
|
func incNestedValue(data map[string]interface{}, field string, increment interface{}) {
|
|
current := getNestedValue(data, field)
|
|
if current == nil {
|
|
setNestedValue(data, field, increment)
|
|
return
|
|
}
|
|
|
|
newValue := toFloat64(current) + toFloat64(increment)
|
|
setNestedValue(data, field, newValue)
|
|
}
|
|
|
|
// mulNestedValue 乘以嵌套字段值
|
|
func mulNestedValue(data map[string]interface{}, field string, multiplier interface{}) {
|
|
current := getNestedValue(data, field)
|
|
if current == nil {
|
|
return
|
|
}
|
|
|
|
newValue := toFloat64(current) * toFloat64(multiplier)
|
|
setNestedValue(data, field, newValue)
|
|
}
|
|
|
|
// pushNestedValue 推入数组
|
|
func pushNestedValue(data map[string]interface{}, field string, value interface{}) {
|
|
current := getNestedValue(data, field)
|
|
|
|
var arr []interface{}
|
|
if current != nil {
|
|
if a, ok := current.([]interface{}); ok {
|
|
arr = a
|
|
}
|
|
}
|
|
|
|
if arr == nil {
|
|
arr = make([]interface{}, 0)
|
|
}
|
|
|
|
arr = append(arr, value)
|
|
setNestedValue(data, field, arr)
|
|
}
|
|
|
|
// pullNestedValue 从数组中移除
|
|
func pullNestedValue(data map[string]interface{}, field string, value interface{}) {
|
|
current := getNestedValue(data, field)
|
|
if current == nil {
|
|
return
|
|
}
|
|
|
|
arr, ok := current.([]interface{})
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
// 过滤掉匹配的值
|
|
filtered := make([]interface{}, 0, len(arr))
|
|
for _, item := range arr {
|
|
if !compareEq(item, value) {
|
|
filtered = append(filtered, item)
|
|
}
|
|
}
|
|
|
|
setNestedValue(data, field, filtered)
|
|
}
|
|
|
|
// splitFieldPath 分割字段路径(支持 "a.b.c" 格式)
|
|
func splitFieldPath(field string) []string {
|
|
// 简单实现,不考虑转义情况
|
|
return strings.Split(field, ".")
|
|
}
|
|
|
|
// generateID 生成唯一 ID
|
|
func generateID() string {
|
|
return time.Now().Format("20060102150405.000000000")
|
|
}
|