package entity import ( "encoding/json" "fmt" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) const ( Name = "_id" JSONName = "name" Relationship = "relationship" Type = "type" Title = "title" Image = "image" Text = "text" Modified = "modified" Connections = "connections" ) 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"` Image string `bson:"image,omitempty" json:"image,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 []One `bson:"connections,omitempty" json:"connections,omitempty"` } func (o One) Query() One { return One{Name: o.Name} } func (o One) Peers() []string { names := make([]string, len(o.Connections)) for i := range o.Connections { names[i] = o.Connections[i].Name } return names } func (o One) MarshalBSON() ([]byte, error) { if fmt.Sprint(o) != fmt.Sprint(o.Query()) { 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) } var connections primitive.A switch m[Connections].(type) { case nil: case []interface{}: connections = primitive.A(m[Connections].([]interface{})) case primitive.A: connections = m[Connections].(primitive.A) default: return nil, fmt.Errorf("bad type for %q: %T", Connections, m[Connections]) } curL := len(connections) wantL := len(o.Connections) for i := curL; i < wantL; i++ { connections = append(connections, nil) } for i, connection := range o.Connections { b, err := bson.Marshal(connection) if err != nil { return nil, err } m := bson.M{} if err := bson.Unmarshal(b, &m); err != nil { return nil, err } connections[i] = m } m[Connections] = connections return bson.Marshal(m) }