Skip to content

Commit

Permalink
Since one cannot replace the driver.DefaultParameterConverter to prop…
Browse files Browse the repository at this point in the history
…erly handle type conversions, handle at least time.Time columns properly by using the column type provided by Crate within the query’s results. driver.DefaultParameterConverter override is scheduled for GO 1.9 (see golang/go#18415)
  • Loading branch information
echarlus committed May 9, 2017
1 parent ec69b9d commit 011e6e2
Showing 1 changed file with 36 additions and 4 deletions.
40 changes: 36 additions & 4 deletions crate.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import (
"io"
"net/http"
"net/url"
"time"
)

const (
typeTime = "11"
)

// Crate conn structure
Expand Down Expand Up @@ -65,8 +70,18 @@ func (c *CrateDriver) query(stmt string, args []driver.Value) (*endpointResponse
Stmt: stmt,
}

if len(args) > 0 {
if l:=len(args); l > 0 {
query.Args = args
//Process each column that needs conversion from time.Time to int64 for Crate
for i:= 0; i<l; i++ {
if val, ok := args[i].(time.Time) ; ok {
if val.IsZero() {
query.Args[i] = 0
} else {
query.Args[i] = val.UnixNano() / 1000000
}
}
}
}

buf, err := json.Marshal(query)
Expand Down Expand Up @@ -123,8 +138,13 @@ func (c *CrateDriver) Query(stmt string, args []driver.Value) (driver.Rows, erro
columns: res.Cols,
values: res.Rows,
rowcount: res.Rowcount,
isTime: make([]bool, len(res.ColumnTypes)),
}
tcount := len(res.ColumnTypes)
for i:=0; i<tcount; i++ {
n, ok := res.ColumnTypes[i].(json.Number)
rows.isTime[i] = (ok && (n.String() == typeTime)) //Probably faster than getting the int64 value of n ...
}

return rows, nil
}

Expand Down Expand Up @@ -161,6 +181,7 @@ func (r *Result) RowsAffected() (int64, error) {
type Rows struct {
columns []string
values [][]interface{}
isTime []bool //Flags columns to convert to time.Time (type 11)
rowcount int64
pos int64 // index position on the values array
}
Expand All @@ -175,9 +196,18 @@ func (r *Rows) Next(dest []driver.Value) error {
if r.pos >= r.rowcount {
return io.EOF
}

for i := range dest {
dest[i] = r.values[r.pos][i]
if (r.isTime[i] && (r.values[r.pos][i] != nil)) { //If column is flagged as time.Time then convert the int64 value to time.Time
if val, ok := r.values[r.pos][i].(json.Number); ok {
v , _ := val.Int64()
sec := v/int64(1000)
dest[i] = time.Unix(sec, (v-sec*int64(1000))*int64(1000000))
} else {
return errors.New(fmt.Sprintf("Failed to convert column %s=%T to time\n", r.columns[i], r.values[r.pos][i]))
}
} else {
dest[i] = r.values[r.pos][i]
}
}

r.pos++
Expand Down Expand Up @@ -238,6 +268,8 @@ func (s *CrateStmt) NumInput() int {
return -1
}



// Register the driver
func init() {
sql.Register("crate", &CrateDriver{})
Expand Down

0 comments on commit 011e6e2

Please sign in to comment.