Index: service/datastore/pls_impl.go |
diff --git a/service/datastore/pls_impl.go b/service/datastore/pls_impl.go |
index 4380d65db1b66d0fef7624117d387f7e29af71bc..8f353290322bbeac12e180ca38ae4cc96aa77e7c 100644 |
--- a/service/datastore/pls_impl.go |
+++ b/service/datastore/pls_impl.go |
@@ -69,16 +69,17 @@ func (p *structPLS) Load(propMap PropertyMap) error { |
} |
} |
t := reflect.Type(nil) |
- for name, props := range propMap { |
- multiple := len(props) > 1 |
- for i, prop := range props { |
- if reason := loadInner(p.c, p.o, i, name, prop, multiple); reason != "" { |
+ for name, pdata := range propMap { |
+ pslice := pdata.Slice() |
+ requireSlice := len(pslice) > 1 |
+ for i, prop := range pslice { |
+ if reason := loadInner(p.c, p.o, i, name, prop, requireSlice); reason != "" { |
if useExtra { |
if extra != nil { |
if *extra == nil { |
*extra = make(PropertyMap, 1) |
} |
- (*extra)[name] = props |
+ (*extra)[name] = pslice |
} |
break // go to the next property in propMap |
} else { |
@@ -241,7 +242,7 @@ func (p *structPLS) Save(withMeta bool) (PropertyMap, error) { |
} else { |
ret = make(PropertyMap, len(p.c.byName)) |
} |
- if _, err := p.save(ret, "", ShouldIndex); err != nil { |
+ if _, err := p.save(ret, "", nil, ShouldIndex); err != nil { |
return nil, err |
} |
return ret, nil |
@@ -254,10 +255,10 @@ func (p *structPLS) getDefaultKind() string { |
return p.o.Type().Name() |
} |
-func (p *structPLS) save(propMap PropertyMap, prefix string, is IndexSetting) (idxCount int, err error) { |
+func (p *structPLS) save(propMap PropertyMap, prefix string, parentST *structTag, is IndexSetting) (idxCount int, err error) { |
saveProp := func(name string, si IndexSetting, v reflect.Value, st *structTag) (err error) { |
if st.substructCodec != nil { |
- count, err := (&structPLS{v, st.substructCodec, nil}).save(propMap, name, si) |
+ count, err := (&structPLS{v, st.substructCodec, nil}).save(propMap, name, st, si) |
if err == nil { |
idxCount += count |
if idxCount > maxIndexedProperties { |
@@ -276,7 +277,21 @@ func (p *structPLS) save(propMap PropertyMap, prefix string, is IndexSetting) (i |
if err != nil { |
return err |
} |
- propMap[name] = append(propMap[name], prop) |
+ |
+ // If we're a slice, or we are members in a slice, then use a PropertySlice. |
+ if st.isSlice || (parentST != nil && parentST.isSlice) { |
+ var pslice PropertySlice |
+ if pdata := propMap[name]; pdata != nil { |
+ pslice = pdata.(PropertySlice) |
+ } |
+ propMap[name] = append(pslice, prop) |
+ } else { |
+ if _, ok := propMap[name]; ok { |
+ return errors.New("non-slice property adding multiple PropertyMap entries") |
+ } |
+ propMap[name] = prop |
+ } |
+ |
if prop.IndexSetting() == ShouldIndex { |
idxCount++ |
if idxCount > maxIndexedProperties { |
@@ -302,11 +317,13 @@ func (p *structPLS) save(propMap PropertyMap, prefix string, is IndexSetting) (i |
if st.isSlice { |
for j := 0; j < v.Len(); j++ { |
if err = saveProp(name, is1, v.Index(j), &st); err != nil { |
+ err = fmt.Errorf("gae: failed to save slice field %q: %v", name, err) |
return |
} |
} |
} else { |
if err = saveProp(name, is1, v, &st); err != nil { |
+ err = fmt.Errorf("gae: failed to save single field %q: %v", name, err) |
return |
} |
} |
@@ -370,12 +387,12 @@ func (p *structPLS) GetAllMeta() PropertyMap { |
if err := p.SetValue(val, NoIndex); err != nil { |
continue |
} |
- ret["$"+k] = []Property{p} |
+ ret["$"+k] = p |
} |
} |
if needKind { |
if _, ok := p.c.byMeta["kind"]; !ok { |
- ret["$kind"] = []Property{MkPropertyNI(p.getDefaultKind())} |
+ ret["$kind"] = MkPropertyNI(p.getDefaultKind()) |
} |
} |
return ret |