feat(sqlite): add SQLite type mapping and conversion functions
* Implement SQLiteToCanonicalTypes for type mapping * Add ConvertSQLiteToCanonical and ConvertCanonicalToSQLite functions * Update mapDataType to utilize new conversion logic
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
package sqlite
|
||||
|
||||
import "strings"
|
||||
|
||||
// SQLiteToCanonicalTypes maps SQLite type names to canonical types.
|
||||
// SQLite has type affinity rules; this maps common type names including
|
||||
// MySQL/PostgreSQL types that users write in SQLite schemas.
|
||||
var SQLiteToCanonicalTypes = map[string]string{
|
||||
// Integer affinity
|
||||
"integer": "int",
|
||||
"int": "int",
|
||||
"tinyint": "int8",
|
||||
"smallint": "int16",
|
||||
"mediumint": "int",
|
||||
"bigint": "int64",
|
||||
"unsigned big int": "uint64",
|
||||
"int2": "int16",
|
||||
"int8": "int64",
|
||||
// Real affinity
|
||||
"real": "float64",
|
||||
"double": "float64",
|
||||
"double precision": "float64",
|
||||
"float": "float32",
|
||||
// Numeric affinity
|
||||
"numeric": "decimal",
|
||||
"decimal": "decimal",
|
||||
// Boolean (stored as integer in SQLite)
|
||||
"boolean": "bool",
|
||||
"bool": "bool",
|
||||
// Date/time (stored as text in SQLite)
|
||||
"date": "date",
|
||||
"datetime": "timestamp",
|
||||
"timestamp": "timestamp",
|
||||
// Text affinity
|
||||
"text": "string",
|
||||
"varchar": "string",
|
||||
"char": "string",
|
||||
"character": "string",
|
||||
"varying character": "string",
|
||||
"nchar": "string",
|
||||
"nvarchar": "string",
|
||||
"clob": "text",
|
||||
// Blob affinity
|
||||
"blob": "bytea",
|
||||
}
|
||||
|
||||
// CanonicalToSQLiteAffinity maps type names to SQLite type affinity names.
|
||||
// Accepts both Go canonical names ("int", "string") and SQL canonical names
|
||||
// ("integer", "varchar") so the writer handles input from any reader.
|
||||
// The five SQLite type affinities are TEXT, INTEGER, REAL, NUMERIC, BLOB.
|
||||
var CanonicalToSQLiteAffinity = map[string]string{
|
||||
// INTEGER affinity — Go canonical
|
||||
"int": "INTEGER",
|
||||
"int8": "INTEGER",
|
||||
"int16": "INTEGER",
|
||||
"int32": "INTEGER",
|
||||
"int64": "INTEGER",
|
||||
"uint": "INTEGER",
|
||||
"uint8": "INTEGER",
|
||||
"uint16": "INTEGER",
|
||||
"uint32": "INTEGER",
|
||||
"uint64": "INTEGER",
|
||||
"bool": "INTEGER",
|
||||
// INTEGER affinity — SQL canonical
|
||||
"integer": "INTEGER",
|
||||
"smallint": "INTEGER",
|
||||
"bigint": "INTEGER",
|
||||
"serial": "INTEGER",
|
||||
"smallserial": "INTEGER",
|
||||
"bigserial": "INTEGER",
|
||||
"boolean": "INTEGER",
|
||||
"tinyint": "INTEGER",
|
||||
"mediumint": "INTEGER",
|
||||
// REAL affinity — Go canonical
|
||||
"float32": "REAL",
|
||||
"float64": "REAL",
|
||||
// REAL affinity — SQL canonical
|
||||
"real": "REAL",
|
||||
"float": "REAL",
|
||||
"double": "REAL",
|
||||
"double precision": "REAL",
|
||||
// NUMERIC affinity
|
||||
"decimal": "NUMERIC",
|
||||
"numeric": "NUMERIC",
|
||||
"money": "NUMERIC",
|
||||
"smallmoney": "NUMERIC",
|
||||
// BLOB affinity
|
||||
"bytea": "BLOB",
|
||||
"blob": "BLOB",
|
||||
// TEXT affinity — Go canonical
|
||||
"string": "TEXT",
|
||||
"text": "TEXT",
|
||||
// TEXT affinity — SQL canonical
|
||||
"varchar": "TEXT",
|
||||
"char": "TEXT",
|
||||
"nvarchar": "TEXT",
|
||||
"nchar": "TEXT",
|
||||
"citext": "TEXT",
|
||||
"date": "TEXT",
|
||||
"time": "TEXT",
|
||||
"timetz": "TEXT",
|
||||
"timestamp": "TEXT",
|
||||
"timestamptz": "TEXT",
|
||||
"datetime": "TEXT",
|
||||
"uuid": "TEXT",
|
||||
"json": "TEXT",
|
||||
"jsonb": "TEXT",
|
||||
"xml": "TEXT",
|
||||
"inet": "TEXT",
|
||||
"cidr": "TEXT",
|
||||
"macaddr": "TEXT",
|
||||
}
|
||||
|
||||
// ConvertSQLiteToCanonical converts a SQLite type name to the canonical type.
|
||||
// Strips dimension parameters (e.g. VARCHAR(255) → string) and handles
|
||||
// SQLite's flexible affinity rules. Defaults to "string" for unknown types.
|
||||
func ConvertSQLiteToCanonical(sqliteType string) string {
|
||||
base := strings.ToUpper(strings.TrimSpace(sqliteType))
|
||||
if idx := strings.Index(base, "("); idx >= 0 {
|
||||
base = strings.TrimSpace(base[:idx])
|
||||
}
|
||||
lower := strings.ToLower(base)
|
||||
|
||||
if canonical, ok := SQLiteToCanonicalTypes[lower]; ok {
|
||||
return canonical
|
||||
}
|
||||
|
||||
// Prefix match for types like "VARYING CHARACTER(255)"
|
||||
for key, canonical := range SQLiteToCanonicalTypes {
|
||||
if strings.HasPrefix(lower, key) {
|
||||
return canonical
|
||||
}
|
||||
}
|
||||
|
||||
return "string"
|
||||
}
|
||||
|
||||
// ConvertCanonicalToSQLite converts a canonical type (or any SQL type) to its
|
||||
// SQLite type affinity. Defaults to TEXT for unrecognised types.
|
||||
func ConvertCanonicalToSQLite(canonicalType string) string {
|
||||
normalized := strings.ToLower(strings.TrimSpace(canonicalType))
|
||||
if idx := strings.Index(normalized, "("); idx >= 0 {
|
||||
normalized = strings.TrimSpace(normalized[:idx])
|
||||
}
|
||||
normalized = strings.TrimSuffix(normalized, "[]")
|
||||
|
||||
if affinity, ok := CanonicalToSQLiteAffinity[normalized]; ok {
|
||||
return affinity
|
||||
}
|
||||
|
||||
return "TEXT"
|
||||
}
|
||||
Reference in New Issue
Block a user