Batch column scans. (#52)

This commit is contained in:
Nuno Cruces
2024-01-16 15:18:14 +00:00
committed by GitHub
parent 1b2c267b2b
commit c822fa95c7
10 changed files with 111 additions and 33 deletions

View File

@@ -50,6 +50,7 @@ import (
"net/url"
"strings"
"time"
"unsafe"
"github.com/ncruces/go-sqlite3"
"github.com/ncruces/go-sqlite3/internal/util"
@@ -532,46 +533,34 @@ func (r *rows) Next(dest []driver.Value) error {
return io.EOF
}
data := unsafe.Slice((*any)(unsafe.SliceData(dest)), len(dest))
err := r.Stmt.Columns(data)
for i := range dest {
t := r.Stmt.ColumnType(i)
if tm, ok := r.decodeTime(i, t); ok {
dest[i] = tm
continue
}
switch t {
case sqlite3.INTEGER:
dest[i] = r.Stmt.ColumnInt64(i)
case sqlite3.FLOAT:
dest[i] = r.Stmt.ColumnFloat(i)
case sqlite3.BLOB:
dest[i] = r.Stmt.ColumnRawBlob(i)
case sqlite3.TEXT:
dest[i] = stringOrTime(r.Stmt.ColumnText(i))
case sqlite3.NULL:
dest[i] = nil
default:
panic(util.AssertErr())
if t, ok := r.decodeTime(i, dest[i]); ok {
dest[i] = t
} else if s, ok := dest[i].(string); ok {
dest[i] = stringOrTime(s)
}
}
return r.Stmt.Err()
return err
}
func (r *rows) decodeTime(i int, typ sqlite3.Datatype) (_ time.Time, _ bool) {
func (r *rows) decodeTime(i int, v any) (_ time.Time, _ bool) {
if r.tmRead == sqlite3.TimeFormatDefault {
return
}
switch typ {
case sqlite3.INTEGER, sqlite3.FLOAT, sqlite3.TEXT:
// maybe
default:
return
}
switch r.declType(i) {
case "DATE", "TIME", "DATETIME", "TIMESTAMP":
// maybe
default:
return
}
return r.Stmt.ColumnTime(i, r.tmRead), r.Stmt.Err() == nil
switch v.(type) {
case int64, float64, string:
// maybe
default:
return
}
t, err := r.tmRead.Decode(v)
return t, err == nil
}