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 // HEAVILY adapted from github.com/golang/appengine/datastore | 5 // HEAVILY adapted from github.com/golang/appengine/datastore |
6 | 6 |
7 package datastore | 7 package datastore |
8 | 8 |
9 import ( | 9 import ( |
10 "fmt" | 10 "fmt" |
(...skipping 17 matching lines...) Expand all Loading... |
28 convert bool | 28 convert bool |
29 metaVal interface{} | 29 metaVal interface{} |
30 canSet bool | 30 canSet bool |
31 } | 31 } |
32 | 32 |
33 type structCodec struct { | 33 type structCodec struct { |
34 byMeta map[string]int | 34 byMeta map[string]int |
35 byName map[string]int | 35 byName map[string]int |
36 byIndex []structTag | 36 byIndex []structTag |
37 hasSlice bool | 37 hasSlice bool |
38 mgs bool | |
39 problem error | 38 problem error |
40 } | 39 } |
41 | 40 |
42 type structPLS struct { | 41 type structPLS struct { |
43 o reflect.Value | 42 o reflect.Value |
44 c *structCodec | 43 c *structCodec |
45 } | 44 } |
46 | 45 |
47 func (p *structPLS) getMGS() MetaGetterSetter { | |
48 if !p.c.mgs { | |
49 return nil | |
50 } | |
51 return p.o.Addr().Interface().(MetaGetterSetter) | |
52 } | |
53 | |
54 var _ PropertyLoadSaver = (*structPLS)(nil) | 46 var _ PropertyLoadSaver = (*structPLS)(nil) |
55 | 47 |
56 // typeMismatchReason returns a string explaining why the property p could not | 48 // typeMismatchReason returns a string explaining why the property p could not |
57 // be stored in an entity field of type v.Type(). | 49 // be stored in an entity field of type v.Type(). |
58 func typeMismatchReason(val interface{}, v reflect.Value) string { | 50 func typeMismatchReason(val interface{}, v reflect.Value) string { |
59 entityType := reflect.TypeOf(val) | 51 entityType := reflect.TypeOf(val) |
60 return fmt.Sprintf("type mismatch: %s versus %v", entityType, v.Type()) | 52 return fmt.Sprintf("type mismatch: %s versus %v", entityType, v.Type()) |
61 } | 53 } |
62 | 54 |
63 func (p *structPLS) Load(propMap PropertyMap) error { | 55 func (p *structPLS) Load(propMap PropertyMap) error { |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 } else { | 211 } else { |
220 ret = make(PropertyMap, len(p.c.byName)) | 212 ret = make(PropertyMap, len(p.c.byName)) |
221 } | 213 } |
222 if _, err := p.save(ret, "", ShouldIndex); err != nil { | 214 if _, err := p.save(ret, "", ShouldIndex); err != nil { |
223 return nil, err | 215 return nil, err |
224 } | 216 } |
225 return ret, nil | 217 return ret, nil |
226 } | 218 } |
227 | 219 |
228 func (p *structPLS) getDefaultKind() string { | 220 func (p *structPLS) getDefaultKind() string { |
| 221 if !p.o.IsValid() { |
| 222 return "" |
| 223 } |
229 return p.o.Type().Name() | 224 return p.o.Type().Name() |
230 } | 225 } |
231 | 226 |
232 func (p *structPLS) save(propMap PropertyMap, prefix string, is IndexSetting) (i
dxCount int, err error) { | 227 func (p *structPLS) save(propMap PropertyMap, prefix string, is IndexSetting) (i
dxCount int, err error) { |
233 if err = p.Problem(); err != nil { | 228 if err = p.Problem(); err != nil { |
234 return | 229 return |
235 } | 230 } |
236 | 231 |
237 saveProp := func(name string, si IndexSetting, v reflect.Value, st *stru
ctTag) (err error) { | 232 saveProp := func(name string, si IndexSetting, v reflect.Value, st *stru
ctTag) (err error) { |
238 if st.substructCodec != nil { | 233 if st.substructCodec != nil { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 | 290 |
296 func (p *structPLS) GetMeta(key string) (interface{}, error) { | 291 func (p *structPLS) GetMeta(key string) (interface{}, error) { |
297 if err := p.Problem(); err != nil { | 292 if err := p.Problem(); err != nil { |
298 return nil, err | 293 return nil, err |
299 } | 294 } |
300 | 295 |
301 if idx, ok := p.c.byMeta[key]; ok { | 296 if idx, ok := p.c.byMeta[key]; ok { |
302 return p.getMetaFor(idx), nil | 297 return p.getMetaFor(idx), nil |
303 } | 298 } |
304 | 299 |
305 if p.c.mgs { | |
306 ret, err := p.getMGS().GetMeta(key) | |
307 if err == nil { | |
308 return ret, err | |
309 } else if err != ErrMetaFieldUnset { | |
310 return nil, err | |
311 } | |
312 } | |
313 if key == "kind" { | 300 if key == "kind" { |
314 return p.getDefaultKind(), nil | 301 return p.getDefaultKind(), nil |
315 } | 302 } |
316 return nil, ErrMetaFieldUnset | 303 return nil, ErrMetaFieldUnset |
317 } | 304 } |
318 | 305 |
319 func (p *structPLS) getMetaFor(idx int) interface{} { | 306 func (p *structPLS) getMetaFor(idx int) interface{} { |
320 st := p.c.byIndex[idx] | 307 st := p.c.byIndex[idx] |
321 val := st.metaVal | 308 val := st.metaVal |
322 f := p.o.Field(idx) | 309 f := p.o.Field(idx) |
323 if st.canSet { | 310 if st.canSet { |
324 if !reflect.DeepEqual(reflect.Zero(f.Type()).Interface(), f.Inte
rface()) { | 311 if !reflect.DeepEqual(reflect.Zero(f.Type()).Interface(), f.Inte
rface()) { |
325 val = f.Interface() | 312 val = f.Interface() |
326 if bf, ok := val.(Toggle); ok { | 313 if bf, ok := val.(Toggle); ok { |
327 val = bf == On // true if On, otherwise false | 314 val = bf == On // true if On, otherwise false |
328 } | 315 } |
329 } | 316 } |
330 } | 317 } |
331 return val | 318 return val |
332 } | 319 } |
333 | 320 |
334 func (p *structPLS) GetAllMeta() PropertyMap { | 321 func (p *structPLS) GetAllMeta() PropertyMap { |
335 ret := PropertyMap(nil) | |
336 needKind := true | 322 needKind := true |
337 » if p.c.mgs { | 323 » ret := make(PropertyMap, len(p.c.byMeta)+1) |
338 » » ret = p.getMGS().GetAllMeta() | |
339 » » _, haveKind := ret["$kind"] | |
340 » » needKind = !haveKind | |
341 » } else { | |
342 » » ret = make(PropertyMap, len(p.c.byMeta)+1) | |
343 » } | |
344 for k, idx := range p.c.byMeta { | 324 for k, idx := range p.c.byMeta { |
345 val := p.getMetaFor(idx) | 325 val := p.getMetaFor(idx) |
346 p := Property{} | 326 p := Property{} |
347 if err := p.SetValue(val, NoIndex); err != nil { | 327 if err := p.SetValue(val, NoIndex); err != nil { |
348 continue | 328 continue |
349 } | 329 } |
350 ret["$"+k] = []Property{p} | 330 ret["$"+k] = []Property{p} |
351 } | 331 } |
352 if needKind { | 332 if needKind { |
353 if _, ok := p.c.byMeta["kind"]; !ok { | 333 if _, ok := p.c.byMeta["kind"]; !ok { |
354 ret["$kind"] = []Property{MkPropertyNI(p.getDefaultKind(
))} | 334 ret["$kind"] = []Property{MkPropertyNI(p.getDefaultKind(
))} |
355 } | 335 } |
356 } | 336 } |
357 return ret | 337 return ret |
358 } | 338 } |
359 | 339 |
360 func (p *structPLS) GetMetaDefault(key string, def interface{}) interface{} { | 340 func (p *structPLS) GetMetaDefault(key string, def interface{}) interface{} { |
361 return GetMetaDefaultImpl(p.GetMeta, key, def) | 341 return GetMetaDefaultImpl(p.GetMeta, key, def) |
362 } | 342 } |
363 | 343 |
364 func (p *structPLS) SetMeta(key string, val interface{}) (err error) { | 344 func (p *structPLS) SetMeta(key string, val interface{}) (err error) { |
365 if err = p.Problem(); err != nil { | 345 if err = p.Problem(); err != nil { |
366 return | 346 return |
367 } | 347 } |
368 idx, ok := p.c.byMeta[key] | 348 idx, ok := p.c.byMeta[key] |
369 if !ok { | 349 if !ok { |
370 if p.c.mgs { | |
371 return p.getMGS().SetMeta(key, val) | |
372 } | |
373 return ErrMetaFieldUnset | 350 return ErrMetaFieldUnset |
374 } | 351 } |
375 if !p.c.byIndex[idx].canSet { | 352 if !p.c.byIndex[idx].canSet { |
376 return fmt.Errorf("gae/helper: cannot set meta %q: unexported fi
eld", key) | 353 return fmt.Errorf("gae/helper: cannot set meta %q: unexported fi
eld", key) |
377 } | 354 } |
378 // setting a BoolField | 355 // setting a BoolField |
379 if b, ok := val.(bool); ok { | 356 if b, ok := val.(bool); ok { |
380 if b { | 357 if b { |
381 val = On | 358 val = On |
382 } else { | 359 } else { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 | 418 |
442 me := func(fmtStr string, args ...interface{}) error { | 419 me := func(fmtStr string, args ...interface{}) error { |
443 return fmt.Errorf(fmtStr, args...) | 420 return fmt.Errorf(fmtStr, args...) |
444 } | 421 } |
445 | 422 |
446 c = &structCodec{ | 423 c = &structCodec{ |
447 byIndex: make([]structTag, t.NumField()), | 424 byIndex: make([]structTag, t.NumField()), |
448 byName: make(map[string]int, t.NumField()), | 425 byName: make(map[string]int, t.NumField()), |
449 byMeta: make(map[string]int, t.NumField()), | 426 byMeta: make(map[string]int, t.NumField()), |
450 problem: errRecursiveStruct, // we'll clear this later if it's n
ot recursive | 427 problem: errRecursiveStruct, // we'll clear this later if it's n
ot recursive |
451 mgs: reflect.PtrTo(t).Implements(typeOfMGS), | |
452 } | 428 } |
453 defer func() { | 429 defer func() { |
454 // If the codec has a problem, free up the indexes | 430 // If the codec has a problem, free up the indexes |
455 if c.problem != nil { | 431 if c.problem != nil { |
456 c.byIndex = nil | 432 c.byIndex = nil |
457 c.byName = nil | 433 c.byName = nil |
458 c.byMeta = nil | 434 c.byMeta = nil |
459 } | 435 } |
460 }() | 436 }() |
461 structCodecs[t] = c | 437 structCodecs[t] = c |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 switch val { | 580 switch val { |
605 case "on", "On", "true": | 581 case "on", "On", "true": |
606 return true, nil | 582 return true, nil |
607 case "off", "Off", "false": | 583 case "off", "Off", "false": |
608 return false, nil | 584 return false, nil |
609 } | 585 } |
610 return nil, fmt.Errorf("Toggle field has bad/missing default, go
t %q", val) | 586 return nil, fmt.Errorf("Toggle field has bad/missing default, go
t %q", val) |
611 } | 587 } |
612 return nil, fmt.Errorf("helper: meta field with bad type/value %s/%q", t
, val) | 588 return nil, fmt.Errorf("helper: meta field with bad type/value %s/%q", t
, val) |
613 } | 589 } |
OLD | NEW |