Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(638)

Side by Side Diff: impl/memory/datastore_query.go

Issue 1292913002: Split off serialization and key functions to their own packages. (Closed) Base URL: https://github.com/luci/gae.git@make_queries_better
Patch Set: rebase Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « impl/memory/datastore_index.go ('k') | impl/memory/datastore_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « impl/memory/datastore_index.go ('k') | impl/memory/datastore_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698