| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package memory | |
| 6 | |
| 7 import ( | |
| 8 "bytes" | |
| 9 "fmt" | |
| 10 "reflect" | |
| 11 "time" | |
| 12 | |
| 13 "appengine/datastore" | |
| 14 | |
| 15 "github.com/luci/luci-go/common/cmpbin" | |
| 16 ) | |
| 17 | |
| 18 type kv struct{ k, v []byte } | |
| 19 | |
| 20 func indx(kind string, orders ...string) *qIndex { | |
| 21 ancestor := false | |
| 22 if kind[len(kind)-1] == '!' { | |
| 23 ancestor = true | |
| 24 kind = kind[:len(kind)-1] | |
| 25 } | |
| 26 ret := &qIndex{kind, ancestor, nil} | |
| 27 for _, o := range orders { | |
| 28 dir := qASC | |
| 29 if o[0] == '-' { | |
| 30 dir = qDEC | |
| 31 o = o[1:] | |
| 32 } | |
| 33 ret.sortby = append(ret.sortby, qSortBy{o, dir}) | |
| 34 } | |
| 35 return ret | |
| 36 } | |
| 37 | |
| 38 func pl(props ...datastore.Property) *propertyList { | |
| 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 | |
| 45 if len(noIndex) > 0 { | |
| 46 ret.NoIndex = noIndex[0] | |
| 47 } | |
| 48 return | |
| 49 } | |
| 50 | |
| 51 func key(kind string, id interface{}, parent ...*datastore.Key) *datastore.Key { | |
| 52 stringID := "" | |
| 53 intID := int64(0) | |
| 54 switch x := id.(type) { | |
| 55 case string: | |
| 56 stringID = x | |
| 57 case int: | |
| 58 intID = int64(x) | |
| 59 default: | |
| 60 panic(fmt.Errorf("what the %T: %v", id, id)) | |
| 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 } | |
| 75 } | |
| 76 | |
| 77 // cat is a convenience method for concatenating anything with an underlying | |
| 78 // byte representation into a single []byte. | |
| 79 func cat(bytethings ...interface{}) []byte { | |
| 80 buf := &bytes.Buffer{} | |
| 81 for _, thing := range bytethings { | |
| 82 switch x := thing.(type) { | |
| 83 case int, int64: | |
| 84 cmpbin.WriteInt(buf, reflect.ValueOf(x).Int()) | |
| 85 case uint, uint64: | |
| 86 cmpbin.WriteUint(buf, reflect.ValueOf(x).Uint()) | |
| 87 case float64: | |
| 88 writeFloat64(buf, x) | |
| 89 case byte, propValType: | |
| 90 buf.WriteByte(byte(reflect.ValueOf(x).Uint())) | |
| 91 case []byte, serializedPval: | |
| 92 buf.Write(reflect.ValueOf(x).Convert(byteSliceType).Inte
rface().([]byte)) | |
| 93 case string: | |
| 94 writeString(buf, x) | |
| 95 case time.Time: | |
| 96 writeTime(buf, x) | |
| 97 case *datastore.Key: | |
| 98 writeKey(buf, noNS, x) | |
| 99 case *qIndex: | |
| 100 x.WriteBinary(buf) | |
| 101 default: | |
| 102 panic(fmt.Errorf("I don't know how to deal with %T: %#v"
, thing, thing)) | |
| 103 } | |
| 104 } | |
| 105 ret := buf.Bytes() | |
| 106 if ret == nil { | |
| 107 ret = []byte{} | |
| 108 } | |
| 109 return ret | |
| 110 } | |
| 111 | |
| 112 func icat(bytethings ...interface{}) []byte { | |
| 113 ret := cat(bytethings...) | |
| 114 for i := range ret { | |
| 115 ret[i] ^= 0xFF | |
| 116 } | |
| 117 return ret | |
| 118 } | |
| 119 | |
| 120 func sat(bytethings ...interface{}) string { | |
| 121 return string(cat(bytethings...)) | |
| 122 } | |
| OLD | NEW |