diff --git a/example/pkg/database/generated_wrapper_mysql.go b/example/pkg/database/generated_wrapper_mysql.go index f2cf466..9c375b3 100644 --- a/example/pkg/database/generated_wrapper_mysql.go +++ b/example/pkg/database/generated_wrapper_mysql.go @@ -59,7 +59,7 @@ func (w *mysqlWrapper) CreateBook(ctx context.Context, arg CreateBookParams) (Bo return Book{}, err } - id, err := res.LastInsertID() + id, err := res.LastInsertId() if err != nil { return Book{}, err } @@ -89,7 +89,7 @@ func (w *mysqlWrapper) CreateTag(ctx context.Context, name string) (Tag, error) return Tag{}, err } - id, err := res.LastInsertID() + id, err := res.LastInsertId() if err != nil { return Tag{}, err } diff --git a/generator/helpers.go b/generator/helpers.go index 86c68af..56b79c1 100644 --- a/generator/helpers.go +++ b/generator/helpers.go @@ -92,11 +92,24 @@ func FixAcronyms(content []byte) []byte { // 3. Mid: `([a-z])(Acronym)([A-Z])` - acronym in middle of camelCase, e.g., Id in userIdMore. // 4. End: `([a-z])(Acronym)$` - acronym at end of identifier, e.g., Id in userId. // 5. NonLetter: `([a-z])(Acronym)([^A-Za-z])` - acronym followed by non-letter. + // For Id, we exclude '(' to avoid transforming method calls like LastInsertId(). regexStart := regexp.MustCompile(`^(` + a.pattern + `)([A-Z])`) regexAfterUpper := regexp.MustCompile(`([A-Z])(` + a.pattern + `)([A-Z])`) regexMid := regexp.MustCompile(`([a-z])(` + a.pattern + `)([A-Z])`) regexEnd := regexp.MustCompile(`([a-z])(` + a.pattern + `)$`) - regexNonLetter := regexp.MustCompile(`([a-z])(` + a.pattern + `)([^A-Za-z])`) + + // For Id, exclude '(' to preserve method calls like res.LastInsertId() + // For Url, exclude ':' and ',' to preserve struct field names like NewUrl, OldUrl + nonLetterClass := `[^A-Za-z]` + + switch a.pattern { + case "Id": + nonLetterClass = `[^A-Za-z(]` + case "Url": + nonLetterClass = `[^A-Za-z:,]` + } + + regexNonLetter := regexp.MustCompile(`([a-z])(` + a.pattern + `)(` + nonLetterClass + `)`) // Start case: replace with replacement followed by ${2} (the uppercase after). result = regexStart.ReplaceAllString(result, a.replacement+"${2}") @@ -124,7 +137,7 @@ func writeFile(dir, filename string, content []byte) { // 2. Format with gofumpt formatted, err := format.Source(withImports, format.Options{ LangVersion: "", - ExtraRules: true, + ExtraRules: false, }) if err != nil { log.Println(string(withImports)) diff --git a/generator/helpers_test.go b/generator/helpers_test.go index aebbbc2..3a90822 100644 --- a/generator/helpers_test.go +++ b/generator/helpers_test.go @@ -109,6 +109,36 @@ func TestFixAcronyms(t *testing.T) { input: "", expected: "", }, + { + name: "LastInsertId in method call should not be transformed", + input: "res.LastInsertId()", + expected: "res.LastInsertId()", + }, + { + name: "SetId in method call should not be transformed", + input: "obj.SetId(123)", + expected: "obj.SetId(123)", + }, + { + name: "userId in variable assignment should become userID", + input: "userId = 123", + expected: "userID = 123", + }, + { + name: "NewUrl in struct literal should remain NewUrl", + input: "NewUrl: \"value\"", + expected: "NewUrl: \"value\"", + }, + { + name: "OldUrl in struct literal should remain OldUrl", + input: "OldUrl: \"value\"", + expected: "OldUrl: \"value\"", + }, + { + name: "profileUrl in assignment should become profileURL", + input: "profileUrl = \"https://example.com\"", + expected: "profileURL = \"https://example.com\"", + }, } for _, tt := range tests {