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/funnybase" |
| 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 funnybase.Write(buf, reflect.ValueOf(x).Int()) |
| 85 case uint, uint64: |
| 86 funnybase.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 |