OLD | NEW |
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
4 | 4 |
5 package memory | 5 package memory |
6 | 6 |
7 import ( | 7 import ( |
8 "errors" | 8 "errors" |
9 "fmt" | 9 "fmt" |
10 | 10 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 func (d *dsImpl) DeleteMulti(keys []*ds.Key, cb ds.DeleteMultiCB) error { | 98 func (d *dsImpl) DeleteMulti(keys []*ds.Key, cb ds.DeleteMultiCB) error { |
99 d.data.delMulti(keys, cb) | 99 d.data.delMulti(keys, cb) |
100 return nil | 100 return nil |
101 } | 101 } |
102 | 102 |
103 func (d *dsImpl) DecodeCursor(s string) (ds.Cursor, error) { | 103 func (d *dsImpl) DecodeCursor(s string) (ds.Cursor, error) { |
104 return newCursor(s) | 104 return newCursor(s) |
105 } | 105 } |
106 | 106 |
107 func (d *dsImpl) Run(fq *ds.FinalizedQuery, cb ds.RawRunCB) error { | 107 func (d *dsImpl) Run(fq *ds.FinalizedQuery, cb ds.RawRunCB) error { |
108 if err := assertQueryNamespace(d.ns, d.hasNS); err != nil { | |
109 return err | |
110 } | |
111 | |
112 idx, head := d.data.getQuerySnaps(!fq.EventuallyConsistent()) | 108 idx, head := d.data.getQuerySnaps(!fq.EventuallyConsistent()) |
113 err := executeQuery(fq, d.data.aid, d.ns, false, idx, head, cb) | 109 err := executeQuery(fq, d.data.aid, d.ns, false, idx, head, cb) |
114 if d.data.maybeAutoIndex(err) { | 110 if d.data.maybeAutoIndex(err) { |
115 idx, head = d.data.getQuerySnaps(!fq.EventuallyConsistent()) | 111 idx, head = d.data.getQuerySnaps(!fq.EventuallyConsistent()) |
116 err = executeQuery(fq, d.data.aid, d.ns, false, idx, head, cb) | 112 err = executeQuery(fq, d.data.aid, d.ns, false, idx, head, cb) |
117 } | 113 } |
118 return err | 114 return err |
119 } | 115 } |
120 | 116 |
121 func (d *dsImpl) Count(fq *ds.FinalizedQuery) (ret int64, err error) { | 117 func (d *dsImpl) Count(fq *ds.FinalizedQuery) (ret int64, err error) { |
122 if err := assertQueryNamespace(d.ns, d.hasNS); err != nil { | |
123 return 0, err | |
124 } | |
125 | |
126 idx, head := d.data.getQuerySnaps(!fq.EventuallyConsistent()) | 118 idx, head := d.data.getQuerySnaps(!fq.EventuallyConsistent()) |
127 ret, err = countQuery(fq, d.data.aid, d.ns, false, idx, head) | 119 ret, err = countQuery(fq, d.data.aid, d.ns, false, idx, head) |
128 if d.data.maybeAutoIndex(err) { | 120 if d.data.maybeAutoIndex(err) { |
129 idx, head := d.data.getQuerySnaps(!fq.EventuallyConsistent()) | 121 idx, head := d.data.getQuerySnaps(!fq.EventuallyConsistent()) |
130 ret, err = countQuery(fq, d.data.aid, d.ns, false, idx, head) | 122 ret, err = countQuery(fq, d.data.aid, d.ns, false, idx, head) |
131 } | 123 } |
132 return | 124 return |
133 } | 125 } |
134 | 126 |
135 func (d *dsImpl) AddIndexes(idxs ...*ds.IndexDefinition) { | 127 func (d *dsImpl) AddIndexes(idxs ...*ds.IndexDefinition) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 return d.data.run(func() error { | 201 return d.data.run(func() error { |
210 return d.data.delMulti(keys, cb) | 202 return d.data.delMulti(keys, cb) |
211 }) | 203 }) |
212 } | 204 } |
213 | 205 |
214 func (d *txnDsImpl) DecodeCursor(s string) (ds.Cursor, error) { | 206 func (d *txnDsImpl) DecodeCursor(s string) (ds.Cursor, error) { |
215 return newCursor(s) | 207 return newCursor(s) |
216 } | 208 } |
217 | 209 |
218 func (d *txnDsImpl) Run(q *ds.FinalizedQuery, cb ds.RawRunCB) error { | 210 func (d *txnDsImpl) Run(q *ds.FinalizedQuery, cb ds.RawRunCB) error { |
219 if err := assertQueryNamespace(d.ns, d.hasNS); err != nil { | |
220 return err | |
221 } | |
222 | |
223 // note that autoIndex has no effect inside transactions. This is becaus
e | 211 // note that autoIndex has no effect inside transactions. This is becaus
e |
224 // the transaction guarantees a consistent view of head at the time that
the | 212 // the transaction guarantees a consistent view of head at the time that
the |
225 // transaction opens. At best, we could add the index on head, but then
return | 213 // transaction opens. At best, we could add the index on head, but then
return |
226 // the error anyway, but adding the index then re-snapping at head would | 214 // the error anyway, but adding the index then re-snapping at head would |
227 // potentially reveal other entities not in the original transaction sna
pshot. | 215 // potentially reveal other entities not in the original transaction sna
pshot. |
228 // | 216 // |
229 // It's possible that if you have full-consistency and also auto index e
nabled | 217 // It's possible that if you have full-consistency and also auto index e
nabled |
230 // that this would make sense... but at that point you should probably j
ust | 218 // that this would make sense... but at that point you should probably j
ust |
231 // add the index up front. | 219 // add the index up front. |
232 return executeQuery(q, d.data.parent.aid, d.ns, true, d.data.snap, d.dat
a.snap, cb) | 220 return executeQuery(q, d.data.parent.aid, d.ns, true, d.data.snap, d.dat
a.snap, cb) |
233 } | 221 } |
234 | 222 |
235 func (d *txnDsImpl) Count(fq *ds.FinalizedQuery) (ret int64, err error) { | 223 func (d *txnDsImpl) Count(fq *ds.FinalizedQuery) (ret int64, err error) { |
236 if err := assertQueryNamespace(d.ns, d.hasNS); err != nil { | |
237 return 0, err | |
238 } | |
239 | |
240 return countQuery(fq, d.data.parent.aid, d.ns, true, d.data.snap, d.data
.snap) | 224 return countQuery(fq, d.data.parent.aid, d.ns, true, d.data.snap, d.data
.snap) |
241 } | 225 } |
242 | 226 |
243 func (*txnDsImpl) RunInTransaction(func(c context.Context) error, *ds.Transactio
nOptions) error { | 227 func (*txnDsImpl) RunInTransaction(func(c context.Context) error, *ds.Transactio
nOptions) error { |
244 return errors.New("datastore: nested transactions are not supported") | 228 return errors.New("datastore: nested transactions are not supported") |
245 } | 229 } |
246 | 230 |
247 func (*txnDsImpl) Testable() ds.Testable { | 231 func (*txnDsImpl) Testable() ds.Testable { |
248 return nil | 232 return nil |
249 } | 233 } |
250 | |
251 func assertQueryNamespace(ns string, hasNS bool) error { | |
252 if ns == "" && hasNS { | |
253 // The user has set an empty namespace. Datastore does not suppo
rt this | |
254 // for queries. | |
255 // | |
256 // Bug on file is: | |
257 // https://code.google.com/p/googleappengine/issues/detail?id=12
914 | |
258 return errors.New("namespace may not be present and empty") | |
259 } | |
260 return nil | |
261 } | |
OLD | NEW |