From 67647a0ca8a4fa1ea422aada3580a9814e2bb7e1 Mon Sep 17 00:00:00 2001 From: "John W. Carbone" Date: Wed, 14 Jun 2023 00:32:05 -0400 Subject: [PATCH 1/2] Add json_tags_id_camelcase configuration option If json_tags_id_camelcase is true, "ID" in json tags will be camelcase. If false, will be uppercase. Defaults to `false` --- docs/reference/config.md | 2 + internal/cmd/shim.go | 1 + internal/codegen/golang/field.go | 38 ++++++++++++++++++- internal/codegen/golang/gen.go | 2 + internal/config/config.go | 1 + internal/config/v_one.go | 2 + internal/plugin/codegen.pb.go | 8 ++++ internal/plugin/codegen_vtproto.pb.go | 53 +++++++++++++++++++++++++-- 8 files changed, 103 insertions(+), 4 deletions(-) diff --git a/docs/reference/config.md b/docs/reference/config.md index 96bf7fe794..2f6c5166c9 100644 --- a/docs/reference/config.md +++ b/docs/reference/config.md @@ -111,6 +111,8 @@ The `gen` mapping supports the following keys: - `emit_all_enum_values`: - If true, emit a function per enum type that returns all valid enum values. +- `json_tags_id_camelcase`: + - If true, "ID" in json tags will be camelcase. If false, will be uppercase. Defaults to `false` - `json_tags_case_style`: - `camel` for camelCase, `pascal` for PascalCase, `snake` for snake_case or `none` to use the column name in the DB. Defaults to `none`. - `output_batch_file_name`: diff --git a/internal/cmd/shim.go b/internal/cmd/shim.go index 838d344cc3..fc8acf6676 100644 --- a/internal/cmd/shim.go +++ b/internal/cmd/shim.go @@ -84,6 +84,7 @@ func pluginGoCode(s config.SQLGo) *plugin.GoCode { return &plugin.GoCode{ EmitInterface: s.EmitInterface, EmitJsonTags: s.EmitJSONTags, + JsonTagsIDCamelcase: s.JsonTagsIDCamelcase, EmitDbTags: s.EmitDBTags, EmitPreparedQueries: s.EmitPreparedQueries, EmitExactTableNames: s.EmitExactTableNames, diff --git a/internal/codegen/golang/field.go b/internal/codegen/golang/field.go index 6a8a2b6372..cfd70f46c1 100644 --- a/internal/codegen/golang/field.go +++ b/internal/codegen/golang/field.go @@ -42,10 +42,11 @@ func TagsToString(tags map[string]string) string { func JSONTagName(name string, settings *plugin.Settings) string { style := settings.Go.JsonTagsCaseStyle + idCamelcase := settings.Go.JsonTagsIDCamelcase if style == "" || style == "none" { return name } else { - return SetCaseStyle(name, style) + return SetJSONCaseStyle(name, style, idCamelcase) } } @@ -62,6 +63,19 @@ func SetCaseStyle(name string, style string) string { } } +func SetJSONCaseStyle(name string, style string, idCamelcase bool) string { + switch style { + case "camel": + return toJsonCamelCase(name, idCamelcase) + case "pascal": + return toPascalCase(name) + case "snake": + return toSnakeCase(name) + default: + panic(fmt.Sprintf("unsupported JSON tags case style: '%s'", style)) + } +} + var camelPattern = regexp.MustCompile("[^A-Z][A-Z]+") func toSnakeCase(s string) string { @@ -97,6 +111,28 @@ func toCamelInitCase(name string, initUpper bool) string { return out } +func toJsonCamelCase(name string, idCamelcase bool) string { + out := "" + idStr := "ID" + + if idCamelcase { + idStr = "Id" + } + + for i, p := range strings.Split(name, "_") { + if i == 0 { + out += p + continue + } + if p == "id" { + out += idStr + } else { + out += strings.Title(p) + } + } + return out +} + func toLowerCase(str string) string { if str == "" { return "" diff --git a/internal/codegen/golang/gen.go b/internal/codegen/golang/gen.go index dac9d47862..b183c9afa6 100644 --- a/internal/codegen/golang/gen.go +++ b/internal/codegen/golang/gen.go @@ -28,6 +28,7 @@ type tmplCtx struct { SourceName string EmitJSONTags bool + JsonTagsIDCamelcase bool EmitDBTags bool EmitPreparedQueries bool EmitInterface bool @@ -122,6 +123,7 @@ func generate(req *plugin.CodeGenRequest, enums []Enum, structs []Struct, querie tctx := tmplCtx{ EmitInterface: golang.EmitInterface, EmitJSONTags: golang.EmitJsonTags, + JsonTagsIDCamelcase: golang.JsonTagsIDCamelcase, EmitDBTags: golang.EmitDbTags, EmitPreparedQueries: golang.EmitPreparedQueries, EmitEmptySlices: golang.EmitEmptySlices, diff --git a/internal/config/config.go b/internal/config/config.go index b0479a6f12..c50eb20d6f 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -119,6 +119,7 @@ type SQLGen struct { type SQLGo struct { EmitInterface bool `json:"emit_interface" yaml:"emit_interface"` EmitJSONTags bool `json:"emit_json_tags" yaml:"emit_json_tags"` + JsonTagsIDCamelcase bool `json:"json_tags_id_camelcase" yaml:"json_tags_id_camelcase"` 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"` diff --git a/internal/config/v_one.go b/internal/config/v_one.go index b0f1bfae04..fe284d0a17 100644 --- a/internal/config/v_one.go +++ b/internal/config/v_one.go @@ -25,6 +25,7 @@ type v1PackageSettings struct { Queries Paths `json:"queries" yaml:"queries"` EmitInterface bool `json:"emit_interface" yaml:"emit_interface"` EmitJSONTags bool `json:"emit_json_tags" yaml:"emit_json_tags"` + JsonTagsIDCamelcase bool `json:"json_tags_id_camelcase" yaml:"json_tags_id_camelcase"` 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"` @@ -143,6 +144,7 @@ func (c *V1GenerateSettings) Translate() Config { Go: &SQLGo{ EmitInterface: pkg.EmitInterface, EmitJSONTags: pkg.EmitJSONTags, + JsonTagsIDCamelcase: pkg.JsonTagsIDCamelcase, EmitDBTags: pkg.EmitDBTags, EmitPreparedQueries: pkg.EmitPreparedQueries, EmitExactTableNames: pkg.EmitExactTableNames, diff --git a/internal/plugin/codegen.pb.go b/internal/plugin/codegen.pb.go index cd1caa0e31..fb3f5c9e63 100644 --- a/internal/plugin/codegen.pb.go +++ b/internal/plugin/codegen.pb.go @@ -467,6 +467,7 @@ type GoCode struct { EmitPointersForNullTypes bool `protobuf:"varint,22,opt,name=emit_pointers_for_null_types,json=emitPointersForNullTypes,proto3" json:"emit_pointers_for_null_types,omitempty"` QueryParameterLimit *int32 `protobuf:"varint,23,opt,name=query_parameter_limit,json=queryParameterLimit,proto3,oneof" json:"query_parameter_limit,omitempty"` OutputBatchFileName string `protobuf:"bytes,24,opt,name=output_batch_file_name,json=outputBatchFileName,proto3" json:"output_batch_file_name,omitempty"` + JsonTagsIDCamelcase bool `protobuf:"varint,26,opt,name=json_tags_id_camelcase,json=jsonTagsIdCamelcase,proto3" json:"json_tags_id_camelcase,omitempty"` } func (x *GoCode) Reset() { @@ -515,6 +516,13 @@ func (x *GoCode) GetEmitJsonTags() bool { return false } +func (x *GoCode) GetJsonTagsIDCamelcase() bool { + if x != nil { + return x.JsonTagsIDCamelcase + } + return false +} + func (x *GoCode) GetEmitDbTags() bool { if x != nil { return x.EmitDbTags diff --git a/internal/plugin/codegen_vtproto.pb.go b/internal/plugin/codegen_vtproto.pb.go index ea84078968..b8c31b80de 100644 --- a/internal/plugin/codegen_vtproto.pb.go +++ b/internal/plugin/codegen_vtproto.pb.go @@ -172,6 +172,7 @@ func (m *GoCode) CloneVT() *GoCode { r := &GoCode{ EmitInterface: m.EmitInterface, EmitJsonTags: m.EmitJsonTags, + JsonTagsIDCamelcase: m.JsonTagsIDCamelcase, EmitDbTags: m.EmitDbTags, EmitPreparedQueries: m.EmitPreparedQueries, EmitExactTableNames: m.EmitExactTableNames, @@ -754,6 +755,9 @@ func (this *GoCode) EqualVT(that *GoCode) bool { if this.EmitJsonTags != that.EmitJsonTags { return false } + if this.JsonTagsIDCamelcase != that.JsonTagsIDCamelcase { + return false + } if this.EmitDbTags != that.EmitDbTags { return false } @@ -1996,6 +2000,16 @@ func (m *GoCode) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i-- dAtA[i] = 0x10 } + if m.JsonTagsIDCamelcase { + i-- + if m.JsonTagsIDCamelcase { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x64 + } if m.EmitInterface { i-- if m.EmitInterface { @@ -3548,15 +3562,25 @@ func (m *GoCode) MarshalToSizedBufferVTStrict(dAtA []byte) (int, error) { i-- dAtA[i] = 0x10 } - if m.EmitInterface { + if m.EmitJsonTags { i-- - if m.EmitInterface { + if m.EmitJsonTags { dAtA[i] = 1 } else { dAtA[i] = 0 } i-- - dAtA[i] = 0x8 + dAtA[i] = 0x10 + } + if m.JsonTagsIDCamelcase { + i-- + if m.JsonTagsIDCamelcase { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x64 } return len(dAtA) - i, nil } @@ -4605,6 +4629,9 @@ func (m *GoCode) SizeVT() (n int) { if m.EmitJsonTags { n += 2 } + if m.JsonTagsIDCamelcase { + n += 2 + } if m.EmitDbTags { n += 2 } @@ -7007,6 +7034,26 @@ func (m *GoCode) UnmarshalVT(dAtA []byte) error { } m.SqlDriver = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 26: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field JsonTagsIDCamelcase", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.JsonTagsIDCamelcase = bool(v != 0) default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) From acd322f49b50c97bcc8659dd017d28f536641b54 Mon Sep 17 00:00:00 2001 From: "John W. Carbone" Date: Tue, 20 Jun 2023 23:39:27 -0400 Subject: [PATCH 2/2] json_tags_id_uppercase If true, "Id" in json tags will be uppercase. If false, will be camelcase. Defaults to `false` --- docs/reference/config.md | 4 ++-- internal/cmd/shim.go | 2 +- internal/codegen/golang/field.go | 16 ++++++++-------- internal/codegen/golang/gen.go | 4 ++-- internal/config/config.go | 2 +- internal/config/v_one.go | 4 ++-- internal/plugin/codegen.pb.go | 8 ++++---- internal/plugin/codegen_vtproto.pb.go | 18 +++++++++--------- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/docs/reference/config.md b/docs/reference/config.md index 2f6c5166c9..a348901990 100644 --- a/docs/reference/config.md +++ b/docs/reference/config.md @@ -111,8 +111,8 @@ The `gen` mapping supports the following keys: - `emit_all_enum_values`: - If true, emit a function per enum type that returns all valid enum values. -- `json_tags_id_camelcase`: - - If true, "ID" in json tags will be camelcase. If false, will be uppercase. 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`: - `camel` for camelCase, `pascal` for PascalCase, `snake` for snake_case or `none` to use the column name in the DB. Defaults to `none`. - `output_batch_file_name`: diff --git a/internal/cmd/shim.go b/internal/cmd/shim.go index fc8acf6676..c4049ac056 100644 --- a/internal/cmd/shim.go +++ b/internal/cmd/shim.go @@ -84,7 +84,7 @@ func pluginGoCode(s config.SQLGo) *plugin.GoCode { return &plugin.GoCode{ EmitInterface: s.EmitInterface, EmitJsonTags: s.EmitJSONTags, - JsonTagsIDCamelcase: s.JsonTagsIDCamelcase, + JsonTagsIDUppercase: s.JsonTagsIDUppercase, EmitDbTags: s.EmitDBTags, EmitPreparedQueries: s.EmitPreparedQueries, EmitExactTableNames: s.EmitExactTableNames, diff --git a/internal/codegen/golang/field.go b/internal/codegen/golang/field.go index cfd70f46c1..0098eb9fc4 100644 --- a/internal/codegen/golang/field.go +++ b/internal/codegen/golang/field.go @@ -42,11 +42,11 @@ func TagsToString(tags map[string]string) string { func JSONTagName(name string, settings *plugin.Settings) string { style := settings.Go.JsonTagsCaseStyle - idCamelcase := settings.Go.JsonTagsIDCamelcase + idUppercase := settings.Go.JsonTagsIDUppercase if style == "" || style == "none" { return name } else { - return SetJSONCaseStyle(name, style, idCamelcase) + return SetJSONCaseStyle(name, style, idUppercase) } } @@ -63,10 +63,10 @@ func SetCaseStyle(name string, style string) string { } } -func SetJSONCaseStyle(name string, style string, idCamelcase bool) string { +func SetJSONCaseStyle(name string, style string, idUppercase bool) string { switch style { case "camel": - return toJsonCamelCase(name, idCamelcase) + return toJsonCamelCase(name, idUppercase) case "pascal": return toPascalCase(name) case "snake": @@ -111,12 +111,12 @@ func toCamelInitCase(name string, initUpper bool) string { return out } -func toJsonCamelCase(name string, idCamelcase bool) string { +func toJsonCamelCase(name string, idUppercase bool) string { out := "" - idStr := "ID" + idStr := "Id" - if idCamelcase { - idStr = "Id" + if idUppercase { + idStr = "ID" } for i, p := range strings.Split(name, "_") { diff --git a/internal/codegen/golang/gen.go b/internal/codegen/golang/gen.go index b183c9afa6..d0c21b397e 100644 --- a/internal/codegen/golang/gen.go +++ b/internal/codegen/golang/gen.go @@ -28,7 +28,7 @@ type tmplCtx struct { SourceName string EmitJSONTags bool - JsonTagsIDCamelcase bool + JsonTagsIDUppercase bool EmitDBTags bool EmitPreparedQueries bool EmitInterface bool @@ -123,7 +123,7 @@ func generate(req *plugin.CodeGenRequest, enums []Enum, structs []Struct, querie tctx := tmplCtx{ EmitInterface: golang.EmitInterface, EmitJSONTags: golang.EmitJsonTags, - JsonTagsIDCamelcase: golang.JsonTagsIDCamelcase, + JsonTagsIDUppercase: golang.JsonTagsIDUppercase, EmitDBTags: golang.EmitDbTags, EmitPreparedQueries: golang.EmitPreparedQueries, EmitEmptySlices: golang.EmitEmptySlices, diff --git a/internal/config/config.go b/internal/config/config.go index c50eb20d6f..86f03f4757 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -119,7 +119,7 @@ type SQLGen struct { type SQLGo struct { EmitInterface bool `json:"emit_interface" yaml:"emit_interface"` EmitJSONTags bool `json:"emit_json_tags" yaml:"emit_json_tags"` - JsonTagsIDCamelcase bool `json:"json_tags_id_camelcase" yaml:"json_tags_id_camelcase"` + JsonTagsIDUppercase bool `json:"json_tags_id_uppercase" yaml:"json_tags_id_uppercase"` 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"` diff --git a/internal/config/v_one.go b/internal/config/v_one.go index fe284d0a17..1d9a29b2df 100644 --- a/internal/config/v_one.go +++ b/internal/config/v_one.go @@ -25,7 +25,7 @@ type v1PackageSettings struct { Queries Paths `json:"queries" yaml:"queries"` EmitInterface bool `json:"emit_interface" yaml:"emit_interface"` EmitJSONTags bool `json:"emit_json_tags" yaml:"emit_json_tags"` - JsonTagsIDCamelcase bool `json:"json_tags_id_camelcase" yaml:"json_tags_id_camelcase"` + JsonTagsIDUppercase bool `json:"json_tags_id_uppercase" yaml:"json_tags_id_uppercase"` 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"` @@ -144,7 +144,7 @@ func (c *V1GenerateSettings) Translate() Config { Go: &SQLGo{ EmitInterface: pkg.EmitInterface, EmitJSONTags: pkg.EmitJSONTags, - JsonTagsIDCamelcase: pkg.JsonTagsIDCamelcase, + JsonTagsIDUppercase: pkg.JsonTagsIDUppercase, EmitDBTags: pkg.EmitDBTags, EmitPreparedQueries: pkg.EmitPreparedQueries, EmitExactTableNames: pkg.EmitExactTableNames, diff --git a/internal/plugin/codegen.pb.go b/internal/plugin/codegen.pb.go index fb3f5c9e63..3b91d2cfed 100644 --- a/internal/plugin/codegen.pb.go +++ b/internal/plugin/codegen.pb.go @@ -467,7 +467,7 @@ type GoCode struct { EmitPointersForNullTypes bool `protobuf:"varint,22,opt,name=emit_pointers_for_null_types,json=emitPointersForNullTypes,proto3" json:"emit_pointers_for_null_types,omitempty"` QueryParameterLimit *int32 `protobuf:"varint,23,opt,name=query_parameter_limit,json=queryParameterLimit,proto3,oneof" json:"query_parameter_limit,omitempty"` OutputBatchFileName string `protobuf:"bytes,24,opt,name=output_batch_file_name,json=outputBatchFileName,proto3" json:"output_batch_file_name,omitempty"` - JsonTagsIDCamelcase bool `protobuf:"varint,26,opt,name=json_tags_id_camelcase,json=jsonTagsIdCamelcase,proto3" json:"json_tags_id_camelcase,omitempty"` + JsonTagsIDUppercase bool `protobuf:"varint,26,opt,name=json_tags_id_uppercase,json=jsonTagsIdCamelcase,proto3" json:"json_tags_id_uppercase,omitempty"` } func (x *GoCode) Reset() { @@ -516,11 +516,11 @@ func (x *GoCode) GetEmitJsonTags() bool { return false } -func (x *GoCode) GetJsonTagsIDCamelcase() bool { +func (x *GoCode) GetJsonTagsIDUppercase() bool { if x != nil { - return x.JsonTagsIDCamelcase + return x.JsonTagsIDUppercase } - return false + return true } func (x *GoCode) GetEmitDbTags() bool { diff --git a/internal/plugin/codegen_vtproto.pb.go b/internal/plugin/codegen_vtproto.pb.go index b8c31b80de..c9e50c3a2d 100644 --- a/internal/plugin/codegen_vtproto.pb.go +++ b/internal/plugin/codegen_vtproto.pb.go @@ -172,7 +172,7 @@ func (m *GoCode) CloneVT() *GoCode { r := &GoCode{ EmitInterface: m.EmitInterface, EmitJsonTags: m.EmitJsonTags, - JsonTagsIDCamelcase: m.JsonTagsIDCamelcase, + JsonTagsIDUppercase: m.JsonTagsIDUppercase, EmitDbTags: m.EmitDbTags, EmitPreparedQueries: m.EmitPreparedQueries, EmitExactTableNames: m.EmitExactTableNames, @@ -755,7 +755,7 @@ func (this *GoCode) EqualVT(that *GoCode) bool { if this.EmitJsonTags != that.EmitJsonTags { return false } - if this.JsonTagsIDCamelcase != that.JsonTagsIDCamelcase { + if this.JsonTagsIDUppercase != that.JsonTagsIDUppercase { return false } if this.EmitDbTags != that.EmitDbTags { @@ -2000,9 +2000,9 @@ func (m *GoCode) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i-- dAtA[i] = 0x10 } - if m.JsonTagsIDCamelcase { + if m.JsonTagsIDUppercase { i-- - if m.JsonTagsIDCamelcase { + if m.JsonTagsIDUppercase { dAtA[i] = 1 } else { dAtA[i] = 0 @@ -3572,9 +3572,9 @@ func (m *GoCode) MarshalToSizedBufferVTStrict(dAtA []byte) (int, error) { i-- dAtA[i] = 0x10 } - if m.JsonTagsIDCamelcase { + if m.JsonTagsIDUppercase { i-- - if m.JsonTagsIDCamelcase { + if m.JsonTagsIDUppercase { dAtA[i] = 1 } else { dAtA[i] = 0 @@ -4629,7 +4629,7 @@ func (m *GoCode) SizeVT() (n int) { if m.EmitJsonTags { n += 2 } - if m.JsonTagsIDCamelcase { + if m.JsonTagsIDUppercase { n += 2 } if m.EmitDbTags { @@ -7036,7 +7036,7 @@ func (m *GoCode) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex case 26: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field JsonTagsIDCamelcase", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field JsonTagsIDUppercase", wireType) } var v int for shift := uint(0); ; shift += 7 { @@ -7053,7 +7053,7 @@ func (m *GoCode) UnmarshalVT(dAtA []byte) error { break } } - m.JsonTagsIDCamelcase = bool(v != 0) + m.JsonTagsIDUppercase = bool(v != 0) default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:])