Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Side by Side Diff: impl/prod/raw_datastore.go

Issue 1253263002: Make rawdatastore API safer for writing filters. (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: fix comments Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « impl/prod/info.go ('k') | impl/prod/raw_datastore_type_converter.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 » » return nil
91 } 85 }
92 » return ret 86 » me, ok := err.(appengine.MultiError)
87 » if ok {
88 » » for i, err := range me {
89 » » » cb(i, err)
90 » » }
91 » » return nil
92 » }
93 » return err
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 » tf := typeFilter{}
122 func (d rdsImpl) Count(q rds.Query) (int, error) { 137 » t := q.(queryImpl).Query.Run(d)
123 » return q.(queryImpl).Query.Count(d) 138 » cfunc := func() (rds.Cursor, error) {
124 } 139 » » return t.Cursor()
125 func (d rdsImpl) GetAll(q rds.Query, dst *[]rds.PropertyMap) ([]rds.Key, error) {
126 » fakeDst := []datastore.PropertyList(nil)
127 » ks, err := q.(queryImpl).GetAll(d, &fakeDst)
128 » if err != nil {
129 » » return nil, err
130 } 140 }
131 » *dst = make([]rds.PropertyMap, len(fakeDst)) 141 » for {
132 » for i, pl := range fakeDst { 142 » » k, err := t.Next(&tf)
133 » » (*dst)[i] = rds.PropertyMap{} 143 » » if err == datastore.Done {
134 » » if err := (&typeFilter{(*dst)[i]}).Load(pl); err != nil { 144 » » » return nil
135 » » » return nil, err 145 » » }
146 » » if err != nil {
147 » » » return err
148 » » }
149 » » if !cb(dsR2F(k), tf.pm, cfunc) {
150 » » » return nil
136 } 151 }
137 } 152 }
138 return dsMR2F(ks), err
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 }
OLDNEW
« no previous file with comments | « impl/prod/info.go ('k') | impl/prod/raw_datastore_type_converter.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698