-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
use sqlite3_column_type() for ColumnTypeScanType() #1327
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,27 @@ import ( | |
"strings" | ||
) | ||
|
||
const ( | ||
SQLITE_INTEGER = iota | ||
SQLITE_TEXT | ||
SQLITE_BLOB | ||
SQLITE_REAL | ||
SQLITE_NUMERIC | ||
SQLITE_TIME | ||
SQLITE_BOOL | ||
SQLITE_NULL | ||
) | ||
|
||
var ( | ||
TYPE_NULLINT = reflect.TypeOf(sql.NullInt64{}) | ||
TYPE_NULLFLOAT = reflect.TypeOf(sql.NullFloat64{}) | ||
TYPE_NULLSTRING = reflect.TypeOf(sql.NullString{}) | ||
TYPE_RAWBYTES = reflect.TypeOf(sql.RawBytes{}) | ||
TYPE_NULLBOOL = reflect.TypeOf(sql.NullBool{}) | ||
TYPE_NULLTIME = reflect.TypeOf(sql.NullTime{}) | ||
TYPE_ANY = reflect.TypeOf(new(any)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well this is unfortunate - this means we are saying |
||
) | ||
|
||
// ColumnTypeDatabaseTypeName implement RowsColumnTypeDatabaseTypeName. | ||
func (rc *SQLiteRows) ColumnTypeDatabaseTypeName(i int) string { | ||
return C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))) | ||
|
@@ -39,42 +60,50 @@ func (rc *SQLiteRows) ColumnTypeNullable(i int) (nullable, ok bool) { | |
} | ||
|
||
// ColumnTypeScanType implement RowsColumnTypeScanType. | ||
// In SQLite3, this method should be called after Next() has been called, as sqlite3_column_type() | ||
// returns the column type for a specific row. If Next() has not been called, fallback to | ||
// sqlite3_column_decltype() | ||
func (rc *SQLiteRows) ColumnTypeScanType(i int) reflect.Type { | ||
//ct := C.sqlite3_column_type(rc.s.s, C.int(i)) // Always returns 5 | ||
switch C.sqlite3_column_type(rc.s.s, C.int(i)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We cannot call this if we haven't called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure if you mean
If it is the first, the method signature does not allow a clear way of signaling errors (except for the empty interface, which signals not-supported) and I can't find a way to know if we have a valid row. The design of the packages (sql and go-sqlite3) seems to imply this should not be a concern beyond If it is the second, it is troublesome because that means there is no way of getting the rows without risking a type conversion unless the types are known by the calling code. |
||
case C.SQLITE_INTEGER: | ||
return TYPE_NULLINT | ||
case C.SQLITE_FLOAT: | ||
return TYPE_NULLFLOAT | ||
case C.SQLITE_TEXT: | ||
return TYPE_NULLSTRING | ||
case C.SQLITE_BLOB: | ||
return TYPE_RAWBYTES | ||
// This case can signal that the value is NULL or that Next() has not been called yet. | ||
// Skip it and return the fallback behaviour as a best effort. This is safe as all types | ||
// returned are Nullable or any, which is the expected value for SQLite3. | ||
//case C.SQLITE_NULL: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this commented out? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it doesn't apply, then just remove the code? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Its to document that the omission is intentional and not a miss, this is the actual value that we would be getting in 2 cases:
Happy to remove it or add a comment clarifying. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like a mistake. An explicit comment is better. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added comment. Please take another look. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
// return TYPE_ANY | ||
} | ||
|
||
// Fallback to schema declared to remain retro-compatible | ||
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{}) | ||
return TYPE_NULLINT | ||
case SQLITE_TEXT: | ||
return reflect.TypeOf(sql.NullString{}) | ||
return TYPE_NULLSTRING | ||
case SQLITE_BLOB: | ||
return reflect.TypeOf(sql.RawBytes{}) | ||
return TYPE_RAWBYTES | ||
case SQLITE_REAL: | ||
return reflect.TypeOf(sql.NullFloat64{}) | ||
return TYPE_NULLFLOAT | ||
case SQLITE_NUMERIC: | ||
return reflect.TypeOf(sql.NullFloat64{}) | ||
return TYPE_NULLFLOAT | ||
case SQLITE_BOOL: | ||
return reflect.TypeOf(sql.NullBool{}) | ||
return TYPE_NULLBOOL | ||
case SQLITE_TIME: | ||
return reflect.TypeOf(sql.NullTime{}) | ||
return TYPE_NULLTIME | ||
} | ||
return reflect.TypeOf(new(any)) | ||
return TYPE_ANY | ||
} | ||
|
||
func databaseTypeConvSqlite(t string) int { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are these all public?