-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
Showing
1 changed file
with
69 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
// Copyright (C) 2019 Yasuhiro Matsumoto <[email protected]>. | ||
// | ||
// Use of this source code is governed by an MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
|
@@ -14,8 +13,9 @@ package sqlite3 | |
*/ | ||
import "C" | ||
import ( | ||
"database/sql" | ||
"reflect" | ||
"time" | ||
"strings" | ||
) | ||
|
||
// 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) { | ||
return 0, 0, false | ||
} | ||
*/ | ||
|
||
// ColumnTypeNullable implement RowsColumnTypeNullable. | ||
func (rc *SQLiteRows) ColumnTypeNullable(i int) (nullable, ok bool) { | ||
return false, false | ||
return true, true | ||
} | ||
*/ | ||
|
||
// ColumnTypeScanType implement RowsColumnTypeScanType. | ||
func (rc *SQLiteRows) ColumnTypeScanType(i int) reflect.Type { | ||
switch C.sqlite3_column_type(rc.s.s, C.int(i)) { | ||
case C.SQLITE_INTEGER: | ||
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: | ||
return reflect.TypeOf(float64(0)) | ||
case C.SQLITE_BLOB: | ||
return reflect.SliceOf(reflect.TypeOf(byte(0))) | ||
case C.SQLITE_NULL: | ||
return reflect.TypeOf(nil) | ||
case C.SQLITE_TEXT: | ||
return reflect.TypeOf("") | ||
} | ||
return reflect.SliceOf(reflect.TypeOf(byte(0))) | ||
//ct := C.sqlite3_column_type(rc.s.s, C.int(i)) // Always returns 5 | ||
return scanType(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i)))) | ||
} | ||
|
||
const ( | ||
SQLITE_INTEGER = iota | ||
SQLITE_TEXT | ||
SQLITE_BLOB | ||
SQLITE_REAL | ||
SQLITE_NUMERIC | ||
SQLITE_TIME | ||
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.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 | ||
} |