예제 #1
0
파일: orm.go 프로젝트: rainycape/gondola
func (o *Orm) primaryKey(f *driver.Fields, obj interface{}) (string, reflect.Value) {
	pk := f.PrimaryKey
	if pk < 0 {
		return "", reflect.Value{}
	}
	val := driver.Direct(reflect.ValueOf(obj))
	return f.QNames[pk], o.fieldByIndex(val, f.Indexes[pk])
}
예제 #2
0
파일: orm.go 프로젝트: rainycape/gondola
func (o *Orm) compositePrimaryKey(f *driver.Fields, obj interface{}) ([]string, []reflect.Value) {
	if len(f.CompositePrimaryKey) == 0 {
		return nil, nil
	}
	val := driver.Direct(reflect.ValueOf(obj))
	var names []string
	var values []reflect.Value
	for _, v := range f.CompositePrimaryKey {
		names = append(names, f.QNames[v])
		values = append(values, o.fieldByIndex(val, f.Indexes[v]))
	}
	return names, values
}
예제 #3
0
func (b *Backend) TransformOutValue(val reflect.Value) (interface{}, error) {
	val = driver.Direct(val)
	switch x := val.Interface().(type) {
	case time.Time:
		if x.IsZero() {
			return nil, nil
		}
		return x.Unix(), nil
	case bool:
		if x {
			return 1, nil
		}
		return 0, nil
	}
	return nil, fmt.Errorf("can't transform type %v", val.Type())
}
예제 #4
0
파일: driver.go 프로젝트: rainycape/gondola
func (d *Driver) saveParameters(m driver.Model, data interface{}) (reflect.Value, []string, []interface{}, error) {
	// data is guaranteed to be of m.Type()
	val := driver.Direct(reflect.ValueOf(data))
	fields := m.Fields()
	max := len(fields.MNames)
	names := make([]string, 0, max)
	values := make([]interface{}, 0, max)
	var err error
	if d.transforms != nil {
		for ii, v := range fields.Indexes {
			f := d.fieldByIndex(val, v, false)
			if !f.IsValid() {
				continue
			}
			if fields.OmitEmpty[ii] && driver.IsZero(f) {
				continue
			}
			ft := f.Type()
			var fval interface{}
			if _, ok := d.transforms[ft]; ok {
				fval, err = d.backend.TransformOutValue(f)
				if err != nil {
					return val, nil, nil, err
				}
				if fields.NullEmpty[ii] && driver.IsZero(reflect.ValueOf(fval)) {
					fval = nil
				}
			} else if !fields.NullEmpty[ii] || !driver.IsZero(f) {
				if c := codec.FromTag(fields.Tags[ii]); c != nil {
					fval, err = c.Encode(f.Interface())
					if err != nil {
						return val, nil, nil, err
					}
					if p := pipe.FromTag(fields.Tags[ii]); p != nil {
						data, err := p.Encode(fval.([]byte))
						if err != nil {
							return val, nil, nil, err
						}
						fval = data
					}
				} else {
					// Most sql drivers won't accept aliases for string type
					if ft.Kind() == reflect.String && ft != stringType {
						f = f.Convert(stringType)
					}
					fval = f.Interface()
				}
			}
			names = append(names, fields.MNames[ii])
			values = append(values, fval)
		}
	} else {
		for ii, v := range fields.Indexes {
			f := d.fieldByIndex(val, v, false)
			if !f.IsValid() {
				continue
			}
			if fields.OmitEmpty[ii] && driver.IsZero(f) {
				continue
			}
			var fval interface{}
			if !fields.NullEmpty[ii] || !driver.IsZero(f) {
				if c := codec.FromTag(fields.Tags[ii]); c != nil {
					fval, err = c.Encode(&f)
					if err != nil {
						return val, nil, nil, err
					}
				} else {
					ft := f.Type()
					// Most sql drivers won't accept aliases for string type
					if ft.Kind() == reflect.String && ft != stringType {
						f = f.Convert(stringType)
					}
					fval = f.Interface()
				}
			}
			names = append(names, fields.MNames[ii])
			values = append(values, fval)
		}
	}
	return val, names, values, nil
}