From f29cec40daf780e86c5f6d1e4528de4ff9d9841a Mon Sep 17 00:00:00 2001 From: fc221 Date: Thu, 27 Nov 2025 20:14:24 +0800 Subject: [PATCH 1/6] Fix generics types with custom type support --- examples/models/user.go | 3 ++ examples/output/models/user.go | 15 +++--- internal/gen/generator.go | 99 ++++++++++++++++++++++++++++++++-- internal/gen/generator_test.go | 1 + 4 files changed, 108 insertions(+), 10 deletions(-) diff --git a/examples/models/user.go b/examples/models/user.go index 35cae09..498a691 100644 --- a/examples/models/user.go +++ b/examples/models/user.go @@ -38,8 +38,11 @@ type User struct { IsAdult bool `gorm:"column:is_adult"` Profile string `gen:"json"` AwardTypes datatypes.JSONSlice[int] + TagTypes datatypes.JSONSlice[UserTagType] } +type UserTagType string + type Account struct { gorm.Model UserID sql.NullInt64 diff --git a/examples/output/models/user.go b/examples/output/models/user.go index 0960590..eeba8b9 100644 --- a/examples/output/models/user.go +++ b/examples/output/models/user.go @@ -5,7 +5,6 @@ package models import ( "database/sql" - "gorm.io/cli/gorm/examples" "gorm.io/cli/gorm/examples/models" "gorm.io/cli/gorm/field" "gorm.io/datatypes" @@ -21,7 +20,7 @@ var User = struct { Age field.Number[int] Birthday field.Time Score field.Field[sql.NullInt64] - LastLogin field.Time + LastLogin field.Field[sql.NullTime] Account field.Struct[models.Account] Pets field.Slice[models.Pet] Toys field.Slice[models.Toy] @@ -34,8 +33,9 @@ var User = struct { Friends field.Slice[models.User] Role field.String IsAdult field.Bool - Profile examples.JSON + Profile field.String AwardTypes field.Struct[datatypes.JSONSlice[int]] + TagTypes field.Struct[datatypes.JSONSlice[models.UserTagType]] }{ ID: field.Number[uint]{}.WithColumn("id"), CreatedAt: field.Time{}.WithColumn("created_at"), @@ -45,7 +45,7 @@ var User = struct { Age: field.Number[int]{}.WithColumn("age"), Birthday: field.Time{}.WithColumn("birthday"), Score: field.Field[sql.NullInt64]{}.WithColumn("score"), - LastLogin: field.Time{}.WithColumn("last_login"), + LastLogin: field.Field[sql.NullTime]{}.WithColumn("last_login"), Account: field.Struct[models.Account]{}.WithName("Account"), Pets: field.Slice[models.Pet]{}.WithName("Pets"), Toys: field.Slice[models.Toy]{}.WithName("Toys"), @@ -58,8 +58,9 @@ var User = struct { Friends: field.Slice[models.User]{}.WithName("Friends"), Role: field.String{}.WithColumn("role"), IsAdult: field.Bool{}.WithColumn("is_adult"), - Profile: examples.JSON{}.WithColumn("profile"), + Profile: field.String{}.WithColumn("profile"), AwardTypes: field.Struct[datatypes.JSONSlice[int]]{}.WithName("AwardTypes"), + TagTypes: field.Struct[datatypes.JSONSlice[models.UserTagType]]{}.WithName("TagTypes"), } var Account = struct { @@ -70,7 +71,7 @@ var Account = struct { UserID field.Field[sql.NullInt64] Number field.String RewardPoints field.Field[sql.NullInt64] - LastUsedAt field.Time + LastUsedAt field.Field[sql.NullTime] }{ ID: field.Number[uint]{}.WithColumn("id"), CreatedAt: field.Time{}.WithColumn("created_at"), @@ -79,7 +80,7 @@ var Account = struct { UserID: field.Field[sql.NullInt64]{}.WithColumn("user_id"), Number: field.String{}.WithColumn("number"), RewardPoints: field.Field[sql.NullInt64]{}.WithColumn("reward_points"), - LastUsedAt: field.Time{}.WithColumn("last_used_at"), + LastUsedAt: field.Field[sql.NullTime]{}.WithColumn("last_used_at"), } var Pet = struct { diff --git a/internal/gen/generator.go b/internal/gen/generator.go index f67eca0..8ad523a 100644 --- a/internal/gen/generator.go +++ b/internal/gen/generator.go @@ -433,13 +433,25 @@ func (f Field) Type() string { } // Check if type implements allowed interfaces + goType := strings.TrimPrefix(f.GoType, "*") + + // Process generic type parameters to convert full paths to short names + goType = f.processGenericType(goType) + var ( - goType = strings.TrimPrefix(f.GoType, "*") - pkgIdx = strings.LastIndex(goType, ".") + pkgIdx int pkgName = f.file.Package typName = goType ) + // Find the last '.' before any generic bracket '[' + bracketIdx := strings.Index(goType, "[") + if bracketIdx != -1 { + pkgIdx = strings.LastIndex(goType[:bracketIdx], ".") + } else { + pkgIdx = strings.LastIndex(goType, ".") + } + if pkgIdx > 0 { pkgName, typName = goType[:pkgIdx], goType[pkgIdx+1:] } @@ -454,7 +466,7 @@ func (f Field) Type() string { } if typ := loadNamedType(f.file.goModDir, f.file.getFullImportPath(pkgName), typName); typ != nil { - if ImplementsAllowedInterfaces(typ) { // For interface-implementing types, use generic Field + if ImplementsAllowedInterfaces(typ) { return fmt.Sprintf("field.Field[%s]", filepath.Base(goType)) } } @@ -470,6 +482,87 @@ func (f Field) Type() string { return fmt.Sprintf("field.Field[%s]", filepath.Base(goType)) } +// processGenericType converts full package paths in generic type parameters to short names +// and ensures required imports are added +// e.g., "datatypes.JSONSlice[gorm.io/cli/gorm/examples/models.UserTagType]" +// +// -> "datatypes.JSONSlice[models.UserTagType]" +func (f Field) processGenericType(goType string) string { + bracketIdx := strings.Index(goType, "[") + if bracketIdx == -1 { + return goType + } + + // Split into base type and type parameters + baseType := goType[:bracketIdx] + remaining := goType[bracketIdx+1:] + + // Find matching closing bracket + depth := 1 + endIdx := 0 + for i, ch := range remaining { + if ch == '[' { + depth++ + } else if ch == ']' { + depth-- + if depth == 0 { + endIdx = i + break + } + } + } + + if endIdx == 0 { + return goType + } + + params := remaining[:endIdx] + suffix := remaining[endIdx+1:] + + // Process each type parameter + var processedParams []string + paramParts := strings.Split(params, ",") + + for _, param := range paramParts { + param = strings.TrimSpace(param) + + // Recursively process nested generics + param = f.processGenericType(param) + + // Convert full package path to short name + if lastDot := strings.LastIndex(param, "."); lastDot > 0 { + fullPkgPath := param[:lastDot] + typeName := param[lastDot+1:] + + // Get or create short package name + shortName := filepath.Base(fullPkgPath) + + // Ensure import exists + f.file.ensureImport(shortName, fullPkgPath) + + param = shortName + "." + typeName + } + + processedParams = append(processedParams, param) + } + + return baseType + "[" + strings.Join(processedParams, ", ") + "]" + suffix +} + +// ensureImport adds an import if it doesn't already exist +func (p *File) ensureImport(name, path string) { + for _, imp := range p.Imports { + if imp.Path == path { + return + } + } + + p.Imports = append(p.Imports, Import{ + Name: name, + Path: path, + }) +} + // Value returns the field value string with column name for template generation func (f Field) Value() string { fieldType := f.Type() diff --git a/internal/gen/generator_test.go b/internal/gen/generator_test.go index 8534990..7a3aa03 100644 --- a/internal/gen/generator_test.go +++ b/internal/gen/generator_test.go @@ -179,6 +179,7 @@ func TestProcessStructType(t *testing.T) { {Name: "IsAdult", DBName: "is_adult", GoType: "bool"}, {Name: "Profile", DBName: "profile", GoType: "string", NamedGoType: "json"}, {Name: "AwardTypes", DBName: "award_types", GoType: "datatypes.JSONSlice[int]"}, + {Name: "TagTypes", DBName: "tag_types", GoType: "datatypes.JSONSlice[UserTagType]"}, }, } From 71f77492d010c136822f1cb9f54bc5e0f5240db1 Mon Sep 17 00:00:00 2001 From: fc221 Date: Thu, 27 Nov 2025 20:41:42 +0800 Subject: [PATCH 2/6] Fix generated user type is incorrect --- examples/output/models/user.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/output/models/user.go b/examples/output/models/user.go index eeba8b9..535ca2c 100644 --- a/examples/output/models/user.go +++ b/examples/output/models/user.go @@ -5,6 +5,7 @@ package models import ( "database/sql" + "gorm.io/cli/gorm/examples" "gorm.io/cli/gorm/examples/models" "gorm.io/cli/gorm/field" "gorm.io/datatypes" @@ -20,7 +21,7 @@ var User = struct { Age field.Number[int] Birthday field.Time Score field.Field[sql.NullInt64] - LastLogin field.Field[sql.NullTime] + LastLogin field.Time Account field.Struct[models.Account] Pets field.Slice[models.Pet] Toys field.Slice[models.Toy] @@ -33,7 +34,7 @@ var User = struct { Friends field.Slice[models.User] Role field.String IsAdult field.Bool - Profile field.String + Profile examples.JSON AwardTypes field.Struct[datatypes.JSONSlice[int]] TagTypes field.Struct[datatypes.JSONSlice[models.UserTagType]] }{ @@ -45,7 +46,7 @@ var User = struct { Age: field.Number[int]{}.WithColumn("age"), Birthday: field.Time{}.WithColumn("birthday"), Score: field.Field[sql.NullInt64]{}.WithColumn("score"), - LastLogin: field.Field[sql.NullTime]{}.WithColumn("last_login"), + LastLogin: field.Time{}.WithColumn("last_login"), Account: field.Struct[models.Account]{}.WithName("Account"), Pets: field.Slice[models.Pet]{}.WithName("Pets"), Toys: field.Slice[models.Toy]{}.WithName("Toys"), @@ -58,7 +59,7 @@ var User = struct { Friends: field.Slice[models.User]{}.WithName("Friends"), Role: field.String{}.WithColumn("role"), IsAdult: field.Bool{}.WithColumn("is_adult"), - Profile: field.String{}.WithColumn("profile"), + Profile: examples.JSON{}.WithColumn("profile"), AwardTypes: field.Struct[datatypes.JSONSlice[int]]{}.WithName("AwardTypes"), TagTypes: field.Struct[datatypes.JSONSlice[models.UserTagType]]{}.WithName("TagTypes"), } @@ -71,7 +72,7 @@ var Account = struct { UserID field.Field[sql.NullInt64] Number field.String RewardPoints field.Field[sql.NullInt64] - LastUsedAt field.Field[sql.NullTime] + LastUsedAt field.Time }{ ID: field.Number[uint]{}.WithColumn("id"), CreatedAt: field.Time{}.WithColumn("created_at"), @@ -80,7 +81,7 @@ var Account = struct { UserID: field.Field[sql.NullInt64]{}.WithColumn("user_id"), Number: field.String{}.WithColumn("number"), RewardPoints: field.Field[sql.NullInt64]{}.WithColumn("reward_points"), - LastUsedAt: field.Field[sql.NullTime]{}.WithColumn("last_used_at"), + LastUsedAt: field.Time{}.WithColumn("last_used_at"), } var Pet = struct { From d799c6a9190cd8eaa032488b8964dc82ec2fda17 Mon Sep 17 00:00:00 2001 From: fc221 Date: Thu, 27 Nov 2025 21:57:04 +0800 Subject: [PATCH 3/6] Add Custom enumeration type compatibility --- examples/models/user.go | 1 + examples/output/models/user.go | 2 ++ internal/gen/generator.go | 2 +- internal/gen/generator_test.go | 1 + internal/gen/utils.go | 8 ++++++++ 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/examples/models/user.go b/examples/models/user.go index 498a691..822b50e 100644 --- a/examples/models/user.go +++ b/examples/models/user.go @@ -39,6 +39,7 @@ type User struct { Profile string `gen:"json"` AwardTypes datatypes.JSONSlice[int] TagTypes datatypes.JSONSlice[UserTagType] + Tag UserTagType } type UserTagType string diff --git a/examples/output/models/user.go b/examples/output/models/user.go index 535ca2c..18ed157 100644 --- a/examples/output/models/user.go +++ b/examples/output/models/user.go @@ -36,6 +36,7 @@ var User = struct { IsAdult field.Bool Profile examples.JSON AwardTypes field.Struct[datatypes.JSONSlice[int]] + Tag field.Field[models.UserTagType] TagTypes field.Struct[datatypes.JSONSlice[models.UserTagType]] }{ ID: field.Number[uint]{}.WithColumn("id"), @@ -61,6 +62,7 @@ var User = struct { IsAdult: field.Bool{}.WithColumn("is_adult"), Profile: examples.JSON{}.WithColumn("profile"), AwardTypes: field.Struct[datatypes.JSONSlice[int]]{}.WithName("AwardTypes"), + Tag: field.Field[models.UserTagType]{}.WithColumn("tag"), TagTypes: field.Struct[datatypes.JSONSlice[models.UserTagType]]{}.WithName("TagTypes"), } diff --git a/internal/gen/generator.go b/internal/gen/generator.go index 8ad523a..c4bd922 100644 --- a/internal/gen/generator.go +++ b/internal/gen/generator.go @@ -466,7 +466,7 @@ func (f Field) Type() string { } if typ := loadNamedType(f.file.goModDir, f.file.getFullImportPath(pkgName), typName); typ != nil { - if ImplementsAllowedInterfaces(typ) { + if ImplementsAllowedInterfaces(typ) || IsUnderlyingComparable(typ) { return fmt.Sprintf("field.Field[%s]", filepath.Base(goType)) } } diff --git a/internal/gen/generator_test.go b/internal/gen/generator_test.go index 7a3aa03..f383343 100644 --- a/internal/gen/generator_test.go +++ b/internal/gen/generator_test.go @@ -180,6 +180,7 @@ func TestProcessStructType(t *testing.T) { {Name: "Profile", DBName: "profile", GoType: "string", NamedGoType: "json"}, {Name: "AwardTypes", DBName: "award_types", GoType: "datatypes.JSONSlice[int]"}, {Name: "TagTypes", DBName: "tag_types", GoType: "datatypes.JSONSlice[UserTagType]"}, + {Name: "Tag", DBName: "tag", GoType: "UserTagType"}, }, } diff --git a/internal/gen/utils.go b/internal/gen/utils.go index 88dc6d4..c67566c 100644 --- a/internal/gen/utils.go +++ b/internal/gen/utils.go @@ -73,6 +73,14 @@ func ImplementsAllowedInterfaces(typ types.Type) bool { return false } +func IsUnderlyingComparable(typ types.Type) bool { + underlying := typ.Underlying() + if _, ok := underlying.(*types.Struct); ok { + return false + } + return types.Comparable(underlying) +} + func findGoModDir(filename string) string { cmd := exec.Command("go", "env", "GOMOD") cmd.Dir = filepath.Dir(filename) From a62ba69b8f9a33e4f63a23e99a53277e70739922 Mon Sep 17 00:00:00 2001 From: fc221 Date: Fri, 28 Nov 2025 12:48:25 +0800 Subject: [PATCH 4/6] Refactor generic type processing and fix alias import issue --- examples/models/user.go | 3 +- examples/output/models/user.go | 4 +- internal/gen/generator.go | 120 +++++++++++++++------------------ internal/gen/utils.go | 24 +++++++ 4 files changed, 84 insertions(+), 67 deletions(-) diff --git a/examples/models/user.go b/examples/models/user.go index 822b50e..c39a758 100644 --- a/examples/models/user.go +++ b/examples/models/user.go @@ -6,6 +6,7 @@ import ( "gorm.io/cli/gorm/genconfig" "gorm.io/datatypes" + datatypes2 "gorm.io/datatypes" "gorm.io/gorm" ) @@ -38,7 +39,7 @@ type User struct { IsAdult bool `gorm:"column:is_adult"` Profile string `gen:"json"` AwardTypes datatypes.JSONSlice[int] - TagTypes datatypes.JSONSlice[UserTagType] + TagTypes datatypes2.JSONSlice[UserTagType] Tag UserTagType } diff --git a/examples/output/models/user.go b/examples/output/models/user.go index 18ed157..293c6c1 100644 --- a/examples/output/models/user.go +++ b/examples/output/models/user.go @@ -36,8 +36,8 @@ var User = struct { IsAdult field.Bool Profile examples.JSON AwardTypes field.Struct[datatypes.JSONSlice[int]] - Tag field.Field[models.UserTagType] TagTypes field.Struct[datatypes.JSONSlice[models.UserTagType]] + Tag field.Field[models.UserTagType] }{ ID: field.Number[uint]{}.WithColumn("id"), CreatedAt: field.Time{}.WithColumn("created_at"), @@ -62,8 +62,8 @@ var User = struct { IsAdult: field.Bool{}.WithColumn("is_adult"), Profile: examples.JSON{}.WithColumn("profile"), AwardTypes: field.Struct[datatypes.JSONSlice[int]]{}.WithName("AwardTypes"), - Tag: field.Field[models.UserTagType]{}.WithColumn("tag"), TagTypes: field.Struct[datatypes.JSONSlice[models.UserTagType]]{}.WithName("TagTypes"), + Tag: field.Field[models.UserTagType]{}.WithColumn("tag"), } var Account = struct { diff --git a/internal/gen/generator.go b/internal/gen/generator.go index c4bd922..2376cf5 100644 --- a/internal/gen/generator.go +++ b/internal/gen/generator.go @@ -435,9 +435,6 @@ func (f Field) Type() string { // Check if type implements allowed interfaces goType := strings.TrimPrefix(f.GoType, "*") - // Process generic type parameters to convert full paths to short names - goType = f.processGenericType(goType) - var ( pkgIdx int pkgName = f.file.Package @@ -465,21 +462,24 @@ func (f Field) Type() string { return fmt.Sprintf("field.Number[%s]", goType) } + // Process generic type parameters to convert full paths to short names + goType = f.processGenericType(goType) + if typ := loadNamedType(f.file.goModDir, f.file.getFullImportPath(pkgName), typName); typ != nil { if ImplementsAllowedInterfaces(typ) || IsUnderlyingComparable(typ) { - return fmt.Sprintf("field.Field[%s]", filepath.Base(goType)) + return fmt.Sprintf("field.Field[%s]", goType) } } // Check if this is a relation field based on its type if strings.HasPrefix(goType, "[]") { - elementType := filepath.Base(strings.TrimPrefix(goType, "[]")) + elementType := strings.TrimPrefix(goType, "[]") return fmt.Sprintf("field.Slice[%s]", elementType) } else if strings.Contains(goType, ".") { - return fmt.Sprintf("field.Struct[%s]", filepath.Base(goType)) + return fmt.Sprintf("field.Struct[%s]", goType) } - return fmt.Sprintf("field.Field[%s]", filepath.Base(goType)) + return fmt.Sprintf("field.Field[%s]", goType) } // processGenericType converts full package paths in generic type parameters to short names @@ -488,79 +488,62 @@ func (f Field) Type() string { // // -> "datatypes.JSONSlice[models.UserTagType]" func (f Field) processGenericType(goType string) string { - bracketIdx := strings.Index(goType, "[") - if bracketIdx == -1 { - return goType - } - - // Split into base type and type parameters - baseType := goType[:bracketIdx] - remaining := goType[bracketIdx+1:] - - // Find matching closing bracket - depth := 1 - endIdx := 0 - for i, ch := range remaining { - if ch == '[' { - depth++ - } else if ch == ']' { - depth-- - if depth == 0 { - endIdx = i - break - } - } - } + goType = strings.TrimSpace(goType) - if endIdx == 0 { - return goType + // Handle pointer types by recursively processing without the pointer prefix + if strings.HasPrefix(goType, "*") { + return f.processGenericType(goType[1:]) } - params := remaining[:endIdx] - suffix := remaining[endIdx+1:] - - // Process each type parameter - var processedParams []string - paramParts := strings.Split(params, ",") - - for _, param := range paramParts { - param = strings.TrimSpace(param) + // Handle slice types by recursively processing the element type + if strings.HasPrefix(goType, "[]") { + return "[]" + f.processGenericType(goType[2:]) + } - // Recursively process nested generics - param = f.processGenericType(param) + // Split the type into the main identifier and the generic arguments (separated by '[') + mainPart, argsPart, hasArgs := strings.Cut(goType, "[") - // Convert full package path to short name - if lastDot := strings.LastIndex(param, "."); lastDot > 0 { - fullPkgPath := param[:lastDot] - typeName := param[lastDot+1:] + // Resolve the package alias for the main type + shortMain := f.file.getImportAliasType(mainPart) - // Get or create short package name - shortName := filepath.Base(fullPkgPath) + // If generic arguments exist, process them recursively + if hasArgs { + // Remove the trailing closing bracket ']' from the arguments part + cleanArgs := strings.TrimSuffix(argsPart, "]") - // Ensure import exists - f.file.ensureImport(shortName, fullPkgPath) + // Split the arguments string by comma, respecting nested brackets + // e.g., "TypeA, Map[K,V]" -> ["TypeA", "Map[K,V]"] + args := splitGenericArgs(cleanArgs) - param = shortName + "." + typeName + var simplifiedArgs []string + for _, arg := range args { + simplifiedArgs = append(simplifiedArgs, f.processGenericType(arg)) } - processedParams = append(processedParams, param) + return shortMain + "[" + strings.Join(simplifiedArgs, ", ") + "]" } - return baseType + "[" + strings.Join(processedParams, ", ") + "]" + suffix + return shortMain } -// ensureImport adds an import if it doesn't already exist -func (p *File) ensureImport(name, path string) { - for _, imp := range p.Imports { - if imp.Path == path { - return - } +// getImportAliasType returns the import alias type string for a raw type string +// e.g., "datatypes2 gorm.io/datatypes.JSONSlice" -> "datatypes2.JSONSlice" +func (p *File) getImportAliasType(raw string) string { + lastDot := strings.LastIndex(raw, ".") + if lastDot == -1 { + return raw + } + + pathStr := raw[:lastDot] + typeName := raw[lastDot+1:] + + pkgName := filepath.Base(pathStr) + imp := p.getImport(pathStr) + if imp != nil { + pkgName = imp.Name } - p.Imports = append(p.Imports, Import{ - Name: name, - Path: path, - }) + return pkgName + "." + typeName } // Value returns the field value string with column name for template generation @@ -870,6 +853,15 @@ func (p *File) getFullImportPath(shortName string) string { return shortName } +func (p *File) getImport(path string) *Import { + for _, i := range p.Imports { + if i.Path == path { + return &i + } + } + return nil +} + // handleAnonymousEmbedding processes anonymous embedded fields and returns true if handled func (p *File) handleAnonymousEmbedding(field *ast.Field, pkgName string, s *Struct) bool { // Helper function to add fields from embedded struct diff --git a/internal/gen/utils.go b/internal/gen/utils.go index c67566c..ea736ac 100644 --- a/internal/gen/utils.go +++ b/internal/gen/utils.go @@ -210,3 +210,27 @@ func stripGeneric(s string) string { } return s } + +// splitGenericArgs splits a generic type argument string into individual arguments. +func splitGenericArgs(s string) []string { + var args []string + depth := 0 + start := 0 + for i, char := range s { + switch char { + case '[': + depth++ + case ']': + depth-- + case ',': + if depth == 0 { + args = append(args, s[start:i]) + start = i + 1 + } + } + } + if start < len(s) { + args = append(args, s[start:]) + } + return args +} From 3e2bee18033e87cfdddbf66f684ff284e91cc82c Mon Sep 17 00:00:00 2001 From: fc221 Date: Fri, 28 Nov 2025 12:58:03 +0800 Subject: [PATCH 5/6] Add Enum type and integrate into User struct --- examples/models/enum/enum.go | 3 +++ examples/models/enum/enum/enum.go | 3 +++ examples/models/user.go | 7 +++++-- 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 examples/models/enum/enum.go create mode 100644 examples/models/enum/enum/enum.go diff --git a/examples/models/enum/enum.go b/examples/models/enum/enum.go new file mode 100644 index 0000000..ad59f87 --- /dev/null +++ b/examples/models/enum/enum.go @@ -0,0 +1,3 @@ +package enum + +type Enum string diff --git a/examples/models/enum/enum/enum.go b/examples/models/enum/enum/enum.go new file mode 100644 index 0000000..ad59f87 --- /dev/null +++ b/examples/models/enum/enum/enum.go @@ -0,0 +1,3 @@ +package enum + +type Enum string diff --git a/examples/models/user.go b/examples/models/user.go index c39a758..40aab05 100644 --- a/examples/models/user.go +++ b/examples/models/user.go @@ -4,9 +4,10 @@ import ( "database/sql" "time" + "gorm.io/cli/gorm/examples/models/enum" + enum2 "gorm.io/cli/gorm/examples/models/enum/enum" "gorm.io/cli/gorm/genconfig" "gorm.io/datatypes" - datatypes2 "gorm.io/datatypes" "gorm.io/gorm" ) @@ -39,8 +40,10 @@ type User struct { IsAdult bool `gorm:"column:is_adult"` Profile string `gen:"json"` AwardTypes datatypes.JSONSlice[int] - TagTypes datatypes2.JSONSlice[UserTagType] + TagTypes datatypes.JSONSlice[UserTagType] Tag UserTagType + Enum enum.Enum + Enum2 enum2.Enum } type UserTagType string From 8598d83a59a98d4ef7fdf01fbeddc7ef7a018779 Mon Sep 17 00:00:00 2001 From: fc221 Date: Fri, 28 Nov 2025 13:00:23 +0800 Subject: [PATCH 6/6] Fix generator_test error --- internal/gen/generator_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/gen/generator_test.go b/internal/gen/generator_test.go index f383343..5f81aa5 100644 --- a/internal/gen/generator_test.go +++ b/internal/gen/generator_test.go @@ -181,6 +181,8 @@ func TestProcessStructType(t *testing.T) { {Name: "AwardTypes", DBName: "award_types", GoType: "datatypes.JSONSlice[int]"}, {Name: "TagTypes", DBName: "tag_types", GoType: "datatypes.JSONSlice[UserTagType]"}, {Name: "Tag", DBName: "tag", GoType: "UserTagType"}, + {Name: "Enum", DBName: "enum", GoType: "enum.Enum"}, // 添加 + {Name: "Enum2", DBName: "enum2", GoType: "enum2.Enum"}, }, }