使用自定义类型扩展 Bun
Bun 使用 database/sql 与不同的 DBMS 协同工作,因此您可以使用 sql.Scanner 和 driver.Valuer 接口扩展它。
在本教程中,我们将编写一个简单的类型来处理没有日期的时间。
const timeFormat = "15:04:05.999999999"
type Time struct {
time.Time
}
sql.Scanner
sql.Scanner 从数据库驱动程序分配一个值。该值可以是以下类型之一
int64
float64
bool
[]byte
string
time.Time
nil
- 用于 NULL 值
var _ sql.Scanner = (*Time)(nil)
// Scan scans the time parsing it if necessary using timeFormat.
func (tm *Time) Scan(src interface{}) (err error) {
switch src := src.(type) {
case time.Time:
*tm = NewTime(src)
return nil
case string:
tm.Time, err = time.ParseInLocation(timeFormat, src, time.UTC)
return err
case []byte:
tm.Time, err = time.ParseInLocation(timeFormat, string(src), time.UTC)
return err
case nil:
tm.Time = time.Time{}
return nil
default:
return fmt.Errorf("unsupported data type: %T", src)
}
}
您可以在 GitHub 中找到完整的示例。
driver.Valuer
driver.Valuer 为数据库驱动程序返回一个值。该值必须是以下类型之一
int64
float64
bool
[]byte
string
time.Time
nil
- 用于 NULL 值
var _ driver.Valuer = (*Time)(nil)
// Scan scans the time parsing it if necessary using timeFormat.
func (tm Time) Value() (driver.Value, error) {
return tm.UTC().Format(timeFormat), nil
}
您可以在 GitHub 中找到完整的示例。
结论
您可以轻松地使用自定义类型扩展 Bun,以充分利用您的 DBMS 功能,例如,bunbig 为 Bun 添加了对 big.Int
的支持。
另请参阅