diff --git a/docs/reference/config.md b/docs/reference/config.md index 85e68cf05b..9e9910190a 100644 --- a/docs/reference/config.md +++ b/docs/reference/config.md @@ -167,6 +167,8 @@ The `gen` mapping supports the following keys: - If true, emits the SQL statement as a code-block comment above the generated function, appending to any existing comments. Defaults to `false`. - `build_tags`: - If set, add a `//go:build ` directive at the beginning of each generated Go file. +- `initialisms`: + - An array of [initialisms](https://google.github.io/styleguide/go/decisions.html#initialisms) to upper-case. For example, `app_id` becomes `AppID`. Defaults to `["id"]`. - `json_tags_id_uppercase`: - If true, "Id" in json tags will be uppercase. If false, will be camelcase. Defaults to `false` - `json_tags_case_style`: diff --git a/internal/codegen/golang/opts/options.go b/internal/codegen/golang/opts/options.go index 0e2a8562e5..30a6c2246c 100644 --- a/internal/codegen/golang/opts/options.go +++ b/internal/codegen/golang/opts/options.go @@ -43,6 +43,9 @@ type Options struct { OmitSqlcVersion bool `json:"omit_sqlc_version,omitempty" yaml:"omit_sqlc_version"` OmitUnusedStructs bool `json:"omit_unused_structs,omitempty" yaml:"omit_unused_structs"` BuildTags string `json:"build_tags,omitempty" yaml:"build_tags"` + Initialisms *[]string `json:"initialisms,omitempty" yaml:"initialisms"` + + InitialismsMap map[string]struct{} `json:"-" yaml:"-"` } type GlobalOptions struct { @@ -111,6 +114,16 @@ func parseOpts(req *plugin.GenerateRequest) (*Options, error) { *options.QueryParameterLimit = 1 } + if options.Initialisms == nil { + options.Initialisms = new([]string) + *options.Initialisms = []string{"id"} + } + + options.InitialismsMap = map[string]struct{}{} + for _, initial := range *options.Initialisms { + options.InitialismsMap[initial] = struct{}{} + } + return &options, nil } diff --git a/internal/codegen/golang/struct.go b/internal/codegen/golang/struct.go index 322dd71bf6..ed9311800e 100644 --- a/internal/codegen/golang/struct.go +++ b/internal/codegen/golang/struct.go @@ -32,8 +32,8 @@ func StructName(name string, options *opts.Options) string { }, name) for _, p := range strings.Split(name, "_") { - if p == "id" { - out += "ID" + if _, found := options.InitialismsMap[p]; found { + out += strings.ToUpper(p) } else { out += strings.Title(p) } diff --git a/internal/endtoend/testdata/golang_initialisms_empty/db/db.go b/internal/endtoend/testdata/golang_initialisms_empty/db/db.go new file mode 100644 index 0000000000..17d86e9304 --- /dev/null +++ b/internal/endtoend/testdata/golang_initialisms_empty/db/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.26.0 + +package db + +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/golang_initialisms_empty/db/models.go b/internal/endtoend/testdata/golang_initialisms_empty/db/models.go new file mode 100644 index 0000000000..e442271ec4 --- /dev/null +++ b/internal/endtoend/testdata/golang_initialisms_empty/db/models.go @@ -0,0 +1,13 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.26.0 + +package db + +import ( + "database/sql" +) + +type Foo struct { + BarId sql.NullString +} diff --git a/internal/endtoend/testdata/golang_initialisms_empty/db/query.sql.go b/internal/endtoend/testdata/golang_initialisms_empty/db/query.sql.go new file mode 100644 index 0000000000..a36ef225d7 --- /dev/null +++ b/internal/endtoend/testdata/golang_initialisms_empty/db/query.sql.go @@ -0,0 +1,38 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.26.0 +// source: query.sql + +package db + +import ( + "context" + "database/sql" +) + +const selectFoo = `-- name: SelectFoo :many +SELECT bar_id FROM foo +` + +func (q *Queries) SelectFoo(ctx context.Context) ([]sql.NullString, error) { + rows, err := q.db.QueryContext(ctx, selectFoo) + if err != nil { + return nil, err + } + defer rows.Close() + var items []sql.NullString + for rows.Next() { + var bar_id sql.NullString + if err := rows.Scan(&bar_id); err != nil { + return nil, err + } + items = append(items, bar_id) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/golang_initialisms_empty/query.sql b/internal/endtoend/testdata/golang_initialisms_empty/query.sql new file mode 100644 index 0000000000..e32e926b32 --- /dev/null +++ b/internal/endtoend/testdata/golang_initialisms_empty/query.sql @@ -0,0 +1,2 @@ +-- name: SelectFoo :many +SELECT * FROM foo; diff --git a/internal/endtoend/testdata/golang_initialisms_empty/schema.sql b/internal/endtoend/testdata/golang_initialisms_empty/schema.sql new file mode 100644 index 0000000000..fe692b6af6 --- /dev/null +++ b/internal/endtoend/testdata/golang_initialisms_empty/schema.sql @@ -0,0 +1,3 @@ +CREATE TABLE foo( + bar_id text +); diff --git a/internal/endtoend/testdata/golang_initialisms_empty/sqlc.json b/internal/endtoend/testdata/golang_initialisms_empty/sqlc.json new file mode 100644 index 0000000000..02ab2e395c --- /dev/null +++ b/internal/endtoend/testdata/golang_initialisms_empty/sqlc.json @@ -0,0 +1,16 @@ +{ + "version": "2", + "sql": [ + { + "schema": "schema.sql", + "queries": "query.sql", + "engine": "postgresql", + "gen": { + "go": { + "out": "db", + "initialisms": [] + } + } + } + ] +} diff --git a/internal/endtoend/testdata/golang_initialisms_url/db/db.go b/internal/endtoend/testdata/golang_initialisms_url/db/db.go new file mode 100644 index 0000000000..17d86e9304 --- /dev/null +++ b/internal/endtoend/testdata/golang_initialisms_url/db/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.26.0 + +package db + +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/golang_initialisms_url/db/models.go b/internal/endtoend/testdata/golang_initialisms_url/db/models.go new file mode 100644 index 0000000000..63087f994e --- /dev/null +++ b/internal/endtoend/testdata/golang_initialisms_url/db/models.go @@ -0,0 +1,14 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.26.0 + +package db + +import ( + "database/sql" +) + +type Foo struct { + BarID sql.NullString + SiteURL sql.NullString +} diff --git a/internal/endtoend/testdata/golang_initialisms_url/db/query.sql.go b/internal/endtoend/testdata/golang_initialisms_url/db/query.sql.go new file mode 100644 index 0000000000..86f3251b25 --- /dev/null +++ b/internal/endtoend/testdata/golang_initialisms_url/db/query.sql.go @@ -0,0 +1,37 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.26.0 +// source: query.sql + +package db + +import ( + "context" +) + +const selectFoo = `-- name: SelectFoo :many +SELECT bar_id, site_url FROM foo +` + +func (q *Queries) SelectFoo(ctx context.Context) ([]Foo, error) { + rows, err := q.db.QueryContext(ctx, selectFoo) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Foo + for rows.Next() { + var i Foo + if err := rows.Scan(&i.BarID, &i.SiteURL); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/golang_initialisms_url/query.sql b/internal/endtoend/testdata/golang_initialisms_url/query.sql new file mode 100644 index 0000000000..e32e926b32 --- /dev/null +++ b/internal/endtoend/testdata/golang_initialisms_url/query.sql @@ -0,0 +1,2 @@ +-- name: SelectFoo :many +SELECT * FROM foo; diff --git a/internal/endtoend/testdata/golang_initialisms_url/schema.sql b/internal/endtoend/testdata/golang_initialisms_url/schema.sql new file mode 100644 index 0000000000..83ab160129 --- /dev/null +++ b/internal/endtoend/testdata/golang_initialisms_url/schema.sql @@ -0,0 +1,4 @@ +CREATE TABLE foo( + bar_id text, + site_url text +); diff --git a/internal/endtoend/testdata/golang_initialisms_url/sqlc.json b/internal/endtoend/testdata/golang_initialisms_url/sqlc.json new file mode 100644 index 0000000000..2b135eec3e --- /dev/null +++ b/internal/endtoend/testdata/golang_initialisms_url/sqlc.json @@ -0,0 +1,16 @@ +{ + "version": "2", + "sql": [ + { + "schema": "schema.sql", + "queries": "query.sql", + "engine": "postgresql", + "gen": { + "go": { + "out": "db", + "initialisms": ["id", "url"] + } + } + } + ] +}