dndex/storage/entity/one.go

115 lines
2.6 KiB
Go

package entity
import (
"encoding/json"
"fmt"
"strings"
"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" 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
}
for k, v := range m {
switch v.(type) {
case string:
m[k] = strings.TrimSpace(v.(string))
}
}
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])
}
delete(connections, "")
for k := range connections {
if k == "" {
continue
}
if o.Connections[k].Name == "" {
p := o.Connections[k]
p.Name = k
o.Connections[k] = p
}
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)
}