From 1984ce33fc3c640b3f949ff46cf1b44e53e8e509 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 5 Oct 2026 18:08:02 +0000 Subject: [PATCH 1/2] Rename dedicated read replica client identifiers Co-authored-by: Nick Holden --- internal/cmd/dedicatedreadreplica/create.go | 6 +- .../dedicatedreadreplica.go | 22 ++-- .../dedicatedreadreplica_test.go | 60 +++++----- internal/cmd/dedicatedreadreplica/delete.go | 2 +- internal/cmd/dedicatedreadreplica/list.go | 4 +- internal/cmd/dedicatedreadreplica/show.go | 4 +- internal/cmd/dedicatedreadreplica/update.go | 6 +- internal/cmd/role/get.go | 18 +-- internal/cmd/role/get_test.go | 4 +- internal/mock/postgres_read_only_replica.go | 26 +++-- internal/planetscale/client.go | 38 ++++--- .../postgres_read_only_replicas.go | 104 +++++++++++------- .../postgres_read_only_replicas_test.go | 56 +++++++--- internal/planetscale/postgres_roles.go | 20 ++-- internal/planetscale/postgres_roles_test.go | 7 ++ 15 files changed, 226 insertions(+), 151 deletions(-) diff --git a/internal/cmd/dedicatedreadreplica/create.go b/internal/cmd/dedicatedreadreplica/create.go index d27e9552..cd4e0a5e 100644 --- a/internal/cmd/dedicatedreadreplica/create.go +++ b/internal/cmd/dedicatedreadreplica/create.go @@ -37,7 +37,7 @@ defaults to the primary cluster size when those flags are omitted.`, return err } - req := &ps.CreatePostgresReadOnlyReplicaRequest{ + req := &ps.CreatePostgresDedicatedReadReplicaRequest{ Organization: ch.Config.Organization, Database: database, Branch: branch, @@ -52,7 +52,7 @@ defaults to the primary cluster size when those flags are omitted.`, end := ch.Printer.PrintProgress(fmt.Sprintf("Creating dedicated read replica %s for %s/%s", printer.BoldBlue(name), printer.BoldBlue(database), printer.BoldBlue(branch))) defer end() - replica, err := client.PostgresReadOnlyReplicas.Create(ctx, req) + replica, err := client.PostgresDedicatedReadReplicas.Create(ctx, req) if err != nil { switch cmdutil.ErrCode(err) { case ps.ErrNotFound: @@ -69,7 +69,7 @@ defaults to the primary cluster size when those flags are omitted.`, printer.BoldBlue(replica.Name), printer.BoldBlue(database), printer.BoldBlue(branch), printer.BoldBlue(replica.State)) return nil } - return ch.Printer.PrintResource(toReadOnlyReplica(replica)) + return ch.Printer.PrintResource(toDedicatedReadReplica(replica)) }, } diff --git a/internal/cmd/dedicatedreadreplica/dedicatedreadreplica.go b/internal/cmd/dedicatedreadreplica/dedicatedreadreplica.go index 015316fe..e336623a 100644 --- a/internal/cmd/dedicatedreadreplica/dedicatedreadreplica.go +++ b/internal/cmd/dedicatedreadreplica/dedicatedreadreplica.go @@ -55,8 +55,8 @@ This command is only available for PostgreSQL databases.`, return cmd } -// ReadOnlyReplica is the human/JSON/CSV view of a Postgres dedicated read replica. -type ReadOnlyReplica struct { +// DedicatedReadReplica is the human/JSON/CSV view of a Postgres dedicated read replica. +type DedicatedReadReplica struct { ID string `header:"id" json:"id"` Name string `header:"name" json:"name"` State string `header:"state" json:"state"` @@ -66,18 +66,18 @@ type ReadOnlyReplica struct { Ready bool `header:"ready" json:"ready"` CreatedAt int64 `header:"created_at,timestamp(ms|utc|human)" json:"created_at"` - orig *ps.PostgresReadOnlyReplica + orig *ps.PostgresDedicatedReadReplica } -func (r *ReadOnlyReplica) MarshalJSON() ([]byte, error) { +func (r *DedicatedReadReplica) MarshalJSON() ([]byte, error) { return json.MarshalIndent(r.orig, "", " ") } -func (r *ReadOnlyReplica) MarshalCSVValue() interface{} { - return []*ReadOnlyReplica{r} +func (r *DedicatedReadReplica) MarshalCSVValue() interface{} { + return []*DedicatedReadReplica{r} } -func toReadOnlyReplica(replica *ps.PostgresReadOnlyReplica) *ReadOnlyReplica { +func toDedicatedReadReplica(replica *ps.PostgresDedicatedReadReplica) *DedicatedReadReplica { size := replica.ClusterDisplayName if size == "" { size = replica.ClusterName @@ -94,7 +94,7 @@ func toReadOnlyReplica(replica *ps.PostgresReadOnlyReplica) *ReadOnlyReplica { region = "-" } - return &ReadOnlyReplica{ + return &DedicatedReadReplica{ ID: replica.ID, Name: replica.Name, State: replica.State, @@ -107,10 +107,10 @@ func toReadOnlyReplica(replica *ps.PostgresReadOnlyReplica) *ReadOnlyReplica { } } -func toReadOnlyReplicas(replicas []*ps.PostgresReadOnlyReplica) []*ReadOnlyReplica { - out := make([]*ReadOnlyReplica, 0, len(replicas)) +func toDedicatedReadReplicas(replicas []*ps.PostgresDedicatedReadReplica) []*DedicatedReadReplica { + out := make([]*DedicatedReadReplica, 0, len(replicas)) for _, replica := range replicas { - out = append(out, toReadOnlyReplica(replica)) + out = append(out, toDedicatedReadReplica(replica)) } return out } diff --git a/internal/cmd/dedicatedreadreplica/dedicatedreadreplica_test.go b/internal/cmd/dedicatedreadreplica/dedicatedreadreplica_test.go index 08534f44..be00cfc1 100644 --- a/internal/cmd/dedicatedreadreplica/dedicatedreadreplica_test.go +++ b/internal/cmd/dedicatedreadreplica/dedicatedreadreplica_test.go @@ -15,9 +15,9 @@ import ( "github.com/planetscale/cli/internal/printer" ) -func testReplica() *ps.PostgresReadOnlyReplica { +func testDedicatedReadReplica() *ps.PostgresDedicatedReadReplica { readyAt := time.Date(2026, 8, 28, 10, 20, 23, 0, time.UTC) - return &ps.PostgresReadOnlyReplica{ + return &ps.PostgresDedicatedReadReplica{ ID: "replica-1", Name: "analytics", State: "ready", @@ -34,7 +34,7 @@ func testReplica() *ps.PostgresReadOnlyReplica { } } -func testHelper(org string, dbSvc *mock.DatabaseService, replicaSvc *mock.PostgresReadOnlyReplicasService, format printer.Format, buf *bytes.Buffer) *cmdutil.Helper { +func testHelper(org string, dbSvc *mock.DatabaseService, replicaSvc *mock.PostgresDedicatedReadReplicasService, format printer.Format, buf *bytes.Buffer) *cmdutil.Helper { p := printer.NewPrinter(&format) p.SetResourceOutput(buf) return &cmdutil.Helper{ @@ -42,8 +42,8 @@ func testHelper(org string, dbSvc *mock.DatabaseService, replicaSvc *mock.Postgr Config: &config.Config{Organization: org}, Client: func() (*ps.Client, error) { return &ps.Client{ - Databases: dbSvc, - PostgresReadOnlyReplicas: replicaSvc, + Databases: dbSvc, + PostgresDedicatedReadReplicas: replicaSvc, }, nil }, } @@ -86,9 +86,9 @@ func TestDeprecatedCmdWarnsOnSubcommand(t *testing.T) { c := qt.New(t) var stdout, stderr bytes.Buffer org, database, branch := "planetscale", "mydb", "main" - svc := &mock.PostgresReadOnlyReplicasService{ - ListFn: func(ctx context.Context, req *ps.ListPostgresReadOnlyReplicasRequest) ([]*ps.PostgresReadOnlyReplica, error) { - return []*ps.PostgresReadOnlyReplica{testReplica()}, nil + svc := &mock.PostgresDedicatedReadReplicasService{ + ListFn: func(ctx context.Context, req *ps.ListPostgresDedicatedReadReplicasRequest) ([]*ps.PostgresDedicatedReadReplica, error) { + return []*ps.PostgresDedicatedReadReplica{testDedicatedReadReplica()}, nil }, } @@ -112,13 +112,13 @@ func TestListCmd(t *testing.T) { c := qt.New(t) var buf bytes.Buffer org, database, branch := "planetscale", "mydb", "main" - replica := testReplica() - svc := &mock.PostgresReadOnlyReplicasService{ - ListFn: func(ctx context.Context, req *ps.ListPostgresReadOnlyReplicasRequest) ([]*ps.PostgresReadOnlyReplica, error) { + replica := testDedicatedReadReplica() + svc := &mock.PostgresDedicatedReadReplicasService{ + ListFn: func(ctx context.Context, req *ps.ListPostgresDedicatedReadReplicasRequest) ([]*ps.PostgresDedicatedReadReplica, error) { c.Assert(req.Organization, qt.Equals, org) c.Assert(req.Database, qt.Equals, database) c.Assert(req.Branch, qt.Equals, branch) - return []*ps.PostgresReadOnlyReplica{replica}, nil + return []*ps.PostgresDedicatedReadReplica{replica}, nil }, } @@ -126,16 +126,16 @@ func TestListCmd(t *testing.T) { cmd.SetArgs([]string{database, branch}) c.Assert(cmd.Execute(), qt.IsNil) c.Assert(svc.ListFnInvoked, qt.IsTrue) - c.Assert(buf.String(), qt.JSONEquals, []*ReadOnlyReplica{{orig: replica}}) + c.Assert(buf.String(), qt.JSONEquals, []*DedicatedReadReplica{{orig: replica}}) } func TestShowCmd(t *testing.T) { c := qt.New(t) var buf bytes.Buffer org, database, branch := "planetscale", "mydb", "main" - replica := testReplica() - svc := &mock.PostgresReadOnlyReplicasService{ - GetFn: func(ctx context.Context, req *ps.GetPostgresReadOnlyReplicaRequest) (*ps.PostgresReadOnlyReplica, error) { + replica := testDedicatedReadReplica() + svc := &mock.PostgresDedicatedReadReplicasService{ + GetFn: func(ctx context.Context, req *ps.GetPostgresDedicatedReadReplicaRequest) (*ps.PostgresDedicatedReadReplica, error) { c.Assert(req.Organization, qt.Equals, org) c.Assert(req.Database, qt.Equals, database) c.Assert(req.Branch, qt.Equals, branch) @@ -148,16 +148,16 @@ func TestShowCmd(t *testing.T) { cmd.SetArgs([]string{database, branch, "analytics"}) c.Assert(cmd.Execute(), qt.IsNil) c.Assert(svc.GetFnInvoked, qt.IsTrue) - c.Assert(buf.String(), qt.JSONEquals, &ReadOnlyReplica{orig: replica}) + c.Assert(buf.String(), qt.JSONEquals, &DedicatedReadReplica{orig: replica}) } func TestCreateCmd(t *testing.T) { c := qt.New(t) var buf bytes.Buffer org, database, branch := "planetscale", "mydb", "main" - replica := testReplica() - svc := &mock.PostgresReadOnlyReplicasService{ - CreateFn: func(ctx context.Context, req *ps.CreatePostgresReadOnlyReplicaRequest) (*ps.PostgresReadOnlyReplica, error) { + replica := testDedicatedReadReplica() + svc := &mock.PostgresDedicatedReadReplicasService{ + CreateFn: func(ctx context.Context, req *ps.CreatePostgresDedicatedReadReplicaRequest) (*ps.PostgresDedicatedReadReplica, error) { c.Assert(req.Organization, qt.Equals, org) c.Assert(req.Database, qt.Equals, database) c.Assert(req.Branch, qt.Equals, branch) @@ -174,16 +174,16 @@ func TestCreateCmd(t *testing.T) { cmd.SetArgs([]string{database, branch, "analytics", "--region", "us-east", "--replicas", "2", "--cluster-size", "PS_10_GCP_X86"}) c.Assert(cmd.Execute(), qt.IsNil) c.Assert(svc.CreateFnInvoked, qt.IsTrue) - c.Assert(buf.String(), qt.JSONEquals, &ReadOnlyReplica{orig: replica}) + c.Assert(buf.String(), qt.JSONEquals, &DedicatedReadReplica{orig: replica}) } func TestUpdateCmd(t *testing.T) { c := qt.New(t) var buf bytes.Buffer org, database, branch := "planetscale", "mydb", "main" - replica := testReplica() - svc := &mock.PostgresReadOnlyReplicasService{ - UpdateFn: func(ctx context.Context, req *ps.UpdatePostgresReadOnlyReplicaRequest) (*ps.PostgresReadOnlyReplica, error) { + replica := testDedicatedReadReplica() + svc := &mock.PostgresDedicatedReadReplicasService{ + UpdateFn: func(ctx context.Context, req *ps.UpdatePostgresDedicatedReadReplicaRequest) (*ps.PostgresDedicatedReadReplica, error) { c.Assert(req.Organization, qt.Equals, org) c.Assert(req.Database, qt.Equals, database) c.Assert(req.Branch, qt.Equals, branch) @@ -207,12 +207,12 @@ func TestUpdateCmd(t *testing.T) { }) c.Assert(cmd.Execute(), qt.IsNil) c.Assert(svc.UpdateFnInvoked, qt.IsTrue) - c.Assert(buf.String(), qt.JSONEquals, &ReadOnlyReplica{orig: replica}) + c.Assert(buf.String(), qt.JSONEquals, &DedicatedReadReplica{orig: replica}) } func TestUpdateCmdRequiresChange(t *testing.T) { c := qt.New(t) - svc := &mock.PostgresReadOnlyReplicasService{} + svc := &mock.PostgresDedicatedReadReplicasService{} cmd := UpdateCmd(testHelper("planetscale", &mock.DatabaseService{}, svc, printer.JSON, &bytes.Buffer{})) cmd.SetArgs([]string{"mydb", "main", "analytics"}) c.Assert(cmd.Execute(), qt.ErrorMatches, `nothing to change:.*`) @@ -223,8 +223,8 @@ func TestDeleteCmd(t *testing.T) { c := qt.New(t) var buf bytes.Buffer org, database, branch := "planetscale", "mydb", "main" - svc := &mock.PostgresReadOnlyReplicasService{ - DeleteFn: func(ctx context.Context, req *ps.DeletePostgresReadOnlyReplicaRequest) error { + svc := &mock.PostgresDedicatedReadReplicasService{ + DeleteFn: func(ctx context.Context, req *ps.DeletePostgresDedicatedReadReplicaRequest) error { c.Assert(req.Organization, qt.Equals, org) c.Assert(req.Database, qt.Equals, database) c.Assert(req.Branch, qt.Equals, branch) @@ -248,7 +248,7 @@ func TestDeleteCmd(t *testing.T) { func TestDeleteCmdRequiresForceInJSON(t *testing.T) { c := qt.New(t) org, database := "planetscale", "mydb" - svc := &mock.PostgresReadOnlyReplicasService{} + svc := &mock.PostgresDedicatedReadReplicasService{} cmd := DeleteCmd(testHelper(org, databaseService(c, org, database), svc, printer.JSON, &bytes.Buffer{})) cmd.SetArgs([]string{database, "main", "analytics"}) c.Assert(cmd.Execute(), qt.ErrorMatches, `(?s).*run with --force.*`) @@ -263,7 +263,7 @@ func TestListCmdRejectsMySQL(t *testing.T) { return &ps.Database{Name: database, Kind: ps.DatabaseEngineMySQL}, nil }, } - svc := &mock.PostgresReadOnlyReplicasService{} + svc := &mock.PostgresDedicatedReadReplicasService{} cmd := ListCmd(testHelper(org, dbSvc, svc, printer.JSON, &bytes.Buffer{})) cmd.SetArgs([]string{database, "main"}) c.Assert(cmd.Execute(), qt.ErrorMatches, `(?s).*only available for PostgreSQL.*mysql.*`) diff --git a/internal/cmd/dedicatedreadreplica/delete.go b/internal/cmd/dedicatedreadreplica/delete.go index 6857bae2..9559d80e 100644 --- a/internal/cmd/dedicatedreadreplica/delete.go +++ b/internal/cmd/dedicatedreadreplica/delete.go @@ -40,7 +40,7 @@ func DeleteCmd(ch *cmdutil.Helper) *cobra.Command { end := ch.Printer.PrintProgress(fmt.Sprintf("Deleting dedicated read replica %s from %s/%s", printer.BoldBlue(name), printer.BoldBlue(database), printer.BoldBlue(branch))) defer end() - err = client.PostgresReadOnlyReplicas.Delete(ctx, &ps.DeletePostgresReadOnlyReplicaRequest{ + err = client.PostgresDedicatedReadReplicas.Delete(ctx, &ps.DeletePostgresDedicatedReadReplicaRequest{ Organization: ch.Config.Organization, Database: database, Branch: branch, diff --git a/internal/cmd/dedicatedreadreplica/list.go b/internal/cmd/dedicatedreadreplica/list.go index 7c431559..a64437c6 100644 --- a/internal/cmd/dedicatedreadreplica/list.go +++ b/internal/cmd/dedicatedreadreplica/list.go @@ -31,7 +31,7 @@ func ListCmd(ch *cmdutil.Helper) *cobra.Command { end := ch.Printer.PrintProgress(fmt.Sprintf("Fetching dedicated read replicas for %s/%s", printer.BoldBlue(database), printer.BoldBlue(branch))) defer end() - replicas, err := client.PostgresReadOnlyReplicas.List(ctx, &ps.ListPostgresReadOnlyReplicasRequest{ + replicas, err := client.PostgresDedicatedReadReplicas.List(ctx, &ps.ListPostgresDedicatedReadReplicasRequest{ Organization: ch.Config.Organization, Database: database, Branch: branch, @@ -52,7 +52,7 @@ func ListCmd(ch *cmdutil.Helper) *cobra.Command { return nil } - return ch.Printer.PrintResource(toReadOnlyReplicas(replicas)) + return ch.Printer.PrintResource(toDedicatedReadReplicas(replicas)) }, } diff --git a/internal/cmd/dedicatedreadreplica/show.go b/internal/cmd/dedicatedreadreplica/show.go index adf86073..15929f60 100644 --- a/internal/cmd/dedicatedreadreplica/show.go +++ b/internal/cmd/dedicatedreadreplica/show.go @@ -30,7 +30,7 @@ func ShowCmd(ch *cmdutil.Helper) *cobra.Command { end := ch.Printer.PrintProgress(fmt.Sprintf("Fetching dedicated read replica %s for %s/%s", printer.BoldBlue(name), printer.BoldBlue(database), printer.BoldBlue(branch))) defer end() - replica, err := client.PostgresReadOnlyReplicas.Get(ctx, &ps.GetPostgresReadOnlyReplicaRequest{ + replica, err := client.PostgresDedicatedReadReplicas.Get(ctx, &ps.GetPostgresDedicatedReadReplicaRequest{ Organization: ch.Config.Organization, Database: database, Branch: branch, @@ -47,7 +47,7 @@ func ShowCmd(ch *cmdutil.Helper) *cobra.Command { } end() - return ch.Printer.PrintResource(toReadOnlyReplica(replica)) + return ch.Printer.PrintResource(toDedicatedReadReplica(replica)) }, } diff --git a/internal/cmd/dedicatedreadreplica/update.go b/internal/cmd/dedicatedreadreplica/update.go index a5a85495..6dfd1222 100644 --- a/internal/cmd/dedicatedreadreplica/update.go +++ b/internal/cmd/dedicatedreadreplica/update.go @@ -50,7 +50,7 @@ equal to the primary branch's corresponding values.`, return err } - req := &ps.UpdatePostgresReadOnlyReplicaRequest{ + req := &ps.UpdatePostgresDedicatedReadReplicaRequest{ Organization: ch.Config.Organization, Database: database, Branch: branch, @@ -65,7 +65,7 @@ equal to the primary branch's corresponding values.`, end := ch.Printer.PrintProgress(fmt.Sprintf("Updating dedicated read replica %s on %s/%s", printer.BoldBlue(name), printer.BoldBlue(database), printer.BoldBlue(branch))) defer end() - replica, err := client.PostgresReadOnlyReplicas.Update(ctx, req) + replica, err := client.PostgresDedicatedReadReplicas.Update(ctx, req) if err != nil { switch cmdutil.ErrCode(err) { case ps.ErrNotFound: @@ -82,7 +82,7 @@ equal to the primary branch's corresponding values.`, printer.BoldBlue(name), printer.BoldBlue(database), printer.BoldBlue(branch), printer.BoldBlue(replica.State)) return nil } - return ch.Printer.PrintResource(toReadOnlyReplica(replica)) + return ch.Printer.PrintResource(toDedicatedReadReplica(replica)) }, } diff --git a/internal/cmd/role/get.go b/internal/cmd/role/get.go index 6b8ade36..4efca6a0 100644 --- a/internal/cmd/role/get.go +++ b/internal/cmd/role/get.go @@ -39,15 +39,15 @@ func GetCmd(ch *cmdutil.Helper) *cobra.Command { defer end() role, err := client.PostgresRoles.Get(ctx, &ps.GetPostgresRoleRequest{ - Organization: ch.Config.Organization, - Database: database, - Branch: branch, - RoleId: roleID, - Replica: flags.replica, - ReadOnlyReplica: flags.dedicatedReadReplica, - Bouncer: flags.bouncer, - Router: flags.router, - Shard: flags.shard, + Organization: ch.Config.Organization, + Database: database, + Branch: branch, + RoleId: roleID, + Replica: flags.replica, + DedicatedReadReplica: flags.dedicatedReadReplica, + Bouncer: flags.bouncer, + Router: flags.router, + Shard: flags.shard, }) if err != nil { switch cmdutil.ErrCode(err) { diff --git a/internal/cmd/role/get_test.go b/internal/cmd/role/get_test.go index 78166ba2..e2729f0d 100644 --- a/internal/cmd/role/get_test.go +++ b/internal/cmd/role/get_test.go @@ -90,7 +90,7 @@ func TestRole_GetCmdConnectionTargets(t *testing.T) { name: "dedicated read replica", args: []string{"mydb", "main", "role-id", "--dedicated-read-replica", "analytics"}, request: ps.GetPostgresRoleRequest{ - ReadOnlyReplica: "analytics", + DedicatedReadReplica: "analytics", }, username: "app.read-only|replica", accessHostURL: "analytics.pg.psdb.cloud", @@ -100,7 +100,7 @@ func TestRole_GetCmdConnectionTargets(t *testing.T) { name: "deprecated read-only replica alias", args: []string{"mydb", "main", "role-id", "--read-only-replica", "analytics"}, request: ps.GetPostgresRoleRequest{ - ReadOnlyReplica: "analytics", + DedicatedReadReplica: "analytics", }, username: "app.read-only|replica", accessHostURL: "analytics.pg.psdb.cloud", diff --git a/internal/mock/postgres_read_only_replica.go b/internal/mock/postgres_read_only_replica.go index f4e907a1..180f6d12 100644 --- a/internal/mock/postgres_read_only_replica.go +++ b/internal/mock/postgres_read_only_replica.go @@ -6,44 +6,48 @@ import ( ps "github.com/planetscale/cli/internal/planetscale" ) -type PostgresReadOnlyReplicasService struct { - ListFn func(context.Context, *ps.ListPostgresReadOnlyReplicasRequest) ([]*ps.PostgresReadOnlyReplica, error) +type PostgresDedicatedReadReplicasService struct { + ListFn func(context.Context, *ps.ListPostgresDedicatedReadReplicasRequest) ([]*ps.PostgresDedicatedReadReplica, error) ListFnInvoked bool - GetFn func(context.Context, *ps.GetPostgresReadOnlyReplicaRequest) (*ps.PostgresReadOnlyReplica, error) + GetFn func(context.Context, *ps.GetPostgresDedicatedReadReplicaRequest) (*ps.PostgresDedicatedReadReplica, error) GetFnInvoked bool - CreateFn func(context.Context, *ps.CreatePostgresReadOnlyReplicaRequest) (*ps.PostgresReadOnlyReplica, error) + CreateFn func(context.Context, *ps.CreatePostgresDedicatedReadReplicaRequest) (*ps.PostgresDedicatedReadReplica, error) CreateFnInvoked bool - UpdateFn func(context.Context, *ps.UpdatePostgresReadOnlyReplicaRequest) (*ps.PostgresReadOnlyReplica, error) + UpdateFn func(context.Context, *ps.UpdatePostgresDedicatedReadReplicaRequest) (*ps.PostgresDedicatedReadReplica, error) UpdateFnInvoked bool - DeleteFn func(context.Context, *ps.DeletePostgresReadOnlyReplicaRequest) error + DeleteFn func(context.Context, *ps.DeletePostgresDedicatedReadReplicaRequest) error DeleteFnInvoked bool } -func (s *PostgresReadOnlyReplicasService) List(ctx context.Context, req *ps.ListPostgresReadOnlyReplicasRequest) ([]*ps.PostgresReadOnlyReplica, error) { +// PostgresReadOnlyReplicasService is the former name for PostgresDedicatedReadReplicasService. +// Deprecated: use PostgresDedicatedReadReplicasService. +type PostgresReadOnlyReplicasService = PostgresDedicatedReadReplicasService + +func (s *PostgresDedicatedReadReplicasService) List(ctx context.Context, req *ps.ListPostgresDedicatedReadReplicasRequest) ([]*ps.PostgresDedicatedReadReplica, error) { s.ListFnInvoked = true return s.ListFn(ctx, req) } -func (s *PostgresReadOnlyReplicasService) Get(ctx context.Context, req *ps.GetPostgresReadOnlyReplicaRequest) (*ps.PostgresReadOnlyReplica, error) { +func (s *PostgresDedicatedReadReplicasService) Get(ctx context.Context, req *ps.GetPostgresDedicatedReadReplicaRequest) (*ps.PostgresDedicatedReadReplica, error) { s.GetFnInvoked = true return s.GetFn(ctx, req) } -func (s *PostgresReadOnlyReplicasService) Create(ctx context.Context, req *ps.CreatePostgresReadOnlyReplicaRequest) (*ps.PostgresReadOnlyReplica, error) { +func (s *PostgresDedicatedReadReplicasService) Create(ctx context.Context, req *ps.CreatePostgresDedicatedReadReplicaRequest) (*ps.PostgresDedicatedReadReplica, error) { s.CreateFnInvoked = true return s.CreateFn(ctx, req) } -func (s *PostgresReadOnlyReplicasService) Update(ctx context.Context, req *ps.UpdatePostgresReadOnlyReplicaRequest) (*ps.PostgresReadOnlyReplica, error) { +func (s *PostgresDedicatedReadReplicasService) Update(ctx context.Context, req *ps.UpdatePostgresDedicatedReadReplicaRequest) (*ps.PostgresDedicatedReadReplica, error) { s.UpdateFnInvoked = true return s.UpdateFn(ctx, req) } -func (s *PostgresReadOnlyReplicasService) Delete(ctx context.Context, req *ps.DeletePostgresReadOnlyReplicaRequest) error { +func (s *PostgresDedicatedReadReplicasService) Delete(ctx context.Context, req *ps.DeletePostgresDedicatedReadReplicaRequest) error { s.DeleteFnInvoked = true return s.DeleteFn(ctx, req) } diff --git a/internal/planetscale/client.go b/internal/planetscale/client.go index a7e65d0a..b8652d4b 100644 --- a/internal/planetscale/client.go +++ b/internal/planetscale/client.go @@ -82,22 +82,24 @@ type Client struct { PostgresBranches PostgresBranchesService PostgresBouncers PostgresBouncersService PostgresCIDRs PostgresCIDRsService - PostgresReadOnlyReplicas PostgresReadOnlyReplicasService - PostgresRoles PostgresRolesService - PostgresSwitchovers PostgresSwitchoversService - Processlist ProcesslistService - QueryInsights QueryInsightsService - QueryPatterns QueryPatternsService - ReadOnlyRegions ReadOnlyRegionsService - Regions RegionsService - SchemaRecommendations SchemaRecommendationService - ServiceTokens ServiceTokenService - TrafficBudgets TrafficBudgetsService - TrafficRules TrafficRulesService - VDiff VDiffService - Vtctld VtctldService - Webhooks WebhooksService - Workflows WorkflowsService + PostgresDedicatedReadReplicas PostgresDedicatedReadReplicasService + // Deprecated: use PostgresDedicatedReadReplicas. + PostgresReadOnlyReplicas PostgresReadOnlyReplicasService + PostgresRoles PostgresRolesService + PostgresSwitchovers PostgresSwitchoversService + Processlist ProcesslistService + QueryInsights QueryInsightsService + QueryPatterns QueryPatternsService + ReadOnlyRegions ReadOnlyRegionsService + Regions RegionsService + SchemaRecommendations SchemaRecommendationService + ServiceTokens ServiceTokenService + TrafficBudgets TrafficBudgetsService + TrafficRules TrafficRulesService + VDiff VDiffService + Vtctld VtctldService + Webhooks WebhooksService + Workflows WorkflowsService } // ListOptions are options for listing responses. @@ -386,7 +388,9 @@ func NewClient(opts ...ClientOption) (*Client, error) { c.PostgresBranches = &postgresBranchesService{client: c} c.PostgresBouncers = &postgresBouncersService{client: c} c.PostgresCIDRs = &postgresCIDRsService{client: c} - c.PostgresReadOnlyReplicas = &postgresReadOnlyReplicasService{client: c} + postgresDedicatedReadReplicas := &postgresDedicatedReadReplicasService{client: c} + c.PostgresDedicatedReadReplicas = postgresDedicatedReadReplicas + c.PostgresReadOnlyReplicas = postgresDedicatedReadReplicas c.PostgresRoles = &postgresRolesService{client: c} c.PostgresSwitchovers = &postgresSwitchoversService{client: c} c.Processlist = &processlistService{client: c} diff --git a/internal/planetscale/postgres_read_only_replicas.go b/internal/planetscale/postgres_read_only_replicas.go index 24ee8726..d87e4190 100644 --- a/internal/planetscale/postgres_read_only_replicas.go +++ b/internal/planetscale/postgres_read_only_replicas.go @@ -8,8 +8,8 @@ import ( "time" ) -// PostgresReadOnlyReplica represents a dedicated read replica for a Postgres branch. -type PostgresReadOnlyReplica struct { +// PostgresDedicatedReadReplica represents a dedicated read replica for a Postgres branch. +type PostgresDedicatedReadReplica struct { ID string `json:"id"` Name string `json:"name"` State string `json:"state"` @@ -28,23 +28,23 @@ type PostgresReadOnlyReplica struct { Parameters []*PostgresParameter `json:"parameters"` } -// ListPostgresReadOnlyReplicasRequest encapsulates listing dedicated read replicas. -type ListPostgresReadOnlyReplicasRequest struct { +// ListPostgresDedicatedReadReplicasRequest encapsulates listing dedicated read replicas. +type ListPostgresDedicatedReadReplicasRequest struct { Organization string Database string Branch string } -// GetPostgresReadOnlyReplicaRequest encapsulates getting a dedicated read replica by name. -type GetPostgresReadOnlyReplicaRequest struct { +// GetPostgresDedicatedReadReplicaRequest encapsulates getting a dedicated read replica by name. +type GetPostgresDedicatedReadReplicaRequest struct { Organization string Database string Branch string Replica string } -// CreatePostgresReadOnlyReplicaRequest encapsulates creating a dedicated read replica. -type CreatePostgresReadOnlyReplicaRequest struct { +// CreatePostgresDedicatedReadReplicaRequest encapsulates creating a dedicated read replica. +type CreatePostgresDedicatedReadReplicaRequest struct { Organization string `json:"-"` Database string `json:"-"` Branch string `json:"-"` @@ -54,8 +54,8 @@ type CreatePostgresReadOnlyReplicaRequest struct { ClusterSize string `json:"cluster_size,omitempty"` } -// UpdatePostgresReadOnlyReplicaRequest encapsulates updating a dedicated read replica. -type UpdatePostgresReadOnlyReplicaRequest struct { +// UpdatePostgresDedicatedReadReplicaRequest encapsulates updating a dedicated read replica. +type UpdatePostgresDedicatedReadReplicaRequest struct { Organization string `json:"-"` Database string `json:"-"` Branch string `json:"-"` @@ -65,94 +65,122 @@ type UpdatePostgresReadOnlyReplicaRequest struct { Parameters map[string]map[string]string `json:"parameters,omitempty"` } -// DeletePostgresReadOnlyReplicaRequest encapsulates deleting a dedicated read replica. -type DeletePostgresReadOnlyReplicaRequest struct { +// DeletePostgresDedicatedReadReplicaRequest encapsulates deleting a dedicated read replica. +type DeletePostgresDedicatedReadReplicaRequest struct { Organization string Database string Branch string Replica string } -// PostgresReadOnlyReplicasService is an interface for the Postgres dedicated +// PostgresDedicatedReadReplicasService is an interface for the Postgres dedicated // read replicas API. -type PostgresReadOnlyReplicasService interface { - List(context.Context, *ListPostgresReadOnlyReplicasRequest) ([]*PostgresReadOnlyReplica, error) - Get(context.Context, *GetPostgresReadOnlyReplicaRequest) (*PostgresReadOnlyReplica, error) - Create(context.Context, *CreatePostgresReadOnlyReplicaRequest) (*PostgresReadOnlyReplica, error) - Update(context.Context, *UpdatePostgresReadOnlyReplicaRequest) (*PostgresReadOnlyReplica, error) - Delete(context.Context, *DeletePostgresReadOnlyReplicaRequest) error +type PostgresDedicatedReadReplicasService interface { + List(context.Context, *ListPostgresDedicatedReadReplicasRequest) ([]*PostgresDedicatedReadReplica, error) + Get(context.Context, *GetPostgresDedicatedReadReplicaRequest) (*PostgresDedicatedReadReplica, error) + Create(context.Context, *CreatePostgresDedicatedReadReplicaRequest) (*PostgresDedicatedReadReplica, error) + Update(context.Context, *UpdatePostgresDedicatedReadReplicaRequest) (*PostgresDedicatedReadReplica, error) + Delete(context.Context, *DeletePostgresDedicatedReadReplicaRequest) error } -type postgresReadOnlyReplicasService struct { +// PostgresReadOnlyReplica is the former name for PostgresDedicatedReadReplica. +// Deprecated: use PostgresDedicatedReadReplica. +type PostgresReadOnlyReplica = PostgresDedicatedReadReplica + +// ListPostgresReadOnlyReplicasRequest is the former name for ListPostgresDedicatedReadReplicasRequest. +// Deprecated: use ListPostgresDedicatedReadReplicasRequest. +type ListPostgresReadOnlyReplicasRequest = ListPostgresDedicatedReadReplicasRequest + +// GetPostgresReadOnlyReplicaRequest is the former name for GetPostgresDedicatedReadReplicaRequest. +// Deprecated: use GetPostgresDedicatedReadReplicaRequest. +type GetPostgresReadOnlyReplicaRequest = GetPostgresDedicatedReadReplicaRequest + +// CreatePostgresReadOnlyReplicaRequest is the former name for CreatePostgresDedicatedReadReplicaRequest. +// Deprecated: use CreatePostgresDedicatedReadReplicaRequest. +type CreatePostgresReadOnlyReplicaRequest = CreatePostgresDedicatedReadReplicaRequest + +// UpdatePostgresReadOnlyReplicaRequest is the former name for UpdatePostgresDedicatedReadReplicaRequest. +// Deprecated: use UpdatePostgresDedicatedReadReplicaRequest. +type UpdatePostgresReadOnlyReplicaRequest = UpdatePostgresDedicatedReadReplicaRequest + +// DeletePostgresReadOnlyReplicaRequest is the former name for DeletePostgresDedicatedReadReplicaRequest. +// Deprecated: use DeletePostgresDedicatedReadReplicaRequest. +type DeletePostgresReadOnlyReplicaRequest = DeletePostgresDedicatedReadReplicaRequest + +// PostgresReadOnlyReplicasService is the former name for PostgresDedicatedReadReplicasService. +// Deprecated: use PostgresDedicatedReadReplicasService. +type PostgresReadOnlyReplicasService = PostgresDedicatedReadReplicasService + +type postgresDedicatedReadReplicasService struct { client *Client } -var _ PostgresReadOnlyReplicasService = &postgresReadOnlyReplicasService{} +var _ PostgresDedicatedReadReplicasService = &postgresDedicatedReadReplicasService{} -func (s *postgresReadOnlyReplicasService) List(ctx context.Context, listReq *ListPostgresReadOnlyReplicasRequest) ([]*PostgresReadOnlyReplica, error) { - req, err := s.client.newRequest(http.MethodGet, postgresReadOnlyReplicasAPIPath(listReq.Organization, listReq.Database, listReq.Branch), nil) +func (s *postgresDedicatedReadReplicasService) List(ctx context.Context, listReq *ListPostgresDedicatedReadReplicasRequest) ([]*PostgresDedicatedReadReplica, error) { + req, err := s.client.newRequest(http.MethodGet, postgresDedicatedReadReplicasAPIPath(listReq.Organization, listReq.Database, listReq.Branch), nil) if err != nil { return nil, fmt.Errorf("error creating request for list postgres dedicated read replicas: %w", err) } - replicas := []*PostgresReadOnlyReplica{} + replicas := []*PostgresDedicatedReadReplica{} if err := s.client.do(ctx, req, &replicas); err != nil { return nil, err } return replicas, nil } -func (s *postgresReadOnlyReplicasService) Get(ctx context.Context, getReq *GetPostgresReadOnlyReplicaRequest) (*PostgresReadOnlyReplica, error) { - req, err := s.client.newRequest(http.MethodGet, postgresReadOnlyReplicaAPIPath(getReq.Organization, getReq.Database, getReq.Branch, getReq.Replica), nil) +func (s *postgresDedicatedReadReplicasService) Get(ctx context.Context, getReq *GetPostgresDedicatedReadReplicaRequest) (*PostgresDedicatedReadReplica, error) { + req, err := s.client.newRequest(http.MethodGet, postgresDedicatedReadReplicaAPIPath(getReq.Organization, getReq.Database, getReq.Branch, getReq.Replica), nil) if err != nil { return nil, fmt.Errorf("error creating request for get postgres dedicated read replica: %w", err) } - replica := &PostgresReadOnlyReplica{} + replica := &PostgresDedicatedReadReplica{} if err := s.client.do(ctx, req, replica); err != nil { return nil, err } return replica, nil } -func (s *postgresReadOnlyReplicasService) Create(ctx context.Context, createReq *CreatePostgresReadOnlyReplicaRequest) (*PostgresReadOnlyReplica, error) { - req, err := s.client.newRequest(http.MethodPost, postgresReadOnlyReplicasAPIPath(createReq.Organization, createReq.Database, createReq.Branch), createReq) +func (s *postgresDedicatedReadReplicasService) Create(ctx context.Context, createReq *CreatePostgresDedicatedReadReplicaRequest) (*PostgresDedicatedReadReplica, error) { + req, err := s.client.newRequest(http.MethodPost, postgresDedicatedReadReplicasAPIPath(createReq.Organization, createReq.Database, createReq.Branch), createReq) if err != nil { return nil, fmt.Errorf("error creating request for create postgres dedicated read replica: %w", err) } - replica := &PostgresReadOnlyReplica{} + replica := &PostgresDedicatedReadReplica{} if err := s.client.do(ctx, req, replica); err != nil { return nil, err } return replica, nil } -func (s *postgresReadOnlyReplicasService) Update(ctx context.Context, updateReq *UpdatePostgresReadOnlyReplicaRequest) (*PostgresReadOnlyReplica, error) { - req, err := s.client.newRequest(http.MethodPatch, postgresReadOnlyReplicaAPIPath(updateReq.Organization, updateReq.Database, updateReq.Branch, updateReq.Replica), updateReq) +func (s *postgresDedicatedReadReplicasService) Update(ctx context.Context, updateReq *UpdatePostgresDedicatedReadReplicaRequest) (*PostgresDedicatedReadReplica, error) { + req, err := s.client.newRequest(http.MethodPatch, postgresDedicatedReadReplicaAPIPath(updateReq.Organization, updateReq.Database, updateReq.Branch, updateReq.Replica), updateReq) if err != nil { return nil, fmt.Errorf("error creating request for update postgres dedicated read replica: %w", err) } - replica := &PostgresReadOnlyReplica{} + replica := &PostgresDedicatedReadReplica{} if err := s.client.do(ctx, req, replica); err != nil { return nil, err } return replica, nil } -func (s *postgresReadOnlyReplicasService) Delete(ctx context.Context, deleteReq *DeletePostgresReadOnlyReplicaRequest) error { - req, err := s.client.newRequest(http.MethodDelete, postgresReadOnlyReplicaAPIPath(deleteReq.Organization, deleteReq.Database, deleteReq.Branch, deleteReq.Replica), nil) +func (s *postgresDedicatedReadReplicasService) Delete(ctx context.Context, deleteReq *DeletePostgresDedicatedReadReplicaRequest) error { + req, err := s.client.newRequest(http.MethodDelete, postgresDedicatedReadReplicaAPIPath(deleteReq.Organization, deleteReq.Database, deleteReq.Branch, deleteReq.Replica), nil) if err != nil { return fmt.Errorf("error creating request for delete postgres dedicated read replica: %w", err) } return s.client.do(ctx, req, nil) } -func postgresReadOnlyReplicasAPIPath(org, db, branch string) string { +func postgresDedicatedReadReplicasAPIPath(org, db, branch string) string { return path.Join(postgresBranchAPIPath(org, db, branch), "read-only-replicas") } -func postgresReadOnlyReplicaAPIPath(org, db, branch, replica string) string { - return path.Join(postgresReadOnlyReplicasAPIPath(org, db, branch), replica) +func postgresDedicatedReadReplicaAPIPath(org, db, branch, replica string) string { + return path.Join(postgresDedicatedReadReplicasAPIPath(org, db, branch), replica) } diff --git a/internal/planetscale/postgres_read_only_replicas_test.go b/internal/planetscale/postgres_read_only_replicas_test.go index 905addcf..3454f3b2 100644 --- a/internal/planetscale/postgres_read_only_replicas_test.go +++ b/internal/planetscale/postgres_read_only_replicas_test.go @@ -10,7 +10,7 @@ import ( qt "github.com/frankban/quicktest" ) -const testReadOnlyReplicaJSON = `{ +const testDedicatedReadReplicaJSON = `{ "id":"replica-1", "name":"analytics", "state":"ready", @@ -29,12 +29,12 @@ const testReadOnlyReplicaJSON = `{ "parameters":[] }` -func TestPostgresReadOnlyReplicas_List(t *testing.T) { +func TestPostgresDedicatedReadReplicas_List(t *testing.T) { c := qt.New(t) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { c.Assert(r.Method, qt.Equals, http.MethodGet) c.Assert(r.URL.Path, qt.Equals, "/v1/organizations/my-org/databases/my-db/branches/main/read-only-replicas") - _, err := w.Write([]byte("[" + testReadOnlyReplicaJSON + "]")) + _, err := w.Write([]byte("[" + testDedicatedReadReplicaJSON + "]")) c.Assert(err, qt.IsNil) })) defer ts.Close() @@ -42,7 +42,7 @@ func TestPostgresReadOnlyReplicas_List(t *testing.T) { client, err := NewClient(WithBaseURL(ts.URL)) c.Assert(err, qt.IsNil) - replicas, err := client.PostgresReadOnlyReplicas.List(context.Background(), &ListPostgresReadOnlyReplicasRequest{ + replicas, err := client.PostgresDedicatedReadReplicas.List(context.Background(), &ListPostgresDedicatedReadReplicasRequest{ Organization: testOrg, Database: "my-db", Branch: "main", @@ -54,12 +54,12 @@ func TestPostgresReadOnlyReplicas_List(t *testing.T) { c.Assert(replicas[0].Region.Slug, qt.Equals, "us-east") } -func TestPostgresReadOnlyReplicas_Get(t *testing.T) { +func TestPostgresDedicatedReadReplicas_Get(t *testing.T) { c := qt.New(t) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { c.Assert(r.Method, qt.Equals, http.MethodGet) c.Assert(r.URL.Path, qt.Equals, "/v1/organizations/my-org/databases/my-db/branches/main/read-only-replicas/analytics") - _, err := w.Write([]byte(testReadOnlyReplicaJSON)) + _, err := w.Write([]byte(testDedicatedReadReplicaJSON)) c.Assert(err, qt.IsNil) })) defer ts.Close() @@ -67,7 +67,7 @@ func TestPostgresReadOnlyReplicas_Get(t *testing.T) { client, err := NewClient(WithBaseURL(ts.URL)) c.Assert(err, qt.IsNil) - replica, err := client.PostgresReadOnlyReplicas.Get(context.Background(), &GetPostgresReadOnlyReplicaRequest{ + replica, err := client.PostgresDedicatedReadReplicas.Get(context.Background(), &GetPostgresDedicatedReadReplicaRequest{ Organization: testOrg, Database: "my-db", Branch: "main", @@ -78,7 +78,7 @@ func TestPostgresReadOnlyReplicas_Get(t *testing.T) { c.Assert(replica.Name, qt.Equals, "analytics") } -func TestPostgresReadOnlyReplicas_Create(t *testing.T) { +func TestPostgresDedicatedReadReplicas_Create(t *testing.T) { c := qt.New(t) replicaCount := 2 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -93,7 +93,7 @@ func TestPostgresReadOnlyReplicas_Create(t *testing.T) { "replicas": float64(2), "cluster_size": "PS_10_GCP_X86", }) - _, err := w.Write([]byte(testReadOnlyReplicaJSON)) + _, err := w.Write([]byte(testDedicatedReadReplicaJSON)) c.Assert(err, qt.IsNil) })) defer ts.Close() @@ -101,7 +101,7 @@ func TestPostgresReadOnlyReplicas_Create(t *testing.T) { client, err := NewClient(WithBaseURL(ts.URL)) c.Assert(err, qt.IsNil) - replica, err := client.PostgresReadOnlyReplicas.Create(context.Background(), &CreatePostgresReadOnlyReplicaRequest{ + replica, err := client.PostgresDedicatedReadReplicas.Create(context.Background(), &CreatePostgresDedicatedReadReplicaRequest{ Organization: testOrg, Database: "my-db", Branch: "main", @@ -114,7 +114,7 @@ func TestPostgresReadOnlyReplicas_Create(t *testing.T) { c.Assert(replica.ID, qt.Equals, "replica-1") } -func TestPostgresReadOnlyReplicas_Update(t *testing.T) { +func TestPostgresDedicatedReadReplicas_Update(t *testing.T) { c := qt.New(t) replicaCount := 3 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -128,7 +128,7 @@ func TestPostgresReadOnlyReplicas_Update(t *testing.T) { c.Assert(body["parameters"], qt.DeepEquals, map[string]any{ "pgconf": map[string]any{"max_connections": "300"}, }) - _, err := w.Write([]byte(testReadOnlyReplicaJSON)) + _, err := w.Write([]byte(testDedicatedReadReplicaJSON)) c.Assert(err, qt.IsNil) })) defer ts.Close() @@ -136,7 +136,7 @@ func TestPostgresReadOnlyReplicas_Update(t *testing.T) { client, err := NewClient(WithBaseURL(ts.URL)) c.Assert(err, qt.IsNil) - replica, err := client.PostgresReadOnlyReplicas.Update(context.Background(), &UpdatePostgresReadOnlyReplicaRequest{ + replica, err := client.PostgresDedicatedReadReplicas.Update(context.Background(), &UpdatePostgresDedicatedReadReplicaRequest{ Organization: testOrg, Database: "my-db", Branch: "main", @@ -151,7 +151,7 @@ func TestPostgresReadOnlyReplicas_Update(t *testing.T) { c.Assert(replica.ID, qt.Equals, "replica-1") } -func TestPostgresReadOnlyReplicas_Delete(t *testing.T) { +func TestPostgresDedicatedReadReplicas_Delete(t *testing.T) { c := qt.New(t) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { c.Assert(r.Method, qt.Equals, http.MethodDelete) @@ -163,7 +163,7 @@ func TestPostgresReadOnlyReplicas_Delete(t *testing.T) { client, err := NewClient(WithBaseURL(ts.URL)) c.Assert(err, qt.IsNil) - err = client.PostgresReadOnlyReplicas.Delete(context.Background(), &DeletePostgresReadOnlyReplicaRequest{ + err = client.PostgresDedicatedReadReplicas.Delete(context.Background(), &DeletePostgresDedicatedReadReplicaRequest{ Organization: testOrg, Database: "my-db", Branch: "main", @@ -171,3 +171,29 @@ func TestPostgresReadOnlyReplicas_Delete(t *testing.T) { }) c.Assert(err, qt.IsNil) } + +func TestPostgresReadOnlyReplicasBackwardCompatibility(t *testing.T) { + c := qt.New(t) + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + c.Assert(r.Method, qt.Equals, http.MethodGet) + c.Assert(r.URL.Path, qt.Equals, "/v1/organizations/my-org/databases/my-db/branches/main/read-only-replicas") + _, err := w.Write([]byte("[" + testDedicatedReadReplicaJSON + "]")) + c.Assert(err, qt.IsNil) + })) + defer ts.Close() + + client, err := NewClient(WithBaseURL(ts.URL)) + c.Assert(err, qt.IsNil) + c.Assert(client.PostgresReadOnlyReplicas, qt.Equals, client.PostgresDedicatedReadReplicas) + + replicas, err := client.PostgresReadOnlyReplicas.List(context.Background(), &ListPostgresReadOnlyReplicasRequest{ + Organization: testOrg, + Database: "my-db", + Branch: "main", + }) + c.Assert(err, qt.IsNil) + c.Assert(replicas, qt.HasLen, 1) + + var replica *PostgresReadOnlyReplica = replicas[0] + c.Assert(replica.Name, qt.Equals, "analytics") +} diff --git a/internal/planetscale/postgres_roles.go b/internal/planetscale/postgres_roles.go index cbb41201..b92bd88f 100644 --- a/internal/planetscale/postgres_roles.go +++ b/internal/planetscale/postgres_roles.go @@ -41,11 +41,13 @@ type ListPostgresRolesRequest struct { // GetPostgresRoleRequest encapsulates the request for getting a specific role for a given database branch. type GetPostgresRoleRequest struct { - Organization string - Database string - Branch string - RoleId string - Replica bool + Organization string + Database string + Branch string + RoleId string + Replica bool + DedicatedReadReplica string + // Deprecated: use DedicatedReadReplica. DedicatedReadReplica takes precedence when both are set. ReadOnlyReplica string Bouncer string Router string @@ -210,8 +212,12 @@ func (p *postgresRolesService) Get(ctx context.Context, getReq *GetPostgresRoleR if getReq.Replica { query.Set("replica", "true") } - if getReq.ReadOnlyReplica != "" { - query.Set("read_only_replica", getReq.ReadOnlyReplica) + dedicatedReadReplica := getReq.DedicatedReadReplica + if dedicatedReadReplica == "" { + dedicatedReadReplica = getReq.ReadOnlyReplica + } + if dedicatedReadReplica != "" { + query.Set("read_only_replica", dedicatedReadReplica) } if getReq.Bouncer != "" { query.Set("bouncer", getReq.Bouncer) diff --git a/internal/planetscale/postgres_roles_test.go b/internal/planetscale/postgres_roles_test.go index c905fb67..e34139f2 100644 --- a/internal/planetscale/postgres_roles_test.go +++ b/internal/planetscale/postgres_roles_test.go @@ -399,6 +399,13 @@ func TestPostgresRoles_GetConnectionTargets(t *testing.T) { }, { name: "dedicated read replica", + request: GetPostgresRoleRequest{DedicatedReadReplica: "analytics"}, + query: url.Values{"read_only_replica": []string{"analytics"}}, + username: "test-user.replica-id|replica", + accessHost: "analytics.planetscale.com", + }, + { + name: "deprecated read-only replica field", request: GetPostgresRoleRequest{ReadOnlyReplica: "analytics"}, query: url.Values{"read_only_replica": []string{"analytics"}}, username: "test-user.replica-id|replica", From 1374fac3cc6112d22a3525b2e49f05e55db74ae5 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 5 Oct 2026 18:11:32 +0000 Subject: [PATCH 2/2] Fix compatibility test lint Co-authored-by: Nick Holden --- internal/planetscale/postgres_read_only_replicas_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/planetscale/postgres_read_only_replicas_test.go b/internal/planetscale/postgres_read_only_replicas_test.go index 3454f3b2..c0e336f2 100644 --- a/internal/planetscale/postgres_read_only_replicas_test.go +++ b/internal/planetscale/postgres_read_only_replicas_test.go @@ -194,6 +194,6 @@ func TestPostgresReadOnlyReplicasBackwardCompatibility(t *testing.T) { c.Assert(err, qt.IsNil) c.Assert(replicas, qt.HasLen, 1) - var replica *PostgresReadOnlyReplica = replicas[0] + replica := replicas[0] c.Assert(replica.Name, qt.Equals, "analytics") }