Skip to content

Commit 36f4272

Browse files
committed
add ability to exclude whole type
1 parent b0eba42 commit 36f4272

4 files changed

Lines changed: 89 additions & 27 deletions

File tree

README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ It has the capability to create a GraphQL schema based on the database schema, a
3030
author(id: UUID!): Author!
3131
```
3232
- Add the ability to rename Row type names by golang type names
33-
- Exclude types from the schema generation
3433
- Add config to generate everything in one file
3534
- Make the ability to generate query from comment that is like this
3635
```sql
@@ -87,11 +86,15 @@ sql:
8786
## override GO type with a custom GraphQL type
8887
- go_type: "tutorial/tutorial.NullImage"
8988
gql_type: "Image"
90-
## exclude columns from the generated schema
91-
## Test - is the generated Graphql object
92-
## and CreatedAt is the column name to be excluded
89+
## exclude entire graphql types or specific fields
9390
exclude:
94-
- "Test.CreatedAt"
91+
## Exclude one specific field from a type
92+
- "Author.CreatedAt"
93+
## You can exclude multiple fields from the same type
94+
- "Author.UpdatedAt"
95+
- "Author.DeletedAt"
96+
## Exclude an entire type from the schema
97+
- "BookAuthor"
9598
## rename the GraphQL type
9699
rename:
97100
## renames like this type RenamedAuthor @goModel(model: "authors/storage.Author")
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Code generated by sqlc. DO NOT EDIT.
2+
# versions:
3+
# sqlc v1.27.0
4+
5+
6+
enum Status @goModel(model: "authors/storage.Status") {
7+
active
8+
inactive
9+
}
10+
11+

internal/gen_gql.go

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ import (
44
"bufio"
55
"bytes"
66
"errors"
7-
"github.com/debugger84/sqlc-graphql/internal/opts"
8-
"github.com/sqlc-dev/plugin-sdk-go/plugin"
9-
"github.com/sqlc-dev/plugin-sdk-go/sdk"
107
"slices"
118
"strings"
129
"text/template"
10+
11+
"github.com/debugger84/sqlc-graphql/internal/opts"
12+
"github.com/sqlc-dev/plugin-sdk-go/plugin"
13+
"github.com/sqlc-dev/plugin-sdk-go/sdk"
1314
)
1415

