@@ -8,8 +8,12 @@ import (
88 "io"
99 "os"
1010 "path/filepath"
11+ "runtime"
1112 "runtime/trace"
1213 "strings"
14+ "sync"
15+
16+ "golang.org/x/sync/errgroup"
1317
1418 "github.com/kyleconroy/sqlc/internal/codegen/golang"
1519 "github.com/kyleconroy/sqlc/internal/codegen/json"
@@ -159,71 +163,94 @@ func Generate(ctx context.Context, e Env, dir, filename string, stderr io.Writer
159163 }
160164 }
161165
162- for _ , sql := range pairs {
163- combo := config .Combine (* conf , sql .SQL )
164- if sql .Plugin != nil {
165- combo .Codegen = * sql .Plugin
166- }
166+ var m sync.Mutex
167+ grp , gctx := errgroup .WithContext (ctx )
168+ grp .SetLimit (runtime .GOMAXPROCS (0 ))
167169
168- // TODO: This feels like a hack that will bite us later
169- joined := make ([]string , 0 , len (sql .Schema ))
170- for _ , s := range sql .Schema {
171- joined = append (joined , filepath .Join (dir , s ))
172- }
173- sql .Schema = joined
170+ stderrs := make ([]bytes.Buffer , len (pairs ))
174171
175- joined = make ([]string , 0 , len (sql .Queries ))
176- for _ , q := range sql .Queries {
177- joined = append (joined , filepath .Join (dir , q ))
178- }
179- sql .Queries = joined
172+ for i , pair := range pairs {
173+ sql := pair
174+ errout := & stderrs [i ]
180175
181- var name , lang string
182- parseOpts := opts.Parser {
183- Debug : debug .Debug ,
184- }
176+ grp .Go (func () error {
177+ combo := config .Combine (* conf , sql .SQL )
178+ if sql .Plugin != nil {
179+ combo .Codegen = * sql .Plugin
180+ }
185181
186- switch {
187- case sql .Gen .Go != nil :
188- name = combo .Go .Package
189- lang = "golang"
182+ // TODO: This feels like a hack that will bite us later
183+ joined := make ([]string , 0 , len (sql .Schema ))
184+ for _ , s := range sql .Schema {
185+ joined = append (joined , filepath .Join (dir , s ))
186+ }
187+ sql .Schema = joined
190188
191- case sql .Plugin != nil :
192- lang = fmt .Sprintf ("process:%s" , sql .Plugin .Plugin )
193- name = sql .Plugin .Plugin
194- }
189+ joined = make ([]string , 0 , len (sql .Queries ))
190+ for _ , q := range sql .Queries {
191+ joined = append (joined , filepath .Join (dir , q ))
192+ }
193+ sql .Queries = joined
195194
196- packageRegion := trace .StartRegion (ctx , "package" )
197- trace .Logf (ctx , "" , "name=%s dir=%s plugin=%s" , name , dir , lang )
195+ var name , lang string
196+ parseOpts := opts.Parser {
197+ Debug : debug .Debug ,
198+ }
198199
199- result , failed := parse (ctx , name , dir , sql .SQL , combo , parseOpts , stderr )
200- if failed {
201- packageRegion .End ()
202- errored = true
203- break
204- }
200+ switch {
201+ case sql .Gen .Go != nil :
202+ name = combo .Go .Package
203+ lang = "golang"
205204
206- out , resp , err := codegen (ctx , combo , sql , result )
207- if err != nil {
208- fmt .Fprintf (stderr , "# package %s\n " , name )
209- fmt .Fprintf (stderr , "error generating code: %s\n " , err )
210- errored = true
211- packageRegion .End ()
212- continue
213- }
205+ case sql .Plugin != nil :
206+ lang = fmt .Sprintf ("process:%s" , sql .Plugin .Plugin )
207+ name = sql .Plugin .Plugin
208+ }
214209
215- files := map [string ]string {}
216- for _ , file := range resp .Files {
217- files [file .Name ] = string (file .Contents )
218- }
219- for n , source := range files {
220- filename := filepath .Join (dir , out , n )
221- output [filename ] = source
222- }
223- packageRegion .End ()
224- }
210+ packageRegion := trace .StartRegion (gctx , "package" )
211+ trace .Logf (gctx , "" , "name=%s dir=%s plugin=%s" , name , dir , lang )
212+
213+ result , failed := parse (gctx , name , dir , sql .SQL , combo , parseOpts , errout )
214+ if failed {
215+ packageRegion .End ()
216+ errored = true
217+ return nil
218+ }
219+
220+ out , resp , err := codegen (gctx , combo , sql , result )
221+ if err != nil {
222+ fmt .Fprintf (errout , "# package %s\n " , name )
223+ fmt .Fprintf (errout , "error generating code: %s\n " , err )
224+ errored = true
225+ packageRegion .End ()
226+ return nil
227+ }
228+
229+ files := map [string ]string {}
230+ for _ , file := range resp .Files {
231+ files [file .Name ] = string (file .Contents )
232+ }
225233
234+ m .Lock ()
235+ for n , source := range files {
236+ filename := filepath .Join (dir , out , n )
237+ output [filename ] = source
238+ }
239+ m .Unlock ()
240+
241+ packageRegion .End ()
242+ return nil
243+ })
244+ }
245+ if err := grp .Wait (); err != nil {
246+ return nil , err
247+ }
226248 if errored {
249+ for i , _ := range stderrs {
250+ if _ , err := io .Copy (stderr , & stderrs [i ]); err != nil {
251+ return nil , err
252+ }
253+ }
227254 return nil , fmt .Errorf ("errored" )
228255 }
229256 return output , nil
0 commit comments