From d5aa1c536bc4a0a18654d76e20c08ffcf8598368 Mon Sep 17 00:00:00 2001 From: Rollulus Date: Thu, 8 Sep 2022 19:06:33 +0200 Subject: [PATCH] fix: Let column names not result in invalid Go field names Column names are less restricted than Go struct field names, which should be proper Go identifiers. Hence, column names cannot be translated directly into field names. This commit tries to address this. Characters in column names that do not qualify as a Go identifier are stripped. The title casing as applied to underscores is applied to stripped characters. --- internal/codegen/golang/struct.go | 9 ++++++ .../stdlib/README.md | 1 + .../stdlib/go/db.go | 31 +++++++++++++++++++ .../stdlib/go/models.go | 15 +++++++++ .../stdlib/go/query.sql.go | 21 +++++++++++++ .../stdlib/query.sql | 7 +++++ .../stdlib/sqlc.json | 11 +++++++ 7 files changed, 95 insertions(+) create mode 100644 internal/endtoend/testdata/codegen_struct_field_names/stdlib/README.md create mode 100644 internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/db.go create mode 100644 internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/models.go create mode 100644 internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/query.sql.go create mode 100644 internal/endtoend/testdata/codegen_struct_field_names/stdlib/query.sql create mode 100644 internal/endtoend/testdata/codegen_struct_field_names/stdlib/sqlc.json diff --git a/internal/codegen/golang/struct.go b/internal/codegen/golang/struct.go index f72a228ae3..e0f97caf97 100644 --- a/internal/codegen/golang/struct.go +++ b/internal/codegen/golang/struct.go @@ -20,6 +20,15 @@ func StructName(name string, settings *plugin.Settings) string { return rename } out := "" + name = strings.Map(func(r rune) rune { + if unicode.IsLetter(r) { + return r + } + if unicode.IsDigit(r) { + return r + } + return rune('_') + }, name) for _, p := range strings.Split(name, "_") { if p == "id" { out += "ID" diff --git a/internal/endtoend/testdata/codegen_struct_field_names/stdlib/README.md b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/README.md new file mode 100644 index 0000000000..910e4f711f --- /dev/null +++ b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/README.md @@ -0,0 +1 @@ +This tests that Go struct field names are proper Go identifiers. \ No newline at end of file diff --git a/internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/db.go b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/db.go new file mode 100644 index 0000000000..5f69347d4b --- /dev/null +++ b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.15.0 + +package querytest + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/models.go b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/models.go new file mode 100644 index 0000000000..6f927007f9 --- /dev/null +++ b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/models.go @@ -0,0 +1,15 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.15.0 + +package querytest + +import ( + "database/sql" +) + +type Bar struct { + ID int32 + NobodyWouldBelieveThis sql.NullInt32 + ParentID sql.NullInt32 +} diff --git a/internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/query.sql.go b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/query.sql.go new file mode 100644 index 0000000000..1d589fcac6 --- /dev/null +++ b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/query.sql.go @@ -0,0 +1,21 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.15.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const test = `-- name: test :one +SELECT id, !!!nobody,_,-would-believe---this-...?!, parent id from bar limit 1 +` + +func (q *Queries) test(ctx context.Context) (Bar, error) { + row := q.db.QueryRowContext(ctx, test) + var i Bar + err := row.Scan(&i.ID, &i.NobodyWouldBelieveThis, &i.ParentID) + return i, err +} diff --git a/internal/endtoend/testdata/codegen_struct_field_names/stdlib/query.sql b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/query.sql new file mode 100644 index 0000000000..853a207ad8 --- /dev/null +++ b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/query.sql @@ -0,0 +1,7 @@ +CREATE TABLE bar ( + id INT NOT NULL, + "!!!nobody,_,-would-believe---this-...?!" INT, + "parent id" INT); + +-- name: test :one +SELECT * from bar limit 1; diff --git a/internal/endtoend/testdata/codegen_struct_field_names/stdlib/sqlc.json b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/sqlc.json new file mode 100644 index 0000000000..bc05cb0384 --- /dev/null +++ b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/sqlc.json @@ -0,0 +1,11 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "name": "querytest", + "schema": "query.sql", + "queries": "query.sql" + } + ] +} \ No newline at end of file