コード例 #1
0
ファイル: article.go プロジェクト: rainycape/gondola
func (a *Article) add(key string, value string, begin bool) error {
	var err error
	switch strings.ToLower(key) {
	case idKey:
		err = input.Parse(value, &a.Id)
	case titleKey:
		if begin {
			a.Titles = append([]string{value}, a.Titles...)
		} else {
			a.Titles = append(a.Titles, value)
		}
	case slugKey:
		if begin {
			a.Slugs = append([]string{value}, a.Slugs...)
		} else {
			a.Slugs = append(a.Slugs, value)
		}
	case synopsisKey:
		a.Synopsis = value
	case updatedKey:
		var t time.Time
		switch strings.ToLower(value) {
		case "now":
			t = time.Now().UTC()
		case "today":
			t = time.Now().UTC().Truncate(24 * time.Hour)
		default:
			for _, v := range timeFormats {
				t, err = time.Parse(v, value)
				if err == nil {
					break
				}
			}
		}
		if err == nil {
			if begin {
				a.Updated = append([]time.Time{t}, a.Updated...)
			} else {
				a.Updated = append(a.Updated, t)
			}
		}
	case priorityKey:
		err = input.Parse(value, &a.Priority)
	default:
		if a.Properties == nil {
			a.Properties = make(map[string][]string)
		}
		a.Properties[key] = append(a.Properties[key], value)
	}
	return err
}
コード例 #2
0
ファイル: context.go プロジェクト: rainycape/gondola
func (c *Context) parseTypedValue(idx int, name string, val string, found bool, arg interface{}) error {
	if !found {
		return &MissingParameterError{Index: idx, Name: name}
	}
	if err := input.Parse(val, arg); err != nil {
		if err == types.ErrCantSet {
			// Programming error, user did not pass a pointer
			panic(err)
		}
		return &InvalidParameterError{
			Index: idx,
			Name:  name,
			Type:  reflect.TypeOf(arg),
			Err:   err,
		}
	}
	return nil
}
コード例 #3
0
ファイル: registry.go プロジェクト: rainycape/gondola
func (o *Orm) setFieldsDefaults(f *driver.Fields) error {
	defaults := make(map[int]reflect.Value)
	for ii, v := range f.Tags {
		def := v.Value("default")
		if def == "" {
			continue
		}
		if driver.IsFunc(def) {
			// Currently we only support two hardcoded functions, now() and today()
			fname, _ := driver.SplitFuncArgs(def)
			fn, ok := ormFuncs[fname]
			if !ok {
				return fmt.Errorf("unknown orm function %s()", fname)
			}
			retType := fn.Type().Out(0)
			if retType != f.Types[ii] {
				return fmt.Errorf("type mismatch: orm function %s() returns %s, but field %s in %s is of type %s", fname, retType, f.QNames[ii], f.Type, f.Types[ii])
			}
			if o.driver.Capabilities()&driver.CAP_DEFAULTS == 0 || !o.driver.HasFunc(fname, retType) {
				defaults[ii] = fn
			}
		} else {
			// Raw value, only to be stored in defaults if the driver
			// does not support CAP_DEFAULTS or it's a TEXT value and
			// the driver lacks CAP_DEFAULTS_TEXT
			caps := o.driver.Capabilities()
			if caps&driver.CAP_DEFAULTS != 0 && (caps&driver.CAP_DEFAULTS_TEXT != 0 || !isText(f, ii)) {
				continue
			}
			// Try to parse it
			ftyp := f.Types[ii]
			indirs := 0
			for ftyp.Kind() == reflect.Ptr {
				indirs++
				ftyp = ftyp.Elem()
			}
			val := reflect.New(ftyp)
			if err := input.Parse(def, val.Interface()); err != nil {
				return fmt.Errorf("invalid default value %q for field %s of type %s in %s: %s", def, f.QNames[ii], f.Types[ii], f.Type, err)
			}
			if indirs == 0 {
				defaults[ii] = val.Elem()
			} else {
				// Pointer, need to allocate a new value each time
				typ := f.Types[ii].Elem()
				defVal := val.Elem()
				f := func() reflect.Value {
					v := reflect.New(typ).Elem()
					for v.Kind() == reflect.Ptr {
						v.Set(reflect.New(v.Type().Elem()))
						v = v.Elem()
					}
					v.Set(defVal)
					return v
				}
				defaults[ii] = reflect.ValueOf(f)
			}
		}
	}
	if len(defaults) > 0 {
		f.Defaults = defaults
	}
	return nil
}
コード例 #4
0
ファイル: parse.go プロジェクト: rainycape/gondola
func parseValue(v reflect.Value, raw string) error {
	switch v.Type().Kind() {
	case reflect.Bool:
		value, err := strconv.ParseBool(raw)
		if err != nil {
			return err
		}
		v.SetBool(value)
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		value, err := strconv.ParseInt(raw, 10, 64)
		if err != nil {
			return err
		}
		v.SetInt(int64(value))
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		value, err := strconv.ParseUint(raw, 10, 64)
		if err != nil {
			return err
		}
		v.SetUint(uint64(value))
	case reflect.Float32, reflect.Float64:
		value, err := strconv.ParseFloat(raw, 64)
		if err != nil {
			return err
		}
		v.SetFloat(value)
	case reflect.String:
		v.SetString(raw)
	case reflect.Slice:
		fields, err := stringutil.SplitFields(raw, ",")
		if err != nil {
			return fmt.Errorf("error splitting values: %s", err)
		}
		count := len(fields)
		v.Set(reflect.MakeSlice(v.Type(), count, count))
		for ii, f := range fields {
			if err := input.Parse(f, v.Index(ii).Addr().Interface()); err != nil {
				return fmt.Errorf("error parsing field at index %d: %s", ii, err)
			}
		}
	case reflect.Map:
		fields, err := stringutil.SplitFields(raw, ",")
		if err != nil {
			return fmt.Errorf("error splitting values: %s", err)
		}
		v.Set(reflect.MakeMap(v.Type()))
		ktyp := v.Type().Key()
		etyp := v.Type().Elem()
		for ii, field := range fields {
			subFields, err := stringutil.SplitFields(field, "=")
			if err != nil {
				return fmt.Errorf("error splitting key-value %q: %s", field, err)
			}
			k := reflect.New(ktyp)
			if err := input.Parse(subFields[0], k.Interface()); err != nil {
				return fmt.Errorf("error parsing key at index %d: %s", ii, err)
			}
			elem := reflect.New(etyp)
			if len(subFields) < 2 {
				return fmt.Errorf("invalid map field %q", field)
			}
			if err := input.Parse(subFields[1], elem.Interface()); err != nil {
				return fmt.Errorf("error parsing value at index %d: %s", ii, err)
			}
			v.SetMapIndex(k.Elem(), elem.Elem())
		}
	default:
		parser, ok := v.Interface().(input.Parser)
		if !ok {
			return fmt.Errorf("can't parse value of type %s", v.Type())
		}
		if v.Kind() == reflect.Ptr && !v.Elem().IsValid() {
			v.Set(reflect.New(v.Type().Elem()))
			parser = v.Interface().(input.Parser)
		}
		return parser.Parse(raw)
	}
	return nil
}