From 761b1e6b3ba97eb78ecdf1fa6f74d45dc63c4812 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Tue, 19 Sep 2023 17:12:37 -0700 Subject: [PATCH 1/5] test(endtoend): Verify all schemas in endtoend For each test in the endtoend package, use the new sqlc managed databases to verify that the schemas are valid. In the future, we'll attempt to prepare all the queries as well. --- internal/endtoend/ddl_test.go | 133 ++++++++ internal/quickdb/rpc.go | 59 ++++ internal/quickdb/v1/quickdb.pb.go | 507 ++++++++++++++++++++++++++++++ 3 files changed, 699 insertions(+) create mode 100644 internal/endtoend/ddl_test.go create mode 100644 internal/quickdb/rpc.go create mode 100755 internal/quickdb/v1/quickdb.pb.go diff --git a/internal/endtoend/ddl_test.go b/internal/endtoend/ddl_test.go new file mode 100644 index 0000000000..a50617b0aa --- /dev/null +++ b/internal/endtoend/ddl_test.go @@ -0,0 +1,133 @@ +package main + +import ( + "context" + "fmt" + "io/fs" + "os" + "path/filepath" + "strings" + "testing" + "time" + + "github.com/jackc/pgx/v5" + + "github.com/sqlc-dev/sqlc/internal/config" + "github.com/sqlc-dev/sqlc/internal/migrations" + "github.com/sqlc-dev/sqlc/internal/quickdb" + pb "github.com/sqlc-dev/sqlc/internal/quickdb/v1" + "github.com/sqlc-dev/sqlc/internal/sql/sqlpath" +) + +func TestValidSchema(t *testing.T) { + ctx := context.Background() + + projectID := os.Getenv("DDL_SQLC_PROJECT_ID") + authToken := os.Getenv("DDL_SQLC_AUTH_TOKEN") + + if projectID == "" || authToken == "" { + if os.Getenv("CI") == "" { + t.Skip("skiping ddl tests outside of CI") + } else { + t.Fatal("missing project id and auth token") + } + } + + client, err := quickdb.NewClient(projectID, authToken) + if err != nil { + t.Fatal(err) + } + + files := []string{} + + // Find all tests that do not have a stderr.txt file + err = filepath.Walk("testdata", func(path string, info fs.FileInfo, err error) error { + if err != nil { + return err + } + if filepath.Base(path) == "sqlc.json" || filepath.Base(path) == "sqlc.yaml" { + stderr := filepath.Join(filepath.Dir(path), "stderr.txt") + if _, err := os.Stat(stderr); !os.IsNotExist(err) { + return nil + } + files = append(files, path) + } + return nil + }) + if err != nil { + t.Fatal(err) + } + + for _, file := range files { + file := file // https://golang.org/doc/faq#closures_and_goroutines + rd, err := os.Open(file) + if err != nil { + t.Fatal(err) + } + + conf, err := config.ParseConfig(rd) + if err != nil { + t.Fatal(err) + } + + for j, pkg := range conf.SQL { + j, pkg := j, pkg + if pkg.Engine != config.EnginePostgreSQL { + continue + } + t.Run(fmt.Sprintf("endtoend-%s-%d", file, j), func(t *testing.T) { + t.Parallel() + + var schema []string + for _, path := range pkg.Schema { + schema = append(schema, filepath.Join(filepath.Dir(file), path)) + } + + files, err := sqlpath.Glob(schema) + if err != nil { + t.Fatal(err) + } + + var sqls []string + for _, f := range files { + contents, err := os.ReadFile(f) + if err != nil { + t.Fatalf("%s: %s", f, err) + } + // TODO: Split schema into separate files + before, _, _ := strings.Cut(string(contents), "-- name:") + before, _, _ = strings.Cut(before, "/* name:") + // Support loading pg_dump SQL files + before = strings.ReplaceAll(before, "CREATE SCHEMA public;", "CREATE SCHEMA IF NOT EXISTS public;") + sqls = append(sqls, migrations.RemoveRollbackStatements(before)) + } + + start := time.Now() + resp, err := client.CreateEphemeralDatabase(ctx, &pb.CreateEphemeralDatabaseRequest{ + Engine: "postgresql", + Region: "sjc", + Migrations: sqls, + }) + t.Logf("%s", time.Since(start)) + if err != nil { + t.Fatal(err) + } + + t.Cleanup(func() { + _, err = client.DropEphemeralDatabase(ctx, &pb.DropEphemeralDatabaseRequest{ + DatabaseId: resp.DatabaseId, + }) + if err != nil { + t.Fatal(err) + } + }) + + conn, err := pgx.Connect(ctx, resp.Uri) + if err != nil { + t.Fatalf("connect %s: %s", resp.Uri, err) + } + defer conn.Close(ctx) + }) + } + } +} diff --git a/internal/quickdb/rpc.go b/internal/quickdb/rpc.go new file mode 100644 index 0000000000..b8530a1860 --- /dev/null +++ b/internal/quickdb/rpc.go @@ -0,0 +1,59 @@ +package quickdb + +import ( + "crypto/tls" + "os" + + "github.com/riza-io/grpc-go/credentials/basic" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + + "github.com/sqlc-dev/sqlc/internal/config" + pb "github.com/sqlc-dev/sqlc/internal/quickdb/v1" +) + +const defaultHostname = "grpc.sqlc.dev" + +func NewClientFromConfig(cloudConfig config.Cloud) (pb.QuickClient, error) { + projectID := cloudConfig.Project + authToken := os.Getenv("SQLC_AUTH_TOKEN") + return NewClient(projectID, authToken, WithHost(cloudConfig.Hostname)) +} + +type options struct { + hostname string +} + +type Option func(*options) + +func WithHost(host string) Option { + return func(o *options) { + o.hostname = host + } +} + +func NewClient(project, token string, opts ...Option) (pb.QuickClient, error) { + var o options + for _, apply := range opts { + apply(&o) + } + + dialOpts := []grpc.DialOption{ + grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{ + InsecureSkipVerify: true, + })), + grpc.WithPerRPCCredentials(basic.NewPerRPCCredentials(project, token)), + } + + hostname := o.hostname + if hostname == "" { + hostname = defaultHostname + } + + conn, err := grpc.Dial(hostname+":443", dialOpts...) + if err != nil { + return nil, err + } + + return pb.NewQuickClient(conn), nil +} diff --git a/internal/quickdb/v1/quickdb.pb.go b/internal/quickdb/v1/quickdb.pb.go new file mode 100755 index 0000000000..7bdec99748 --- /dev/null +++ b/internal/quickdb/v1/quickdb.pb.go @@ -0,0 +1,507 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.21.7 +// source: proto/quickdb/v1/quickdb.proto + +package v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type CreateEphemeralDatabaseRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Region string `protobuf:"bytes,1,opt,name=region,proto3" json:"region,omitempty"` + Engine string `protobuf:"bytes,2,opt,name=engine,proto3" json:"engine,omitempty"` + ServerId string `protobuf:"bytes,3,opt,name=server_id,json=serverId,proto3" json:"server_id,omitempty"` + Migrations []string `protobuf:"bytes,4,rep,name=migrations,proto3" json:"migrations,omitempty"` +} + +func (x *CreateEphemeralDatabaseRequest) Reset() { + *x = CreateEphemeralDatabaseRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_quickdb_v1_quickdb_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateEphemeralDatabaseRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateEphemeralDatabaseRequest) ProtoMessage() {} + +func (x *CreateEphemeralDatabaseRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_quickdb_v1_quickdb_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateEphemeralDatabaseRequest.ProtoReflect.Descriptor instead. +func (*CreateEphemeralDatabaseRequest) Descriptor() ([]byte, []int) { + return file_proto_quickdb_v1_quickdb_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateEphemeralDatabaseRequest) GetRegion() string { + if x != nil { + return x.Region + } + return "" +} + +func (x *CreateEphemeralDatabaseRequest) GetEngine() string { + if x != nil { + return x.Engine + } + return "" +} + +func (x *CreateEphemeralDatabaseRequest) GetServerId() string { + if x != nil { + return x.ServerId + } + return "" +} + +func (x *CreateEphemeralDatabaseRequest) GetMigrations() []string { + if x != nil { + return x.Migrations + } + return nil +} + +type CreateEphemeralDatabaseResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DatabaseId string `protobuf:"bytes,1,opt,name=database_id,json=databaseId,proto3" json:"database_id,omitempty"` + Uri string `protobuf:"bytes,2,opt,name=uri,proto3" json:"uri,omitempty"` +} + +func (x *CreateEphemeralDatabaseResponse) Reset() { + *x = CreateEphemeralDatabaseResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_quickdb_v1_quickdb_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateEphemeralDatabaseResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateEphemeralDatabaseResponse) ProtoMessage() {} + +func (x *CreateEphemeralDatabaseResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_quickdb_v1_quickdb_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateEphemeralDatabaseResponse.ProtoReflect.Descriptor instead. +func (*CreateEphemeralDatabaseResponse) Descriptor() ([]byte, []int) { + return file_proto_quickdb_v1_quickdb_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateEphemeralDatabaseResponse) GetDatabaseId() string { + if x != nil { + return x.DatabaseId + } + return "" +} + +func (x *CreateEphemeralDatabaseResponse) GetUri() string { + if x != nil { + return x.Uri + } + return "" +} + +type DropEphemeralDatabaseRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DatabaseId string `protobuf:"bytes,1,opt,name=database_id,json=databaseId,proto3" json:"database_id,omitempty"` +} + +func (x *DropEphemeralDatabaseRequest) Reset() { + *x = DropEphemeralDatabaseRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_quickdb_v1_quickdb_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DropEphemeralDatabaseRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DropEphemeralDatabaseRequest) ProtoMessage() {} + +func (x *DropEphemeralDatabaseRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_quickdb_v1_quickdb_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DropEphemeralDatabaseRequest.ProtoReflect.Descriptor instead. +func (*DropEphemeralDatabaseRequest) Descriptor() ([]byte, []int) { + return file_proto_quickdb_v1_quickdb_proto_rawDescGZIP(), []int{2} +} + +func (x *DropEphemeralDatabaseRequest) GetDatabaseId() string { + if x != nil { + return x.DatabaseId + } + return "" +} + +type DropEphemeralDatabaseResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DropEphemeralDatabaseResponse) Reset() { + *x = DropEphemeralDatabaseResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_quickdb_v1_quickdb_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DropEphemeralDatabaseResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DropEphemeralDatabaseResponse) ProtoMessage() {} + +func (x *DropEphemeralDatabaseResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_quickdb_v1_quickdb_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DropEphemeralDatabaseResponse.ProtoReflect.Descriptor instead. +func (*DropEphemeralDatabaseResponse) Descriptor() ([]byte, []int) { + return file_proto_quickdb_v1_quickdb_proto_rawDescGZIP(), []int{3} +} + +var File_proto_quickdb_v1_quickdb_proto protoreflect.FileDescriptor + +var file_proto_quickdb_v1_quickdb_proto_rawDesc = []byte{ + 0x0a, 0x1e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x64, 0x62, 0x2f, + 0x76, 0x31, 0x2f, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x64, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x1a, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x73, 0x71, 0x6c, 0x63, 0x2e, 0x64, 0x65, + 0x76, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x64, 0x62, 0x2e, 0x76, 0x31, 0x22, 0x8d, 0x01, 0x0a, + 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, + 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x12, + 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, + 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0a, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x54, 0x0a, 0x1f, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x44, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x1f, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x49, 0x64, + 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, + 0x72, 0x69, 0x22, 0x3f, 0x0a, 0x1c, 0x44, 0x72, 0x6f, 0x70, 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, + 0x72, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x49, 0x64, 0x22, 0x1f, 0x0a, 0x1d, 0x44, 0x72, 0x6f, 0x70, 0x45, 0x70, 0x68, 0x65, 0x6d, + 0x65, 0x72, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xab, 0x02, 0x0a, 0x05, 0x51, 0x75, 0x69, 0x63, 0x6b, 0x12, 0x92, + 0x01, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, + 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x3a, 0x2e, 0x72, 0x65, 0x6d, + 0x6f, 0x74, 0x65, 0x2e, 0x73, 0x71, 0x6c, 0x63, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x71, 0x75, 0x69, + 0x63, 0x6b, 0x64, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x70, + 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, + 0x73, 0x71, 0x6c, 0x63, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x64, 0x62, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, + 0x72, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x8c, 0x01, 0x0a, 0x15, 0x44, 0x72, 0x6f, 0x70, 0x45, 0x70, 0x68, 0x65, + 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x38, 0x2e, + 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2e, 0x73, 0x71, 0x6c, 0x63, 0x2e, 0x64, 0x65, 0x76, 0x2e, + 0x71, 0x75, 0x69, 0x63, 0x6b, 0x64, 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x72, 0x6f, 0x70, 0x45, + 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, + 0x2e, 0x73, 0x71, 0x6c, 0x63, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x64, + 0x62, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x72, 0x6f, 0x70, 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, + 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_proto_quickdb_v1_quickdb_proto_rawDescOnce sync.Once + file_proto_quickdb_v1_quickdb_proto_rawDescData = file_proto_quickdb_v1_quickdb_proto_rawDesc +) + +func file_proto_quickdb_v1_quickdb_proto_rawDescGZIP() []byte { + file_proto_quickdb_v1_quickdb_proto_rawDescOnce.Do(func() { + file_proto_quickdb_v1_quickdb_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_quickdb_v1_quickdb_proto_rawDescData) + }) + return file_proto_quickdb_v1_quickdb_proto_rawDescData +} + +var file_proto_quickdb_v1_quickdb_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_proto_quickdb_v1_quickdb_proto_goTypes = []interface{}{ + (*CreateEphemeralDatabaseRequest)(nil), // 0: remote.sqlc.dev.quickdb.v1.CreateEphemeralDatabaseRequest + (*CreateEphemeralDatabaseResponse)(nil), // 1: remote.sqlc.dev.quickdb.v1.CreateEphemeralDatabaseResponse + (*DropEphemeralDatabaseRequest)(nil), // 2: remote.sqlc.dev.quickdb.v1.DropEphemeralDatabaseRequest + (*DropEphemeralDatabaseResponse)(nil), // 3: remote.sqlc.dev.quickdb.v1.DropEphemeralDatabaseResponse +} +var file_proto_quickdb_v1_quickdb_proto_depIdxs = []int32{ + 0, // 0: remote.sqlc.dev.quickdb.v1.Quick.CreateEphemeralDatabase:input_type -> remote.sqlc.dev.quickdb.v1.CreateEphemeralDatabaseRequest + 2, // 1: remote.sqlc.dev.quickdb.v1.Quick.DropEphemeralDatabase:input_type -> remote.sqlc.dev.quickdb.v1.DropEphemeralDatabaseRequest + 1, // 2: remote.sqlc.dev.quickdb.v1.Quick.CreateEphemeralDatabase:output_type -> remote.sqlc.dev.quickdb.v1.CreateEphemeralDatabaseResponse + 3, // 3: remote.sqlc.dev.quickdb.v1.Quick.DropEphemeralDatabase:output_type -> remote.sqlc.dev.quickdb.v1.DropEphemeralDatabaseResponse + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_proto_quickdb_v1_quickdb_proto_init() } +func file_proto_quickdb_v1_quickdb_proto_init() { + if File_proto_quickdb_v1_quickdb_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_quickdb_v1_quickdb_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateEphemeralDatabaseRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_quickdb_v1_quickdb_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateEphemeralDatabaseResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_quickdb_v1_quickdb_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DropEphemeralDatabaseRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_quickdb_v1_quickdb_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DropEphemeralDatabaseResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_quickdb_v1_quickdb_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_quickdb_v1_quickdb_proto_goTypes, + DependencyIndexes: file_proto_quickdb_v1_quickdb_proto_depIdxs, + MessageInfos: file_proto_quickdb_v1_quickdb_proto_msgTypes, + }.Build() + File_proto_quickdb_v1_quickdb_proto = out.File + file_proto_quickdb_v1_quickdb_proto_rawDesc = nil + file_proto_quickdb_v1_quickdb_proto_goTypes = nil + file_proto_quickdb_v1_quickdb_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// QuickClient is the client API for Quick service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QuickClient interface { + CreateEphemeralDatabase(ctx context.Context, in *CreateEphemeralDatabaseRequest, opts ...grpc.CallOption) (*CreateEphemeralDatabaseResponse, error) + DropEphemeralDatabase(ctx context.Context, in *DropEphemeralDatabaseRequest, opts ...grpc.CallOption) (*DropEphemeralDatabaseResponse, error) +} + +type quickClient struct { + cc grpc.ClientConnInterface +} + +func NewQuickClient(cc grpc.ClientConnInterface) QuickClient { + return &quickClient{cc} +} + +func (c *quickClient) CreateEphemeralDatabase(ctx context.Context, in *CreateEphemeralDatabaseRequest, opts ...grpc.CallOption) (*CreateEphemeralDatabaseResponse, error) { + out := new(CreateEphemeralDatabaseResponse) + err := c.cc.Invoke(ctx, "/remote.sqlc.dev.quickdb.v1.Quick/CreateEphemeralDatabase", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *quickClient) DropEphemeralDatabase(ctx context.Context, in *DropEphemeralDatabaseRequest, opts ...grpc.CallOption) (*DropEphemeralDatabaseResponse, error) { + out := new(DropEphemeralDatabaseResponse) + err := c.cc.Invoke(ctx, "/remote.sqlc.dev.quickdb.v1.Quick/DropEphemeralDatabase", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QuickServer is the server API for Quick service. +type QuickServer interface { + CreateEphemeralDatabase(context.Context, *CreateEphemeralDatabaseRequest) (*CreateEphemeralDatabaseResponse, error) + DropEphemeralDatabase(context.Context, *DropEphemeralDatabaseRequest) (*DropEphemeralDatabaseResponse, error) +} + +// UnimplementedQuickServer can be embedded to have forward compatible implementations. +type UnimplementedQuickServer struct { +} + +func (*UnimplementedQuickServer) CreateEphemeralDatabase(context.Context, *CreateEphemeralDatabaseRequest) (*CreateEphemeralDatabaseResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateEphemeralDatabase not implemented") +} +func (*UnimplementedQuickServer) DropEphemeralDatabase(context.Context, *DropEphemeralDatabaseRequest) (*DropEphemeralDatabaseResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DropEphemeralDatabase not implemented") +} + +func RegisterQuickServer(s *grpc.Server, srv QuickServer) { + s.RegisterService(&_Quick_serviceDesc, srv) +} + +func _Quick_CreateEphemeralDatabase_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateEphemeralDatabaseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QuickServer).CreateEphemeralDatabase(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/remote.sqlc.dev.quickdb.v1.Quick/CreateEphemeralDatabase", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QuickServer).CreateEphemeralDatabase(ctx, req.(*CreateEphemeralDatabaseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Quick_DropEphemeralDatabase_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DropEphemeralDatabaseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QuickServer).DropEphemeralDatabase(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/remote.sqlc.dev.quickdb.v1.Quick/DropEphemeralDatabase", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QuickServer).DropEphemeralDatabase(ctx, req.(*DropEphemeralDatabaseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Quick_serviceDesc = grpc.ServiceDesc{ + ServiceName: "remote.sqlc.dev.quickdb.v1.Quick", + HandlerType: (*QuickServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateEphemeralDatabase", + Handler: _Quick_CreateEphemeralDatabase_Handler, + }, + { + MethodName: "DropEphemeralDatabase", + Handler: _Quick_DropEphemeralDatabase_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "proto/quickdb/v1/quickdb.proto", +} From 5bbcefbba82c8270c8d38871c17dbd141a2e2161 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Tue, 19 Sep 2023 17:20:13 -0700 Subject: [PATCH 2/5] Fix CI --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3706e74b61..6c50d7b07b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,6 +76,8 @@ jobs: MYSQL_HOST: localhost MYSQL_PORT: ${{ job.services.mysql.ports['3306'] }} MYSQL_ROOT_PASSWORD: mysecretpassword + DDL_SQLC_PROJECT_ID: ${{ secrets.DDL_SQLC_PROJECT_ID }} + DDL_SQLC_AUTH_TOKEN: ${{ secrets.DDL_SQLC_AUTH_TOKEN }} - name: build internal/endtoend run: go build ./... From ab9ed94b562cdc0335eee5ae64fdeed27868ee14 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Tue, 19 Sep 2023 17:45:14 -0700 Subject: [PATCH 3/5] Remove skip verify --- internal/quickdb/rpc.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/quickdb/rpc.go b/internal/quickdb/rpc.go index b8530a1860..c1f9ffd4c2 100644 --- a/internal/quickdb/rpc.go +++ b/internal/quickdb/rpc.go @@ -39,9 +39,7 @@ func NewClient(project, token string, opts ...Option) (pb.QuickClient, error) { } dialOpts := []grpc.DialOption{ - grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{ - InsecureSkipVerify: true, - })), + grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})), grpc.WithPerRPCCredentials(basic.NewPerRPCCredentials(project, token)), } From 0a10f1ac3ea4770ec4a2dc61d632d5c27ef51305 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Tue, 19 Sep 2023 17:57:12 -0700 Subject: [PATCH 4/5] what region --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c50d7b07b..b9417c0ae8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,6 +55,8 @@ jobs: with: go-version: '1.21.1' + - run: curl -I https://debug.fly.dev + - name: install gotestsum run: go install gotest.tools/gotestsum@latest From 90bfddd106134584cf783d367e3af3c46dd3bafd Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Tue, 19 Sep 2023 18:02:36 -0700 Subject: [PATCH 5/5] Pick a better region --- internal/endtoend/ddl_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/endtoend/ddl_test.go b/internal/endtoend/ddl_test.go index a50617b0aa..363ba8cbb5 100644 --- a/internal/endtoend/ddl_test.go +++ b/internal/endtoend/ddl_test.go @@ -105,7 +105,7 @@ func TestValidSchema(t *testing.T) { start := time.Now() resp, err := client.CreateEphemeralDatabase(ctx, &pb.CreateEphemeralDatabaseRequest{ Engine: "postgresql", - Region: "sjc", + Region: "iad", Migrations: sqls, }) t.Logf("%s", time.Since(start))