From 2110aa631e09728711e45c473bfa31cb0a2c1f7c Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 26 Jun 2013 01:02:22 +0800 Subject: [PATCH] add conversion interface; add struct derive support; add single mapping support --- examples/conversion.go | 76 ++++++++++++++++++++++++++++++++++++++++++ session.go | 13 ++++++++ table.go | 5 +++ 3 files changed, 94 insertions(+) create mode 100644 examples/conversion.go diff --git a/examples/conversion.go b/examples/conversion.go new file mode 100644 index 00000000..6b56a54a --- /dev/null +++ b/examples/conversion.go @@ -0,0 +1,76 @@ +package main + +import ( + "errors" + "fmt" + _ "github.com/mattn/go-sqlite3" + "os" + . "xorm" +) + +type Status struct { + Name string + Color string +} + +var ( + Registed Status = Status{"Registed", "white"} + Approved Status = Status{"Approved", "green"} + Removed Status = Status{"Removed", "red"} + Statuses map[string]Status = map[string]Status{ + Registed.Name: Registed, + Approved.Name: Approved, + Removed.Name: Removed, + } +) + +func (s *Status) FromDB(bytes []byte) error { + if r, ok := Statuses[string(bytes)]; ok { + *s = r + return nil + } else { + return errors.New("no this data") + } +} + +func (s *Status) ToDB() ([]byte, error) { + return []byte(s.Name), nil +} + +type User struct { + Id int64 + Name string + Status Status `xorm:"varchar(40)"` +} + +func main() { + f := "conversion.db" + os.Remove(f) + + Orm, err := NewEngine("sqlite3", f) + if err != nil { + fmt.Println(err) + return + } + Orm.ShowSQL = true + err = Orm.CreateTables(&User{}) + if err != nil { + fmt.Println(err) + return + } + + _, err = Orm.Insert(&User{1, "xlw", Registed}) + if err != nil { + fmt.Println(err) + return + } + + users := make([]User, 0) + err = Orm.Find(&users) + if err != nil { + fmt.Println(err) + return + } + + fmt.Println(users) +} diff --git a/session.go b/session.go index bd69a9d2..e2c9cbc5 100644 --- a/session.go +++ b/session.go @@ -225,6 +225,12 @@ func (session *Session) scanMapIntoStruct(obj interface{}, objMap map[string][]b } v = x + } else if structConvert, ok := structField.Addr().Interface().(Conversion); ok { + err := structConvert.FromDB(data) + if err != nil { + return err + } + continue } else if session.Statement.UseCascade { table := session.Engine.AutoMapType(structField.Type()) if table != nil { @@ -710,6 +716,13 @@ func (session *Session) InsertOne(bean interface{}) (int64, error) { } else { continue } + } else if fieldConvert, ok := fieldValue.Addr().Interface().(Conversion); ok { + data, err := fieldConvert.ToDB() + if err != nil { + return 0, err + } else { + args = append(args, string(data)) + } } else { args = append(args, val) } diff --git a/table.go b/table.go index 31540cd6..2edcd353 100644 --- a/table.go +++ b/table.go @@ -94,3 +94,8 @@ type Table struct { func (table *Table) PKColumn() Column { return table.Columns[table.PrimaryKey] } + +type Conversion interface { + FromDB([]byte) error + ToDB() ([]byte, error) +}