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 valid bool | 15 valid bool |
16 | 16 |
17 » getKey func(aid, ns string, slot reflect.Value) (*Key, error) | 17 » getKey func(aid, ns string, slot reflect.Value) (*Key, error) |
18 » getPM func(slot reflect.Value) (PropertyMap, error) | 18 » getPM func(slot reflect.Value) (PropertyMap, error) |
19 » setPM func(slot reflect.Value, pm PropertyMap) error | 19 » getMetaPM func(slot reflect.Value) PropertyMap |
20 » setKey func(slot reflect.Value, k *Key) | 20 » setPM func(slot reflect.Value, pm PropertyMap) error |
21 » newElem func() reflect.Value | 21 » setKey func(slot reflect.Value, k *Key) |
| 22 » newElem func() reflect.Value |
22 } | 23 } |
23 | 24 |
24 func (mat *multiArgType) GetKeysPMs(aid, ns string, slice reflect.Value) ([]*Key
, []PropertyMap, error) { | 25 func (mat *multiArgType) GetKeysPMs(aid, ns string, slice reflect.Value, meta bo
ol) ([]*Key, []PropertyMap, error) { |
25 retKey := make([]*Key, slice.Len()) | 26 retKey := make([]*Key, slice.Len()) |
26 retPM := make([]PropertyMap, slice.Len()) | 27 retPM := make([]PropertyMap, slice.Len()) |
| 28 getter := mat.getPM |
| 29 if meta { |
| 30 getter = func(slot reflect.Value) (PropertyMap, error) { |
| 31 return mat.getMetaPM(slot), nil |
| 32 } |
| 33 } |
27 lme := errors.NewLazyMultiError(len(retKey)) | 34 lme := errors.NewLazyMultiError(len(retKey)) |
28 for i := range retKey { | 35 for i := range retKey { |
29 key, err := mat.getKey(aid, ns, slice.Index(i)) | 36 key, err := mat.getKey(aid, ns, slice.Index(i)) |
30 if !lme.Assign(i, err) { | 37 if !lme.Assign(i, err) { |
31 retKey[i] = key | 38 retKey[i] = key |
32 » » » pm, err := mat.getPM(slice.Index(i)) | 39 » » » pm, err := getter(slice.Index(i)) |
33 if !lme.Assign(i, err) { | 40 if !lme.Assign(i, err) { |
34 retPM[i] = pm | 41 retPM[i] = pm |
35 } | 42 } |
36 } | 43 } |
37 } | 44 } |
38 return retKey, retPM, lme.Get() | 45 return retKey, retPM, lme.Get() |
39 } | 46 } |
40 | 47 |
41 // parseMultiArg checks that v has type []S, []*S, []I, []P or []*P, for some | 48 // parseMultiArg checks that v has type []S, []*S, []I, []P or []*P, for some |
42 // struct type S, for some interface type I, or some non-interface non-pointer | 49 // struct type S, for some interface type I, or some non-interface non-pointer |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 func multiArgTypePLS(et reflect.Type) multiArgType { | 90 func multiArgTypePLS(et reflect.Type) multiArgType { |
84 ret := multiArgType{ | 91 ret := multiArgType{ |
85 valid: true, | 92 valid: true, |
86 | 93 |
87 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 94 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
88 return newKeyObjErr(aid, ns, slot.Addr().Interface()) | 95 return newKeyObjErr(aid, ns, slot.Addr().Interface()) |
89 }, | 96 }, |
90 getPM: func(slot reflect.Value) (PropertyMap, error) { | 97 getPM: func(slot reflect.Value) (PropertyMap, error) { |
91 return slot.Addr().Interface().(PropertyLoadSaver).Save(
true) | 98 return slot.Addr().Interface().(PropertyLoadSaver).Save(
true) |
92 }, | 99 }, |
| 100 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 101 return slot.Addr().Interface().(PropertyLoadSaver).GetAl
lMeta() |
| 102 }, |
93 setPM: func(slot reflect.Value, pm PropertyMap) error { | 103 setPM: func(slot reflect.Value, pm PropertyMap) error { |
94 return slot.Addr().Interface().(PropertyLoadSaver).Load(
pm) | 104 return slot.Addr().Interface().(PropertyLoadSaver).Load(
pm) |
95 }, | 105 }, |
96 setKey: func(slot reflect.Value, k *Key) { | 106 setKey: func(slot reflect.Value, k *Key) { |
97 setKey(slot.Addr().Interface(), k) | 107 setKey(slot.Addr().Interface(), k) |
98 }, | 108 }, |
99 } | 109 } |
100 if et.Kind() == reflect.Map { | 110 if et.Kind() == reflect.Map { |
101 ret.newElem = func() reflect.Value { | 111 ret.newElem = func() reflect.Value { |
102 // Create a *map so that way slot.Addr() works above whe
n this is | 112 // Create a *map so that way slot.Addr() works above whe
n this is |
(...skipping 16 matching lines...) Expand all Loading... |
119 func multiArgTypePLSPtr(et reflect.Type) multiArgType { | 129 func multiArgTypePLSPtr(et reflect.Type) multiArgType { |
120 ret := multiArgType{ | 130 ret := multiArgType{ |
121 valid: true, | 131 valid: true, |
122 | 132 |
123 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 133 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
124 return newKeyObjErr(aid, ns, slot.Interface()) | 134 return newKeyObjErr(aid, ns, slot.Interface()) |
125 }, | 135 }, |
126 getPM: func(slot reflect.Value) (PropertyMap, error) { | 136 getPM: func(slot reflect.Value) (PropertyMap, error) { |
127 return slot.Interface().(PropertyLoadSaver).Save(true) | 137 return slot.Interface().(PropertyLoadSaver).Save(true) |
128 }, | 138 }, |
| 139 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 140 return slot.Interface().(PropertyLoadSaver).GetAllMeta() |
| 141 }, |
129 setPM: func(slot reflect.Value, pm PropertyMap) error { | 142 setPM: func(slot reflect.Value, pm PropertyMap) error { |
130 return slot.Interface().(PropertyLoadSaver).Load(pm) | 143 return slot.Interface().(PropertyLoadSaver).Load(pm) |
131 }, | 144 }, |
132 setKey: func(slot reflect.Value, k *Key) { | 145 setKey: func(slot reflect.Value, k *Key) { |
133 setKey(slot.Interface(), k) | 146 setKey(slot.Interface(), k) |
134 }, | 147 }, |
135 } | 148 } |
136 if et.Kind() == reflect.Map { | 149 if et.Kind() == reflect.Map { |
137 ret.newElem = func() reflect.Value { | 150 ret.newElem = func() reflect.Value { |
138 ptr := reflect.New(et) | 151 ptr := reflect.New(et) |
(...skipping 17 matching lines...) Expand all Loading... |
156 } | 169 } |
157 return multiArgType{ | 170 return multiArgType{ |
158 valid: true, | 171 valid: true, |
159 | 172 |
160 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 173 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
161 return newKeyObjErr(aid, ns, toPLS(slot)) | 174 return newKeyObjErr(aid, ns, toPLS(slot)) |
162 }, | 175 }, |
163 getPM: func(slot reflect.Value) (PropertyMap, error) { | 176 getPM: func(slot reflect.Value) (PropertyMap, error) { |
164 return toPLS(slot).(PropertyLoadSaver).Save(true) | 177 return toPLS(slot).(PropertyLoadSaver).Save(true) |
165 }, | 178 }, |
| 179 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 180 return toPLS(slot).(PropertyLoadSaver).GetAllMeta() |
| 181 }, |
166 setPM: func(slot reflect.Value, pm PropertyMap) error { | 182 setPM: func(slot reflect.Value, pm PropertyMap) error { |
167 return toPLS(slot).(PropertyLoadSaver).Load(pm) | 183 return toPLS(slot).(PropertyLoadSaver).Load(pm) |
168 }, | 184 }, |
169 setKey: func(slot reflect.Value, k *Key) { | 185 setKey: func(slot reflect.Value, k *Key) { |
170 setKey(toPLS(slot), k) | 186 setKey(toPLS(slot), k) |
171 }, | 187 }, |
172 newElem: func() reflect.Value { | 188 newElem: func() reflect.Value { |
173 return reflect.New(et).Elem() | 189 return reflect.New(et).Elem() |
174 }, | 190 }, |
175 } | 191 } |
(...skipping 10 matching lines...) Expand all Loading... |
186 } | 202 } |
187 return multiArgType{ | 203 return multiArgType{ |
188 valid: true, | 204 valid: true, |
189 | 205 |
190 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 206 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
191 return newKeyObjErr(aid, ns, toPLS(slot)) | 207 return newKeyObjErr(aid, ns, toPLS(slot)) |
192 }, | 208 }, |
193 getPM: func(slot reflect.Value) (PropertyMap, error) { | 209 getPM: func(slot reflect.Value) (PropertyMap, error) { |
194 return toPLS(slot).(PropertyLoadSaver).Save(true) | 210 return toPLS(slot).(PropertyLoadSaver).Save(true) |
195 }, | 211 }, |
| 212 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 213 return toPLS(slot).(PropertyLoadSaver).GetAllMeta() |
| 214 }, |
196 setPM: func(slot reflect.Value, pm PropertyMap) error { | 215 setPM: func(slot reflect.Value, pm PropertyMap) error { |
197 return toPLS(slot).(PropertyLoadSaver).Load(pm) | 216 return toPLS(slot).(PropertyLoadSaver).Load(pm) |
198 }, | 217 }, |
199 setKey: func(slot reflect.Value, k *Key) { | 218 setKey: func(slot reflect.Value, k *Key) { |
200 setKey(toPLS(slot), k) | 219 setKey(toPLS(slot), k) |
201 }, | 220 }, |
202 newElem: func() reflect.Value { | 221 newElem: func() reflect.Value { |
203 return reflect.New(et) | 222 return reflect.New(et) |
204 }, | 223 }, |
205 } | 224 } |
206 } | 225 } |
207 | 226 |
208 // multiArgTypeInterface == []I | 227 // multiArgTypeInterface == []I |
209 func multiArgTypeInterface() multiArgType { | 228 func multiArgTypeInterface() multiArgType { |
210 return multiArgType{ | 229 return multiArgType{ |
211 valid: true, | 230 valid: true, |
212 | 231 |
213 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 232 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
214 return newKeyObjErr(aid, ns, slot.Elem().Interface()) | 233 return newKeyObjErr(aid, ns, slot.Elem().Interface()) |
215 }, | 234 }, |
216 getPM: func(slot reflect.Value) (PropertyMap, error) { | 235 getPM: func(slot reflect.Value) (PropertyMap, error) { |
217 pls := mkPLS(slot.Elem().Interface()) | 236 pls := mkPLS(slot.Elem().Interface()) |
218 return pls.Save(true) | 237 return pls.Save(true) |
219 }, | 238 }, |
| 239 getMetaPM: func(slot reflect.Value) PropertyMap { |
| 240 pls := mkPLS(slot.Elem().Interface()) |
| 241 return pls.GetAllMeta() |
| 242 }, |
220 setPM: func(slot reflect.Value, pm PropertyMap) error { | 243 setPM: func(slot reflect.Value, pm PropertyMap) error { |
221 pls := mkPLS(slot.Elem().Interface()) | 244 pls := mkPLS(slot.Elem().Interface()) |
222 return pls.Load(pm) | 245 return pls.Load(pm) |
223 }, | 246 }, |
224 setKey: func(slot reflect.Value, k *Key) { | 247 setKey: func(slot reflect.Value, k *Key) { |
225 setKey(slot.Elem().Interface(), k) | 248 setKey(slot.Elem().Interface(), k) |
226 }, | 249 }, |
227 } | 250 } |
228 } | 251 } |
229 | 252 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 _ = pls.SetMeta("parent", key.Parent()) | 285 _ = pls.SetMeta("parent", key.Parent()) |
263 } | 286 } |
264 } | 287 } |
265 | 288 |
266 func mkPLS(o interface{}) PropertyLoadSaver { | 289 func mkPLS(o interface{}) PropertyLoadSaver { |
267 if pls, ok := o.(PropertyLoadSaver); ok { | 290 if pls, ok := o.(PropertyLoadSaver); ok { |
268 return pls | 291 return pls |
269 } | 292 } |
270 return GetPLS(o) | 293 return GetPLS(o) |
271 } | 294 } |
OLD | NEW |