Index: service/datastore/pls_impl.go |
diff --git a/service/datastore/pls_impl.go b/service/datastore/pls_impl.go |
index 067ed06e325094d37698129a0c3d4fc38505153c..535b8d524b1acb868bb3889f1111e45ccf259c11 100644 |
--- a/service/datastore/pls_impl.go |
+++ b/service/datastore/pls_impl.go |
@@ -35,6 +35,7 @@ type structCodec struct { |
byName map[string]int |
byIndex []structTag |
hasSlice bool |
+ mgs bool |
problem error |
} |
@@ -43,6 +44,13 @@ type structPLS struct { |
c *structCodec |
} |
+func (p *structPLS) getMGS() MetaGetterSetter { |
+ if !p.c.mgs { |
+ return nil |
+ } |
+ return p.o.Addr().Interface().(MetaGetterSetter) |
+} |
+ |
var _ PropertyLoadSaver = (*structPLS)(nil) |
// typeMismatchReason returns a string explaining why the property p could not |
@@ -289,14 +297,23 @@ func (p *structPLS) GetMeta(key string) (interface{}, error) { |
if err := p.Problem(); err != nil { |
return nil, err |
} |
- idx, ok := p.c.byMeta[key] |
- if !ok { |
- if key == "kind" { |
- return p.getDefaultKind(), nil |
+ |
+ if idx, ok := p.c.byMeta[key]; ok { |
+ return p.getMetaFor(idx), nil |
+ } |
+ |
+ if p.c.mgs { |
+ ret, err := p.getMGS().GetMeta(key) |
+ if err == nil { |
+ return ret, err |
+ } else if err != ErrMetaFieldUnset { |
+ return nil, err |
} |
- return nil, ErrMetaFieldUnset |
} |
- return p.getMetaFor(idx), nil |
+ if key == "kind" { |
+ return p.getDefaultKind(), nil |
+ } |
+ return nil, ErrMetaFieldUnset |
} |
func (p *structPLS) getMetaFor(idx int) interface{} { |
@@ -315,7 +332,15 @@ func (p *structPLS) getMetaFor(idx int) interface{} { |
} |
func (p *structPLS) GetAllMeta() PropertyMap { |
- ret := make(PropertyMap, len(p.c.byMeta)+1) |
+ ret := PropertyMap(nil) |
+ needKind := true |
+ if p.c.mgs { |
+ ret = p.getMGS().GetAllMeta() |
+ _, haveKind := ret["$kind"] |
+ needKind = !haveKind |
+ } else { |
+ ret = make(PropertyMap, len(p.c.byMeta)+1) |
+ } |
for k, idx := range p.c.byMeta { |
val := p.getMetaFor(idx) |
p := Property{} |
@@ -324,8 +349,10 @@ func (p *structPLS) GetAllMeta() PropertyMap { |
} |
ret["$"+k] = []Property{p} |
} |
- if _, ok := p.c.byMeta["kind"]; !ok { |
- ret["$kind"] = []Property{MkPropertyNI(p.getDefaultKind())} |
+ if needKind { |
+ if _, ok := p.c.byMeta["kind"]; !ok { |
+ ret["$kind"] = []Property{MkPropertyNI(p.getDefaultKind())} |
+ } |
} |
return ret |
} |
@@ -340,6 +367,9 @@ func (p *structPLS) SetMeta(key string, val interface{}) (err error) { |
} |
idx, ok := p.c.byMeta[key] |
if !ok { |
+ if p.c.mgs { |
+ return p.getMGS().SetMeta(key, val) |
+ } |
return ErrMetaFieldUnset |
} |
if !p.c.byIndex[idx].canSet { |
@@ -418,6 +448,7 @@ func getStructCodecLocked(t reflect.Type) (c *structCodec) { |
byName: make(map[string]int, t.NumField()), |
byMeta: make(map[string]int, t.NumField()), |
problem: errRecursiveStruct, // we'll clear this later if it's not recursive |
+ mgs: reflect.PtrTo(t).Implements(typeOfMGS), |
} |
defer func() { |
// If the codec has a problem, free up the indexes |