Skip to content

Commit 3496d2d

Browse files
refactor: enrich resolved postgres scope (#479)
`postgres.Service` has a `Resolve` method that returns a client.PostgresDetail object. This makes it instead return a struct that contains the Postgres detail, as well as the Project and Environment it belongs to (if it belongs to one). GROW-2588 GitOrigin-RevId: a987cf5e39d274e7c24065c3f640b790d1029d95
1 parent d055576 commit 3496d2d

7 files changed

Lines changed: 106 additions & 12 deletions

File tree

cmd/pgdelete.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,15 @@ Postgres ID instead (which works across workspaces).`,
8181
confirm := command.GetConfirmFromContext(cmd.Context())
8282

8383
loadData := func() (*pgDeleteResult, error) {
84-
pg, err := deps.PostgresService().Resolve(cmd.Context(), postgres.ResolveInput{
84+
resolved, err := deps.PostgresService().Resolve(cmd.Context(), postgres.ResolveInput{
8585
IDOrName: input.IDOrName,
8686
ProjectIDOrName: input.ProjectIDOrName,
8787
EnvironmentIDOrName: input.EnvironmentIDOrName,
8888
})
8989
if err != nil {
9090
return nil, err
9191
}
92+
pg := resolved.Postgres
9293
if confirm {
9394
if err := deps.PostgresService().Delete(cmd.Context(), pg.Id); err != nil {
9495
return nil, err

cmd/pgget.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,15 @@ Postgres ID instead (which works across workspaces).`,
6262
input = pgtypes.NormalizeGetInput(input)
6363

6464
loadData := func() (*postgres.GetResult, error) {
65-
pg, err := deps.PostgresService().Resolve(cmd.Context(), postgres.ResolveInput{
65+
resolved, err := deps.PostgresService().Resolve(cmd.Context(), postgres.ResolveInput{
6666
IDOrName: input.IDOrName,
6767
ProjectIDOrName: input.ProjectIDOrName,
6868
EnvironmentIDOrName: input.EnvironmentIDOrName,
6969
})
7070
if err != nil {
7171
return nil, err
7272
}
73+
pg := resolved.Postgres
7374
var conn *client.PostgresConnectionInfo
7475
if input.IncludeSensitiveConnectionInfo {
7576
conn, err = deps.PostgresService().GetConnectionInfo(cmd.Context(), pg.Id)

cmd/pgresume.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,23 @@ Postgres ID instead (which works across workspaces).`,
5757
input = pgtypes.NormalizeResumeInput(input)
5858

5959
loadData := func() (*client.PostgresDetail, error) {
60-
pg, err := deps.PostgresService().Resolve(cmd.Context(), postgres.ResolveInput{
60+
resolved, err := deps.PostgresService().Resolve(cmd.Context(), postgres.ResolveInput{
6161
IDOrName: input.IDOrName,
6262
ProjectIDOrName: input.ProjectIDOrName,
6363
EnvironmentIDOrName: input.EnvironmentIDOrName,
6464
})
6565
if err != nil {
6666
return nil, err
6767
}
68+
pg := resolved.Postgres
6869
if err := deps.PostgresService().ResumePostgres(cmd.Context(), pg.Id); err != nil {
6970
return nil, err
7071
}
71-
return deps.PostgresService().Resolve(cmd.Context(), postgres.ResolveInput{IDOrName: pg.Id})
72+
resolved, err = deps.PostgresService().Resolve(cmd.Context(), postgres.ResolveInput{IDOrName: pg.Id})
73+
if err != nil {
74+
return nil, err
75+
}
76+
return resolved.Postgres, nil
7277
}
7378

7479
_, err := command.NonInteractive(cmd,

cmd/pgsuspend.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,15 @@ Postgres ID instead (which works across workspaces).`,
6969
confirm := command.GetConfirmFromContext(cmd.Context())
7070

7171
loadData := func() (*pgSuspendResult, error) {
72-
pg, err := deps.PostgresService().Resolve(cmd.Context(), postgres.ResolveInput{
72+
resolved, err := deps.PostgresService().Resolve(cmd.Context(), postgres.ResolveInput{
7373
IDOrName: input.IDOrName,
7474
ProjectIDOrName: input.ProjectIDOrName,
7575
EnvironmentIDOrName: input.EnvironmentIDOrName,
7676
})
7777
if err != nil {
7878
return nil, err
7979
}
80+
pg := resolved.Postgres
8081
if !confirm {
8182
return &pgSuspendResult{Postgres: pg, Suspended: false}, nil
8283
}
@@ -87,7 +88,7 @@ Postgres ID instead (which works across workspaces).`,
8788
if err != nil {
8889
return nil, err
8990
}
90-
return &pgSuspendResult{Postgres: post, Suspended: true}, nil
91+
return &pgSuspendResult{Postgres: post.Postgres, Suspended: true}, nil
9192
}
9293

9394
_, err := command.NonInteractive(cmd,

pkg/postgres/resolve.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,49 @@ type resolveScope struct {
2626
env *client.Environment
2727
}
2828

29-
func (s *Service) resolve(ctx context.Context, input ResolveInput) (*client.PostgresDetail, error) {
29+
func (s *Service) resolve(ctx context.Context, input ResolveInput) (*ResolvedPostgres, error) {
3030
scope, err := s.resolveScope(ctx, input)
3131
if err != nil {
3232
return nil, err
3333
}
34-
return s.resolveInScope(ctx, input.IDOrName, scope)
34+
pg, err := s.resolveInScope(ctx, input.IDOrName, scope)
35+
if err != nil {
36+
return nil, err
37+
}
38+
resolved := &ResolvedPostgres{
39+
Postgres: pg,
40+
Project: scope.project,
41+
Environment: scope.env,
42+
}
43+
if err := s.enrichResolvedPostgres(ctx, resolved); err != nil {
44+
return nil, err
45+
}
46+
return resolved, nil
47+
}
48+
49+
// enrichResolvedPostgres fills in related project/environment data when the
50+
// lookup itself did not already resolve that context.
51+
func (s *Service) enrichResolvedPostgres(ctx context.Context, resolved *ResolvedPostgres) error {
52+
if resolved.Postgres == nil || resolved.Postgres.EnvironmentId == nil {
53+
return nil
54+
}
55+
56+
pg := postgresFromPostgresDetail(resolved.Postgres)
57+
if resolved.Environment == nil {
58+
env, err := s.environmentForPostgres(ctx, pg, nil)
59+
if err != nil {
60+
return err
61+
}
62+
resolved.Environment = env
63+
}
64+
if resolved.Project == nil && resolved.Environment != nil {
65+
project, err := s.projectRepo.GetProject(ctx, resolved.Environment.ProjectId)
66+
if err != nil {
67+
return err
68+
}
69+
resolved.Project = project
70+
}
71+
return nil
3572
}
3673

3774
func (s *Service) resolveScope(ctx context.Context, input ResolveInput) (resolveScope, error) {

pkg/postgres/service.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ type Service struct {
1919
resolver *resolve.Resolver
2020
}
2121

22+
// ResolvedPostgres carries a Postgres detail plus its resolved scope.
23+
type ResolvedPostgres struct {
24+
Postgres *client.PostgresDetail
25+
Project *client.Project
26+
Environment *client.Environment
27+
}
28+
2229
func NewService(repo *Repo, environmentRepo *environment.Repo, projectRepo *project.Repo, resolver *resolve.Resolver) *Service {
2330
return &Service{
2431
repo: repo,
@@ -100,7 +107,7 @@ func (s *Service) GetConnectionInfo(ctx context.Context, id string) (*client.Pos
100107

101108
// Resolve resolves a Postgres database by ID or name within an optional
102109
// active-workspace project/environment scope.
103-
func (s *Service) Resolve(ctx context.Context, input ResolveInput) (*client.PostgresDetail, error) {
110+
func (s *Service) Resolve(ctx context.Context, input ResolveInput) (*ResolvedPostgres, error) {
104111
return s.resolve(ctx, input)
105112
}
106113

@@ -149,14 +156,15 @@ func (s *Service) Create(ctx context.Context, input pgtypes.CreatePostgresInput)
149156
// narrowed by project/environment), builds the PATCH body, and applies it via
150157
// the Render API. Returns both the pre- and post-update server state.
151158
func (s *Service) Update(ctx context.Context, input pgtypes.UpdatePostgresInput) (*UpdateResult, error) {
152-
before, err := s.Resolve(ctx, ResolveInput{
159+
resolvedBefore, err := s.Resolve(ctx, ResolveInput{
153160
IDOrName: input.IDOrName,
154161
ProjectIDOrName: input.ProjectIDOrName,
155162
EnvironmentIDOrName: input.EnvironmentIDOrName,
156163
})
157164
if err != nil {
158165
return nil, err
159166
}
167+
before := resolvedBefore.Postgres
160168

161169
body, err := BuildUpdateRequest(input)
162170
if err != nil {

pkg/postgres/service_test.go

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,49 @@ func TestServiceResolve_EnvironmentLookupStaysInActiveWorkspace(t *testing.T) {
255255
})
256256
require.NoError(t, err)
257257

258-
assert.NotEqual(t, otherWorkspacePG.Id, result.Id)
259-
assert.Equal(t, activeWorkspacePG.Id, result.Id)
258+
require.NotNil(t, result.Postgres)
259+
assert.NotEqual(t, otherWorkspacePG.Id, result.Postgres.Id)
260+
assert.Equal(t, activeWorkspacePG.Id, result.Postgres.Id)
261+
}
262+
263+
func TestServiceResolve_EnrichesProjectAndEnvironmentForIDLookup(t *testing.T) {
264+
harness := newHarness(t)
265+
env := harness.addProjectAndEnvironment(harness.workspaceID, "Active Project", "production")
266+
pg := harness.addPostgresInEnvironment("my-db", env.Id)
267+
project := harness.requireProject(env.ProjectId)
268+
269+
result, err := harness.service.Resolve(context.Background(), postgres.ResolveInput{
270+
IDOrName: pg.Id,
271+
})
272+
require.NoError(t, err)
273+
274+
require.NotNil(t, result.Postgres)
275+
assert.Equal(t, pg.Id, result.Postgres.Id)
276+
require.NotNil(t, result.Environment)
277+
assert.Equal(t, env.Id, result.Environment.Id)
278+
require.NotNil(t, result.Project)
279+
assert.Equal(t, project.Id, result.Project.Id)
280+
}
281+
282+
func TestServiceResolve_PreservesResolvedProjectAndEnvironmentForScopedNameLookup(t *testing.T) {
283+
harness := newHarness(t)
284+
env := harness.addProjectAndEnvironment(harness.workspaceID, "Active Project", "production")
285+
pg := harness.addPostgresInEnvironment("my-db", env.Id)
286+
project := harness.requireProject(env.ProjectId)
287+
288+
result, err := harness.service.Resolve(context.Background(), postgres.ResolveInput{
289+
IDOrName: "my-db",
290+
ProjectIDOrName: pointers.From(project.Name),
291+
EnvironmentIDOrName: pointers.From(env.Name),
292+
})
293+
require.NoError(t, err)
294+
295+
require.NotNil(t, result.Postgres)
296+
assert.Equal(t, pg.Id, result.Postgres.Id)
297+
require.NotNil(t, result.Environment)
298+
assert.Equal(t, env.Id, result.Environment.Id)
299+
require.NotNil(t, result.Project)
300+
assert.Equal(t, project.Id, result.Project.Id)
260301
}
261302

262303
func TestServiceResolve_IDLookup_NonNotFoundError_Surfaces(t *testing.T) {

0 commit comments

Comments
 (0)