diff --git a/lib/debezium/converters/date.go b/lib/debezium/converters/date.go index 07023d85d..1d38255d3 100644 --- a/lib/debezium/converters/date.go +++ b/lib/debezium/converters/date.go @@ -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 } diff --git a/lib/debezium/converters/date_test.go b/lib/debezium/converters/date_test.go index 870124d24..639cfd687 100644 --- a/lib/debezium/converters/date_test.go +++ b/lib/debezium/converters/date_test.go @@ -20,7 +20,7 @@ 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)) @@ -28,6 +28,6 @@ func TestDate_Convert(t *testing.T) { 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())) } } diff --git a/lib/debezium/converters/time_test.go b/lib/debezium/converters/time_test.go index f74d22429..c42916e46 100644 --- a/lib/debezium/converters/time_test.go +++ b/lib/debezium/converters/time_test.go @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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) @@ -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 @@ -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 @@ -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) @@ -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())) } } } @@ -130,7 +130,7 @@ 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)) @@ -138,7 +138,7 @@ func TestTime_Convert(t *testing.T) { 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())) } } @@ -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())) } } @@ -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())) } } @@ -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())) } } diff --git a/lib/debezium/converters/timestamp_test.go b/lib/debezium/converters/timestamp_test.go index cf191929d..2745e04bf 100644 --- a/lib/debezium/converters/timestamp_test.go +++ b/lib/debezium/converters/timestamp_test.go @@ -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())) } } @@ -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())) } } @@ -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())) } } diff --git a/lib/debezium/schema_test.go b/lib/debezium/schema_test.go index f4ae7f3ac..bcdabb16b 100644 --- a/lib/debezium/schema_test.go +++ b/lib/debezium/schema_test.go @@ -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) } } { diff --git a/lib/debezium/types_test.go b/lib/debezium/types_test.go index 6037f922c..f6ed3281a 100644 --- a/lib/debezium/types_test.go +++ b/lib/debezium/types_test.go @@ -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")) } } { @@ -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)) } } { diff --git a/lib/typing/mongo/bson_test.go b/lib/typing/mongo/bson_test.go index 500ce2cc4..5073b5aac 100644 --- a/lib/typing/mongo/bson_test.go +++ b/lib/typing/mongo/bson_test.go @@ -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 @@ -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 diff --git a/lib/typing/values/string_test.go b/lib/typing/values/string_test.go index f113e9348..5cc75878b 100644 --- a/lib/typing/values/string_test.go +++ b/lib/typing/values/string_test.go @@ -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) } } }