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 » ds "github.com/luci/gae/service/datastore" |
| 9 » "github.com/luci/gae/service/info" |
9 "golang.org/x/net/context" | 10 "golang.org/x/net/context" |
10 "google.golang.org/appengine" | 11 "google.golang.org/appengine" |
11 "google.golang.org/appengine/datastore" | 12 "google.golang.org/appengine/datastore" |
12 ) | 13 ) |
13 | 14 |
14 // useRDS adds a gae.RawDatastore implementation to context, accessible | 15 // useRDS adds a gae.RawDatastore implementation to context, accessible |
15 // by gae.GetDS(c) | 16 // by gae.GetDS(c) |
16 func useRDS(c context.Context) context.Context { | 17 func useRDS(c context.Context) context.Context { |
17 » return rds.SetFactory(c, func(ci context.Context) rds.Interface { | 18 » return ds.SetRawFactory(c, func(ci context.Context) ds.RawInterface { |
18 » » // TODO(riannucci): Track namespace in a better way | 19 » » return rdsImpl{ci, info.Get(ci).GetNamespace()} |
19 » » k := datastore.NewKey(ci, "kind", "", 1, nil) // get current nam
espace. | |
20 » » return rdsImpl{ci, k.Namespace()} | |
21 }) | 20 }) |
22 } | 21 } |
23 | 22 |
24 ////////// Query | 23 ////////// Query |
25 | 24 |
26 type queryImpl struct{ *datastore.Query } | 25 type queryImpl struct{ *datastore.Query } |
27 | 26 |
28 func (q queryImpl) Distinct() rds.Query { | 27 func (q queryImpl) Distinct() ds.Query { |
29 return queryImpl{q.Query.Distinct()} | 28 return queryImpl{q.Query.Distinct()} |
30 } | 29 } |
31 func (q queryImpl) End(c rds.Cursor) rds.Query { | 30 func (q queryImpl) End(c ds.Cursor) ds.Query { |
32 return queryImpl{q.Query.End(c.(datastore.Cursor))} | 31 return queryImpl{q.Query.End(c.(datastore.Cursor))} |
33 } | 32 } |
34 func (q queryImpl) EventualConsistency() rds.Query { | 33 func (q queryImpl) EventualConsistency() ds.Query { |
35 return queryImpl{q.Query.EventualConsistency()} | 34 return queryImpl{q.Query.EventualConsistency()} |
36 } | 35 } |
37 func (q queryImpl) KeysOnly() rds.Query { | 36 func (q queryImpl) KeysOnly() ds.Query { |
38 return queryImpl{q.Query.KeysOnly()} | 37 return queryImpl{q.Query.KeysOnly()} |
39 } | 38 } |
40 func (q queryImpl) Limit(limit int) rds.Query { | 39 func (q queryImpl) Limit(limit int) ds.Query { |
41 return queryImpl{q.Query.Limit(limit)} | 40 return queryImpl{q.Query.Limit(limit)} |
42 } | 41 } |
43 func (q queryImpl) Offset(offset int) rds.Query { | 42 func (q queryImpl) Offset(offset int) ds.Query { |
44 return queryImpl{q.Query.Offset(offset)} | 43 return queryImpl{q.Query.Offset(offset)} |
45 } | 44 } |
46 func (q queryImpl) Order(fieldName string) rds.Query { | 45 func (q queryImpl) Order(fieldName string) ds.Query { |
47 return queryImpl{q.Query.Order(fieldName)} | 46 return queryImpl{q.Query.Order(fieldName)} |
48 } | 47 } |
49 func (q queryImpl) Start(c rds.Cursor) rds.Query { | 48 func (q queryImpl) Start(c ds.Cursor) ds.Query { |
50 return queryImpl{q.Query.Start(c.(datastore.Cursor))} | 49 return queryImpl{q.Query.Start(c.(datastore.Cursor))} |
51 } | 50 } |
52 func (q queryImpl) Ancestor(ancestor rds.Key) rds.Query { | 51 func (q queryImpl) Ancestor(ancestor ds.Key) ds.Query { |
53 return queryImpl{q.Query.Ancestor(dsF2R(ancestor))} | 52 return queryImpl{q.Query.Ancestor(dsF2R(ancestor))} |
54 } | 53 } |
55 func (q queryImpl) Project(fieldNames ...string) rds.Query { | 54 func (q queryImpl) Project(fieldNames ...string) ds.Query { |
56 return queryImpl{q.Query.Project(fieldNames...)} | 55 return queryImpl{q.Query.Project(fieldNames...)} |
57 } | 56 } |
58 func (q queryImpl) Filter(filterStr string, value interface{}) rds.Query { | 57 func (q queryImpl) Filter(filterStr string, value interface{}) ds.Query { |
59 return queryImpl{q.Query.Filter(filterStr, value)} | 58 return queryImpl{q.Query.Filter(filterStr, value)} |
60 } | 59 } |
61 | 60 |
62 ////////// Datastore | 61 ////////// Datastore |
63 | 62 |
64 type rdsImpl struct { | 63 type rdsImpl struct { |
65 context.Context | 64 context.Context |
66 | 65 |
67 ns string | 66 ns string |
68 } | 67 } |
69 | 68 |
70 func (d rdsImpl) NewKey(kind, stringID string, intID int64, parent rds.Key) rds.
Key { | 69 func (d rdsImpl) NewKey(kind, stringID string, intID int64, parent ds.Key) ds.Ke
y { |
71 return dsR2F(datastore.NewKey(d, kind, stringID, intID, dsF2R(parent))) | 70 return dsR2F(datastore.NewKey(d, kind, stringID, intID, dsF2R(parent))) |
72 } | 71 } |
73 | 72 |
74 func (rdsImpl) DecodeKey(encoded string) (rds.Key, error) { | 73 func (rdsImpl) DecodeKey(encoded string) (ds.Key, error) { |
75 k, err := datastore.DecodeKey(encoded) | 74 k, err := datastore.DecodeKey(encoded) |
76 return dsR2F(k), err | 75 return dsR2F(k), err |
77 } | 76 } |
78 | 77 |
79 func idxCallbacker(err error, amt int, cb func(idx int, err error)) error { | 78 func idxCallbacker(err error, amt int, cb func(idx int, err error)) error { |
80 if err == nil { | 79 if err == nil { |
81 for i := 0; i < amt; i++ { | 80 for i := 0; i < amt; i++ { |
82 cb(i, nil) | 81 cb(i, nil) |
83 } | 82 } |
84 return nil | 83 return nil |
85 } | 84 } |
86 me, ok := err.(appengine.MultiError) | 85 me, ok := err.(appengine.MultiError) |
87 if ok { | 86 if ok { |
88 for i, err := range me { | 87 for i, err := range me { |
89 cb(i, err) | 88 cb(i, err) |
90 } | 89 } |
91 return nil | 90 return nil |
92 } | 91 } |
93 return err | 92 return err |
94 } | 93 } |
95 | 94 |
96 func (d rdsImpl) DeleteMulti(ks []rds.Key, cb rds.DeleteMultiCB) error { | 95 func (d rdsImpl) DeleteMulti(ks []ds.Key, cb ds.DeleteMultiCB) error { |
97 err := datastore.DeleteMulti(d, dsMF2R(ks)) | 96 err := datastore.DeleteMulti(d, dsMF2R(ks)) |
98 return idxCallbacker(err, len(ks), func(_ int, err error) { | 97 return idxCallbacker(err, len(ks), func(_ int, err error) { |
99 cb(err) | 98 cb(err) |
100 }) | 99 }) |
101 } | 100 } |
102 | 101 |
103 func (d rdsImpl) GetMulti(keys []rds.Key, cb rds.GetMultiCB) error { | 102 func (d rdsImpl) GetMulti(keys []ds.Key, cb ds.GetMultiCB) error { |
104 rkeys := dsMF2R(keys) | 103 rkeys := dsMF2R(keys) |
105 vals := make([]datastore.PropertyLoadSaver, len(keys)) | 104 vals := make([]datastore.PropertyLoadSaver, len(keys)) |
106 for i := range keys { | 105 for i := range keys { |
107 » » vals[i] = &typeFilter{rds.PropertyMap{}} | 106 » » vals[i] = &typeFilter{ds.PropertyMap{}} |
108 } | 107 } |
109 err := datastore.GetMulti(d, rkeys, vals) | 108 err := datastore.GetMulti(d, rkeys, vals) |
110 return idxCallbacker(err, len(keys), func(idx int, err error) { | 109 return idxCallbacker(err, len(keys), func(idx int, err error) { |
111 cb(vals[idx].(*typeFilter).pm, err) | 110 cb(vals[idx].(*typeFilter).pm, err) |
112 }) | 111 }) |
113 } | 112 } |
114 | 113 |
115 func (d rdsImpl) PutMulti(keys []rds.Key, vals []rds.PropertyLoadSaver, cb rds.P
utMultiCB) error { | 114 func (d rdsImpl) PutMulti(keys []ds.Key, vals []ds.PropertyMap, cb ds.PutMultiCB
) error { |
116 rkeys := dsMF2R(keys) | 115 rkeys := dsMF2R(keys) |
117 rvals := make([]datastore.PropertyLoadSaver, len(vals)) | 116 rvals := make([]datastore.PropertyLoadSaver, len(vals)) |
118 for i, val := range vals { | 117 for i, val := range vals { |
119 » » rvals[i] = &typeFilter{val.(rds.PropertyMap)} | 118 » » rvals[i] = &typeFilter{val} |
120 } | 119 } |
121 rkeys, err := datastore.PutMulti(d, rkeys, vals) | 120 rkeys, err := datastore.PutMulti(d, rkeys, vals) |
122 return idxCallbacker(err, len(keys), func(idx int, err error) { | 121 return idxCallbacker(err, len(keys), func(idx int, err error) { |
123 » » k := rds.Key(nil) | 122 » » k := ds.Key(nil) |
124 if err == nil { | 123 if err == nil { |
125 k = dsR2F(rkeys[idx]) | 124 k = dsR2F(rkeys[idx]) |
126 } | 125 } |
127 cb(k, err) | 126 cb(k, err) |
128 }) | 127 }) |
129 } | 128 } |
130 | 129 |
131 func (d rdsImpl) NewQuery(kind string) rds.Query { | 130 func (d rdsImpl) NewQuery(kind string) ds.Query { |
132 return queryImpl{datastore.NewQuery(kind)} | 131 return queryImpl{datastore.NewQuery(kind)} |
133 } | 132 } |
134 | 133 |
135 func (d rdsImpl) Run(q rds.Query, cb rds.RunCB) error { | 134 func (d rdsImpl) Run(q ds.Query, cb ds.RawRunCB) error { |
136 tf := typeFilter{} | 135 tf := typeFilter{} |
137 t := q.(queryImpl).Query.Run(d) | 136 t := q.(queryImpl).Query.Run(d) |
138 » cfunc := func() (rds.Cursor, error) { | 137 » cfunc := func() (ds.Cursor, error) { |
139 return t.Cursor() | 138 return t.Cursor() |
140 } | 139 } |
141 for { | 140 for { |
142 k, err := t.Next(&tf) | 141 k, err := t.Next(&tf) |
143 if err == datastore.Done { | 142 if err == datastore.Done { |
144 return nil | 143 return nil |
145 } | 144 } |
146 if err != nil { | 145 if err != nil { |
147 return err | 146 return err |
148 } | 147 } |
149 if !cb(dsR2F(k), tf.pm, cfunc) { | 148 if !cb(dsR2F(k), tf.pm, cfunc) { |
150 return nil | 149 return nil |
151 } | 150 } |
152 } | 151 } |
153 } | 152 } |
154 | 153 |
155 func (d rdsImpl) RunInTransaction(f func(c context.Context) error, opts *rds.Tra
nsactionOptions) error { | 154 func (d rdsImpl) RunInTransaction(f func(c context.Context) error, opts *ds.Tran
sactionOptions) error { |
156 ropts := (*datastore.TransactionOptions)(opts) | 155 ropts := (*datastore.TransactionOptions)(opts) |
157 return datastore.RunInTransaction(d, f, ropts) | 156 return datastore.RunInTransaction(d, f, ropts) |
158 } | 157 } |
OLD | NEW |