| 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 |