Вы должны реализовать интерфейсы sql.Scanner
и driver.Valuer
.
Примерно так:
func (j *jsonTime) Scan(src interface{}) error {
if t, ok := src.(time.Time); ok {
j.Time = t
}
return nil
}
func (j jsonTime) Value() (driver.Value, error) {
return j.Time, nil
}
Это необходимо, потому что пакет database/sql
, который используется gorm
и некоторыми другими go ORM, если не всеми из них, обеспечивает готовую поддержку только для нескольких типов.
Большинство поддерживаемых типов - это встроенные типы языка basi c, такие как string
, int
, bool
, et c. по расширению он также поддерживает любой настраиваемый пользовательский тип, чей базовый тип является одним из вышеупомянутых базовых c типов, затем есть поддержка типа []byte
и связанного с ним типа sql.RawBytes
, и, наконец, Тип time.Time
также поддерживается ootb.
Любой другой тип, который вы можете захотеть записать или прочитать из базы данных, должен будет реализовать два вышеуказанных интерфейса. Метод Scan
sql.Scanner
вызывается автоматически после значение столбца декодируется в один из поддерживаемых типов (поэтому вам нужно вводить assert против time.Time
, а не против, скажем []byte
). Метод driver.Valuer
s Value
вызывается автоматически перед драйвер кодирует его в формат, допустимый для целевого столбца (поэтому вы можете вернуть time.Time
, а чем кодирование самостоятельно).
И имейте в виду, что
type jsonTime struct {
time.Time
}
или даже
type jsonTime time.Time
объявляет новый тип что не равно и time.Time
, и поэтому он не принимается пакетом database/sql
.