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 "golang.org/x/net/context" | |
11 "strings" | |
12 | |
13 "infra/gae/libs/wrapper" | |
14 | |
15 "appengine/datastore" | |
16 "appengine_internal" | |
17 pb "appengine_internal/datastore" | |
18 | |
19 "github.com/mjibson/goon" | |
20 ) | |
21 | |
22 //////////////////////////////////// public //////////////////////////////////// | |
23 | |
24 // UseDS adds a wrapper.Datastore implementation to context, accessible | |
25 // by wrapper.GetDS(c) | |
26 func UseDS(c context.Context) context.Context { | |
27 return wrapper.SetDSFactory(c, func(ic context.Context) wrapper.Datastor e { | |
28 dsd := cur(ic).Get("DS") | |
29 var ret interface { | |
30 wrapper.Testable | |
31 wrapper.Datastore | |
32 } | |
33 | |
34 switch x := dsd.(type) { | |
35 case *dataStoreData: | |
36 ret = &dsImpl{wrapper.DummyDS(), x, curGID(ic).namespace , ic} | |
M-A Ruel
2015/05/25 18:21:08
return
iannucci
2015/05/27 19:33:30
done
| |
37 case *txnDataStoreData: | |
38 ret = &txnDsImpl{wrapper.DummyDS(), x, curGID(ic).namesp ace} | |
M-A Ruel
2015/05/25 18:21:08
return
iannucci
2015/05/27 19:33:30
done
| |
39 default: | |
40 panic(fmt.Errorf("DS: bad type: %v", dsd)) | |
M-A Ruel
2015/05/25 18:21:08
well, dsd will probably be nil so using ic would p
iannucci
2015/05/27 19:33:30
ic is also opaque :(. Added it anyway.
| |
41 } | |
42 | |
43 return ret | |
M-A Ruel
2015/05/25 18:21:08
Unnecessary, the compiler realizes all switch case
iannucci
2015/05/27 19:33:30
yeah I was trying to assert that the various retur
| |
44 }) | |
45 } | |
46 | |
47 //////////////////////////////////// dsImpl //////////////////////////////////// | |
48 | |
49 // dsImpl exists solely to bind the current c to the datastore data. | |
50 type dsImpl struct { | |
51 wrapper.Datastore | |
52 | |
53 data *dataStoreData | |
54 ns string | |
55 c context.Context | |
56 } | |
57 | |
58 /////////////////////////////// Testable(dsImpl) /////////////////////////////// | |
59 | |
60 func (d *dsImpl) IsBroken() error { | |
61 return d.data.IsBroken() | |
62 } | |
63 func (d *dsImpl) SetBrokenFeatures(features ...string) { | |
64 d.data.SetBrokenFeatures(features...) | |
65 } | |
66 func (d *dsImpl) UnsetBrokenFeatures(features ...string) { | |
67 d.data.UnsetBrokenFeatures(features...) | |
68 } | |
69 | |
70 /////////////////////////////// DSKinder(dsImpl) /////////////////////////////// | |
71 | |
72 func (d *dsImpl) Kind(src interface{}) string { | |
73 return kind(d.ns, d.KindNameResolver(), src) | |
74 } | |
75 | |
76 ///////////////////////////// DSKindSetter(dsImpl) ///////////////////////////// | |
77 | |
78 func (d *dsImpl) KindNameResolver() goon.KindNameResolver { | |
79 return d.data.KindNameResolver() | |
80 } | |
81 func (d *dsImpl) SetKindNameResolver(knr goon.KindNameResolver) { | |
82 d.data.SetKindNameResolver(knr) | |
83 } | |
84 | |
85 ////////////////////////////// DSNewKeyer(dsImpl) ////////////////////////////// | |
86 | |
87 func (d *dsImpl) NewKey(kind, stringID string, intID int64, parent *datastore.Ke y) *datastore.Key { | |
88 return newKey(d.ns, kind, stringID, intID, parent) | |
89 } | |
90 func (d *dsImpl) NewKeyObj(src interface{}) *datastore.Key { | |
91 return newKeyObj(d.ns, d.KindNameResolver(), src) | |
92 } | |
93 func (d *dsImpl) NewKeyObjError(src interface{}) (*datastore.Key, error) { | |
94 return newKeyObjError(d.ns, d.KindNameResolver(), src) | |
95 } | |
96 | |
97 ////////////////////// DSSingleReadWriter(*dataStoreData) ////////////////////// | |
98 | |
99 func (d *dsImpl) Put(src interface{}) (*datastore.Key, error) { | |
100 err := d.data.IsBroken() | |
101 if err != nil { | |
102 return nil, err | |
103 } | |
104 return d.data.put(d.ns, src) | |
105 } | |
106 | |
107 func (d *dsImpl) Get(dst interface{}) error { | |
108 err := d.data.IsBroken() | |
109 if err != nil { | |
110 return err | |
111 } | |
112 return d.data.get(d.ns, dst) | |
113 } | |
114 | |
115 func (d *dsImpl) Delete(key *datastore.Key) error { | |
116 err := d.data.IsBroken() | |
117 if err != nil { | |
118 return err | |
119 } | |
120 return d.data.del(d.ns, key) | |
121 } | |
122 | |
123 ////////////////////////////////// txnDsImpl /////////////////////////////////// | |
124 | |
125 type txnDsImpl struct { | |
126 wrapper.Datastore | |
127 | |
128 data *txnDataStoreData | |
129 ns string | |
130 } | |
131 | |
132 ///////////////////////////// Testable(txnDsImpl) ////////////////////////////// | |
133 | |
134 func (d *txnDsImpl) IsBroken() error { | |
135 return d.data.IsBroken() | |
136 } | |
137 func (d *txnDsImpl) SetBrokenFeatures(features ...string) { | |
138 d.data.SetBrokenFeatures(features...) | |
139 } | |
140 func (d *txnDsImpl) UnsetBrokenFeatures(features ...string) { | |
141 d.data.UnsetBrokenFeatures(features...) | |
142 } | |
143 | |
144 ///////////////////////////// DSKinder(txnDsImpl) ////////////////////////////// | |
145 | |
146 func (d *txnDsImpl) Kind(src interface{}) string { | |
147 return kind(d.ns, d.KindNameResolver(), src) | |
148 } | |
149 | |
150 /////////////////////////// DSKindSetter(txnDsImpl) //////////////////////////// | |
151 | |
152 func (d *txnDsImpl) KindNameResolver() goon.KindNameResolver { | |
153 return d.data.KindNameResolver() | |
154 } | |
155 func (d *txnDsImpl) SetKindNameResolver(knr goon.KindNameResolver) { | |
156 d.data.SetKindNameResolver(knr) | |
157 } | |
158 | |
159 //////////////////////////// DSNewKeyer(txnDsImpl) ///////////////////////////// | |
160 | |
161 func (d *txnDsImpl) NewKey(kind, stringID string, intID int64, parent *datastore .Key) *datastore.Key { | |
162 return newKey(d.ns, kind, stringID, intID, parent) | |
163 } | |
164 func (d *txnDsImpl) NewKeyObj(src interface{}) *datastore.Key { | |
165 return newKeyObj(d.ns, d.KindNameResolver(), src) | |
166 } | |
167 func (d *txnDsImpl) NewKeyObjError(src interface{}) (*datastore.Key, error) { | |
168 return newKeyObjError(d.ns, d.KindNameResolver(), src) | |
169 } | |
170 | |
171 //////////////////////// DSSingleReadWriter(*txnDsImpl) //////////////////////// | |
172 | |
173 func (d *txnDsImpl) Put(src interface{}) (*datastore.Key, error) { | |
174 err := d.data.IsBroken() | |
175 if err != nil { | |
176 return nil, err | |
177 } | |
178 return d.data.put(d.ns, src) | |
179 } | |
180 | |
181 func (d *txnDsImpl) Get(dst interface{}) error { | |
182 err := d.data.IsBroken() | |
183 if err != nil { | |
184 return err | |
185 } | |
186 return d.data.get(d.ns, dst) | |
187 } | |
188 | |
189 func (d *txnDsImpl) Delete(key *datastore.Key) error { | |
190 err := d.data.IsBroken() | |
191 if err != nil { | |
192 return err | |
193 } | |
194 return d.data.del(d.ns, key) | |
195 } | |
196 | |
197 ///////////////////////// DSTransactioner(*txnDsImpl) ////////////////////////// | |
198 | |
199 func (*txnDsImpl) RunInTransaction(func(c context.Context) error, *datastore.Tra nsactionOptions) error { | |
200 return errors.New("datastore: nested transactions are not supported") | |
201 } | |
202 | |
203 ////////////////////////////// private functions /////////////////////////////// | |
204 | |
205 func newDSError(code pb.Error_ErrorCode, message ...string) *appengine_internal. APIError { | |
206 return &appengine_internal.APIError{ | |
207 Detail: strings.Join(message, ""), | |
208 Service: "datastore_v3", | |
209 Code: int32(code), | |
210 } | |
211 } | |
OLD | NEW |