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 "encoding/base64" |
8 "errors" | 9 "errors" |
9 "fmt" | 10 "fmt" |
10 "math" | 11 "math" |
11 "strings" | 12 "strings" |
12 | 13 |
13 ds "github.com/luci/gae/service/datastore" | 14 ds "github.com/luci/gae/service/datastore" |
14 "github.com/luci/gae/service/datastore/serialize" | 15 "github.com/luci/gae/service/datastore/serialize" |
15 ) | 16 ) |
16 | 17 |
17 // MaxQueryComponents was lifted from a hard-coded constant in dev_appserver. | 18 // MaxQueryComponents was lifted from a hard-coded constant in dev_appserver. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 err = fmt.Errorf("datastore: invalid operator %q in filt
er %q", toks[1], f) | 57 err = fmt.Errorf("datastore: invalid operator %q in filt
er %q", toks[1], f) |
57 } else { | 58 } else { |
58 prop = toks[0] | 59 prop = toks[0] |
59 } | 60 } |
60 } | 61 } |
61 return | 62 return |
62 } | 63 } |
63 | 64 |
64 type queryCursor string | 65 type queryCursor string |
65 | 66 |
66 func (q queryCursor) String() string { return string(q) } | 67 func (q queryCursor) String() string { return base64.URLEncoding.EncodeToString(
[]byte(q)) } |
67 func (q queryCursor) Valid() bool { return q != "" } | 68 func (q queryCursor) Valid() bool { return q != "" } |
68 | 69 |
69 type queryIneqFilter struct { | 70 type queryIneqFilter struct { |
70 prop string | 71 prop string |
71 | 72 |
72 low *string | 73 low *string |
73 high *string | 74 high *string |
74 } | 75 } |
75 | 76 |
| 77 func decodeCursor(s string) (ds.Cursor, error) { |
| 78 d, err := base64.URLEncoding.DecodeString(s) |
| 79 if err != nil { |
| 80 return nil, fmt.Errorf("Failed to Base64-decode cursor: %s", err
) |
| 81 } |
| 82 c := queryCursor(string(d)) |
| 83 if !c.Valid() { |
| 84 return nil, errors.New("Decoded cursor is not valid.") |
| 85 } |
| 86 return c, nil |
| 87 } |
| 88 |
76 func increment(bstr string, positive bool) string { | 89 func increment(bstr string, positive bool) string { |
77 lastIdx := len(bstr) - 1 | 90 lastIdx := len(bstr) - 1 |
78 last := bstr[lastIdx] | 91 last := bstr[lastIdx] |
79 if positive { | 92 if positive { |
80 if last == 0xFF { | 93 if last == 0xFF { |
81 return bstr + "\x00" | 94 return bstr + "\x00" |
82 } | 95 } |
83 return bstr[:lastIdx-1] + string(last+1) | 96 return bstr[:lastIdx-1] + string(last+1) |
84 } else { | 97 } else { |
85 if last == 0 { | 98 if last == 0 { |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 q.end = curs | 530 q.end = curs |
518 }) | 531 }) |
519 } | 532 } |
520 | 533 |
521 func (q *queryImpl) EventualConsistency() ds.Query { | 534 func (q *queryImpl) EventualConsistency() ds.Query { |
522 return q.checkMutateClone( | 535 return q.checkMutateClone( |
523 nil, func(q *queryImpl) { | 536 nil, func(q *queryImpl) { |
524 q.eventualConsistency = true | 537 q.eventualConsistency = true |
525 }) | 538 }) |
526 } | 539 } |
OLD | NEW |