我如何在 Gorp 中使用 TypeConverter?
How do I use a TypeConverter in Gorp?
我想使用 Gorp 从包含专用类型的数据库中加载和保存结构。除其他外,这对于枚举字符串很有用,例如角色:
type Role string
type Account struct {
User string
Role Role
}
这行不通 "out of the box"。出现一条错误消息,例如
panic: sql: converting Exec argument #0's type: unsupported type user.Role, a string
我怀疑我需要使用 gorp.TypeConverter
来解决这个问题,但是没有关于如何做到这一点的文档。
你能帮忙吗?
Valuer and Scanner 界面会做你想做的事。这是一个工作示例:
package roleGorp
import (
"gopkg.in/gorp.v1"
"github.com/DATA-DOG/go-sqlmock"
"fmt"
"testing"
"database/sql/driver"
)
type Role string
func (r *Role) Scan(value interface{}) error { *r = Role(value.(string)); return nil }
func (r Role) Value() (driver.Value, error) { return string(r), nil }
type Account struct {
User string `db:"user"`
Role Role `db:"role"`
}
func TestRoleGorp(t *testing.T) {
db, err := sqlmock.New()
if err != nil {
panic(err)
}
dbMap := gorp.DbMap{
Db: db,
Dialect: gorp.MySQLDialect{
Engine: "InnoDB",
},
}
rows := sqlmock.NewRows([]string{"user", "role"}).AddRow("user1", "admin")
sqlmock.ExpectQuery(`SELECT \* FROM account LIMIT 1`).WillReturnRows(rows)
dbMap.AddTableWithName(Account{}, "account")
result := &Account{}
err = dbMap.SelectOne(result, "SELECT * FROM account LIMIT 1")
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", *result)
result2 := &Account{
User: "user2",
Role: Role("moderator"),
}
sqlmock.ExpectExec("insert into `account` \(`user`,`role`\) values \(\?,\?\);").WithArgs("user2", "moderator").WillReturnResult(sqlmock.NewResult(1, 1))
err = dbMap.Insert(result2)
if err != nil {
panic(err)
}
}
我想使用 Gorp 从包含专用类型的数据库中加载和保存结构。除其他外,这对于枚举字符串很有用,例如角色:
type Role string
type Account struct {
User string
Role Role
}
这行不通 "out of the box"。出现一条错误消息,例如
panic: sql: converting Exec argument #0's type: unsupported type user.Role, a string
我怀疑我需要使用 gorp.TypeConverter
来解决这个问题,但是没有关于如何做到这一点的文档。
你能帮忙吗?
Valuer and Scanner 界面会做你想做的事。这是一个工作示例:
package roleGorp
import (
"gopkg.in/gorp.v1"
"github.com/DATA-DOG/go-sqlmock"
"fmt"
"testing"
"database/sql/driver"
)
type Role string
func (r *Role) Scan(value interface{}) error { *r = Role(value.(string)); return nil }
func (r Role) Value() (driver.Value, error) { return string(r), nil }
type Account struct {
User string `db:"user"`
Role Role `db:"role"`
}
func TestRoleGorp(t *testing.T) {
db, err := sqlmock.New()
if err != nil {
panic(err)
}
dbMap := gorp.DbMap{
Db: db,
Dialect: gorp.MySQLDialect{
Engine: "InnoDB",
},
}
rows := sqlmock.NewRows([]string{"user", "role"}).AddRow("user1", "admin")
sqlmock.ExpectQuery(`SELECT \* FROM account LIMIT 1`).WillReturnRows(rows)
dbMap.AddTableWithName(Account{}, "account")
result := &Account{}
err = dbMap.SelectOne(result, "SELECT * FROM account LIMIT 1")
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", *result)
result2 := &Account{
User: "user2",
Role: Role("moderator"),
}
sqlmock.ExpectExec("insert into `account` \(`user`,`role`\) values \(\?,\?\);").WithArgs("user2", "moderator").WillReturnResult(sqlmock.NewResult(1, 1))
err = dbMap.Insert(result2)
if err != nil {
panic(err)
}
}