예제 #1
0
파일: from_row.go 프로젝트: metakeule/pgsql
/*
  only the fields that are *fat.Field and not nil are chosen to be set
	from the row. fields that are not set in the row, are set to nil
*/
func (r *Registry) FromRow(row *Row, øptrToFatStruct interface{}) (err error) {
	fn := func(field *meta.Field) {
		if err != nil {
			return
		}

		if field.Value.IsNil() {
			return
		}

		ff, isFat := field.Value.Interface().(*fat.Field)

		if !isFat {
			return
		}

		dbField := r.FieldOf(ff)

		if row.Values()[dbField] != nil {
			fatField := field.Value.Interface().(*fat.Field)
			err = scanFieldToStruct(row, fatField, dbField)
			return
		}

		field.Value.Set(fatFieldNil)
		//		ff.Set(fatFieldNil)
		/*
			if dbField.Is(NullAllowed) {
				ff.Set(fatFieldNil)
			}
		*/
	}

	var stru *meta.Struct
	stru, err = meta.StructByValue(reflect.ValueOf(øptrToFatStruct))

	if err == nil {
		stru.Each(fn)
	}
	return
}
예제 #2
0
파일: crud.go 프로젝트: metakeule/pgsql
func (r *CRUD) scanFields() (err error) {
	var hasDeleteField bool
	//fn := func(fld reflect.StructField, vl reflect.Value, tag string) {
	fn := func(fld *meta.Field) {
		if err != nil {
			return
		}
		tag := fld.Type.Tag.Get("rest")
		if tag == "" {
			return
		}

		methods := map[string]bool{}

		if strings.Contains(tag, "C") {
			methods["C"] = true
		}

		if strings.Contains(tag, "D") {
			if hasDeleteField {
				err = fmt.Errorf("more than one delete field (key) is not supported")
				return
			}
			methods["D"] = true
			hasDeleteField = true
		}

		if strings.Contains(tag, "L") {
			methods["L"] = true
		}

		if strings.Contains(tag, "U") {
			methods["U"] = true
		}

		if strings.Contains(tag, "R") {
			methods["R"] = true
		}

		if len(methods) == 0 {
			return
		}

		//ff := r.field(fld.Name)
		ff := r.field(fld.Type.Name)
		if ff == nil {
			err = fmt.Errorf("can't find field for table %s field %s\n", r.typeString(), fld.Type.Name)
			return
		}

		// pgsql.flags
		if strings.Contains(fld.Type.Tag.Get("db"), "PKEY") {
			if r.primaryKey != nil {
				err = fmt.Errorf("can't have more than one primary key %s and %s\n", r.primaryKey, fld.Type.Name)
				return
			}
			r.primaryKey = r.field(fld.Type.Name)
		}

		r.fields[fld.Type.Name] = methods
	}

	var stru *meta.Struct
	stru, err = meta.StructByValue(reflect.ValueOf(r.prototype))
	stru.Each(fn)
	//meta.Struct.EachTag(r.prototype, "rest", fn)

	if r.primaryKey == nil {
		err = fmt.Errorf("has not primary key, add db:\"PKEY\"")
	}

	pkType := r.primaryKey.Type
	if !pkType.IsCompatible(IntType) {
		if pkType.IsCompatible(TextType) {
			r.pKeyIsString = true
			return
		}
		err = fmt.Errorf("primary key %s (%s) is not compatible to int or string", r.primaryKey.Name, pkType.String())
	}

	return
}
예제 #3
0
파일: to_row.go 프로젝트: metakeule/pgsql
/*
	only the fields that are *fat.Field and not nil are chosen to set
	the row. øptrToFatStruct must be registered with RegisterTable
	before using this function
*/
func (r *Registry) ToRow(øptrToFatStruct interface{}, row *Row) (err error) {
	var stru *meta.Struct
	stru, err = meta.StructByValue(reflect.ValueOf(øptrToFatStruct))

	if err != nil {
		return
	}

	t := r.TableOf(øptrToFatStruct)

	if t == nil {
		err = fmt.Errorf("%T is not registered, use RegisterTable", øptrToFatStruct)
		return
	}

	if row.Table != t {
		err = fmt.Errorf("table of the given fatstruct (%s) is not the same as table of the given row (%s)",
			t.Sql().String(),
			row.Table.Sql().String(),
		)
	}

	if err != nil {
		return
	}

	fn := func(field *meta.Field) {
		// stop on first error
		if err != nil {
			return
		}

		if field.Value.IsNil() {
			return
		}

		ff, isFat := field.Value.Interface().(*fat.Field)

		if !isFat {
			return
		}

		rowField := r.FieldOf(ff)
		v := ff.Get()

		switch v.(type) {
		case []fat.Type:
			vl := ff.String()
			vl = strings.Replace(vl, "[", "{", -1)
			vl = strings.Replace(vl, "]", "}", -1)
			err = row.Set(rowField, vl)
		case map[string]fat.Type:
			err = row.Set(rowField, ff.String())
		default:
			err = row.Set(rowField, v)
		}
	}

	stru.Each(fn)
	return
}