Skip to content

Instantly share code, notes, and snippets.

@roothybrid7
Last active December 6, 2015 02:05
Show Gist options
  • Save roothybrid7/2b7868e00539e70e51b3 to your computer and use it in GitHub Desktop.
Save roothybrid7/2b7868e00539e70e51b3 to your computer and use it in GitHub Desktop.
Golangのgormで、PrimaryKeyにUUIDを使う ref: http://qiita.com/roothybrid7/items/dc58bae01f941e1a72be
// gorm.Model
//type Model struct {
// ID uint64 `gorm:"primary_key"`
// CreatedAt time.Time
// UpdatedAt time.Time
// DeletedAt *time.Time
//}
type User struct {
gorm.Model
Name string
}
var (
reqKey private
UUIDGenerator = func(db *gorm.DB) UUID {
var uuid uint64
db.Unscoped().Raw("SELECT UUID_SHORT()").Row().Scan(&uuid)
return UUID(uuid)
}
)
// MARK: Gorm callbacks
func UpdateUUIDWhenCreate(scope *gorm.Scope) {
if !scope.HasError() {
scope.SetColumn("UUID", UUIDGenerator(scope.DB())) // Primary Key
}
}
func init() {
// XXX: DBのtimestampをUTCにする
gorm.NowFunc = util.NowUtcFunc
gorm.DefaultCallback.Create().Before("gorm:save_before_associations").Register("myapp:update_uuid_when_create", UpdateUUIDWhenCreate)
}
type User struct {
//gorm.Model // see: https://github.com/jinzhu/gorm#conventions
SoftModel
Username string `sql:"size:180;not null;index" json:"username"`
package typedef
import (
"errors"
"strconv"
)
// UUIDは、RDBではuint64で保存するが、
// APIのレスポンスやRedisでは16進数の文字列に変換して返すためのType
type UUID uint64
func (u UUID) IsZero() bool {
return u == 0
}
func (u UUID) MarshalJSON() ([]byte, error) {
hex := UintToHex(u)
if hex != "" {
return []byte(`"` + UintToHex(u) + `"`), nil
}
return nil, errors.New("UUID.MarshalText: invalid value")
}
// TODO: 多分タブルクオートを先にトリミングする必要がある
func (u *UUID) UnmarshalJSON(data []byte) (err error) {
i := UUID(UintFromHex(string(data)))
u = &i
return
}
func (u UUID) MarshalText() ([]byte, error) {
hex := UintToHex(u)
if hex != "" {
return []byte(UintToHex(u)), nil
}
return nil, errors.New("UUID.MarshalText: invalid value")
}
func (u *UUID) UnmarshalText(data []byte) (err error) {
i := UUID(UintFromHex(string(data)))
u = &i
return
}
func (u UUID) ToHex() string {
return strconv.FormatUint(uint64(u), 16)
}
// MARK: Helpers
func UintToHex(i interface{}) string {
switch v := i.(type) {
case uint64:
return strconv.FormatUint(v, 16)
case UUID:
return strconv.FormatUint(uint64(v), 16)
}
return ""
}
func UintFromHex(hex string) uint64 {
if num, err := strconv.ParseUint(hex, 16, 64); err != nil {
return 0
} else {
return num
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment