in oplog/oplog.go [315:385]
func BuildUpdateDelteOplog(prefixField string, obj bson.D) (interface{}, error) {
var result bson.D
for _, ele := range obj {
if ele.Key == "d" {
result = append(result, primitive.E{
Key: "$unset",
Value: combinePrefixField(prefixField, ele.Value)})
} else if ele.Key == "i" || ele.Key == "u" {
result = append(result, primitive.E{
Key: "$set",
Value: combinePrefixField(prefixField, ele.Value)})
} else if len(ele.Key) > 1 && ele.Key[0] == 's' {
// s means subgroup field(array or nest)
tmpPrefixField := ""
if len(prefixField) == 0 {
tmpPrefixField = ele.Key[1:]
} else {
tmpPrefixField = prefixField + "." + ele.Key[1:]
}
nestObj, err := BuildUpdateDelteOplog(tmpPrefixField, ele.Value.(bson.D))
if err != nil {
return obj, fmt.Errorf("parse ele[%v] failed, updateObj:[%v]", ele, obj)
}
if _, ok := nestObj.(mongo.Pipeline); ok {
return nestObj, nil
} else if _, ok := nestObj.(bson.D); ok {
for _, nestObjEle := range nestObj.(bson.D) {
result = append(result, nestObjEle)
}
} else {
return obj, fmt.Errorf("unknown nest type ele[%v] updateObj:[%v] nestObj[%v]", ele, obj, nestObj)
}
} else if len(ele.Key) > 1 && ele.Key[0] == 'u' {
result = append(result, primitive.E{
Key: "$set",
Value: bson.D{
primitive.E{
Key: prefixField + "." + ele.Key[1:],
Value: ele.Value,
},
},
})
} else if ele.Key == "l" {
if len(result) != 0 {
return obj, fmt.Errorf("len should be 0, Key[%v] updateObj:[%v], result:[%v]",
ele, obj, result)
}
return mongo.Pipeline{
{{"$set", bson.D{
{prefixField, bson.D{
{"$slice", []interface{}{"$" + prefixField, ele.Value}},
}},
}}},
}, nil
} else if ele.Key == "a" && ele.Value == true {
continue
} else {
return obj, fmt.Errorf("unknow Key[%v] updateObj:[%v]", ele, obj)
}
}
return result, nil
}