Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ sql:
out: "ent/query"
options:
tables:
include:
- "users"
- "auth.accounts"
exclude:
- "audit_logs"
- "auth.sessions"
Expand All @@ -68,9 +71,13 @@ sql:
- "GetUserWithPost"
```

Use `options.tables.exclude` to skip generating query files for tables that
should not be managed by sqlc. Entries may be table names (`audit_logs`) or
schema-qualified table names (`auth.sessions`).
Use `options.tables` to control which tables get query files. Entries may be
table names (`audit_logs`) or schema-qualified table names (`auth.sessions`).

- `include` is an allow-list: when non-empty, only the listed tables are
generated. When omitted or empty, every table is generated.
- `exclude` is a deny-list that always takes precedence over `include`, so a
table present in both lists is skipped.

### Default queries (always generated)

Expand Down
2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
inherit version;
src = pkgs.lib.cleanSource ./.;
subPackages = [ "cmd/sqlc-gen-queries" ];
vendorHash = "sha256-+p3CtZbFv2NQV8d2HI1wFBW2jbn4a9kc3+6qtjoLl8c=";
vendorHash = "sha256-DJWhLrSOSAy1VjJS9BjVYqws8nQShWr7Y89vjWDO8VQ=";
doInstallCheck = true;
installCheckPhase = ''
$out/bin/sqlc-gen-queries --help
Expand Down
34 changes: 30 additions & 4 deletions internal/sqlc/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ type CodegenOptions struct {
}

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

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

// GetExcludeSet returns a set of table names to skip during query generation.
// Entries may be unqualified table names or schema-qualified names.
// GetIncludeSet returns the allow-list of table names for query generation.
// Entries may be unqualified table names or schema-qualified names. An empty
// set means every table is included.
func (s *SQL) GetIncludeSet() map[string]bool {
opts := s.GetOptions()
includeSet := make(map[string]bool, len(opts.Tables.Include))
for _, name := range opts.Tables.Include {
includeSet[name] = true
}
return includeSet
}

// GetExcludeSet returns the deny-list of table names to skip during query
// generation. Entries may be unqualified table names or schema-qualified names.
func (s *SQL) GetExcludeSet() map[string]bool {
opts := s.GetOptions()
excludeSet := make(map[string]bool, len(opts.Tables.Exclude))
Expand All @@ -113,6 +128,17 @@ func (s *SQL) GetExcludeSet() map[string]bool {
return excludeSet
}

func tableExcluded(excludeSet map[string]bool, schema, table string) bool {
return excludeSet[table] || excludeSet[schema+"."+table]
// tableSelected reports whether a table should have query files generated.
// Exclude always takes precedence over include; an empty include set matches
// every table. Both sets are checked against the unqualified table name and
// the schema-qualified name (schema.table).
func tableSelected(includeSet, excludeSet map[string]bool, schema, table string) bool {
qualified := schema + "." + table
if excludeSet[table] || excludeSet[qualified] {
return false
}
if len(includeSet) == 0 {
return true
}
return includeSet[table] || includeSet[qualified]
}
43 changes: 43 additions & 0 deletions internal/sqlc/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,47 @@ var _ = Describe("Config", func() {
Expect(excludeSet["posts"]).To(BeFalse())
})
})

Describe("SQL.GetIncludeSet", func() {
It("returns an empty map when codegen is nil", func() {
sql := sqlc.SQL{}
includeSet := sql.GetIncludeSet()
Expect(includeSet).NotTo(BeNil())
Expect(includeSet).To(BeEmpty())
})

It("returns an empty map when include is empty", func() {
sql := sqlc.SQL{
Codegen: []sqlc.Codegen{
{
Plugin: "gen-queries",
Out: "out",
Options: sqlc.CodegenOptions{Tables: sqlc.TableOptions{Include: []string{}}},
},
},
}
includeSet := sql.GetIncludeSet()
Expect(includeSet).NotTo(BeNil())
Expect(includeSet).To(BeEmpty())
})

It("returns a map with included table names", func() {
sql := sqlc.SQL{
Codegen: []sqlc.Codegen{
{
Plugin: "gen-queries",
Out: "out",
Options: sqlc.CodegenOptions{
Tables: sqlc.TableOptions{Include: []string{"users", "analytics.events"}},
},
},
},
}
includeSet := sql.GetIncludeSet()
Expect(includeSet).To(HaveLen(2))
Expect(includeSet["users"]).To(BeTrue())
Expect(includeSet["analytics.events"]).To(BeTrue())
Expect(includeSet["posts"]).To(BeFalse())
})
})
})
3 changes: 2 additions & 1 deletion internal/sqlc/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,12 @@ func (x *Generator) Generate() error {
}

queries := config.GetQueriesSet()
include := config.GetIncludeSet()
exclude := config.GetExcludeSet()

for _, schema := range x.Catalog.Schemas {
for _, table := range schema.Tables {
if tableExcluded(exclude, schema.Name, table.Name) {
if !tableSelected(include, exclude, schema.Name, table.Name) {
continue
}

Expand Down
43 changes: 43 additions & 0 deletions internal/sqlc/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,49 @@ var _ = Describe("Generator", func() {
}
})

It("generates only included tables", func() {
dir := generator.Config.SQL[0].Queries
generator.Config.SQL[0].Codegen = []sqlc.Codegen{
{
Plugin: "gen-queries",
Out: dir,
Options: sqlc.CodegenOptions{
Tables: sqlc.TableOptions{Include: []string{"public.users"}},
},
},
}

Expect(generator.Generate()).NotTo(HaveOccurred())

for _, config := range generator.Config.SQL {
Expect(filepath.Join(config.Queries, "users.sql")).To(BeAnExistingFile())
Expect(filepath.Join(config.Queries, "posts.sql")).NotTo(BeAnExistingFile())
}
})

It("excludes tables even when they are included", func() {
dir := generator.Config.SQL[0].Queries
generator.Config.SQL[0].Codegen = []sqlc.Codegen{
{
Plugin: "gen-queries",
Out: dir,
Options: sqlc.CodegenOptions{
Tables: sqlc.TableOptions{
Include: []string{"users", "posts"},
Exclude: []string{"posts"},
},
},
},
}

Expect(generator.Generate()).NotTo(HaveOccurred())

for _, config := range generator.Config.SQL {
Expect(filepath.Join(config.Queries, "users.sql")).To(BeAnExistingFile())
Expect(filepath.Join(config.Queries, "posts.sql")).NotTo(BeAnExistingFile())
}
})

It("generates valid SQL content with default PK queries", func() {
err := generator.Generate()
Expect(err).NotTo(HaveOccurred())
Expand Down