mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
database/sql: support returning query database types
Creates a ColumnType structure that can be extended in to future. Allow drivers to implement what makes sense for the database. Fixes #16652 Change-Id: Ieb1fd64eac1460107b1d3474eba5201fa300a4ec Reviewed-on: https://go-review.googlesource.com/29961 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
2ecaaf18f9
commit
2a85578b0e
4 changed files with 259 additions and 11 deletions
|
|
@ -11,6 +11,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -405,6 +406,7 @@ func (c *fakeConn) prepareSelect(stmt *fakeStmt, parts []string) (*fakeStmt, err
|
|||
return nil, errf("invalid SELECT syntax with %d parts; want 3", len(parts))
|
||||
}
|
||||
stmt.table = parts[0]
|
||||
|
||||
stmt.colName = strings.Split(parts[1], ",")
|
||||
for n, colspec := range strings.Split(parts[2], ",") {
|
||||
if colspec == "" {
|
||||
|
|
@ -725,6 +727,7 @@ func (s *fakeStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (
|
|||
|
||||
setMRows := make([][]*row, 0, 1)
|
||||
setColumns := make([][]string, 0, 1)
|
||||
setColType := make([][]string, 0, 1)
|
||||
|
||||
for {
|
||||
db.mu.Lock()
|
||||
|
|
@ -794,10 +797,16 @@ func (s *fakeStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (
|
|||
mrows = append(mrows, mrow)
|
||||
}
|
||||
|
||||
var colType []string
|
||||
for _, column := range s.colName {
|
||||
colType = append(colType, t.coltype[t.columnIndex(column)])
|
||||
}
|
||||
|
||||
t.mu.Unlock()
|
||||
|
||||
setMRows = append(setMRows, mrows)
|
||||
setColumns = append(setColumns, s.colName)
|
||||
setColType = append(setColType, colType)
|
||||
|
||||
if s.next == nil {
|
||||
break
|
||||
|
|
@ -806,10 +815,11 @@ func (s *fakeStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (
|
|||
}
|
||||
|
||||
cursor := &rowsCursor{
|
||||
posRow: -1,
|
||||
rows: setMRows,
|
||||
cols: setColumns,
|
||||
errPos: -1,
|
||||
posRow: -1,
|
||||
rows: setMRows,
|
||||
cols: setColumns,
|
||||
colType: setColType,
|
||||
errPos: -1,
|
||||
}
|
||||
return cursor, nil
|
||||
}
|
||||
|
|
@ -844,11 +854,12 @@ func (tx *fakeTx) Rollback() error {
|
|||
}
|
||||
|
||||
type rowsCursor struct {
|
||||
cols [][]string
|
||||
posSet int
|
||||
posRow int
|
||||
rows [][]*row
|
||||
closed bool
|
||||
cols [][]string
|
||||
colType [][]string
|
||||
posSet int
|
||||
posRow int
|
||||
rows [][]*row
|
||||
closed bool
|
||||
|
||||
// errPos and err are for making Next return early with error.
|
||||
errPos int
|
||||
|
|
@ -874,6 +885,10 @@ func (rc *rowsCursor) Columns() []string {
|
|||
return rc.cols[rc.posSet]
|
||||
}
|
||||
|
||||
func (rc *rowsCursor) ColumnTypeScanType(index int) reflect.Type {
|
||||
return colTypeToReflectType(rc.colType[rc.posSet][index])
|
||||
}
|
||||
|
||||
var rowsCursorNextHook func(dest []driver.Value) error
|
||||
|
||||
func (rc *rowsCursor) Next(dest []driver.Value) error {
|
||||
|
|
@ -980,3 +995,29 @@ func converterForType(typ string) driver.ValueConverter {
|
|||
}
|
||||
panic("invalid fakedb column type of " + typ)
|
||||
}
|
||||
|
||||
func colTypeToReflectType(typ string) reflect.Type {
|
||||
switch typ {
|
||||
case "bool":
|
||||
return reflect.TypeOf(false)
|
||||
case "nullbool":
|
||||
return reflect.TypeOf(NullBool{})
|
||||
case "int32":
|
||||
return reflect.TypeOf(int32(0))
|
||||
case "string":
|
||||
return reflect.TypeOf("")
|
||||
case "nullstring":
|
||||
return reflect.TypeOf(NullString{})
|
||||
case "int64":
|
||||
return reflect.TypeOf(int64(0))
|
||||
case "nullint64":
|
||||
return reflect.TypeOf(NullInt64{})
|
||||
case "float64":
|
||||
return reflect.TypeOf(float64(0))
|
||||
case "nullfloat64":
|
||||
return reflect.TypeOf(NullFloat64{})
|
||||
case "datetime":
|
||||
return reflect.TypeOf(time.Time{})
|
||||
}
|
||||
panic("invalid fakedb column type of " + typ)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue