orm 1. complete QueryRow/QueryRows api 2. QuerySeter.All support *[]Type and *[]*Type
This commit is contained in:
		
							parent
							
								
									22d2de9fc7
								
							
						
					
					
						commit
						41dd6e580d
					
				
							
								
								
									
										20
									
								
								orm/db.go
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								orm/db.go
									
									
									
									
									
								
							| @ -479,15 +479,19 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi | |||||||
| 	ind := reflect.Indirect(val) | 	ind := reflect.Indirect(val) | ||||||
| 
 | 
 | ||||||
| 	errTyp := true | 	errTyp := true | ||||||
| 
 |  | ||||||
| 	one := true | 	one := true | ||||||
|  | 	isPtr := true | ||||||
| 
 | 
 | ||||||
| 	if val.Kind() == reflect.Ptr { | 	if val.Kind() == reflect.Ptr { | ||||||
| 		fn := "" | 		fn := "" | ||||||
| 		if ind.Kind() == reflect.Slice { | 		if ind.Kind() == reflect.Slice { | ||||||
| 			one = false | 			one = false | ||||||
| 			if ind.Type().Elem().Kind() == reflect.Ptr { | 			typ := ind.Type().Elem() | ||||||
| 				typ := ind.Type().Elem().Elem() | 			switch typ.Kind() { | ||||||
|  | 			case reflect.Ptr: | ||||||
|  | 				fn = getFullName(typ.Elem()) | ||||||
|  | 			case reflect.Struct: | ||||||
|  | 				isPtr = false | ||||||
| 				fn = getFullName(typ) | 				fn = getFullName(typ) | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| @ -601,13 +605,21 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi | |||||||
| 			if one { | 			if one { | ||||||
| 				ind.Set(mind) | 				ind.Set(mind) | ||||||
| 			} else { | 			} else { | ||||||
|  | 				if cnt == 0 { | ||||||
|  | 					slice = reflect.New(ind.Type()).Elem() | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				if isPtr { | ||||||
| 					slice = reflect.Append(slice, mind.Addr()) | 					slice = reflect.Append(slice, mind.Addr()) | ||||||
|  | 				} else { | ||||||
|  | 					slice = reflect.Append(slice, mind) | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		cnt++ | 		cnt++ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if one == false { | 	if one == false && cnt > 0 { | ||||||
| 		ind.Set(slice) | 		ind.Set(slice) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ const ( | |||||||
| 	od_SET_DEFAULT        = "set_default" | 	od_SET_DEFAULT        = "set_default" | ||||||
| 	od_DO_NOTHING         = "do_nothing" | 	od_DO_NOTHING         = "do_nothing" | ||||||
| 	defaultStructTagName  = "orm" | 	defaultStructTagName  = "orm" | ||||||
|  | 	defaultStructTagDelim = ";" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ type Data struct { | |||||||
| 	Char     string    `orm:"size(50)"` | 	Char     string    `orm:"size(50)"` | ||||||
| 	Text     string    `orm:"type(text)"` | 	Text     string    `orm:"type(text)"` | ||||||
| 	Date     time.Time `orm:"type(date)"` | 	Date     time.Time `orm:"type(date)"` | ||||||
| 	DateTime time.Time | 	DateTime time.Time `orm:"column(datetime)"` | ||||||
| 	Byte     byte | 	Byte     byte | ||||||
| 	Rune     rune | 	Rune     rune | ||||||
| 	Int      int | 	Int      int | ||||||
| @ -37,10 +37,10 @@ type Data struct { | |||||||
| type DataNull struct { | type DataNull struct { | ||||||
| 	Id       int | 	Id       int | ||||||
| 	Boolean  bool      `orm:"null"` | 	Boolean  bool      `orm:"null"` | ||||||
| 	Char     string    `orm:"size(50);null"` | 	Char     string    `orm:"null;size(50)"` | ||||||
| 	Text     string    `orm:"type(text);null"` | 	Text     string    `orm:"null;type(text)"` | ||||||
| 	Date     time.Time `orm:"type(date);null"` | 	Date     time.Time `orm:"null;type(date)"` | ||||||
| 	DateTime time.Time `orm:"null"` | 	DateTime time.Time `orm:"null;column(datetime)""` | ||||||
| 	Byte     byte      `orm:"null"` | 	Byte     byte      `orm:"null"` | ||||||
| 	Rune     rune      `orm:"null"` | 	Rune     rune      `orm:"null"` | ||||||
| 	Int      int       `orm:"null"` | 	Int      int       `orm:"null"` | ||||||
| @ -174,7 +174,10 @@ var ( | |||||||
| 	IsPostgres = DBARGS.Driver == "postgres" | 	IsPostgres = DBARGS.Driver == "postgres" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var dORM Ormer | var ( | ||||||
|  | 	dORM     Ormer | ||||||
|  | 	dDbBaser dbBaser | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	Debug, _ = StrTo(DBARGS.Debug).Bool() | 	Debug, _ = StrTo(DBARGS.Debug).Bool() | ||||||
|  | |||||||
| @ -114,7 +114,7 @@ func getFieldType(val reflect.Value) (ft int, err error) { | |||||||
| func parseStructTag(data string, attrs *map[string]bool, tags *map[string]string) { | func parseStructTag(data string, attrs *map[string]bool, tags *map[string]string) { | ||||||
| 	attr := make(map[string]bool) | 	attr := make(map[string]bool) | ||||||
| 	tag := make(map[string]string) | 	tag := make(map[string]string) | ||||||
| 	for _, v := range strings.Split(data, ";") { | 	for _, v := range strings.Split(data, defaultStructTagDelim) { | ||||||
| 		v = strings.TrimSpace(v) | 		v = strings.TrimSpace(v) | ||||||
| 		if supportTag[v] == 1 { | 		if supportTag[v] == 1 { | ||||||
| 			attr[v] = true | 			attr[v] = true | ||||||
|  | |||||||
							
								
								
									
										360
									
								
								orm/orm_raw.go
									
									
									
									
									
								
							
							
						
						
									
										360
									
								
								orm/orm_raw.go
									
									
									
									
									
								
							| @ -4,6 +4,8 @@ import ( | |||||||
| 	"database/sql" | 	"database/sql" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"reflect" | 	"reflect" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type rawPrepare struct { | type rawPrepare struct { | ||||||
| @ -64,14 +66,362 @@ func (o *rawSet) Exec() (sql.Result, error) { | |||||||
| 	return o.orm.db.Exec(query, args...) | 	return o.orm.db.Exec(query, args...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (o *rawSet) QueryRow(...interface{}) error { | func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) { | ||||||
| 	//TODO | 	switch ind.Kind() { | ||||||
|  | 	case reflect.Bool: | ||||||
|  | 		if value == nil { | ||||||
|  | 			ind.SetBool(false) | ||||||
|  | 		} else if v, ok := value.(bool); ok { | ||||||
|  | 			ind.SetBool(v) | ||||||
|  | 		} else { | ||||||
|  | 			v, _ := StrTo(ToStr(value)).Bool() | ||||||
|  | 			ind.SetBool(v) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	case reflect.String: | ||||||
|  | 		if value == nil { | ||||||
|  | 			ind.SetString("") | ||||||
|  | 		} else { | ||||||
|  | 			ind.SetString(ToStr(value)) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||||
|  | 		if value == nil { | ||||||
|  | 			ind.SetInt(0) | ||||||
|  | 		} else { | ||||||
|  | 			val := reflect.ValueOf(value) | ||||||
|  | 			switch val.Kind() { | ||||||
|  | 			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||||
|  | 				ind.SetInt(val.Int()) | ||||||
|  | 			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||||
|  | 				ind.SetInt(int64(val.Uint())) | ||||||
|  | 			default: | ||||||
|  | 				v, _ := StrTo(ToStr(value)).Int64() | ||||||
|  | 				ind.SetInt(v) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||||
|  | 		if value == nil { | ||||||
|  | 			ind.SetUint(0) | ||||||
|  | 		} else { | ||||||
|  | 			val := reflect.ValueOf(value) | ||||||
|  | 			switch val.Kind() { | ||||||
|  | 			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||||
|  | 				ind.SetUint(uint64(val.Int())) | ||||||
|  | 			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||||
|  | 				ind.SetUint(val.Uint()) | ||||||
|  | 			default: | ||||||
|  | 				v, _ := StrTo(ToStr(value)).Uint64() | ||||||
|  | 				ind.SetUint(v) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	case reflect.Float64, reflect.Float32: | ||||||
|  | 		if value == nil { | ||||||
|  | 			ind.SetFloat(0) | ||||||
|  | 		} else { | ||||||
|  | 			val := reflect.ValueOf(value) | ||||||
|  | 			switch val.Kind() { | ||||||
|  | 			case reflect.Float64: | ||||||
|  | 				ind.SetFloat(val.Float()) | ||||||
|  | 			default: | ||||||
|  | 				v, _ := StrTo(ToStr(value)).Float64() | ||||||
|  | 				ind.SetFloat(v) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	case reflect.Struct: | ||||||
|  | 		if value == nil { | ||||||
|  | 			ind.Set(reflect.Zero(ind.Type())) | ||||||
|  | 
 | ||||||
|  | 		} else if _, ok := ind.Interface().(time.Time); ok { | ||||||
|  | 			var str string | ||||||
|  | 			switch d := value.(type) { | ||||||
|  | 			case time.Time: | ||||||
|  | 				o.orm.alias.DbBaser.TimeFromDB(&d, o.orm.alias.TZ) | ||||||
|  | 				ind.Set(reflect.ValueOf(d)) | ||||||
|  | 			case []byte: | ||||||
|  | 				str = string(d) | ||||||
|  | 			case string: | ||||||
|  | 				str = d | ||||||
|  | 			} | ||||||
|  | 			if str != "" { | ||||||
|  | 				if len(str) >= 19 { | ||||||
|  | 					str = str[:19] | ||||||
|  | 					t, err := time.ParseInLocation(format_DateTime, str, o.orm.alias.TZ) | ||||||
|  | 					if err == nil { | ||||||
|  | 						t = t.In(DefaultTimeLoc) | ||||||
|  | 						ind.Set(reflect.ValueOf(t)) | ||||||
|  | 					} | ||||||
|  | 				} else if len(str) >= 10 { | ||||||
|  | 					str = str[:10] | ||||||
|  | 					t, err := time.ParseInLocation(format_Date, str, DefaultTimeLoc) | ||||||
|  | 					if err == nil { | ||||||
|  | 						ind.Set(reflect.ValueOf(t)) | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o *rawSet) loopInitRefs(typ reflect.Type, refsPtr *[]interface{}, sIdxesPtr *[][]int) { | ||||||
|  | 	sIdxes := *sIdxesPtr | ||||||
|  | 	refs := *refsPtr | ||||||
|  | 
 | ||||||
|  | 	if typ.Kind() == reflect.Struct { | ||||||
|  | 		if typ.String() == "time.Time" { | ||||||
|  | 			var ref interface{} | ||||||
|  | 			refs = append(refs, &ref) | ||||||
|  | 			sIdxes = append(sIdxes, []int{0}) | ||||||
|  | 		} else { | ||||||
|  | 			idxs := []int{} | ||||||
|  | 		outFor: | ||||||
|  | 			for idx := 0; idx < typ.NumField(); idx++ { | ||||||
|  | 				ctyp := typ.Field(idx) | ||||||
|  | 
 | ||||||
|  | 				tag := ctyp.Tag.Get(defaultStructTagName) | ||||||
|  | 				for _, v := range strings.Split(tag, defaultStructTagDelim) { | ||||||
|  | 					if v == "-" { | ||||||
|  | 						continue outFor | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				tp := ctyp.Type | ||||||
|  | 				if tp.Kind() == reflect.Ptr { | ||||||
|  | 					tp = tp.Elem() | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				if tp.String() == "time.Time" { | ||||||
|  | 					var ref interface{} | ||||||
|  | 					refs = append(refs, &ref) | ||||||
|  | 
 | ||||||
|  | 				} else if tp.Kind() != reflect.Struct { | ||||||
|  | 					var ref interface{} | ||||||
|  | 					refs = append(refs, &ref) | ||||||
|  | 
 | ||||||
|  | 				} else { | ||||||
|  | 					// skip other type | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				idxs = append(idxs, idx) | ||||||
|  | 			} | ||||||
|  | 			sIdxes = append(sIdxes, idxs) | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		var ref interface{} | ||||||
|  | 		refs = append(refs, &ref) | ||||||
|  | 		sIdxes = append(sIdxes, []int{0}) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	*sIdxesPtr = sIdxes | ||||||
|  | 	*refsPtr = refs | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o *rawSet) loopSetRefs(refs []interface{}, sIdxes [][]int, sInds []reflect.Value, nIndsPtr *[]reflect.Value, eTyps []reflect.Type, init bool) { | ||||||
|  | 	nInds := *nIndsPtr | ||||||
|  | 
 | ||||||
|  | 	cur := 0 | ||||||
|  | 	for i, idxs := range sIdxes { | ||||||
|  | 		sInd := sInds[i] | ||||||
|  | 		eTyp := eTyps[i] | ||||||
|  | 
 | ||||||
|  | 		typ := eTyp | ||||||
|  | 		isPtr := false | ||||||
|  | 		if typ.Kind() == reflect.Ptr { | ||||||
|  | 			isPtr = true | ||||||
|  | 			typ = typ.Elem() | ||||||
|  | 		} | ||||||
|  | 		if typ.Kind() == reflect.Ptr { | ||||||
|  | 			isPtr = true | ||||||
|  | 			typ = typ.Elem() | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		var nInd reflect.Value | ||||||
|  | 		if init { | ||||||
|  | 			nInd = reflect.New(sInd.Type()).Elem() | ||||||
|  | 		} else { | ||||||
|  | 			nInd = nInds[i] | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		val := reflect.New(typ) | ||||||
|  | 		ind := val.Elem() | ||||||
|  | 
 | ||||||
|  | 		tpName := ind.Type().String() | ||||||
|  | 
 | ||||||
|  | 		if ind.Kind() == reflect.Struct { | ||||||
|  | 			if tpName == "time.Time" { | ||||||
|  | 				value := reflect.ValueOf(refs[cur]).Elem().Interface() | ||||||
|  | 				if isPtr && value == nil { | ||||||
|  | 					val = reflect.New(val.Type()).Elem() | ||||||
|  | 				} else { | ||||||
|  | 					o.setFieldValue(ind, value) | ||||||
|  | 				} | ||||||
|  | 				cur++ | ||||||
|  | 			} else { | ||||||
|  | 				hasValue := false | ||||||
|  | 				for _, idx := range idxs { | ||||||
|  | 					tind := ind.Field(idx) | ||||||
|  | 					value := reflect.ValueOf(refs[cur]).Elem().Interface() | ||||||
|  | 					if value != nil { | ||||||
|  | 						hasValue = true | ||||||
|  | 					} | ||||||
|  | 					if tind.Kind() == reflect.Ptr { | ||||||
|  | 						if value == nil { | ||||||
|  | 							tindV := reflect.New(tind.Type()).Elem() | ||||||
|  | 							tind.Set(tindV) | ||||||
|  | 						} else { | ||||||
|  | 							tindV := reflect.New(tind.Type().Elem()) | ||||||
|  | 							o.setFieldValue(tindV.Elem(), value) | ||||||
|  | 							tind.Set(tindV) | ||||||
|  | 						} | ||||||
|  | 					} else { | ||||||
|  | 						o.setFieldValue(tind, value) | ||||||
|  | 					} | ||||||
|  | 					cur++ | ||||||
|  | 				} | ||||||
|  | 				if hasValue == false && isPtr { | ||||||
|  | 					val = reflect.New(val.Type()).Elem() | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			value := reflect.ValueOf(refs[cur]).Elem().Interface() | ||||||
|  | 			if isPtr && value == nil { | ||||||
|  | 				val = reflect.New(val.Type()).Elem() | ||||||
|  | 			} else { | ||||||
|  | 				o.setFieldValue(ind, value) | ||||||
|  | 			} | ||||||
|  | 			cur++ | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if nInd.Kind() == reflect.Slice { | ||||||
|  | 			if isPtr { | ||||||
|  | 				nInd = reflect.Append(nInd, val) | ||||||
|  | 			} else { | ||||||
|  | 				nInd = reflect.Append(nInd, ind) | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			if isPtr { | ||||||
|  | 				nInd.Set(val) | ||||||
|  | 			} else { | ||||||
|  | 				nInd.Set(ind) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		nInds[i] = nInd | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o *rawSet) QueryRow(containers ...interface{}) error { | ||||||
|  | 	if len(containers) == 0 { | ||||||
|  | 		panic("<RawSeter.QueryRow> need at least one arg") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	refs := make([]interface{}, 0, len(containers)) | ||||||
|  | 	sIdxes := make([][]int, 0) | ||||||
|  | 	sInds := make([]reflect.Value, 0) | ||||||
|  | 	eTyps := make([]reflect.Type, 0) | ||||||
|  | 
 | ||||||
|  | 	for _, container := range containers { | ||||||
|  | 		val := reflect.ValueOf(container) | ||||||
|  | 		ind := reflect.Indirect(val) | ||||||
|  | 
 | ||||||
|  | 		if val.Kind() != reflect.Ptr { | ||||||
|  | 			panic("<RawSeter.QueryRow> all args must be use ptr") | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		etyp := ind.Type() | ||||||
|  | 		typ := etyp | ||||||
|  | 		if typ.Kind() == reflect.Ptr { | ||||||
|  | 			typ = typ.Elem() | ||||||
|  | 		} | ||||||
|  | 		if typ.Kind() == reflect.Ptr { | ||||||
|  | 			typ = typ.Elem() | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		sInds = append(sInds, ind) | ||||||
|  | 		eTyps = append(eTyps, etyp) | ||||||
|  | 
 | ||||||
|  | 		o.loopInitRefs(typ, &refs, &sIdxes) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	query := o.query | ||||||
|  | 	o.orm.alias.DbBaser.ReplaceMarks(&query) | ||||||
|  | 
 | ||||||
|  | 	args := getFlatParams(nil, o.args, o.orm.alias.TZ) | ||||||
|  | 	row := o.orm.db.QueryRow(query, args...) | ||||||
|  | 
 | ||||||
|  | 	if err := row.Scan(refs...); err == sql.ErrNoRows { | ||||||
|  | 		return ErrNoRows | ||||||
|  | 	} else if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	nInds := make([]reflect.Value, len(sInds)) | ||||||
|  | 	o.loopSetRefs(refs, sIdxes, sInds, &nInds, eTyps, true) | ||||||
|  | 	for i, sInd := range sInds { | ||||||
|  | 		nInd := nInds[i] | ||||||
|  | 		sInd.Set(nInd) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (o *rawSet) QueryRows(...interface{}) (int64, error) { | func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) { | ||||||
| 	//TODO | 	refs := make([]interface{}, 0) | ||||||
| 	return 0, nil | 	sIdxes := make([][]int, 0) | ||||||
|  | 	sInds := make([]reflect.Value, 0) | ||||||
|  | 	eTyps := make([]reflect.Type, 0) | ||||||
|  | 
 | ||||||
|  | 	for _, container := range containers { | ||||||
|  | 		val := reflect.ValueOf(container) | ||||||
|  | 		sInd := reflect.Indirect(val) | ||||||
|  | 		if val.Kind() != reflect.Ptr || sInd.Kind() != reflect.Slice { | ||||||
|  | 			panic("<RawSeter.QueryRows> all args must be use ptr slice") | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		etyp := sInd.Type().Elem() | ||||||
|  | 		typ := etyp | ||||||
|  | 		if typ.Kind() == reflect.Ptr { | ||||||
|  | 			typ = typ.Elem() | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		sInds = append(sInds, sInd) | ||||||
|  | 		eTyps = append(eTyps, etyp) | ||||||
|  | 
 | ||||||
|  | 		o.loopInitRefs(typ, &refs, &sIdxes) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	query := o.query | ||||||
|  | 	o.orm.alias.DbBaser.ReplaceMarks(&query) | ||||||
|  | 
 | ||||||
|  | 	args := getFlatParams(nil, o.args, o.orm.alias.TZ) | ||||||
|  | 	rows, err := o.orm.db.Query(query, args...) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return 0, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	nInds := make([]reflect.Value, len(sInds)) | ||||||
|  | 
 | ||||||
|  | 	var cnt int64 | ||||||
|  | 	for rows.Next() { | ||||||
|  | 		if err := rows.Scan(refs...); err != nil { | ||||||
|  | 			return 0, err | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		o.loopSetRefs(refs, sIdxes, sInds, &nInds, eTyps, cnt == 0) | ||||||
|  | 
 | ||||||
|  | 		cnt++ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if cnt > 0 { | ||||||
|  | 		for i, sInd := range sInds { | ||||||
|  | 			nInd := nInds[i] | ||||||
|  | 			sInd.Set(nInd) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return cnt, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (o *rawSet) readValues(container interface{}) (int64, error) { | func (o *rawSet) readValues(container interface{}) (int64, error) { | ||||||
|  | |||||||
							
								
								
									
										351
									
								
								orm/orm_test.go
									
									
									
									
									
								
							
							
						
						
									
										351
									
								
								orm/orm_test.go
									
									
									
									
									
								
							| @ -216,6 +216,7 @@ func TestRegisterModels(t *testing.T) { | |||||||
| 	BootStrap() | 	BootStrap() | ||||||
| 
 | 
 | ||||||
| 	dORM = NewOrm() | 	dORM = NewOrm() | ||||||
|  | 	dDbBaser = getDbAlias("default").DbBaser | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestModelSyntax(t *testing.T) { | func TestModelSyntax(t *testing.T) { | ||||||
| @ -629,9 +630,23 @@ func TestOperators(t *testing.T) { | |||||||
| func TestAll(t *testing.T) { | func TestAll(t *testing.T) { | ||||||
| 	var users []*User | 	var users []*User | ||||||
| 	qs := dORM.QueryTable("user") | 	qs := dORM.QueryTable("user") | ||||||
| 	num, err := qs.All(&users) | 	num, err := qs.OrderBy("Id").All(&users) | ||||||
| 	throwFail(t, err) | 	throwFail(t, err) | ||||||
| 	throwFail(t, AssertIs(num, T_Equal, 3)) | 	throwFailNow(t, AssertIs(num, T_Equal, 3)) | ||||||
|  | 
 | ||||||
|  | 	throwFail(t, AssertIs(users[0].UserName, T_Equal, "slene")) | ||||||
|  | 	throwFail(t, AssertIs(users[1].UserName, T_Equal, "astaxie")) | ||||||
|  | 	throwFail(t, AssertIs(users[2].UserName, T_Equal, "nobody")) | ||||||
|  | 
 | ||||||
|  | 	var users2 []User | ||||||
|  | 	qs = dORM.QueryTable("user") | ||||||
|  | 	num, err = qs.OrderBy("Id").All(&users2) | ||||||
|  | 	throwFail(t, err) | ||||||
|  | 	throwFailNow(t, AssertIs(num, T_Equal, 3)) | ||||||
|  | 
 | ||||||
|  | 	throwFailNow(t, AssertIs(users2[0].UserName, T_Equal, "slene")) | ||||||
|  | 	throwFailNow(t, AssertIs(users2[1].UserName, T_Equal, "astaxie")) | ||||||
|  | 	throwFailNow(t, AssertIs(users2[2].UserName, T_Equal, "nobody")) | ||||||
| 
 | 
 | ||||||
| 	qs = dORM.QueryTable("user") | 	qs = dORM.QueryTable("user") | ||||||
| 	num, err = qs.Filter("user_name", "nothing").All(&users) | 	num, err = qs.Filter("user_name", "nothing").All(&users) | ||||||
| @ -645,8 +660,14 @@ func TestOne(t *testing.T) { | |||||||
| 	err := qs.One(&user) | 	err := qs.One(&user) | ||||||
| 	throwFail(t, AssertIs(err, T_Equal, ErrMultiRows)) | 	throwFail(t, AssertIs(err, T_Equal, ErrMultiRows)) | ||||||
| 
 | 
 | ||||||
|  | 	user = User{} | ||||||
|  | 	err = qs.OrderBy("Id").Limit(1).One(&user) | ||||||
|  | 	throwFailNow(t, err) | ||||||
|  | 	throwFail(t, AssertIs(user.UserName, T_Equal, "slene")) | ||||||
|  | 
 | ||||||
| 	err = qs.Filter("user_name", "nothing").One(&user) | 	err = qs.Filter("user_name", "nothing").One(&user) | ||||||
| 	throwFail(t, AssertIs(err, T_Equal, ErrNoRows)) | 	throwFail(t, AssertIs(err, T_Equal, ErrNoRows)) | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestValues(t *testing.T) { | func TestValues(t *testing.T) { | ||||||
| @ -836,30 +857,282 @@ func TestPrepareInsert(t *testing.T) { | |||||||
| 	throwFail(t, AssertIs(err, T_Equal, ErrStmtClosed)) | 	throwFail(t, AssertIs(err, T_Equal, ErrStmtClosed)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestRawQueryRow(t *testing.T) { | func TestRawExec(t *testing.T) { | ||||||
|  | 	Q := dDbBaser.TableQuote() | ||||||
| 
 | 
 | ||||||
|  | 	query := fmt.Sprintf("UPDATE %suser%s SET %suser_name%s = ? WHERE %suser_name%s = ?", Q, Q, Q, Q, Q, Q) | ||||||
|  | 	res, err := dORM.Raw(query, "testing", "slene").Exec() | ||||||
|  | 	throwFail(t, err) | ||||||
|  | 	num, err := res.RowsAffected() | ||||||
|  | 	throwFail(t, AssertIs(num, T_Equal, 1), err) | ||||||
|  | 
 | ||||||
|  | 	res, err = dORM.Raw(query, "slene", "testing").Exec() | ||||||
|  | 	throwFail(t, err) | ||||||
|  | 	num, err = res.RowsAffected() | ||||||
|  | 	throwFail(t, AssertIs(num, T_Equal, 1), err) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestRawQueryRows(t *testing.T) { | func TestRawQueryRow(t *testing.T) { | ||||||
|  | 	var ( | ||||||
|  | 		Boolean  bool | ||||||
|  | 		Char     string | ||||||
|  | 		Text     string | ||||||
|  | 		Date     time.Time | ||||||
|  | 		DateTime time.Time | ||||||
|  | 		Byte     byte | ||||||
|  | 		Rune     rune | ||||||
|  | 		Int      int | ||||||
|  | 		Int8     int | ||||||
|  | 		Int16    int16 | ||||||
|  | 		Int32    int32 | ||||||
|  | 		Int64    int64 | ||||||
|  | 		Uint     uint | ||||||
|  | 		Uint8    uint8 | ||||||
|  | 		Uint16   uint16 | ||||||
|  | 		Uint32   uint32 | ||||||
|  | 		Uint64   uint64 | ||||||
|  | 		Float32  float32 | ||||||
|  | 		Float64  float64 | ||||||
|  | 		Decimal  float64 | ||||||
|  | 	) | ||||||
| 
 | 
 | ||||||
|  | 	data_values := make(map[string]interface{}, len(Data_Values)) | ||||||
|  | 
 | ||||||
|  | 	for k, v := range Data_Values { | ||||||
|  | 		data_values[strings.ToLower(k)] = v | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Q := dDbBaser.TableQuote() | ||||||
|  | 
 | ||||||
|  | 	cols := []string{ | ||||||
|  | 		"id", "boolean", "char", "text", "date", "datetime", "byte", "rune", "int", "int8", "int16", "int32", | ||||||
|  | 		"int64", "uint", "uint8", "uint16", "uint32", "uint64", "float32", "float64", "decimal", | ||||||
|  | 	} | ||||||
|  | 	sep := fmt.Sprintf("%s, %s", Q, Q) | ||||||
|  | 	query := fmt.Sprintf("SELECT %s%s%s FROM data WHERE id = ?", Q, strings.Join(cols, sep), Q) | ||||||
|  | 	var id int | ||||||
|  | 	values := []interface{}{ | ||||||
|  | 		&id, &Boolean, &Char, &Text, &Date, &DateTime, &Byte, &Rune, &Int, &Int8, &Int16, &Int32, | ||||||
|  | 		&Int64, &Uint, &Uint8, &Uint16, &Uint32, &Uint64, &Float32, &Float64, &Decimal, | ||||||
|  | 	} | ||||||
|  | 	err := dORM.Raw(query, 1).QueryRow(values...) | ||||||
|  | 	throwFailNow(t, err) | ||||||
|  | 	for i, col := range cols { | ||||||
|  | 		vu := values[i] | ||||||
|  | 		v := reflect.ValueOf(vu).Elem().Interface() | ||||||
|  | 		switch col { | ||||||
|  | 		case "id": | ||||||
|  | 			throwFail(t, AssertIs(id, T_Equal, 1)) | ||||||
|  | 		case "date": | ||||||
|  | 			v = v.(time.Time).In(DefaultTimeLoc) | ||||||
|  | 			value := data_values[col].(time.Time).In(DefaultTimeLoc) | ||||||
|  | 			throwFail(t, AssertIs(v, T_Equal, value, test_Date)) | ||||||
|  | 		case "datetime": | ||||||
|  | 			v = v.(time.Time).In(DefaultTimeLoc) | ||||||
|  | 			value := data_values[col].(time.Time).In(DefaultTimeLoc) | ||||||
|  | 			throwFail(t, AssertIs(v, T_Equal, value, test_DateTime)) | ||||||
|  | 		default: | ||||||
|  | 			throwFail(t, AssertIs(v, T_Equal, data_values[col])) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	type Tmp struct { | ||||||
|  | 		Skip0    string | ||||||
|  | 		Id       int | ||||||
|  | 		Char     *string | ||||||
|  | 		Skip1    int `orm:"-"` | ||||||
|  | 		Date     time.Time | ||||||
|  | 		DateTime time.Time | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Boolean = false | ||||||
|  | 	Text = "" | ||||||
|  | 	Int64 = 0 | ||||||
|  | 	Uint = 0 | ||||||
|  | 
 | ||||||
|  | 	tmp := new(Tmp) | ||||||
|  | 
 | ||||||
|  | 	cols = []string{ | ||||||
|  | 		"int", "char", "date", "datetime", "boolean", "text", "int64", "uint", | ||||||
|  | 	} | ||||||
|  | 	query = fmt.Sprintf("SELECT NULL, %s%s%s FROM data WHERE id = ?", Q, strings.Join(cols, sep), Q) | ||||||
|  | 	values = []interface{}{ | ||||||
|  | 		tmp, &Boolean, &Text, &Int64, &Uint, | ||||||
|  | 	} | ||||||
|  | 	err = dORM.Raw(query, 1).QueryRow(values...) | ||||||
|  | 	throwFailNow(t, err) | ||||||
|  | 
 | ||||||
|  | 	for _, col := range cols { | ||||||
|  | 		switch col { | ||||||
|  | 		case "id": | ||||||
|  | 			throwFail(t, AssertIs(tmp.Id, T_Equal, data_values[col])) | ||||||
|  | 		case "char": | ||||||
|  | 			c := tmp.Char | ||||||
|  | 			throwFail(t, AssertIs(*c, T_Equal, data_values[col])) | ||||||
|  | 		case "date": | ||||||
|  | 			v := tmp.Date.In(DefaultTimeLoc) | ||||||
|  | 			value := data_values[col].(time.Time).In(DefaultTimeLoc) | ||||||
|  | 			throwFail(t, AssertIs(v, T_Equal, value, test_Date)) | ||||||
|  | 		case "datetime": | ||||||
|  | 			v := tmp.DateTime.In(DefaultTimeLoc) | ||||||
|  | 			value := data_values[col].(time.Time).In(DefaultTimeLoc) | ||||||
|  | 			throwFail(t, AssertIs(v, T_Equal, value, test_DateTime)) | ||||||
|  | 		case "boolean": | ||||||
|  | 			throwFail(t, AssertIs(Boolean, T_Equal, data_values[col])) | ||||||
|  | 		case "text": | ||||||
|  | 			throwFail(t, AssertIs(Text, T_Equal, data_values[col])) | ||||||
|  | 		case "int64": | ||||||
|  | 			throwFail(t, AssertIs(Int64, T_Equal, data_values[col])) | ||||||
|  | 		case "uint": | ||||||
|  | 			throwFail(t, AssertIs(Uint, T_Equal, data_values[col])) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var ( | ||||||
|  | 		uid    int | ||||||
|  | 		status *int | ||||||
|  | 		pid    *int | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	cols = []string{ | ||||||
|  | 		"id", "status", "profile_id", | ||||||
|  | 	} | ||||||
|  | 	query = fmt.Sprintf("SELECT %s%s%s FROM %suser%s WHERE id = ?", Q, strings.Join(cols, sep), Q, Q, Q) | ||||||
|  | 	err = dORM.Raw(query, 4).QueryRow(&uid, &status, &pid) | ||||||
|  | 	throwFail(t, err) | ||||||
|  | 	throwFail(t, AssertIs(uid, T_Equal, 4)) | ||||||
|  | 	throwFail(t, AssertIs(*status, T_Equal, 3)) | ||||||
|  | 	throwFail(t, AssertIs(pid, T_Equal, nil)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestQueryRows(t *testing.T) { | ||||||
|  | 	Q := dDbBaser.TableQuote() | ||||||
|  | 
 | ||||||
|  | 	cols := []string{ | ||||||
|  | 		"id", "boolean", "char", "text", "date", "datetime", "byte", "rune", "int", "int8", "int16", "int32", | ||||||
|  | 		"int64", "uint", "uint8", "uint16", "uint32", "uint64", "float32", "float64", "decimal", | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var datas []*Data | ||||||
|  | 	var dids []int | ||||||
|  | 
 | ||||||
|  | 	sep := fmt.Sprintf("%s, %s", Q, Q) | ||||||
|  | 	query := fmt.Sprintf("SELECT %s%s%s, id FROM %sdata%s", Q, strings.Join(cols, sep), Q, Q, Q) | ||||||
|  | 	num, err := dORM.Raw(query).QueryRows(&datas, &dids) | ||||||
|  | 	throwFailNow(t, err) | ||||||
|  | 	throwFailNow(t, AssertIs(num, T_Equal, 1)) | ||||||
|  | 	throwFailNow(t, AssertIs(len(datas), T_Equal, 1)) | ||||||
|  | 	throwFailNow(t, AssertIs(len(dids), T_Equal, 1)) | ||||||
|  | 	throwFailNow(t, AssertIs(dids[0], T_Equal, 1)) | ||||||
|  | 
 | ||||||
|  | 	ind := reflect.Indirect(reflect.ValueOf(datas[0])) | ||||||
|  | 
 | ||||||
|  | 	for name, value := range Data_Values { | ||||||
|  | 		e := ind.FieldByName(name) | ||||||
|  | 		vu := e.Interface() | ||||||
|  | 		switch name { | ||||||
|  | 		case "Date": | ||||||
|  | 			vu = vu.(time.Time).In(DefaultTimeLoc).Format(test_Date) | ||||||
|  | 			value = value.(time.Time).In(DefaultTimeLoc).Format(test_Date) | ||||||
|  | 		case "DateTime": | ||||||
|  | 			vu = vu.(time.Time).In(DefaultTimeLoc).Format(test_DateTime) | ||||||
|  | 			value = value.(time.Time).In(DefaultTimeLoc).Format(test_DateTime) | ||||||
|  | 		} | ||||||
|  | 		throwFail(t, AssertIs(vu == value, T_Equal, true), value, vu) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	type Tmp struct { | ||||||
|  | 		Id      int | ||||||
|  | 		Name    string | ||||||
|  | 		Skiped0 string `orm:"-"` | ||||||
|  | 		Pid     *int | ||||||
|  | 		Skiped1 Data | ||||||
|  | 		Skiped2 *Data | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var ( | ||||||
|  | 		ids         []int | ||||||
|  | 		userNames   []string | ||||||
|  | 		profileIds1 []int | ||||||
|  | 		profileIds2 []*int | ||||||
|  | 		createds    []time.Time | ||||||
|  | 		updateds    []time.Time | ||||||
|  | 		tmps1       []*Tmp | ||||||
|  | 		tmps2       []Tmp | ||||||
|  | 	) | ||||||
|  | 	cols = []string{ | ||||||
|  | 		"id", "user_name", "profile_id", "profile_id", "id", "user_name", "profile_id", "id", "user_name", "profile_id", "created", "updated", | ||||||
|  | 	} | ||||||
|  | 	query = fmt.Sprintf("SELECT %s%s%s FROM %suser%s ORDER BY id", Q, strings.Join(cols, sep), Q, Q, Q) | ||||||
|  | 	num, err = dORM.Raw(query).QueryRows(&ids, &userNames, &profileIds1, &profileIds2, &tmps1, &tmps2, &createds, &updateds) | ||||||
|  | 	throwFailNow(t, err) | ||||||
|  | 	throwFailNow(t, AssertIs(num, T_Equal, 3)) | ||||||
|  | 
 | ||||||
|  | 	var users []User | ||||||
|  | 	dORM.QueryTable("user").OrderBy("Id").All(&users) | ||||||
|  | 
 | ||||||
|  | 	for i := 0; i < 3; i++ { | ||||||
|  | 		id := ids[i] | ||||||
|  | 		name := userNames[i] | ||||||
|  | 		pid1 := profileIds1[i] | ||||||
|  | 		pid2 := profileIds2[i] | ||||||
|  | 		created := createds[i] | ||||||
|  | 		updated := updateds[i] | ||||||
|  | 
 | ||||||
|  | 		user := users[i] | ||||||
|  | 		throwFailNow(t, AssertIs(id, T_Equal, user.Id)) | ||||||
|  | 		throwFailNow(t, AssertIs(name, T_Equal, user.UserName)) | ||||||
|  | 		if user.Profile != nil { | ||||||
|  | 			throwFailNow(t, AssertIs(pid1, T_Equal, user.Profile.Id)) | ||||||
|  | 			throwFailNow(t, AssertIs(*pid2, T_Equal, user.Profile.Id)) | ||||||
|  | 		} else { | ||||||
|  | 			throwFailNow(t, AssertIs(pid1, T_Equal, 0)) | ||||||
|  | 			throwFailNow(t, AssertIs(pid2, T_Equal, nil)) | ||||||
|  | 		} | ||||||
|  | 		throwFailNow(t, AssertIs(created, T_Equal, user.Created, test_Date)) | ||||||
|  | 		throwFailNow(t, AssertIs(updated, T_Equal, user.Updated, test_DateTime)) | ||||||
|  | 
 | ||||||
|  | 		tmp := tmps1[i] | ||||||
|  | 		tmp1 := *tmp | ||||||
|  | 		throwFailNow(t, AssertIs(tmp1.Id, T_Equal, user.Id)) | ||||||
|  | 		throwFailNow(t, AssertIs(tmp1.Name, T_Equal, user.UserName)) | ||||||
|  | 		if user.Profile != nil { | ||||||
|  | 			pid := tmp1.Pid | ||||||
|  | 			throwFailNow(t, AssertIs(*pid, T_Equal, user.Profile.Id)) | ||||||
|  | 		} else { | ||||||
|  | 			throwFailNow(t, AssertIs(tmp1.Pid, T_Equal, nil)) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		tmp2 := tmps2[i] | ||||||
|  | 		throwFailNow(t, AssertIs(tmp2.Id, T_Equal, user.Id)) | ||||||
|  | 		throwFailNow(t, AssertIs(tmp2.Name, T_Equal, user.UserName)) | ||||||
|  | 		if user.Profile != nil { | ||||||
|  | 			pid := tmp2.Pid | ||||||
|  | 			throwFailNow(t, AssertIs(*pid, T_Equal, user.Profile.Id)) | ||||||
|  | 		} else { | ||||||
|  | 			throwFailNow(t, AssertIs(tmp2.Pid, T_Equal, nil)) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	type Sec struct { | ||||||
|  | 		Id   int | ||||||
|  | 		Name string | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var tmp []*Sec | ||||||
|  | 	query = fmt.Sprintf("SELECT NULL, NULL FROM %suser%s LIMIT 1", Q, Q) | ||||||
|  | 	num, err = dORM.Raw(query).QueryRows(&tmp) | ||||||
|  | 	throwFail(t, err) | ||||||
|  | 	throwFail(t, AssertIs(num, T_Equal, 1)) | ||||||
|  | 	throwFail(t, AssertIs(tmp[0], T_Equal, nil)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestRawValues(t *testing.T) { | func TestRawValues(t *testing.T) { | ||||||
| 	switch { | 	Q := dDbBaser.TableQuote() | ||||||
| 	case IsMysql || IsSqlite: |  | ||||||
| 
 |  | ||||||
| 		res, err := dORM.Raw("UPDATE user SET user_name = ? WHERE user_name = ?", "testing", "slene").Exec() |  | ||||||
| 		throwFail(t, err) |  | ||||||
| 		num, err := res.RowsAffected() |  | ||||||
| 		throwFail(t, AssertIs(num, T_Equal, 1), err) |  | ||||||
| 
 |  | ||||||
| 		res, err = dORM.Raw("UPDATE user SET user_name = ? WHERE user_name = ?", "slene", "testing").Exec() |  | ||||||
| 		throwFail(t, err) |  | ||||||
| 		num, err = res.RowsAffected() |  | ||||||
| 		throwFail(t, AssertIs(num, T_Equal, 1), err) |  | ||||||
| 
 | 
 | ||||||
| 	var maps []Params | 	var maps []Params | ||||||
| 		num, err = dORM.Raw("SELECT user_name FROM user WHERE status = ?", 1).Values(&maps) | 	query := fmt.Sprintf("SELECT %suser_name%s FROM %suser%s WHERE %sstatus%s = ?", Q, Q, Q, Q, Q, Q) | ||||||
|  | 	num, err := dORM.Raw(query, 1).Values(&maps) | ||||||
| 	throwFail(t, err) | 	throwFail(t, err) | ||||||
| 	throwFail(t, AssertIs(num, T_Equal, 1)) | 	throwFail(t, AssertIs(num, T_Equal, 1)) | ||||||
| 	if num == 1 { | 	if num == 1 { | ||||||
| @ -867,15 +1140,16 @@ func TestRawValues(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var lists []ParamsList | 	var lists []ParamsList | ||||||
| 		num, err = dORM.Raw("SELECT user_name FROM user WHERE status = ?", 1).ValuesList(&lists) | 	num, err = dORM.Raw(query, 1).ValuesList(&lists) | ||||||
| 	throwFail(t, err) | 	throwFail(t, err) | ||||||
| 	throwFail(t, AssertIs(num, T_Equal, 1)) | 	throwFail(t, AssertIs(num, T_Equal, 1)) | ||||||
| 	if num == 1 { | 	if num == 1 { | ||||||
| 		throwFail(t, AssertIs(lists[0][0], T_Equal, "slene")) | 		throwFail(t, AssertIs(lists[0][0], T_Equal, "slene")) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	query = fmt.Sprintf("SELECT %sprofile_id%s FROM %suser%s ORDER BY %sid%s ASC", Q, Q, Q, Q, Q, Q) | ||||||
| 	var list ParamsList | 	var list ParamsList | ||||||
| 		num, err = dORM.Raw("SELECT profile_id FROM user ORDER BY id ASC").ValuesFlat(&list) | 	num, err = dORM.Raw(query).ValuesFlat(&list) | ||||||
| 	throwFail(t, err) | 	throwFail(t, err) | ||||||
| 	throwFail(t, AssertIs(num, T_Equal, 3)) | 	throwFail(t, AssertIs(num, T_Equal, 3)) | ||||||
| 	if num == 3 { | 	if num == 3 { | ||||||
| @ -883,45 +1157,6 @@ func TestRawValues(t *testing.T) { | |||||||
| 		throwFail(t, AssertIs(list[1], T_Equal, "3")) | 		throwFail(t, AssertIs(list[1], T_Equal, "3")) | ||||||
| 		throwFail(t, AssertIs(list[2], T_Equal, nil)) | 		throwFail(t, AssertIs(list[2], T_Equal, nil)) | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	case IsPostgres: |  | ||||||
| 
 |  | ||||||
| 		res, err := dORM.Raw(`UPDATE "user" SET "user_name" = ? WHERE "user_name" = ?`, "testing", "slene").Exec() |  | ||||||
| 		throwFail(t, err) |  | ||||||
| 		num, err := res.RowsAffected() |  | ||||||
| 		throwFail(t, AssertIs(num, T_Equal, 1), err) |  | ||||||
| 
 |  | ||||||
| 		res, err = dORM.Raw(`UPDATE "user" SET "user_name" = ? WHERE "user_name" = ?`, "slene", "testing").Exec() |  | ||||||
| 		throwFail(t, err) |  | ||||||
| 		num, err = res.RowsAffected() |  | ||||||
| 		throwFail(t, AssertIs(num, T_Equal, 1), err) |  | ||||||
| 
 |  | ||||||
| 		var maps []Params |  | ||||||
| 		num, err = dORM.Raw(`SELECT "user_name" FROM "user" WHERE "status" = ?`, 1).Values(&maps) |  | ||||||
| 		throwFail(t, err) |  | ||||||
| 		throwFail(t, AssertIs(num, T_Equal, 1)) |  | ||||||
| 		if num == 1 { |  | ||||||
| 			throwFail(t, AssertIs(maps[0]["user_name"], T_Equal, "slene")) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		var lists []ParamsList |  | ||||||
| 		num, err = dORM.Raw(`SELECT "user_name" FROM "user" WHERE "status" = ?`, 1).ValuesList(&lists) |  | ||||||
| 		throwFail(t, err) |  | ||||||
| 		throwFail(t, AssertIs(num, T_Equal, 1)) |  | ||||||
| 		if num == 1 { |  | ||||||
| 			throwFail(t, AssertIs(lists[0][0], T_Equal, "slene")) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		var list ParamsList |  | ||||||
| 		num, err = dORM.Raw(`SELECT "profile_id" FROM "user" ORDER BY id ASC`).ValuesFlat(&list) |  | ||||||
| 		throwFail(t, err) |  | ||||||
| 		throwFail(t, AssertIs(num, T_Equal, 3)) |  | ||||||
| 		if num == 3 { |  | ||||||
| 			throwFail(t, AssertIs(list[0], T_Equal, "2")) |  | ||||||
| 			throwFail(t, AssertIs(list[1], T_Equal, "3")) |  | ||||||
| 			throwFail(t, AssertIs(list[2], T_Equal, nil)) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestRawPrepare(t *testing.T) { | func TestRawPrepare(t *testing.T) { | ||||||
|  | |||||||
| @ -115,6 +115,8 @@ func ToStr(value interface{}, args ...int) (s string) { | |||||||
| 		s = strconv.FormatUint(v, argInt(args).Get(0, 10)) | 		s = strconv.FormatUint(v, argInt(args).Get(0, 10)) | ||||||
| 	case string: | 	case string: | ||||||
| 		s = v | 		s = v | ||||||
|  | 	case []byte: | ||||||
|  | 		s = string(v) | ||||||
| 	default: | 	default: | ||||||
| 		s = fmt.Sprintf("%v", v) | 		s = fmt.Sprintf("%v", v) | ||||||
| 	} | 	} | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user