added custom int and string type for primary key support

This commit is contained in:
Lunny Xiao 2016-04-06 22:19:38 +08:00
parent 2f8952d39b
commit 2b34c682f1
5 changed files with 31 additions and 19 deletions

View File

@ -1 +1 @@
xorm v0.5.3.0331 xorm v0.5.3.0406

View File

@ -75,15 +75,17 @@ func isZero(k interface{}) bool {
return false return false
} }
func int64ToInt(id int64, k reflect.Kind) interface{} { func int64ToIntValue(id int64, tp reflect.Type) reflect.Value {
var v interface{} = id var v interface{}
switch k { switch tp.Kind() {
case reflect.Int16: case reflect.Int16:
v = int16(id) v = int16(id)
case reflect.Int32: case reflect.Int32:
v = int32(id) v = int32(id)
case reflect.Int: case reflect.Int:
v = int(id) v = int(id)
case reflect.Int64:
v = id
case reflect.Uint16: case reflect.Uint16:
v = uint16(id) v = uint16(id)
case reflect.Uint32: case reflect.Uint32:
@ -93,7 +95,11 @@ func int64ToInt(id int64, k reflect.Kind) interface{} {
case reflect.Uint: case reflect.Uint:
v = uint(id) v = uint(id)
} }
return v return reflect.ValueOf(v).Convert(tp)
}
func int64ToInt(id int64, tp reflect.Type) interface{} {
return int64ToIntValue(id, tp).Interface()
} }
func isPKZero(pk core.PK) bool { func isPKZero(pk core.PK) bool {

View File

@ -960,7 +960,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
keyType := sliceValue.Type().Key() keyType := sliceValue.Type().Key()
var ikey interface{} var ikey interface{}
if len(key) == 1 { if len(key) == 1 {
ikey, err = Atot(fmt.Sprintf("%v", key[0]), keyType) ikey, err = Str2PK(fmt.Sprintf("%v", key[0]), keyType)
if err != nil { if err != nil {
return err return err
} }
@ -1123,7 +1123,8 @@ func (session *Session) Count(bean interface{}) (int64, error) {
return int64(total), err return int64(total), err
} }
func Atot(s string, tp reflect.Type) (interface{}, error) { // Str2PK convert string value to primary key value according to tp
func Str2PK(s string, tp reflect.Type) (interface{}, error) {
var err error var err error
var result interface{} var result interface{}
switch tp.Kind() { switch tp.Kind() {
@ -1189,6 +1190,7 @@ func Atot(s string, tp reflect.Type) (interface{}, error) {
default: default:
panic("unsupported convert type") panic("unsupported convert type")
} }
result = reflect.ValueOf(result).Convert(tp).Interface()
return result, nil return result, nil
} }
@ -1382,7 +1384,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
var key interface{} var key interface{}
// if there is only one pk, we can put the id as map key. // if there is only one pk, we can put the id as map key.
if len(table.PrimaryKeys) == 1 { if len(table.PrimaryKeys) == 1 {
key, err = Atot(string(results[table.PrimaryKeys[0]]), keyType) key, err = Str2PK(string(results[table.PrimaryKeys[0]]), keyType)
if err != nil { if err != nil {
return err return err
} }
@ -1392,7 +1394,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
} else { } else {
keys := core.PK{} keys := core.PK{}
for _, pk := range table.PrimaryKeys { for _, pk := range table.PrimaryKeys {
skey, err := Atot(string(results[pk]), keyType) skey, err := Str2PK(string(results[pk]), keyType)
if err != nil { if err != nil {
return err return err
} }
@ -3298,8 +3300,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
return 1, nil return 1, nil
} }
v := int64ToInt(id, aiValue.Type().Kind()) aiValue.Set(int64ToIntValue(id, aiValue.Type()))
aiValue.Set(reflect.ValueOf(v))
return 1, nil return 1, nil
} else if session.Engine.dialect.DBType() == core.POSTGRES && len(table.AutoIncrement) > 0 { } else if session.Engine.dialect.DBType() == core.POSTGRES && len(table.AutoIncrement) > 0 {
@ -3344,8 +3345,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
return 1, nil return 1, nil
} }
v := int64ToInt(id, aiValue.Type().Kind()) aiValue.Set(int64ToIntValue(id, aiValue.Type()))
aiValue.Set(reflect.ValueOf(v))
return 1, nil return 1, nil
} else { } else {
@ -3387,7 +3387,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
return res.RowsAffected() return res.RowsAffected()
} }
v := int64ToInt(id, aiValue.Type().Kind()) v := int64ToInt(id, aiValue.Type())
aiValue.Set(reflect.ValueOf(v)) aiValue.Set(reflect.ValueOf(v))
return res.RowsAffected() return res.RowsAffected()

View File

@ -688,7 +688,7 @@ var (
pkType = reflect.TypeOf(core.PK{}) pkType = reflect.TypeOf(core.PK{})
) )
// Generate "where id = ? " statment or for composite key "where key1 = ? and key2 = ?" // Id generate "where id = ? " statment or for composite key "where key1 = ? and key2 = ?"
func (statement *Statement) Id(id interface{}) *Statement { func (statement *Statement) Id(id interface{}) *Statement {
idValue := reflect.ValueOf(id) idValue := reflect.ValueOf(id)
idType := reflect.TypeOf(idValue.Interface()) idType := reflect.TypeOf(idValue.Interface())
@ -697,16 +697,22 @@ func (statement *Statement) Id(id interface{}) *Statement {
case ptrPkType: case ptrPkType:
if pkPtr, ok := (id).(*core.PK); ok { if pkPtr, ok := (id).(*core.PK); ok {
statement.IdParam = pkPtr statement.IdParam = pkPtr
return statement
} }
case pkType: case pkType:
if pk, ok := (id).(core.PK); ok { if pk, ok := (id).(core.PK); ok {
statement.IdParam = &pk statement.IdParam = &pk
return statement
} }
default:
// TODO: treat as int primitve for now, need to handle type check?
statement.IdParam = &core.PK{id}
} }
switch idType.Kind() {
case reflect.String:
statement.IdParam = &core.PK{idValue.Convert(reflect.TypeOf("")).Interface()}
return statement
}
statement.IdParam = &core.PK{id}
return statement return statement
} }

View File

@ -17,7 +17,7 @@ import (
const ( const (
// Version show the xorm's version // Version show the xorm's version
Version string = "0.5.3.0331" Version string = "0.5.3.0406"
) )
func regDrvsNDialects() bool { func regDrvsNDialects() bool {