From 2b34c682f1aef03c50f9733b2a443d9f8278c679 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 6 Apr 2016 22:19:38 +0800 Subject: [PATCH] added custom int and string type for primary key support --- VERSION | 2 +- helpers.go | 14 ++++++++++---- session.go | 18 +++++++++--------- statement.go | 14 ++++++++++---- xorm.go | 2 +- 5 files changed, 31 insertions(+), 19 deletions(-) diff --git a/VERSION b/VERSION index eae5ed79..29ae8505 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -xorm v0.5.3.0331 +xorm v0.5.3.0406 diff --git a/helpers.go b/helpers.go index 5962c106..b0949d3f 100644 --- a/helpers.go +++ b/helpers.go @@ -75,15 +75,17 @@ func isZero(k interface{}) bool { return false } -func int64ToInt(id int64, k reflect.Kind) interface{} { - var v interface{} = id - switch k { +func int64ToIntValue(id int64, tp reflect.Type) reflect.Value { + var v interface{} + switch tp.Kind() { case reflect.Int16: v = int16(id) case reflect.Int32: v = int32(id) case reflect.Int: v = int(id) + case reflect.Int64: + v = id case reflect.Uint16: v = uint16(id) case reflect.Uint32: @@ -93,7 +95,11 @@ func int64ToInt(id int64, k reflect.Kind) interface{} { case reflect.Uint: 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 { diff --git a/session.go b/session.go index e6eb0431..432104e6 100644 --- a/session.go +++ b/session.go @@ -960,7 +960,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in keyType := sliceValue.Type().Key() var ikey interface{} 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 { return err } @@ -1123,7 +1123,8 @@ func (session *Session) Count(bean interface{}) (int64, error) { 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 result interface{} switch tp.Kind() { @@ -1189,6 +1190,7 @@ func Atot(s string, tp reflect.Type) (interface{}, error) { default: panic("unsupported convert type") } + result = reflect.ValueOf(result).Convert(tp).Interface() return result, nil } @@ -1382,7 +1384,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) var key interface{} // if there is only one pk, we can put the id as map key. 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 { return err } @@ -1392,7 +1394,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) } else { keys := core.PK{} for _, pk := range table.PrimaryKeys { - skey, err := Atot(string(results[pk]), keyType) + skey, err := Str2PK(string(results[pk]), keyType) if err != nil { return err } @@ -3298,8 +3300,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) { return 1, nil } - v := int64ToInt(id, aiValue.Type().Kind()) - aiValue.Set(reflect.ValueOf(v)) + aiValue.Set(int64ToIntValue(id, aiValue.Type())) return 1, nil } 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 } - v := int64ToInt(id, aiValue.Type().Kind()) - aiValue.Set(reflect.ValueOf(v)) + aiValue.Set(int64ToIntValue(id, aiValue.Type())) return 1, nil } else { @@ -3387,7 +3387,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) { return res.RowsAffected() } - v := int64ToInt(id, aiValue.Type().Kind()) + v := int64ToInt(id, aiValue.Type()) aiValue.Set(reflect.ValueOf(v)) return res.RowsAffected() diff --git a/statement.go b/statement.go index 10ed3a20..5662a805 100644 --- a/statement.go +++ b/statement.go @@ -688,7 +688,7 @@ var ( 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 { idValue := reflect.ValueOf(id) idType := reflect.TypeOf(idValue.Interface()) @@ -697,16 +697,22 @@ func (statement *Statement) Id(id interface{}) *Statement { case ptrPkType: if pkPtr, ok := (id).(*core.PK); ok { statement.IdParam = pkPtr + return statement } case pkType: if pk, ok := (id).(core.PK); ok { 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 } diff --git a/xorm.go b/xorm.go index fad9c0c4..fcae102c 100644 --- a/xorm.go +++ b/xorm.go @@ -17,7 +17,7 @@ import ( const ( // Version show the xorm's version - Version string = "0.5.3.0331" + Version string = "0.5.3.0406" ) func regDrvsNDialects() bool {