5
5
"errors"
6
6
"fmt"
7
7
"net/http"
8
+ "time"
8
9
9
10
"github.com/go-chi/render"
10
11
"github.com/google/uuid"
@@ -30,7 +31,16 @@ type CreateParameterValueRequest struct {
30
31
// Project is the JSON representation of a Coder project.
31
32
// This type matches the database object for now, but is
32
33
// abstracted for ease of change later on.
33
- type Project database.Project
34
+ type Project struct {
35
+ ID uuid.UUID `json:"id"`
36
+ CreatedAt time.Time `json:"created_at"`
37
+ UpdatedAt time.Time `json:"updated_at"`
38
+ OrganizationID string `json:"organization_id"`
39
+ Name string `json:"name"`
40
+ Provisioner database.ProvisionerType `json:"provisioner"`
41
+ ActiveVersionID uuid.UUID `json:"active_version_id"`
42
+ WorkspaceOwnerCount uint32 `json:"workspace_owner_count"`
43
+ }
34
44
35
45
// CreateProjectRequest enables callers to create a new Project.
36
46
type CreateProjectRequest struct {
@@ -69,11 +79,22 @@ func (api *api) projects(rw http.ResponseWriter, r *http.Request) {
69
79
})
70
80
return
71
81
}
72
- if projects == nil {
73
- projects = []database.Project {}
82
+ projectIDs := make ([]uuid.UUID , 0 , len (projects ))
83
+ for _ , project := range projects {
84
+ projectIDs = append (projectIDs , project .ID )
85
+ }
86
+ workspaceCounts , err := api .Database .GetWorkspaceOwnerCountsByProjectIDs (r .Context (), projectIDs )
87
+ if errors .Is (err , sql .ErrNoRows ) {
88
+ err = nil
89
+ }
90
+ if err != nil {
91
+ httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
92
+ Message : fmt .Sprintf ("get workspace counts: %s" , err .Error ()),
93
+ })
94
+ return
74
95
}
75
96
render .Status (r , http .StatusOK )
76
- render .JSON (rw , r , projects )
97
+ render .JSON (rw , r , convertProjects ( projects , workspaceCounts ) )
77
98
}
78
99
79
100
// Lists all projects in an organization.
@@ -89,11 +110,22 @@ func (api *api) projectsByOrganization(rw http.ResponseWriter, r *http.Request)
89
110
})
90
111
return
91
112
}
92
- if projects == nil {
93
- projects = []database.Project {}
113
+ projectIDs := make ([]uuid.UUID , 0 , len (projects ))
114
+ for _ , project := range projects {
115
+ projectIDs = append (projectIDs , project .ID )
116
+ }
117
+ workspaceCounts , err := api .Database .GetWorkspaceOwnerCountsByProjectIDs (r .Context (), projectIDs )
118
+ if errors .Is (err , sql .ErrNoRows ) {
119
+ err = nil
120
+ }
121
+ if err != nil {
122
+ httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
123
+ Message : fmt .Sprintf ("get workspace counts: %s" , err .Error ()),
124
+ })
125
+ return
94
126
}
95
127
render .Status (r , http .StatusOK )
96
- render .JSON (rw , r , projects )
128
+ render .JSON (rw , r , convertProjects ( projects , workspaceCounts ) )
97
129
}
98
130
99
131
// Create a new project in an organization.
@@ -162,7 +194,7 @@ func (api *api) postProjectsByOrganization(rw http.ResponseWriter, r *http.Reque
162
194
if err != nil {
163
195
return xerrors .Errorf ("insert project version: %s" , err )
164
196
}
165
- project = Project (dbProject )
197
+ project = convertProject (dbProject , 0 )
166
198
return nil
167
199
})
168
200
if err != nil {
@@ -241,6 +273,38 @@ func (api *api) parametersByProject(rw http.ResponseWriter, r *http.Request) {
241
273
render .JSON (rw , r , apiParameterValues )
242
274
}
243
275
276
+ func convertProjects (projects []database.Project , workspaceCounts []database.GetWorkspaceOwnerCountsByProjectIDsRow ) []Project {
277
+ apiProjects := make ([]Project , 0 , len (projects ))
278
+ for _ , project := range projects {
279
+ found := false
280
+ for _ , workspaceCount := range workspaceCounts {
281
+ if workspaceCount .ProjectID .String () != project .ID .String () {
282
+ continue
283
+ }
284
+ apiProjects = append (apiProjects , convertProject (project , uint32 (workspaceCount .Count )))
285
+ found = true
286
+ break
287
+ }
288
+ if ! found {
289
+ apiProjects = append (apiProjects , convertProject (project , uint32 (0 )))
290
+ }
291
+ }
292
+ return apiProjects
293
+ }
294
+
295
+ func convertProject (project database.Project , workspaceOwnerCount uint32 ) Project {
296
+ return Project {
297
+ ID : project .ID ,
298
+ CreatedAt : project .CreatedAt ,
299
+ UpdatedAt : project .UpdatedAt ,
300
+ OrganizationID : project .OrganizationID ,
301
+ Name : project .Name ,
302
+ Provisioner : project .Provisioner ,
303
+ ActiveVersionID : project .ActiveVersionID ,
304
+ WorkspaceOwnerCount : workspaceOwnerCount ,
305
+ }
306
+ }
307
+
244
308
func convertParameterValue (parameterValue database.ParameterValue ) ParameterValue {
245
309
parameterValue .SourceValue = ""
246
310
return ParameterValue (parameterValue )
0 commit comments