1
- // Copyright (C) 2019 Yasuhiro Matsumoto <[email protected] >.
2
- //
3
- // Use of this source code is governed by an MIT-style
4
- // license that can be found in the LICENSE file.
5
-
6
1
package sqlite3
7
2
8
3
/*
@@ -14,8 +9,9 @@ package sqlite3
14
9
*/
15
10
import "C"
16
11
import (
12
+ "database/sql"
17
13
"reflect"
18
- "time "
14
+ "strings "
19
15
)
20
16
21
17
// ColumnTypeDatabaseTypeName implement RowsColumnTypeDatabaseTypeName.
@@ -31,26 +27,78 @@ func (rc *SQLiteRows) ColumnTypeLength(index int) (length int64, ok bool) {
31
27
func (rc *SQLiteRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
32
28
return 0, 0, false
33
29
}
30
+ */
34
31
35
32
// ColumnTypeNullable implement RowsColumnTypeNullable.
36
33
func (rc * SQLiteRows ) ColumnTypeNullable (i int ) (nullable , ok bool ) {
37
- return false, false
34
+ return true , true
38
35
}
39
- */
36
+
40
37
// ColumnTypeScanType implement RowsColumnTypeScanType.
41
38
func (rc * SQLiteRows ) ColumnTypeScanType (i int ) reflect.Type {
42
- switch C .GoString (C .sqlite3_column_decltype (rc .s .s , C .int (i ))) {
43
- case "int" , "integer" , "tinyint" , "smallint" , "mediumint" , "bigint" :
44
- return reflect .TypeOf (int64 (0 ))
45
- case "timestamp" , "datetime" , "date" :
46
- return reflect .TypeOf (time.Time {})
47
- case "boolean" :
48
- return reflect .TypeOf (false )
49
- case "double" , "float" :
50
- return reflect .TypeOf (float64 (0 ))
51
- case "varchar" , "character" , "nchar" :
52
- return reflect .TypeOf ("" )
53
- }
54
- return reflect .SliceOf (reflect .TypeOf (byte (0 )))
39
+ //ct := C.sqlite3_column_type(rc.s.s, C.int(i)) // Always returns 5
40
+ return scanType (C .GoString (C .sqlite3_column_decltype (rc .s .s , C .int (i ))))
41
+ }
42
+
43
+ const (
44
+ SQLITE_INTEGER = iota
45
+ SQLITE_TEXT
46
+ SQLITE_BLOB
47
+ SQLITE_REAL
48
+ SQLITE_NUMERIC
49
+ SQLITE_TIME
50
+ SQLITE_BOOL
51
+ SQLITE_NULL
52
+ )
53
+
54
+ func scanType (cdt string ) reflect.Type {
55
+ t := strings .ToUpper (cdt )
56
+ i := databaseTypeConvSqlite (t )
57
+ switch i {
58
+ case SQLITE_INTEGER :
59
+ return reflect .TypeOf (sql.NullInt64 {})
60
+ case SQLITE_TEXT :
61
+ return reflect .TypeOf (sql.NullString {})
62
+ case SQLITE_BLOB :
63
+ return reflect .TypeOf (sql.RawBytes {})
64
+ case SQLITE_REAL :
65
+ return reflect .TypeOf (sql.NullFloat64 {})
66
+ case SQLITE_NUMERIC :
67
+ return reflect .TypeOf (sql.NullFloat64 {})
68
+ case SQLITE_BOOL :
69
+ return reflect .TypeOf (sql.NullBool {})
70
+ case SQLITE_TIME :
71
+ return reflect .TypeOf (sql.NullTime {})
72
+ }
73
+ return reflect .TypeOf (new (interface {}))
55
74
}
56
75
76
+ func databaseTypeConvSqlite (t string ) int {
77
+ if strings .Contains (t , "INT" ) {
78
+ return SQLITE_INTEGER
79
+ }
80
+ if t == "CLOB" || t == "TEXT" ||
81
+ strings .Contains (t , "CHAR" ) {
82
+ return SQLITE_TEXT
83
+ }
84
+ if t == "BLOB" {
85
+ return SQLITE_BLOB
86
+ }
87
+ if t == "REAL" || t == "FLOAT" ||
88
+ strings .Contains (t , "DOUBLE" ) {
89
+ return SQLITE_REAL
90
+ }
91
+ if t == "DATE" || t == "DATETIME" ||
92
+ t == "TIMESTAMP" {
93
+ return SQLITE_TIME
94
+ }
95
+ if t == "NUMERIC" ||
96
+ strings .Contains (t , "DECIMAL" ) {
97
+ return SQLITE_NUMERIC
98
+ }
99
+ if t == "BOOLEAN" {
100
+ return SQLITE_BOOL
101
+ }
102
+
103
+ return SQLITE_NULL
104
+ }
0 commit comments