diff --git a/pkg/writers/bun/type_mapper.go b/pkg/writers/bun/type_mapper.go index fd41bfd..54c4fe1 100644 --- a/pkg/writers/bun/type_mapper.go +++ b/pkg/writers/bun/type_mapper.go @@ -311,10 +311,11 @@ func (tm *TypeMapper) BuildBunTag(column *models.Column, table *models.Table) st if column.Type != "" { // Sanitize type to remove backticks typeStr := writers.SanitizeStructTagValue(column.Type) + isArray := pgsql.IsArrayType(typeStr) hasExplicitTypeModifier := pgsql.HasExplicitTypeModifier(typeStr) - if !hasExplicitTypeModifier && column.Length > 0 { + if !hasExplicitTypeModifier && !isArray && column.Length > 0 { typeStr = fmt.Sprintf("%s(%d)", typeStr, column.Length) - } else if !hasExplicitTypeModifier && column.Precision > 0 { + } else if !hasExplicitTypeModifier && !isArray && column.Precision > 0 { if column.Scale > 0 { typeStr = fmt.Sprintf("%s(%d,%d)", typeStr, column.Precision, column.Scale) } else { @@ -322,6 +323,9 @@ func (tm *TypeMapper) BuildBunTag(column *models.Column, table *models.Table) st } } parts = append(parts, fmt.Sprintf("type:%s", typeStr)) + if isArray { + parts = append(parts, "array") + } } // Primary key diff --git a/pkg/writers/bun/writer_test.go b/pkg/writers/bun/writer_test.go index 0e5ba60..2a203a6 100644 --- a/pkg/writers/bun/writer_test.go +++ b/pkg/writers/bun/writer_test.go @@ -574,6 +574,10 @@ func TestTypeMapper_SQLTypeToGoType_Bun(t *testing.T) { {"boolean", false, "resolvespec_common.SqlBool"}, {"uuid", false, "resolvespec_common.SqlUUID"}, {"jsonb", false, "resolvespec_common.SqlJSONB"}, + {"text[]", true, "resolvespec_common.SqlStringArray"}, + {"text[]", false, "resolvespec_common.SqlStringArray"}, + {"integer[]", true, "resolvespec_common.SqlInt32Array"}, + {"bigint[]", false, "resolvespec_common.SqlInt64Array"}, } for _, tt := range tests { @@ -685,6 +689,24 @@ func TestTypeMapper_BuildBunTag(t *testing.T) { }, want: []string{"id,", "type:bigserial,", "pk,", "autoincrement,"}, }, + { + name: "text array type", + column: &models.Column{ + Name: "tags", + Type: "text[]", + NotNull: false, + }, + want: []string{"tags,", "type:text[],", "array,"}, + }, + { + name: "integer array type", + column: &models.Column{ + Name: "scores", + Type: "integer[]", + NotNull: true, + }, + want: []string{"scores,", "type:integer[],", "array,"}, + }, } for _, tt := range tests { diff --git a/pkg/writers/gorm/writer_test.go b/pkg/writers/gorm/writer_test.go index 8bf3d90..f743d04 100644 --- a/pkg/writers/gorm/writer_test.go +++ b/pkg/writers/gorm/writer_test.go @@ -658,6 +658,10 @@ func TestTypeMapper_SQLTypeToGoType(t *testing.T) { {"timestamp", false, "sql_types.SqlTimeStamp"}, {"boolean", true, "bool"}, {"boolean", false, "sql_types.SqlBool"}, + {"text[]", true, "sql_types.SqlStringArray"}, + {"text[]", false, "sql_types.SqlStringArray"}, + {"integer[]", true, "sql_types.SqlInt32Array"}, + {"bigint[]", false, "sql_types.SqlInt64Array"}, } for _, tt := range tests { @@ -670,6 +674,21 @@ func TestTypeMapper_SQLTypeToGoType(t *testing.T) { } } +func TestTypeMapper_BuildGormTag_ArrayType(t *testing.T) { + mapper := NewTypeMapper("") + + col := &models.Column{ + Name: "tags", + Type: "text[]", + NotNull: false, + } + + tag := mapper.BuildGormTag(col, nil) + if !strings.Contains(tag, "type:text[]") { + t.Fatalf("expected array type to be preserved, got %q", tag) + } +} + func TestTypeMapper_BuildGormTag_PreservesExplicitTypeModifiers(t *testing.T) { mapper := NewTypeMapper("") diff --git a/pkg/writers/writer.go b/pkg/writers/writer.go index 137c4c6..605ad79 100644 --- a/pkg/writers/writer.go +++ b/pkg/writers/writer.go @@ -207,7 +207,8 @@ func quoteSQLLiteral(value string) string { // - Returns a clean identifier safe for use in struct tags and field names func SanitizeStructTagValue(value string) string { // Remove DBML/DCTX style comments in brackets (e.g., [note: 'description']) - commentRegex := regexp.MustCompile(`\s*\[.*?\]\s*`) + // Require at least one character inside brackets to avoid stripping PostgreSQL array suffix "[]" + commentRegex := regexp.MustCompile(`\s*\[[^\]]+\]\s*`) value = commentRegex.ReplaceAllString(value, "") // Trim whitespace