| 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 datastore | 5 package datastore |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "fmt" | 8 "fmt" |
| 9 "reflect" | 9 "reflect" |
| 10 | 10 |
| 11 "github.com/luci/luci-go/common/errors" | 11 "github.com/luci/luci-go/common/errors" |
| 12 ) | 12 ) |
| 13 | 13 |
| 14 type multiArgType struct { | 14 type multiArgType struct { |
| 15 getKey func(aid, ns string, slot reflect.Value) (*Key, error) | 15 getKey func(aid, ns string, slot reflect.Value) (*Key, error) |
| 16 getPM func(slot reflect.Value) (PropertyMap, error) | 16 getPM func(slot reflect.Value) (PropertyMap, error) |
| 17 getMetaPM func(slot reflect.Value) PropertyMap | 17 getMetaPM func(slot reflect.Value) PropertyMap |
| 18 setPM func(slot reflect.Value, pm PropertyMap) error | 18 setPM func(slot reflect.Value, pm PropertyMap) error |
| 19 » setKey func(slot reflect.Value, k *Key) | 19 » setKey func(slot reflect.Value, k *Key) bool |
| 20 newElem func() reflect.Value | 20 newElem func() reflect.Value |
| 21 } | 21 } |
| 22 | 22 |
| 23 // parseArg checks that et is of type S, *S, I, P or *P, for some | 23 // parseArg checks that et is of type S, *S, I, P or *P, for some |
| 24 // struct type S, for some interface type I, or some non-interface non-pointer | 24 // struct type S, for some interface type I, or some non-interface non-pointer |
| 25 // type P such that P or *P implements PropertyLoadSaver. | 25 // type P such that P or *P implements PropertyLoadSaver. |
| 26 // | 26 // |
| 27 // If et is a chan type that implements PropertyLoadSaver, new elements will be | 27 // If et is a chan type that implements PropertyLoadSaver, new elements will be |
| 28 // allocated with a buffer of 0. | 28 // allocated with a buffer of 0. |
| 29 // | 29 // |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 }, | 90 }, |
| 91 getPM: func(slot reflect.Value) (PropertyMap, error) { | 91 getPM: func(slot reflect.Value) (PropertyMap, error) { |
| 92 return slot.Interface().(PropertyLoadSaver).Save(true) | 92 return slot.Interface().(PropertyLoadSaver).Save(true) |
| 93 }, | 93 }, |
| 94 getMetaPM: func(slot reflect.Value) PropertyMap { | 94 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 95 return getMGS(slot.Interface()).GetAllMeta() | 95 return getMGS(slot.Interface()).GetAllMeta() |
| 96 }, | 96 }, |
| 97 setPM: func(slot reflect.Value, pm PropertyMap) error { | 97 setPM: func(slot reflect.Value, pm PropertyMap) error { |
| 98 return slot.Interface().(PropertyLoadSaver).Load(pm) | 98 return slot.Interface().(PropertyLoadSaver).Load(pm) |
| 99 }, | 99 }, |
| 100 » » setKey: func(slot reflect.Value, k *Key) { | 100 » » setKey: func(slot reflect.Value, k *Key) bool { |
| 101 » » » PopulateKey(slot.Interface(), k) | 101 » » » return PopulateKey(slot.Interface(), k) |
| 102 }, | 102 }, |
| 103 } | 103 } |
| 104 switch et.Kind() { | 104 switch et.Kind() { |
| 105 case reflect.Map: | 105 case reflect.Map: |
| 106 ret.newElem = func() reflect.Value { | 106 ret.newElem = func() reflect.Value { |
| 107 return reflect.MakeMap(et) | 107 return reflect.MakeMap(et) |
| 108 } | 108 } |
| 109 | 109 |
| 110 case reflect.Chan: | 110 case reflect.Chan: |
| 111 ret.newElem = func() reflect.Value { | 111 ret.newElem = func() reflect.Value { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 }, | 148 }, |
| 149 getPM: func(slot reflect.Value) (PropertyMap, error) { | 149 getPM: func(slot reflect.Value) (PropertyMap, error) { |
| 150 return slot.Addr().Interface().(PropertyLoadSaver).Save(
true) | 150 return slot.Addr().Interface().(PropertyLoadSaver).Save(
true) |
| 151 }, | 151 }, |
| 152 getMetaPM: func(slot reflect.Value) PropertyMap { | 152 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 153 return getMGS(slot.Addr().Interface()).GetAllMeta() | 153 return getMGS(slot.Addr().Interface()).GetAllMeta() |
| 154 }, | 154 }, |
| 155 setPM: func(slot reflect.Value, pm PropertyMap) error { | 155 setPM: func(slot reflect.Value, pm PropertyMap) error { |
| 156 return slot.Addr().Interface().(PropertyLoadSaver).Load(
pm) | 156 return slot.Addr().Interface().(PropertyLoadSaver).Load(
pm) |
| 157 }, | 157 }, |
| 158 » » setKey: func(slot reflect.Value, k *Key) { | 158 » » setKey: func(slot reflect.Value, k *Key) bool { |
| 159 » » » PopulateKey(slot.Addr().Interface(), k) | 159 » » » return PopulateKey(slot.Addr().Interface(), k) |
| 160 }, | 160 }, |
| 161 newElem: func() reflect.Value { | 161 newElem: func() reflect.Value { |
| 162 return reflect.New(et).Elem() | 162 return reflect.New(et).Elem() |
| 163 }, | 163 }, |
| 164 } | 164 } |
| 165 } | 165 } |
| 166 | 166 |
| 167 // multiArgTypeStruct == []S | 167 // multiArgTypeStruct == []S |
| 168 func multiArgTypeStruct(et reflect.Type) *multiArgType { | 168 func multiArgTypeStruct(et reflect.Type) *multiArgType { |
| 169 cdc := getCodec(et) | 169 cdc := getCodec(et) |
| 170 toPLS := func(slot reflect.Value) *structPLS { | 170 toPLS := func(slot reflect.Value) *structPLS { |
| 171 return &structPLS{slot, cdc} | 171 return &structPLS{slot, cdc} |
| 172 } | 172 } |
| 173 return &multiArgType{ | 173 return &multiArgType{ |
| 174 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 174 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
| 175 return newKeyObjErr(aid, ns, getMGS(slot.Addr().Interfac
e())) | 175 return newKeyObjErr(aid, ns, getMGS(slot.Addr().Interfac
e())) |
| 176 }, | 176 }, |
| 177 getPM: func(slot reflect.Value) (PropertyMap, error) { | 177 getPM: func(slot reflect.Value) (PropertyMap, error) { |
| 178 return toPLS(slot).Save(true) | 178 return toPLS(slot).Save(true) |
| 179 }, | 179 }, |
| 180 getMetaPM: func(slot reflect.Value) PropertyMap { | 180 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 181 return getMGS(slot.Addr().Interface()).GetAllMeta() | 181 return getMGS(slot.Addr().Interface()).GetAllMeta() |
| 182 }, | 182 }, |
| 183 setPM: func(slot reflect.Value, pm PropertyMap) error { | 183 setPM: func(slot reflect.Value, pm PropertyMap) error { |
| 184 return toPLS(slot).Load(pm) | 184 return toPLS(slot).Load(pm) |
| 185 }, | 185 }, |
| 186 » » setKey: func(slot reflect.Value, k *Key) { | 186 » » setKey: func(slot reflect.Value, k *Key) bool { |
| 187 » » » PopulateKey(toPLS(slot), k) | 187 » » » return PopulateKey(toPLS(slot), k) |
| 188 }, | 188 }, |
| 189 newElem: func() reflect.Value { | 189 newElem: func() reflect.Value { |
| 190 return reflect.New(et).Elem() | 190 return reflect.New(et).Elem() |
| 191 }, | 191 }, |
| 192 } | 192 } |
| 193 } | 193 } |
| 194 | 194 |
| 195 // multiArgTypeStructPtr == []*S | 195 // multiArgTypeStructPtr == []*S |
| 196 func multiArgTypeStructPtr(et reflect.Type) *multiArgType { | 196 func multiArgTypeStructPtr(et reflect.Type) *multiArgType { |
| 197 cdc := getCodec(et.Elem()) | 197 cdc := getCodec(et.Elem()) |
| 198 toPLS := func(slot reflect.Value) *structPLS { | 198 toPLS := func(slot reflect.Value) *structPLS { |
| 199 return &structPLS{slot.Elem(), cdc} | 199 return &structPLS{slot.Elem(), cdc} |
| 200 } | 200 } |
| 201 return &multiArgType{ | 201 return &multiArgType{ |
| 202 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 202 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
| 203 return newKeyObjErr(aid, ns, getMGS(slot.Interface())) | 203 return newKeyObjErr(aid, ns, getMGS(slot.Interface())) |
| 204 }, | 204 }, |
| 205 getPM: func(slot reflect.Value) (PropertyMap, error) { | 205 getPM: func(slot reflect.Value) (PropertyMap, error) { |
| 206 return toPLS(slot).Save(true) | 206 return toPLS(slot).Save(true) |
| 207 }, | 207 }, |
| 208 getMetaPM: func(slot reflect.Value) PropertyMap { | 208 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 209 return getMGS(slot.Interface()).GetAllMeta() | 209 return getMGS(slot.Interface()).GetAllMeta() |
| 210 }, | 210 }, |
| 211 setPM: func(slot reflect.Value, pm PropertyMap) error { | 211 setPM: func(slot reflect.Value, pm PropertyMap) error { |
| 212 return toPLS(slot).Load(pm) | 212 return toPLS(slot).Load(pm) |
| 213 }, | 213 }, |
| 214 » » setKey: func(slot reflect.Value, k *Key) { | 214 » » setKey: func(slot reflect.Value, k *Key) bool { |
| 215 » » » PopulateKey(toPLS(slot), k) | 215 » » » return PopulateKey(toPLS(slot), k) |
| 216 }, | 216 }, |
| 217 newElem: func() reflect.Value { | 217 newElem: func() reflect.Value { |
| 218 return reflect.New(et.Elem()) | 218 return reflect.New(et.Elem()) |
| 219 }, | 219 }, |
| 220 } | 220 } |
| 221 } | 221 } |
| 222 | 222 |
| 223 // multiArgTypeInterface == []I | 223 // multiArgTypeInterface == []I |
| 224 func multiArgTypeInterface() *multiArgType { | 224 func multiArgTypeInterface() *multiArgType { |
| 225 return &multiArgType{ | 225 return &multiArgType{ |
| 226 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 226 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
| 227 return newKeyObjErr(aid, ns, getMGS(slot.Elem().Interfac
e())) | 227 return newKeyObjErr(aid, ns, getMGS(slot.Elem().Interfac
e())) |
| 228 }, | 228 }, |
| 229 getPM: func(slot reflect.Value) (PropertyMap, error) { | 229 getPM: func(slot reflect.Value) (PropertyMap, error) { |
| 230 return mkPLS(slot.Elem().Interface()).Save(true) | 230 return mkPLS(slot.Elem().Interface()).Save(true) |
| 231 }, | 231 }, |
| 232 getMetaPM: func(slot reflect.Value) PropertyMap { | 232 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 233 return getMGS(slot.Elem().Interface()).GetAllMeta() | 233 return getMGS(slot.Elem().Interface()).GetAllMeta() |
| 234 }, | 234 }, |
| 235 setPM: func(slot reflect.Value, pm PropertyMap) error { | 235 setPM: func(slot reflect.Value, pm PropertyMap) error { |
| 236 return mkPLS(slot.Elem().Interface()).Load(pm) | 236 return mkPLS(slot.Elem().Interface()).Load(pm) |
| 237 }, | 237 }, |
| 238 » » setKey: func(slot reflect.Value, k *Key) { | 238 » » setKey: func(slot reflect.Value, k *Key) bool { |
| 239 » » » PopulateKey(slot.Elem().Interface(), k) | 239 » » » return PopulateKey(slot.Elem().Interface(), k) |
| 240 }, | 240 }, |
| 241 } | 241 } |
| 242 } | 242 } |
| 243 | 243 |
| 244 // multiArgTypeKeyExtraction == *Key | 244 // multiArgTypeKeyExtraction == *Key |
| 245 // | 245 // |
| 246 // This ONLY implements getKey. | 246 // This ONLY implements getKey. |
| 247 func multiArgTypeKeyExtraction() *multiArgType { | 247 func multiArgTypeKeyExtraction() *multiArgType { |
| 248 return &multiArgType{ | 248 return &multiArgType{ |
| 249 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 249 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
| 250 return slot.Interface().(*Key), nil | 250 return slot.Interface().(*Key), nil |
| 251 }, | 251 }, |
| 252 setKey: func(slot reflect.Value, k *Key) bool { |
| 253 slot.Elem().Set(reflect.ValueOf(k).Elem()) |
| 254 return true |
| 255 }, |
| 252 } | 256 } |
| 253 } | 257 } |
| 254 | 258 |
| 255 func newKeyObjErr(aid, ns string, mgs MetaGetterSetter) (*Key, error) { | 259 func newKeyObjErr(aid, ns string, mgs MetaGetterSetter) (*Key, error) { |
| 256 if key, _ := GetMetaDefault(mgs, "key", nil).(*Key); key != nil { | 260 if key, _ := GetMetaDefault(mgs, "key", nil).(*Key); key != nil { |
| 257 return key, nil | 261 return key, nil |
| 258 } | 262 } |
| 259 | 263 |
| 260 // get kind | 264 // get kind |
| 261 kind := GetMetaDefault(mgs, "kind", "").(string) | 265 kind := GetMetaDefault(mgs, "kind", "").(string) |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 default: | 543 default: |
| 540 // Pass through to track as MultiError. | 544 // Pass through to track as MultiError. |
| 541 bt.errorTracker.trackError(it, err) | 545 bt.errorTracker.trackError(it, err) |
| 542 } | 546 } |
| 543 } | 547 } |
| 544 | 548 |
| 545 func (bt *boolTracker) result() *ExistsResult { | 549 func (bt *boolTracker) result() *ExistsResult { |
| 546 bt.res.updateSlices() | 550 bt.res.updateSlices() |
| 547 return &bt.res | 551 return &bt.res |
| 548 } | 552 } |
| OLD | NEW |