Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 939dcdc

Browse files
committed
Write interface and database fake
1 parent fbcfa36 commit 939dcdc

File tree

2 files changed

+201
-0
lines changed

2 files changed

+201
-0
lines changed

coderd/database/databasefake/databasefake.go

+150
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,156 @@ func (q *fakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.
711711
return workspaces, nil
712712
}
713713

714+
func (q *fakeQuerier) GetWorkspaceCount(ctx context.Context, arg database.GetWorkspaceCountParams) (int64, error) {
715+
count, err := q.GetAuthorizedWorkspaceCount(ctx, arg, nil)
716+
return count, err
717+
}
718+
719+
//nolint:gocyclo
720+
func (q *fakeQuerier) GetAuthorizedWorkspaceCount(ctx context.Context, arg database.GetWorkspacesParams, authorizedFilter rbac.AuthorizeFilter) (int64, error) {
721+
q.mutex.RLock()
722+
defer q.mutex.RUnlock()
723+
724+
workspaces := make([]database.Workspace, 0)
725+
for _, workspace := range q.workspaces {
726+
if arg.OwnerID != uuid.Nil && workspace.OwnerID != arg.OwnerID {
727+
continue
728+
}
729+
730+
if arg.OwnerUsername != "" {
731+
owner, err := q.GetUserByID(ctx, workspace.OwnerID)
732+
if err == nil && !strings.EqualFold(arg.OwnerUsername, owner.Username) {
733+
continue
734+
}
735+
}
736+
737+
if arg.TemplateName != "" {
738+
template, err := q.GetTemplateByID(ctx, workspace.TemplateID)
739+
if err == nil && !strings.EqualFold(arg.TemplateName, template.Name) {
740+
continue
741+
}
742+
}
743+
744+
if !arg.Deleted && workspace.Deleted {
745+
continue
746+
}
747+
748+
if arg.Name != "" && !strings.Contains(strings.ToLower(workspace.Name), strings.ToLower(arg.Name)) {
749+
continue
750+
}
751+
752+
if arg.Status != "" {
753+
build, err := q.GetLatestWorkspaceBuildByWorkspaceID(ctx, workspace.ID)
754+
if err != nil {
755+
return 0, xerrors.Errorf("get latest build: %w", err)
756+
}
757+
758+
job, err := q.GetProvisionerJobByID(ctx, build.JobID)
759+
if err != nil {
760+
return 0, xerrors.Errorf("get provisioner job: %w", err)
761+
}
762+
763+
switch arg.Status {
764+
case "pending":
765+
if !job.StartedAt.Valid {
766+
continue
767+
}
768+
769+
case "starting":
770+
if !job.StartedAt.Valid &&
771+
!job.CanceledAt.Valid &&
772+
job.CompletedAt.Valid &&
773+
time.Since(job.UpdatedAt) > 30*time.Second ||
774+
build.Transition != database.WorkspaceTransitionStart {
775+
continue
776+
}
777+
778+
case "running":
779+
if !job.CompletedAt.Valid &&
780+
job.CanceledAt.Valid &&
781+
job.Error.Valid ||
782+
build.Transition != database.WorkspaceTransitionStart {
783+
continue
784+
}
785+
786+
case "stopping":
787+
if !job.StartedAt.Valid &&
788+
!job.CanceledAt.Valid &&
789+
job.CompletedAt.Valid &&
790+
time.Since(job.UpdatedAt) > 30*time.Second ||
791+
build.Transition != database.WorkspaceTransitionStop {
792+
continue
793+
}
794+
795+
case "stopped":
796+
if !job.CompletedAt.Valid &&
797+
job.CanceledAt.Valid &&
798+
job.Error.Valid ||
799+
build.Transition != database.WorkspaceTransitionStop {
800+
continue
801+
}
802+
803+
case "failed":
804+
if (!job.CanceledAt.Valid && !job.Error.Valid) ||
805+
(!job.CompletedAt.Valid && !job.Error.Valid) {
806+
continue
807+
}
808+
809+
case "canceling":
810+
if !job.CanceledAt.Valid && job.CompletedAt.Valid {
811+
continue
812+
}
813+
814+
case "canceled":
815+
if !job.CanceledAt.Valid && !job.CompletedAt.Valid {
816+
continue
817+
}
818+
819+
case "deleted":
820+
if !job.StartedAt.Valid &&
821+
job.CanceledAt.Valid &&
822+
!job.CompletedAt.Valid &&
823+
time.Since(job.UpdatedAt) > 30*time.Second ||
824+
build.Transition != database.WorkspaceTransitionDelete {
825+
continue
826+
}
827+
828+
case "deleting":
829+
if !job.CompletedAt.Valid &&
830+
job.CanceledAt.Valid &&
831+
job.Error.Valid &&
832+
build.Transition != database.WorkspaceTransitionDelete {
833+
continue
834+
}
835+
836+
default:
837+
return 0, xerrors.Errorf("unknown workspace status in filter: %q", arg.Status)
838+
}
839+
}
840+
841+
if len(arg.TemplateIds) > 0 {
842+
match := false
843+
for _, id := range arg.TemplateIds {
844+
if workspace.TemplateID == id {
845+
match = true
846+
break
847+
}
848+
}
849+
if !match {
850+
continue
851+
}
852+
}
853+
854+
// If the filter exists, ensure the object is authorized.
855+
if authorizedFilter != nil && !authorizedFilter.Eval(workspace.RBACObject()) {
856+
continue
857+
}
858+
workspaces = append(workspaces, workspace)
859+
}
860+
861+
return int64(len(workspaces)), nil
862+
}
863+
714864
func (q *fakeQuerier) GetWorkspaceByID(_ context.Context, id uuid.UUID) (database.Workspace, error) {
715865
q.mutex.RLock()
716866
defer q.mutex.RUnlock()

coderd/database/modelqueries.go

+51
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ func (q *sqlQuerier) GetTemplateGroupRoles(ctx context.Context, id uuid.UUID) ([
159159

160160
type workspaceQuerier interface {
161161
GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspacesParams, authorizedFilter rbac.AuthorizeFilter) ([]Workspace, error)
162+
GetAuthorizedWorkspaceCount(ctx context.Context, arg GetWorkspaceCountParams, authorizedFilter rbac.AuthorizeFilter) (int64, error)
162163
}
163164

164165
// GetAuthorizedWorkspaces returns all workspaces that the user is authorized to access.
@@ -213,3 +214,53 @@ func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspa
213214
}
214215
return items, nil
215216
}
217+
218+
func (q *sqlQuerier) GetAuthorizedWorkspaceCount(ctx context.Context, arg GetWorkspacesParams, authorizedFilter rbac.AuthorizeFilter) (int64, error) {
219+
// In order to properly use ORDER BY, OFFSET, and LIMIT, we need to inject the
220+
// authorizedFilter between the end of the where clause and those statements.
221+
filter := strings.Replace(getWorkspaces, "-- @authorize_filter", fmt.Sprintf(" AND %s", authorizedFilter.SQLString(rbac.NoACLConfig())), 1)
222+
// The name comment is for metric tracking
223+
query := fmt.Sprintf("-- name: GetAuthorizedWorkspaces :many\n%s", filter)
224+
rows, err := q.db.QueryContext(ctx, query,
225+
arg.Deleted,
226+
arg.Status,
227+
arg.OwnerID,
228+
arg.OwnerUsername,
229+
arg.TemplateName,
230+
pq.Array(arg.TemplateIds),
231+
arg.Name,
232+
arg.Offset,
233+
arg.Limit,
234+
)
235+
if err != nil {
236+
return 0, xerrors.Errorf("get authorized workspaces: %w", err)
237+
}
238+
defer rows.Close()
239+
var items []Workspace
240+
for rows.Next() {
241+
var i Workspace
242+
if err := rows.Scan(
243+
&i.ID,
244+
&i.CreatedAt,
245+
&i.UpdatedAt,
246+
&i.OwnerID,
247+
&i.OrganizationID,
248+
&i.TemplateID,
249+
&i.Deleted,
250+
&i.Name,
251+
&i.AutostartSchedule,
252+
&i.Ttl,
253+
&i.LastUsedAt,
254+
); err != nil {
255+
return 0, err
256+
}
257+
items = append(items, i)
258+
}
259+
if err := rows.Close(); err != nil {
260+
return 0, err
261+
}
262+
if err := rows.Err(); err != nil {
263+
return 0, err
264+
}
265+
return int64(len(items)), nil
266+
}

0 commit comments

Comments
 (0)