Skip to content

Commit 5bd8a65

Browse files
committed
refactor(schema): share apply-time schema loading
Extract the repeated apply-time schema glob/read/preprocess/warn loop into a shared helper so command setup and PostgreSQL sqltest seeding use the same schema preprocessing path. Changes: - Add `schemautil.LoadSchemasForApply()` to expand schema globs, read files, run `PreprocessSchemaForApply()`, and surface warnings through a caller-provided callback. - Update `createdb`, `verify`, and managed `vet` setup to reuse the shared loader instead of open-coding the same apply-time preprocessing loop. - Update PostgreSQL sqltest seeding helpers to reuse the shared loader for both regular and read-only database setup. - Preserve read-only PostgreSQL fixture cache behavior by hashing the preprocessed DDL returned by the shared loader. - Leave schema semantics unchanged: unsafe psql meta-commands are still rejected by apply-mode preprocessing, and invalid SQL continues to fail with the database's normal PostgreSQL error. Behavioral effect: - Apply-time callers and PostgreSQL test helpers now share one codepath, reducing drift between managed-database setup and sqltest seeding. - No special-case rewriting of pg_dump `public` schema DDL is performed; callers still see PostgreSQL's native apply-time behavior. Testing: - `go test ./internal/migrations ./internal/compiler ./internal/schemautil ./internal/cmd ./internal/sqltest/...`
1 parent 4206712 commit 5bd8a65

6 files changed

Lines changed: 73 additions & 100 deletions

File tree

internal/cmd/createdb.go

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ import (
1010
"github.com/spf13/cobra"
1111
"github.com/sqlc-dev/sqlc/internal/config"
1212
"github.com/sqlc-dev/sqlc/internal/dbmanager"
13-
"github.com/sqlc-dev/sqlc/internal/migrations"
14-
"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
13+
"github.com/sqlc-dev/sqlc/internal/schemautil"
1514
)
1615

