From 58adb4b2a6d07e18e87bdf2c33848d01bc3a2c44 Mon Sep 17 00:00:00 2001 From: jdl Date: Thu, 25 Jun 2026 13:35:41 +0200 Subject: [PATCH] Cleanup / audit --- gen.go.tmpl | 16 +++++----------- parse.go | 32 ++++++++++++++++++++++++++------ template.go | 19 +++++++++++-------- test-files/TestParse/000.json | 1 + test-files/TestParse/001.json | 1 + test-files/TestParse/002.json | 1 + test-files/TestParse/003.json | 2 ++ test-files/TestParse/004.json | 2 ++ 8 files changed, 49 insertions(+), 25 deletions(-) diff --git a/gen.go.tmpl b/gen.go.tmpl index dd96006..803e1b4 100644 --- a/gen.go.tmpl +++ b/gen.go.tmpl @@ -139,14 +139,11 @@ func {{.LowerType}}_Get( tx TX, {{.PKFunctionArgs -}} ) ( - row *{{.Type}}, + row {{.Type}}, err error, ) { - row = &{{.Type}}{} r := tx.QueryRow("{{.GetQuery}}", {{.DeleteArgs}}) - if err = r.Scan({{.ScanArgs}}); err != nil { - row = nil - } + err = r.Scan({{.ScanArgs}}) return } @@ -155,14 +152,11 @@ func {{.LowerType}}_GetWhere( query string, args ...any, ) ( - row *{{.Type}}, + row {{.Type}}, err error, ) { - row = &{{.Type}}{} r := tx.QueryRow(query, args...) - if err = r.Scan({{.ScanArgs}}); err != nil { - row = nil - } + err = r.Scan({{.ScanArgs}}) return } @@ -176,7 +170,7 @@ func {{.LowerType}}_Iterate( rows, err := tx.Query(query, args...) if err != nil { return func(yield func({{.Type}}, error) bool) { - yield(nil, err) + yield({{.Type}}{}, err) } } diff --git a/parse.go b/parse.go index 1fd60fe..1693e86 100644 --- a/parse.go +++ b/parse.go @@ -77,7 +77,14 @@ func parseTable(driver string, schema *schema, tokens []string) ([]string, error table.NoDelete = true tokens = tokens[1:] case "(": - return parseTableBody(table, tokens[1:]) + tokens, err := parseTableBody(table, tokens[1:]) + if err != nil { + return tokens, err + } + if len(table.pkCols()) == 0 { + return tokens, errors.New("table " + table.Name + " has no PK column") + } + return tokens, nil default: return tokens, errors.New("unexpected token in table definition: " + tokens[0]) } @@ -87,17 +94,25 @@ func parseTable(driver string, schema *schema, tokens []string) ([]string, error } func parseTableBody(table *table, tokens []string) ([]string, error) { - var err error + if len(tokens) > 0 && tokens[0] == ")" { + return tokens, errors.New("empty table body") + } - for len(tokens) > 0 && tokens[0] != ";" { + var err error + for len(tokens) > 0 && tokens[0] != ")" { tokens, err = parseTableColumn(table, tokens) if err != nil { return tokens, err } } - if len(tokens) < 1 || tokens[0] != ";" { - return tokens, errors.New("incomplete table column definitions") + if len(tokens) == 0 || tokens[0] != ")" { + return tokens, errors.New("missing closing ) in table definition") + } + tokens = tokens[1:] // consume ")" + + if len(tokens) == 0 || tokens[0] != ";" { + return tokens, errors.New("missing ; after table definition") } return tokens[1:], nil @@ -141,5 +156,10 @@ func parseTableColumn(table *table, tokens []string) ([]string, error) { return tokens, errors.New("incomplete column definition") } - return tokens[1:], nil + // Leave the closing ")" for parseTableBody; consume a "," separator. + // A trailing comma before ")" is allowed. + if tokens[0] == "," { + return tokens[1:], nil + } + return tokens, nil } diff --git a/template.go b/template.go index 19dc50e..e92ec81 100644 --- a/template.go +++ b/template.go @@ -1,9 +1,11 @@ package sqlgen import ( + "bytes" _ "embed" + "fmt" + "go/format" "os" - "os/exec" "path/filepath" "text/template" ) @@ -22,13 +24,9 @@ func render(driver, schemaPath, outputPath string) (err error) { } tmpl := template.Must(template.New("").Parse(fileTemplate)) - fOut, err := os.Create(outputPath) - if err != nil { - return err - } - defer fOut.Close() - err = tmpl.Execute(fOut, struct { + buf := &bytes.Buffer{} + err = tmpl.Execute(buf, struct { PackageName string Schema *schema }{filepath.Base(filepath.Dir(outputPath)), sch}) @@ -36,5 +34,10 @@ func render(driver, schemaPath, outputPath string) (err error) { return err } - return exec.Command("gofmt", "-w", outputPath).Run() + formatted, err := format.Source(buf.Bytes()) + if err != nil { + return fmt.Errorf("formatting generated code: %w", err) + } + + return os.WriteFile(outputPath, formatted, 0o644) } diff --git a/test-files/TestParse/000.json b/test-files/TestParse/000.json index 596727c..3e59a70 100644 --- a/test-files/TestParse/000.json +++ b/test-files/TestParse/000.json @@ -3,6 +3,7 @@ { "Name": "users", "Type": "User", + "LowerType": "user", "NoDelete": true, "Columns": [ { diff --git a/test-files/TestParse/001.json b/test-files/TestParse/001.json index ded27f4..d8090d4 100644 --- a/test-files/TestParse/001.json +++ b/test-files/TestParse/001.json @@ -3,6 +3,7 @@ { "Name": "users", "Type": "User", + "LowerType": "user", "NoDelete": true, "Columns": [ { diff --git a/test-files/TestParse/002.json b/test-files/TestParse/002.json index 2693687..d35bb35 100644 --- a/test-files/TestParse/002.json +++ b/test-files/TestParse/002.json @@ -3,6 +3,7 @@ { "Name": "users", "Type": "User", + "LowerType": "user", "NoDelete": true, "Columns": [ { diff --git a/test-files/TestParse/003.json b/test-files/TestParse/003.json index 110d1fb..0e06aa9 100644 --- a/test-files/TestParse/003.json +++ b/test-files/TestParse/003.json @@ -3,6 +3,7 @@ { "Name": "users", "Type": "User", + "LowerType": "user", "NoDelete": true, "Columns": [ { @@ -35,6 +36,7 @@ { "Name": "users_view", "Type": "UserView", + "LowerType": "userView", "NoInsert": true, "NoUpdate": true, "NoDelete": true, diff --git a/test-files/TestParse/004.json b/test-files/TestParse/004.json index 088f931..dc15fcd 100644 --- a/test-files/TestParse/004.json +++ b/test-files/TestParse/004.json @@ -3,6 +3,7 @@ { "Name": "users", "Type": "User", + "LowerType": "user", "NoDelete": true, "Columns": [ { @@ -40,6 +41,7 @@ { "Name": "users_view", "Type": "UserView", + "LowerType": "userView", "NoInsert": true, "NoUpdate": true, "NoDelete": true,