@@ -2,14 +2,22 @@ package cmd
22
33import (
44 "context"
5+ "database/sql"
56 "fmt"
7+ "log/slog"
68 "os"
79
10+ _ "github.com/jackc/pgx/v5/stdlib"
811 "github.com/spf13/cobra"
12+ "google.golang.org/protobuf/proto"
913
10- "github.com/sqlc-dev/sqlc/internal/bundler"
14+ "github.com/sqlc-dev/sqlc/internal/config"
15+ "github.com/sqlc-dev/sqlc/internal/dbmanager"
16+ "github.com/sqlc-dev/sqlc/internal/migrations"
17+ "github.com/sqlc-dev/sqlc/internal/plugin"
1118 "github.com/sqlc-dev/sqlc/internal/quickdb"
12- quickdbv1 "github.com/sqlc-dev/sqlc/internal/quickdb/v1"
19+ pb "github.com/sqlc-dev/sqlc/internal/quickdb/v1"
20+ "github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
1321)
1422
1523func init () {
@@ -32,7 +40,6 @@ var verifyCmd = &cobra.Command{
3240 Against : against ,
3341 }
3442 if err := Verify (cmd .Context (), dir , name , opts ); err != nil {
35- fmt .Fprintf (stderr , "error verifying: %s\n " , err )
3643 os .Exit (1 )
3744 }
3845 return nil
@@ -41,50 +48,103 @@ var verifyCmd = &cobra.Command{
4148
4249func Verify (ctx context.Context , dir , filename string , opts * Options ) error {
4350 stderr := opts .Stderr
44- configPath , conf , err := readConfig (stderr , dir , filename )
51+ _ , conf , err := readConfig (stderr , dir , filename )
4552 if err != nil {
4653 return err
4754 }
55+
4856 client , err := quickdb .NewClientFromConfig (conf .Cloud )
4957 if err != nil {
5058 return fmt .Errorf ("client init failed: %w" , err )
5159 }
52- p := & pusher {}
53- if err := Process (ctx , p , dir , filename , opts ); err != nil {
54- return err
55- }
56- req , err := bundler .BuildRequest (ctx , dir , configPath , p .results , nil )
57- if err != nil {
58- return err
59- }
60- if val := os .Getenv ("CI" ); val != "" {
61- req .Annotations ["env.ci" ] = val
62- }
63- if val := os .Getenv ("GITHUB_RUN_ID" ); val != "" {
64- req .Annotations ["github.run.id" ] = val
65- }
6660
67- resp , err := client . VerifyQuerySets ( ctx , & quickdbv1. VerifyQuerySetsRequest {
68- Against : opts . Against ,
69- SqlcVersion : req . SqlcVersion ,
70- QuerySets : req . QuerySets ,
71- Config : req . Config ,
72- Annotations : req . Annotations ,
61+ manager := dbmanager . NewClient ( conf . Servers )
62+
63+ // Get query sets from a previous archive by tag. If no tag is provided, get
64+ // the latest query sets.
65+ previous , err := client . GetQuerySets ( ctx , & pb. GetQuerySetsRequest {
66+ Tag : opts . Against ,
7367 })
7468 if err != nil {
7569 return err
7670 }
77- summaryPath := os .Getenv ("GITHUB_STEP_SUMMARY" )
78- if resp .Summary != "" {
79- if _ , err := os .Stat (summaryPath ); err == nil {
80- if err := os .WriteFile (summaryPath , []byte (resp .Summary ), 0644 ); err != nil {
71+
72+ // Create a mapping of name to query set
73+ existing := map [string ]config.SQL {}
74+ for _ , qs := range conf .SQL {
75+ existing [qs .Name ] = qs
76+ }
77+
78+ for _ , qs := range previous .QuerySets {
79+ // TODO: Create a function for this so that we can return early on errors
80+
81+ check := func () error {
82+ if qs .Name == "" {
83+ return fmt .Errorf ("unnamed query set" )
84+ }
85+
86+ current , found := existing [qs .Name ]
87+ if ! found {
88+ return fmt .Errorf ("unknown query set: %s" , qs .Name )
89+ }
90+
91+ // Read the schema files into memory, removing rollback statements
92+ var ddl []string
93+ files , err := sqlpath .Glob (current .Schema )
94+ if err != nil {
8195 return err
8296 }
97+ for _ , schema := range files {
98+ contents , err := os .ReadFile (schema )
99+ if err != nil {
100+ return fmt .Errorf ("read file: %w" , err )
101+ }
102+ ddl = append (ddl , migrations .RemoveRollbackStatements (string (contents )))
103+ }
104+
105+ var codegen plugin.GenerateRequest
106+ if err := proto .Unmarshal (qs .CodegenRequest .Contents , & codegen ); err != nil {
107+ return err
108+ }
109+
110+ // Create (or re-use) a database to verify against
111+ resp , err := manager .CreateDatabase (ctx , & dbmanager.CreateDatabaseRequest {
112+ Migrations : ddl ,
113+ })
114+ if err != nil {
115+ return err
116+ }
117+
118+ db , err := sql .Open ("pgx" , resp .Uri )
119+ if err != nil {
120+ return err
121+ }
122+ defer db .Close ()
123+
124+ for _ , query := range codegen .Queries {
125+ stmt , err := db .PrepareContext (ctx , query .Text )
126+ if err != nil {
127+ fmt .Fprintf (stderr , "Failed to prepare the following query:\n " )
128+ fmt .Fprintf (stderr , "%s\n " , query .Text )
129+ fmt .Fprintf (stderr , "Error was: %s\n " , err )
130+ continue
131+ }
132+ if err := stmt .Close (); err != nil {
133+ slog .Error ("stmt.Close failed" , "err" , err )
134+ }
135+ }
136+
137+ return nil
138+ }
139+
140+ if err := check (); err != nil {
141+ fmt .Fprintf (stderr , "FAIL\t %s\n " , qs .Name )
142+ } else {
143+ fmt .Fprintf (stderr , "ok\t %s\n " , qs .Name )
83144 }
84145 }
85- fmt .Fprintf (stderr , resp .Output )
86- if resp .Errored {
87- return fmt .Errorf ("BREAKING CHANGES DETECTED" )
88- }
146+
147+ // return fmt.Errorf("BREAKING CHANGES DETECTED")
148+
89149 return nil
90150}
0 commit comments