Chromium Code Reviews| Index: service/datastore/pls_impl.go |
| diff --git a/service/datastore/pls_impl.go b/service/datastore/pls_impl.go |
| index b5e945ccfb5224e545889feca88084247123f8a5..d0f67488fa15f75a881451010a205a2e60bfa36c 100644 |
| --- a/service/datastore/pls_impl.go |
| +++ b/service/datastore/pls_impl.go |
| @@ -298,7 +298,7 @@ func (p *structPLS) GetMeta(key string) (interface{}, error) { |
| } |
| if idx, ok := p.c.byMeta[key]; ok { |
| - return p.getMetaFor(idx), nil |
| + return p.getMetaFor(idx) |
| } |
| if key == "kind" { |
| @@ -307,11 +307,19 @@ func (p *structPLS) GetMeta(key string) (interface{}, error) { |
| return nil, ErrMetaFieldUnset |
| } |
| -func (p *structPLS) getMetaFor(idx int) interface{} { |
| +func (p *structPLS) getMetaFor(idx int) (interface{}, error) { |
| st := p.c.byIndex[idx] |
| val := st.metaVal |
| - f := p.o.Field(idx) |
| if st.canSet { |
| + f := p.o.Field(idx) |
| + if st.convert { |
| + prop, err := f.Addr().Interface().(PropertyConverter).ToProperty() |
| + if err == nil { |
|
dnj
2015/11/03 01:18:10
nit: Handle err != nil (more standard).
|
| + return prop.value, err |
| + } |
| + return nil, err |
| + } |
| + |
| if !reflect.DeepEqual(reflect.Zero(f.Type()).Interface(), f.Interface()) { |
| val = f.Interface() |
| if bf, ok := val.(Toggle); ok { |
| @@ -319,19 +327,21 @@ func (p *structPLS) getMetaFor(idx int) interface{} { |
| } |
| } |
| } |
| - return val |
| + return val, nil |
| } |
| func (p *structPLS) GetAllMeta() PropertyMap { |
| needKind := true |
| ret := make(PropertyMap, len(p.c.byMeta)+1) |
| for k, idx := range p.c.byMeta { |
| - val := p.getMetaFor(idx) |
| - p := Property{} |
| - if err := p.SetValue(val, NoIndex); err != nil { |
| - continue |
| + val, err := p.getMetaFor(idx) |
|
dnj
2015/11/03 01:18:10
Do we care about non-nil errors? If not, have getM
iannucci
2015/11/03 01:29:12
eh, returning an error is standarder
dnj
2015/11/03 03:11:25
Gah I I don't like the feel of returning an error
iannucci
2015/11/03 20:29:32
done
|
| + if err == nil { |
| + p := Property{} |
| + if err := p.SetValue(val, NoIndex); err != nil { |
| + continue |
| + } |
| + ret["$"+k] = []Property{p} |
| } |
| - ret["$"+k] = []Property{p} |
| } |
| if needKind { |
| if _, ok := p.c.byMeta["kind"]; !ok { |
| @@ -353,9 +363,15 @@ func (p *structPLS) SetMeta(key string, val interface{}) (err error) { |
| if !ok { |
| return ErrMetaFieldUnset |
| } |
| - if !p.c.byIndex[idx].canSet { |
| + st := p.c.byIndex[idx] |
| + if !st.canSet { |
| return fmt.Errorf("gae/helper: cannot set meta %q: unexported field", key) |
| } |
| + if st.convert { |
| + return p.o.Field(idx).Addr().Interface().(PropertyConverter).FromProperty( |
| + MkPropertyNI(val)) |
| + } |
| + |
| // setting a BoolField |
| if b, ok := val.(bool); ok { |
| if b { |
| @@ -443,12 +459,17 @@ func getStructCodecLocked(t reflect.Type) (c *structCodec) { |
| for i := range c.byIndex { |
| st := &c.byIndex[i] |
| f := t.Field(i) |
| + ft := f.Type |
| + |
| name := f.Tag.Get("gae") |
| opts := "" |
| if i := strings.Index(name, ","); i != -1 { |
| name, opts = name[:i], name[i+1:] |
| } |
| st.canSet = f.PkgPath == "" // blank == exported |
| + if reflect.PtrTo(ft).Implements(typeOfPropertyConverter) { |
|
dnj
2015/11/03 01:18:10
nit: st.convert = reflect.PtrTo(ft)....
iannucci
2015/11/03 01:29:12
DERP
|
| + st.convert = true |
| + } |
| switch { |
| case name == "": |
| if !f.Anonymous { |
| @@ -461,12 +482,14 @@ func getStructCodecLocked(t reflect.Type) (c *structCodec) { |
| return |
| } |
| c.byMeta[name] = i |
| - mv, err := convertMeta(opts, f.Type) |
| - if err != nil { |
| - c.problem = me("meta field %q has bad type: %s", "$"+name, err) |
| - return |
| + if !st.convert { |
| + mv, err := convertMeta(opts, f.Type) |
|
dnj
2015/11/03 01:18:10
nit: f.Type => ft
iannucci
2015/11/03 01:29:13
done (and others)
|
| + if err != nil { |
| + c.problem = me("meta field %q has bad type: %s", "$"+name, err) |
| + return |
| + } |
| + st.metaVal = mv |
| } |
| - st.metaVal = mv |
| fallthrough |
| case name == "-": |
| st.name = "-" |
| @@ -483,10 +506,7 @@ func getStructCodecLocked(t reflect.Type) (c *structCodec) { |
| } |
| substructType := reflect.Type(nil) |
| - ft := f.Type |
| - if reflect.PtrTo(ft).Implements(typeOfPropertyConverter) { |
| - st.convert = true |
| - } else { |
| + if !st.convert { |
| switch f.Type.Kind() { |
| case reflect.Struct: |
| if ft != typeOfTime && ft != typeOfGeoPoint { |