Update SQLite3_ The columntypescantype method of type (#909)

* sqlite3_type update

The main reason for this change is that the original reflected values are nil. I found that there was no good mapping when dealing with the code here

* Update sqlite3_type.go

Update 'ColumnTypeScanType' method,
Different types of mapping values

* Restore copyright

* Update go.mod

* Update go.mod
This commit is contained in:
Auler 2021-10-25 23:19:41 +08:00 committed by GitHub
parent 2b780b4a7f
commit 5671e01493
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 69 additions and 23 deletions

View File

@ -1,5 +1,4 @@
// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
//
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
@ -14,8 +13,9 @@ package sqlite3
*/ */
import "C" import "C"
import ( import (
"database/sql"
"reflect" "reflect"
"time" "strings"
) )
// ColumnTypeDatabaseTypeName implement RowsColumnTypeDatabaseTypeName. // ColumnTypeDatabaseTypeName implement RowsColumnTypeDatabaseTypeName.
@ -31,32 +31,78 @@ func (rc *SQLiteRows) ColumnTypeLength(index int) (length int64, ok bool) {
func (rc *SQLiteRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) { func (rc *SQLiteRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
return 0, 0, false return 0, 0, false
} }
*/
// ColumnTypeNullable implement RowsColumnTypeNullable. // ColumnTypeNullable implement RowsColumnTypeNullable.
func (rc *SQLiteRows) ColumnTypeNullable(i int) (nullable, ok bool) { func (rc *SQLiteRows) ColumnTypeNullable(i int) (nullable, ok bool) {
return false, false return true, true
} }
*/
// ColumnTypeScanType implement RowsColumnTypeScanType. // ColumnTypeScanType implement RowsColumnTypeScanType.
func (rc *SQLiteRows) ColumnTypeScanType(i int) reflect.Type { func (rc *SQLiteRows) ColumnTypeScanType(i int) reflect.Type {
switch C.sqlite3_column_type(rc.s.s, C.int(i)) { //ct := C.sqlite3_column_type(rc.s.s, C.int(i)) // Always returns 5
case C.SQLITE_INTEGER: return scanType(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))))
switch C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))) {
case "timestamp", "datetime", "date":
return reflect.TypeOf(time.Time{})
case "boolean":
return reflect.TypeOf(false)
} }
return reflect.TypeOf(int64(0))
case C.SQLITE_FLOAT: const (
return reflect.TypeOf(float64(0)) SQLITE_INTEGER = iota
case C.SQLITE_BLOB: SQLITE_TEXT
return reflect.SliceOf(reflect.TypeOf(byte(0))) SQLITE_BLOB
case C.SQLITE_NULL: SQLITE_REAL
return reflect.TypeOf(nil) SQLITE_NUMERIC
case C.SQLITE_TEXT: SQLITE_TIME
return reflect.TypeOf("") SQLITE_BOOL
SQLITE_NULL
)
func scanType(cdt string) reflect.Type {
t := strings.ToUpper(cdt)
i := databaseTypeConvSqlite(t)
switch i {
case SQLITE_INTEGER:
return reflect.TypeOf(sql.NullInt64{})
case SQLITE_TEXT:
return reflect.TypeOf(sql.NullString{})
case SQLITE_BLOB:
return reflect.TypeOf(sql.RawBytes{})
case SQLITE_REAL:
return reflect.TypeOf(sql.NullFloat64{})
case SQLITE_NUMERIC:
return reflect.TypeOf(sql.NullFloat64{})
case SQLITE_BOOL:
return reflect.TypeOf(sql.NullBool{})
case SQLITE_TIME:
return reflect.TypeOf(sql.NullTime{})
} }
return reflect.SliceOf(reflect.TypeOf(byte(0))) return reflect.TypeOf(new(interface{}))
}
func databaseTypeConvSqlite(t string) int {
if strings.Contains(t, "INT") {
return SQLITE_INTEGER
}
if t == "CLOB" || t == "TEXT" ||
strings.Contains(t, "CHAR") {
return SQLITE_TEXT
}
if t == "BLOB" {
return SQLITE_BLOB
}
if t == "REAL" || t == "FLOAT" ||
strings.Contains(t, "DOUBLE") {
return SQLITE_REAL
}
if t == "DATE" || t == "DATETIME" ||
t == "TIMESTAMP" {
return SQLITE_TIME
}
if t == "NUMERIC" ||
strings.Contains(t, "DECIMAL") {
return SQLITE_NUMERIC
}
if t == "BOOLEAN" {
return SQLITE_BOOL
}
return SQLITE_NULL
} }