Chromium Code Reviews| 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 |