Skip to content

Commit

Permalink
Add support for signed and unsigned integer types as primary key type
Browse files Browse the repository at this point in the history
  • Loading branch information
galeone committed Oct 22, 2014
1 parent 52ba185 commit c108cf0
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 14 deletions.
13 changes: 13 additions & 0 deletions query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,19 @@ func TestFirstAndLastWithNoStdPrimaryKey(t *testing.T) {
}
}

func TestUIntPrimaryKey(t *testing.T) {
var animal Animal
DB.First(&animal, uint64(1))
if animal.Counter != 1 {
t.Errorf("Fetch a record from with a non-int primary key should work, but failed")
}

DB.Model(Animal{}).Where(Animal{Counter: uint64(2)}).Scan(&animal)
if animal.Counter != 2 {
t.Errorf("Fetch a record from with a non-int primary key should work, but failed")
}
}

func TestFindAsSliceOfPointers(t *testing.T) {
DB.Save(&User{Name: "user"})

Expand Down
8 changes: 4 additions & 4 deletions scope_private.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ func (scope *Scope) buildWhereCondition(clause map[string]interface{}) (str stri
} else {
str = value
}
case int, int64, int32:
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
return scope.primaryCondiation(scope.AddToVars(value))
case sql.NullInt64:
return scope.primaryCondiation(scope.AddToVars(value.Int64))
case []int64, []int, []int32, []string:
case []int, []int8, []int16, []int32, []int64, []uint, []uint8, []uint16, []uint32, []uint64, []string:
str = fmt.Sprintf("(%v in (?))", scope.Quote(scope.PrimaryKey()))
clause["args"] = []interface{}{value}
case map[string]interface{}:
Expand Down Expand Up @@ -84,9 +84,9 @@ func (scope *Scope) buildNotCondition(clause map[string]interface{}) (str string
str = fmt.Sprintf("(%v NOT IN (?))", scope.Quote(value))
notEqualSql = fmt.Sprintf("(%v <> ?)", scope.Quote(value))
}
case int, int64, int32:
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
return fmt.Sprintf("(%v <> %v)", scope.Quote(scope.PrimaryKey()), value)
case []int64, []int, []int32, []string:
case []int, []int8, []int16, []int32, []int64, []uint, []uint8, []uint16, []uint32, []uint64, []string:
if reflect.ValueOf(value).Len() > 0 {
str = fmt.Sprintf("(%v not in (?))", scope.Quote(scope.PrimaryKey()))
clause["args"] = []interface{}{value}
Expand Down
1 change: 0 additions & 1 deletion scope_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package gorm_test

import (
"github.com/jinzhu/gorm"

"testing"
)

Expand Down
51 changes: 44 additions & 7 deletions search.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,54 @@ func (s *search) table(name string) *search {
}

func (s *search) getInterfaceAsSql(value interface{}) (str string) {
switch value := value.(type) {
var s_num int64
var u_num uint64
var isString, unsigned bool = false, false

switch value.(type) {
case string:
str = value
str = value.(string)
isString = true
case int:
if value < 0 {
str = ""
} else {
str = strconv.Itoa(value)
}
s_num = int64(value.(int))
case int8:
s_num = int64(value.(int8))
case int16:
s_num = int64(value.(int16))
case int32:
s_num = int64(value.(int32))
case int64:
s_num = int64(value.(int64))
case uint:
u_num = uint64(value.(uint))
unsigned = true
case uint8:
u_num = uint64(value.(uint8))
unsigned = true
case uint16:
u_num = uint64(value.(uint16))
unsigned = true
case uint32:
u_num = uint64(value.(uint32))
unsigned = true
case uint64:
u_num = uint64(value.(uint64))
unsigned = true
default:
s.db.err(InvalidSql)
}

if !isString {
if unsigned {
str = strconv.FormatUint(u_num, 10)
} else {
if s_num < 0 {
str = ""
} else {
str = strconv.FormatInt(s_num, 10)
}
}
}

return
}
3 changes: 1 addition & 2 deletions structs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ type Role struct {
Name string
}


func (role *Role) Scan(value interface{}) error {
if b, ok := value.([]uint8); ok {
role.Name = string(b)
Expand Down Expand Up @@ -126,7 +125,7 @@ func (i *Num) Scan(src interface{}) error {
}

type Animal struct {
Counter int64 `gorm:"primary_key:yes"`
Counter uint64 `gorm:"primary_key:yes"`
Name string
From string //test reserved sql keyword as field name
CreatedAt time.Time
Expand Down

0 comments on commit c108cf0

Please sign in to comment.