From db0157bc2552831bdb84711d9630cda45406530c Mon Sep 17 00:00:00 2001 From: Jason Cabot Date: Fri, 15 Sep 2023 11:35:12 +0100 Subject: [PATCH] Add `emit_sql_as_comment` option to Go code plugin This option adds the raw SQL query as a comment to the generated query function This is useful when working in an IDE that displays comments over functions, you are able to glance at the actual SQL query that will be executed without having to lose context of where you are in the current file you are working on. --- docs/reference/config.md | 2 + internal/codegen/golang/opts/options.go | 1 + internal/codegen/golang/result.go | 13 ++++- internal/config/v_one.go | 2 + internal/config/v_one.json | 5 +- internal/config/v_two.json | 3 + .../emit_sql_as_comment/stdlib/go/db.go | 31 ++++++++++ .../emit_sql_as_comment/stdlib/go/models.go | 11 ++++ .../stdlib/go/query.sql.go | 56 +++++++++++++++++++ .../emit_sql_as_comment/stdlib/query.sql | 10 ++++ .../emit_sql_as_comment/stdlib/sqlc.json | 12 ++++ .../process_plugin_disabled/gen/codegen.json | 3 +- 12 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 internal/endtoend/testdata/emit_sql_as_comment/stdlib/go/db.go create mode 100644 internal/endtoend/testdata/emit_sql_as_comment/stdlib/go/models.go create mode 100644 internal/endtoend/testdata/emit_sql_as_comment/stdlib/go/query.sql.go create mode 100644 internal/endtoend/testdata/emit_sql_as_comment/stdlib/query.sql create mode 100644 internal/endtoend/testdata/emit_sql_as_comment/stdlib/sqlc.json diff --git a/docs/reference/config.md b/docs/reference/config.md index a05367436d..6f5136e41b 100644 --- a/docs/reference/config.md +++ b/docs/reference/config.md @@ -163,6 +163,8 @@ The `gen` mapping supports the following keys: - `emit_all_enum_values`: - If true, emit a function per enum type that returns all valid enum values. +- `emit_sql_as_comment`: + - 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. - `json_tags_id_uppercase`: diff --git a/internal/codegen/golang/opts/options.go b/internal/codegen/golang/opts/options.go index 7325520e78..0b66975506 100644 --- a/internal/codegen/golang/opts/options.go +++ b/internal/codegen/golang/opts/options.go @@ -24,6 +24,7 @@ type Options struct { EmitPointersForNullTypes bool `json:"emit_pointers_for_null_types" yaml:"emit_pointers_for_null_types"` EmitEnumValidMethod bool `json:"emit_enum_valid_method,omitempty" yaml:"emit_enum_valid_method"` EmitAllEnumValues bool `json:"emit_all_enum_values,omitempty" yaml:"emit_all_enum_values"` + EmitSqlAsComment bool `json:"emit_sql_as_comment,omitempty" yaml:"emit_sql_as_comment"` JsonTagsCaseStyle string `json:"json_tags_case_style,omitempty" yaml:"json_tags_case_style"` Package string `json:"package" yaml:"package"` Out string `json:"out" yaml:"out"` diff --git a/internal/codegen/golang/result.go b/internal/codegen/golang/result.go index 787329dea1..475d55ae09 100644 --- a/internal/codegen/golang/result.go +++ b/internal/codegen/golang/result.go @@ -199,6 +199,17 @@ func buildQueries(req *plugin.GenerateRequest, options *opts.Options, structs [] constantName = sdk.LowerTitle(query.Name) } + comments := query.Comments + if options.EmitSqlAsComment { + if len(comments) == 0 { + comments = append(comments, query.Name) + } + comments = append(comments, " ") + for _, line := range strings.Split(query.Text, "\n") { + comments = append(comments, " "+line) + } + } + gq := Query{ Cmd: query.Cmd, ConstantName: constantName, @@ -206,7 +217,7 @@ func buildQueries(req *plugin.GenerateRequest, options *opts.Options, structs [] MethodName: query.Name, SourceName: query.Filename, SQL: query.Text, - Comments: query.Comments, + Comments: comments, Table: query.InsertIntoTable, } sqlpkg := parseDriver(options.SqlPackage) diff --git a/internal/config/v_one.go b/internal/config/v_one.go index 17c4fcffa8..8efa9f42fc 100644 --- a/internal/config/v_one.go +++ b/internal/config/v_one.go @@ -41,6 +41,7 @@ type v1PackageSettings struct { EmitPointersForNullTypes bool `json:"emit_pointers_for_null_types" yaml:"emit_pointers_for_null_types"` EmitEnumValidMethod bool `json:"emit_enum_valid_method,omitempty" yaml:"emit_enum_valid_method"` EmitAllEnumValues bool `json:"emit_all_enum_values,omitempty" yaml:"emit_all_enum_values"` + EmitSqlAsComment bool `json:"emit_sql_as_comment,omitempty" yaml:"emit_sql_as_comment"` JSONTagsCaseStyle string `json:"json_tags_case_style,omitempty" yaml:"json_tags_case_style"` SQLPackage string `json:"sql_package" yaml:"sql_package"` SQLDriver string `json:"sql_driver" yaml:"sql_driver"` @@ -150,6 +151,7 @@ func (c *V1GenerateSettings) Translate() Config { EmitPointersForNullTypes: pkg.EmitPointersForNullTypes, EmitEnumValidMethod: pkg.EmitEnumValidMethod, EmitAllEnumValues: pkg.EmitAllEnumValues, + EmitSqlAsComment: pkg.EmitSqlAsComment, Package: pkg.Name, Out: pkg.Path, SqlPackage: pkg.SQLPackage, diff --git a/internal/config/v_one.json b/internal/config/v_one.json index 166888ab93..a0667a7c9c 100644 --- a/internal/config/v_one.json +++ b/internal/config/v_one.json @@ -131,6 +131,9 @@ "emit_all_enum_values": { "type": "boolean" }, + "emit_sql_as_comment": { + "type": "boolean" + }, "build_tags": { "type": "string" }, @@ -340,4 +343,4 @@ } } } -} \ No newline at end of file +} diff --git a/internal/config/v_two.json b/internal/config/v_two.json index dd39fddc10..acf914997d 100644 --- a/internal/config/v_two.json +++ b/internal/config/v_two.json @@ -140,6 +140,9 @@ "emit_all_enum_values": { "type": "boolean" }, + "emit_sql_as_comment": { + "type": "boolean" + }, "build_tags": { "type": "string" }, diff --git a/internal/endtoend/testdata/emit_sql_as_comment/stdlib/go/db.go b/internal/endtoend/testdata/emit_sql_as_comment/stdlib/go/db.go new file mode 100644 index 0000000000..7cd3a57354 --- /dev/null +++ b/internal/endtoend/testdata/emit_sql_as_comment/stdlib/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.24.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/emit_sql_as_comment/stdlib/go/models.go b/internal/endtoend/testdata/emit_sql_as_comment/stdlib/go/models.go new file mode 100644 index 0000000000..919d2b7238 --- /dev/null +++ b/internal/endtoend/testdata/emit_sql_as_comment/stdlib/go/models.go @@ -0,0 +1,11 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.24.0 + +package querytest + +import () + +type Bar struct { + ID int32 +} diff --git a/internal/endtoend/testdata/emit_sql_as_comment/stdlib/go/query.sql.go b/internal/endtoend/testdata/emit_sql_as_comment/stdlib/go/query.sql.go new file mode 100644 index 0000000000..7f1c9097d5 --- /dev/null +++ b/internal/endtoend/testdata/emit_sql_as_comment/stdlib/go/query.sql.go @@ -0,0 +1,56 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.24.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const listBar = `-- name: ListBar :many +SELECT id FROM ( + SELECT id FROM bar +) bar +` + +// Lists all bars +// +// SELECT id FROM ( +// SELECT id FROM bar +// ) bar +func (q *Queries) ListBar(ctx context.Context) ([]int32, error) { + rows, err := q.db.QueryContext(ctx, listBar) + if err != nil { + return nil, err + } + defer rows.Close() + var items []int32 + for rows.Next() { + var id int32 + if err := rows.Scan(&id); err != nil { + return nil, err + } + items = append(items, id) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const removeBar = `-- name: RemoveBar :exec +DELETE FROM bar WHERE id = $1 +` + +// RemoveBar +// +// DELETE FROM bar WHERE id = $1 +func (q *Queries) RemoveBar(ctx context.Context, id int32) error { + _, err := q.db.ExecContext(ctx, removeBar, id) + return err +} diff --git a/internal/endtoend/testdata/emit_sql_as_comment/stdlib/query.sql b/internal/endtoend/testdata/emit_sql_as_comment/stdlib/query.sql new file mode 100644 index 0000000000..2cf6edbfa2 --- /dev/null +++ b/internal/endtoend/testdata/emit_sql_as_comment/stdlib/query.sql @@ -0,0 +1,10 @@ +CREATE TABLE bar (id serial not null); + +-- name: ListBar :many +-- Lists all bars +SELECT id FROM ( + SELECT * FROM bar +) bar; + +-- name: RemoveBar :exec +DELETE FROM bar WHERE id = $1; diff --git a/internal/endtoend/testdata/emit_sql_as_comment/stdlib/sqlc.json b/internal/endtoend/testdata/emit_sql_as_comment/stdlib/sqlc.json new file mode 100644 index 0000000000..fa5408afdf --- /dev/null +++ b/internal/endtoend/testdata/emit_sql_as_comment/stdlib/sqlc.json @@ -0,0 +1,12 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "name": "querytest", + "schema": "query.sql", + "queries": "query.sql", + "emit_sql_as_comment": true + } + ] +} diff --git a/internal/endtoend/testdata/process_plugin_disabled/gen/codegen.json b/internal/endtoend/testdata/process_plugin_disabled/gen/codegen.json index 5b460f31b0..acb45343e7 100644 --- a/internal/endtoend/testdata/process_plugin_disabled/gen/codegen.json +++ b/internal/endtoend/testdata/process_plugin_disabled/gen/codegen.json @@ -43,7 +43,8 @@ "query_parameter_limit": 1, "output_batch_file_name": "", "json_tags_id_uppercase": false, - "omit_unused_structs": false + "omit_unused_structs": false, + "emit_sql_as_comment": false }, "json": { "out": "",