| 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 |