WIP: Support clickhouse #1664
4
Makefile
4
Makefile
|
@ -249,13 +249,13 @@ test-tidb\#%: go-check
|
|||
|
||||
.PNONY: test-clickhouse
|
||||
test-clickhouse: go-check
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -db=mysql -cache=$(TEST_CACHE_ENABLE) -ignore_select_update=true \
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -db=clickhouse -cache=$(TEST_CACHE_ENABLE) -ignore_select_update=true \
|
||||
-conn_str="tcp://$(TEST_CLICKHOUSE_HOST)?username=$(TEST_CLICKHOUSE_USERNAME)&password=$(TEST_CLICKHOUSE_PASSWORD)&database=$(TEST_CLICKHOUSE_DBNAME)" \
|
||||
-quote=$(TEST_QUOTE_POLICY) -coverprofile=tidb.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
|
||||
|
||||
.PHONY: test-clickhouse\#%
|
||||
test-clickhouse\#%: go-check
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -run $* -db=mysql -cache=$(TEST_CACHE_ENABLE) -ignore_select_update=true \
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -run $* -db=clickhouse -cache=$(TEST_CACHE_ENABLE) -ignore_select_update=true \
|
||||
-conn_str="tcp://$(TEST_CLICKHOUSE_HOST)?username=$(TEST_CLICKHOUSE_USERNAME)&password=$(TEST_CLICKHOUSE_PASSWORD)&database=$(TEST_CLICKHOUSE_DBNAME)" \
|
||||
-quote=$(TEST_QUOTE_POLICY) -coverprofile=tidb.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
|
||||
|
||||
|
|
133
convert.go
133
convert.go
|
@ -113,54 +113,6 @@ func asInt64(src interface{}) (int64, error) {
|
|||
return 0, fmt.Errorf("unsupported value %T as int64", src)
|
||||
}
|
||||
|
||||
func asUint64(src interface{}) (uint64, error) {
|
||||
switch v := src.(type) {
|
||||
case int:
|
||||
return uint64(v), nil
|
||||
case int16:
|
||||
return uint64(v), nil
|
||||
case int32:
|
||||
return uint64(v), nil
|
||||
case int8:
|
||||
return uint64(v), nil
|
||||
case int64:
|
||||
return uint64(v), nil
|
||||
case uint:
|
||||
return uint64(v), nil
|
||||
case uint8:
|
||||
return uint64(v), nil
|
||||
case uint16:
|
||||
return uint64(v), nil
|
||||
case uint32:
|
||||
return uint64(v), nil
|
||||
case uint64:
|
||||
return v, nil
|
||||
case []byte:
|
||||
return strconv.ParseUint(string(v), 10, 64)
|
||||
case string:
|
||||
return strconv.ParseUint(v, 10, 64)
|
||||
case *sql.NullString:
|
||||
return strconv.ParseUint(v.String, 10, 64)
|
||||
case *sql.NullInt32:
|
||||
return uint64(v.Int32), nil
|
||||
case *sql.NullInt64:
|
||||
return uint64(v.Int64), nil
|
||||
}
|
||||
|
||||
rv := reflect.ValueOf(src)
|
||||
switch rv.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return uint64(rv.Int()), nil
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
return uint64(rv.Uint()), nil
|
||||
case reflect.Float64, reflect.Float32:
|
||||
return uint64(rv.Float()), nil
|
||||
case reflect.String:
|
||||
return strconv.ParseUint(rv.String(), 10, 64)
|
||||
}
|
||||
return 0, fmt.Errorf("unsupported value %T as uint64", src)
|
||||
}
|
||||
|
||||
func asFloat64(src interface{}) (float64, error) {
|
||||
switch v := src.(type) {
|
||||
case int:
|
||||
|
@ -585,7 +537,7 @@ func convertAssign(dest, src interface{}, originalLocation *time.Location, conve
|
|||
}
|
||||
return nil
|
||||
}
|
||||
case *NullUint32:
|
||||
case *convert.NullUint32:
|
||||
switch d := dest.(type) {
|
||||
case *uint8:
|
||||
if s.Valid {
|
||||
|
@ -603,7 +555,7 @@ func convertAssign(dest, src interface{}, originalLocation *time.Location, conve
|
|||
}
|
||||
return nil
|
||||
}
|
||||
case *NullUint64:
|
||||
case *convert.NullUint64:
|
||||
switch d := dest.(type) {
|
||||
case *uint64:
|
||||
if s.Valid {
|
||||
|
@ -674,7 +626,7 @@ func convertAssignV(dv reflect.Value, src interface{}) error {
|
|||
dv.SetInt(i64)
|
||||
return nil
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
u64, err := asUint64(src)
|
||||
u64, err := convert.AsUint64(src)
|
||||
if err != nil {
|
||||
err = strconvErr(err)
|
||||
return fmt.Errorf("converting driver.Value type %T to a %s: %v", src, dv.Kind(), err)
|
||||
|
@ -872,82 +824,3 @@ func str2PK(s string, tp reflect.Type) (interface{}, error) {
|
|||
}
|
||||
return v.Interface(), nil
|
||||
}
|
||||
|
||||
var (
|
||||
_ sql.Scanner = &NullUint64{}
|
||||
)
|
||||
|
||||
// NullUint64 represents an uint64 that may be null.
|
||||
// NullUint64 implements the Scanner interface so
|
||||
// it can be used as a scan destination, similar to NullString.
|
||||
type NullUint64 struct {
|
||||
Uint64 uint64
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullUint64) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Uint64, n.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
var err error
|
||||
n.Uint64, err = asUint64(value)
|
||||
return err
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullUint64) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return n.Uint64, nil
|
||||
}
|
||||
|
||||
var (
|
||||
_ sql.Scanner = &NullUint32{}
|
||||
)
|
||||
|
||||
// NullUint32 represents an uint32 that may be null.
|
||||
// NullUint32 implements the Scanner interface so
|
||||
// it can be used as a scan destination, similar to NullString.
|
||||
type NullUint32 struct {
|
||||
Uint32 uint32
|
||||
Valid bool // Valid is true if Uint32 is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullUint32) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Uint32, n.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
i64, err := asUint64(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n.Uint32 = uint32(i64)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullUint32) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return int64(n.Uint32), nil
|
||||
}
|
||||
|
||||
var (
|
||||
_ sql.Scanner = &EmptyScanner{}
|
||||
)
|
||||
|
||||
// EmptyScanner represents an empty scanner which will ignore the scan
|
||||
type EmptyScanner struct{}
|
||||
|
||||
// Scan implements sql.Scanner
|
||||
func (EmptyScanner) Scan(value interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
|
19
convert/scanner.go
Normal file
19
convert/scanner.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2021 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package convert
|
||||
|
||||
import "database/sql"
|
||||
|
||||
var (
|
||||
_ sql.Scanner = &EmptyScanner{}
|
||||
)
|
||||
|
||||
// EmptyScanner represents an empty scanner which will ignore the scan
|
||||
type EmptyScanner struct{}
|
||||
|
||||
// Scan implements sql.Scanner
|
||||
func (EmptyScanner) Scan(value interface{}) error {
|
||||
return nil
|
||||
}
|
128
convert/uint.go
Normal file
128
convert/uint.go
Normal file
|
@ -0,0 +1,128 @@
|
|||
// Copyright 2021 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package convert
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func AsUint64(src interface{}) (uint64, error) {
|
||||
switch v := src.(type) {
|
||||
case int:
|
||||
return uint64(v), nil
|
||||
case int16:
|
||||
return uint64(v), nil
|
||||
case int32:
|
||||
return uint64(v), nil
|
||||
case int8:
|
||||
return uint64(v), nil
|
||||
case int64:
|
||||
return uint64(v), nil
|
||||
case uint:
|
||||
return uint64(v), nil
|
||||
case uint8:
|
||||
return uint64(v), nil
|
||||
case uint16:
|
||||
return uint64(v), nil
|
||||
case uint32:
|
||||
return uint64(v), nil
|
||||
case uint64:
|
||||
return v, nil
|
||||
case []byte:
|
||||
return strconv.ParseUint(string(v), 10, 64)
|
||||
case string:
|
||||
return strconv.ParseUint(v, 10, 64)
|
||||
case *sql.NullString:
|
||||
return strconv.ParseUint(v.String, 10, 64)
|
||||
case *sql.NullInt32:
|
||||
return uint64(v.Int32), nil
|
||||
case *sql.NullInt64:
|
||||
return uint64(v.Int64), nil
|
||||
}
|
||||
|
||||
rv := reflect.ValueOf(src)
|
||||
switch rv.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return uint64(rv.Int()), nil
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
return uint64(rv.Uint()), nil
|
||||
case reflect.Float64, reflect.Float32:
|
||||
return uint64(rv.Float()), nil
|
||||
case reflect.String:
|
||||
return strconv.ParseUint(rv.String(), 10, 64)
|
||||
}
|
||||
return 0, fmt.Errorf("unsupported value %T as uint64", src)
|
||||
}
|
||||
|
||||
var (
|
||||
_ sql.Scanner = &NullUint64{}
|
||||
)
|
||||
|
||||
// NullUint64 represents an uint64 that may be null.
|
||||
// NullUint64 implements the Scanner interface so
|
||||
// it can be used as a scan destination, similar to NullString.
|
||||
type NullUint64 struct {
|
||||
Uint64 uint64
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullUint64) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Uint64, n.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
var err error
|
||||
n.Uint64, err = AsUint64(value)
|
||||
return err
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullUint64) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return n.Uint64, nil
|
||||
}
|
||||
|
||||
var (
|
||||
_ sql.Scanner = &NullUint32{}
|
||||
)
|
||||
|
||||
// NullUint32 represents an uint32 that may be null.
|
||||
// NullUint32 implements the Scanner interface so
|
||||
// it can be used as a scan destination, similar to NullString.
|
||||
type NullUint32 struct {
|
||||
Uint32 uint32
|
||||
Valid bool // Valid is true if Uint32 is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullUint32) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Uint32, n.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
i64, err := AsUint64(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n.Uint32 = uint32(i64)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullUint32) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return int64(n.Uint32), nil
|
||||
}
|
|
@ -6,20 +6,77 @@ package dialects
|
|||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"math/big"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"xorm.io/xorm/convert"
|
||||
"xorm.io/xorm/core"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
type clickhouse struct {
|
||||
Base
|
||||
baseDriver
|
||||
}
|
||||
|
||||
func (p *clickhouse) Parse(driverName, dataSourceName string) (*URI, error) {
|
||||
return ParseClickHouse(dataSourceName)
|
||||
}
|
||||
|
||||
func (db *clickhouse) Init(uri *URI) error {
|
||||
return db.Base.Init(db, uri)
|
||||
}
|
||||
|
||||
func (db *clickhouse) Version(ctx context.Context, queryer core.Queryer) (*schemas.Version, error) {
|
||||
rows, err := queryer.QueryContext(ctx,
|
||||
"SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel') AS ProductLevel, SERVERPROPERTY ('edition') AS ProductEdition")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var version, level, edition string
|
||||
if !rows.Next() {
|
||||
if rows.Err() != nil {
|
||||
return nil, rows.Err()
|
||||
}
|
||||
return nil, errors.New("unknow version")
|
||||
}
|
||||
|
||||
if err := rows.Scan(&version, &level, &edition); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// MSSQL: Microsoft SQL Server 2017 (RTM-CU13) (KB4466404) - 14.0.3048.4 (X64) Nov 30 2018 12:57:58 Copyright (C) 2017 Microsoft Corporation Developer Edition (64-bit) on Linux (Ubuntu 16.04.5 LTS)
|
||||
return &schemas.Version{
|
||||
Number: version,
|
||||
Level: level,
|
||||
Edition: edition,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (db *clickhouse) ColumnTypeKind(t string) int {
|
||||
switch t {
|
||||
case "Date", "DateTime", "DateTime64":
|
||||
return schemas.TIME_TYPE
|
||||
case "String", "FixedString", "UUID", "Enum":
|
||||
return schemas.TEXT_TYPE
|
||||
case "Int8", "Int16", "Int32", "Int64", "Int128", "Int256",
|
||||
"UInt8", "UInt16", "UInt32", "UInt64", "UInt256",
|
||||
"Float32", "Float64",
|
||||
"Decimal32", "Decimal64", "Decimal128", "Decimal256":
|
||||
return schemas.NUMERIC_TYPE
|
||||
default:
|
||||
if strings.HasPrefix(t, "Array(") {
|
||||
return schemas.ARRAY_TYPE
|
||||
}
|
||||
return schemas.UNKNOW_TYPE
|
||||
}
|
||||
}
|
||||
|
||||
func (db *clickhouse) IsReserved(name string) bool {
|
||||
return false
|
||||
}
|
||||
|
@ -63,6 +120,33 @@ func (db *clickhouse) GetTables(queryer core.Queryer, ctx context.Context) ([]*s
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (db *clickhouse) GenScanResult(colType string) (interface{}, error) {
|
||||
switch colType {
|
||||
case "Date", "DateTime", "DateTime64":
|
||||
return &sql.NullString{}, nil
|
||||
case "String", "FixedString", "UUID", "Enum":
|
||||
return &sql.NullString{}, nil
|
||||
case "Int8", "Int16", "Int32":
|
||||
return &sql.NullInt32{}, nil
|
||||
case "Int64":
|
||||
return &sql.NullInt64{}, nil
|
||||
case "Int128", "Int256":
|
||||
return &big.Int{}, nil
|
||||
case "UInt8", "UInt16", "UInt32":
|
||||
return &convert.NullUint32{}, nil
|
||||
case "UInt64":
|
||||
return &convert.NullUint64{}, nil
|
||||
case "UInt256":
|
||||
return &big.Int{}, nil
|
||||
case "Float32", "Float64":
|
||||
return &sql.NullFloat64{}, nil
|
||||
case "Decimal32", "Decimal64", "Decimal128", "Decimal256":
|
||||
return &sql.NullString{}, nil
|
||||
default:
|
||||
return &sql.RawBytes{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ParseClickHouse parsed clickhouse connection string
|
||||
// tcp://host1:9000?username=user&password=qwerty&database=clicks&read_timeout=10&write_timeout=20&alt_hosts=host2:9000,host3:9000
|
||||
func ParseClickHouse(connStr string) (*URI, error) {
|
||||
|
|
|
@ -221,7 +221,7 @@ func regDrvsNDialects() bool {
|
|||
"sqlite": {"sqlite3", func() Driver { return &sqlite3Driver{} }, func() Dialect { return &sqlite3{} }},
|
||||
"oci8": {"oracle", func() Driver { return &oci8Driver{} }, func() Dialect { return &oracle{} }},
|
||||
"godror": {"oracle", func() Driver { return &godrorDriver{} }, func() Dialect { return &oracle{} }},
|
||||
"clickhouse": {"clickhouse", func() Driver { return &driverProxy{ParseClickHouse} }, func() Dialect { return &clickhouse{} }},
|
||||
"clickhouse": {"clickhouse", func() Driver { return &clickhouse{} }, func() Dialect { return &clickhouse{} }},
|
||||
}
|
||||
|
||||
for driverName, v := range providedDrvsNDialects {
|
||||
|
|
|
@ -83,11 +83,3 @@ type baseDriver struct{}
|
|||
func (b *baseDriver) Scan(ctx *ScanContext, rows *core.Rows, types []*sql.ColumnType, v ...interface{}) error {
|
||||
return rows.Scan(v...)
|
||||
}
|
||||
|
||||
type driverProxy struct {
|
||||
parser func(connStr string) (*URI, error)
|
||||
}
|
||||
|
||||
func (p *driverProxy) Parse(driverName, dataSourceName string) (*URI, error) {
|
||||
return p.parser(dataSourceName)
|
||||
}
|
||||
|
|
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module xorm.io/xorm
|
|||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/ClickHouse/clickhouse-go v1.4.5
|
||||
github.com/denisenkom/go-mssqldb v0.10.0
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/goccy/go-json v0.7.4
|
||||
|
|
39
go.sum
39
go.sum
|
@ -1,18 +1,21 @@
|
|||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||
github.com/ClickHouse/clickhouse-go v1.4.5 h1:FfhyEnv6/BaWldyjgT2k4gDDmeNwJ9C4NbY/MXxJlXk=
|
||||
github.com/ClickHouse/clickhouse-go v1.4.5/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D0yGjAk=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8=
|
||||
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
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/goccy/go-json v0.7.4 h1:B44qRUFwz/vxPKPISQ1KhvzRi9kZ28RAf6YtjriBZ5k=
|
||||
|
@ -28,17 +31,17 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
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/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/lib/pq v1.7.0 h1:h93mCPfUSkaul3Ka/VG8uZdmW1uMHDGxzu0NWHuJmHY=
|
||||
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU=
|
||||
github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
|
@ -51,17 +54,16 @@ github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
|||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
|
@ -118,24 +120,17 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie
|
|||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
|
||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.31.5-0.20210308123301-7a3e9dab9009 h1:u0oCo5b9wyLr++HF3AN9JicGhkUxJhMz51+8TIZH9N0=
|
||||
modernc.org/cc/v3 v3.31.5-0.20210308123301-7a3e9dab9009/go.mod h1:0R6jl1aZlIl2avnYfbfHBS1QB6/f+16mihBObaBC878=
|
||||
modernc.org/cc/v3 v3.33.6 h1:r63dgSzVzRxUpAJFPQWHy1QeZeY1ydNENUDaBx1GqYc=
|
||||
modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/ccgo/v3 v3.9.0 h1:JbcEIqjw4Agf+0g3Tc85YvfYqkkFOv6xBwS4zkfqSoA=
|
||||
modernc.org/ccgo/v3 v3.9.0/go.mod h1:nQbgkn8mwzPdp4mm6BT6+p85ugQ7FrGgIcYaE7nSrpY=
|
||||
modernc.org/ccgo/v3 v3.9.5 h1:dEuUSf8WN51rDkprFuAqjfchKEzN0WttP/Py3enBwjk=
|
||||
modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/libc v1.8.0 h1:Pp4uv9g0csgBMpGPABKtkieF6O5MGhfGo6ZiOdlYfR8=
|
||||
modernc.org/libc v1.8.0/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/libc v1.9.11 h1:QUxZMs48Ahg2F7SN41aERvMfGLY2HU/ADnB9DC4Yts8=
|
||||
modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q=
|
||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.2.2 h1:+yFk8hBprV+4c0U9GjFtL+dV3N8hOJ8JCituQcMShFY=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.4.0 h1:GCjoRaBew8ECCKINQA2nYjzvufFW9YiEuuB+rQ9bn2E=
|
||||
modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
|
@ -143,23 +138,15 @@ modernc.org/memory v1.0.4 h1:utMBrFcpnQDdNsmM6asmyH/FM9TqLPS7XF7otpJmrwM=
|
|||
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84 h1:rgEUzE849tFlHSoeCrKyS9cZAljC+DY7MdMHKq6R6sY=
|
||||
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84/go.mod h1:PGzq6qlhyYjL6uVbSgS6WoF7ZopTW/sI7+7p+mb4ZVU=
|
||||
modernc.org/sqlite v1.11.2 h1:ShWQpeD3ag/bmx6TqidBlIWonWmQaSQKls3aenCbt+w=
|
||||
modernc.org/sqlite v1.11.2/go.mod h1:+mhs/P1ONd+6G7hcAs6irwDi/bjTQ7nLW6LHRBsEa3A=
|
||||
modernc.org/strutil v1.1.0 h1:+1/yCzZxY2pZwwrsbH+4T7BQMoLQ9QiBshRC9eicYsc=
|
||||
modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
|
||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||
modernc.org/tcl v1.5.0 h1:euZSUNfE0Fd4W8VqXI1Ly1v7fqDJoBuAV88Ea+SnaSs=
|
||||
modernc.org/tcl v1.5.0/go.mod h1:gb57hj4pO8fRrK54zveIfFXBaMHK3SKJNWcmRw1cRzc=
|
||||
modernc.org/tcl v1.5.5 h1:N03RwthgTR/l/eQvz3UjfYnvVVj1G2sZqzFGfoD4HE4=
|
||||
modernc.org/tcl v1.5.5/go.mod h1:ADkaTUuwukkrlhqwERyq0SM8OvyXo7+TjFz7yAF56EI=
|
||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
modernc.org/z v1.0.1 h1:WyIDpEpAIx4Hel6q/Pcgj/VhaQV5XPJ2I6ryIYbjnpc=
|
||||
modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
xorm.io/builder v0.3.8 h1:P/wPgRqa9kX5uE0aA1/ukJ23u9KH0aSRpHLwDKXigSE=
|
||||
xorm.io/builder v0.3.8/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/builder v0.3.9 h1:Sd65/LdWyO7LR8+Cbd+e7mm3sK/7U9k0jS3999IDHMc=
|
||||
xorm.io/builder v0.3.9/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
|
|
|
@ -14,13 +14,15 @@ import (
|
|||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/schemas"
|
||||
|
||||
_ "github.com/ClickHouse/clickhouse-go"
|
||||
_ "github.com/denisenkom/go-mssqldb"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
_ "github.com/ziutek/mymysql/godrv"
|
||||
_ "modernc.org/sqlite"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPing(t *testing.T) {
|
||||
|
|
8
scan.go
8
scan.go
|
@ -35,9 +35,9 @@ func genScanResultsByBeanNullable(bean interface{}) (interface{}, bool, error) {
|
|||
case *int64:
|
||||
return &sql.NullInt64{}, true, nil
|
||||
case *uint, *uint8, *uint16, *uint32:
|
||||
return &NullUint32{}, true, nil
|
||||
return &convert.NullUint32{}, true, nil
|
||||
case *uint64:
|
||||
return &NullUint64{}, true, nil
|
||||
return &convert.NullUint64{}, true, nil
|
||||
case *float32, *float64:
|
||||
return &sql.NullFloat64{}, true, nil
|
||||
case *bool:
|
||||
|
@ -63,9 +63,9 @@ func genScanResultsByBeanNullable(bean interface{}) (interface{}, bool, error) {
|
|||
case reflect.Int32, reflect.Int, reflect.Int16, reflect.Int8:
|
||||
return &sql.NullInt32{}, true, nil
|
||||
case reflect.Uint64:
|
||||
return &NullUint64{}, true, nil
|
||||
return &convert.NullUint64{}, true, nil
|
||||
case reflect.Uint32, reflect.Uint, reflect.Uint16, reflect.Uint8:
|
||||
return &NullUint32{}, true, nil
|
||||
return &convert.NullUint32{}, true, nil
|
||||
default:
|
||||
return nil, false, fmt.Errorf("unsupported type: %#v", bean)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user