Skip to content

Commit b2698bb

Browse files
authored
Add table include option (#49)
* feat: add options.tables.include allow-list Add an include allow-list alongside the existing exclude deny-list. When include is non-empty, only the listed tables are generated; an empty include matches all tables. Exclude always takes precedence over include. Both lists match unqualified and schema-qualified table names. Selection is unified in a single tableSelected predicate. * fix(flake): refresh vendorHash after gomod bumps go.mod was bumped (inflect, ginkgo, gomega, urfave/cli) without regenerating the Nix vendorHash, causing buildGoModule to build against a stale vendor dir and fail with inconsistent vendoring. --------- Co-authored-by: Svetlin Ralchev <iamralch@users.noreply.github.com>
1 parent 96299d5 commit b2698bb

5 files changed

Lines changed: 128 additions & 8 deletions

File tree

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ sql:
6060
out: "ent/query"
6161
options:
6262
tables:
63+
include:
64+
- "users"
65+
- "auth.accounts"
6366
exclude:
6467
- "audit_logs"
6568
- "auth.sessions"
@@ -68,9 +71,13 @@ sql:
6871
- "GetUserWithPost"
6972
```
7073
71-
Use `options.tables.exclude` to skip generating query files for tables that
72-
should not be managed by sqlc. Entries may be table names (`audit_logs`) or
73-
schema-qualified table names (`auth.sessions`).
74+
Use `options.tables` to control which tables get query files. Entries may be
75+
table names (`audit_logs`) or schema-qualified table names (`auth.sessions`).
76+
77+
- `include` is an allow-list: when non-empty, only the listed tables are
78+
generated. When omitted or empty, every table is generated.
79+
- `exclude` is a deny-list that always takes precedence over `include`, so a
80+
table present in both lists is skipped.
7481

7582
### Default queries (always generated)
7683

internal/sqlc/config.go

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,10 @@ type CodegenOptions struct {
7676
}
7777

7878
// TableOptions holds table-level filtering options for the gen-queries plugin.
79+
// Include is an allow-list: when non-empty, only the listed tables are
80+
// generated. Exclude is a deny-list that always takes precedence over Include.
7981
type TableOptions struct {
82+
Include []string `yaml:"include,omitempty"`
8083
Exclude []string `yaml:"exclude,omitempty"`
8184
}
8285

@@ -102,8 +105,20 @@ func (s *SQL) GetQueriesSet() map[string]bool {
102105
return querySet
103106
}
104107

105-
// GetExcludeSet returns a set of table names to skip during query generation.
106-
// Entries may be unqualified table names or schema-qualified names.
108+
// GetIncludeSet returns the allow-list of table names for query generation.
109+
// Entries may be unqualified table names or schema-qualified names. An empty
110+
// set means every table is included.
111+
func (s *SQL) GetIncludeSet() map[string]bool {
112+
opts := s.GetOptions()
113+
includeSet := make(map[string]bool, len(opts.Tables.Include))
114+
for _, name := range opts.Tables.Include {
115+
includeSet[name] = true
116+
}
117+
return includeSet
118+
}
119+
120+
// GetExcludeSet returns the deny-list of table names to skip during query
121+
// generation. Entries may be unqualified table names or schema-qualified names.
107122
func (s *SQL) GetExcludeSet() map[string]bool {
108123
opts := s.GetOptions()
109124
excludeSet := make(map[string]bool, len(opts.Tables.Exclude))
@@ -113,6 +128,17 @@ func (s *SQL) GetExcludeSet() map[string]bool {
113128
return excludeSet
114129
}
115130

116-
func tableExcluded(excludeSet map[string]bool, schema, table string) bool {
117-
return excludeSet[table] || excludeSet[schema+"."+table]
131+
// tableSelected reports whether a table should have query files generated.
132+
// Exclude always takes precedence over include; an empty include set matches
133+
// every table. Both sets are checked against the unqualified table name and
134+
// the schema-qualified name (schema.table).
135+
func tableSelected(includeSet, excludeSet map[string]bool, schema, table string) bool {
136+
qualified := schema + "." + table
137+
if excludeSet[table] || excludeSet[qualified] {
138+
return false
139+
}
140+
if len(includeSet) == 0 {
141+
return true
142+
}
143+
return includeSet[table] || includeSet[qualified]
118144
}

internal/sqlc/config_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,47 @@ var _ = Describe("Config", func() {
190190
Expect(excludeSet["posts"]).To(BeFalse())
191191
})
192192
})
193+
194+
Describe("SQL.GetIncludeSet", func() {
195+
It("returns an empty map when codegen is nil", func() {
196+
sql := sqlc.SQL{}
197+
includeSet := sql.GetIncludeSet()
198+
Expect(includeSet).NotTo(BeNil())
199+
Expect(includeSet).To(BeEmpty())
200+
})
201+
202+
It("returns an empty map when include is empty", func() {
203+
sql := sqlc.SQL{
204+
Codegen: []sqlc.Codegen{
205+
{
206+
Plugin: "gen-queries",
207+
Out: "out",
208+
Options: sqlc.CodegenOptions{Tables: sqlc.TableOptions{Include: []string{}}},
209+
},
210+
},
211+
}
212+
includeSet := sql.GetIncludeSet()
213+
Expect(includeSet).NotTo(BeNil())
214+
Expect(includeSet).To(BeEmpty())
215+
})
216+
217+
It("returns a map with included table names", func() {
218+
sql := sqlc.SQL{
219+
Codegen: []sqlc.Codegen{
220+
{
221+
Plugin: "gen-queries",
222+
Out: "out",
223+
Options: sqlc.CodegenOptions{
224+
Tables: sqlc.TableOptions{Include: []string{"users", "analytics.events"}},
225+
},
226+
},
227+
},
228+
}
229+
includeSet := sql.GetIncludeSet()
230+
Expect(includeSet).To(HaveLen(2))
231+
Expect(includeSet["users"]).To(BeTrue())
232+
Expect(includeSet["analytics.events"]).To(BeTrue())
233+
Expect(includeSet["posts"]).To(BeFalse())
234+
})
235+
})
193236
})

internal/sqlc/generator.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,12 @@ func (x *Generator) Generate() error {
162162
}
163163

164164
queries := config.GetQueriesSet()
165+
include := config.GetIncludeSet()
165166
exclude := config.GetExcludeSet()
166167

167168
for _, schema := range x.Catalog.Schemas {
168169
for _, table := range schema.Tables {
169-
if tableExcluded(exclude, schema.Name, table.Name) {
170+
if !tableSelected(include, exclude, schema.Name, table.Name) {
170171
continue
171172
}
172173

internal/sqlc/generator_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,49 @@ var _ = Describe("Generator", func() {
7070
}
7171
})
7272

73+
It("generates only included tables", func() {
74+
dir := generator.Config.SQL[0].Queries
75+
generator.Config.SQL[0].Codegen = []sqlc.Codegen{
76+
{
77+
Plugin: "gen-queries",
78+
Out: dir,
79+
Options: sqlc.CodegenOptions{
80+
Tables: sqlc.TableOptions{Include: []string{"public.users"}},
81+
},
82+
},
83+
}
84+
85+
Expect(generator.Generate()).NotTo(HaveOccurred())
86+
87+
for _, config := range generator.Config.SQL {
88+
Expect(filepath.Join(config.Queries, "users.sql")).To(BeAnExistingFile())
89+
Expect(filepath.Join(config.Queries, "posts.sql")).NotTo(BeAnExistingFile())
90+
}
91+
})
92+
93+
It("excludes tables even when they are included", func() {
94+
dir := generator.Config.SQL[0].Queries
95+
generator.Config.SQL[0].Codegen = []sqlc.Codegen{
96+
{
97+
Plugin: "gen-queries",
98+
Out: dir,
99+
Options: sqlc.CodegenOptions{
100+
Tables: sqlc.TableOptions{
101+
Include: []string{"users", "posts"},
102+
Exclude: []string{"posts"},
103+
},
104+
},
105+
},
106+
}
107+
108+
Expect(generator.Generate()).NotTo(HaveOccurred())
109+
110+
for _, config := range generator.Config.SQL {
111+
Expect(filepath.Join(config.Queries, "users.sql")).To(BeAnExistingFile())
112+
Expect(filepath.Join(config.Queries, "posts.sql")).NotTo(BeAnExistingFile())
113+
}
114+
})
115+
73116
It("generates valid SQL content with default PK queries", func() {
74117
err := generator.Generate()
75118
Expect(err).NotTo(HaveOccurred())

0 commit comments

Comments
 (0)