package operator import ( "fmt" "local/dndex/storage/entity" "time" "go.mongodb.org/mongo-driver/bson" ) type Unset string func (u Unset) MarshalBSON() ([]byte, error) { return opMarshal("$unset", string(u), "") } type PopIf struct { Key string Filter interface{} } func (pi PopIf) MarshalBSON() ([]byte, error) { return opMarshal("$pull", pi.Key, pi.Filter) } type SetMany struct { Value interface{} } func (s SetMany) MarshalBSON() ([]byte, error) { return opMarshal("$set", "", s.Value) } type Set struct { Key string Value interface{} } func (s Set) MarshalBSON() ([]byte, error) { return opMarshal("$set", s.Key, s.Value) } type Push struct { Key string Value interface{} } func (p Push) MarshalBSON() ([]byte, error) { return opMarshal("$push", p.Key, p.Value) } func opMarshal(op, key string, value interface{}) ([]byte, error) { marshalable := opMarshalable(op, key, value) if len(marshalable) == 0 { return nil, fmt.Errorf("failed marshalling op") } return bson.Marshal(marshalable) } func opMarshalable(op, key string, value interface{}) map[string]interface{} { if len(key) == 0 && value == nil { return nil } m := map[string]interface{}{ op: map[string]interface{}{ key: value, }, } if len(key) == 0 { m[op] = value } if _, ok := m["$set"]; !ok { m["$set"] = map[string]interface{}{} } switch m["$set"].(type) { case map[string]interface{}: m["$set"].(map[string]interface{})[entity.Modified] = time.Now().UnixNano() case bson.M: m["$set"].(bson.M)[entity.Modified] = time.Now().UnixNano() } return m }