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 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 ret := multiArgType{ | 91 ret := multiArgType{ |
92 valid: true, | 92 valid: true, |
93 | 93 |
94 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 94 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
95 return newKeyObjErr(aid, ns, slot.Addr().Interface()) | 95 return newKeyObjErr(aid, ns, slot.Addr().Interface()) |
96 }, | 96 }, |
97 getPM: func(slot reflect.Value) (PropertyMap, error) { | 97 getPM: func(slot reflect.Value) (PropertyMap, error) { |
98 return slot.Addr().Interface().(PropertyLoadSaver).Save(
true) | 98 return slot.Addr().Interface().(PropertyLoadSaver).Save(
true) |
99 }, | 99 }, |
100 getMetaPM: func(slot reflect.Value) PropertyMap { | 100 getMetaPM: func(slot reflect.Value) PropertyMap { |
101 » » » return slot.Addr().Interface().(PropertyLoadSaver).GetAl
lMeta() | 101 » » » return getMGS(slot.Addr().Interface()).GetAllMeta() |
102 }, | 102 }, |
103 setPM: func(slot reflect.Value, pm PropertyMap) error { | 103 setPM: func(slot reflect.Value, pm PropertyMap) error { |
104 return slot.Addr().Interface().(PropertyLoadSaver).Load(
pm) | 104 return slot.Addr().Interface().(PropertyLoadSaver).Load(
pm) |
105 }, | 105 }, |
106 setKey: func(slot reflect.Value, k *Key) { | 106 setKey: func(slot reflect.Value, k *Key) { |
107 setKey(slot.Addr().Interface(), k) | 107 setKey(slot.Addr().Interface(), k) |
108 }, | 108 }, |
109 } | 109 } |
110 if et.Kind() == reflect.Map { | 110 if et.Kind() == reflect.Map { |
111 ret.newElem = func() reflect.Value { | 111 ret.newElem = func() reflect.Value { |
(...skipping 18 matching lines...) Expand all Loading... |
130 ret := multiArgType{ | 130 ret := multiArgType{ |
131 valid: true, | 131 valid: true, |
132 | 132 |
133 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 133 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
134 return newKeyObjErr(aid, ns, slot.Interface()) | 134 return newKeyObjErr(aid, ns, slot.Interface()) |
135 }, | 135 }, |
136 getPM: func(slot reflect.Value) (PropertyMap, error) { | 136 getPM: func(slot reflect.Value) (PropertyMap, error) { |
137 return slot.Interface().(PropertyLoadSaver).Save(true) | 137 return slot.Interface().(PropertyLoadSaver).Save(true) |
138 }, | 138 }, |
139 getMetaPM: func(slot reflect.Value) PropertyMap { | 139 getMetaPM: func(slot reflect.Value) PropertyMap { |
140 » » » return slot.Interface().(PropertyLoadSaver).GetAllMeta() | 140 » » » return getMGS(slot.Interface()).GetAllMeta() |
141 }, | 141 }, |
142 setPM: func(slot reflect.Value, pm PropertyMap) error { | 142 setPM: func(slot reflect.Value, pm PropertyMap) error { |
143 return slot.Interface().(PropertyLoadSaver).Load(pm) | 143 return slot.Interface().(PropertyLoadSaver).Load(pm) |
144 }, | 144 }, |
145 setKey: func(slot reflect.Value, k *Key) { | 145 setKey: func(slot reflect.Value, k *Key) { |
146 setKey(slot.Interface(), k) | 146 setKey(slot.Interface(), k) |
147 }, | 147 }, |
148 } | 148 } |
149 if et.Kind() == reflect.Map { | 149 if et.Kind() == reflect.Map { |
150 ret.newElem = func() reflect.Value { | 150 ret.newElem = func() reflect.Value { |
151 ptr := reflect.New(et) | 151 ptr := reflect.New(et) |
152 ptr.Elem().Set(reflect.MakeMap(et)) | 152 ptr.Elem().Set(reflect.MakeMap(et)) |
153 return ptr | 153 return ptr |
154 } | 154 } |
155 } else { | 155 } else { |
156 ret.newElem = func() reflect.Value { return reflect.New(et) } | 156 ret.newElem = func() reflect.Value { return reflect.New(et) } |
157 } | 157 } |
158 return ret | 158 return ret |
159 } | 159 } |
160 | 160 |
161 // multiArgTypeStruct == []S | 161 // multiArgTypeStruct == []S |
162 func multiArgTypeStruct(et reflect.Type) multiArgType { | 162 func multiArgTypeStruct(et reflect.Type) multiArgType { |
163 cdc := getCodec(et) | 163 cdc := getCodec(et) |
164 if cdc.problem != nil { | 164 if cdc.problem != nil { |
165 return multiArgTypeInvalid() | 165 return multiArgTypeInvalid() |
166 } | 166 } |
167 » toPLS := func(slot reflect.Value) PropertyLoadSaver { | 167 » toPLS := func(slot reflect.Value) *structPLS { |
168 return &structPLS{slot, cdc} | 168 return &structPLS{slot, cdc} |
169 } | 169 } |
170 return multiArgType{ | 170 return multiArgType{ |
171 valid: true, | 171 valid: true, |
172 | 172 |
173 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 173 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
174 return newKeyObjErr(aid, ns, toPLS(slot)) | 174 return newKeyObjErr(aid, ns, toPLS(slot)) |
175 }, | 175 }, |
176 getPM: func(slot reflect.Value) (PropertyMap, error) { | 176 getPM: func(slot reflect.Value) (PropertyMap, error) { |
177 » » » return toPLS(slot).(PropertyLoadSaver).Save(true) | 177 » » » return toPLS(slot).Save(true) |
178 }, | 178 }, |
179 getMetaPM: func(slot reflect.Value) PropertyMap { | 179 getMetaPM: func(slot reflect.Value) PropertyMap { |
180 » » » return toPLS(slot).(PropertyLoadSaver).GetAllMeta() | 180 » » » if slot.Type().Implements(typeOfMGS) { |
| 181 » » » » return slot.Interface().(MetaGetterSetter).GetAl
lMeta() |
| 182 » » » } |
| 183 » » » return toPLS(slot).GetAllMeta() |
181 }, | 184 }, |
182 setPM: func(slot reflect.Value, pm PropertyMap) error { | 185 setPM: func(slot reflect.Value, pm PropertyMap) error { |
183 » » » return toPLS(slot).(PropertyLoadSaver).Load(pm) | 186 » » » return toPLS(slot).Load(pm) |
184 }, | 187 }, |
185 setKey: func(slot reflect.Value, k *Key) { | 188 setKey: func(slot reflect.Value, k *Key) { |
186 setKey(toPLS(slot), k) | 189 setKey(toPLS(slot), k) |
187 }, | 190 }, |
188 newElem: func() reflect.Value { | 191 newElem: func() reflect.Value { |
189 return reflect.New(et).Elem() | 192 return reflect.New(et).Elem() |
190 }, | 193 }, |
191 } | 194 } |
192 } | 195 } |
193 | 196 |
194 // multiArgTypeStructPtr == []*S | 197 // multiArgTypeStructPtr == []*S |
195 func multiArgTypeStructPtr(et reflect.Type) multiArgType { | 198 func multiArgTypeStructPtr(et reflect.Type) multiArgType { |
196 cdc := getCodec(et) | 199 cdc := getCodec(et) |
197 if cdc.problem != nil { | 200 if cdc.problem != nil { |
198 return multiArgTypeInvalid() | 201 return multiArgTypeInvalid() |
199 } | 202 } |
200 » toPLS := func(slot reflect.Value) PropertyLoadSaver { | 203 » toPLS := func(slot reflect.Value) *structPLS { |
201 return &structPLS{slot.Elem(), cdc} | 204 return &structPLS{slot.Elem(), cdc} |
202 } | 205 } |
203 return multiArgType{ | 206 return multiArgType{ |
204 valid: true, | 207 valid: true, |
205 | 208 |
206 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 209 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
207 return newKeyObjErr(aid, ns, toPLS(slot)) | 210 return newKeyObjErr(aid, ns, toPLS(slot)) |
208 }, | 211 }, |
209 getPM: func(slot reflect.Value) (PropertyMap, error) { | 212 getPM: func(slot reflect.Value) (PropertyMap, error) { |
210 » » » return toPLS(slot).(PropertyLoadSaver).Save(true) | 213 » » » return toPLS(slot).Save(true) |
211 }, | 214 }, |
212 getMetaPM: func(slot reflect.Value) PropertyMap { | 215 getMetaPM: func(slot reflect.Value) PropertyMap { |
213 » » » return toPLS(slot).(PropertyLoadSaver).GetAllMeta() | 216 » » » if slot.Elem().Type().Implements(typeOfMGS) { |
| 217 » » » » return getMGS(slot.Interface()).GetAllMeta() |
| 218 » » » } |
| 219 » » » return toPLS(slot).GetAllMeta() |
214 }, | 220 }, |
215 setPM: func(slot reflect.Value, pm PropertyMap) error { | 221 setPM: func(slot reflect.Value, pm PropertyMap) error { |
216 » » » return toPLS(slot).(PropertyLoadSaver).Load(pm) | 222 » » » return toPLS(slot).Load(pm) |
217 }, | 223 }, |
218 setKey: func(slot reflect.Value, k *Key) { | 224 setKey: func(slot reflect.Value, k *Key) { |
219 setKey(toPLS(slot), k) | 225 setKey(toPLS(slot), k) |
220 }, | 226 }, |
221 newElem: func() reflect.Value { | 227 newElem: func() reflect.Value { |
222 return reflect.New(et) | 228 return reflect.New(et) |
223 }, | 229 }, |
224 } | 230 } |
225 } | 231 } |
226 | 232 |
227 // multiArgTypeInterface == []I | 233 // multiArgTypeInterface == []I |
228 func multiArgTypeInterface() multiArgType { | 234 func multiArgTypeInterface() multiArgType { |
229 return multiArgType{ | 235 return multiArgType{ |
230 valid: true, | 236 valid: true, |
231 | 237 |
232 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { | 238 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { |
233 return newKeyObjErr(aid, ns, slot.Elem().Interface()) | 239 return newKeyObjErr(aid, ns, slot.Elem().Interface()) |
234 }, | 240 }, |
235 getPM: func(slot reflect.Value) (PropertyMap, error) { | 241 getPM: func(slot reflect.Value) (PropertyMap, error) { |
236 pls := mkPLS(slot.Elem().Interface()) | 242 pls := mkPLS(slot.Elem().Interface()) |
237 return pls.Save(true) | 243 return pls.Save(true) |
238 }, | 244 }, |
239 getMetaPM: func(slot reflect.Value) PropertyMap { | 245 getMetaPM: func(slot reflect.Value) PropertyMap { |
240 » » » pls := mkPLS(slot.Elem().Interface()) | 246 » » » pls := getMGS(slot.Elem().Interface()) |
241 return pls.GetAllMeta() | 247 return pls.GetAllMeta() |
242 }, | 248 }, |
243 setPM: func(slot reflect.Value, pm PropertyMap) error { | 249 setPM: func(slot reflect.Value, pm PropertyMap) error { |
244 pls := mkPLS(slot.Elem().Interface()) | 250 pls := mkPLS(slot.Elem().Interface()) |
245 return pls.Load(pm) | 251 return pls.Load(pm) |
246 }, | 252 }, |
247 setKey: func(slot reflect.Value, k *Key) { | 253 setKey: func(slot reflect.Value, k *Key) { |
248 setKey(slot.Elem().Interface(), k) | 254 setKey(slot.Elem().Interface(), k) |
249 }, | 255 }, |
250 } | 256 } |
251 } | 257 } |
252 | 258 |
253 func newKeyObjErr(aid, ns string, src interface{}) (*Key, error) { | 259 func newKeyObjErr(aid, ns string, src interface{}) (*Key, error) { |
254 » pls := mkPLS(src) | 260 » pls := getMGS(src) |
255 if key, _ := pls.GetMetaDefault("key", nil).(*Key); key != nil { | 261 if key, _ := pls.GetMetaDefault("key", nil).(*Key); key != nil { |
256 return key, nil | 262 return key, nil |
257 } | 263 } |
258 | 264 |
259 // get kind | 265 // get kind |
260 kind := pls.GetMetaDefault("kind", "").(string) | 266 kind := pls.GetMetaDefault("kind", "").(string) |
261 if kind == "" { | 267 if kind == "" { |
262 return nil, fmt.Errorf("unable to extract $kind from %T", src) | 268 return nil, fmt.Errorf("unable to extract $kind from %T", src) |
263 } | 269 } |
264 | 270 |
265 // get id - allow both to be default for default keys | 271 // get id - allow both to be default for default keys |
266 sid := pls.GetMetaDefault("id", "").(string) | 272 sid := pls.GetMetaDefault("id", "").(string) |
267 iid := pls.GetMetaDefault("id", 0).(int64) | 273 iid := pls.GetMetaDefault("id", 0).(int64) |
268 | 274 |
269 // get parent | 275 // get parent |
270 par, _ := pls.GetMetaDefault("parent", nil).(*Key) | 276 par, _ := pls.GetMetaDefault("parent", nil).(*Key) |
271 | 277 |
272 return NewKey(aid, ns, kind, sid, iid, par), nil | 278 return NewKey(aid, ns, kind, sid, iid, par), nil |
273 } | 279 } |
274 | 280 |
275 func setKey(src interface{}, key *Key) { | 281 func setKey(src interface{}, key *Key) { |
276 » pls := mkPLS(src) | 282 » pls := getMGS(src) |
277 if pls.SetMeta("key", key) == ErrMetaFieldUnset { | 283 if pls.SetMeta("key", key) == ErrMetaFieldUnset { |
278 lst := key.LastTok() | 284 lst := key.LastTok() |
279 if lst.StringID != "" { | 285 if lst.StringID != "" { |
280 _ = pls.SetMeta("id", lst.StringID) | 286 _ = pls.SetMeta("id", lst.StringID) |
281 } else { | 287 } else { |
282 _ = pls.SetMeta("id", lst.IntID) | 288 _ = pls.SetMeta("id", lst.IntID) |
283 } | 289 } |
284 _ = pls.SetMeta("kind", lst.Kind) | 290 _ = pls.SetMeta("kind", lst.Kind) |
285 _ = pls.SetMeta("parent", key.Parent()) | 291 _ = pls.SetMeta("parent", key.Parent()) |
286 } | 292 } |
287 } | 293 } |
288 | 294 |
289 func mkPLS(o interface{}) PropertyLoadSaver { | 295 func mkPLS(o interface{}) PropertyLoadSaver { |
290 if pls, ok := o.(PropertyLoadSaver); ok { | 296 if pls, ok := o.(PropertyLoadSaver); ok { |
291 return pls | 297 return pls |
292 } | 298 } |
293 return GetPLS(o) | 299 return GetPLS(o) |
294 } | 300 } |
OLD | NEW |