feat(pkg): preserve PostgreSQL types in mapDataType function
* Add support for known PostgreSQL types and modifiers * Implement canonicalization for PostgreSQL types * Introduce unit tests for PostgreSQL type handling
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/pgsql"
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/readers"
|
||||
)
|
||||
|
||||
@@ -232,7 +233,19 @@ func (r *Reader) convertField(dctxField *models.DCTXField, tableName string) ([]
|
||||
|
||||
// mapDataType maps Clarion data types to SQL types
|
||||
func (r *Reader) mapDataType(clarionType string, size int) (sqlType string, precision int) {
|
||||
switch strings.ToUpper(clarionType) {
|
||||
trimmedType := strings.TrimSpace(clarionType)
|
||||
|
||||
// Preserve known PostgreSQL types (including arrays and extension types)
|
||||
// from DCTX input instead of coercing them to generic text.
|
||||
if pgsql.IsKnownPostgresType(trimmedType) {
|
||||
pgType := canonicalizePostgresType(trimmedType)
|
||||
if !pgsql.HasExplicitTypeModifier(pgType) && size > 0 && pgsql.SupportsLength(pgType) {
|
||||
return pgType, size
|
||||
}
|
||||
return pgType, 0
|
||||
}
|
||||
|
||||
switch strings.ToUpper(trimmedType) {
|
||||
case "LONG":
|
||||
if size == 8 {
|
||||
return "bigint", 0
|
||||
@@ -306,6 +319,32 @@ func (r *Reader) mapDataType(clarionType string, size int) (sqlType string, prec
|
||||
}
|
||||
}
|
||||
|
||||
func canonicalizePostgresType(typeStr string) string {
|
||||
t := strings.ToLower(strings.Join(strings.Fields(strings.TrimSpace(typeStr)), " "))
|
||||
if t == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Handle array suffixes
|
||||
arrayCount := 0
|
||||
for strings.HasSuffix(t, "[]") {
|
||||
arrayCount++
|
||||
t = strings.TrimSpace(strings.TrimSuffix(t, "[]"))
|
||||
}
|
||||
|
||||
// Handle optional type modifier
|
||||
modifier := ""
|
||||
if idx := strings.Index(t, "("); idx > 0 {
|
||||
if end := strings.LastIndex(t, ")"); end > idx {
|
||||
modifier = t[idx : end+1]
|
||||
t = strings.TrimSpace(t[:idx])
|
||||
}
|
||||
}
|
||||
|
||||
base := pgsql.CanonicalizeBaseType(t)
|
||||
return base + modifier + strings.Repeat("[]", arrayCount)
|
||||
}
|
||||
|
||||
// processKeys processes DCTX keys and converts them to indexes and primary keys
|
||||
func (r *Reader) processKeys(dctxTable *models.DCTXTable, table *models.Table, fieldGuidMap map[string]string) error {
|
||||
for _, dctxKey := range dctxTable.Keys {
|
||||
|
||||
@@ -493,3 +493,55 @@ func TestRelationships(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapDataType_PostgresTypes(t *testing.T) {
|
||||
reader := &Reader{}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
inputType string
|
||||
size int
|
||||
wantType string
|
||||
wantLength int
|
||||
}{
|
||||
{
|
||||
name: "integer array preserved",
|
||||
inputType: "integer[]",
|
||||
wantType: "integer[]",
|
||||
},
|
||||
{
|
||||
name: "citext array preserved",
|
||||
inputType: "citext[]",
|
||||
wantType: "citext[]",
|
||||
},
|
||||
{
|
||||
name: "vector modifier preserved",
|
||||
inputType: "vector(1536)",
|
||||
wantType: "vector(1536)",
|
||||
},
|
||||
{
|
||||
name: "alias canonicalized in array",
|
||||
inputType: "int4[]",
|
||||
wantType: "integer[]",
|
||||
},
|
||||
{
|
||||
name: "varchar length from size",
|
||||
inputType: "varchar",
|
||||
size: 120,
|
||||
wantType: "varchar",
|
||||
wantLength: 120,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotType, gotLength := reader.mapDataType(tt.inputType, tt.size)
|
||||
if gotType != tt.wantType {
|
||||
t.Fatalf("mapDataType(%q, %d) type = %q, want %q", tt.inputType, tt.size, gotType, tt.wantType)
|
||||
}
|
||||
if gotLength != tt.wantLength {
|
||||
t.Fatalf("mapDataType(%q, %d) length = %d, want %d", tt.inputType, tt.size, gotLength, tt.wantLength)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user