From d0199594ea9f8592b0836c21dcf30ba4db2d392e Mon Sep 17 00:00:00 2001 From: Dmitriy Chertkov Date: Wed, 21 Apr 2021 21:53:20 +0500 Subject: [PATCH 1/3] Add emit_result_struct_pointers and emit_params_struct_pointers options for Go generator --- internal/codegen/golang/gen.go | 16 ++-- internal/codegen/golang/query.go | 17 ++++- internal/codegen/golang/result.go | 8 +- internal/config/config.go | 24 +++--- internal/config/v_one.go | 50 +++++++------ .../go/db.go | 29 ++++++++ .../go/models.go | 12 +++ .../go/querier.go | 16 ++++ .../go/query.sql.go | 74 +++++++++++++++++++ .../query.sql | 10 +++ .../sqlc.json | 15 ++++ 11 files changed, 222 insertions(+), 49 deletions(-) create mode 100644 internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/db.go create mode 100644 internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/models.go create mode 100644 internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/querier.go create mode 100644 internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/query.sql.go create mode 100644 internal/endtoend/testdata/emit_result_and_params_struct_pointers/query.sql create mode 100644 internal/endtoend/testdata/emit_result_and_params_struct_pointers/sqlc.json diff --git a/internal/codegen/golang/gen.go b/internal/codegen/golang/gen.go index 138a9f41cd..4e1d2e2e0e 100644 --- a/internal/codegen/golang/gen.go +++ b/internal/codegen/golang/gen.go @@ -149,10 +149,10 @@ import ( type Querier interface { {{- range .GoQueries}} {{- if eq .Cmd ":one"}} - {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{.Ret.Type}}, error) + {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}, error) {{- end}} {{- if eq .Cmd ":many"}} - {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{.Ret.Type}}, error) + {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}, error) {{- end}} {{- if eq .Cmd ":exec"}} {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) error @@ -258,7 +258,7 @@ type {{.Ret.Type}} struct { {{- range .Ret.Struct.Fields}} {{if eq .Cmd ":one"}} {{range .Comments}}//{{.}} {{end -}} -func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{.Ret.Type}}, error) { +func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}, error) { {{- if $.EmitPreparedQueries}} row := q.queryRow(ctx, q.{{.FieldName}}, {{.ConstantName}}, {{.Arg.Params}}) {{- else}} @@ -266,14 +266,14 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{.Ret.Ty {{- end}} var {{.Ret.Name}} {{.Ret.Type}} err := row.Scan({{.Ret.Scan}}) - return {{.Ret.Name}}, err + return {{if .Ret.IsPointer }}&{{end}}{{.Ret.Name}}, err } {{end}} {{if eq .Cmd ":many"}} {{range .Comments}}//{{.}} {{end -}} -func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{.Ret.Type}}, error) { +func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}, error) { {{- if $.EmitPreparedQueries}} rows, err := q.query(ctx, q.{{.FieldName}}, {{.ConstantName}}, {{.Arg.Params}}) {{- else}} @@ -284,16 +284,16 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{.Ret. } defer rows.Close() {{- if $.EmitEmptySlices}} - items := []{{.Ret.Type}}{} + items := []{{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}{} {{else}} - var items []{{.Ret.Type}} + var items []{{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}} {{end -}} for rows.Next() { var {{.Ret.Name}} {{.Ret.Type}} if err := rows.Scan({{.Ret.Scan}}); err != nil { return nil, err } - items = append(items, {{.Ret.Name}}) + items = append(items, {{if .Ret.IsPointer }}&{{end}}{{.Ret.Name}}) } if err := rows.Close(); err != nil { return nil, err diff --git a/internal/codegen/golang/query.go b/internal/codegen/golang/query.go index afade092d4..a6d6fb11b8 100644 --- a/internal/codegen/golang/query.go +++ b/internal/codegen/golang/query.go @@ -1,16 +1,18 @@ package golang import ( + "fmt" "strings" "github.com/kyleconroy/sqlc/internal/metadata" ) type QueryValue struct { - Emit bool - Name string - Struct *Struct - Typ string + Emit bool + EmitPointer bool + Name string + Struct *Struct + Typ string } func (v QueryValue) EmitStruct() bool { @@ -21,6 +23,10 @@ func (v QueryValue) IsStruct() bool { return v.Struct != nil } +func (v QueryValue) IsPointer() bool { + return v.EmitPointer && v.Struct != nil +} + func (v QueryValue) isEmpty() bool { return v.Typ == "" && v.Name == "" && v.Struct == nil } @@ -29,6 +35,9 @@ func (v QueryValue) Pair() string { if v.isEmpty() { return "" } + if v.EmitPointer && v.Struct != nil { + return fmt.Sprintf("%s *%s", v.Name, v.Type()) + } return v.Name + " " + v.Type() } diff --git a/internal/codegen/golang/result.go b/internal/codegen/golang/result.go index cbce7d4a2e..6ae4b7127d 100644 --- a/internal/codegen/golang/result.go +++ b/internal/codegen/golang/result.go @@ -173,6 +173,7 @@ func buildQueries(r *compiler.Result, settings config.CombinedSettings, structs Emit: true, Name: "arg", Struct: columnsToStruct(r, gq.MethodName+"Params", cols, settings), + EmitPointer: settings.Go.EmitResultStructPointers, } } @@ -218,9 +219,10 @@ func buildQueries(r *compiler.Result, settings config.CombinedSettings, structs emit = true } gq.Ret = QueryValue{ - Emit: emit, - Name: "i", - Struct: gs, + Emit: emit, + Name: "i", + Struct: gs, + EmitPointer: settings.Go.EmitResultStructPointers, } } diff --git a/internal/config/config.go b/internal/config/config.go index bdfba2d28d..408b17c74d 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -110,17 +110,19 @@ type SQLGen struct { } type SQLGo struct { - EmitInterface bool `json:"emit_interface" yaml:"emit_interface"` - EmitJSONTags bool `json:"emit_json_tags" yaml:"emit_json_tags"` - EmitDBTags bool `json:"emit_db_tags" yaml:"emit_db_tags"` - EmitPreparedQueries bool `json:"emit_prepared_queries" yaml:"emit_prepared_queries"` - EmitExactTableNames bool `json:"emit_exact_table_names,omitempty" yaml:"emit_exact_table_names"` - EmitEmptySlices bool `json:"emit_empty_slices,omitempty" yaml:"emit_empty_slices"` - 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"` - Overrides []Override `json:"overrides,omitempty" yaml:"overrides"` - Rename map[string]string `json:"rename,omitempty" yaml:"rename"` + EmitInterface bool `json:"emit_interface" yaml:"emit_interface"` + EmitJSONTags bool `json:"emit_json_tags" yaml:"emit_json_tags"` + EmitDBTags bool `json:"emit_db_tags" yaml:"emit_db_tags"` + EmitPreparedQueries bool `json:"emit_prepared_queries" yaml:"emit_prepared_queries"` + EmitExactTableNames bool `json:"emit_exact_table_names,omitempty" yaml:"emit_exact_table_names"` + EmitEmptySlices bool `json:"emit_empty_slices,omitempty" yaml:"emit_empty_slices"` + EmitResultStructPointers bool `json:"emit_result_struct_pointers" yaml:"emit_result_struct_pointers"` + EmitParamsStructPointers bool `json:"emit_params_struct_pointers" yaml:"emit_params_struct_pointers"` + 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"` + Overrides []Override `json:"overrides,omitempty" yaml:"overrides"` + Rename map[string]string `json:"rename,omitempty" yaml:"rename"` } type SQLKotlin struct { diff --git a/internal/config/v_one.go b/internal/config/v_one.go index 19210df3aa..44d1ee2ffc 100644 --- a/internal/config/v_one.go +++ b/internal/config/v_one.go @@ -16,19 +16,21 @@ type V1GenerateSettings struct { } type v1PackageSettings struct { - Name string `json:"name" yaml:"name"` - Engine Engine `json:"engine,omitempty" yaml:"engine"` - Path string `json:"path" yaml:"path"` - Schema Paths `json:"schema" yaml:"schema"` - Queries Paths `json:"queries" yaml:"queries"` - EmitInterface bool `json:"emit_interface" yaml:"emit_interface"` - EmitJSONTags bool `json:"emit_json_tags" yaml:"emit_json_tags"` - EmitDBTags bool `json:"emit_db_tags" yaml:"emit_db_tags"` - EmitPreparedQueries bool `json:"emit_prepared_queries" yaml:"emit_prepared_queries"` - EmitExactTableNames bool `json:"emit_exact_table_names,omitempty" yaml:"emit_exact_table_names"` - EmitEmptySlices bool `json:"emit_empty_slices,omitempty" yaml:"emit_empty_slices"` - JSONTagsCaseStyle string `json:"json_tags_case_style,omitempty" yaml:"json_tags_case_style"` - Overrides []Override `json:"overrides" yaml:"overrides"` + Name string `json:"name" yaml:"name"` + Engine Engine `json:"engine,omitempty" yaml:"engine"` + Path string `json:"path" yaml:"path"` + Schema Paths `json:"schema" yaml:"schema"` + Queries Paths `json:"queries" yaml:"queries"` + EmitInterface bool `json:"emit_interface" yaml:"emit_interface"` + EmitJSONTags bool `json:"emit_json_tags" yaml:"emit_json_tags"` + EmitDBTags bool `json:"emit_db_tags" yaml:"emit_db_tags"` + EmitPreparedQueries bool `json:"emit_prepared_queries" yaml:"emit_prepared_queries"` + EmitExactTableNames bool `json:"emit_exact_table_names,omitempty" yaml:"emit_exact_table_names"` + EmitEmptySlices bool `json:"emit_empty_slices,omitempty" yaml:"emit_empty_slices"` + EmitResultStructPointers bool `json:"emit_result_struct_pointers" yaml:"emit_result_struct_pointers"` + EmitParamsStructPointers bool `json:"emit_params_struct_pointers" yaml:"emit_params_struct_pointers"` + JSONTagsCaseStyle string `json:"json_tags_case_style,omitempty" yaml:"json_tags_case_style"` + Overrides []Override `json:"overrides" yaml:"overrides"` } func v1ParseConfig(rd io.Reader) (Config, error) { @@ -104,16 +106,18 @@ func (c *V1GenerateSettings) Translate() Config { Queries: pkg.Queries, Gen: SQLGen{ Go: &SQLGo{ - EmitInterface: pkg.EmitInterface, - EmitJSONTags: pkg.EmitJSONTags, - EmitDBTags: pkg.EmitDBTags, - EmitPreparedQueries: pkg.EmitPreparedQueries, - EmitExactTableNames: pkg.EmitExactTableNames, - EmitEmptySlices: pkg.EmitEmptySlices, - Package: pkg.Name, - Out: pkg.Path, - Overrides: pkg.Overrides, - JSONTagsCaseStyle: pkg.JSONTagsCaseStyle, + EmitInterface: pkg.EmitInterface, + EmitJSONTags: pkg.EmitJSONTags, + EmitDBTags: pkg.EmitDBTags, + EmitPreparedQueries: pkg.EmitPreparedQueries, + EmitExactTableNames: pkg.EmitExactTableNames, + EmitEmptySlices: pkg.EmitEmptySlices, + EmitResultStructPointers: pkg.EmitResultStructPointers, + EmitParamsStructPointers: pkg.EmitParamsStructPointers, + Package: pkg.Name, + Out: pkg.Path, + Overrides: pkg.Overrides, + JSONTagsCaseStyle: pkg.JSONTagsCaseStyle, }, }, }) diff --git a/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/db.go b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/db.go new file mode 100644 index 0000000000..6a99519302 --- /dev/null +++ b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/db.go @@ -0,0 +1,29 @@ +// Code generated by sqlc. DO NOT EDIT. + +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_result_and_params_struct_pointers/go/models.go b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/models.go new file mode 100644 index 0000000000..5d38c1d2d3 --- /dev/null +++ b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/models.go @@ -0,0 +1,12 @@ +// Code generated by sqlc. DO NOT EDIT. + +package querytest + +import ( + "database/sql" +) + +type Foo struct { + A sql.NullInt32 + B sql.NullInt32 +} diff --git a/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/querier.go b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/querier.go new file mode 100644 index 0000000000..ff4763ebec --- /dev/null +++ b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/querier.go @@ -0,0 +1,16 @@ +// Code generated by sqlc. DO NOT EDIT. + +package querytest + +import ( + "context" + "database/sql" +) + +type Querier interface { + GetAll(ctx context.Context) ([]*Foo, error) + GetAllAByB(ctx context.Context, b sql.NullInt32) ([]sql.NullInt32, error) + GetOne(ctx context.Context, a sql.NullInt32) (*Foo, error) +} + +var _ Querier = (*Queries)(nil) diff --git a/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/query.sql.go b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/query.sql.go new file mode 100644 index 0000000000..00a1bf70a6 --- /dev/null +++ b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/query.sql.go @@ -0,0 +1,74 @@ +// Code generated by sqlc. DO NOT EDIT. +// source: query.sql + +package querytest + +import ( + "context" + "database/sql" +) + +const getAll = `-- name: GetAll :many +SELECT a, b FROM foo +` + +func (q *Queries) GetAll(ctx context.Context) ([]*Foo, error) { + rows, err := q.db.QueryContext(ctx, getAll) + if err != nil { + return nil, err + } + defer rows.Close() + var items []*Foo + for rows.Next() { + var i Foo + if err := rows.Scan(&i.A, &i.B); 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 +} + +const getAllAByB = `-- name: GetAllAByB :many +SELECT a FROM foo WHERE b = ? +` + +func (q *Queries) GetAllAByB(ctx context.Context, b sql.NullInt32) ([]sql.NullInt32, error) { + rows, err := q.db.QueryContext(ctx, getAllAByB, b) + if err != nil { + return nil, err + } + defer rows.Close() + var items []sql.NullInt32 + for rows.Next() { + var a sql.NullInt32 + if err := rows.Scan(&a); err != nil { + return nil, err + } + items = append(items, a) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getOne = `-- name: GetOne :one +SELECT a, b FROM foo WHERE a = ? LIMIT 1 +` + +func (q *Queries) GetOne(ctx context.Context, a sql.NullInt32) (*Foo, error) { + row := q.db.QueryRowContext(ctx, getOne, a) + var i Foo + err := row.Scan(&i.A, &i.B) + return &i, err +} diff --git a/internal/endtoend/testdata/emit_result_and_params_struct_pointers/query.sql b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/query.sql new file mode 100644 index 0000000000..4d14424da5 --- /dev/null +++ b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/query.sql @@ -0,0 +1,10 @@ +CREATE TABLE foo (a integer, b integer); + +/* name: GetOne :one */ +SELECT * FROM foo WHERE a = ? LIMIT 1; + +/* name: GetAll :many */ +SELECT * FROM foo; + +/* name: GetAllAByB :many */ +SELECT a FROM foo WHERE b = ?; diff --git a/internal/endtoend/testdata/emit_result_and_params_struct_pointers/sqlc.json b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/sqlc.json new file mode 100644 index 0000000000..5bd5791999 --- /dev/null +++ b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/sqlc.json @@ -0,0 +1,15 @@ +{ + "version": "1", + "packages": [ + { + "name": "querytest", + "path": "go", + "schema": "query.sql", + "queries": "query.sql", + "engine": "mysql", + "emit_interface": true, + "emit_result_struct_pointers": true, + "emit_params_struct_pointers": true + } + ] +} From 254348d292dfe4eb24791ba14c4b598485511266 Mon Sep 17 00:00:00 2001 From: Dmitriy Chertkov Date: Wed, 21 Apr 2021 22:08:42 +0500 Subject: [PATCH 2/3] Fix --- internal/codegen/golang/result.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/codegen/golang/result.go b/internal/codegen/golang/result.go index 6ae4b7127d..0a165b1df7 100644 --- a/internal/codegen/golang/result.go +++ b/internal/codegen/golang/result.go @@ -170,10 +170,10 @@ func buildQueries(r *compiler.Result, settings config.CombinedSettings, structs }) } gq.Arg = QueryValue{ - Emit: true, - Name: "arg", - Struct: columnsToStruct(r, gq.MethodName+"Params", cols, settings), - EmitPointer: settings.Go.EmitResultStructPointers, + Emit: true, + Name: "arg", + Struct: columnsToStruct(r, gq.MethodName+"Params", cols, settings), + EmitPointer: settings.Go.EmitParamsStructPointers, } } From 92233b38b70d5ebc846bb6ac0f2a6bbb1635d056 Mon Sep 17 00:00:00 2001 From: Dmitriy Chertkov Date: Sun, 19 Sep 2021 21:38:51 +0500 Subject: [PATCH 3/3] Fixed review comments --- internal/codegen/golang/query.go | 21 ++++++++++++++----- .../golang/templates/pgx/interfaceCode.tmpl | 4 ++-- .../golang/templates/pgx/queryCode.tmpl | 12 +++++------ .../templates/stdlib/interfaceCode.tmpl | 4 ++-- .../golang/templates/stdlib/queryCode.tmpl | 12 +++++------ .../go/querier.go | 2 +- .../go/query.sql.go | 11 +++++++--- .../query.sql | 2 +- 8 files changed, 42 insertions(+), 26 deletions(-) diff --git a/internal/codegen/golang/query.go b/internal/codegen/golang/query.go index a131dbf03f..63ee7f68de 100644 --- a/internal/codegen/golang/query.go +++ b/internal/codegen/golang/query.go @@ -1,7 +1,6 @@ package golang import ( - "fmt" "strings" "github.com/kyleconroy/sqlc/internal/metadata" @@ -36,10 +35,7 @@ func (v QueryValue) Pair() string { if v.isEmpty() { return "" } - if v.EmitPointer && v.Struct != nil { - return fmt.Sprintf("%s *%s", v.Name, v.Type()) - } - return v.Name + " " + v.Type() + return v.Name + " " + v.DefineType() } func (v QueryValue) Type() string { @@ -52,6 +48,21 @@ func (v QueryValue) Type() string { panic("no type for QueryValue: " + v.Name) } +func (v *QueryValue) DefineType() string { + t := v.Type() + if v.IsPointer() { + return "*" + t + } + return t +} + +func (v *QueryValue) ReturnName() string { + if v.IsPointer() { + return "&" + v.Name + } + return v.Name +} + func (v QueryValue) Params() string { if v.isEmpty() { return "" diff --git a/internal/codegen/golang/templates/pgx/interfaceCode.tmpl b/internal/codegen/golang/templates/pgx/interfaceCode.tmpl index 76ee9f898b..a7e48974d3 100644 --- a/internal/codegen/golang/templates/pgx/interfaceCode.tmpl +++ b/internal/codegen/golang/templates/pgx/interfaceCode.tmpl @@ -2,10 +2,10 @@ type Querier interface { {{- range .GoQueries}} {{- if eq .Cmd ":one"}} - {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}, error) + {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{.Ret.DefineType}}, error) {{- end}} {{- if eq .Cmd ":many"}} - {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}, error) + {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{.Ret.DefineType}}, error) {{- end}} {{- if eq .Cmd ":exec"}} {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) error diff --git a/internal/codegen/golang/templates/pgx/queryCode.tmpl b/internal/codegen/golang/templates/pgx/queryCode.tmpl index 124eeb23fc..f5c9e3ed58 100644 --- a/internal/codegen/golang/templates/pgx/queryCode.tmpl +++ b/internal/codegen/golang/templates/pgx/queryCode.tmpl @@ -22,34 +22,34 @@ type {{.Ret.Type}} struct { {{- range .Ret.Struct.Fields}} {{if eq .Cmd ":one"}} {{range .Comments}}//{{.}} {{end -}} -func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}, error) { +func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{.Ret.DefineType}}, error) { row := q.db.QueryRow(ctx, {{.ConstantName}}, {{.Arg.Params}}) var {{.Ret.Name}} {{.Ret.Type}} err := row.Scan({{.Ret.Scan}}) - return {{if .Ret.IsPointer }}&{{end}}{{.Ret.Name}}, err + return {{.Ret.ReturnName}}, err } {{end}} {{if eq .Cmd ":many"}} {{range .Comments}}//{{.}} {{end -}} -func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}, error) { +func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{.Ret.DefineType}}, error) { rows, err := q.db.Query(ctx, {{.ConstantName}}, {{.Arg.Params}}) if err != nil { return nil, err } defer rows.Close() {{- if $.EmitEmptySlices}} - items := []{{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}{} + items := []{{.Ret.DefineType}}{} {{else}} - var items []{{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}} + var items []{{.Ret.DefineType}} {{end -}} for rows.Next() { var {{.Ret.Name}} {{.Ret.Type}} if err := rows.Scan({{.Ret.Scan}}); err != nil { return nil, err } - items = append(items, {{if .Ret.IsPointer }}&{{end}}{{.Ret.Name}}) + items = append(items, {{.Ret.ReturnName}}) } if err := rows.Err(); err != nil { return nil, err diff --git a/internal/codegen/golang/templates/stdlib/interfaceCode.tmpl b/internal/codegen/golang/templates/stdlib/interfaceCode.tmpl index fee0eb791b..5705c69fd1 100644 --- a/internal/codegen/golang/templates/stdlib/interfaceCode.tmpl +++ b/internal/codegen/golang/templates/stdlib/interfaceCode.tmpl @@ -2,10 +2,10 @@ type Querier interface { {{- range .GoQueries}} {{- if eq .Cmd ":one"}} - {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}, error) + {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{.Ret.DefineType}}, error) {{- end}} {{- if eq .Cmd ":many"}} - {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}, error) + {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{.Ret.DefineType}}, error) {{- end}} {{- if eq .Cmd ":exec"}} {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) error diff --git a/internal/codegen/golang/templates/stdlib/queryCode.tmpl b/internal/codegen/golang/templates/stdlib/queryCode.tmpl index 04d542d50c..1b06f4e1a8 100644 --- a/internal/codegen/golang/templates/stdlib/queryCode.tmpl +++ b/internal/codegen/golang/templates/stdlib/queryCode.tmpl @@ -22,7 +22,7 @@ type {{.Ret.Type}} struct { {{- range .Ret.Struct.Fields}} {{if eq .Cmd ":one"}} {{range .Comments}}//{{.}} {{end -}} -func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}, error) { +func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{.Ret.DefineType}}, error) { {{- if $.EmitPreparedQueries}} row := q.queryRow(ctx, q.{{.FieldName}}, {{.ConstantName}}, {{.Arg.Params}}) {{- else}} @@ -30,14 +30,14 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{if .Ret {{- end}} var {{.Ret.Name}} {{.Ret.Type}} err := row.Scan({{.Ret.Scan}}) - return {{if .Ret.IsPointer }}&{{end}}{{.Ret.Name}}, err + return {{.Ret.ReturnName}}, err } {{end}} {{if eq .Cmd ":many"}} {{range .Comments}}//{{.}} {{end -}} -func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}, error) { +func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{.Ret.DefineType}}, error) { {{- if $.EmitPreparedQueries}} rows, err := q.query(ctx, q.{{.FieldName}}, {{.ConstantName}}, {{.Arg.Params}}) {{- else}} @@ -48,16 +48,16 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{if .R } defer rows.Close() {{- if $.EmitEmptySlices}} - items := []{{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}}{} + items := []{{.Ret.DefineType}}{} {{else}} - var items []{{if .Ret.IsPointer }}*{{end}}{{.Ret.Type}} + var items []{{.Ret.DefineType}} {{end -}} for rows.Next() { var {{.Ret.Name}} {{.Ret.Type}} if err := rows.Scan({{.Ret.Scan}}); err != nil { return nil, err } - items = append(items, {{if .Ret.IsPointer }}&{{end}}{{.Ret.Name}}) + items = append(items, {{.Ret.ReturnName}}) } if err := rows.Close(); err != nil { return nil, err diff --git a/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/querier.go b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/querier.go index ff4763ebec..075bbc63ee 100644 --- a/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/querier.go +++ b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/querier.go @@ -10,7 +10,7 @@ import ( type Querier interface { GetAll(ctx context.Context) ([]*Foo, error) GetAllAByB(ctx context.Context, b sql.NullInt32) ([]sql.NullInt32, error) - GetOne(ctx context.Context, a sql.NullInt32) (*Foo, error) + GetOne(ctx context.Context, arg *GetOneParams) (*Foo, error) } var _ Querier = (*Queries)(nil) diff --git a/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/query.sql.go b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/query.sql.go index 00a1bf70a6..033123f1eb 100644 --- a/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/query.sql.go +++ b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/go/query.sql.go @@ -63,11 +63,16 @@ func (q *Queries) GetAllAByB(ctx context.Context, b sql.NullInt32) ([]sql.NullIn } const getOne = `-- name: GetOne :one -SELECT a, b FROM foo WHERE a = ? LIMIT 1 +SELECT a, b FROM foo WHERE a = ? AND b = ? LIMIT 1 ` -func (q *Queries) GetOne(ctx context.Context, a sql.NullInt32) (*Foo, error) { - row := q.db.QueryRowContext(ctx, getOne, a) +type GetOneParams struct { + A sql.NullInt32 + B sql.NullInt32 +} + +func (q *Queries) GetOne(ctx context.Context, arg *GetOneParams) (*Foo, error) { + row := q.db.QueryRowContext(ctx, getOne, arg.A, arg.B) var i Foo err := row.Scan(&i.A, &i.B) return &i, err diff --git a/internal/endtoend/testdata/emit_result_and_params_struct_pointers/query.sql b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/query.sql index 4d14424da5..53bbf19f94 100644 --- a/internal/endtoend/testdata/emit_result_and_params_struct_pointers/query.sql +++ b/internal/endtoend/testdata/emit_result_and_params_struct_pointers/query.sql @@ -1,7 +1,7 @@ CREATE TABLE foo (a integer, b integer); /* name: GetOne :one */ -SELECT * FROM foo WHERE a = ? LIMIT 1; +SELECT * FROM foo WHERE a = ? AND b = ? LIMIT 1; /* name: GetAll :many */ SELECT * FROM foo;