Skip to content

Commit 77738fd

Browse files
authored
feat(json-tags): Add case style config option (#905)
1 parent 25d0731 commit 77738fd

File tree

20 files changed

+360
-7
lines changed

20 files changed

+360
-7
lines changed

docs/reference/config.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ packages:
1111
queries: "./sql/query/"
1212
schema: "./sql/schema/"
1313
engine: "postgresql"
14-
emit_json_tags: true
1514
emit_prepared_queries: true
1615
emit_interface: false
1716
emit_exact_table_names: false
1817
emit_empty_slices: false
18+
emit_json_tags: true
19+
json_tags_case_style: "camel"
1920
```
2021
2122
Each package document has the following keys:
@@ -29,8 +30,6 @@ Each package document has the following keys:
2930
- Directory of SQL migrations or path to single SQL file; or a list of paths
3031
- `engine`:
3132
- Either `postgresql` or `mysql`. Defaults to `postgresql`. MySQL support is experimental
32-
- `emit_json_tags`:
33-
- If true, add JSON tags to generated structs. Defaults to `false`.
3433
- `emit_db_tags`:
3534
- If true, add DB tags to generated structs. Defaults to `false`.
3635
- `emit_prepared_queries`:
@@ -41,6 +40,10 @@ Each package document has the following keys:
4140
- If true, struct names will mirror table names. Otherwise, sqlc attempts to singularize plural table names. Defaults to `false`.
4241
- `emit_empty_slices`:
4342
- If true, slices returned by `:many` queries will be empty instead of `nil`. Defaults to `false`.
43+
- `emit_json_tags`:
44+
- If true, add JSON tags to generated structs. Defaults to `false`.
45+
- `json_tags_case_style`:
46+
- `camel` for camelCase, `pascal` for PascalCase, `snake` for snake_case or `none` to use the column name in the DB. Defaults to `none`.
4447

4548
## Type Overrides
4649

@@ -118,5 +121,3 @@ packages: [...]
118121
rename:
119122
spotify_url: "SpotifyURL"
120123
```
121-
122-

internal/codegen/golang/field.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"fmt"
55
"sort"
66
"strings"
7+
8+
"github.com/kyleconroy/sqlc/internal/config"
79
)
810

911
type Field struct {
@@ -24,3 +26,53 @@ func (gf Field) Tag() string {
2426
sort.Strings(tags)
2527
return strings.Join(tags, " ")
2628
}
29+
30+
func JSONTagName(name string, settings config.CombinedSettings) string {
31+
style := settings.Go.JSONTagsCaseStyle
32+
if style == "" || style == "none" {
33+
return name
34+
} else {
35+
return SetCaseStyle(name, style)
36+
}
37+
}
38+
39+
func SetCaseStyle(name string, style string) string {
40+
switch style {
41+
case "camel":
42+
return toCamelCase(name)
43+
case "pascal":
44+
return toPascalCase(name)
45+
case "snake":
46+
return toSnakeCase(name)
47+
default:
48+
panic(fmt.Sprintf("unsupported JSON tags case style: '%s'", style))
49+
}
50+
}
51+
52+
func toSnakeCase(s string) string {
53+
return strings.ToLower(s)
54+
}
55+
56+
func toCamelCase(s string) string {
57+
return toCamelInitCase(s, false)
58+
}
59+
60+
func toPascalCase(s string) string {
61+
return toCamelInitCase(s, true)
62+
}
63+
64+
func toCamelInitCase(name string, initUpper bool) string {
65+
out := ""
66+
for i, p := range strings.Split(name, "_") {
67+
if !initUpper && i == 0 {
68+
out += p
69+
continue
70+
}
71+
if p == "id" {
72+
out += "ID"
73+
} else {
74+
out += strings.Title(p)
75+
}
76+
}
77+
return out
78+
}

internal/codegen/golang/result.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func buildStructs(r *compiler.Result, settings config.CombinedSettings) []Struct
7878
tags["db:"] = column.Name
7979
}
8080
if settings.Go.EmitJSONTags {
81-
tags["json:"] = column.Name
81+
tags["json:"] = JSONTagName(column.Name, settings)
8282
}
8383
s.Fields = append(s.Fields, Field{
8484
Name: StructName(column.Name, settings),
@@ -259,7 +259,7 @@ func columnsToStruct(r *compiler.Result, name string, columns []goColumn, settin
259259
tags["db:"] = tagName
260260
}
261261
if settings.Go.EmitJSONTags {
262-
tags["json:"] = tagName
262+
tags["json:"] = JSONTagName(tagName, settings)
263263
}
264264
gs.Fields = append(gs.Fields, Field{
265265
Name: fieldName,

internal/config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ type SQLGo struct {
116116
EmitPreparedQueries bool `json:"emit_prepared_queries" yaml:"emit_prepared_queries"`
117117
EmitExactTableNames bool `json:"emit_exact_table_names,omitempty" yaml:"emit_exact_table_names"`
118118
EmitEmptySlices bool `json:"emit_empty_slices,omitempty" yaml:"emit_empty_slices"`
119+
JSONTagsCaseStyle string `json:"json_tags_case_style,omitempty" yaml:"json_tags_case_style"`
119120
Package string `json:"package" yaml:"package"`
120121
Out string `json:"out" yaml:"out"`
121122
Overrides []Override `json:"overrides,omitempty" yaml:"overrides"`

internal/config/v_one.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type v1PackageSettings struct {
2727
EmitPreparedQueries bool `json:"emit_prepared_queries" yaml:"emit_prepared_queries"`
2828
EmitExactTableNames bool `json:"emit_exact_table_names,omitempty" yaml:"emit_exact_table_names"`
2929
EmitEmptySlices bool `json:"emit_empty_slices,omitempty" yaml:"emit_empty_slices"`
30+
JSONTagsCaseStyle string `json:"json_tags_case_style,omitempty" yaml:"json_tags_case_style"`
3031
Overrides []Override `json:"overrides" yaml:"overrides"`
3132
}
3233

@@ -112,6 +113,7 @@ func (c *V1GenerateSettings) Translate() Config {
112113
Package: pkg.Name,
113114
Out: pkg.Path,
114115
Overrides: pkg.Overrides,
116+
JSONTagsCaseStyle: pkg.JSONTagsCaseStyle,
115117
},
116118
},
117119
})

internal/endtoend/testdata/json_tags/camel_case/go/db.go

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

internal/endtoend/testdata/json_tags/camel_case/go/models.go

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

internal/endtoend/testdata/json_tags/camel_case/go/query.sql.go

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CREATE TABLE users (
2+
first_name varchar(255),
3+
last_name varchar(255),
4+
age smallint
5+
);
6+
7+
-- name: GetAll :many
8+
SELECT * FROM users;
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+
"emit_json_tags": true,
11+
"json_tags_case_style": "camel"
12+
}
13+
]
14+
}

internal/endtoend/testdata/json_tags/pascal_case/go/db.go

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

internal/endtoend/testdata/json_tags/pascal_case/go/models.go

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

internal/endtoend/testdata/json_tags/pascal_case/go/query.sql.go

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CREATE TABLE users (
2+
first_name varchar(255),
3+
last_name varchar(255),
4+
age smallint
5+
);
6+
7+
-- name: GetAll :many
8+
SELECT * FROM users;
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+
"emit_json_tags": true,
11+
"json_tags_case_style": "pascal"
12+
}
13+
]
14+
}

internal/endtoend/testdata/json_tags/snake_case/go/db.go

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

internal/endtoend/testdata/json_tags/snake_case/go/models.go

Lines changed: 13 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)