1716
var createDBCmd = &cobra.Command{
@@ -75,24 +74,12 @@ func CreateDB(ctx context.Context, dir, filename, querySetName string, o *Option
7574
}
7675

7776
var ddl []string
78-
files, err := sqlpath.Glob(queryset.Schema)
77+
ddl, err = schemautil.LoadSchemasForApply(queryset.Schema, string(queryset.Engine), func(warning string) {
78+
fmt.Fprintln(o.Stderr, warning)
79+
})
7980
if err != nil {
8081
return err
8182
}
82-
for _, schema := range files {
83-
contents, err := os.ReadFile(schema)
84-
if err != nil {
85-
return fmt.Errorf("read file: %w", err)
86-
}
87-
ddlText, warnings, err := migrations.PreprocessSchemaForApply(string(contents), string(queryset.Engine))
88-
if err != nil {
89-
return err
90-
}
91-
for _, warning := range warnings {
92-
fmt.Fprintln(o.Stderr, warning)
93-
}
94-
ddl = append(ddl, ddlText)
95-
}
9683

9784
now := time.Now().UTC().UnixNano()
9885
client := dbmanager.NewClient(conf.Servers)

internal/cmd/verify.go

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ import (
1414

1515
"github.com/sqlc-dev/sqlc/internal/config"
1616
"github.com/sqlc-dev/sqlc/internal/dbmanager"
17-
"github.com/sqlc-dev/sqlc/internal/migrations"
1817
"github.com/sqlc-dev/sqlc/internal/plugin"
1918
"github.com/sqlc-dev/sqlc/internal/quickdb"
2019
pb "github.com/sqlc-dev/sqlc/internal/quickdb/v1"
21-
"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
20+
"github.com/sqlc-dev/sqlc/internal/schemautil"
2221
)
2322

2423
func init() {
@@ -93,24 +92,12 @@ func Verify(ctx context.Context, dir, filename string, opts *Options) error {
9392

9493
// Read the schema files into memory, removing rollback statements
9594
var ddl []string
96-
files, err := sqlpath.Glob(current.Schema)
95+
ddl, err = schemautil.LoadSchemasForApply(current.Schema, string(current.Engine), func(warning string) {
96+
fmt.Fprintln(stderr, warning)
97+
})
9798
if err != nil {
9899
return err
99100
}
100-
for _, schema := range files {
101-
contents, err := os.ReadFile(schema)
102-
if err != nil {
103-
return fmt.Errorf("read file: %w", err)
104-
}
105-
ddlText, warnings, err := migrations.PreprocessSchemaForApply(string(contents), string(current.Engine))
106-
if err != nil {
107-
return err
108-
}
109-
for _, warning := range warnings {
110-
fmt.Fprintln(stderr, warning)
111-
}
112-
ddl = append(ddl, ddlText)
113-
}
114101

115102
var codegen plugin.GenerateRequest
116103
if err := proto.Unmarshal(qs.CodegenRequest.Contents, &codegen); err != nil {

internal/cmd/vet.go

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,11 @@ import (
2727
"github.com/sqlc-dev/sqlc/internal/config"
2828
"github.com/sqlc-dev/sqlc/internal/dbmanager"
2929
"github.com/sqlc-dev/sqlc/internal/debug"
30-
"github.com/sqlc-dev/sqlc/internal/migrations"
3130
"github.com/sqlc-dev/sqlc/internal/opts"
3231
"github.com/sqlc-dev/sqlc/internal/plugin"
3332
"github.com/sqlc-dev/sqlc/internal/quickdb"
33+
"github.com/sqlc-dev/sqlc/internal/schemautil"
3434
"github.com/sqlc-dev/sqlc/internal/shfmt"
35-
"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
3635
"github.com/sqlc-dev/sqlc/internal/sqlcdebug"
3736
"github.com/sqlc-dev/sqlc/internal/vet"
3837
)
@@ -429,25 +428,12 @@ func (c *checker) fetchDatabaseUri(ctx context.Context, s config.SQL) (string, f
429428
c.Client = dbmanager.NewClient(c.Conf.Servers)
430429
})
431430

432-
var ddl []string
433-
files, err := sqlpath.Glob(s.Schema)
431+
ddl, err := schemautil.LoadSchemasForApply(s.Schema, string(s.Engine), func(warning string) {
432+
fmt.Fprintln(c.Stderr, warning)
433+
})
434434
if err != nil {
435435
return "", cleanup, err
436436
}
437-
for _, schema := range files {
438-
contents, err := os.ReadFile(schema)
439-
if err != nil {
440-
return "", cleanup, fmt.Errorf("read file: %w", err)
441-
}
442-
ddlText, warnings, err := migrations.PreprocessSchemaForApply(string(contents), string(s.Engine))
443-
if err != nil {
444-
return "", cleanup, err
445-
}
446-
for _, warning := range warnings {
447-
fmt.Fprintln(c.Stderr, warning)
448-
}
449-
ddl = append(ddl, ddlText)
450-
}
451437

452438
resp, err := c.Client.CreateDatabase(ctx, &dbmanager.CreateDatabaseRequest{
453439
Engine: string(s.Engine),
@@ -552,24 +538,15 @@ func (c *checker) checkSQL(ctx context.Context, s config.SQL) error {
552538
defer db.Close()
553539
// For in-memory SQLite databases, apply migrations
554540
if isInMemorySQLite(dburl) {
555-
files, err := sqlpath.Glob(s.Schema)
541+
ddl, err := schemautil.LoadSchemasForApply(s.Schema, string(s.Engine), func(warning string) {
542+
fmt.Fprintln(c.Stderr, warning)
543+
})
556544
if err != nil {
557545
return fmt.Errorf("schema: %w", err)
558546
}
559-
for _, schema := range files {
560-
contents, err := os.ReadFile(schema)
561-
if err != nil {
562-
return fmt.Errorf("read schema file: %w", err)
563-
}
564-
ddl, warnings, err := migrations.PreprocessSchemaForApply(string(contents), string(s.Engine))
565-
if err != nil {
566-
return err
567-
}
568-
for _, warning := range warnings {
569-
fmt.Fprintln(c.Stderr, warning)
570-
}
571-
if _, err := db.ExecContext(ctx, ddl); err != nil {
572-
return fmt.Errorf("apply schema %s: %w", schema, err)
547+
for _, stmt := range ddl {
548+
if _, err := db.ExecContext(ctx, stmt); err != nil {
549+
return fmt.Errorf("apply schema: %w", err)
573550
}
574551
}
575552
}

internal/schemautil/load.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package schemautil
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/sqlc-dev/sqlc/internal/migrations"
8+
"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
9+
)
10+
11+
// LoadSchemasForApply expands globs, preprocesses each schema in order, and
12+
// reports any warnings through warn. The returned DDL is suitable for callers
13+
// that will apply schema text to a live database.
14+
func LoadSchemasForApply(globs []string, engine string, warn func(string)) ([]string, error) {
15+
files, err := sqlpath.Glob(globs)
16+
if err != nil {
17+
return nil, err
18+
}
19+
20+
ddl := make([]string, 0, len(files))
21+
for _, schema := range files {
22+
contents, err := os.ReadFile(schema)
23+
if err != nil {
24+
return nil, fmt.Errorf("read file: %w", err)
25+
}
26+
ddlText, warnings, err := migrations.PreprocessSchemaForApply(string(contents), engine)
27+
if err != nil {
28+
return nil, err
29+
}
30+
for _, warning := range warnings {
31+
if warn != nil {
32+
warn(warning)
33+
}
34+
}
35+
ddl = append(ddl, ddlText)
36+
}
37+
38+
return ddl, nil
39+
}

internal/sqltest/local/postgres.go

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ import (
1212
"github.com/jackc/pgx/v5"
1313
"golang.org/x/sync/singleflight"
1414

15-
migrate "github.com/sqlc-dev/sqlc/internal/migrations"
1615
"github.com/sqlc-dev/sqlc/internal/pgx/poolcache"
17-
"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
16+
"github.com/sqlc-dev/sqlc/internal/schemautil"
1817
"github.com/sqlc-dev/sqlc/internal/sqltest/docker"
1918
"github.com/sqlc-dev/sqlc/internal/sqltest/native"
2019
)
@@ -60,26 +59,15 @@ func postgreSQL(t *testing.T, migrations []string, rw bool) string {
6059
}
6160

6261
var seed []string
63-
files, err := sqlpath.Glob(migrations)
62+
h := fnv.New64()
63+
seed, err = schemautil.LoadSchemasForApply(migrations, "postgresql", func(warning string) {
64+
t.Log(warning)
65+
})
6466
if err != nil {
6567
t.Fatal(err)
6668
}
67-
68-
h := fnv.New64()
69-
for _, f := range files {
70-
blob, err := os.ReadFile(f)
71-
if err != nil {
72-
t.Fatal(err)
73-
}
74-
ddl, warnings, err := migrate.PreprocessSchemaForApply(string(blob), "postgresql")
75-
if err != nil {
76-
t.Fatal(err)
77-
}
69+
for _, ddl := range seed {
7870
h.Write([]byte(ddl))
79-
for _, warning := range warnings {
80-
t.Log(warning)
81-
}
82-
seed = append(seed, ddl)
8371
}
8472

8573
var name string

internal/sqltest/postgres.go

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"testing"
1010
"time"
1111

12-
migrate "github.com/sqlc-dev/sqlc/internal/migrations"
12+
"github.com/sqlc-dev/sqlc/internal/schemautil"
1313
"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
1414

1515
_ "github.com/lib/pq"
@@ -99,20 +99,15 @@ func CreatePostgreSQLDatabase(t *testing.T, name string, schema bool, migrations
9999
if err != nil {
100100
t.Fatal(err)
101101
}
102-
for _, f := range files {
103-
blob, err := os.ReadFile(f)
104-
if err != nil {
105-
t.Fatal(err)
106-
}
107-
ddl, warnings, err := migrate.PreprocessSchemaForApply(string(blob), "postgresql")
108-
if err != nil {
109-
t.Fatal(err)
110-
}
111-
for _, warning := range warnings {
112-
t.Log(warning)
113-
}
114-
if _, err := sdb.Exec(ddl); err != nil {
115-
t.Fatalf("%s: %s", filepath.Base(f), err)
102+
ddl, err := schemautil.LoadSchemasForApply(migrations, "postgresql", func(warning string) {
103+
t.Log(warning)
104+
})
105+
if err != nil {
106+
t.Fatal(err)
107+
}
108+
for i, stmt := range ddl {
109+
if _, err := sdb.Exec(stmt); err != nil {
110+
t.Fatalf("%s: %s", filepath.Base(files[i]), err)
116111
}
117112
}
118113

0 commit comments

Comments
 (0)