使用自定义类型扩展 Bun

Bun 使用 database/sql 与不同的 DBMS 协同工作,因此您可以使用 sql.Scannerdriver.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 的支持。

另请参阅