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": "",