コード例 #1
0
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
}
コード例 #2
0
ファイル: fixture.go プロジェクト: speedland/service
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
}
コード例 #3
0
ファイル: marshal.go プロジェクト: ronoaldo/aetools
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
}