Skip to content

Commit

Permalink
Merge pull request #71 from fschoell/feature/support_clickhouse_data
Browse files Browse the repository at this point in the history
added support for Clickhouse Date type
  • Loading branch information
maoueh authored Dec 2, 2024
2 parents 803abd5 + c58d14c commit a1361dc
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

* Added support for the Clickhouse `Date` type.

## v4.3.0

* Added a check for non-existent columns in Clickhouse
Expand Down
8 changes: 8 additions & 0 deletions db/dialect_clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,14 @@ func convertToType(value string, valueType reflect.Type) (any, error) {
var err error
if strings.Contains(value, "T") && strings.HasSuffix(value, "Z") {
v, err = time.Parse("2006-01-02T15:04:05Z", value)
} else if dateRegex.MatchString(value) {
// This is a Clickhouse Date field. The Clickhouse Go client doesn't convert unix timestamp into Date,
// so we just validate the format here and return a string.
_, err = time.Parse("2006-01-02", value)
if err != nil {
return "", fmt.Errorf("could not convert %s to date: %w", value, err)
}
return value, nil
} else {
v, err = time.Parse("2006-01-02 15:04:05", value)
}
Expand Down
59 changes: 59 additions & 0 deletions db/dialect_clickhouse_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package db

import (
"errors"
"github.com/stretchr/testify/assert"
"reflect"
"testing"
"time"
)

func Test_convertToType(t *testing.T) {

tests := []struct {
name string
value string
expect any
expectErr error
valueType reflect.Type
}{
{
name: "Date",
value: "2021-01-01",
expect: "2021-01-01",
expectErr: nil,
valueType: reflect.TypeOf(time.Time{}),
}, {
name: "Invalid Date",
value: "2021-99-01",
expect: nil,
expectErr: errors.New(`could not convert 2021-99-01 to date: parsing time "2021-99-01": month out of range`),
valueType: reflect.TypeOf(time.Time{}),
},
{
name: "ISO 8601 datetime",
value: "2021-01-01T00:00:00Z",
expect: int64(1609459200),
expectErr: nil,
valueType: reflect.TypeOf(time.Time{}),
},
{
name: "common datetime",
value: "2021-01-01 00:00:00",
expect: int64(1609459200),
expectErr: nil,
valueType: reflect.TypeOf(time.Time{}),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
res, err := convertToType(test.value, test.valueType)
if test.expectErr != nil {
assert.EqualError(t, err, test.expectErr.Error())
} else {
assert.NoError(t, err)
assert.Equal(t, test.expect, res)
}
})
}
}
1 change: 1 addition & 0 deletions db/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func (o *Operation) mergeData(newData map[string]string) error {
}

var integerRegex = regexp.MustCompile(`^\d+$`)
var dateRegex = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}$`)
var reflectTypeTime = reflect.TypeOf(time.Time{})

func EscapeIdentifier(valueToEscape string) string {
Expand Down

0 comments on commit a1361dc

Please sign in to comment.