예제 #1
0
파일: orm.go 프로젝트: rainycape/gondola
func (o *Orm) insert(m *model, obj interface{}) (Result, error) {
	if profile.On && profile.Profiling() {
		defer profile.Start(orm).Note("insert", m.name).End()
	}
	var pkName string
	var pkVal reflect.Value
	f := m.fields
	if f.AutoincrementPk {
		pkName, pkVal = o.primaryKey(f, obj)
		if pkVal.Int() == 0 && !pkVal.CanSet() {
			typ := reflect.TypeOf(obj)
			return nil, fmt.Errorf("can't set primary key field %q. Please, insert a %v rather than a %v", pkName, reflect.PtrTo(typ), typ)
		}
	}
	if f.Defaults != nil {
		val := reflect.ValueOf(obj)
		for k, v := range f.Defaults {
			indexes := f.Indexes[k]
			fval := o.fieldByIndexCreating(val, indexes)
			isTrue, _ := types.IsTrueVal(fval)
			if !isTrue {
				if !fval.CanSet() {
					// Need to copy to alter the fields
					pval := reflect.New(val.Type())
					pval.Elem().Set(val)
					obj = pval.Interface()
					val = pval
					fval = o.fieldByIndexCreating(val, indexes)
				}
				if v.Kind() == reflect.Func {
					out := v.Call(nil)
					fval.Set(out[0])
				} else {
					fval.Set(v)
				}
			}
		}
	}
	res, err := o.conn.Insert(m, obj)
	if err == nil && pkVal.IsValid() && pkVal.Int() == 0 {
		id, err := res.LastInsertId()
		if err == nil && id != 0 {
			if o.logger != nil {
				o.logger.Debugf("Setting primary key %q to %d on model %v", pkName, id, m.Type())
			}
			pkVal.SetInt(id)
		} else if err != nil && o.logger != nil {
			o.logger.Errorf("could not obtain last insert id: %s", err)
		}
	}
	return res, err
}
예제 #2
0
func isTrue(v reflect.Value) bool {
	t, _ := types.IsTrueVal(v)
	return t
}