@@ -14,6 +14,7 @@ import (
1414
1515 _ "github.com/go-sql-driver/mysql"
1616 "github.com/google/cel-go/cel"
17+ "github.com/google/cel-go/common/types/ref"
1718 "github.com/google/cel-go/ext"
1819 "github.com/jackc/pgx/v5"
1920 _ "github.com/mattn/go-sqlite3"
@@ -29,6 +30,8 @@ import (
2930
3031var ErrFailedChecks = errors .New ("failed checks" )
3132
33+ const RuleDbPrepare = "sqlc/db-prepare"
34+
3235func NewCmdVet () * cobra.Command {
3336 return & cobra.Command {
3437 Use : "vet" ,
@@ -48,6 +51,17 @@ func NewCmdVet() *cobra.Command {
4851 }
4952}
5053
54+ type emptyProgram struct {
55+ }
56+
57+ func (e * emptyProgram ) Eval (any ) (ref.Val , * cel.EvalDetails , error ) {
58+ return nil , nil , fmt .Errorf ("unimplemented" )
59+ }
60+
61+ func (e * emptyProgram ) ContextEval (ctx context.Context , a any ) (ref.Val , * cel.EvalDetails , error ) {
62+ return e .Eval (a )
63+ }
64+
5165func Vet (ctx context.Context , e Env , dir , filename string , stderr io.Writer ) error {
5266 configPath , conf , err := readConfig (stderr , dir , filename )
5367 if err != nil {
@@ -83,7 +97,9 @@ func Vet(ctx context.Context, e Env, dir, filename string, stderr io.Writer) err
8397 return fmt .Errorf ("new env: %s" , err )
8498 }
8599
86- checks := map [string ]cel.Program {}
100+ checks := map [string ]cel.Program {
101+ RuleDbPrepare : & emptyProgram {},
102+ }
87103 msgs := map [string ]string {}
88104
89105 for _ , c := range conf .Rules {
@@ -278,16 +294,26 @@ func (c *checker) checkSQL(ctx context.Context, s config.SQL) error {
278294 req := codeGenRequest (result , combo )
279295 cfg := vetConfig (req )
280296 for i , query := range req .Queries {
281- original := result .Queries [i ]
282- if prep != nil && prepareable (s , original .RawStmt ) {
283- name := fmt .Sprintf ("sqlc_vet_%d_%d" , time .Now ().Unix (), i )
284- if err := prep .Prepare (ctx , name , query .Text ); err != nil {
285- fmt .Fprintf (c .Stderr , "%s: error preparing %s on %s: %s\n " , query .Filename , query .Name , s .Engine , err )
286- errored = true
287- }
288- }
289297 q := vetQuery (query )
290298 for _ , name := range s .Rules {
299+ // Built-in rule
300+ if name == RuleDbPrepare {
301+ if prep == nil {
302+ fmt .Fprintf (c .Stderr , "%s: %s: %s: error preparing query: database connection required\n " , query .Filename , q .Name , name )
303+ errored = true
304+ continue
305+ }
306+ original := result .Queries [i ]
307+ if prepareable (s , original .RawStmt ) {
308+ name := fmt .Sprintf ("sqlc_vet_%d_%d" , time .Now ().Unix (), i )
309+ if err := prep .Prepare (ctx , name , query .Text ); err != nil {
310+ fmt .Fprintf (c .Stderr , "%s: %s: %s: error preparing query: %s\n " , query .Filename , q .Name , name , err )
311+ errored = true
312+ }
313+ }
314+ continue
315+ }
316+
291317 prg , ok := c .Checks [name ]
292318 if ! ok {
293319 return fmt .Errorf ("type-check error: a check with the name '%s' does not exist" , name )
0 commit comments