Last active
October 15, 2016 12:48
-
-
Save roothybrid7/fafebcf3cbdc70143f15486f96229f7f to your computer and use it in GitHub Desktop.
Golangのgormで、PrimaryKeyにXIDを使う ref: http://qiita.com/roothybrid7/items/2db3ccbf46f2bdb9cd00
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Model is a base model that defines a primary key and timestamp on operation. | |
type Model struct { | |
XID T.XID `gorm:"type:varchar(20);primary_key" json:"id"` // XXX: XID on create callback. | |
CreatedAt T.ResourceTime `json:"createdAt"` | |
UpdatedAt T.ResourceTime `json:"updatedAt"` | |
} | |
// SoftModel is a base model to delete a record. | |
type SoftModel struct { | |
XID T.XID `gorm:"type:varchar(20);primary_key" json:"id"` // XXX: XID on create callback. | |
CreatedAt T.ResourceTime `json:"createdAt"` | |
UpdatedAt T.ResourceTime `json:"updatedAt"` | |
DeletedAt *time.Time `json:"deletedAt,omitempty"` // XXX: ポインターだとカラム追加できない | |
} | |
// User is a model of user. | |
type User struct { | |
//gorm.Model // see: https://github.com/jinzhu/gorm#conventions | |
SoftModel | |
Username string `gorm:"size:180;not null;index" json:"username"` | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package repos | |
import ( | |
"github.com/jinzhu/gorm" | |
T "bitbucket.org/team1/app/module/typedef" | |
"bitbucket.org/team1/app/module/util" | |
) | |
// Gorm callbacks | |
func updateXIDWhenCreate(scope *gorm.Scope) { | |
if !scope.HasError() { | |
scope.SetColumn("XID", *T.NewXID()) // Primary Key | |
} | |
} | |
func init() { | |
// XXX: DBのtimestampをUTCにする | |
gorm.NowFunc = util.NowUtcFunc | |
gorm.DefaultCallback.Create().Before("gorm:save_before_associations").Register("app:update_xid_when_create", updateXIDWhenCreate) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package typedef | |
import ( | |
"database/sql/driver" | |
"errors" | |
json "github.com/pquerna/ffjson/ffjson" | |
"github.com/rs/xid" | |
) | |
// XID redefines a new type to use application. | |
type XID struct { | |
id xid.ID | |
} | |
// NewXID creates a new xid. | |
func NewXID() *XID { | |
return &XID{id: xid.New()} | |
} | |
// NewXIDFromString creates a XID object to use xid generator. | |
func NewXIDFromString(str string) *XID { | |
id, err := xid.FromString(str) | |
if err != nil { | |
return nil | |
} | |
return &XID{id: id} | |
} | |
// XIDFromString creates from string representation. | |
func XIDFromString(str string) (id XID, err error) { | |
v, err := xid.FromString(str) | |
if err != nil { | |
return | |
} | |
id.id = v | |
return | |
} | |
// IsZero defines to check whether nil value or not. | |
func (id XID) IsZero() bool { | |
return len(id.id) == 0 | |
} | |
// EqualString returns both string representation. | |
func (id XID) EqualString(s string) bool { | |
return id.String() == s | |
} | |
// String returns xid string representation. | |
func (id XID) String() string { | |
return id.id.String() | |
} | |
// Marshalizations | |
// MarshalJSON returns the encoded JSON string. | |
func (id XID) MarshalJSON() ([]byte, error) { | |
v := id.id | |
return []byte(`"` + v.String() + `"`), nil | |
} | |
// UnmarshalJSON sets the value that decoded JSON. | |
func (id *XID) UnmarshalJSON(data []byte) (err error) { | |
var v string | |
if err = json.Unmarshal(data, &v); err != nil { | |
return | |
} | |
if err = id.Scan(v); err != nil { | |
return | |
} | |
return | |
} | |
// Sql driver interface. | |
// Scan casts a value to xid.ID | |
// XXX: DBからのvalueは、[]uint8で渡ってくるっぽい(ascii codeが入ってる) | |
func (id *XID) Scan(value interface{}) (err error) { | |
switch v := value.(type) { | |
case string: | |
id.id, err = xid.FromString(v) | |
case []uint8: | |
b := make([]byte, len(v)) | |
for i, a := range v { | |
b[i] = byte(a) | |
} | |
id.id, err = xid.FromString(string(b)) | |
default: | |
err = errors.New("xid.Scan: invalid value") | |
} | |
return | |
} | |
// Value exports the casted object value. | |
func (id XID) Value() (driver.Value, error) { | |
return id.String(), nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment