/
gus.go
59 lines (51 loc) · 1.65 KB
/
gus.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
package gus
import(
`github.com/0xor1/sus`
`github.com/qedus/nds`
`golang.org/x/net/context`
`google.golang.org/appengine/datastore`
)
// Creates and configures a store that stores entities in Google AppEngines memcache and datastore.
// github.com/qedus/nds is used for strongly consistent automatic caching.
func NewGaeStore(kind string, ctx context.Context, idf sus.IdFactory, vf sus.VersionFactory, ei sus.EntityInitializer) sus.Store {
getKey := func(ctx context.Context, id string) *datastore.Key {
return datastore.NewKey(ctx, kind, id, 0, nil)
}
getMulti := func(ids []string) (vs []sus.Version, err error) {
count := len(ids)
vs = make([]sus.Version, count, count)
ks := make([]*datastore.Key, count, count)
for i := 0; i < count; i++ {
vs[i] = vf()
ks[i] = getKey(ctx, ids[i])
}
err = nds.GetMulti(ctx, ks, vs)
return
}
putMulti := func(ids []string, vs []sus.Version) (err error) {
count := len(ids)
ks := make([]*datastore.Key, count, count)
for i := 0; i < count; i++ {
ks[i] = getKey(ctx, ids[i])
}
_, err = nds.PutMulti(ctx, ks, vs)
return
}
delMulti := func(ids []string) error {
count := len(ids)
ks := make([]*datastore.Key, count, count)
for i := 0; i < count; i++ {
ks[i] = getKey(ctx, ids[i])
}
return nds.DeleteMulti(ctx, ks)
}
isNonExtantError := func(err error) bool {
return err.Error() == datastore.ErrNoSuchEntity.Error()
}
rit := func(tran sus.Transaction) error {
return nds.RunInTransaction(ctx, func(ctx context.Context)error{
return tran()
}, &datastore.TransactionOptions{XG:true})
}
return sus.NewStore(getMulti, putMulti, delMulti, idf, vf, ei, isNonExtantError, rit)
}