| 
 | 1 | +package cmd  | 
 | 2 | + | 
 | 3 | +import (  | 
 | 4 | +	"context"  | 
 | 5 | +	"fmt"  | 
 | 6 | +	"os"  | 
 | 7 | +	"runtime/trace"  | 
 | 8 | + | 
 | 9 | +	"github.com/spf13/cobra"  | 
 | 10 | +	"github.com/sqlc-dev/sqlc/internal/config"  | 
 | 11 | +	"github.com/sqlc-dev/sqlc/internal/migrations"  | 
 | 12 | +	"github.com/sqlc-dev/sqlc/internal/quickdb"  | 
 | 13 | +	pb "github.com/sqlc-dev/sqlc/internal/quickdb/v1"  | 
 | 14 | +	"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"  | 
 | 15 | +)  | 
 | 16 | + | 
 | 17 | +var createDBCmd = &cobra.Command{  | 
 | 18 | +	Use:   "createdb",  | 
 | 19 | +	Short: "Create an ephemeral database",  | 
 | 20 | +	Args:  cobra.NoArgs,  | 
 | 21 | +	RunE: func(cmd *cobra.Command, args []string) error {  | 
 | 22 | +		defer trace.StartRegion(cmd.Context(), "createdb").End()  | 
 | 23 | +		stderr := cmd.ErrOrStderr()  | 
 | 24 | +		dir, filename := getConfigPath(stderr, cmd.Flag("file"))  | 
 | 25 | +		querySetName, err := cmd.Flags().GetString("queryset")  | 
 | 26 | +		if err != nil {  | 
 | 27 | +			return err  | 
 | 28 | +		}  | 
 | 29 | +		err = CreateDB(cmd.Context(), dir, filename, querySetName, &Options{  | 
 | 30 | +			Env:    ParseEnv(cmd),  | 
 | 31 | +			Stderr: stderr,  | 
 | 32 | +		})  | 
 | 33 | +		if err != nil {  | 
 | 34 | +			fmt.Fprintln(stderr, err.Error())  | 
 | 35 | +			os.Exit(1)  | 
 | 36 | +		}  | 
 | 37 | +		return nil  | 
 | 38 | +	},  | 
 | 39 | +}  | 
 | 40 | + | 
 | 41 | +func CreateDB(ctx context.Context, dir, filename, querySetName string, o *Options) error {  | 
 | 42 | +	_, conf, err := o.ReadConfig(dir, filename)  | 
 | 43 | +	if err != nil {  | 
 | 44 | +		return err  | 
 | 45 | +	}  | 
 | 46 | +	// Find the first queryset with a managed database  | 
 | 47 | +	var queryset *config.SQL  | 
 | 48 | +	var count int  | 
 | 49 | +	for _, sql := range conf.SQL {  | 
 | 50 | +		sql := sql  | 
 | 51 | +		if querySetName != "" && sql.Name != querySetName {  | 
 | 52 | +			continue  | 
 | 53 | +		}  | 
 | 54 | +		if sql.Database != nil && sql.Database.Managed {  | 
 | 55 | +			queryset = &sql  | 
 | 56 | +			count += 1  | 
 | 57 | +		}  | 
 | 58 | +	}  | 
 | 59 | +	if queryset == nil && querySetName != "" {  | 
 | 60 | +		return fmt.Errorf("no queryset found with name %q", querySetName)  | 
 | 61 | +	}  | 
 | 62 | +	if queryset == nil {  | 
 | 63 | +		return fmt.Errorf("no querysets configured to use a managed database")  | 
 | 64 | +	}  | 
 | 65 | +	if count > 1 {  | 
 | 66 | +		return fmt.Errorf("multiple querysets configured to use managed databases")  | 
 | 67 | +	}  | 
 | 68 | +	if queryset.Engine != config.EnginePostgreSQL {  | 
 | 69 | +		return fmt.Errorf("managed databases currently only support PostgreSQL")  | 
 | 70 | +	}  | 
 | 71 | + | 
 | 72 | +	var ddl []string  | 
 | 73 | +	files, err := sqlpath.Glob(queryset.Schema)  | 
 | 74 | +	if err != nil {  | 
 | 75 | +		return err  | 
 | 76 | +	}  | 
 | 77 | +	for _, schema := range files {  | 
 | 78 | +		contents, err := os.ReadFile(schema)  | 
 | 79 | +		if err != nil {  | 
 | 80 | +			return fmt.Errorf("read file: %w", err)  | 
 | 81 | +		}  | 
 | 82 | +		ddl = append(ddl, migrations.RemoveRollbackStatements(string(contents)))  | 
 | 83 | +	}  | 
 | 84 | + | 
 | 85 | +	client, err := quickdb.NewClientFromConfig(conf.Cloud)  | 
 | 86 | +	if err != nil {  | 
 | 87 | +		return fmt.Errorf("client error: %w", err)  | 
 | 88 | +	}  | 
 | 89 | + | 
 | 90 | +	resp, err := client.CreateEphemeralDatabase(ctx, &pb.CreateEphemeralDatabaseRequest{  | 
 | 91 | +		Engine:     "postgresql",  | 
 | 92 | +		Region:     quickdb.GetClosestRegion(),  | 
 | 93 | +		Migrations: ddl,  | 
 | 94 | +	})  | 
 | 95 | +	if err != nil {  | 
 | 96 | +		return fmt.Errorf("managed: create database: %w", err)  | 
 | 97 | +	}  | 
 | 98 | +	fmt.Fprintln(os.Stderr, "WARNING: This database will be removed in two minutes")  | 
 | 99 | +	fmt.Println(resp.Uri)  | 
 | 100 | +	return nil  | 
 | 101 | +}  | 
0 commit comments