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 |