func TestStringMeaning(t *testing.T) { var xx [4]interface{} xx[0] = &struct { X string }{"xx0"} xx[1] = &struct { X string `datastore:",noindex"` }{"xx1"} xx[2] = &struct { X []byte }{[]byte("xx2")} xx[3] = &struct { X []byte `datastore:",noindex"` }{[]byte("xx3")} indexed := [4]bool{ true, false, false, // A []byte is always no-index. false, } want := [4]pb.Property_Meaning{ pb.Property_NO_MEANING, pb.Property_TEXT, pb.Property_BLOB, pb.Property_BLOB, } for i, x := range xx { c := make(chan Property, 1) err := SaveStruct(x, c) if err != nil { t.Errorf("i=%d: SaveStruct: %v", i, err) continue } e, err := propertiesToProto("appID", testKey0, c) if err != nil { t.Errorf("i=%d: propertiesToProto: %v", i, err) continue } var p *pb.Property switch { case indexed[i] && len(e.Property) == 1: p = e.Property[0] case !indexed[i] && len(e.RawProperty) == 1: p = e.RawProperty[0] default: t.Errorf("i=%d: EntityProto did not have expected property slice", i) continue } if got := p.GetMeaning(); got != want[i] { t.Errorf("i=%d: meaning: got %v, want %v", i, got, want[i]) continue } } }
func protoToEntity(src *pb.EntityProto) (*Entity, error) { props, rawProps := src.Property, src.RawProperty outProps := make([]Property, 0, len(props)+len(rawProps)) for { var ( x *pb.Property noIndex bool ) if len(props) > 0 { x, props = props[0], props[1:] } else if len(rawProps) > 0 { x, rawProps = rawProps[0], rawProps[1:] noIndex = true } else { break } var value interface{} if x.Meaning != nil && *x.Meaning == pb.Property_INDEX_VALUE { value = indexValue{x.Value} } else { var err error value, err = propValue(x.Value, x.GetMeaning()) if err != nil { return nil, err } } outProps = append(outProps, Property{ Name: x.GetName(), Value: value, NoIndex: noIndex, Multiple: x.GetMultiple(), }) } var key *Key if src.Key != nil { // Ignore any error, since nested entity values // are allowed to have an invalid key. key, _ = protoToKey(src.Key) } return &Entity{key, outProps}, nil }
func protoToProperties(dst chan<- Property, errc chan<- error, src *pb.EntityProto) { defer close(dst) props, rawProps := src.Property, src.RawProperty for { var ( x *pb.Property noIndex bool ) if len(props) > 0 { x, props = props[0], props[1:] } else if len(rawProps) > 0 { x, rawProps = rawProps[0], rawProps[1:] noIndex = true } else { break } var value interface{} if x.Meaning != nil && *x.Meaning == pb.Property_INDEX_VALUE { value = indexValue{x.Value} } else { var err error value, err = propValue(x.Value, x.GetMeaning()) if err != nil { errc <- err return } } dst <- Property{ Name: x.GetName(), Value: value, NoIndex: noIndex, Multiple: x.GetMultiple(), } } errc <- nil }
func protoToProperties(src *pb.EntityProto) ([]Property, error) { props, rawProps := src.Property, src.RawProperty out := make([]Property, 0, len(props)+len(rawProps)) for { var ( x *pb.Property noIndex bool ) if len(props) > 0 { x, props = props[0], props[1:] } else if len(rawProps) > 0 { x, rawProps = rawProps[0], rawProps[1:] noIndex = true } else { break } var value interface{} if x.Meaning != nil && *x.Meaning == pb.Property_INDEX_VALUE { value = indexValue{x.Value} } else { var err error value, err = propValue(x.Value, x.GetMeaning()) if err != nil { return nil, err } } out = append(out, Property{ Name: x.GetName(), Value: value, NoIndex: noIndex, Multiple: x.GetMultiple(), }) } return out, nil }