Skip to content

Commit b4d2e91

Browse files
go-mezgo-mezkyleconroy
authored
feat(Go):Add query_parameter_limit conf to codegen (#1558)
* feat(Go):Add query_parameter_limit conf to codegen * Fix nil pointer reference * Allow query_parameter_limit to be zero * resolve conversation * remove qpl check * docs: Remove duplicate config entry --------- Co-authored-by: go-mez <cristobal.gomez@mercadolibre.cl> Co-authored-by: Kyle Conroy <kyle@conroy.org>
1 parent c7c6a36 commit b4d2e91

File tree

28 files changed

+663
-130
lines changed

28 files changed

+663
-130
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/.idea/
22
__pycache__
3+
.DS_Store

docs/reference/config.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ The `gen` mapping supports the following keys:
121121
- Customize the name of the querier file. Defaults to `querier.go`.
122122
- `output_files_suffix`:
123123
- If specified the suffix will be added to the name of the generated files.
124-
- `rename`:
124+
- `query_parameter_limit`:
125+
- Positional arguments that will be generated in Go functions (>= `1` or `-1`). To always emit a parameter struct, you would need to set it to `-1`. `0` is invalid. Defaults to `1`.
126+
`rename`:
125127
- Customize the name of generated struct fields. Explained in detail on the `Renaming fields` section.
126128
- `overrides`:
127129
- It is a collection of definitions that dictates which types are used to map a database types. Explained in detail on the `Type overriding` section.
@@ -403,6 +405,8 @@ Each mapping in the `packages` collection has the following keys:
403405
- Customize the name of the querier file. Defaults to `querier.go`.
404406
- `output_files_suffix`:
405407
- If specified the suffix will be added to the name of the generated files.
408+
- `query_parameter_limit`:
409+
- Positional arguments that will be generated in Go functions (`>= 0`). To always emit a parameter struct, you would need to set it to `0`. Defaults to `1`.
406410

407411
### overrides
408412

internal/cmd/shim.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ func pluginCodegen(s config.Codegen) *plugin.Codegen {
7575
}
7676

7777
func pluginGoCode(s config.SQLGo) *plugin.GoCode {
78+
if s.QueryParameterLimit == nil {
79+
s.QueryParameterLimit = new(int32)
80+
*s.QueryParameterLimit = 1
81+
}
82+
7883
return &plugin.GoCode{
7984
EmitInterface: s.EmitInterface,
8085
EmitJsonTags: s.EmitJSONTags,
@@ -98,6 +103,7 @@ func pluginGoCode(s config.SQLGo) *plugin.GoCode {
98103
OutputQuerierFileName: s.OutputQuerierFileName,
99104
OutputFilesSuffix: s.OutputFilesSuffix,
100105
InflectionExcludeTableNames: s.InflectionExcludeTableNames,
106+
QueryParameterLimit: s.QueryParameterLimit,
101107
}
102108
}
103109

internal/codegen/golang/field.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,11 @@ func toCamelInitCase(name string, initUpper bool) string {
8484
}
8585
return out
8686
}
87+
88+
func toLowerCase(str string) string {
89+
if str == "" {
90+
return ""
91+
}
92+
93+
return strings.ToLower(str[:1]) + str[1:]
94+
}

internal/codegen/golang/query.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ func (v QueryValue) Pair() string {
4242
if v.isEmpty() {
4343
return ""
4444
}
45+
46+
var out []string
47+
if !v.EmitStruct() && v.IsStruct() {
48+
for _, f := range v.Struct.Fields {
49+
out = append(out, toLowerCase(f.Name)+" "+f.Type)
50+
}
51+
52+
return strings.Join(out, ",")
53+
}
54+
4555
return v.Name + " " + v.DefineType()
4656
}
4757

@@ -107,6 +117,8 @@ func (v QueryValue) Params() string {
107117
for _, f := range v.Struct.Fields {
108118
if !f.HasSqlcSlice() && strings.HasPrefix(f.Type, "[]") && f.Type != "[]byte" && !v.SQLDriver.IsPGX() {
109119
out = append(out, "pq.Array("+v.Name+"."+f.Name+")")
120+
} else if !v.EmitStruct() && v.IsStruct() {
121+
out = append(out, toLowerCase(f.Name))
110122
} else {
111123
out = append(out, v.Name+"."+f.Name)
112124
}

internal/codegen/golang/result.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,9 @@ func buildQueries(req *plugin.CodeGenRequest, structs []Struct) ([]Query, error)
202202
}
203203
sqlpkg := parseDriver(req.Settings.Go.SqlPackage)
204204

205-
if len(query.Params) == 1 {
205+
qpl := int(*req.Settings.Go.QueryParameterLimit)
206+
207+
if len(query.Params) == 1 && qpl != 0 {
206208
p := query.Params[0]
207209
gq.Arg = QueryValue{
208210
Name: paramName(p),
@@ -211,7 +213,7 @@ func buildQueries(req *plugin.CodeGenRequest, structs []Struct) ([]Query, error)
211213
SQLDriver: sqlpkg,
212214
Column: p.Column,
213215
}
214-
} else if len(query.Params) > 1 {
216+
} else if len(query.Params) >= 1 {
215217
var cols []goColumn
216218
for _, p := range query.Params {
217219
cols = append(cols, goColumn{
@@ -230,6 +232,10 @@ func buildQueries(req *plugin.CodeGenRequest, structs []Struct) ([]Query, error)
230232
SQLDriver: sqlpkg,
231233
EmitPointer: req.Settings.Go.EmitParamsStructPointers,
232234
}
235+
236+
if len(query.Params) <= qpl {
237+
gq.Arg.Emit = false
238+
}
233239
}
234240

235241
if len(query.Columns) == 1 && query.Columns[0].EmbedTable == nil {

internal/config/config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ type SQLGo struct {
133133
OutputQuerierFileName string `json:"output_querier_file_name,omitempty" yaml:"output_querier_file_name"`
134134
OutputFilesSuffix string `json:"output_files_suffix,omitempty" yaml:"output_files_suffix"`
135135
InflectionExcludeTableNames []string `json:"inflection_exclude_table_names,omitempty" yaml:"inflection_exclude_table_names"`
136+
QueryParameterLimit *int32 `json:"query_parameter_limit,omitempty" yaml:"query_parameter_limit"`
136137
}
137138

138139
type SQLJSON struct {
@@ -150,6 +151,7 @@ var ErrNoPackages = errors.New("no packages")
150151
var ErrNoQuerierType = errors.New("no querier emit type enabled")
151152
var ErrUnknownEngine = errors.New("invalid engine")
152153
var ErrUnknownVersion = errors.New("invalid version number")
154+
var ErrInvalidQueryParameterLimit = errors.New("invalid query parameter limit")
153155

154156
var ErrPluginBuiltin = errors.New("a built-in plugin with that name already exists")
155157
var ErrPluginNoName = errors.New("missing plugin name")
@@ -159,8 +161,6 @@ var ErrPluginNoType = errors.New("plugin: field `process` or `wasm` required")
159161
var ErrPluginBothTypes = errors.New("plugin: both `process` and `wasm` cannot both be defined")
160162
var ErrPluginProcessNoCmd = errors.New("plugin: missing process command")
161163

162-
var ErrInvalidQueryParameterLimit = errors.New("invalid query parameter limit")
163-
164164
func ParseConfig(rd io.Reader) (Config, error) {
165165
var buf bytes.Buffer
166166
var config Config

internal/config/v_one.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type v1PackageSettings struct {
4343
OutputQuerierFileName string `json:"output_querier_file_name,omitempty" yaml:"output_querier_file_name"`
4444
OutputFilesSuffix string `json:"output_files_suffix,omitempty" yaml:"output_files_suffix"`
4545
StrictFunctionChecks bool `json:"strict_function_checks" yaml:"strict_function_checks"`
46+
QueryParameterLimit *int32 `json:"query_parameter_limit,omitempty" yaml:"query_parameter_limit"`
4647
}
4748

4849
func v1ParseConfig(rd io.Reader) (Config, error) {
@@ -74,6 +75,16 @@ func v1ParseConfig(rd io.Reader) (Config, error) {
7475
if settings.Packages[j].Path == "" {
7576
return config, ErrNoPackagePath
7677
}
78+
79+
if settings.Packages[j].QueryParameterLimit != nil && (*settings.Packages[j].QueryParameterLimit < 0) {
80+
return config, ErrInvalidQueryParameterLimit
81+
}
82+
83+
if settings.Packages[j].QueryParameterLimit == nil {
84+
settings.Packages[j].QueryParameterLimit = new(int32)
85+
*settings.Packages[j].QueryParameterLimit = 1
86+
}
87+
7788
for i := range settings.Packages[j].Overrides {
7889
if err := settings.Packages[j].Overrides[i].Parse(); err != nil {
7990
return config, err
@@ -143,6 +154,7 @@ func (c *V1GenerateSettings) Translate() Config {
143154
OutputModelsFileName: pkg.OutputModelsFileName,
144155
OutputQuerierFileName: pkg.OutputQuerierFileName,
145156
OutputFilesSuffix: pkg.OutputFilesSuffix,
157+
QueryParameterLimit: pkg.QueryParameterLimit,
146158
},
147159
},
148160
StrictFunctionChecks: pkg.StrictFunctionChecks,

internal/config/v_two.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@ func v2ParseConfig(rd io.Reader) (Config, error) {
7474
if conf.SQL[j].Gen.Go.Package == "" {
7575
conf.SQL[j].Gen.Go.Package = filepath.Base(conf.SQL[j].Gen.Go.Out)
7676
}
77+
78+
if conf.SQL[j].Gen.Go.QueryParameterLimit != nil && (*conf.SQL[j].Gen.Go.QueryParameterLimit < 0) {
79+
return conf, ErrInvalidQueryParameterLimit
80+
}
81+
82+
if conf.SQL[j].Gen.Go.QueryParameterLimit == nil {
83+
conf.SQL[j].Gen.Go.QueryParameterLimit = new(int32)
84+
*conf.SQL[j].Gen.Go.QueryParameterLimit = 1
85+
}
86+
7787
for i := range conf.SQL[j].Gen.Go.Overrides {
7888
if err := conf.SQL[j].Gen.Go.Overrides[i].Parse(); err != nil {
7989
return conf, err

internal/endtoend/testdata/codegen_json/gen/codegen.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
"emit_enum_valid_method": false,
3838
"emit_all_enum_values": false,
3939
"inflection_exclude_table_names": [],
40-
"emit_pointers_for_null_types": false
40+
"emit_pointers_for_null_types": false,
41+
"query_parameter_limit": 1
4142
},
4243
"json": {
4344
"out": "gen",

internal/endtoend/testdata/process_plugin_disabled/gen/codegen.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
"emit_enum_valid_method": false,
3838
"emit_all_enum_values": false,
3939
"inflection_exclude_table_names": [],
40-
"emit_pointers_for_null_types": false
40+
"emit_pointers_for_null_types": false,
41+
"query_parameter_limit": 1
4142
},
4243
"json": {
4344
"out": "",

internal/endtoend/testdata/process_plugin_sqlc_gen_json/gen/codegen.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
"emit_enum_valid_method": false,
3838
"emit_all_enum_values": false,
3939
"inflection_exclude_table_names": [],
40-
"emit_pointers_for_null_types": false
40+
"emit_pointers_for_null_types": false,
41+
"query_parameter_limit": 1
4142
},
4243
"json": {
4344
"out": "",
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-- Example queries for sqlc
2+
CREATE TABLE authors (
3+
id BIGSERIAL PRIMARY KEY,
4+
name text NOT NULL,
5+
bio text,
6+
country_code CHAR(2) NOT NULL
7+
);
8+
9+
-- name: GetAuthor :one
10+
SELECT * FROM authors
11+
WHERE name = $1 AND country_code = $2 LIMIT 1;
12+
13+
-- name: ListAuthors :many
14+
SELECT * FROM authors
15+
ORDER BY name;
16+
17+
-- name: CreateAuthor :one
18+
INSERT INTO authors (
19+
name, bio, country_code
20+
) VALUES (
21+
$1, $2, $3
22+
)
23+
RETURNING *;
24+
25+
-- name: DeleteAuthor :exec
26+
DELETE FROM authors
27+
WHERE id = $1;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"version": "1",
3+
"packages": [
4+
{
5+
"path": "go",
6+
"engine": "postgresql",
7+
"name": "querytest",
8+
"schema": "query.sql",
9+
"queries": "query.sql",
10+
"query_parameter_limit": -1
11+
}
12+
]
13+
}
14+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
error parsing sqlc.json: invalid query parameter limit

internal/endtoend/testdata/query_parameter_limit_to_two/postgresql/go/db.go

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/query_parameter_limit_to_two/postgresql/go/models.go

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)