mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix: use unique workspace owners over unique users (#11044)
This commit is contained in:
@@ -2053,6 +2053,13 @@ func (q *querier) GetWorkspaceResourcesCreatedAfter(ctx context.Context, created
|
||||
return q.db.GetWorkspaceResourcesCreatedAfter(ctx, createdAt)
|
||||
}
|
||||
|
||||
func (q *querier) GetWorkspaceUniqueOwnerCountByTemplateIDs(ctx context.Context, templateIds []uuid.UUID) ([]database.GetWorkspaceUniqueOwnerCountByTemplateIDsRow, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetWorkspaceUniqueOwnerCountByTemplateIDs(ctx, templateIds)
|
||||
}
|
||||
|
||||
func (q *querier) GetWorkspaces(ctx context.Context, arg database.GetWorkspacesParams) ([]database.GetWorkspacesRow, error) {
|
||||
prep, err := prepareSQLFilter(ctx, q.auth, rbac.ActionRead, rbac.ResourceWorkspace.Type)
|
||||
if err != nil {
|
||||
|
||||
@@ -4520,6 +4520,36 @@ func (q *FakeQuerier) GetWorkspaceResourcesCreatedAfter(_ context.Context, after
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetWorkspaceUniqueOwnerCountByTemplateIDs(_ context.Context, templateIds []uuid.UUID) ([]database.GetWorkspaceUniqueOwnerCountByTemplateIDsRow, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
workspaceOwners := make(map[uuid.UUID]map[uuid.UUID]struct{})
|
||||
for _, workspace := range q.workspaces {
|
||||
if workspace.Deleted {
|
||||
continue
|
||||
}
|
||||
if !slices.Contains(templateIds, workspace.TemplateID) {
|
||||
continue
|
||||
}
|
||||
_, ok := workspaceOwners[workspace.TemplateID]
|
||||
if !ok {
|
||||
workspaceOwners[workspace.TemplateID] = make(map[uuid.UUID]struct{})
|
||||
}
|
||||
workspaceOwners[workspace.TemplateID][workspace.OwnerID] = struct{}{}
|
||||
}
|
||||
resp := make([]database.GetWorkspaceUniqueOwnerCountByTemplateIDsRow, 0)
|
||||
for _, templateID := range templateIds {
|
||||
count := len(workspaceOwners[templateID])
|
||||
resp = append(resp, database.GetWorkspaceUniqueOwnerCountByTemplateIDsRow{
|
||||
TemplateID: templateID,
|
||||
UniqueOwnersSum: int64(count),
|
||||
})
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetWorkspaces(ctx context.Context, arg database.GetWorkspacesParams) ([]database.GetWorkspacesRow, error) {
|
||||
if err := validateDatabaseType(arg); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -1229,6 +1229,13 @@ func (m metricsStore) GetWorkspaceResourcesCreatedAfter(ctx context.Context, cre
|
||||
return resources, err
|
||||
}
|
||||
|
||||
func (m metricsStore) GetWorkspaceUniqueOwnerCountByTemplateIDs(ctx context.Context, templateIds []uuid.UUID) ([]database.GetWorkspaceUniqueOwnerCountByTemplateIDsRow, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetWorkspaceUniqueOwnerCountByTemplateIDs(ctx, templateIds)
|
||||
m.queryLatencies.WithLabelValues("GetWorkspaceUniqueOwnerCountByTemplateIDs").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m metricsStore) GetWorkspaces(ctx context.Context, arg database.GetWorkspacesParams) ([]database.GetWorkspacesRow, error) {
|
||||
start := time.Now()
|
||||
workspaces, err := m.s.GetWorkspaces(ctx, arg)
|
||||
|
||||
@@ -2568,6 +2568,21 @@ func (mr *MockStoreMockRecorder) GetWorkspaceResourcesCreatedAfter(arg0, arg1 in
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspaceResourcesCreatedAfter", reflect.TypeOf((*MockStore)(nil).GetWorkspaceResourcesCreatedAfter), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetWorkspaceUniqueOwnerCountByTemplateIDs mocks base method.
|
||||
func (m *MockStore) GetWorkspaceUniqueOwnerCountByTemplateIDs(arg0 context.Context, arg1 []uuid.UUID) ([]database.GetWorkspaceUniqueOwnerCountByTemplateIDsRow, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetWorkspaceUniqueOwnerCountByTemplateIDs", arg0, arg1)
|
||||
ret0, _ := ret[0].([]database.GetWorkspaceUniqueOwnerCountByTemplateIDsRow)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetWorkspaceUniqueOwnerCountByTemplateIDs indicates an expected call of GetWorkspaceUniqueOwnerCountByTemplateIDs.
|
||||
func (mr *MockStoreMockRecorder) GetWorkspaceUniqueOwnerCountByTemplateIDs(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspaceUniqueOwnerCountByTemplateIDs", reflect.TypeOf((*MockStore)(nil).GetWorkspaceUniqueOwnerCountByTemplateIDs), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetWorkspaces mocks base method.
|
||||
func (m *MockStore) GetWorkspaces(arg0 context.Context, arg1 database.GetWorkspacesParams) ([]database.GetWorkspacesRow, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@@ -253,6 +253,7 @@ type sqlcQuerier interface {
|
||||
GetWorkspaceResourcesByJobID(ctx context.Context, jobID uuid.UUID) ([]WorkspaceResource, error)
|
||||
GetWorkspaceResourcesByJobIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceResource, error)
|
||||
GetWorkspaceResourcesCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceResource, error)
|
||||
GetWorkspaceUniqueOwnerCountByTemplateIDs(ctx context.Context, templateIds []uuid.UUID) ([]GetWorkspaceUniqueOwnerCountByTemplateIDsRow, error)
|
||||
GetWorkspaces(ctx context.Context, arg GetWorkspacesParams) ([]GetWorkspacesRow, error)
|
||||
GetWorkspacesEligibleForTransition(ctx context.Context, now time.Time) ([]Workspace, error)
|
||||
InsertAPIKey(ctx context.Context, arg InsertAPIKeyParams) (APIKey, error)
|
||||
|
||||
@@ -10734,6 +10734,44 @@ func (q *sqlQuerier) GetWorkspaceByWorkspaceAppID(ctx context.Context, workspace
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getWorkspaceUniqueOwnerCountByTemplateIDs = `-- name: GetWorkspaceUniqueOwnerCountByTemplateIDs :many
|
||||
SELECT
|
||||
template_id, COUNT(DISTINCT owner_id) AS unique_owners_sum
|
||||
FROM
|
||||
workspaces
|
||||
WHERE
|
||||
template_id = ANY($1 :: uuid[]) AND deleted = false
|
||||
GROUP BY template_id
|
||||
`
|
||||
|
||||
type GetWorkspaceUniqueOwnerCountByTemplateIDsRow struct {
|
||||
TemplateID uuid.UUID `db:"template_id" json:"template_id"`
|
||||
UniqueOwnersSum int64 `db:"unique_owners_sum" json:"unique_owners_sum"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) GetWorkspaceUniqueOwnerCountByTemplateIDs(ctx context.Context, templateIds []uuid.UUID) ([]GetWorkspaceUniqueOwnerCountByTemplateIDsRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getWorkspaceUniqueOwnerCountByTemplateIDs, pq.Array(templateIds))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetWorkspaceUniqueOwnerCountByTemplateIDsRow
|
||||
for rows.Next() {
|
||||
var i GetWorkspaceUniqueOwnerCountByTemplateIDsRow
|
||||
if err := rows.Scan(&i.TemplateID, &i.UniqueOwnersSum); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getWorkspaces = `-- name: GetWorkspaces :many
|
||||
SELECT
|
||||
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,
|
||||
|
||||
@@ -287,6 +287,15 @@ WHERE
|
||||
AND LOWER("name") = LOWER(@name)
|
||||
ORDER BY created_at DESC;
|
||||
|
||||
-- name: GetWorkspaceUniqueOwnerCountByTemplateIDs :many
|
||||
SELECT
|
||||
template_id, COUNT(DISTINCT owner_id) AS unique_owners_sum
|
||||
FROM
|
||||
workspaces
|
||||
WHERE
|
||||
template_id = ANY(@template_ids :: uuid[]) AND deleted = false
|
||||
GROUP BY template_id;
|
||||
|
||||
-- name: InsertWorkspace :one
|
||||
INSERT INTO
|
||||
workspaces (
|
||||
|
||||
Reference in New Issue
Block a user