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

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: 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
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 const MaxQueryComponents = 100 17 const MaxQueryComponents = 100
18 18
19 var errQueryDone = errors.New("query is done") 19 var errQueryDone = errors.New("query is done")
20 20
21 type queryOp int 21 type queryOp int
22 22
23 const ( 23 const (
24 qInvalid queryOp = iota 24 qInvalid queryOp = iota
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 return &nq 239 return &nq
240 } 240 }
241 241
242 func (q *queryImpl) Ancestor(k ds.Key) ds.Query { 242 func (q *queryImpl) Ancestor(k ds.Key) ds.Query {
243 return q.checkMutateClone( 243 return q.checkMutateClone(
244 func() error { 244 func() error {
245 if k == nil { 245 if k == nil {
246 // SDK has an explicit nil-check 246 // SDK has an explicit nil-check
247 return errors.New("datastore: nil query ancestor ") 247 return errors.New("datastore: nil query ancestor ")
248 } 248 }
249 » » » if !ds.KeyValid(k, false, globalAppID, q.ns) { 249 » » » if !k.Valid(false, globalAppID, q.ns) {
250 // technically the SDK implementation does a Wei rd Thing (tm) if both the 250 // technically the SDK implementation does a Wei rd Thing (tm) if both the
251 // stringID and intID are set on a key; it only serializes the stringID in 251 // stringID and intID are set on a key; it only serializes the stringID in
252 // the proto. This means that if you set the Anc estor to an invalid key, 252 // the proto. This means that if you set the Anc estor to an invalid key,
253 // you'll never actually hear about it. Instead of doing that insanity, we 253 // you'll never actually hear about it. Instead of doing that insanity, we
254 // just swap to an error here. 254 // just swap to an error here.
255 return ds.ErrInvalidKey 255 return ds.ErrInvalidKey
256 } 256 }
257 if k.Namespace() != q.ns { 257 if k.Namespace() != q.ns {
258 return fmt.Errorf("bad namespace: %q (expected % q)", k.Namespace(), q.ns) 258 return fmt.Errorf("bad namespace: %q (expected % q)", k.Namespace(), q.ns)
259 } 259 }
(...skipping 30 matching lines...) Expand all
290 "kindless queries can only filter on __k ey__, got %q", fStr) 290 "kindless queries can only filter on __k ey__, got %q", fStr)
291 } 291 }
292 292
293 p := ds.Property{} 293 p := ds.Property{}
294 err = p.SetValue(val, ds.NoIndex) 294 err = p.SetValue(val, ds.NoIndex)
295 if err != nil { 295 if err != nil {
296 return err 296 return err
297 } 297 }
298 298
299 if p.Type() == ds.PTKey { 299 if p.Type() == ds.PTKey {
300 » » » » if !ds.KeyValid(p.Value().(ds.Key), false, globa lAppID, q.ns) { 300 » » » » if !p.Value().(ds.Key).Valid(false, globalAppID, q.ns) {
301 return ds.ErrInvalidKey 301 return ds.ErrInvalidKey
302 } 302 }
303 } 303 }
304 304
305 » » » buf := &bytes.Buffer{} 305 » » » binVal = string(serialize.ToBytes(p))
306 » » » p.Write(buf, ds.WithoutContext)
307 306
308 if prop == "__key__" { 307 if prop == "__key__" {
309 if op == qEqual { 308 if op == qEqual {
310 return fmt.Errorf( 309 return fmt.Errorf(
311 "query equality filter on __key_ _ is silly: %q", fStr) 310 "query equality filter on __key_ _ is silly: %q", fStr)
312 } 311 }
313 if p.Type() != ds.PTKey { 312 if p.Type() != ds.PTKey {
314 return fmt.Errorf("__key__ filter value is not a key: %T", val) 313 return fmt.Errorf("__key__ filter value is not a key: %T", val)
315 } 314 }
316 } 315 }
317 316
318 if op != qEqual { 317 if op != qEqual {
319 if q.ineqFilter.prop != "" && q.ineqFilter.prop != prop { 318 if q.ineqFilter.prop != "" && q.ineqFilter.prop != prop {
320 return fmt.Errorf( 319 return fmt.Errorf(
321 "inequality filters on multiple properties: %q and %q", 320 "inequality filters on multiple properties: %q and %q",
322 q.ineqFilter.prop, prop) 321 q.ineqFilter.prop, prop)
323 } 322 }
324 if len(q.order) > 0 && q.order[0].Property != pr op { 323 if len(q.order) > 0 && q.order[0].Property != pr op {
325 return fmt.Errorf( 324 return fmt.Errorf(
326 "first sort order must match ine quality filter: %q v %q", 325 "first sort order must match ine quality filter: %q v %q",
327 q.order[0].Property, prop) 326 q.order[0].Property, prop)
328 } 327 }
329 } else if _, ok := q.project[prop]; ok { 328 } else if _, ok := q.project[prop]; ok {
330 return fmt.Errorf( 329 return fmt.Errorf(
331 "cannot project on field which is used i n an equality filter: %q", 330 "cannot project on field which is used i n an equality filter: %q",
332 prop) 331 prop)
333 } 332 }
334 binVal = buf.String()
335 return 333 return
336 }, 334 },
337 func(q *queryImpl) { 335 func(q *queryImpl) {
338 if op == qEqual { 336 if op == qEqual {
339 // add it to eq filters 337 // add it to eq filters
340 if _, ok := q.eqFilters[prop]; !ok { 338 if _, ok := q.eqFilters[prop]; !ok {
341 q.eqFilters[prop] = map[string]struct{}{ binVal: {}} 339 q.eqFilters[prop] = map[string]struct{}{ binVal: {}}
342 } else { 340 } else {
343 q.eqFilters[prop][binVal] = struct{}{} 341 q.eqFilters[prop][binVal] = struct{}{}
344 } 342 }
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 q.end = curs 513 q.end = curs
516 }) 514 })
517 } 515 }
518 516
519 func (q *queryImpl) EventualConsistency() ds.Query { 517 func (q *queryImpl) EventualConsistency() ds.Query {
520 return q.checkMutateClone( 518 return q.checkMutateClone(
521 nil, func(q *queryImpl) { 519 nil, func(q *queryImpl) {
522 q.eventualConsistency = true 520 q.eventualConsistency = true
523 }) 521 })
524 } 522 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698