gomog/internal/engine/crud.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")
}