Skip to content

Commit cadffb5

Browse files
authored
Update sqlite3_type.go
Update 'ColumnTypeScanType' method, Different types of mapping values
1 parent 39c267d commit cadffb5

File tree

1 file changed

+69
-21
lines changed

1 file changed

+69
-21
lines changed

sqlite3_type.go

Lines changed: 69 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
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-
61
package sqlite3
72

83
/*
@@ -14,8 +9,9 @@ package sqlite3
149
*/
1510
import "C"
1611
import (
12+
"database/sql"
1713
"reflect"
18-
"time"
14+
"strings"
1915
)
2016

2117
// ColumnTypeDatabaseTypeName implement RowsColumnTypeDatabaseTypeName.
@@ -31,26 +27,78 @@ func (rc *SQLiteRows) ColumnTypeLength(index int) (length int64, ok bool) {
3127
func (rc *SQLiteRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
3228
return 0, 0, false
3329
}
30+
*/
3431

3532
// ColumnTypeNullable implement RowsColumnTypeNullable.
3633
func (rc *SQLiteRows) ColumnTypeNullable(i int) (nullable, ok bool) {
37-
return false, false
34+
return true, true
3835
}
39-
*/
36+
4037
// ColumnTypeScanType implement RowsColumnTypeScanType.
4138
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{}))
5574
}
5675

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

Comments
 (0)