Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

latest #2

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
989f914
Bump github.com/hashicorp/go-version from 1.4.0 to 1.5.0 (#47)
dependabot[bot] May 22, 2022
ce3f69a
feat: add HasIndex in clickhouse Migrator (#51)
yuikns Jun 29, 2022
be08f1b
Migrate to clickhouse v2 driver
jinzhu Jul 1, 2022
c9ff42b
Upgrade README
jinzhu Jul 1, 2022
a586f1b
Fix go.mod
jinzhu Jul 1, 2022
214ffb5
Update tests workflow
jinzhu Jul 1, 2022
44f5337
clickhouse < 22.0's columns doesn't support precision, close #54
jinzhu Jul 4, 2022
c9f9358
Tests with go 1.18 & 1.19
jinzhu Jan 17, 2023
12aa6bb
Bump gorm.io/gorm from 1.23.7 to 1.24.3 (#75)
dependabot[bot] Jan 17, 2023
867c805
Upgrade ClickHouse driver
jinzhu Mar 8, 2023
eeabf17
Bump github.com/ClickHouse/clickhouse-go/v2 from 2.6.5 to 2.7.0 (#90)
dependabot[bot] Mar 11, 2023
a55101a
Bump actions/setup-go from 3 to 4 (#95)
dependabot[bot] Mar 23, 2023
8902aed
Bump github.com/ClickHouse/clickhouse-go/v2 from 2.7.0 to 2.8.3 (#101)
dependabot[bot] Apr 11, 2023
1359b05
Add db option to fix bug where tables with default values always trig…
maggie-lou Apr 11, 2023
e67fa58
Upgrade ClickHouse driver (#111)
xiaoxiaolai May 28, 2023
c26dd99
Bump github.com/ClickHouse/clickhouse-go/v2 from 2.10.0 to 2.14.2 (#134)
dependabot[bot] Oct 10, 2023
3f6c1cd
Implement the GetTables() interface of Migrator (#137)
zelozzz Oct 26, 2023
59dcc52
Bump github.com/ClickHouse/clickhouse-go/v2 from 2.14.2 to 2.15.0 (#138)
dependabot[bot] Nov 15, 2023
cad4814
Allow update local tables for distributed table engine (#142)
jinzhu Dec 8, 2023
50229b0
Bump github.com/ClickHouse/clickhouse-go/v2 from 2.15.0 to 2.20.0 (#156)
dependabot[bot] Mar 9, 2024
1f0c14f
Bump github.com/ClickHouse/clickhouse-go/v2 from 2.20.0 to 2.23.1 (#169)
dependabot[bot] Apr 26, 2024
edc0605
Bump gorm.io/gorm from 1.24.6 to 1.25.9 (#168)
dependabot[bot] Apr 26, 2024
02e3fe9
Add test for partial query with nullable (#128)
looi Apr 26, 2024
187d003
Fix issue (#117)
EasonXeu Apr 26, 2024
10557f4
Update README
jinzhu Apr 26, 2024
065c557
Close local table conns for distributed table engine
jinzhu Jun 3, 2024
0f1c09d
test scan into slice
jinzhu Jun 20, 2024
cd28769
test map field
jinzhu Jun 20, 2024
f363ecf
Bump github.com/ClickHouse/clickhouse-go/v2 from 2.23.2 to 2.26.0 (#182)
dependabot[bot] Jul 12, 2024
b087361
Bump github.com/ClickHouse/clickhouse-go/v2 from 2.26.0 to 2.29.0 (#195)
dependabot[bot] Sep 30, 2024
d113d4b
Bump github.com/ClickHouse/clickhouse-go/v2 from 2.29.0 to 2.30.0 (#197)
dependabot[bot] Nov 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ jobs:
clickhouse:
strategy:
matrix:
dbversion: ['yandex/clickhouse-server']
go: ['1.18', '1.17', '1.16', '1.15', '1.14', '1.13']
dbversion: ['clickhouse/clickhouse-server']
go: ['1.21', '1.22']
platform: [ubuntu-latest]
runs-on: ${{ matrix.platform }}

Expand All @@ -32,7 +32,7 @@ jobs:

steps:
- name: Set up Go 1.x
uses: actions/setup-go@v3
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go }}

Expand Down
42 changes: 40 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ type User struct {
}

func main() {
dsn := "tcp://localhost:9000?database=gorm&username=gorm&password=gorm&read_timeout=10&write_timeout=20"
dsn := "clickhouse://gorm:gorm@localhost:9942/gorm?dial_timeout=10s&read_timeout=20s"
db, err := gorm.Open(clickhouse.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}

// Auto Migrate
db.AutoMigrate(&User{})
// Set table options
Expand Down Expand Up @@ -57,20 +58,57 @@ func main() {
```go
package main

import (
std_ck "github.com/ClickHouse/clickhouse-go/v2"
"gorm.io/driver/clickhouse"
"gorm.io/gorm"
)

sqlDB, err := std_ck.OpenDB(&std_ck.Options{
Addr: []string{"127.0.0.1:9999"},
Auth: std_ck.Auth{
Database: "default",
Username: "default",
Password: "",
},
TLS: &tls.Config{
InsecureSkipVerify: true,
},
Settings: std_ck.Settings{
"max_execution_time": 60,
},
DialTimeout: 5 * time.Second,
Compression: &std_ck.Compression{
std_ck.CompressionLZ4,
},
Debug: true,
})

func main() {
db, err := gorm.Open(clickhouse.New(click.Config{
Conn: sqlDB, // initialize with existing database conn
})
}
```

```go
package main

import (
"gorm.io/driver/clickhouse"
"gorm.io/gorm"
)

// refer to https://github.com/ClickHouse/clickhouse-go
var dsn = "tcp://localhost:9000?database=gorm&username=gorm&password=gorm&read_timeout=10&write_timeout=20"
var dsn = "clickhouse://username:password@host1:9000,host2:9000/database?dial_timeout=200ms&max_execution_time=60"

func main() {
db, err := gorm.Open(clickhouse.New(click.Config{
DSN: dsn,
Conn: conn, // initialize with existing database conn
DisableDatetimePrecision: true, // disable datetime64 precision, not supported before clickhouse 20.4
DontSupportRenameColumn: true, // rename column not supported before clickhouse 20.4
DontSupportEmptyDefaultValue: false, // do not consider empty strings as valid default values
SkipInitializeWithVersion: false, // smart configure based on used version
DefaultGranularity: 3, // 1 granule = 8192 rows
DefaultCompression: "LZ4", // default compression algorithm. LZ4 is lossless
Expand Down
49 changes: 32 additions & 17 deletions clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"reflect"
"strings"

_ "github.com/ClickHouse/clickhouse-go"
"github.com/ClickHouse/clickhouse-go/v2"
"github.com/hashicorp/go-version"
"gorm.io/gorm"
"gorm.io/gorm/callbacks"
Expand All @@ -18,20 +18,24 @@ import (
)

type Config struct {
DriverName string
DSN string
Conn gorm.ConnPool
DisableDatetimePrecision bool
DontSupportRenameColumn bool
SkipInitializeWithVersion bool
DefaultGranularity int // 1 granule = 8192 rows
DefaultCompression string // default compression algorithm. LZ4 is lossless
DefaultIndexType string // index stores extremes of the expression
DefaultTableEngineOpts string
DriverName string
DSN string
Conn gorm.ConnPool
DisableDatetimePrecision bool
DontSupportRenameColumn bool
DontSupportColumnPrecision bool
DontSupportEmptyDefaultValue bool
SkipInitializeWithVersion bool
DefaultGranularity int // 1 granule = 8192 rows
DefaultCompression string // default compression algorithm. LZ4 is lossless
DefaultIndexType string // index stores extremes of the expression
DefaultTableEngineOpts string
}

type Dialector struct {
*Config
options clickhouse.Options
Version string
}

func Open(dsn string) gorm.Dialector {
Expand All @@ -46,13 +50,14 @@ func (dialector Dialector) Name() string {
return "clickhouse"
}

func (dialector Dialector) Initialize(db *gorm.DB) (err error) {
func (dialector *Dialector) Initialize(db *gorm.DB) (err error) {
// register callbacks
ctx := context.Background()
callbacks.RegisterDefaultCallbacks(db, &callbacks.Config{
DeleteClauses: []string{"DELETE", "WHERE"},
})
db.Callback().Create().Replace("gorm:create", Create)
db.Callback().Create().Replace("gorm:create", dialector.Create)
db.Callback().Update().Replace("gorm:update", dialector.Update)

// assign option fields to default values
if dialector.DriverName == "" {
Expand Down Expand Up @@ -85,18 +90,28 @@ func (dialector Dialector) Initialize(db *gorm.DB) (err error) {
}
}

if dialector.DSN != "" {
if opts, err := clickhouse.ParseDSN(dialector.DSN); err == nil {
dialector.options = *opts
}
}

if !dialector.SkipInitializeWithVersion {
var vs string
err = db.ConnPool.QueryRowContext(ctx, "SELECT version()").Scan(&vs)
err = db.ConnPool.QueryRowContext(ctx, "SELECT version()").Scan(&dialector.Version)
if err != nil {
return err
}
if dbversion, err := version.NewVersion(vs); err == nil {
if dbversion, err := version.NewVersion(dialector.Version); err == nil {
versionNoRenameColumn, _ := version.NewConstraint("< 20.4")

if versionNoRenameColumn.Check(dbversion) {
dialector.Config.DontSupportRenameColumn = true
}

versionNoPrecisionColumn, _ := version.NewConstraint("< 21.11")
if versionNoPrecisionColumn.Check(dbversion) {
dialector.DontSupportColumnPrecision = true
}
}
}

Expand Down Expand Up @@ -192,7 +207,7 @@ func (dialector Dialector) Migrator(db *gorm.DB) gorm.Migrator {
Migrator: migrator.Migrator{
Config: migrator.Config{
DB: db,
Dialector: dialector,
Dialector: &dialector,
},
},
Dialector: dialector,
Expand Down
7 changes: 2 additions & 5 deletions create.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"gorm.io/gorm/clause"
)

func Create(db *gorm.DB) {
func (dialector *Dialector) Create(db *gorm.DB) {
if db.Error == nil {
if db.Statement.Schema != nil && !db.Statement.Unscoped {
for _, c := range db.Statement.Schema.CreateClauses {
Expand All @@ -18,7 +18,7 @@ func Create(db *gorm.DB) {
db.Statement.SQL.Grow(180)
db.Statement.AddClauseIfNotExists(clause.Insert{})

if values := callbacks.ConvertToCreateValues(db.Statement); len(values.Values) > 1 {
if values := callbacks.ConvertToCreateValues(db.Statement); len(values.Values) >= 1 {
prepareValues := clause.Values{
Columns: values.Columns,
Values: [][]interface{}{values.Values[0]},
Expand All @@ -38,9 +38,6 @@ func Create(db *gorm.DB) {
}
}
return
} else {
db.Statement.AddClause(values)
db.Statement.Build("INSERT", "VALUES", "ON CONFLICT")
}
}

Expand Down
27 changes: 24 additions & 3 deletions create_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package clickhouse_test

import (
"slices"
"testing"

"gorm.io/gorm/utils/tests"
)

func TestCreate(t *testing.T) {
var user = User{ID: 1, Name: "create", FirstName: "zhang", LastName: "jinzhu", Age: 18, Active: true, Salary: 8.8888}
user := User{ID: 1, Name: "create", FirstName: "zhang", LastName: "jinzhu", Age: 18, Active: true, Salary: 8.8888, Attrs: map[string]string{
"a": "a",
"b": "b",
}}

if err := DB.Create(&user).Error; err != nil {
t.Fatalf("failed to create user, got error %v", err)
Expand All @@ -19,10 +23,27 @@ func TestCreate(t *testing.T) {
}

tests.AssertEqual(t, result, user)

type partialUser struct {
Name string
}
var partialResult partialUser
if err := DB.Raw("select * from users where id = ?", user.ID).Scan(&partialResult).Error; err != nil {
t.Fatalf("failed to query partial, got error %v", err)
}

var names []string
if err := DB.Select("name").Model(&User{}).Find(&names).Error; err != nil {
t.Fatalf("failed to query user, got error %v", err)
}

if !slices.Contains(names, user.Name) {
t.Errorf("name should be included in the result")
}
}

func TestBatchCreate(t *testing.T) {
var users = []User{
users := []User{
{ID: 11, Name: "batch_create_1", FirstName: "zhang", LastName: "jinzhu", Age: 18, Active: true, Salary: 6},
{ID: 12, Name: "batch_create_2", FirstName: "zhang", LastName: "jinzhu", Age: 18, Active: false, Salary: 6.12},
{ID: 13, Name: "batch_create_3", FirstName: "zhang", LastName: "jinzhu", Age: 18, Active: true, Salary: 6.1234},
Expand All @@ -47,7 +68,7 @@ func TestBatchCreate(t *testing.T) {
}

func TestCreateWithMap(t *testing.T) {
var user = User{ID: 122, Name: "create2", FirstName: "zhang", LastName: "jinzhu", Age: 18, Active: true, Salary: 6.6666}
user := User{ID: 122, Name: "create2", FirstName: "zhang", LastName: "jinzhu", Age: 18, Active: true, Salary: 6.6666}

if err := DB.Table("users").Create(&map[string]interface{}{
"id": user.ID, "name": user.Name, "first_name": user.FirstName, "last_name": user.LastName, "age": user.Age, "active": user.Active, "salary": user.Salary,
Expand Down
4 changes: 2 additions & 2 deletions delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func TestDelete(t *testing.T) {
var user = User{ID: 2, Name: "delete", FirstName: "zhang", LastName: "jinzhu", Age: 18, Active: true, Salary: 8.8888}
user := User{ID: 2, Name: "delete", FirstName: "zhang", LastName: "jinzhu", Age: 18, Active: true, Salary: 8.8888}

if err := DB.Create(&user).Error; err != nil {
t.Fatalf("failed to create user, got error %v", err)
Expand All @@ -25,7 +25,7 @@ func TestDelete(t *testing.T) {
t.Fatalf("failed to delete user, got error %v", err)
}

time.Sleep(200 * time.Millisecond)
time.Sleep(500 * time.Millisecond)
if err := DB.First(&result, user.ID).Error; err == nil {
t.Fatalf("should raise ErrRecordNotFound, got error %v", err)
}
Expand Down
8 changes: 4 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
version: "3"
services:
server:
image: yandex/clickhouse-server
image: yandex/clickhouse-server:latest
environment:
- CLICKHOUSE_DB=gorm
- CLICKHOUSE_USER=gorm
- CLICKHOUSE_PASSWORD=gorm
ports:
- "9941:8123"
- "9942:9000"
- "9943:9009"
- 9941:8123
- 9942:9000
- 9943:9009
31 changes: 26 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
module gorm.io/driver/clickhouse

go 1.14
go 1.21

toolchain go1.21.1

require (
github.com/ClickHouse/clickhouse-go v1.5.4
github.com/hashicorp/go-version v1.4.0
gorm.io/gorm v1.23.4
github.com/ClickHouse/clickhouse-go/v2 v2.30.0
github.com/hashicorp/go-version v1.6.0
gorm.io/gorm v1.25.10
)

replace github.com/ClickHouse/clickhouse-go => github.com/go-gorm/clickhouse-go v1.4.5
require (
github.com/ClickHouse/ch-go v0.61.5 // indirect
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/go-faster/city v1.0.1 // indirect
github.com/go-faster/errors v0.7.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/klauspost/compress v1.17.8 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/paulmach/orb v0.11.1 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/segmentio/asm v1.2.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
go.opentelemetry.io/otel v1.26.0 // indirect
go.opentelemetry.io/otel/trace v1.26.0 // indirect
golang.org/x/sys v0.26.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading