Skip to content

Commit 325418e

Browse files
jskelcykyleconroy
andauthored
Schemas and queries can now be a list of paths (#426)
Co-authored-by: Kyle Conroy <kyle@conroy.org>
1 parent 463a07a commit 325418e

File tree

11 files changed

+135
-92
lines changed

11 files changed

+135
-92
lines changed

examples/authors/db_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
)
1212

1313
func TestAuthors(t *testing.T) {
14-
sdb, cleanup := sqltest.PostgreSQL(t, "schema.sql")
14+
sdb, cleanup := sqltest.PostgreSQL(t, []string{"schema.sql"})
1515
defer cleanup()
1616

1717
ctx := context.Background()

examples/booktest/postgresql/db_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@ package booktest
44

55
import (
66
"context"
7-
"path/filepath"
87
"testing"
98
"time"
109

1110
"github.com/kyleconroy/sqlc/internal/sqltest"
1211
)
1312

1413
func TestBooks(t *testing.T) {
15-
db, cleanup := sqltest.PostgreSQL(t, filepath.Join("schema.sql"))
14+
db, cleanup := sqltest.PostgreSQL(t, []string{"schema.sql"})
1615
defer cleanup()
1716

1817
ctx := context.Background()

examples/ondeck/db_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func runOnDeckQueries(t *testing.T, q *Queries) {
123123
func TestPrepared(t *testing.T) {
124124
t.Parallel()
125125

126-
sdb, cleanup := sqltest.PostgreSQL(t, "schema")
126+
sdb, cleanup := sqltest.PostgreSQL(t, []string{"schema"})
127127
defer cleanup()
128128

129129
q, err := Prepare(context.Background(), sdb)
@@ -137,7 +137,7 @@ func TestPrepared(t *testing.T) {
137137
func TestQueries(t *testing.T) {
138138
t.Parallel()
139139

140-
sdb, cleanup := sqltest.PostgreSQL(t, "schema")
140+
sdb, cleanup := sqltest.PostgreSQL(t, []string{"schema"})
141141
defer cleanup()
142142

143143
runOnDeckQueries(t, New(sdb))

go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,11 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
257257
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
258258
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
259259
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
260+
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
260261
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
261262
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
262263
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
264+
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
263265
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
264266
github.com/krishicks/yaml-patch v0.0.10/go.mod h1:Sm5TchwZS6sm7RJoyg87tzxm2ZcKzdRE4Q7TjNhPrME=
265267
github.com/lfittl/pg_query_go v1.0.0 h1:rcHZK5DBEUoxtO6dACP+UVCHKtA1ZsELBW0rSjOXMAE=
@@ -674,6 +676,7 @@ gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20180810215634-df19058c872c/go.mo
674676
gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
675677
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
676678
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
679+
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
677680
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
678681
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
679682
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=

internal/cmd/generate.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,17 @@ func Generate(dir string, stderr io.Writer) (map[string]string, error) {
113113
var result dinosql.Generateable
114114

115115
// TODO: This feels like a hack that will bite us later
116-
sql.Schema = filepath.Join(dir, sql.Schema)
117-
sql.Queries = filepath.Join(dir, sql.Queries)
116+
joined := make([]string, 0, len(sql.Schema))
117+
for _, s := range sql.Schema {
118+
joined = append(joined, filepath.Join(dir, s))
119+
}
120+
sql.Schema = joined
121+
122+
joined = make([]string, 0, len(sql.Queries))
123+
for _, q := range sql.Queries {
124+
joined = append(joined, filepath.Join(dir, q))
125+
}
126+
sql.Queries = joined
118127

119128
var name string
120129
parseOpts := dinosql.ParserOpts{}

internal/compiler/compile.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,15 @@ func Run(conf config.SQL, combo config.CombinedSettings) (*Result, error) {
7171
return nil, fmt.Errorf("unknown engine: %s", conf.Engine)
7272
}
7373

74-
rd, err := os.Open(conf.Schema)
75-
if err != nil {
76-
return nil, err
74+
blobs := make([]io.Reader, 0, len(conf.Schema))
75+
for _, s := range conf.Schema {
76+
b, err := os.Open(s)
77+
if err != nil {
78+
return nil, err
79+
}
80+
blobs = append(blobs, b)
7781
}
82+
rd := io.MultiReader(blobs...)
7883

7984
stmts, err := p.Parse(rd)
8085
if err != nil {

internal/config/config.go

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package config
22

33
import (
44
"bytes"
5+
"encoding/json"
56
"errors"
67
"fmt"
78
"go/types"
@@ -35,6 +36,39 @@ type versionSetting struct {
3536

3637
type Engine string
3738

39+
type Paths []string
40+
41+
func (p *Paths) UnmarshalJSON(data []byte) error {
42+
if string(data[0]) == `[` {
43+
var out []string
44+
if err := json.Unmarshal(data, &out); err != nil {
45+
return nil
46+
}
47+
*p = Paths(out)
48+
return nil
49+
}
50+
var out string
51+
if err := json.Unmarshal(data, &out); err != nil {
52+
return nil
53+
}
54+
*p = Paths([]string{out})
55+
return nil
56+
}
57+
58+
func (p *Paths) UnmarshalYAML(unmarshal func(interface{}) error) error {
59+
out := []string{}
60+
if sliceErr := unmarshal(&out); sliceErr != nil {
61+
var ele string
62+
if strErr := unmarshal(&ele); strErr != nil {
63+
return strErr
64+
}
65+
out = []string{ele}
66+
}
67+
68+
*p = Paths(out)
69+
return nil
70+
}
71+
3872
const (
3973
EngineMySQL Engine = "mysql"
4074
EnginePostgreSQL Engine = "postgresql"
@@ -67,8 +101,8 @@ type GenKotlin struct {
67101

68102
type SQL struct {
69103
Engine Engine `json:"engine,omitempty" yaml:"engine"`
70-
Schema string `json:"schema" yaml:"schema"`
71-
Queries string `json:"queries" yaml:"queries"`
104+
Schema Paths `json:"schema" yaml:"schema"`
105+
Queries Paths `json:"queries" yaml:"queries"`
72106
Gen SQLGen `json:"gen" yaml:"gen"`
73107
}
74108

internal/config/v_one.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ type v1PackageSettings struct {
1919
Name string `json:"name" yaml:"name"`
2020
Engine Engine `json:"engine,omitempty" yaml:"engine"`
2121
Path string `json:"path" yaml:"path"`
22-
Schema string `json:"schema" yaml:"schema"`
23-
Queries string `json:"queries" yaml:"queries"`
22+
Schema Paths `json:"schema" yaml:"schema"`
23+
Queries Paths `json:"queries" yaml:"queries"`
2424
EmitInterface bool `json:"emit_interface" yaml:"emit_interface"`
2525
EmitJSONTags bool `json:"emit_json_tags" yaml:"emit_json_tags"`
2626
EmitPreparedQueries bool `json:"emit_prepared_queries" yaml:"emit_prepared_queries"`

internal/dinosql/parser.go

Lines changed: 68 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -60,43 +60,34 @@ func (e *ParserErr) Error() string {
6060
return fmt.Sprintf("multiple errors: %d errors", len(e.Errs))
6161
}
6262

63-
func ReadSQLFiles(path string) ([]string, error) {
64-
f, err := os.Stat(path)
65-
if err != nil {
66-
return nil, fmt.Errorf("path %s does not exist", path)
67-
}
68-
63+
func ReadSQLFiles(paths []string) ([]string, error) {
6964
var files []string
70-
if f.IsDir() {
71-
listing, err := ioutil.ReadDir(path)
65+
for _, path := range paths {
66+
f, err := os.Stat(path)
7267
if err != nil {
73-
return nil, err
68+
return nil, fmt.Errorf("path %s does not exist", path)
7469
}
75-
for _, f := range listing {
76-
files = append(files, filepath.Join(path, f.Name()))
77-
}
78-
} else {
79-
files = append(files, path)
80-
}
8170

82-
var sql []string
83-
for _, filename := range files {
84-
if !strings.HasSuffix(filename, ".sql") {
85-
continue
86-
}
87-
if strings.HasPrefix(filepath.Base(filename), ".") {
88-
continue
71+
if f.IsDir() {
72+
listing, err := ioutil.ReadDir(path)
73+
if err != nil {
74+
return nil, err
75+
}
76+
for _, f := range listing {
77+
files = append(files, filepath.Join(path, f.Name()))
78+
}
79+
} else {
80+
files = append(files, path)
8981
}
90-
if migrations.IsDown(filename) {
82+
if migrations.IsDown(path) {
9183
continue
9284
}
93-
sql = append(sql, filename)
9485
}
95-
return sql, nil
86+
return files, nil
9687
}
9788

98-
func ParseCatalog(schema string) (core.Catalog, error) {
99-
files, err := ReadSQLFiles(schema)
89+
func ParseCatalog(schemas []string) (core.Catalog, error) {
90+
files, err := ReadSQLFiles(schemas)
10091
if err != nil {
10192
return core.Catalog{}, err
10293
}
@@ -197,73 +188,75 @@ type ParserOpts struct {
197188
UsePositionalParameters bool
198189
}
199190

200-
func ParseQueries(c core.Catalog, queries string, opts ParserOpts) (*Result, error) {
201-
f, err := os.Stat(queries)
202-
if err != nil {
203-
return nil, fmt.Errorf("path %s does not exist", queries)
204-
}
205-
206-
var files []string
207-
if f.IsDir() {
208-
listing, err := ioutil.ReadDir(queries)
209-
if err != nil {
210-
return nil, err
211-
}
212-
for _, f := range listing {
213-
files = append(files, filepath.Join(queries, f.Name()))
214-
}
215-
} else {
216-
files = append(files, queries)
217-
}
218-
191+
func ParseQueries(c core.Catalog, queriesPaths []string, opts ParserOpts) (*Result, error) {
219192
merr := NewParserErr()
220193
var q []*Query
221-
set := map[string]struct{}{}
222-
for _, filename := range files {
223-
if !strings.HasSuffix(filename, ".sql") {
224-
continue
225-
}
226-
if strings.HasPrefix(filepath.Base(filename), ".") {
227-
continue
228-
}
229-
blob, err := ioutil.ReadFile(filename)
194+
for _, queries := range queriesPaths {
195+
f, err := os.Stat(queries)
230196
if err != nil {
231-
merr.Add(filename, "", 0, err)
232-
continue
197+
return nil, fmt.Errorf("path %s does not exist", queries)
233198
}
234-
source := string(blob)
235-
tree, err := pg.Parse(source)
236-
if err != nil {
237-
merr.Add(filename, source, 0, err)
238-
continue
199+
200+
var files []string
201+
if f.IsDir() {
202+
listing, err := ioutil.ReadDir(queries)
203+
if err != nil {
204+
return nil, err
205+
}
206+
for _, f := range listing {
207+
files = append(files, filepath.Join(queries, f.Name()))
208+
}
209+
} else {
210+
files = append(files, queries)
239211
}
240-
for _, stmt := range tree.Statements {
241-
query, err := parseQuery(c, stmt, source, opts.UsePositionalParameters)
242-
if err == errUnsupportedStatementType {
212+
213+
set := map[string]struct{}{}
214+
for _, filename := range files {
215+
if !strings.HasSuffix(filename, ".sql") {
216+
continue
217+
}
218+
if strings.HasPrefix(filepath.Base(filename), ".") {
243219
continue
244220
}
221+
blob, err := ioutil.ReadFile(filename)
245222
if err != nil {
246-
merr.Add(filename, source, location(stmt), err)
223+
merr.Add(filename, "", 0, err)
247224
continue
248225
}
249-
if query.Name != "" {
250-
if _, exists := set[query.Name]; exists {
251-
merr.Add(filename, source, location(stmt), fmt.Errorf("duplicate query name: %s", query.Name))
226+
source := string(blob)
227+
tree, err := pg.Parse(source)
228+
if err != nil {
229+
merr.Add(filename, source, 0, err)
230+
continue
231+
}
232+
for _, stmt := range tree.Statements {
233+
query, err := parseQuery(c, stmt, source, opts.UsePositionalParameters)
234+
if err == errUnsupportedStatementType {
252235
continue
253236
}
254-
set[query.Name] = struct{}{}
255-
}
256-
query.Filename = filepath.Base(filename)
257-
if query != nil {
258-
q = append(q, query)
237+
if err != nil {
238+
merr.Add(filename, source, location(stmt), err)
239+
continue
240+
}
241+
if query.Name != "" {
242+
if _, exists := set[query.Name]; exists {
243+
merr.Add(filename, source, location(stmt), fmt.Errorf("duplicate query name: %s", query.Name))
244+
continue
245+
}
246+
set[query.Name] = struct{}{}
247+
}
248+
query.Filename = filepath.Base(filename)
249+
if query != nil {
250+
q = append(q, query)
251+
}
259252
}
260253
}
261254
}
262255
if len(merr.Errs) > 0 {
263256
return nil, merr
264257
}
265258
if len(q) == 0 {
266-
return nil, fmt.Errorf("path %s contains no queries", queries)
259+
return nil, fmt.Errorf("no queries contained in paths %s", strings.Join(queriesPaths, ","))
267260
}
268261
return &Result{
269262
Catalog: c,

internal/mysql/parse.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type Column struct {
3131
Table string
3232
}
3333

34-
func parsePath(sqlPath string, generator PackageGenerator) (*Result, error) {
34+
func parsePath(sqlPath []string, generator PackageGenerator) (*Result, error) {
3535
files, err := dinosql.ReadSQLFiles(sqlPath)
3636
if err != nil {
3737
return nil, err
@@ -464,7 +464,7 @@ func (pGen PackageGenerator) parseSelectAliasExpr(exprs sqlparser.SelectExprs, t
464464
}
465465

466466
// GeneratePkg is the main entry to mysql generator package
467-
func GeneratePkg(pkgName, schemaPath, querysPath string, settings config.CombinedSettings) (*Result, error) {
467+
func GeneratePkg(pkgName string, schemaPath, querysPath []string, settings config.CombinedSettings) (*Result, error) {
468468
s := NewSchema()
469469
generator := PackageGenerator{
470470
Schema: s,

internal/sqltest/postgres.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func id() string {
2929
return string(b)
3030
}
3131

32-
func PostgreSQL(t *testing.T, migrations string) (*sql.DB, func()) {
32+
func PostgreSQL(t *testing.T, migrations []string) (*sql.DB, func()) {
3333
t.Helper()
3434

3535
pgUser := os.Getenv("PG_USER")

0 commit comments

Comments
 (0)