Skip to content

Commit 5671e01

Browse files
authored
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
1 parent 2b780b4 commit 5671e01

File tree

1 file changed

+69
-23
lines changed

1 file changed

+69
-23
lines changed

Diff for: sqlite3_type.go

+69-23
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// Copyright (C) 2019 Yasuhiro Matsumoto <[email protected]>.
2-
//
32
// Use of this source code is governed by an MIT-style
43
// license that can be found in the LICENSE file.
54

@@ -14,8 +13,9 @@ package sqlite3
1413
*/
1514
import "C"
1615
import (
16+
"database/sql"
1717
"reflect"
18-
"time"
18+
"strings"
1919
)
2020

2121
// ColumnTypeDatabaseTypeName implement RowsColumnTypeDatabaseTypeName.
@@ -31,32 +31,78 @@ func (rc *SQLiteRows) ColumnTypeLength(index int) (length int64, ok bool) {
3131
func (rc *SQLiteRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
3232
return 0, 0, false
3333
}
34+
*/
3435

3536
// ColumnTypeNullable implement RowsColumnTypeNullable.
3637
func (rc *SQLiteRows) ColumnTypeNullable(i int) (nullable, ok bool) {
37-
return false, false
38+
return true, true
3839
}
39-
*/
4040

4141
// ColumnTypeScanType implement RowsColumnTypeScanType.
4242
func (rc *SQLiteRows) ColumnTypeScanType(i int) reflect.Type {
43-
switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
44-
case C.SQLITE_INTEGER:
45-
switch C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))) {
46-
case "timestamp", "datetime", "date":
47-
return reflect.TypeOf(time.Time{})
48-
case "boolean":
49-
return reflect.TypeOf(false)
50-
}
51-
return reflect.TypeOf(int64(0))
52-
case C.SQLITE_FLOAT:
53-
return reflect.TypeOf(float64(0))
54-
case C.SQLITE_BLOB:
55-
return reflect.SliceOf(reflect.TypeOf(byte(0)))
56-
case C.SQLITE_NULL:
57-
return reflect.TypeOf(nil)
58-
case C.SQLITE_TEXT:
59-
return reflect.TypeOf("")
60-
}
61-
return reflect.SliceOf(reflect.TypeOf(byte(0)))
43+
//ct := C.sqlite3_column_type(rc.s.s, C.int(i)) // Always returns 5
44+
return scanType(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))))
45+
}
46+
47+
const (
48+
SQLITE_INTEGER = iota
49+
SQLITE_TEXT
50+
SQLITE_BLOB
51+
SQLITE_REAL
52+
SQLITE_NUMERIC
53+
SQLITE_TIME
54+
SQLITE_BOOL
55+
SQLITE_NULL
56+
)
57+
58+
func scanType(cdt string) reflect.Type {
59+
t := strings.ToUpper(cdt)
60+
i := databaseTypeConvSqlite(t)
61+
switch i {
62+
case SQLITE_INTEGER:
63+
return reflect.TypeOf(sql.NullInt64{})
64+
case SQLITE_TEXT:
65+
return reflect.TypeOf(sql.NullString{})
66+
case SQLITE_BLOB:
67+
return reflect.TypeOf(sql.RawBytes{})
68+
case SQLITE_REAL:
69+
return reflect.TypeOf(sql.NullFloat64{})
70+
case SQLITE_NUMERIC:
71+
return reflect.TypeOf(sql.NullFloat64{})
72+
case SQLITE_BOOL:
73+
return reflect.TypeOf(sql.NullBool{})
74+
case SQLITE_TIME:
75+
return reflect.TypeOf(sql.NullTime{})
76+
}
77+
return reflect.TypeOf(new(interface{}))
78+
}
79+
80+
func databaseTypeConvSqlite(t string) int {
81+
if strings.Contains(t, "INT") {
82+
return SQLITE_INTEGER
83+
}
84+
if t == "CLOB" || t == "TEXT" ||
85+
strings.Contains(t, "CHAR") {
86+
return SQLITE_TEXT
87+
}
88+
if t == "BLOB" {
89+
return SQLITE_BLOB
90+
}
91+
if t == "REAL" || t == "FLOAT" ||
92+
strings.Contains(t, "DOUBLE") {
93+
return SQLITE_REAL
94+
}
95+
if t == "DATE" || t == "DATETIME" ||
96+
t == "TIMESTAMP" {
97+
return SQLITE_TIME
98+
}
99+
if t == "NUMERIC" ||
100+
strings.Contains(t, "DECIMAL") {
101+
return SQLITE_NUMERIC
102+
}
103+
if t == "BOOLEAN" {
104+
return SQLITE_BOOL
105+
}
106+
107+
return SQLITE_NULL
62108
}

0 commit comments

Comments
 (0)