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" | 8 "bytes" |
9 "fmt" | 9 "fmt" |
| 10 "reflect" |
10 "time" | 11 "time" |
11 | 12 |
12 » "infra/gae/libs/gae" | 13 » "appengine/datastore" |
13 » "infra/gae/libs/gae/helper" | |
14 | 14 |
15 "github.com/luci/luci-go/common/cmpbin" | 15 "github.com/luci/luci-go/common/cmpbin" |
16 ) | 16 ) |
17 | 17 |
18 type kv struct{ k, v []byte } | 18 type kv struct{ k, v []byte } |
19 | 19 |
20 func indx(kind string, orders ...string) *qIndex { | 20 func indx(kind string, orders ...string) *qIndex { |
21 ancestor := false | 21 ancestor := false |
22 if kind[len(kind)-1] == '!' { | 22 if kind[len(kind)-1] == '!' { |
23 ancestor = true | 23 ancestor = true |
24 kind = kind[:len(kind)-1] | 24 kind = kind[:len(kind)-1] |
25 } | 25 } |
26 ret := &qIndex{kind, ancestor, nil} | 26 ret := &qIndex{kind, ancestor, nil} |
27 for _, o := range orders { | 27 for _, o := range orders { |
28 dir := qASC | 28 dir := qASC |
29 if o[0] == '-' { | 29 if o[0] == '-' { |
30 dir = qDEC | 30 dir = qDEC |
31 o = o[1:] | 31 o = o[1:] |
32 } | 32 } |
33 ret.sortby = append(ret.sortby, qSortBy{o, dir}) | 33 ret.sortby = append(ret.sortby, qSortBy{o, dir}) |
34 } | 34 } |
35 return ret | 35 return ret |
36 } | 36 } |
37 | 37 |
38 func prop(val interface{}, noIndex ...bool) (ret gae.DSProperty) { | 38 func pl(props ...datastore.Property) *propertyList { |
39 » ni := false | 39 » return (*propertyList)(&props) |
| 40 } |
| 41 |
| 42 func prop(name string, val interface{}, noIndex ...bool) (ret datastore.Property
) { |
| 43 » ret.Name = name |
| 44 » ret.Value = val |
40 if len(noIndex) > 0 { | 45 if len(noIndex) > 0 { |
41 » » ni = noIndex[0] | 46 » » ret.NoIndex = noIndex[0] |
42 » } | |
43 » if err := ret.SetValue(val, ni); err != nil { | |
44 » » panic(err) | |
45 } | 47 } |
46 return | 48 return |
47 } | 49 } |
48 | 50 |
49 func key(kind string, id interface{}, parent ...gae.DSKey) gae.DSKey { | 51 func key(kind string, id interface{}, parent ...*datastore.Key) *datastore.Key { |
50 » p := gae.DSKey(nil) | 52 » stringID := "" |
51 » if len(parent) > 0 { | 53 » intID := int64(0) |
52 » » p = parent[0] | |
53 » } | |
54 switch x := id.(type) { | 54 switch x := id.(type) { |
55 case string: | 55 case string: |
56 » » return helper.NewDSKey(globalAppID, "ns", kind, x, 0, p) | 56 » » stringID = x |
57 case int: | 57 case int: |
58 » » return helper.NewDSKey(globalAppID, "ns", kind, "", int64(x), p) | 58 » » intID = int64(x) |
59 default: | 59 default: |
60 panic(fmt.Errorf("what the %T: %v", id, id)) | 60 panic(fmt.Errorf("what the %T: %v", id, id)) |
61 } | 61 } |
| 62 par := (*datastore.Key)(nil) |
| 63 if len(parent) > 0 { |
| 64 par = parent[0] |
| 65 } |
| 66 return newKey("ns", kind, stringID, intID, par) |
| 67 } |
| 68 |
| 69 func mustLoadLocation(loc string) *time.Location { |
| 70 if z, err := time.LoadLocation(loc); err != nil { |
| 71 panic(err) |
| 72 } else { |
| 73 return z |
| 74 } |
62 } | 75 } |
63 | 76 |
64 // cat is a convenience method for concatenating anything with an underlying | 77 // cat is a convenience method for concatenating anything with an underlying |
65 // byte representation into a single []byte. | 78 // byte representation into a single []byte. |
66 func cat(bytethings ...interface{}) []byte { | 79 func cat(bytethings ...interface{}) []byte { |
67 buf := &bytes.Buffer{} | 80 buf := &bytes.Buffer{} |
68 for _, thing := range bytethings { | 81 for _, thing := range bytethings { |
69 switch x := thing.(type) { | 82 switch x := thing.(type) { |
70 » » case int64: | 83 » » case int, int64: |
71 » » » cmpbin.WriteInt(buf, x) | 84 » » » cmpbin.WriteInt(buf, reflect.ValueOf(x).Int()) |
72 » » case int: | 85 » » case uint, uint64: |
73 » » » cmpbin.WriteInt(buf, int64(x)) | 86 » » » cmpbin.WriteUint(buf, reflect.ValueOf(x).Uint()) |
74 » » case uint64: | |
75 » » » cmpbin.WriteUint(buf, x) | |
76 » » case uint: | |
77 » » » cmpbin.WriteUint(buf, uint64(x)) | |
78 case float64: | 87 case float64: |
79 » » » cmpbin.WriteFloat64(buf, x) | 88 » » » writeFloat64(buf, x) |
80 » » case byte: | 89 » » case byte, propValType: |
81 » » » buf.WriteByte(x) | 90 » » » buf.WriteByte(byte(reflect.ValueOf(x).Uint())) |
82 » » case gae.DSPropertyType: | 91 » » case []byte, serializedPval: |
83 » » » buf.WriteByte(byte(x)) | 92 » » » buf.Write(reflect.ValueOf(x).Convert(byteSliceType).Inte
rface().([]byte)) |
84 case string: | 93 case string: |
85 » » » cmpbin.WriteString(buf, x) | 94 » » » writeString(buf, x) |
86 » » case []byte: | |
87 » » » buf.Write(x) | |
88 case time.Time: | 95 case time.Time: |
89 » » » helper.WriteTime(buf, x) | 96 » » » writeTime(buf, x) |
90 » » case gae.DSKey: | 97 » » case *datastore.Key: |
91 » » » helper.WriteDSKey(buf, helper.WithoutContext, x) | 98 » » » writeKey(buf, noNS, x) |
92 case *qIndex: | 99 case *qIndex: |
93 x.WriteBinary(buf) | 100 x.WriteBinary(buf) |
94 default: | 101 default: |
95 panic(fmt.Errorf("I don't know how to deal with %T: %#v"
, thing, thing)) | 102 panic(fmt.Errorf("I don't know how to deal with %T: %#v"
, thing, thing)) |
96 } | 103 } |
97 } | 104 } |
98 ret := buf.Bytes() | 105 ret := buf.Bytes() |
99 if ret == nil { | 106 if ret == nil { |
100 ret = []byte{} | 107 ret = []byte{} |
101 } | 108 } |
102 return ret | 109 return ret |
103 } | 110 } |
104 | 111 |
105 func icat(bytethings ...interface{}) []byte { | 112 func icat(bytethings ...interface{}) []byte { |
106 ret := cat(bytethings...) | 113 ret := cat(bytethings...) |
107 for i := range ret { | 114 for i := range ret { |
108 ret[i] ^= 0xFF | 115 ret[i] ^= 0xFF |
109 } | 116 } |
110 return ret | 117 return ret |
111 } | 118 } |
112 | 119 |
113 func sat(bytethings ...interface{}) string { | 120 func sat(bytethings ...interface{}) string { |
114 return string(cat(bytethings...)) | 121 return string(cat(bytethings...)) |
115 } | 122 } |
OLD | NEW |