Skip to content

Commit c4eeaf6

Browse files
committed
ClickHouse#64 add missing support of driver.Valuer interface
1 parent 0c1ee71 commit c4eeaf6

File tree

3 files changed

+68
-4
lines changed

3 files changed

+68
-4
lines changed

clickhouse.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,14 @@ func (ch *clickhouse) CheckNamedValue(nv *driver.NamedValue) error {
173173
[]float32, []float64,
174174
[]string:
175175
nv.Value = types.NewArray(v)
176-
case Date:
177-
nv.Value = v.convert()
178-
case DateTime:
179-
nv.Value = v.convert()
180176
case net.IP:
181177
nv.Value = IP(v)
178+
case driver.Valuer:
179+
value, err := v.Value()
180+
if err != nil {
181+
return err
182+
}
183+
nv.Value = value
182184
default:
183185
switch value := reflect.ValueOf(nv.Value); value.Kind() {
184186
case reflect.Bool:

clickhouse_custom_types_test.go

+60
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package clickhouse_test
22

33
import (
44
"database/sql"
5+
"database/sql/driver"
56
"fmt"
67
"testing"
78

@@ -159,3 +160,62 @@ func Test_Custom_Types(t *testing.T) {
159160
}
160161
}
161162
}
163+
164+
type PointType struct {
165+
x int32
166+
y int32
167+
z int32
168+
}
169+
170+
func (p PointType) Value() (driver.Value, error) {
171+
return fmt.Sprintf("%v,%v,%v", p.x, p.y, p.z), nil
172+
}
173+
174+
func (p *PointType) Scan(v interface{}) error {
175+
var src string
176+
switch v := v.(type) {
177+
case string:
178+
src = v
179+
case []byte:
180+
src = string(v)
181+
default:
182+
return fmt.Errorf("unexpected type '%T'", v)
183+
}
184+
if _, err := fmt.Sscanf(src, "%d,%d,%d", &p.x, &p.y, &p.z); err != nil {
185+
return err
186+
}
187+
return nil
188+
}
189+
190+
func Test_Scan_Value(t *testing.T) {
191+
const (
192+
ddl = `
193+
CREATE TABLE clickhouse_test_scan_value (
194+
Value String
195+
) Engine = Memory
196+
`
197+
)
198+
199+
point := PointType{1, 2, 3}
200+
if connect, err := sql.Open("clickhouse", "tcp://127.0.0.1:9000?debug=true"); assert.NoError(t, err) && assert.NoError(t, connect.Ping()) {
201+
if _, err := connect.Exec("DROP TABLE IF EXISTS clickhouse_test_scan_value"); assert.NoError(t, err) {
202+
if _, err := connect.Exec(ddl); assert.NoError(t, err) {
203+
if tx, err := connect.Begin(); assert.NoError(t, err) {
204+
if stmt, err := tx.Prepare(`INSERT INTO clickhouse_test_scan_value VALUES (?)`); assert.NoError(t, err) {
205+
if _, err = stmt.Exec(point); !assert.NoError(t, err) {
206+
return
207+
}
208+
} else {
209+
return
210+
}
211+
if assert.NoError(t, tx.Commit()) {
212+
var p PointType
213+
if err := connect.QueryRow(`SELECT Value FROM clickhouse_test_scan_value`).Scan(&p); assert.NoError(t, err) {
214+
assert.Equal(t, point, p)
215+
}
216+
}
217+
}
218+
}
219+
}
220+
}
221+
}

value_converter.go

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ func (c *converter) ConvertValue(v interface{}) (driver.Value, error) {
6363
return (types.NewArray(v)).Value()
6464
case net.IP:
6565
return IP(value).Value()
66+
case driver.Valuer:
67+
return value.Value()
6668
}
6769

6870
switch v := v.(type) {

0 commit comments

Comments
 (0)