| 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 memory | 5 package memory |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "bytes" | |
| 9 "errors" | 8 "errors" |
| 10 "fmt" | 9 "fmt" |
| 11 "math" | 10 "math" |
| 12 "strings" | 11 "strings" |
| 13 | 12 |
| 14 ds "github.com/luci/gae/service/datastore" | 13 ds "github.com/luci/gae/service/datastore" |
| 14 "github.com/luci/gae/service/datastore/serialize" |
| 15 ) | 15 ) |
| 16 | 16 |
| 17 // MaxQueryComponents was lifted from a hard-coded constant in dev_appserver. | 17 // MaxQueryComponents was lifted from a hard-coded constant in dev_appserver. |
| 18 // No idea if it's a real limit or just a convenience in the current dev | 18 // No idea if it's a real limit or just a convenience in the current dev |
| 19 // appserver implementation. | 19 // appserver implementation. |
| 20 const MaxQueryComponents = 100 | 20 const MaxQueryComponents = 100 |
| 21 | 21 |
| 22 var errQueryDone = errors.New("query is done") | 22 var errQueryDone = errors.New("query is done") |
| 23 | 23 |
| 24 type queryOp int | 24 type queryOp int |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 return &nq | 243 return &nq |
| 244 } | 244 } |
| 245 | 245 |
| 246 func (q *queryImpl) Ancestor(k ds.Key) ds.Query { | 246 func (q *queryImpl) Ancestor(k ds.Key) ds.Query { |
| 247 return q.checkMutateClone( | 247 return q.checkMutateClone( |
| 248 func() error { | 248 func() error { |
| 249 if k == nil { | 249 if k == nil { |
| 250 // SDK has an explicit nil-check | 250 // SDK has an explicit nil-check |
| 251 return errors.New("datastore: nil query ancestor
") | 251 return errors.New("datastore: nil query ancestor
") |
| 252 } | 252 } |
| 253 » » » if !ds.KeyValid(k, false, globalAppID, q.ns) { | 253 » » » if !k.Valid(false, globalAppID, q.ns) { |
| 254 // technically the SDK implementation does a Wei
rd Thing (tm) if both the | 254 // technically the SDK implementation does a Wei
rd Thing (tm) if both the |
| 255 // stringID and intID are set on a key; it only
serializes the stringID in | 255 // stringID and intID are set on a key; it only
serializes the stringID in |
| 256 // the proto. This means that if you set the Anc
estor to an invalid key, | 256 // the proto. This means that if you set the Anc
estor to an invalid key, |
| 257 // you'll never actually hear about it. Instead
of doing that insanity, we | 257 // you'll never actually hear about it. Instead
of doing that insanity, we |
| 258 // just swap to an error here. | 258 // just swap to an error here. |
| 259 return ds.ErrInvalidKey | 259 return ds.ErrInvalidKey |
| 260 } | 260 } |
| 261 if k.Namespace() != q.ns { | 261 if k.Namespace() != q.ns { |
| 262 return fmt.Errorf("bad namespace: %q (expected %
q)", k.Namespace(), q.ns) | 262 return fmt.Errorf("bad namespace: %q (expected %
q)", k.Namespace(), q.ns) |
| 263 } | 263 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 "kindless queries can only filter on __k
ey__, got %q", fStr) | 295 "kindless queries can only filter on __k
ey__, got %q", fStr) |
| 296 } | 296 } |
| 297 | 297 |
| 298 p := ds.Property{} | 298 p := ds.Property{} |
| 299 err = p.SetValue(val, ds.NoIndex) | 299 err = p.SetValue(val, ds.NoIndex) |
| 300 if err != nil { | 300 if err != nil { |
| 301 return err | 301 return err |
| 302 } | 302 } |
| 303 | 303 |
| 304 if p.Type() == ds.PTKey { | 304 if p.Type() == ds.PTKey { |
| 305 » » » » if !ds.KeyValid(p.Value().(ds.Key), false, globa
lAppID, q.ns) { | 305 » » » » if !p.Value().(ds.Key).Valid(false, globalAppID,
q.ns) { |
| 306 return ds.ErrInvalidKey | 306 return ds.ErrInvalidKey |
| 307 } | 307 } |
| 308 } | 308 } |
| 309 | 309 |
| 310 if prop == "__key__" { | 310 if prop == "__key__" { |
| 311 if op == qEqual { | 311 if op == qEqual { |
| 312 return fmt.Errorf( | 312 return fmt.Errorf( |
| 313 "query equality filter on __key_
_ is silly: %q", fStr) | 313 "query equality filter on __key_
_ is silly: %q", fStr) |
| 314 } | 314 } |
| 315 if p.Type() != ds.PTKey { | 315 if p.Type() != ds.PTKey { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 326 if len(q.order) > 0 && q.order[0].Property != pr
op { | 326 if len(q.order) > 0 && q.order[0].Property != pr
op { |
| 327 return fmt.Errorf( | 327 return fmt.Errorf( |
| 328 "first sort order must match ine
quality filter: %q v %q", | 328 "first sort order must match ine
quality filter: %q v %q", |
| 329 q.order[0].Property, prop) | 329 q.order[0].Property, prop) |
| 330 } | 330 } |
| 331 } else if _, ok := q.project[prop]; ok { | 331 } else if _, ok := q.project[prop]; ok { |
| 332 return fmt.Errorf( | 332 return fmt.Errorf( |
| 333 "cannot project on field which is used i
n an equality filter: %q", | 333 "cannot project on field which is used i
n an equality filter: %q", |
| 334 prop) | 334 prop) |
| 335 } | 335 } |
| 336 | 336 » » » binVal = string(serialize.ToBytes(p)) |
| 337 » » » buf := &bytes.Buffer{} | 337 » » » return err |
| 338 » » » p.Write(buf, ds.WithoutContext) | |
| 339 » » » binVal = buf.String() | |
| 340 » » » return nil | |
| 341 }, | 338 }, |
| 342 func(q *queryImpl) { | 339 func(q *queryImpl) { |
| 343 if op == qEqual { | 340 if op == qEqual { |
| 344 // add it to eq filters | 341 // add it to eq filters |
| 345 if _, ok := q.eqFilters[prop]; !ok { | 342 if _, ok := q.eqFilters[prop]; !ok { |
| 346 q.eqFilters[prop] = map[string]struct{}{
binVal: {}} | 343 q.eqFilters[prop] = map[string]struct{}{
binVal: {}} |
| 347 } else { | 344 } else { |
| 348 q.eqFilters[prop][binVal] = struct{}{} | 345 q.eqFilters[prop][binVal] = struct{}{} |
| 349 } | 346 } |
| 350 | 347 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 q.end = curs | 517 q.end = curs |
| 521 }) | 518 }) |
| 522 } | 519 } |
| 523 | 520 |
| 524 func (q *queryImpl) EventualConsistency() ds.Query { | 521 func (q *queryImpl) EventualConsistency() ds.Query { |
| 525 return q.checkMutateClone( | 522 return q.checkMutateClone( |
| 526 nil, func(q *queryImpl) { | 523 nil, func(q *queryImpl) { |
| 527 q.eventualConsistency = true | 524 q.eventualConsistency = true |
| 528 }) | 525 }) |
| 529 } | 526 } |
| OLD | NEW |