diff --git a/jsontime/integer.go b/jsontime/integer.go index 26ac588..d751755 100644 --- a/jsontime/integer.go +++ b/jsontime/integer.go @@ -7,7 +7,11 @@ package jsontime import ( + "database/sql" + "database/sql/driver" "encoding/json" + "errors" + "fmt" "time" ) @@ -25,6 +29,9 @@ func parseTime(data []byte, unixConv func(int64) time.Time, into *time.Time) err return nil } +var _ sql.Scanner = &UnixMilli{} +var _ driver.Valuer = UnixMilli{} + type UnixMilli struct { time.Time } @@ -40,6 +47,32 @@ func (um *UnixMilli) UnmarshalJSON(data []byte) error { return parseTime(data, time.UnixMilli, &um.Time) } +func (um UnixMilli) Value() (driver.Value, error) { + return time.Time(um.Time).UnixMilli(), nil +} + +func (um *UnixMilli) Scan(src any) error { + switch v := src.(type) { + case int: + um.Time = time.UnixMilli(int64(v)) + case int8: + um.Time = time.UnixMilli(int64(v)) + case int16: + um.Time = time.UnixMilli(int64(v)) + case int32: + um.Time = time.UnixMilli(int64(v)) + case int64: + um.Time = time.UnixMilli(v) + default: + return fmt.Errorf("%w: %T is not an integer", errors.ErrUnsupported, src) + } + + return nil +} + +var _ sql.Scanner = &UnixMicro{} +var _ driver.Valuer = UnixMicro{} + type UnixMicro struct { time.Time } @@ -55,6 +88,32 @@ func (um *UnixMicro) UnmarshalJSON(data []byte) error { return parseTime(data, time.UnixMicro, &um.Time) } +func (um UnixMicro) Value() (driver.Value, error) { + return time.Time(um.Time).UnixMicro(), nil +} + +func (um *UnixMicro) Scan(src any) error { + switch v := src.(type) { + case int: + um.Time = time.UnixMicro(int64(v)) + case int8: + um.Time = time.UnixMicro(int64(v)) + case int16: + um.Time = time.UnixMicro(int64(v)) + case int32: + um.Time = time.UnixMicro(int64(v)) + case int64: + um.Time = time.UnixMicro(v) + default: + return fmt.Errorf("%w: %T is not an integer", errors.ErrUnsupported, src) + } + + return nil +} + +var _ sql.Scanner = &UnixNano{} +var _ driver.Valuer = UnixNano{} + type UnixNano struct { time.Time } @@ -72,6 +131,29 @@ func (un *UnixNano) UnmarshalJSON(data []byte) error { }, &un.Time) } +func (un UnixNano) Value() (driver.Value, error) { + return time.Time(un.Time).UnixNano(), nil +} + +func (un *UnixNano) Scan(src any) error { + switch v := src.(type) { + case int: + un.Time = time.Unix(0, int64(v)) + case int8: + un.Time = time.Unix(0, int64(v)) + case int16: + un.Time = time.Unix(0, int64(v)) + case int32: + un.Time = time.Unix(0, int64(v)) + case int64: + un.Time = time.Unix(0, v) + default: + return fmt.Errorf("%w: %T is not an integer", errors.ErrUnsupported, src) + } + + return nil +} + type Unix struct { time.Time } @@ -83,8 +165,34 @@ func (u Unix) MarshalJSON() ([]byte, error) { return json.Marshal(u.Unix()) } +var _ sql.Scanner = &Unix{} +var _ driver.Valuer = Unix{} + func (u *Unix) UnmarshalJSON(data []byte) error { return parseTime(data, func(i int64) time.Time { return time.Unix(i, 0) }, &u.Time) } + +func (u Unix) Value() (driver.Value, error) { + return time.Time(u.Time).Unix(), nil +} + +func (u *Unix) Scan(src any) error { + switch v := src.(type) { + case int: + u.Time = time.Unix(int64(v), 0) + case int8: + u.Time = time.Unix(int64(v), 0) + case int16: + u.Time = time.Unix(int64(v), 0) + case int32: + u.Time = time.Unix(int64(v), 0) + case int64: + u.Time = time.Unix(v, 0) + default: + return fmt.Errorf("%w: %T is not an integer", errors.ErrUnsupported, src) + } + + return nil +}