package entity import ( "encoding/json" "fmt" "time" "go.mongodb.org/mongo-driver/bson" ) const ( Name = "_id" JSONName = "name" Relationship = "relationship" Type = "type" Title = "title" Text = "text" Modified = "modified" Connections = "connections" Attachments = "attachments" ) type One struct { Name string `bson:"_id,omitempty" json:"name,omitempty"` Type string `bson:"type,omitempty" json:"type,omitempty"` Title string `bson:"title,omitempty" json:"title,omitempty"` Text string `bson:"text,omitempty" json:"text,omitempty"` Relationship string `bson:"relationship,omitempty" json:"relationship,omitempty"` Modified int64 `bson:"modified,omitempty" json:"modified,omitempty"` Connections map[string]One `bson:"connections,omitempty" json:"connections,omitempty"` Attachments map[string]string `bson:"attachments,omitempty" json:"attachments,omitempty"` } func (o One) Query() One { return One{Name: o.Name} } func (o One) Peer() One { return One{ Name: o.Name, Type: o.Type, Title: o.Title, Relationship: o.Relationship, Modified: o.Modified, } } func (o One) Peers() []string { names := make([]string, len(o.Connections)) i := 0 for k := range o.Connections { names[i] = o.Connections[k].Name i += 1 } return names } func (o One) MarshalBSON() ([]byte, error) { isMin := fmt.Sprint(o) == fmt.Sprint(o.Query()) if !isMin { o.Modified = time.Now().UnixNano() } b, err := json.Marshal(o) if err != nil { return nil, err } m := bson.M{} if err := json.Unmarshal(b, &m); err != nil { return nil, err } if name, ok := m[JSONName]; ok { m[Name] = name delete(m, JSONName) } if !isMin { connections := map[string]interface{}{} switch m[Connections].(type) { case nil: case map[string]interface{}: connections = m[Connections].(map[string]interface{}) default: return nil, fmt.Errorf("bad connections type %T", m[Connections]) } for k := range connections { b, err := bson.Marshal(o.Connections[k]) if err != nil { return nil, err } m := bson.M{} if err := bson.Unmarshal(b, &m); err != nil { return nil, err } connections[k] = m } m[Connections] = connections } return bson.Marshal(m) }