OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 package memory | |
6 | |
7 import ( | |
8 "errors" | |
9 "fmt" | |
10 "infra/gae/libs/wrapper" | |
11 "strings" | |
12 | |
13 "github.com/mjibson/goon" | |
14 "golang.org/x/net/context" | |
15 | |
16 "appengine/datastore" | |
17 "appengine_internal" | |
18 pb "appengine_internal/datastore" | |
19 ) | |
20 | |
21 //////////////////////////////////// public //////////////////////////////////// | |
22 | |
23 // useDS adds a wrapper.Datastore implementation to context, accessible | |
24 // by wrapper.GetDS(c) | |
25 func useDS(c context.Context) context.Context { | |
26 return wrapper.SetDSFactory(c, func(ic context.Context) wrapper.Datastor
e { | |
27 dsd := cur(ic).Get(memContextDSIdx) | |
28 | |
29 switch x := dsd.(type) { | |
30 case *dataStoreData: | |
31 return &dsImpl{wrapper.DummyDS(), x, curGID(ic).namespac
e, ic} | |
32 case *txnDataStoreData: | |
33 return &txnDsImpl{wrapper.DummyDS(), x, curGID(ic).names
pace} | |
34 default: | |
35 panic(fmt.Errorf("DS: bad type: %v in context %v", dsd,
ic)) | |
36 } | |
37 }) | |
38 } | |
39 | |
40 //////////////////////////////////// dsImpl //////////////////////////////////// | |
41 | |
42 // dsImpl exists solely to bind the current c to the datastore data. | |
43 type dsImpl struct { | |
44 wrapper.Datastore | |
45 | |
46 data *dataStoreData | |
47 ns string | |
48 c context.Context | |
49 } | |
50 | |
51 var ( | |
52 _ = wrapper.Datastore((*dsImpl)(nil)) | |
53 _ = wrapper.Testable((*dsImpl)(nil)) | |
54 ) | |
55 | |
56 func (d *dsImpl) BreakFeatures(err error, features ...string) { | |
57 d.data.BreakFeatures(err, features...) | |
58 } | |
59 func (d *dsImpl) UnbreakFeatures(features ...string) { | |
60 d.data.UnbreakFeatures(features...) | |
61 } | |
62 | |
63 func (d *dsImpl) Kind(src interface{}) string { | |
64 return kind(d.ns, d.KindNameResolver(), src) | |
65 } | |
66 | |
67 func (d *dsImpl) KindNameResolver() goon.KindNameResolver { | |
68 return d.data.KindNameResolver() | |
69 } | |
70 func (d *dsImpl) SetKindNameResolver(knr goon.KindNameResolver) { | |
71 d.data.SetKindNameResolver(knr) | |
72 } | |
73 | |
74 func (d *dsImpl) NewKey(kind, stringID string, intID int64, parent *datastore.Ke
y) *datastore.Key { | |
75 return newKey(d.ns, kind, stringID, intID, parent) | |
76 } | |
77 func (d *dsImpl) NewKeyObj(src interface{}) *datastore.Key { | |
78 return newKeyObj(d.ns, d.KindNameResolver(), src) | |
79 } | |
80 func (d *dsImpl) NewKeyObjError(src interface{}) (*datastore.Key, error) { | |
81 return newKeyObjError(d.ns, d.KindNameResolver(), src) | |
82 } | |
83 | |
84 func (d *dsImpl) Put(src interface{}) (*datastore.Key, error) { | |
85 if err := d.data.IsBroken(); err != nil { | |
86 return nil, err | |
87 } | |
88 return d.data.put(d.ns, src) | |
89 } | |
90 | |
91 func (d *dsImpl) Get(dst interface{}) error { | |
92 if err := d.data.IsBroken(); err != nil { | |
93 return err | |
94 } | |
95 return d.data.get(d.ns, dst) | |
96 } | |
97 | |
98 func (d *dsImpl) Delete(key *datastore.Key) error { | |
99 if err := d.data.IsBroken(); err != nil { | |
100 return err | |
101 } | |
102 return d.data.del(d.ns, key) | |
103 } | |
104 | |
105 ////////////////////////////////// txnDsImpl /////////////////////////////////// | |
106 | |
107 type txnDsImpl struct { | |
108 wrapper.Datastore | |
109 | |
110 data *txnDataStoreData | |
111 ns string | |
112 } | |
113 | |
114 var ( | |
115 _ = wrapper.Datastore((*txnDsImpl)(nil)) | |
116 _ = wrapper.Testable((*txnDsImpl)(nil)) | |
117 ) | |
118 | |
119 func (d *dsImpl) NewQuery(kind string) wrapper.DSQuery { | |
120 return &queryImpl{DSQuery: wrapper.DummyQY(), ns: d.ns, kind: kind} | |
121 } | |
122 | |
123 func (d *dsImpl) Run(q wrapper.DSQuery) wrapper.DSIterator { | |
124 rq := q.(*queryImpl) | |
125 rq = rq.normalize().checkCorrectness(d.ns, false) | |
126 return &queryIterImpl{rq} | |
127 } | |
128 | |
129 func (d *dsImpl) GetAll(q wrapper.DSQuery, dst interface{}) ([]*datastore.Key, e
rror) { | |
130 // TODO(riannucci): assert that dst is a slice of structs | |
131 return nil, nil | |
132 } | |
133 | |
134 func (d *dsImpl) Count(q wrapper.DSQuery) (ret int, err error) { | |
135 itr := d.Run(q.KeysOnly()) | |
136 for _, err = itr.Next(nil); err != nil; _, err = itr.Next(nil) { | |
137 ret++ | |
138 } | |
139 if err == datastore.Done { | |
140 err = nil | |
141 } | |
142 return | |
143 } | |
144 | |
145 func (d *txnDsImpl) BreakFeatures(err error, features ...string) { | |
146 d.data.BreakFeatures(err, features...) | |
147 } | |
148 func (d *txnDsImpl) UnbreakFeatures(features ...string) { | |
149 d.data.UnbreakFeatures(features...) | |
150 } | |
151 | |
152 func (d *txnDsImpl) Kind(src interface{}) string { | |
153 return kind(d.ns, d.KindNameResolver(), src) | |
154 } | |
155 | |
156 func (d *txnDsImpl) KindNameResolver() goon.KindNameResolver { | |
157 return d.data.KindNameResolver() | |
158 } | |
159 func (d *txnDsImpl) SetKindNameResolver(knr goon.KindNameResolver) { | |
160 d.data.SetKindNameResolver(knr) | |
161 } | |
162 | |
163 func (d *txnDsImpl) NewKey(kind, stringID string, intID int64, parent *datastore
.Key) *datastore.Key { | |
164 return newKey(d.ns, kind, stringID, intID, parent) | |
165 } | |
166 func (d *txnDsImpl) NewKeyObj(src interface{}) *datastore.Key { | |
167 return newKeyObj(d.ns, d.KindNameResolver(), src) | |
168 } | |
169 func (d *txnDsImpl) NewKeyObjError(src interface{}) (*datastore.Key, error) { | |
170 return newKeyObjError(d.ns, d.KindNameResolver(), src) | |
171 } | |
172 | |
173 func (d *txnDsImpl) Put(src interface{}) (*datastore.Key, error) { | |
174 if err := d.data.IsBroken(); err != nil { | |
175 return nil, err | |
176 } | |
177 return d.data.put(d.ns, src) | |
178 } | |
179 | |
180 func (d *txnDsImpl) Get(dst interface{}) error { | |
181 if err := d.data.IsBroken(); err != nil { | |
182 return err | |
183 } | |
184 return d.data.get(d.ns, dst) | |
185 } | |
186 | |
187 func (d *txnDsImpl) Delete(key *datastore.Key) error { | |
188 if err := d.data.IsBroken(); err != nil { | |
189 return err | |
190 } | |
191 return d.data.del(d.ns, key) | |
192 } | |
193 | |
194 func (*txnDsImpl) RunInTransaction(func(c context.Context) error, *datastore.Tra
nsactionOptions) error { | |
195 return errors.New("datastore: nested transactions are not supported") | |
196 } | |
197 | |
198 ////////////////////////////// private functions /////////////////////////////// | |
199 | |
200 func newDSError(code pb.Error_ErrorCode, message ...string) *appengine_internal.
APIError { | |
201 return &appengine_internal.APIError{ | |
202 Detail: strings.Join(message, ""), | |
203 Service: "datastore_v3", | |
204 Code: int32(code), | |
205 } | |
206 } | |
OLD | NEW |