From 5034f231a9d7bfc4d95bb13889479a3b9a0f96eb Mon Sep 17 00:00:00 2001 From: daguang Date: Mon, 4 Apr 2022 12:46:11 +0800 Subject: [PATCH] improve clickhouse driver --- contrib/drivers/clickhouse/clickhouse.go | 15 ++++++++------- contrib/drivers/clickhouse/go.sum | 8 ++++++-- database/gdb/gdb_core_ctx.go | 23 +++++++++++++++++++++++ database/gdb/gdb_core_underlying.go | 3 +-- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/contrib/drivers/clickhouse/clickhouse.go b/contrib/drivers/clickhouse/clickhouse.go index f23fedfcf..3412cd993 100644 --- a/contrib/drivers/clickhouse/clickhouse.go +++ b/contrib/drivers/clickhouse/clickhouse.go @@ -93,7 +93,7 @@ func (d *Driver) Tables(ctx context.Context, schema ...string) (tables []string, return nil, err } query := fmt.Sprintf("select name from `system`.tables where database = '%s'", d.GetConfig().Name) - result, err = d.DoGetAll(ctx, link, query) + result, err = d.DoSelect(ctx, link, query) if err != nil { return } @@ -126,7 +126,7 @@ func (d *Driver) TableFields(ctx context.Context, table string, schema ...string return nil } getColumnsSql := fmt.Sprintf("select name,position,default_expression,comment from `system`.columns c where database = '%s' and `table` = '%s'", d.GetConfig().Name, table) - result, err = d.DoGetAll(ctx, link, getColumnsSql) + result, err = d.DoSelect(ctx, link, getColumnsSql) if err != nil { return nil } @@ -204,18 +204,18 @@ func (d *Driver) ping(conn *sql.DB) error { } // DoFilter handles the sql before posts it to database. -func (d *Driver) DoFilter(ctx context.Context, link gdb.Link, sql string, args []interface{}) (newSql string, newArgs []interface{}, err error) { +func (d *Driver) DoFilter(ctx context.Context, link gdb.Link, originSql string, args []interface{}) (newSql string, newArgs []interface{}, err error) { // replace MySQL to Clickhouse SQL grammar // MySQL eg: UPDATE visits SET xxx // Clickhouse eg: ALTER TABLE visits UPDATE xxx // MySQL eg: DELETE FROM VISIT // Clickhouse eg: ALTER TABLE VISIT DELETE WHERE filter_expr - result, err := gregex.MatchString("(?i)^UPDATE|DELETE", sql) + result, err := gregex.MatchString("(?i)^UPDATE|DELETE", originSql) if err != nil { return "", nil, err } if len(result) != 0 { - sqlSlice := strings.Split(sql, " ") + sqlSlice := strings.Split(originSql, " ") if len(sqlSlice) < 3 { return "", nil, ErrSQLNull } @@ -229,12 +229,13 @@ func (d *Driver) DoFilter(ctx context.Context, link gdb.Link, sql string, args [ return strings.Join(sqlSlice, " "), args, nil } } - return sql, args, nil + return originSql, args, nil } // DoCommit commits current sql and arguments to underlying sql driver. func (d *Driver) DoCommit(ctx context.Context, in gdb.DoCommitInput) (out gdb.DoCommitOutput, err error) { - return d.Core.DoCommit(context.WithValue(ctx, "isIgnoreResult", true), in) + ctx = d.InjectIgnoreResult(ctx) + return d.Core.DoCommit(ctx, in) } func (d *Driver) DoInsert(ctx context.Context, link gdb.Link, table string, list gdb.List, option gdb.DoInsertOption) (result sql.Result, err error) { diff --git a/contrib/drivers/clickhouse/go.sum b/contrib/drivers/clickhouse/go.sum index e59c58abc..db27d0498 100644 --- a/contrib/drivers/clickhouse/go.sum +++ b/contrib/drivers/clickhouse/go.sum @@ -27,6 +27,8 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= +github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -43,13 +45,15 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0= github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/longbridgeapp/sqlparser v0.3.1 h1:iWOZWGIFgQrJRgobLXUNJdvqGRpbVXkyKUKUA5CNJBE= +github.com/longbridgeapp/sqlparser v0.3.1/go.mod h1:GIHaUq8zvYyHLCLMJJykx1CdM6LHtkUih/QaJXySSx4= github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= diff --git a/database/gdb/gdb_core_ctx.go b/database/gdb/gdb_core_ctx.go index d41db8133..5b22137d6 100644 --- a/database/gdb/gdb_core_ctx.go +++ b/database/gdb/gdb_core_ctx.go @@ -26,6 +26,13 @@ type internalCtxData struct { const ( internalCtxDataKeyInCtx gctx.StrKey = "InternalCtxData" + + // IgnoreResultInCtx + // This option is only available in ClickHouse. + // Because ClickHouse does not support fetching insert/update results and returns errors when executed + // So need to ignore the results to avoid triggering errors + // Rather than ignoring errors after they are triggered + IgnoreResultInCtx gctx.StrKey = "IgnoreResult" ) func (c *Core) injectInternalCtxData(ctx context.Context) context.Context { @@ -38,6 +45,22 @@ func (c *Core) injectInternalCtxData(ctx context.Context) context.Context { }) } +func (c *Core) InjectIgnoreResult(ctx context.Context) context.Context { + if ctx.Value(IgnoreResultInCtx) != nil { + return ctx + } + return context.WithValue(ctx, IgnoreResultInCtx, &internalCtxData{ + DB: c.db, + }) +} + +func (c *Core) GetIgnoreResultFromCtx(ctx context.Context) *internalCtxData { + if v := ctx.Value(internalCtxDataKeyInCtx); v != nil { + return v.(*internalCtxData) + } + return nil +} + func (c *Core) getInternalCtxDataFromCtx(ctx context.Context) *internalCtxData { if v := ctx.Value(internalCtxDataKeyInCtx); v != nil { return v.(*internalCtxData) diff --git a/database/gdb/gdb_core_underlying.go b/database/gdb/gdb_core_underlying.go index 458cfea90..1c7e572d2 100644 --- a/database/gdb/gdb_core_underlying.go +++ b/database/gdb/gdb_core_underlying.go @@ -20,7 +20,6 @@ import ( "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/internal/intlog" "github.com/gogf/gf/v2/os/gtime" - "github.com/gogf/gf/v2/util/gconv" "github.com/gogf/gf/v2/util/guid" ) @@ -262,7 +261,7 @@ func (c *Core) DoCommit(ctx context.Context, in DoCommitInput) (out DoCommitOutp } // Result handling. switch { - case sqlResult != nil && !gconv.Bool(ctx.Value("isIgnoreResult")): + case sqlResult != nil && c.GetIgnoreResultFromCtx(ctx) == nil: rowsAffected, err = sqlResult.RowsAffected() out.Result = sqlResult