-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathinfo.go
119 lines (109 loc) · 2.79 KB
/
info.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package buckets
import (
"context"
"fmt"
"time"
"github.com/ipfs/interface-go-ipfs-core/path"
"github.com/textileio/go-buckets/collection"
"github.com/textileio/go-threads/core/did"
core "github.com/textileio/go-threads/core/thread"
)
// PushPathInfo pushes arbitrary info/metadata to a path,
// allowing users to add application specific path metadata.
func (b *Buckets) PushPathInfo(
ctx context.Context,
thread core.ID,
key string,
identity did.Token,
root path.Resolved,
pth string,
info map[string]interface{},
) (*Bucket, error) {
txn, err := b.NewTxn(thread, key, identity)
if err != nil {
return nil, err
}
defer txn.Close()
return txn.PushPathInfo(ctx, root, pth, info)
}
// PushPathInfo is Txn based PushPathInfo.
func (t *Txn) PushPathInfo(
ctx context.Context,
root path.Resolved,
pth string,
info map[string]interface{},
) (*Bucket, error) {
pth, err := parsePath(pth)
if err != nil {
return nil, err
}
instance, err := t.b.c.GetSafe(ctx, t.thread, t.key, collection.WithIdentity(t.identity))
if err != nil {
return nil, err
}
if root != nil && root.String() != instance.Path {
return nil, ErrNonFastForward
}
md, mdPath, ok := instance.GetMetadataForPath(pth, false)
if !ok {
return nil, fmt.Errorf("could not resolve path: %s", pth)
}
var target collection.Metadata
if mdPath != pth { // If the metadata is inherited from a parent, create a new entry
target = collection.Metadata{
Info: make(map[string]interface{}),
}
} else {
target = md
}
if target.Info == nil {
target.Info = make(map[string]interface{})
}
var changed bool
for k, v := range info {
if x, ok := target.Info[k]; ok && x == v {
continue
}
target.Info[k] = v
changed = true
}
if changed {
instance.UpdatedAt = time.Now().UnixNano()
target.UpdatedAt = instance.UpdatedAt
instance.Metadata[pth] = target
if err := t.b.c.Save(ctx, t.thread, instance, collection.WithIdentity(t.identity)); err != nil {
return nil, err
}
}
log.Debugf("pushed info for %s in %s", pth, t.key)
return instanceToBucket(t.thread, instance), nil
}
// PullPathInfo pulls all info at a path.
func (b *Buckets) PullPathInfo(
ctx context.Context,
thread core.ID,
key string,
identity did.Token,
pth string,
) (map[string]interface{}, error) {
if err := thread.Validate(); err != nil {
return nil, fmt.Errorf("invalid thread id: %v", err)
}
pth, err := parsePath(pth)
if err != nil {
return nil, err
}
instance, err := b.c.GetSafe(ctx, thread, key, collection.WithIdentity(identity))
if err != nil {
return nil, err
}
md, _, ok := instance.GetMetadataForPath(pth, false)
if !ok {
return nil, fmt.Errorf("could not resolve path: %s", pth)
}
if md.Info == nil {
md.Info = make(map[string]interface{})
}
log.Debugf("pulled info for %s in %s", pth, key)
return md.Info, nil
}