1516
type gqlTmplCtx struct {
@@ -40,11 +41,11 @@ func generateGql(
4041
structs []Struct,
4142
queries []Query,
4243
) (*plugin.GenerateResponse, error) {
43-
excludedFields, err := getGqlExcluded(options)
44+
excludedTypes, excludedFields, err := getGqlExcluded(options)
4445
if err != nil {
4546
return nil, err
4647
}
47-
structs = filterStructs(structs, excludedFields)
48+
structs = filterStructs(structs, excludedTypes, excludedFields)
4849

4950
tctx := gqlTmplCtx{
5051
ModelPackage: options.Package,
@@ -75,7 +76,7 @@ func generateGql(
7576
var b bytes.Buffer
7677
w := bufio.NewWriter(&b)
7778
tctx.SourceName = name
78-
tctx.GoQueries = filterQueries(name, queries, excludedFields)
79+
tctx.GoQueries = filterQueries(name, queries, excludedTypes, excludedFields)
7980
tctx.ExtendedTypes = getExtendedTypes(tctx.GoQueries)
8081
err := tmpl.ExecuteTemplate(w, templateName, &tctx)
8182
w.Flush()
@@ -155,20 +156,25 @@ func extractGqlCommentsOnly(comments []string) []string {
155156

156157
}
157158

158-
func filterQueries(sourceName string, queries []Query, excludedFields map[string][]string) []Query {
159+
func filterQueries(
160+
sourceName string,
161+
queries []Query,
162+
excludedTypes map[string]struct{},
163+
excludedFields map[string][]string,
164+
) []Query {
159165
var result []Query
160166
for _, q := range queries {
161167
if q.SourceName == sourceName {
162168
q.Comments = extractGqlCommentsOnly(q.Comments)
163169
if q.Arg.Struct != nil {
164-
args := filterStructs([]Struct{*q.Arg.Struct}, excludedFields)
170+
args := filterStructs([]Struct{*q.Arg.Struct}, excludedTypes, excludedFields)
165171
if len(args) == 1 {
166172
q.Arg.Struct = &args[0]
167173
}
168174
}
169175

170176
if q.Ret.Struct != nil {
171-
returns := filterStructs([]Struct{*q.Ret.Struct}, excludedFields)
177+
returns := filterStructs([]Struct{*q.Ret.Struct}, excludedTypes, excludedFields)
172178
if len(returns) == 1 {
173179
q.Ret.Struct = &returns[0]
174180
}
@@ -194,36 +200,52 @@ func getExtendedTypes(queries []Query) []string {
194200
return result
195201
}
196202

197-
func getGqlExcluded(options *opts.Options) (map[string][]string, error) {
198-
res := make(map[string][]string)
203+
func getGqlExcluded(options *opts.Options) (
204+
excludedTypes map[string]struct{},
205+
excludedFields map[string][]string,
206+
err error,
207+
) {
208+
excludedTypes = make(map[string]struct{})
209+
excludedFields = make(map[string][]string)
199210
if options == nil || options.Exclude == nil {
200-
return nil, nil
211+
return
201212
}
202213
for _, exclude := range options.Exclude {
203214
parts := strings.Split(exclude, ".")
204215

205216
if len(parts) == 0 {
206217
continue
207218
}
208-
209-
if len(parts) != 2 {
210-
return nil, errors.New("invalid exclude format. It should be in the format of 'GqlTypeName.fieldName'")
219+
if len(parts) > 2 {
220+
err = errors.New("invalid exclude format. To exclude single field from type use 'GqlTypeName.fieldName'. To exclude entire type use 'GqlTypeName'")
221+
return
211222
}
212223
typeName := strings.ToLower(parts[0])
213-
fieldName := strings.ToLower(parts[1])
214-
if _, ok := res[typeName]; !ok {
215-
res[typeName] = make([]string, 0)
224+
if len(parts) == 1 {
225+
excludedTypes[typeName] = struct{}{}
226+
continue
227+
}
228+
if _, ok := excludedFields[typeName]; !ok {
229+
excludedFields[typeName] = make([]string, 0)
216230
}
217-
res[typeName] = append(res[typeName], fieldName)
231+
fieldName := strings.ToLower(parts[1])
232+
excludedFields[typeName] = append(excludedFields[typeName], fieldName)
218233
}
219-
return res, nil
234+
return
220235
}
221236

222-
func filterStructs(structs []Struct, excludeFields map[string][]string) []Struct {
237+
func filterStructs(
238+
structs []Struct,
239+
excludedTypes map[string]struct{},
240+
excludeFields map[string][]string,
241+
) []Struct {
223242
var result []Struct
224243
for _, s := range structs {
225244
var fields []Field
226245
structName := strings.ToLower(s.Name)
246+
if _, ok := excludedTypes[structName]; ok {
247+
continue
248+
}
227249
for _, f := range s.Fields {
228250
if _, ok := excludeFields[structName]; ok {
229251
fieldName := strings.ToLower(f.Name)

internal/gen_test.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package golang_test
33
import (
44
"context"
55
"encoding/json"
6+
"testing"
7+
68
golang "github.com/debugger84/sqlc-graphql/internal"
79
"github.com/debugger84/sqlc-graphql/internal/opts"
810
"github.com/gkampitakis/go-snaps/snaps"
911
"github.com/sqlc-dev/plugin-sdk-go/plugin"
1012
"github.com/stretchr/testify/require"
11-
"testing"
1213
)
1314

1415
func TestGenerate(t *testing.T) {
@@ -153,6 +154,31 @@ func TestGenerate(t *testing.T) {
153154
},
154155
)
155156

157+
t.Run(
158+
"Exclude type", func(t *testing.T) {
159+
factory := NewGenReqFactory()
160+
factory.options.Exclude = []string{"Author"}
161+
req := factory.GenerateRequest()
162+
163+
resp, err := golang.Generate(ctx, req)
164+
165+
t.Log("Given the option to exclude the Author type is passed to the generator")
166+
t.Log("When the generator is called")
167+
t.Log(" Then the generator should return a response without an error")
168+
require.NoError(t, err)
169+
t.Log(" And the response should not contain Author type")
170+
require.NotNil(t, resp)
171+
require.Len(t, resp.Files, 2)
172+
for _, file := range resp.Files {
173+
if file.Name == "schema.graphql" {
174+
snaps.WithConfig(snaps.Ext("."+file.Name)).
175+
MatchStandaloneSnapshot(t, string(file.Contents))
176+
require.NotContains(t, string(file.Contents), "type Author")
177+
}
178+
}
179+
},
180+
)
181+
156182
t.Run(
157183
"Add directive to query", func(t *testing.T) {
158184
factory := NewGenReqFactory()

0 commit comments

Comments
 (0)