Skip to content

Commit

Permalink
#64 add missing support of driver.Valuer interface
Browse files Browse the repository at this point in the history
  • Loading branch information
kshvakov committed Aug 30, 2017
1 parent 0c1ee71 commit c4eeaf6
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 4 deletions.
10 changes: 6 additions & 4 deletions clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,14 @@ func (ch *clickhouse) CheckNamedValue(nv *driver.NamedValue) error {
[]float32, []float64,
[]string:
nv.Value = types.NewArray(v)
case Date:
nv.Value = v.convert()
case DateTime:
nv.Value = v.convert()
case net.IP:
nv.Value = IP(v)
case driver.Valuer:
value, err := v.Value()
if err != nil {
return err
}
nv.Value = value
default:
switch value := reflect.ValueOf(nv.Value); value.Kind() {
case reflect.Bool:
Expand Down
60 changes: 60 additions & 0 deletions clickhouse_custom_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package clickhouse_test

import (
"database/sql"
"database/sql/driver"
"fmt"
"testing"

Expand Down Expand Up @@ -159,3 +160,62 @@ func Test_Custom_Types(t *testing.T) {
}
}
}

type PointType struct {
x int32
y int32
z int32
}

func (p PointType) Value() (driver.Value, error) {
return fmt.Sprintf("%v,%v,%v", p.x, p.y, p.z), nil
}

func (p *PointType) Scan(v interface{}) error {
var src string
switch v := v.(type) {
case string:
src = v
case []byte:
src = string(v)
default:
return fmt.Errorf("unexpected type '%T'", v)
}
if _, err := fmt.Sscanf(src, "%d,%d,%d", &p.x, &p.y, &p.z); err != nil {
return err
}
return nil
}

func Test_Scan_Value(t *testing.T) {
const (
ddl = `
CREATE TABLE clickhouse_test_scan_value (
Value String
) Engine = Memory
`
)

point := PointType{1, 2, 3}
if connect, err := sql.Open("clickhouse", "tcp://127.0.0.1:9000?debug=true"); assert.NoError(t, err) && assert.NoError(t, connect.Ping()) {
if _, err := connect.Exec("DROP TABLE IF EXISTS clickhouse_test_scan_value"); assert.NoError(t, err) {
if _, err := connect.Exec(ddl); assert.NoError(t, err) {
if tx, err := connect.Begin(); assert.NoError(t, err) {
if stmt, err := tx.Prepare(`INSERT INTO clickhouse_test_scan_value VALUES (?)`); assert.NoError(t, err) {
if _, err = stmt.Exec(point); !assert.NoError(t, err) {
return
}
} else {
return
}
if assert.NoError(t, tx.Commit()) {
var p PointType
if err := connect.QueryRow(`SELECT Value FROM clickhouse_test_scan_value`).Scan(&p); assert.NoError(t, err) {
assert.Equal(t, point, p)
}
}
}
}
}
}
}
2 changes: 2 additions & 0 deletions value_converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ func (c *converter) ConvertValue(v interface{}) (driver.Value, error) {
return (types.NewArray(v)).Value()
case net.IP:
return IP(value).Value()
case driver.Valuer:
return value.Value()
}

switch v := v.(type) {
Expand Down

0 comments on commit c4eeaf6

Please sign in to comment.