OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package prod | 5 package prod |
6 | 6 |
7 import ( | 7 import ( |
8 rds "github.com/luci/gae/service/rawdatastore" | 8 rds "github.com/luci/gae/service/rawdatastore" |
9 "github.com/luci/luci-go/common/errors" | |
10 "golang.org/x/net/context" | 9 "golang.org/x/net/context" |
10 "google.golang.org/appengine" | |
11 "google.golang.org/appengine/datastore" | 11 "google.golang.org/appengine/datastore" |
12 ) | 12 ) |
13 | 13 |
14 // useRDS adds a gae.RawDatastore implementation to context, accessible | 14 // useRDS adds a gae.RawDatastore implementation to context, accessible |
15 // by gae.GetDS(c) | 15 // by gae.GetDS(c) |
16 func useRDS(c context.Context) context.Context { | 16 func useRDS(c context.Context) context.Context { |
17 return rds.SetFactory(c, func(ci context.Context) rds.Interface { | 17 return rds.SetFactory(c, func(ci context.Context) rds.Interface { |
18 » » return rdsImpl{ci} | 18 » » // TODO(riannucci): Track namespace in a better way |
19 » » k := datastore.NewKey(ci, "kind", "", 1, nil) // get current nam espace. | |
20 » » return rdsImpl{ci, k.Namespace()} | |
19 }) | 21 }) |
20 } | 22 } |
21 | 23 |
22 ////////// Query | 24 ////////// Query |
23 | 25 |
24 type queryImpl struct{ *datastore.Query } | 26 type queryImpl struct{ *datastore.Query } |
25 | 27 |
26 func (q queryImpl) Distinct() rds.Query { | 28 func (q queryImpl) Distinct() rds.Query { |
27 return queryImpl{q.Query.Distinct()} | 29 return queryImpl{q.Query.Distinct()} |
28 } | 30 } |
(...skipping 21 matching lines...) Expand all Loading... | |
50 func (q queryImpl) Ancestor(ancestor rds.Key) rds.Query { | 52 func (q queryImpl) Ancestor(ancestor rds.Key) rds.Query { |
51 return queryImpl{q.Query.Ancestor(dsF2R(ancestor))} | 53 return queryImpl{q.Query.Ancestor(dsF2R(ancestor))} |
52 } | 54 } |
53 func (q queryImpl) Project(fieldNames ...string) rds.Query { | 55 func (q queryImpl) Project(fieldNames ...string) rds.Query { |
54 return queryImpl{q.Query.Project(fieldNames...)} | 56 return queryImpl{q.Query.Project(fieldNames...)} |
55 } | 57 } |
56 func (q queryImpl) Filter(filterStr string, value interface{}) rds.Query { | 58 func (q queryImpl) Filter(filterStr string, value interface{}) rds.Query { |
57 return queryImpl{q.Query.Filter(filterStr, value)} | 59 return queryImpl{q.Query.Filter(filterStr, value)} |
58 } | 60 } |
59 | 61 |
60 ////////// Iterator | |
61 | |
62 type iteratorImpl struct{ *datastore.Iterator } | |
63 | |
64 var _ rds.Iterator = iteratorImpl{} | |
65 | |
66 func (i iteratorImpl) Cursor() (rds.Cursor, error) { | |
67 return i.Iterator.Cursor() | |
68 } | |
69 | |
70 func (i iteratorImpl) Next(pls rds.PropertyLoadSaver) (rds.Key, error) { | |
71 return dsR2FErr(i.Iterator.Next(&typeFilter{pls})) | |
72 } | |
73 | |
74 ////////// Datastore | 62 ////////// Datastore |
75 | 63 |
76 type rdsImpl struct{ context.Context } | 64 type rdsImpl struct { |
65 » context.Context | |
77 | 66 |
78 // NewKeyer | 67 » ns string |
68 } | |
69 | |
79 func (d rdsImpl) NewKey(kind, stringID string, intID int64, parent rds.Key) rds. Key { | 70 func (d rdsImpl) NewKey(kind, stringID string, intID int64, parent rds.Key) rds. Key { |
80 return dsR2F(datastore.NewKey(d, kind, stringID, intID, dsF2R(parent))) | 71 return dsR2F(datastore.NewKey(d, kind, stringID, intID, dsF2R(parent))) |
81 } | 72 } |
82 | 73 |
83 func (rdsImpl) DecodeKey(encoded string) (rds.Key, error) { | 74 func (rdsImpl) DecodeKey(encoded string) (rds.Key, error) { |
84 » return dsR2FErr(datastore.DecodeKey(encoded)) | 75 » k, err := datastore.DecodeKey(encoded) |
76 » return dsR2F(k), err | |
85 } | 77 } |
86 | 78 |
87 func multiWrap(os []rds.PropertyLoadSaver) []datastore.PropertyLoadSaver { | 79 func idxCallbacker(err error, amt int, cb func(idx int, err error)) error { |
88 » ret := make([]datastore.PropertyLoadSaver, len(os)) | 80 » if err == nil { |
89 » for i, pls := range os { | 81 » » for i := 0; i < amt; i++ { |
90 » » ret[i] = &typeFilter{pls} | 82 » » » cb(i, nil) |
83 » » } | |
84 » } else { | |
dnj (Google)
2015/07/29 01:44:59
Remove "else" clause, return nil at the end of the
iannucci
2015/07/29 07:35:48
Done.
| |
85 » » if me, ok := err.(appengine.MultiError); ok { | |
86 » » » for i, err := range me { | |
87 » » » » cb(i, err) | |
88 » » » } | |
89 » » } else { | |
90 » » » return err | |
91 » » } | |
91 } | 92 } |
92 » return ret | 93 » return nil |
93 } | 94 } |
94 | 95 |
95 func (d rdsImpl) Delete(k rds.Key) error { return datastore.Delete(d, dsF2R(k)) } | 96 func (d rdsImpl) DeleteMulti(ks []rds.Key, cb rds.DeleteMultiCB) error { |
96 func (d rdsImpl) Get(key rds.Key, dst rds.PropertyLoadSaver) error { | 97 » err := datastore.DeleteMulti(d, dsMF2R(ks)) |
97 » return datastore.Get(d, dsF2R(key), &typeFilter{dst}) | 98 » return idxCallbacker(err, len(ks), func(_ int, err error) { |
98 } | 99 » » cb(err) |
99 func (d rdsImpl) Put(key rds.Key, src rds.PropertyLoadSaver) (rds.Key, error) { | 100 » }) |
100 » return dsR2FErr(datastore.Put(d, dsF2R(key), &typeFilter{src})) | |
101 } | 101 } |
102 | 102 |
103 func (d rdsImpl) DeleteMulti(ks []rds.Key) error { | 103 func (d rdsImpl) GetMulti(keys []rds.Key, cb rds.GetMultiCB) error { |
104 » return errors.Fix(datastore.DeleteMulti(d, dsMF2R(ks))) | 104 » rkeys := dsMF2R(keys) |
105 » vals := make([]datastore.PropertyLoadSaver, len(keys)) | |
106 » for i := range keys { | |
107 » » vals[i] = &typeFilter{rds.PropertyMap{}} | |
108 » } | |
109 » err := datastore.GetMulti(d, rkeys, vals) | |
110 » return idxCallbacker(err, len(keys), func(idx int, err error) { | |
111 » » cb(vals[idx].(*typeFilter).pm, err) | |
112 » }) | |
105 } | 113 } |
106 | 114 |
107 func (d rdsImpl) GetMulti(ks []rds.Key, plss []rds.PropertyLoadSaver) error { | 115 func (d rdsImpl) PutMulti(keys []rds.Key, vals []rds.PropertyLoadSaver, cb rds.P utMultiCB) error { |
108 » return errors.Fix(datastore.GetMulti(d, dsMF2R(ks), multiWrap(plss))) | 116 » rkeys := dsMF2R(keys) |
109 } | 117 » rvals := make([]datastore.PropertyLoadSaver, len(vals)) |
110 func (d rdsImpl) PutMulti(key []rds.Key, plss []rds.PropertyLoadSaver) ([]rds.Ke y, error) { | 118 » for i, val := range vals { |
111 » ks, err := datastore.PutMulti(d, dsMF2R(key), multiWrap(plss)) | 119 » » rvals[i] = &typeFilter{val.(rds.PropertyMap)} |
112 » return dsMR2F(ks), errors.Fix(err) | 120 » } |
121 » rkeys, err := datastore.PutMulti(d, rkeys, vals) | |
122 » return idxCallbacker(err, len(keys), func(idx int, err error) { | |
123 » » k := rds.Key(nil) | |
124 » » if err == nil { | |
125 » » » k = dsR2F(rkeys[idx]) | |
126 » » } | |
127 » » cb(k, err) | |
128 » }) | |
113 } | 129 } |
114 | 130 |
115 // DSQueryer | |
116 func (d rdsImpl) NewQuery(kind string) rds.Query { | 131 func (d rdsImpl) NewQuery(kind string) rds.Query { |
117 return queryImpl{datastore.NewQuery(kind)} | 132 return queryImpl{datastore.NewQuery(kind)} |
118 } | 133 } |
119 func (d rdsImpl) Run(q rds.Query) rds.Iterator { | 134 |
120 » return iteratorImpl{q.(queryImpl).Query.Run(d)} | 135 func (d rdsImpl) Run(q rds.Query, cb rds.RunCB) error { |
121 } | 136 » keepGoing := true |
122 func (d rdsImpl) Count(q rds.Query) (int, error) { | 137 » tf := typeFilter{} |
123 » return q.(queryImpl).Query.Count(d) | 138 » t := q.(queryImpl).Query.Run(d) |
124 } | 139 » cfunc := func() (rds.Cursor, error) { |
125 func (d rdsImpl) GetAll(q rds.Query, dst *[]rds.PropertyMap) ([]rds.Key, error) { | 140 » » return t.Cursor() |
126 » fakeDst := []datastore.PropertyList(nil) | |
127 » ks, err := q.(queryImpl).GetAll(d, &fakeDst) | |
128 » if err != nil { | |
129 » » return nil, err | |
130 } | 141 } |
131 » *dst = make([]rds.PropertyMap, len(fakeDst)) | 142 » for keepGoing { |
132 » for i, pl := range fakeDst { | 143 » » k, err := t.Next(&tf) |
133 » » (*dst)[i] = rds.PropertyMap{} | 144 » » if err == datastore.Done { |
134 » » if err := (&typeFilter{(*dst)[i]}).Load(pl); err != nil { | 145 » » » return nil |
135 » » » return nil, err | |
136 } | 146 } |
147 if err != nil { | |
148 return err | |
149 } | |
150 keepGoing = cb(dsR2F(k), tf.pm, cfunc) | |
dnj (Google)
2015/07/29 01:44:59
Consider just:
for {
...
if !cb(...) {
re
iannucci
2015/07/29 07:35:48
Done.
| |
137 } | 151 } |
138 » return dsMR2F(ks), err | 152 » return nil |
139 } | 153 } |
140 | 154 |
141 // Transactioner | |
142 func (d rdsImpl) RunInTransaction(f func(c context.Context) error, opts *rds.Tra nsactionOptions) error { | 155 func (d rdsImpl) RunInTransaction(f func(c context.Context) error, opts *rds.Tra nsactionOptions) error { |
143 ropts := (*datastore.TransactionOptions)(opts) | 156 ropts := (*datastore.TransactionOptions)(opts) |
144 return datastore.RunInTransaction(d, f, ropts) | 157 return datastore.RunInTransaction(d, f, ropts) |
145 } | 158 } |
OLD | NEW |