前提
gorp と go-mysql-driver を使っている。DBとマッピングする構造体に、カスタム定義の型を使いたい。
gorp https://github.com/go-gorp/gorp
go-mysql-driver https://github.com/go-sql-driver/mysql
//define my custom type
type ItemId string
// define my table
type Item struct {
ItemId ItemId `db:"item_id"`
}
問題
gorpでクエリを打ってみると、このようなエラーが出て失敗。
error: sql: converting argument $1 type: unsupported type hoge.ItemId, a string
解決
database/sql/driver
.Valuer インターフェースと、
database/sql/sql
.Scanner インターフェースを実装すれば良いらしい。
実装
func (a ItemId) Value() (driver.Value, error) {
return driver.Value(string(a)), nil
}
func (a *ItemId) Scan(value interface{}) error {
*a = ItemId(string(value.([]uint8)))
return nil
}
この、Value()とScan()の中身は、実際の型にあわせて、よしなに実装する。
今回は error は nil で返してしまっているが、型に適合しているかのチェックにも使えるようだ。
また、Value()とScan()はシリアライザ・デシリアライザのように使えるので、複雑な独自の構造体をDBの単一カラムに割り当てるような使い方も可能なようだ。
タイトルに gorp と入れてしまったが、特にgorpに限定した話ではない。