1

我想使用 Gorp 从数据库中加载和保存包含特殊类型的结构。除其他外,这对于枚举字符串(例如角色)很有用:

type Role string

type Account struct {
    User string
    Role Role
}

这不是“开箱即用”的。引发错误消息,例如

panic: sql: converting Exec argument #0's type: unsupported type user.Role, a string

我怀疑我需要使用 agorp.TypeConverter来解决这个问题,但是没有关于如何做到这一点的文档。

你能帮我吗?

4

1 回答 1

2

ValuerScanner界面可以满足您的需求。这是一个工作示例:

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)
    }
}
于 2015-06-17T14:36:12.050 回答