예제 #1
0
파일: crud.go 프로젝트: metakeule/pgsql
/*
ScanFieldToStruct scans a field of the *Row from a database query into the given fatstruct and
returns the value that would be inserted into a json representation or an error, if scan or
validation fails
*/
func (c *CRUD) scanFieldToStruct(queryRow *Row, structField reflect.Value, dbField *Field) (jsonVal interface{}, err error) {
	fatField := structField.Interface().(*fat.Field)
	var stringInMap bool

	switch dbField.Type {
	case TimeType, DateType, TimeStampType, TimeStampTZType:
		stringInMap = true
		var t time.Time
		queryRow.Get(dbField, &t)
		err = fatField.Set(t)
	case IntsType:
		err = fatField.ScanString("[" +
			pgsqlfat.TrimCurly(queryRow.GetString(dbField)) +
			"]")
	case StringsType:
		ss := []string{}
		s__ := pgsqlfat.TrimCurly(queryRow.GetString(dbField))
		if s__ != "" {
			s_s := strings.Split(s__, ",")
			for _, sss := range s_s {
				ss = append(ss, strings.Trim(sss, `" `))
			}
		}
		err = fatField.Set(fat.Strings(ss...))
	case JsonType:
		err = fatField.ScanString(queryRow.GetString(dbField))
	case BoolsType:
		s__ := pgsqlfat.TrimCurly(queryRow.GetString(dbField))
		var bs []bool
		if s__ != "" {
			vls := strings.Split(s__, ",")
			bs = make([]bool, len(vls))
			for j, bstri := range vls {
				switch strings.TrimSpace(bstri) {
				case "t":
					bs[j] = true
				case "f":
					bs[j] = false
				default:
					return nil, fmt.Errorf("%s is no []bool", queryRow.GetString(dbField))
				}
			}
		}
		err = fatField.Set(fat.Bools(bs...))
	case FloatsType:
		err = fatField.ScanString("[" +
			pgsqlfat.TrimCurly(queryRow.GetString(dbField)) +
			"]")
	case TimeStampsTZType:
		//var t []time.Time
		var ts string
		queryRow.Get(dbField, &ts)
		s__ := pgsqlfat.TrimCurly(ts)
		var tms []time.Time
		if s__ != "" {
			vls := strings.Split(s__, ",")
			tms = make([]time.Time, len(vls))
			for j, tmsStri := range vls {
				tm, e := fmtdate.Parse("YYYY-MM-DD hh:mm:ss+00", strings.Trim(tmsStri, `"`))
				if e != nil {
					return nil, fmt.Errorf("can't parse time %s: %s", tmsStri, e.Error())
				}
				tms[j] = tm
			}
		}
		// fmt.Printf("times: %#v\n", tms)
		err = fatField.Set(fat.Times(tms...))
		/*
			err = fatField.ScanString("[" +
				pgsqlfat.TrimCurly(queryRow.GetString(dbField)) +
				"]")
		*/
	default:
		err = fatField.Scan(queryRow.GetString(dbField))
	}

	if err != nil {
		return nil, err
	}
	errs := fatField.Validate()
	if len(errs) > 0 {
		var errStr bytes.Buffer
		for _, e := range errs {
			errStr.WriteString(e.Error() + "\n")
		}
		return nil, fmt.Errorf("Can't set field %s: %s", fatField.Name(), errStr.String())
	}

	if stringInMap {
		jsonVal = fatField.String()
	} else {
		jsonVal = fatField.Get()
	}

	return
}
예제 #2
0
파일: crud.go 프로젝트: metakeule/pgsql
func (c *CRUD) setFieldToStruct(jsonVal interface{}, taggedField string, fatStructVal reflect.Value, backupStruct reflect.Value) (err error) {
	structField := fatStructVal.FieldByName(taggedField)
	backupField := backupStruct.FieldByName(taggedField)
	newFatField := backupField.Interface().(*fat.Field)

	if jsonVal == nil {
		if newFatField.Default() != nil {
			structField.Set(backupField)
			return nil
		}

		dbField := c.field(taggedField)
		if dbField.Is(NullAllowed) {
			structField.Set(fatFieldNil)
			return nil
		}
		return fmt.Errorf("null not allowed")
	}

	//	fmt.Printf("json val is: %T\n", jsonVal)

	switch jsonValTyped := jsonVal.(type) {
	case map[string]interface{}:
		var bt []byte
		bt, err = json.Marshal(jsonValTyped)
		if err == nil {
			err = newFatField.ScanString(string(bt))
		}
	//case map[interface{}]interface{}:
	case []interface{}:
		var inputTypeOk bool
		switch newFatField.Typ() {
		case "[]float":
			flts := make([]float64, len(jsonValTyped))
			for i, intf := range jsonValTyped {
				flts[i], inputTypeOk = intf.(float64)
				if !inputTypeOk {
					//err = fmt.Errorf("is no float64: %v (%T)", intf, intf)
					err = fmt.Errorf("is no float")
					break
				}
			}
			err = newFatField.Set(fat.Floats(flts...))
		case "[]int":
			ints := make([]int64, len(jsonValTyped))

			for i, intf := range jsonValTyped {
				var fl float64
				fl, inputTypeOk = intf.(float64)
				ints[i] = toInt64(fl)
				if !inputTypeOk {
					//err = fmt.Errorf("is no float64: %v (%T)", intf, intf)
					err = fmt.Errorf("is no float")
					break
				}
			}
			err = newFatField.Set(fat.Ints(ints...))
		case "[]string":
			strings := make([]string, len(jsonValTyped))

			for i, intf := range jsonValTyped {
				strings[i], inputTypeOk = intf.(string)
				if !inputTypeOk {
					//err = fmt.Errorf("is no string: %v (%T)", intf, intf)
					err = fmt.Errorf("is no string")
					break
				}
			}
			err = newFatField.Set(fat.Strings(strings...))
		case "[]bool":
			bools := make([]bool, len(jsonValTyped))

			for i, intf := range jsonValTyped {
				bools[i], inputTypeOk = intf.(bool)
				if !inputTypeOk {
					//err = fmt.Errorf("is no bool: %v (%T)", intf, intf)
					err = fmt.Errorf("is no bool")
					break
				}
			}
			err = newFatField.Set(fat.Bools(bools...))
		case "[]time":
			times := make([]time.Time, len(jsonValTyped))
			for i, intf := range jsonValTyped {
				// fmt.Printf("[]Time: %#v\n", intf)
				var timestr string
				timestr, inputTypeOk = intf.(string)

				//times[i], inputTypeOk = intf.(time.Time)
				if !inputTypeOk {
					//err = fmt.Errorf("is no time: %v (%T)", intf, intf)
					err = fmt.Errorf("is no time")
					break
				}

				ti, e := time.Parse(time.RFC3339, timestr)
				if e != nil {
					//err = fmt.Errorf("can't parse time: %v: %s ", timestr, e.Error())
					err = fmt.Errorf("invalid time")
					break
				}
				times[i] = ti
			}
			err = newFatField.Set(fat.Times(times...))

		default:
			//err = fmt.Errorf("unsupported type: %#v", newFatField.Typ())
			err = fmt.Errorf("unsupported type")
		}

	case float64:
		switch newFatField.Typ() {
		case "float":
			err = newFatField.Set(jsonVal)
		case "int":
			err = newFatField.Set(int64(jsonValTyped))
		default:
			err = newFatField.Set(jsonVal)
		}
	case string:
		err = newFatField.ScanString(jsonValTyped)
		if err != nil {
			err = fmt.Errorf("is no %s", newFatField.Typ())
		}
	default:
		err = newFatField.Set(jsonVal)
	}
	errs := newFatField.Validate()
	if len(errs) > 0 {
		//var errStr bytes.Buffer
		errStrings := make([]string, len(errs))
		for j, e := range errs {
			errStrings[j] = e.Error()
			// errStr.WriteString(e.Error() + "\n")
		}

		//return fmt.Errorf("Can't set field %s: %s", taggedField, errStr.String())
		//return fmt.Errorf("error while setting")
		//return fmt.Errorf(errStr.String())
		return fmt.Errorf(strings.Join(errStrings, "\n"))
	}

	if err != nil {
		return err
	}

	structField.Set(backupField)
	return
}
예제 #3
0
파일: from_row.go 프로젝트: metakeule/pgsql
func scanFieldToStruct(row *Row, fatField *fat.Field, dbField *Field) (err error) {
	switch dbField.Type {

	case TimeType, DateType, TimeStampType, TimeStampTZType:
		var t time.Time
		row.Get(dbField, &t)
		err = fatField.Set(t)

	case IntsType:
		err = fatField.ScanString("[" + TrimCurly(row.GetString(dbField)) + "]")

	case StringsType:
		ss := []string{}
		s_s := strings.Split(TrimCurly(row.GetString(dbField)), ",")
		for _, sss := range s_s {
			ss = append(ss, strings.Trim(sss, `" `))
		}
		err = fatField.Set(fat.Strings(ss...))

	case JsonType:
		err = fatField.ScanString(row.GetString(dbField))

	case BoolsType:
		vls := strings.Split(TrimCurly(row.GetString(dbField)), ",")
		bs := make([]bool, len(vls))

		for j, bstri := range vls {
			switch strings.TrimSpace(bstri) {
			case "t":
				bs[j] = true
			case "f":
				bs[j] = false
			default:
				return fmt.Errorf("%s is no []bool", row.GetString(dbField))
			}
		}
		err = fatField.Set(fat.Bools(bs...))

	case FloatsType:
		err = fatField.ScanString("[" +
			TrimCurly(row.GetString(dbField)) +
			"]")

	case TimeStampsTZType:

		var ts string
		row.Get(dbField, &ts)
		vls := strings.Split(TrimCurly(ts), ",")
		tms := make([]time.Time, len(vls))
		for j, tmsStri := range vls {
			tm, e := fmtdate.Parse("YYYY-MM-DD hh:mm:ss+00", strings.Trim(tmsStri, `"`))
			if e != nil {
				return fmt.Errorf("can't parse time %s: %s", tmsStri, e.Error())
			}
			tms[j] = tm
		}
		err = fatField.Set(fat.Times(tms...))

	default:
		err = fatField.Scan(row.GetString(dbField))
	}

	if err != nil {
		return err
	}
	errs := fatField.Validate()
	if len(errs) > 0 {
		var errStr bytes.Buffer
		for _, e := range errs {
			errStr.WriteString(e.Error() + "\n")
		}
		return fmt.Errorf("Can't set field %s: %s", fatField.Name(), errStr.String())
	}

	return nil
}