Fork github.com/mattn/go-sqlite3 with adjustment for go1.16.2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
2.4 KiB

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