1
1
// Copyright (C) 2019 Yasuhiro Matsumoto <[email protected] >.
2
- //
3
2
// Use of this source code is governed by an MIT-style
4
3
// license that can be found in the LICENSE file.
5
4
@@ -14,8 +13,9 @@ package sqlite3
14
13
*/
15
14
import "C"
16
15
import (
16
+ "database/sql"
17
17
"reflect"
18
- "time "
18
+ "strings "
19
19
)
20
20
21
21
// ColumnTypeDatabaseTypeName implement RowsColumnTypeDatabaseTypeName.
@@ -31,32 +31,78 @@ func (rc *SQLiteRows) ColumnTypeLength(index int) (length int64, ok bool) {
31
31
func (rc *SQLiteRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
32
32
return 0, 0, false
33
33
}
34
+ */
34
35
35
36
// ColumnTypeNullable implement RowsColumnTypeNullable.
36
37
func (rc * SQLiteRows ) ColumnTypeNullable (i int ) (nullable , ok bool ) {
37
- return false, false
38
+ return true , true
38
39
}
39
- */
40
40
41
41
// ColumnTypeScanType implement RowsColumnTypeScanType.
42
42
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
62
108
}
0 commit comments