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,156 @@
|
||||
package mariadb
|
||||
|
||||
import "strings"
|
||||
|
||||
// MariaDBToCanonicalTypes maps MariaDB/MySQL type names to canonical types.
|
||||
var MariaDBToCanonicalTypes = map[string]string{
|
||||
// Integer types
|
||||
"tinyint": "int8",
|
||||
"smallint": "int16",
|
||||
"mediumint": "int",
|
||||
"int": "int",
|
||||
"integer": "int",
|
||||
"int2": "int16",
|
||||
"int4": "int",
|
||||
"int8": "int64",
|
||||
"bigint": "int64",
|
||||
// Boolean (TINYINT(1) alias)
|
||||
"boolean": "bool",
|
||||
"bool": "bool",
|
||||
"bit": "bool",
|
||||
// Float types
|
||||
"float": "float32",
|
||||
"double": "float64",
|
||||
"real": "float64",
|
||||
"double precision": "float64",
|
||||
// Decimal types
|
||||
"decimal": "decimal",
|
||||
"numeric": "decimal",
|
||||
"dec": "decimal",
|
||||
"fixed": "decimal",
|
||||
// String types
|
||||
"char": "string",
|
||||
"character": "string",
|
||||
"varchar": "string",
|
||||
"nchar": "string",
|
||||
"nvarchar": "string",
|
||||
"tinytext": "text",
|
||||
"text": "text",
|
||||
"mediumtext": "text",
|
||||
"longtext": "text",
|
||||
// Binary/blob types
|
||||
"binary": "bytea",
|
||||
"varbinary": "bytea",
|
||||
"tinyblob": "bytea",
|
||||
"blob": "bytea",
|
||||
"mediumblob": "bytea",
|
||||
"longblob": "bytea",
|
||||
// Date/time types
|
||||
"date": "date",
|
||||
"time": "time",
|
||||
"datetime": "timestamp",
|
||||
"timestamp": "timestamp",
|
||||
"year": "int",
|
||||
// Other types
|
||||
"json": "json",
|
||||
"enum": "string",
|
||||
"set": "string",
|
||||
"uuid": "uuid",
|
||||
}
|
||||
|
||||
// CanonicalToMariaDBTypes maps canonical types to MariaDB/MySQL types.
|
||||
var CanonicalToMariaDBTypes = map[string]string{
|
||||
"bool": "TINYINT(1)",
|
||||
"int8": "TINYINT",
|
||||
"int16": "SMALLINT",
|
||||
"int": "INT",
|
||||
"int32": "INT",
|
||||
"int64": "BIGINT",
|
||||
"uint": "INT UNSIGNED",
|
||||
"uint8": "TINYINT UNSIGNED",
|
||||
"uint16": "SMALLINT UNSIGNED",
|
||||
"uint32": "INT UNSIGNED",
|
||||
"uint64": "BIGINT UNSIGNED",
|
||||
"float32": "FLOAT",
|
||||
"float64": "DOUBLE",
|
||||
"decimal": "DECIMAL",
|
||||
"string": "VARCHAR(255)",
|
||||
"text": "TEXT",
|
||||
"date": "DATE",
|
||||
"time": "TIME",
|
||||
"timestamp": "DATETIME",
|
||||
"timestamptz": "DATETIME",
|
||||
"uuid": "CHAR(36)",
|
||||
"json": "JSON",
|
||||
"jsonb": "JSON",
|
||||
"bytea": "BLOB",
|
||||
}
|
||||
|
||||
// MariaDBTypeSynonyms maps MariaDB/MySQL type aliases to their canonical MariaDB name.
|
||||
var MariaDBTypeSynonyms = map[string]string{
|
||||
"integer": "int",
|
||||
"int2": "smallint",
|
||||
"int4": "int",
|
||||
"int8": "bigint",
|
||||
"double precision": "double",
|
||||
"character": "char",
|
||||
"dec": "decimal",
|
||||
"fixed": "decimal",
|
||||
"numeric": "decimal",
|
||||
"boolean": "tinyint",
|
||||
"bool": "tinyint",
|
||||
}
|
||||
|
||||
// NormalizeMariaDBType maps a MariaDB/MySQL base type (no dimension parameters)
|
||||
// to its canonical MariaDB form. Unknown types are returned as-is (lowercased).
|
||||
func NormalizeMariaDBType(baseType string) string {
|
||||
lower := strings.ToLower(strings.TrimSpace(baseType))
|
||||
if canonical, ok := MariaDBTypeSynonyms[lower]; ok {
|
||||
return canonical
|
||||
}
|
||||
return lower
|
||||
}
|
||||
|
||||
// ConvertMariaDBToCanonical converts a MariaDB/MySQL type name to the canonical type.
|
||||
// Strips dimension parameters and normalizes aliases. Defaults to "string".
|
||||
func ConvertMariaDBToCanonical(mariadbType string) string {
|
||||
base := strings.ToLower(strings.TrimSpace(mariadbType))
|
||||
if idx := strings.Index(base, "("); idx >= 0 {
|
||||
base = strings.TrimSpace(base[:idx])
|
||||
}
|
||||
|
||||
if canonical, ok := MariaDBToCanonicalTypes[base]; ok {
|
||||
return canonical
|
||||
}
|
||||
|
||||
// Prefix match for composite types (e.g., "unsigned bigint")
|
||||
for key, canonical := range MariaDBToCanonicalTypes {
|
||||
if strings.HasPrefix(base, key) {
|
||||
return canonical
|
||||
}
|
||||
}
|
||||
|
||||
return "string"
|
||||
}
|
||||
|
||||
// ConvertCanonicalToMariaDB converts a canonical type to a MariaDB/MySQL type.
|
||||
// Defaults to VARCHAR(255) for unrecognised types.
|
||||
func ConvertCanonicalToMariaDB(canonicalType string) string {
|
||||
lower := strings.ToLower(strings.TrimSpace(canonicalType))
|
||||
if idx := strings.Index(lower, "("); idx >= 0 {
|
||||
lower = strings.TrimSpace(lower[:idx])
|
||||
}
|
||||
|
||||
if mariadbType, ok := CanonicalToMariaDBTypes[lower]; ok {
|
||||
return mariadbType
|
||||
}
|
||||
|
||||
// Prefix fallback
|
||||
for canonical, mariadb := range CanonicalToMariaDBTypes {
|
||||
if strings.HasPrefix(lower, canonical) {
|
||||
return mariadb
|
||||
}
|
||||
}
|
||||
|
||||
return "VARCHAR(255)"
|
||||
}
|
||||
+76
-32
@@ -2,32 +2,73 @@ package mssql
|
||||
|
||||
import "strings"
|
||||
|
||||
// CanonicalToMSSQLTypes maps canonical types to MSSQL types
|
||||
// CanonicalToMSSQLTypes maps canonical types to MSSQL types.
|
||||
// Accepts both Go canonical names ("int", "string") and SQL canonical names
|
||||
// ("integer", "varchar") so the writer handles input from any reader.
|
||||
var CanonicalToMSSQLTypes = map[string]string{
|
||||
// Boolean — Go and SQL canonical
|
||||
"bool": "BIT",
|
||||
"boolean": "BIT",
|
||||
// Integer — Go canonical
|
||||
"int8": "TINYINT",
|
||||
"int16": "SMALLINT",
|
||||
"int": "INT",
|
||||
"int32": "INT",
|
||||
"int64": "BIGINT",
|
||||
"uint": "BIGINT",
|
||||
"uint8": "SMALLINT",
|
||||
"uint16": "INT",
|
||||
"uint8": "TINYINT",
|
||||
"uint16": "SMALLINT",
|
||||
"uint32": "BIGINT",
|
||||
"uint64": "BIGINT",
|
||||
// Integer — SQL canonical (serial types map to base integer; IDENTITY is set via AutoIncrement)
|
||||
"integer": "INT",
|
||||
"smallint": "SMALLINT",
|
||||
"bigint": "BIGINT",
|
||||
"tinyint": "TINYINT",
|
||||
"serial": "INT",
|
||||
"smallserial": "SMALLINT",
|
||||
"bigserial": "BIGINT",
|
||||
// Float — Go canonical
|
||||
"float32": "REAL",
|
||||
"float64": "FLOAT",
|
||||
// Float — SQL canonical
|
||||
"real": "REAL",
|
||||
"double precision": "FLOAT",
|
||||
"double": "FLOAT",
|
||||
// Decimal/numeric
|
||||
"decimal": "NUMERIC",
|
||||
"numeric": "NUMERIC",
|
||||
"money": "MONEY",
|
||||
// String — Go canonical
|
||||
"string": "NVARCHAR(255)",
|
||||
"text": "NVARCHAR(MAX)",
|
||||
// String — SQL canonical
|
||||
"varchar": "NVARCHAR(255)",
|
||||
"char": "NCHAR",
|
||||
"nvarchar": "NVARCHAR(255)",
|
||||
"nchar": "NCHAR",
|
||||
"citext": "NVARCHAR(MAX)",
|
||||
// Date/time
|
||||
"date": "DATE",
|
||||
"time": "TIME",
|
||||
"timetz": "DATETIMEOFFSET",
|
||||
"timestamp": "DATETIME2",
|
||||
"timestamptz": "DATETIMEOFFSET",
|
||||
"datetime": "DATETIME2",
|
||||
"interval": "NVARCHAR(50)",
|
||||
// UUID
|
||||
"uuid": "UNIQUEIDENTIFIER",
|
||||
// JSON — MSSQL has no native JSON type; stored as NVARCHAR(MAX)
|
||||
"json": "NVARCHAR(MAX)",
|
||||
"jsonb": "NVARCHAR(MAX)",
|
||||
// Binary
|
||||
"bytea": "VARBINARY(MAX)",
|
||||
"blob": "VARBINARY(MAX)",
|
||||
// Network/geo types — no MSSQL native equivalent
|
||||
"xml": "XML",
|
||||
"inet": "NVARCHAR(45)",
|
||||
"cidr": "NVARCHAR(43)",
|
||||
"macaddr": "NVARCHAR(17)",
|
||||
}
|
||||
|
||||
// MSSQLToCanonicalTypes maps MSSQL types to canonical types
|
||||
@@ -68,47 +109,50 @@ var MSSQLToCanonicalTypes = map[string]string{
|
||||
"geometry": "string",
|
||||
}
|
||||
|
||||
// ConvertCanonicalToMSSQL converts a canonical type to MSSQL type
|
||||
// MSSQLTypeSynonyms maps MSSQL type aliases to their canonical MSSQL name.
|
||||
var MSSQLTypeSynonyms = map[string]string{
|
||||
"integer": "int",
|
||||
"dec": "decimal",
|
||||
"float(n)": "float",
|
||||
}
|
||||
|
||||
// NormalizeMSSQLType maps an MSSQL base type (no dimension parameters) to its
|
||||
// canonical MSSQL form. Unknown types are returned as-is (lowercased).
|
||||
func NormalizeMSSQLType(baseType string) string {
|
||||
lower := strings.ToLower(strings.TrimSpace(baseType))
|
||||
if canonical, ok := MSSQLTypeSynonyms[lower]; ok {
|
||||
return canonical
|
||||
}
|
||||
return lower
|
||||
}
|
||||
|
||||
// ConvertCanonicalToMSSQL converts a canonical type (Go or SQL) to an MSSQL type.
|
||||
// Strips dimension parameters before lookup. Defaults to NVARCHAR(255) for unknown types.
|
||||
func ConvertCanonicalToMSSQL(canonicalType string) string {
|
||||
// Check direct mapping
|
||||
if mssqlType, exists := CanonicalToMSSQLTypes[strings.ToLower(canonicalType)]; exists {
|
||||
base := strings.ToLower(strings.TrimSpace(canonicalType))
|
||||
if idx := strings.Index(base, "("); idx >= 0 {
|
||||
base = strings.TrimSpace(base[:idx])
|
||||
}
|
||||
base = strings.TrimSuffix(base, "[]")
|
||||
|
||||
if mssqlType, exists := CanonicalToMSSQLTypes[base]; exists {
|
||||
return mssqlType
|
||||
}
|
||||
|
||||
// Try to find by prefix
|
||||
lowerType := strings.ToLower(canonicalType)
|
||||
for canonical, mssql := range CanonicalToMSSQLTypes {
|
||||
if strings.HasPrefix(lowerType, canonical) {
|
||||
return mssql
|
||||
}
|
||||
}
|
||||
|
||||
// Default to NVARCHAR
|
||||
return "NVARCHAR(255)"
|
||||
}
|
||||
|
||||
// ConvertMSSQLToCanonical converts an MSSQL type to canonical type
|
||||
// ConvertMSSQLToCanonical converts an MSSQL type to the canonical type.
|
||||
// Strips dimension parameters before lookup. Defaults to "string" for unknown types.
|
||||
func ConvertMSSQLToCanonical(mssqlType string) string {
|
||||
// Extract base type (remove parentheses and parameters)
|
||||
baseType := mssqlType
|
||||
if idx := strings.Index(baseType, "("); idx != -1 {
|
||||
baseType = baseType[:idx]
|
||||
base := strings.ToLower(strings.TrimSpace(mssqlType))
|
||||
if idx := strings.Index(base, "("); idx >= 0 {
|
||||
base = strings.TrimSpace(base[:idx])
|
||||
}
|
||||
baseType = strings.TrimSpace(baseType)
|
||||
|
||||
// Check direct mapping
|
||||
if canonicalType, exists := MSSQLToCanonicalTypes[strings.ToLower(baseType)]; exists {
|
||||
if canonicalType, exists := MSSQLToCanonicalTypes[base]; exists {
|
||||
return canonicalType
|
||||
}
|
||||
|
||||
// Try to find by prefix
|
||||
lowerType := strings.ToLower(baseType)
|
||||
for mssql, canonical := range MSSQLToCanonicalTypes {
|
||||
if strings.HasPrefix(lowerType, mssql) {
|
||||
return canonical
|
||||
}
|
||||
}
|
||||
|
||||
// Default to string
|
||||
return "string"
|
||||
}
|
||||
|
||||
@@ -270,8 +270,16 @@ func (r *Reader) queryColumns(schemaName string) (map[string]map[string]*models.
|
||||
}
|
||||
|
||||
if numPrecision != nil {
|
||||
// For integer and serial types, numeric_precision is a bit-width (32, 64, 16)
|
||||
// not a user-visible column parameter. Only store precision for types where
|
||||
// it represents actual decimal/scale precision (numeric, decimal, float).
|
||||
switch column.Type {
|
||||
case "integer", "bigint", "smallint", "serial", "bigserial", "smallserial":
|
||||
// skip — bit-width, not a column parameter
|
||||
default:
|
||||
column.Precision = *numPrecision
|
||||
}
|
||||
}
|
||||
|
||||
if numScale != nil {
|
||||
column.Scale = *numScale
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/readers"
|
||||
sqlitepkg "git.warky.dev/wdevs/relspecgo/pkg/sqlite"
|
||||
)
|
||||
|
||||
// Reader implements the readers.Reader interface for SQLite databases
|
||||
@@ -183,59 +184,9 @@ func (r *Reader) close() {
|
||||
}
|
||||
}
|
||||
|
||||
// mapDataType maps SQLite data types to canonical types
|
||||
// mapDataType maps SQLite data types to canonical types.
|
||||
func (r *Reader) mapDataType(sqliteType string) string {
|
||||
// SQLite has a flexible type system, but we map common types
|
||||
typeMap := map[string]string{
|
||||
"INTEGER": "int",
|
||||
"INT": "int",
|
||||
"TINYINT": "int8",
|
||||
"SMALLINT": "int16",
|
||||
"MEDIUMINT": "int",
|
||||
"BIGINT": "int64",
|
||||
"UNSIGNED BIG INT": "uint64",
|
||||
"INT2": "int16",
|
||||
"INT8": "int64",
|
||||
"REAL": "float64",
|
||||
"DOUBLE": "float64",
|
||||
"DOUBLE PRECISION": "float64",
|
||||
"FLOAT": "float32",
|
||||
"NUMERIC": "decimal",
|
||||
"DECIMAL": "decimal",
|
||||
"BOOLEAN": "bool",
|
||||
"BOOL": "bool",
|
||||
"DATE": "date",
|
||||
"DATETIME": "timestamp",
|
||||
"TIMESTAMP": "timestamp",
|
||||
"TEXT": "string",
|
||||
"VARCHAR": "string",
|
||||
"CHAR": "string",
|
||||
"CHARACTER": "string",
|
||||
"VARYING CHARACTER": "string",
|
||||
"NCHAR": "string",
|
||||
"NVARCHAR": "string",
|
||||
"CLOB": "text",
|
||||
"BLOB": "bytea",
|
||||
}
|
||||
|
||||
// Try exact match first
|
||||
if mapped, exists := typeMap[sqliteType]; exists {
|
||||
return mapped
|
||||
}
|
||||
|
||||
// Try case-insensitive match for common types
|
||||
sqliteTypeUpper := sqliteType
|
||||
if len(sqliteType) > 0 {
|
||||
// Extract base type (e.g., "VARCHAR(255)" -> "VARCHAR")
|
||||
for baseType := range typeMap {
|
||||
if len(sqliteTypeUpper) >= len(baseType) && sqliteTypeUpper[:len(baseType)] == baseType {
|
||||
return typeMap[baseType]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default to string for unknown types
|
||||
return "string"
|
||||
return sqlitepkg.ConvertSQLiteToCanonical(sqliteType)
|
||||
}
|
||||
|
||||
// deriveRelationship creates a relationship from a foreign key constraint
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -3,10 +3,10 @@ package sqlite
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/pgsql"
|
||||
sqlitepkg "git.warky.dev/wdevs/relspecgo/pkg/sqlite"
|
||||
)
|
||||
|
||||
// SQLite type affinities
|
||||
// SQLite type affinity constants
|
||||
const (
|
||||
TypeText = "TEXT"
|
||||
TypeInteger = "INTEGER"
|
||||
@@ -15,55 +15,27 @@ const (
|
||||
TypeBlob = "BLOB"
|
||||
)
|
||||
|
||||
// MapPostgreSQLType maps PostgreSQL data types to SQLite type affinities
|
||||
// MapTypeToSQLite maps any SQL or Go canonical type to a SQLite type affinity.
|
||||
// Handles input from any reader (PostgreSQL, MSSQL, SQLite, Go canonical).
|
||||
func MapTypeToSQLite(colType string) string {
|
||||
return sqlitepkg.ConvertCanonicalToSQLite(colType)
|
||||
}
|
||||
|
||||
// MapPostgreSQLType is an alias for MapTypeToSQLite kept for compatibility.
|
||||
//
|
||||
// Deprecated: use MapTypeToSQLite.
|
||||
func MapPostgreSQLType(pgType string) string {
|
||||
normalized := strings.ToLower(strings.TrimSpace(pgType))
|
||||
normalized = strings.TrimSuffix(normalized, "[]")
|
||||
if idx := strings.Index(normalized, "("); idx != -1 {
|
||||
normalized = normalized[:idx]
|
||||
}
|
||||
// Resolve synonyms to canonical form before mapping
|
||||
normalized = pgsql.NormalizePGType(normalized)
|
||||
|
||||
switch normalized {
|
||||
case "varchar", "char", "text", "citext", "uuid",
|
||||
"timestamp", "timestamptz", "date", "time", "timetz",
|
||||
"json", "jsonb", "xml", "inet", "cidr", "macaddr":
|
||||
return TypeText
|
||||
case "integer", "smallint", "bigint",
|
||||
"serial", "smallserial", "bigserial", "boolean":
|
||||
return TypeInteger
|
||||
case "real", "float", "double precision":
|
||||
return TypeReal
|
||||
case "numeric", "money":
|
||||
return TypeNumeric
|
||||
case "bytea", "blob":
|
||||
return TypeBlob
|
||||
default:
|
||||
return TypeText
|
||||
}
|
||||
return MapTypeToSQLite(pgType)
|
||||
}
|
||||
|
||||
// IsIntegerType checks if a column type should be treated as integer
|
||||
// IsIntegerType reports whether a column type maps to SQLite INTEGER affinity.
|
||||
func IsIntegerType(colType string) bool {
|
||||
normalized := strings.ToLower(strings.TrimSpace(colType))
|
||||
normalized = strings.TrimSuffix(normalized, "[]")
|
||||
if idx := strings.Index(normalized, "("); idx != -1 {
|
||||
normalized = normalized[:idx]
|
||||
}
|
||||
normalized = pgsql.NormalizePGType(normalized)
|
||||
switch normalized {
|
||||
case "integer", "smallint", "bigint", "serial", "smallserial", "bigserial":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return MapTypeToSQLite(colType) == TypeInteger
|
||||
}
|
||||
|
||||
// MapBooleanValue converts PostgreSQL boolean literals to SQLite (0/1)
|
||||
// MapBooleanValue converts common boolean literals to SQLite integers (1/0).
|
||||
func MapBooleanValue(value string) string {
|
||||
normalized := strings.ToLower(strings.TrimSpace(value))
|
||||
switch normalized {
|
||||
switch strings.ToLower(strings.TrimSpace(value)) {
|
||||
case "true", "t", "yes", "y", "1":
|
||||
return "1"
|
||||
case "false", "f", "no", "n", "0":
|
||||
|
||||
Reference in New Issue
Block a user