func (tf *typeFilter) Save() ([]datastore.Property, error) { props := []datastore.Property{} for name, propList := range tf.pm { if len(name) != 0 && name[0] == '$' { continue } multiple := len(propList) > 1 for _, prop := range propList { toAdd := datastore.Property{ Name: name, Multiple: multiple, NoIndex: prop.IndexSetting() == ds.NoIndex, } switch prop.Type() { case ds.PTBytes: v := prop.Value().([]byte) if prop.IndexSetting() == ds.ShouldIndex { toAdd.Value = datastore.ByteString(v) } else { toAdd.Value = v } case ds.PTKey: toAdd.Value = dsF2R(prop.Value().(ds.Key)) case ds.PTBlobKey: toAdd.Value = appengine.BlobKey(prop.Value().(bs.Key)) case ds.PTGeoPoint: toAdd.Value = appengine.GeoPoint(prop.Value().(ds.GeoPoint)) default: toAdd.Value = prop.Value() } props = append(props, toAdd) } } return props, nil }
func decodeJSONPrimitiveValue(v interface{}, p *datastore.Property) error { switch v.(type) { case json.Number: n := v.(json.Number) if strings.Contains(n.String(), ".") { // float64 p.Value, _ = n.Float64() } else { // int64 p.Value, _ = n.Int64() } case string: p.Value = v.(string) case bool: p.Value = v.(bool) case nil: p.Value = nil default: return fmt.Errorf("Invalid primitive value: %#v", v) } return nil }
func PropertyListToMap(pl *datastore.PropertyList) map[string]interface{} { var ret = make(map[string]interface{}, 0) var prop datastore.Property li, _ := pl.Save() for _, prop = range li { if prop.Name == "htmlContent" { prop.Value = string(prop.Value.([]byte)[:]) } ret[prop.Name] = prop.Value } return ret }
func dsF2RProp(ctx context.Context, in ds.Property) (datastore.Property, error) { err := error(nil) ret := datastore.Property{ NoIndex: in.IndexSetting() == ds.NoIndex, } switch in.Type() { case ds.PTBytes: v := in.Value().([]byte) if in.IndexSetting() == ds.ShouldIndex { ret.Value = datastore.ByteString(v) } else { ret.Value = v } case ds.PTKey: ret.Value, err = dsF2R(ctx, in.Value().(*ds.Key)) case ds.PTBlobKey: ret.Value = appengine.BlobKey(in.Value().(bs.Key)) case ds.PTGeoPoint: ret.Value = appengine.GeoPoint(in.Value().(ds.GeoPoint)) default: ret.Value = in.Value() } return ret, err }
func convertJsonValueToProperties(k string, v interface{}) []datastore.Property { var propertyList []datastore.Property var value = reflect.ValueOf(v) switch value.Kind() { case reflect.String: p := datastore.Property{Name: k} s := v.(string) if strings.HasPrefix(s, "[]") { p.Value = []byte(strings.TrimPrefix(s, "[]")) p.NoIndex = true propertyList = append(propertyList, p) } else { if dt, err := wcg.ParseDateTime(fmt.Sprintf("%s", v)); err == nil { p.Value = dt propertyList = append(propertyList, p) } else if d, err := wcg.ParseDate(fmt.Sprintf("%s", v)); err == nil { p.Value = d propertyList = append(propertyList, p) } else { p.Value = s propertyList = append(propertyList, p) } } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: // reach here from FixtureFromMap since it can contain non floating number. var vv int64 switch v.(type) { case int: vv = int64(v.(int)) case int8: vv = int64(v.(int8)) case int16: vv = int64(v.(int16)) case int32: vv = int64(v.(int32)) case int64: vv = v.(int64) } propertyList = append(propertyList, datastore.Property{ Name: k, Value: vv, }) case reflect.Float32, reflect.Float64: str := []byte(fmt.Sprintf("%f", v)) if _floatRe.Match(str) { // should be int. propertyList = append(propertyList, datastore.Property{ Name: k, Value: int64(v.(float64)), }) } else { propertyList = append(propertyList, datastore.Property{ Name: k, Value: v, }) } case reflect.Bool: propertyList = append(propertyList, datastore.Property{ Name: k, Value: v, }) case reflect.Map: for k1, v1 := range v.(map[string]interface{}) { if !strings.HasPrefix(k1, "_") { for _, val := range convertJsonValueToProperties(k1, v1) { propertyList = append(propertyList, datastore.Property{ Name: fmt.Sprintf("%s.%s", k, val.Name), Value: val.Value, Multiple: val.Multiple, }) } } } propertyList = append(propertyList) case reflect.Slice: for i := 0; i < value.Len(); i++ { propertyList = append(propertyList, datastore.Property{ Name: k, Value: value.Index(i).Interface(), Multiple: true, }) } default: break } return propertyList }
func decodeProperty(c context.Context, k string, v interface{}, e *Entity) error { var p datastore.Property p.Name = k var err error switch v.(type) { // Try to decode property object case map[string]interface{}: // Decode custom type m := v.(map[string]interface{}) t, ok := m["type"] if !ok { t = "primitive" } if index, ok := m["indexed"]; ok { if i, ok := index.(bool); ok { p.NoIndex = !i } } switch t { case "key": key, err := decodeKey(c, m["value"]) if err != nil { return err } p.Value = key case "blobkey": v, ok := m["value"].(string) if !ok { return newDecodePropertyError(k, "blobkey", v) } p.Value = appengine.BlobKey(v) case "blob": v, ok := m["value"].(string) if !ok { return newDecodePropertyError(k, "date", v) } p.Value, err = base64.URLEncoding.DecodeString(v) if err != nil { return err } case "date": v, ok := m["value"].(string) if !ok { return newDecodePropertyError(k, "date", v) } var dt time.Time dt, err = time.Parse(DateTimeFormat, v) if err != nil { return newDecodePropertyError(k, "date", err) } p.Value = dt.UTC() default: if v, ok := m["value"]; ok { err = decodeJSONPrimitiveValue(v, &p) } else { err = fmt.Errorf("aetools: complex property %s without 'value' attribute", k) } } default: err = decodeJSONPrimitiveValue(v, &p) } if err == nil { e.Properties = append(e.Properties, p) } return err }
func saveStructProperty(props *[]datastore.Property, name string, noIndex, multiple bool, v reflect.Value) error { p := datastore.Property{ Name: name, NoIndex: noIndex, Multiple: multiple, } switch x := v.Interface().(type) { case json.Number: s := v.Interface().(json.Number).String() i, err := strconv.ParseInt(s, 10, 64) if err != nil { f, err := strconv.ParseFloat(s, 64) if err != nil { p.Value = s } else { p.Value = f } } else { p.Value = i } case *datastore.Key: p.Value = x case time.Time: p.Value = x case appengine.BlobKey: p.Value = x case appengine.GeoPoint: p.Value = x case datastore.ByteString: p.Value = x default: switch v.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: p.Value = v.Int() case reflect.Bool: p.Value = v.Bool() case reflect.String: p.Value = v.String() case reflect.Float32, reflect.Float64: p.Value = v.Float() case reflect.Slice: if v.Type().Elem().Kind() == reflect.Uint8 { p.NoIndex = true p.Value = v.Bytes() } case reflect.Struct: return fmt.Errorf("datastore: struct field is unsupported") } } if p.Value == nil { return fmt.Errorf("datastore: unsupported struct field type: %v", v.Type()) } *props = append(*props, p) return nil }