chore: add GetLatestWorkspaceBuildWithStatusByWorkspaceID query (#24441)

<!--

If you have used AI to produce some or all of this PR, please ensure you have read our [AI Contribution guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING) before submitting.

-->

relates to GRU-18  
  
Adds new database query supporting the Agent Connection Watch we will add.
This commit is contained in:
Spike Curtis
2026-04-17 22:47:08 -04:00
committed by GitHub
parent 72f35e1cd3
commit e19b21b7d5
8 changed files with 110 additions and 0 deletions
+4
View File
@@ -3253,6 +3253,10 @@ func (q *querier) GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, work
return q.db.GetLatestWorkspaceBuildByWorkspaceID(ctx, workspaceID)
}
func (q *querier) GetLatestWorkspaceBuildWithStatusByWorkspaceID(ctx context.Context, workspaceID uuid.UUID) (database.GetLatestWorkspaceBuildWithStatusByWorkspaceIDRow, error) {
return fetch(q.log, q.auth, q.db.GetLatestWorkspaceBuildWithStatusByWorkspaceID)(ctx, workspaceID)
}
func (q *querier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context, ids []uuid.UUID) ([]database.WorkspaceBuild, error) {
// This function is a system function until we implement a join for workspace builds.
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil {
+5
View File
@@ -2991,6 +2991,11 @@ func (s *MethodTestSuite) TestWorkspace() {
dbm.EXPECT().GetLatestWorkspaceBuildByWorkspaceID(gomock.Any(), w.ID).Return(b, nil).AnyTimes()
check.Args(w.ID).Asserts(w, policy.ActionRead).Returns(b)
}))
s.Run("GetLatestWorkspaceBuildWithStatusByWorkspaceID", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
r := testutil.Fake(s.T(), faker, database.GetLatestWorkspaceBuildWithStatusByWorkspaceIDRow{})
dbm.EXPECT().GetLatestWorkspaceBuildWithStatusByWorkspaceID(gomock.Any(), r.WorkspaceTable.ID).Return(r, nil).AnyTimes()
check.Args(r.WorkspaceTable.ID).Asserts(r.WorkspaceTable, policy.ActionRead).Returns(r)
}))
s.Run("GetWorkspaceAgentByID", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
w := testutil.Fake(s.T(), faker, database.Workspace{})
agt := testutil.Fake(s.T(), faker, database.WorkspaceAgent{})
@@ -1800,6 +1800,14 @@ func (m queryMetricsStore) GetLatestWorkspaceBuildByWorkspaceID(ctx context.Cont
return r0, r1
}
func (m queryMetricsStore) GetLatestWorkspaceBuildWithStatusByWorkspaceID(ctx context.Context, workspaceID uuid.UUID) (database.GetLatestWorkspaceBuildWithStatusByWorkspaceIDRow, error) {
start := time.Now()
r0, r1 := m.s.GetLatestWorkspaceBuildWithStatusByWorkspaceID(ctx, workspaceID)
m.queryLatencies.WithLabelValues("GetLatestWorkspaceBuildWithStatusByWorkspaceID").Observe(time.Since(start).Seconds())
m.queryCounts.WithLabelValues(httpmw.ExtractHTTPRoute(ctx), httpmw.ExtractHTTPMethod(ctx), "GetLatestWorkspaceBuildWithStatusByWorkspaceID").Inc()
return r0, r1
}
func (m queryMetricsStore) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context, ids []uuid.UUID) ([]database.WorkspaceBuild, error) {
start := time.Now()
r0, r1 := m.s.GetLatestWorkspaceBuildsByWorkspaceIDs(ctx, ids)
+15
View File
@@ -3332,6 +3332,21 @@ func (mr *MockStoreMockRecorder) GetLatestWorkspaceBuildByWorkspaceID(ctx, works
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLatestWorkspaceBuildByWorkspaceID", reflect.TypeOf((*MockStore)(nil).GetLatestWorkspaceBuildByWorkspaceID), ctx, workspaceID)
}
// GetLatestWorkspaceBuildWithStatusByWorkspaceID mocks base method.
func (m *MockStore) GetLatestWorkspaceBuildWithStatusByWorkspaceID(ctx context.Context, workspaceID uuid.UUID) (database.GetLatestWorkspaceBuildWithStatusByWorkspaceIDRow, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetLatestWorkspaceBuildWithStatusByWorkspaceID", ctx, workspaceID)
ret0, _ := ret[0].(database.GetLatestWorkspaceBuildWithStatusByWorkspaceIDRow)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetLatestWorkspaceBuildWithStatusByWorkspaceID indicates an expected call of GetLatestWorkspaceBuildWithStatusByWorkspaceID.
func (mr *MockStoreMockRecorder) GetLatestWorkspaceBuildWithStatusByWorkspaceID(ctx, workspaceID any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLatestWorkspaceBuildWithStatusByWorkspaceID", reflect.TypeOf((*MockStore)(nil).GetLatestWorkspaceBuildWithStatusByWorkspaceID), ctx, workspaceID)
}
// GetLatestWorkspaceBuildsByWorkspaceIDs mocks base method.
func (m *MockStore) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context, ids []uuid.UUID) ([]database.WorkspaceBuild, error) {
m.ctrl.T.Helper()
+4
View File
@@ -952,3 +952,7 @@ type UpsertConnectionLogParams struct {
Time time.Time `db:"time" json:"time"`
ConnectionStatus ConnectionStatus `db:"connection_status" json:"connection_status"`
}
func (r GetLatestWorkspaceBuildWithStatusByWorkspaceIDRow) RBACObject() rbac.Object {
return r.WorkspaceTable.RBACObject()
}
+1
View File
@@ -410,6 +410,7 @@ type sqlcQuerier interface {
GetLatestWorkspaceAppStatusByAppID(ctx context.Context, appID uuid.UUID) (WorkspaceAppStatus, error)
GetLatestWorkspaceAppStatusesByWorkspaceIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceAppStatus, error)
GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, workspaceID uuid.UUID) (WorkspaceBuild, error)
GetLatestWorkspaceBuildWithStatusByWorkspaceID(ctx context.Context, workspaceID uuid.UUID) (GetLatestWorkspaceBuildWithStatusByWorkspaceIDRow, error)
GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceBuild, error)
GetLicenseByID(ctx context.Context, id int32) (License, error)
GetLicenses(ctx context.Context) ([]License, error)
+55
View File
@@ -29660,6 +29660,61 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, w
return i, err
}
const getLatestWorkspaceBuildWithStatusByWorkspaceID = `-- name: GetLatestWorkspaceBuildWithStatusByWorkspaceID :one
SELECT
workspace_builds.transition, workspace_builds.build_number, provisioner_jobs.job_status,
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates, workspaces.favorite, workspaces.next_start_at, workspaces.group_acl, workspaces.user_acl -- Used for dbauthz fetch() checks
FROM
workspace_builds
INNER JOIN
provisioner_jobs ON workspace_builds.job_id = provisioner_jobs.id
INNER JOIN
workspaces ON workspace_builds.workspace_id = workspaces.id
WHERE
workspace_builds.workspace_id = $1 AND
workspaces.deleted = false
ORDER BY
workspace_builds.build_number desc
LIMIT
1
`
type GetLatestWorkspaceBuildWithStatusByWorkspaceIDRow struct {
Transition WorkspaceTransition `db:"transition" json:"transition"`
BuildNumber int32 `db:"build_number" json:"build_number"`
JobStatus ProvisionerJobStatus `db:"job_status" json:"job_status"`
WorkspaceTable WorkspaceTable `db:"workspace_table" json:"workspace_table"`
}
func (q *sqlQuerier) GetLatestWorkspaceBuildWithStatusByWorkspaceID(ctx context.Context, workspaceID uuid.UUID) (GetLatestWorkspaceBuildWithStatusByWorkspaceIDRow, error) {
row := q.db.QueryRowContext(ctx, getLatestWorkspaceBuildWithStatusByWorkspaceID, workspaceID)
var i GetLatestWorkspaceBuildWithStatusByWorkspaceIDRow
err := row.Scan(
&i.Transition,
&i.BuildNumber,
&i.JobStatus,
&i.WorkspaceTable.ID,
&i.WorkspaceTable.CreatedAt,
&i.WorkspaceTable.UpdatedAt,
&i.WorkspaceTable.OwnerID,
&i.WorkspaceTable.OrganizationID,
&i.WorkspaceTable.TemplateID,
&i.WorkspaceTable.Deleted,
&i.WorkspaceTable.Name,
&i.WorkspaceTable.AutostartSchedule,
&i.WorkspaceTable.Ttl,
&i.WorkspaceTable.LastUsedAt,
&i.WorkspaceTable.DormantAt,
&i.WorkspaceTable.DeletingAt,
&i.WorkspaceTable.AutomaticUpdates,
&i.WorkspaceTable.Favorite,
&i.WorkspaceTable.NextStartAt,
&i.WorkspaceTable.GroupACL,
&i.WorkspaceTable.UserACL,
)
return i, err
}
const getLatestWorkspaceBuildsByWorkspaceIDs = `-- name: GetLatestWorkspaceBuildsByWorkspaceIDs :many
SELECT
DISTINCT ON (workspace_id)
@@ -291,3 +291,21 @@ INNER JOIN
templates ON templates.id = workspaces.template_id
WHERE
workspace_builds.id = @workspace_build_id;
-- name: GetLatestWorkspaceBuildWithStatusByWorkspaceID :one
SELECT
workspace_builds.transition, workspace_builds.build_number, provisioner_jobs.job_status,
sqlc.embed(workspaces) -- Used for dbauthz fetch() checks
FROM
workspace_builds
INNER JOIN
provisioner_jobs ON workspace_builds.job_id = provisioner_jobs.id
INNER JOIN
workspaces ON workspace_builds.workspace_id = workspaces.id
WHERE
workspace_builds.workspace_id = $1 AND
workspaces.deleted = false
ORDER BY
workspace_builds.build_number desc
LIMIT
1;