From de8ae610ebb2a38f5c58aa4df85fa73b91aa2076 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..9410c5f1cb 100644 --- a/docs/reference/config.md +++ b/docs/reference/config.md @@ -165,6 +165,8 @@ The `gen` mapping supports the following keys: that returns all valid enum values. - `build_tags`: - If set, add a `//go:build ` directive at the beginning of each generated Go file. +- `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`. - `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 7325520e78..ee338befee 100644 --- a/internal/codegen/golang/opts/options.go +++ b/internal/codegen/golang/opts/options.go @@ -42,6 +42,7 @@ 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"` + EmitSqlAsComment bool `json:"emit_sql_as_comment,omitempty" yaml:"emit_sql_as_comment"` } type GlobalOptions struct { 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..b9aa4032f5 100644 --- a/internal/config/v_one.go +++ b/internal/config/v_one.go @@ -58,6 +58,7 @@ type v1PackageSettings struct { OmitUnusedStructs bool `json:"omit_unused_structs,omitempty" yaml:"omit_unused_structs"` Rules []string `json:"rules" yaml:"rules"` BuildTags string `json:"build_tags,omitempty" yaml:"build_tags"` + EmitSqlAsComment bool `json:"emit_sql_as_comment,omitempty" yaml:"emit_sql_as_comment"` } func v1ParseConfig(rd io.Reader) (Config, error) { @@ -166,6 +167,7 @@ func (c *V1GenerateSettings) Translate() Config { OmitSqlcVersion: pkg.OmitSqlcVersion, OmitUnusedStructs: pkg.OmitUnusedStructs, BuildTags: pkg.BuildTags, + EmitSqlAsComment: pkg.EmitSqlAsComment, }, }, StrictFunctionChecks: pkg.StrictFunctionChecks, diff --git a/internal/config/v_one.json b/internal/config/v_one.json index 166888ab93..47a743ef92 100644 --- a/internal/config/v_one.json +++ b/internal/config/v_one.json @@ -134,6 +134,9 @@ "build_tags": { "type": "string" }, + "emit_sql_as_comment": { + "type": "boolean" + }, "json_tags_case_style": { "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..64965409e8 100644 --- a/internal/config/v_two.json +++ b/internal/config/v_two.json @@ -143,6 +143,9 @@ "build_tags": { "type": "string" }, + "emit_sql_as_comment": { + "type": "boolean" + }, "json_tags_case_style": { "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": "",