Skip to content

Commit

Permalink
More refactor around extended time (#978)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tang8330 authored Oct 23, 2024
1 parent 20e3b34 commit 97f05e9
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 43 deletions.
12 changes: 8 additions & 4 deletions lib/debezium/converters/date.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,20 @@ import (

type Date struct{}

func (Date) ToKindDetails() typing.KindDetails {
return typing.NewExtendedTimeDetails(typing.ETime, ext.DateKindType, "")
func (Date) layout() string {
return ext.PostgresDateFormat
}

func (Date) Convert(value any) (any, error) {
func (d Date) ToKindDetails() typing.KindDetails {
return typing.NewExtendedTimeDetails(typing.ETime, ext.DateKindType, d.layout())
}

func (d Date) Convert(value any) (any, error) {
valueInt64, isOk := value.(int64)
if !isOk {
return nil, fmt.Errorf("expected int64 got '%v' with type %T", value, value)
}

// Represents the number of days since the epoch.
return ext.NewExtendedTime(time.UnixMilli(0).In(time.UTC).AddDate(0, 0, int(valueInt64)), ext.DateKindType, ""), nil
return ext.NewExtendedTime(time.UnixMilli(0).In(time.UTC).AddDate(0, 0, int(valueInt64)), ext.DateKindType, d.layout()), nil
}
4 changes: 2 additions & 2 deletions lib/debezium/converters/date_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ func TestDate_Convert(t *testing.T) {

extTime, isOk := val.(*ext.ExtendedTime)
assert.True(t, isOk)
assert.Equal(t, "2023-02-13", extTime.String(""))
assert.Equal(t, "2023-02-13", extTime.GetTime().Format(Date{}.layout()))
}
{
val, err := Date{}.Convert(int64(19429))
assert.NoError(t, err)

extTime, isOk := val.(*ext.ExtendedTime)
assert.True(t, isOk)
assert.Equal(t, "2023-03-13", extTime.String(""))
assert.Equal(t, "2023-03-13", extTime.GetTime().Format(Date{}.layout()))
}
}
40 changes: 20 additions & 20 deletions lib/debezium/converters/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestZonedTimestamp_Convert(t *testing.T) {

expectedExtTime := ext.NewExtendedTime(time.Date(2025, time.September, 13, 0, 0, 12, 000000000, time.UTC), ext.TimestampTZKindType, "2006-01-02T15:04:05.999999999Z")
assert.Equal(t, expectedExtTime, val.(*ext.ExtendedTime))
assert.Equal(t, "2025-09-13T00:00:12Z", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2025-09-13T00:00:12Z", val.(*ext.ExtendedTime).GetTime().Format(ZonedTimestamp{}.layout()))
}
{
// 1 digits
Expand All @@ -46,7 +46,7 @@ func TestZonedTimestamp_Convert(t *testing.T) {

expectedExtTime := ext.NewExtendedTime(time.Date(2025, time.September, 13, 0, 0, 0, 100000000, time.UTC), ext.TimestampTZKindType, "2006-01-02T15:04:05.999999999Z")
assert.Equal(t, expectedExtTime, val.(*ext.ExtendedTime))
assert.Equal(t, "2025-09-13T00:00:00.1Z", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2025-09-13T00:00:00.1Z", val.(*ext.ExtendedTime).GetTime().Format(ZonedTimestamp{}.layout()))
}
{
// 2 digits
Expand All @@ -55,7 +55,7 @@ func TestZonedTimestamp_Convert(t *testing.T) {

expectedExtTime := ext.NewExtendedTime(time.Date(2025, time.September, 13, 0, 0, 0, 120000000, time.UTC), ext.TimestampTZKindType, "2006-01-02T15:04:05.999999999Z")
assert.Equal(t, expectedExtTime, val.(*ext.ExtendedTime))
assert.Equal(t, "2025-09-13T00:00:00.12Z", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2025-09-13T00:00:00.12Z", val.(*ext.ExtendedTime).GetTime().Format(ZonedTimestamp{}.layout()))
}
{
// 3 digits
Expand All @@ -64,7 +64,7 @@ func TestZonedTimestamp_Convert(t *testing.T) {

expectedExtTime := ext.NewExtendedTime(time.Date(2025, time.September, 13, 0, 0, 0, 123000000, time.UTC), ext.TimestampTZKindType, "2006-01-02T15:04:05.999999999Z")
assert.Equal(t, expectedExtTime, val.(*ext.ExtendedTime))
assert.Equal(t, "2025-09-13T00:00:00.123Z", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2025-09-13T00:00:00.123Z", val.(*ext.ExtendedTime).GetTime().Format(ZonedTimestamp{}.layout()))
}
{
// 4 digits
Expand All @@ -73,7 +73,7 @@ func TestZonedTimestamp_Convert(t *testing.T) {

expectedExtTime := ext.NewExtendedTime(time.Date(2025, time.September, 13, 0, 0, 0, 123400000, time.UTC), ext.TimestampTZKindType, "2006-01-02T15:04:05.999999999Z")
assert.Equal(t, expectedExtTime, val.(*ext.ExtendedTime))
assert.Equal(t, "2025-09-13T00:00:00.1234Z", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2025-09-13T00:00:00.1234Z", val.(*ext.ExtendedTime).GetTime().Format(ZonedTimestamp{}.layout()))
}
{
// 5 digits
Expand All @@ -82,7 +82,7 @@ func TestZonedTimestamp_Convert(t *testing.T) {

expectedExtTime := ext.NewExtendedTime(time.Date(2025, time.September, 13, 0, 0, 0, 123450000, time.UTC), ext.TimestampTZKindType, "2006-01-02T15:04:05.999999999Z")
assert.Equal(t, expectedExtTime, val.(*ext.ExtendedTime))
assert.Equal(t, "2025-09-13T00:00:00.12345Z", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2025-09-13T00:00:00.12345Z", val.(*ext.ExtendedTime).GetTime().Format(ZonedTimestamp{}.layout()))
}
{
// 6 digits (microseconds)
Expand All @@ -91,7 +91,7 @@ func TestZonedTimestamp_Convert(t *testing.T) {

expectedExtTime := ext.NewExtendedTime(time.Date(2025, time.September, 13, 0, 0, 0, 123456000, time.UTC), ext.TimestampTZKindType, "2006-01-02T15:04:05.999999999Z")
assert.Equal(t, expectedExtTime, val.(*ext.ExtendedTime))
assert.Equal(t, "2025-09-13T00:00:00.123456Z", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2025-09-13T00:00:00.123456Z", val.(*ext.ExtendedTime).GetTime().Format(ZonedTimestamp{}.layout()))
}
{
// 7 digits
Expand All @@ -100,7 +100,7 @@ func TestZonedTimestamp_Convert(t *testing.T) {

expectedExtTime := ext.NewExtendedTime(time.Date(2025, time.September, 13, 0, 0, 0, 123456700, time.UTC), ext.TimestampTZKindType, "2006-01-02T15:04:05.999999999Z")
assert.Equal(t, expectedExtTime, val.(*ext.ExtendedTime))
assert.Equal(t, "2025-09-13T00:00:00.1234567Z", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2025-09-13T00:00:00.1234567Z", val.(*ext.ExtendedTime).GetTime().Format(ZonedTimestamp{}.layout()))
}
{
// 8 digits
Expand All @@ -109,7 +109,7 @@ func TestZonedTimestamp_Convert(t *testing.T) {

expectedExtTime := ext.NewExtendedTime(time.Date(2025, time.September, 13, 0, 0, 0, 123456780, time.UTC), ext.TimestampTZKindType, "2006-01-02T15:04:05.999999999Z")
assert.Equal(t, expectedExtTime, val.(*ext.ExtendedTime))
assert.Equal(t, "2025-09-13T00:00:00.12345678Z", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2025-09-13T00:00:00.12345678Z", val.(*ext.ExtendedTime).GetTime().Format(ZonedTimestamp{}.layout()))
}
{
// 9 digits (nanoseconds)
Expand All @@ -118,7 +118,7 @@ func TestZonedTimestamp_Convert(t *testing.T) {

expectedExtTime := ext.NewExtendedTime(time.Date(2025, time.September, 13, 0, 0, 0, 123456789, time.UTC), ext.TimestampTZKindType, "2006-01-02T15:04:05.999999999Z")
assert.Equal(t, expectedExtTime, val.(*ext.ExtendedTime))
assert.Equal(t, "2025-09-13T00:00:00.123456789Z", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2025-09-13T00:00:00.123456789Z", val.(*ext.ExtendedTime).GetTime().Format(ZonedTimestamp{}.layout()))
}
}
}
Expand All @@ -130,15 +130,15 @@ func TestTime_Convert(t *testing.T) {

extTime, isOk := val.(*ext.ExtendedTime)
assert.True(t, isOk)
assert.Equal(t, "15:12:00.321", extTime.String(""))
assert.Equal(t, "15:12:00.321", extTime.GetTime().Format(Time{}.layout()))
}
{
val, err := Time{}.Convert(int64(54720000))
assert.NoError(t, err)

extTime, isOk := val.(*ext.ExtendedTime)
assert.True(t, isOk)
assert.Equal(t, "15:12:00.000", extTime.String(""))
assert.Equal(t, "15:12:00.000", extTime.GetTime().Format(Time{}.layout()))
}
}

Expand All @@ -153,7 +153,7 @@ func TestNanoTime_Converter(t *testing.T) {
// Valid
val, err := NanoTime{}.Convert(int64(54_720_000_009_000))
assert.NoError(t, err)
assert.Equal(t, "15:12:00.000009000", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "15:12:00.000009000", val.(*ext.ExtendedTime).GetTime().Format(NanoTime{}.layout()))
}
}

Expand All @@ -168,7 +168,7 @@ func TestMicroTime_Converter(t *testing.T) {
// Valid
val, err := MicroTime{}.Convert(int64(54720000000))
assert.NoError(t, err)
assert.Equal(t, "15:12:00.000000", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "15:12:00.000000", val.(*ext.ExtendedTime).GetTime().Format(MicroTime{}.layout()))
}
}

Expand Down Expand Up @@ -196,26 +196,26 @@ func TestConvertTimeWithTimezone(t *testing.T) {
val, err := TimeWithTimezone{}.Convert("23:02:06.745116Z")
assert.NoError(t, err)

expectedTs := ext.NewExtendedTime(time.Date(0, 1, 1, 23, 2, 6, 745116000, time.UTC), ext.TimeKindType, "15:04:05.999999Z")
expectedTs := ext.NewExtendedTime(time.Date(0, 1, 1, 23, 2, 6, 745116000, time.UTC), ext.TimeKindType, TimeWithTimezone{}.layout())
assert.Equal(t, expectedTs, val.(*ext.ExtendedTime))
assert.Equal(t, "23:02:06.745116Z", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "23:02:06.745116Z", val.(*ext.ExtendedTime).GetTime().Format(TimeWithTimezone{}.layout()))
}
{
// ms precision
val, err := TimeWithTimezone{}.Convert("23:02:06.745Z")
assert.NoError(t, err)

expectedTs := ext.NewExtendedTime(time.Date(0, 1, 1, 23, 2, 6, 745000000, time.UTC), ext.TimeKindType, "15:04:05.999999Z")
expectedTs := ext.NewExtendedTime(time.Date(0, 1, 1, 23, 2, 6, 745000000, time.UTC), ext.TimeKindType, TimeWithTimezone{}.layout())
assert.Equal(t, expectedTs, val.(*ext.ExtendedTime))
assert.Equal(t, "23:02:06.745Z", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "23:02:06.745Z", val.(*ext.ExtendedTime).GetTime().Format(TimeWithTimezone{}.layout()))
}
{
// no fractional seconds
val, err := TimeWithTimezone{}.Convert("23:02:06Z")
assert.NoError(t, err)

expectedTs := ext.NewExtendedTime(time.Date(0, 1, 1, 23, 2, 6, 0, time.UTC), ext.TimeKindType, "15:04:05.999999Z")
expectedTs := ext.NewExtendedTime(time.Date(0, 1, 1, 23, 2, 6, 0, time.UTC), ext.TimeKindType, TimeWithTimezone{}.layout())
assert.Equal(t, expectedTs, val.(*ext.ExtendedTime))
assert.Equal(t, "23:02:06Z", val.(*ext.ExtendedTime).String(""))
assert.Equal(t, "23:02:06Z", val.(*ext.ExtendedTime).GetTime().Format(TimeWithTimezone{}.layout()))
}
}
12 changes: 6 additions & 6 deletions lib/debezium/converters/timestamp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ func TestTimestamp_Converter(t *testing.T) {
// Valid conversion
converted, err := Timestamp{}.Convert(int64(1_725_058_799_089))
assert.NoError(t, err)
assert.Equal(t, "2024-08-30T22:59:59.089", converted.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2024-08-30T22:59:59.089", converted.(*ext.ExtendedTime).GetTime().Format(Timestamp{}.layout()))
}
{
// ms is preserved despite it being all zeroes.
converted, err := Timestamp{}.Convert(int64(1_725_058_799_000))
assert.NoError(t, err)
assert.Equal(t, "2024-08-30T22:59:59.000", converted.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2024-08-30T22:59:59.000", converted.(*ext.ExtendedTime).GetTime().Format(Timestamp{}.layout()))
}
}

Expand All @@ -40,13 +40,13 @@ func TestMicroTimestamp_Converter(t *testing.T) {
// Valid conversion
converted, err := MicroTimestamp{}.Convert(int64(1_712_609_795_827_923))
assert.NoError(t, err)
assert.Equal(t, "2024-04-08T20:56:35.827923", converted.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2024-04-08T20:56:35.827923", converted.(*ext.ExtendedTime).GetTime().Format(MicroTimestamp{}.layout()))
}
{
// micros is preserved despite it being all zeroes.
converted, err := MicroTimestamp{}.Convert(int64(1_712_609_795_820_000))
assert.NoError(t, err)
assert.Equal(t, "2024-04-08T20:56:35.820000", converted.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2024-04-08T20:56:35.820000", converted.(*ext.ExtendedTime).GetTime().Format(MicroTimestamp{}.layout()))
}
}

Expand All @@ -61,12 +61,12 @@ func TestNanoTimestamp_Converter(t *testing.T) {
// Valid conversion
converted, err := NanoTimestamp{}.Convert(int64(1_712_609_795_827_001_000))
assert.NoError(t, err)
assert.Equal(t, "2024-04-08T20:56:35.827001000", converted.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2024-04-08T20:56:35.827001000", converted.(*ext.ExtendedTime).GetTime().Format(NanoTimestamp{}.layout()))
}
{
// nanos is preserved despite it being all zeroes.
converted, err := NanoTimestamp{}.Convert(int64(1_712_609_795_827_000_000))
assert.NoError(t, err)
assert.Equal(t, "2024-04-08T20:56:35.827000000", converted.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2024-04-08T20:56:35.827000000", converted.(*ext.ExtendedTime).GetTime().Format(NanoTimestamp{}.layout()))
}
}
2 changes: 1 addition & 1 deletion lib/debezium/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ func TestField_ToKindDetails(t *testing.T) {
for _, dbzType := range []SupportedDebeziumType{Date, DateKafkaConnect} {
kd, err := Field{DebeziumType: dbzType}.ToKindDetails()
assert.NoError(t, err)
assert.Equal(t, typing.NewExtendedTimeDetails(typing.ETime, ext.DateKindType, ""), kd)
assert.Equal(t, typing.NewExtendedTimeDetails(typing.ETime, ext.DateKindType, ext.PostgresDateFormat), kd)
}
}
{
Expand Down
6 changes: 3 additions & 3 deletions lib/debezium/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,14 +284,14 @@ func TestField_ParseValue(t *testing.T) {
field := Field{Type: Int64, DebeziumType: MicroTime}
value, err := field.ParseValue(int64(54720000000))
assert.NoError(t, err)
assert.Equal(t, "15:12:00.000000", value.(*ext.ExtendedTime).String(""))
assert.Equal(t, "15:12:00.000000", value.(*ext.ExtendedTime).GetTime().Format("15:04:05.000000"))
}
{
// Nano time
field := Field{Type: Int64, DebeziumType: NanoTime}
value, err := field.ParseValue(int64(54720000000000))
assert.NoError(t, err)
assert.Equal(t, "15:12:00.000000000", value.(*ext.ExtendedTime).String(""))
assert.Equal(t, "15:12:00.000000000", value.(*ext.ExtendedTime).GetTime().Format("15:04:05.000000000"))
}
}
{
Expand All @@ -302,7 +302,7 @@ func TestField_ParseValue(t *testing.T) {
field := Field{Type: Int64, DebeziumType: dbzType}
value, err := field.ParseValue(int64(1_725_058_799_000))
assert.NoError(t, err)
assert.Equal(t, "2024-08-30T22:59:59.000", value.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2024-08-30T22:59:59.000", value.(*ext.ExtendedTime).GetTime().Format(ext.RFC3339MillisecondNoTZ))
}
}
{
Expand Down
4 changes: 2 additions & 2 deletions lib/typing/mongo/bson_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func TestJSONEToMap(t *testing.T) {
extendedTime, isOk := result["test_timestamp"]
assert.True(t, isOk)
assert.Equal(t, ext.NewExtendedTime(time.Date(2023, time.March, 16, 1, 18, 37, 0, time.UTC), ext.TimestampTZKindType, ext.ISO8601), extendedTime)
assert.Equal(t, "2023-03-16T01:18:37+00:00", extendedTime.(*ext.ExtendedTime).String(""))
assert.Equal(t, "2023-03-16T01:18:37+00:00", extendedTime.(*ext.ExtendedTime).GetTime().Format(ext.ISO8601))
}
{
// Boolean
Expand Down Expand Up @@ -223,7 +223,7 @@ func TestBsonValueToGoValue(t *testing.T) {
extendedTime, isOk := result.(*ext.ExtendedTime)
assert.True(t, isOk)
assert.Equal(t, ext.NewExtendedTime(time.Date(2021, time.January, 1, 0, 0, 0, 0, time.UTC), ext.TimestampTZKindType, ext.ISO8601), extendedTime)
assert.Equal(t, "2021-01-01T00:00:00+00:00", extendedTime.String(""))
assert.Equal(t, "2021-01-01T00:00:00+00:00", extendedTime.GetTime().Format(ext.ISO8601))
}
{
// primitive.ObjectID
Expand Down
11 changes: 6 additions & 5 deletions lib/typing/values/string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,24 @@ func TestToString(t *testing.T) {
eTimeCol := columns.NewColumn("time", typing.ETime)
eTimeCol.KindDetails.ExtendedTimeDetails = &ext.NestedKind{Type: ext.TimeKindType}
{
// Using `string`
// Using [string]
val, err := ToString("2021-01-01T03:52:00Z", eTimeCol.KindDetails)
assert.NoError(t, err)
assert.Equal(t, "03:52:00", val)
}
{
// Using `*ExtendedTime`
// Using [*ExtendedTime]
format := "2006-01-02T15:04:05Z07:00"
dustyBirthday := time.Date(2019, time.December, 31, 0, 0, 0, 0, time.UTC)
extendedTime := ext.NewExtendedTime(dustyBirthday, ext.TimestampTZKindType, "2006-01-02T15:04:05Z07:00")
extendedTime := ext.NewExtendedTime(dustyBirthday, ext.TimestampTZKindType, format)

nestedKind, err := ext.NewNestedKind(ext.TimestampTZKindType, "")
nestedKind, err := ext.NewNestedKind(ext.TimestampTZKindType, format)
assert.NoError(t, err)

eTimeCol.KindDetails.ExtendedTimeDetails = &nestedKind
actualValue, err := ToString(extendedTime, eTimeCol.KindDetails)
assert.NoError(t, err)
assert.Equal(t, extendedTime.String(""), actualValue)
assert.Equal(t, extendedTime.GetTime().Format(format), actualValue)
}
}
}
Expand Down

0 comments on commit 97f05e9

Please sign in to comment.