Skip to content

Commit 3eac162

Browse files
authored
refactor(api,cdsctl): do not load all project components when not needed (#5289)
1 parent b404792 commit 3eac162

File tree

8 files changed

+158
-237
lines changed

8 files changed

+158
-237
lines changed

cli/cdsctl/workflow_label.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,15 @@ var workflowLabelAddCmd = cli.Command{
4444
Ctx: []cli.Arg{
4545
{Name: _ProjectKey},
4646
{Name: _WorkflowName},
47+
},
48+
Args: []cli.Arg{
4749
{Name: "label"},
4850
},
4951
}
5052

5153
func workflowLabelAddRun(v cli.Values) error {
5254
labelName := v.GetString("label")
53-
err := client.WorkflowLabelAdd(v.GetString(_ProjectKey), v.GetString(_WorkflowName), labelName)
54-
return err
55+
return client.WorkflowLabelAdd(v.GetString(_ProjectKey), v.GetString(_WorkflowName), labelName)
5556
}
5657

5758
var workflowLabelDeleteCmd = cli.Command{
@@ -61,6 +62,8 @@ var workflowLabelDeleteCmd = cli.Command{
6162
Ctx: []cli.Arg{
6263
{Name: _ProjectKey},
6364
{Name: _WorkflowName},
65+
},
66+
Args: []cli.Arg{
6467
{Name: "label"},
6568
},
6669
}

engine/api/project/dao.go

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -311,76 +311,6 @@ func unwrap(ctx context.Context, db gorp.SqlExecutor, p *dbProject, opts []LoadO
311311
return &proj, nil
312312
}
313313

314-
// Labels return list of labels given a project ID
315-
func Labels(db gorp.SqlExecutor, projectID int64) ([]sdk.Label, error) {
316-
var labels []sdk.Label
317-
query := `
318-
SELECT project_label.*
319-
FROM project_label
320-
WHERE project_label.project_id = $1
321-
ORDER BY project_label.name
322-
`
323-
if _, err := db.Select(&labels, query, projectID); err != nil {
324-
if err == sql.ErrNoRows {
325-
return labels, nil
326-
}
327-
return labels, sdk.WrapError(err, "Cannot load labels")
328-
}
329-
330-
return labels, nil
331-
}
332-
333-
// LabelByName return a label given his name and project id
334-
func LabelByName(db gorp.SqlExecutor, projectID int64, labelName string) (sdk.Label, error) {
335-
var label sdk.Label
336-
err := db.SelectOne(&label, "SELECT project_label.* FROM project_label WHERE project_id = $1 AND name = $2", projectID, labelName)
337-
338-
return label, err
339-
}
340-
341-
// DeleteLabel delete a label given a label ID
342-
func DeleteLabel(db gorp.SqlExecutor, labelID int64) error {
343-
query := "DELETE FROM project_label WHERE id = $1"
344-
if _, err := db.Exec(query, labelID); err != nil {
345-
if err == sql.ErrNoRows {
346-
return nil
347-
}
348-
return sdk.WrapError(err, "Cannot delete labels")
349-
}
350-
351-
return nil
352-
}
353-
354-
// InsertLabel insert a label
355-
func InsertLabel(db gorp.SqlExecutor, label *sdk.Label) error {
356-
if err := label.IsValid(); err != nil {
357-
return err
358-
}
359-
360-
lbl := dbLabel(*label)
361-
if err := db.Insert(&lbl); err != nil {
362-
return sdk.WrapError(err, "Cannot insert labels")
363-
}
364-
*label = sdk.Label(lbl)
365-
366-
return nil
367-
}
368-
369-
// UpdateLabel update a label
370-
func UpdateLabel(db gorp.SqlExecutor, label *sdk.Label) error {
371-
if err := label.IsValid(); err != nil {
372-
return err
373-
}
374-
375-
lbl := dbLabel(*label)
376-
if _, err := db.Update(&lbl); err != nil {
377-
return sdk.WrapError(err, "Cannot update labels")
378-
}
379-
*label = sdk.Label(lbl)
380-
381-
return nil
382-
}
383-
384314
// UpdateFavorite add or delete project from user favorites
385315
func UpdateFavorite(db gorp.SqlExecutor, projectID int64, userID string, add bool) error {
386316
var query string

engine/api/project/dao_label.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package project
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
7+
"github.com/go-gorp/gorp"
8+
"github.com/ovh/cds/engine/api/database/gorpmapping"
9+
"github.com/ovh/cds/sdk"
10+
)
11+
12+
// Labels return list of labels given a project ID
13+
func Labels(db gorp.SqlExecutor, projectID int64) ([]sdk.Label, error) {
14+
var labels []sdk.Label
15+
query := `
16+
SELECT project_label.*
17+
FROM project_label
18+
WHERE project_label.project_id = $1
19+
ORDER BY project_label.name
20+
`
21+
if _, err := db.Select(&labels, query, projectID); err != nil {
22+
if err == sql.ErrNoRows {
23+
return labels, nil
24+
}
25+
return labels, sdk.WrapError(err, "Cannot load labels")
26+
}
27+
28+
return labels, nil
29+
}
30+
31+
// LabelByName return a label given his name and project id.
32+
func LabelByName(ctx context.Context, db gorp.SqlExecutor, projectID int64, labelName string) (*sdk.Label, error) {
33+
var label dbLabel
34+
query := gorpmapping.NewQuery("SELECT * FROM project_label WHERE project_id = $1 AND name = $2").Args(projectID, labelName)
35+
found, err := gorpmapping.Get(ctx, db, query, &label)
36+
if err != nil {
37+
return nil, sdk.WrapError(err, "cannot get label with name %s for project %d", labelName, projectID)
38+
}
39+
if !found {
40+
return nil, sdk.WithStack(sdk.ErrNotFound)
41+
}
42+
l := sdk.Label(label)
43+
return &l, nil
44+
}
45+
46+
// DeleteLabel delete a label given a label ID
47+
func DeleteLabel(db gorp.SqlExecutor, labelID int64) error {
48+
query := "DELETE FROM project_label WHERE id = $1"
49+
if _, err := db.Exec(query, labelID); err != nil {
50+
if err == sql.ErrNoRows {
51+
return nil
52+
}
53+
return sdk.WrapError(err, "cannot delete labels")
54+
}
55+
return nil
56+
}
57+
58+
// InsertLabel insert a label
59+
func InsertLabel(db gorp.SqlExecutor, label *sdk.Label) error {
60+
if err := label.IsValid(); err != nil {
61+
return err
62+
}
63+
64+
lbl := dbLabel(*label)
65+
if err := db.Insert(&lbl); err != nil {
66+
return sdk.WrapError(err, "cannot insert new label")
67+
}
68+
*label = sdk.Label(lbl)
69+
70+
return nil
71+
}
72+
73+
// UpdateLabel update a label
74+
func UpdateLabel(db gorp.SqlExecutor, label *sdk.Label) error {
75+
if err := label.IsValid(); err != nil {
76+
return err
77+
}
78+
79+
lbl := dbLabel(*label)
80+
if _, err := db.Update(&lbl); err != nil {
81+
return sdk.WrapError(err, "cannot update labels")
82+
}
83+
*label = sdk.Label(lbl)
84+
85+
return nil
86+
}

engine/api/workflow.go

Lines changed: 27 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package api
22

33
import (
44
"context"
5-
"database/sql"
65
"fmt"
76
"io/ioutil"
87
"net/http"
@@ -232,9 +231,7 @@ func (api *API) postWorkflowRollbackHandler() service.Handler {
232231
if err != nil {
233232
return sdk.WrapError(err, "cannot begin transaction")
234233
}
235-
defer func() {
236-
_ = tx.Rollback()
237-
}()
234+
defer tx.Rollback() // nolint
238235

239236
newWf, _, errP := workflow.ParseAndImport(ctx, tx, api.Cache, *proj, wf, exportWf, u, workflow.ImportOptions{Force: true, WorkflowName: workflowName})
240237
if errP != nil {
@@ -265,57 +262,47 @@ func (api *API) postWorkflowLabelHandler() service.Handler {
265262

266263
var label sdk.Label
267264
if err := service.UnmarshalBody(r, &label); err != nil {
268-
return sdk.WrapError(err, "cannot read body")
265+
return err
266+
}
267+
if label.ID == 0 && label.Name == "" {
268+
return sdk.NewErrorFrom(sdk.ErrWrongRequest, "label ID or label name should not be empty")
269269
}
270270

271-
proj, err := project.Load(ctx, db, key,
272-
project.LoadOptions.WithApplicationWithDeploymentStrategies,
273-
project.LoadOptions.WithPipelines,
274-
project.LoadOptions.WithEnvironments,
275-
project.LoadOptions.WithGroups,
276-
project.LoadOptions.WithIntegrations,
277-
)
271+
tx, err := db.Begin()
278272
if err != nil {
279-
return sdk.WrapError(err, "cannot load project %s", key)
273+
return sdk.WrapError(err, "cannot create new transaction")
280274
}
281-
label.ProjectID = proj.ID
275+
defer tx.Rollback() //nolint
282276

283-
tx, errTx := db.Begin()
284-
if errTx != nil {
285-
return sdk.WrapError(errTx, "cannot create new transaction")
277+
proj, err := project.Load(ctx, tx, key)
278+
if err != nil {
279+
return sdk.WrapError(err, "cannot load project %s", key)
286280
}
287-
defer tx.Rollback() //nolint
281+
label.ProjectID = proj.ID
288282

289283
if label.ID == 0 {
290-
if label.Name == "" {
291-
return sdk.NewErrorFrom(sdk.ErrWrongRequest, "label ID or label name should not be empty")
284+
existingLabel, err := project.LabelByName(ctx, tx, proj.ID, label.Name)
285+
if err != nil && !sdk.ErrorIs(err, sdk.ErrNotFound) {
286+
return err
292287
}
293-
294-
lbl, err := project.LabelByName(tx, proj.ID, label.Name)
295-
if err != nil {
296-
if sdk.Cause(err) != sql.ErrNoRows {
297-
return sdk.WrapError(err, "cannot load label by name")
298-
}
299-
// If label doesn't exist create him
288+
if existingLabel == nil {
300289
if err := project.InsertLabel(tx, &label); err != nil {
301290
return sdk.WrapError(err, "cannot create new label")
302291
}
303292
} else {
304-
label.ID = lbl.ID
293+
label.ID = existingLabel.ID
305294
}
306295
}
307296

308-
wf, err := workflow.Load(ctx, tx, api.Cache, *proj, workflowName, workflow.LoadOptions{WithLabels: true})
297+
wf, err := workflow.Load(ctx, tx, api.Cache, *proj, workflowName, workflow.LoadOptions{Minimal: true})
309298
if err != nil {
310299
return sdk.WrapError(err, "cannot load workflow %s/%s", key, workflowName)
311300
}
312301

313302
if err := workflow.LabelWorkflow(tx, label.ID, wf.ID); err != nil {
314303
return sdk.WrapError(err, "cannot link label %d to workflow %s", label.ID, wf.Name)
315304
}
316-
newWf := *wf
317305
label.WorkflowID = wf.ID
318-
newWf.Labels = append(newWf.Labels, label)
319306

320307
if err := tx.Commit(); err != nil {
321308
return sdk.WithStack(err)
@@ -331,25 +318,19 @@ func (api *API) deleteWorkflowLabelHandler() service.Handler {
331318
vars := mux.Vars(r)
332319
key := vars["key"]
333320
workflowName := vars["permWorkflowName"]
334-
labelID, errV := requestVarInt(r, "labelID")
335-
if errV != nil {
336-
return sdk.WrapError(errV, "cannot convert to int labelID")
321+
labelID, err := requestVarInt(r, "labelID")
322+
if err != nil {
323+
return sdk.WrapError(err, "cannot convert to int labelID")
337324
}
338325

339326
db := api.mustDB()
340327

341-
proj, err := project.Load(ctx, db, key,
342-
project.LoadOptions.WithApplicationWithDeploymentStrategies,
343-
project.LoadOptions.WithPipelines,
344-
project.LoadOptions.WithEnvironments,
345-
project.LoadOptions.WithGroups,
346-
project.LoadOptions.WithIntegrations,
347-
)
328+
proj, err := project.Load(ctx, db, key)
348329
if err != nil {
349330
return sdk.WrapError(err, "cannot load project %s", key)
350331
}
351332

352-
wf, err := workflow.Load(ctx, db, api.Cache, *proj, workflowName, workflow.LoadOptions{})
333+
wf, err := workflow.Load(ctx, db, api.Cache, *proj, workflowName, workflow.LoadOptions{Minimal: true})
353334
if err != nil {
354335
return sdk.WrapError(err, "cannot load workflow %s/%s", key, workflowName)
355336
}
@@ -369,9 +350,6 @@ func (api *API) postWorkflowHandler() service.Handler {
369350
key := vars[permProjectKey]
370351

371352
p, err := project.Load(ctx, api.mustDB(), key,
372-
project.LoadOptions.WithApplicationWithDeploymentStrategies,
373-
project.LoadOptions.WithPipelines,
374-
project.LoadOptions.WithEnvironments,
375353
project.LoadOptions.WithGroups,
376354
project.LoadOptions.WithIntegrations,
377355
)
@@ -390,9 +368,9 @@ func (api *API) postWorkflowHandler() service.Handler {
390368
data.ProjectID = p.ID
391369
data.ProjectKey = key
392370

393-
tx, errT := api.mustDB().Begin()
394-
if errT != nil {
395-
return sdk.WithStack(errT)
371+
tx, err := api.mustDB().Begin()
372+
if err != nil {
373+
return sdk.WithStack(err)
396374
}
397375
defer tx.Rollback() // nolint
398376

@@ -429,12 +407,7 @@ func (api *API) putWorkflowHandler() service.Handler {
429407
key := vars["key"]
430408
name := vars["permWorkflowName"]
431409

432-
p, err := project.Load(ctx, api.mustDB(), key,
433-
project.LoadOptions.WithApplicationWithDeploymentStrategies,
434-
project.LoadOptions.WithPipelines,
435-
project.LoadOptions.WithEnvironments,
436-
project.LoadOptions.WithIntegrations,
437-
)
410+
p, err := project.Load(ctx, api.mustDB(), key, project.LoadOptions.WithIntegrations)
438411
if err != nil {
439412
return sdk.WrapError(err, "cannot load Project %s", key)
440413
}

engine/api/workflow/dao_label.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,12 @@ import (
66
"github.com/go-gorp/gorp"
77
"github.com/lib/pq"
88

9-
"github.com/ovh/cds/engine/api/database/gorpmapping"
109
"github.com/ovh/cds/sdk"
11-
"github.com/ovh/cds/sdk/log"
1210
)
1311

1412
// LabelWorkflow link a label on a workflow given his workflow id
1513
func LabelWorkflow(db gorp.SqlExecutor, labelID, workflowID int64) error {
16-
log.Debug("LabelWorkflow> %d %d", labelID, workflowID)
17-
if _, err := db.Exec("INSERT INTO project_label_workflow (label_id, workflow_id) VALUES ($1, $2)", labelID, workflowID); err != nil {
18-
if errPG, ok := err.(*pq.Error); ok && errPG.Code == gorpmapping.ViolateUniqueKeyPGCode {
19-
return sdk.WrapError(sdk.ErrForbidden, "this label %d is already linked to workflow %d", labelID, workflowID)
20-
}
14+
if _, err := db.Exec("INSERT INTO project_label_workflow (label_id, workflow_id) VALUES ($1, $2) ON CONFLICT DO NOTHING", labelID, workflowID); err != nil {
2115
return sdk.WrapError(err, "cannot link label %d to workflow %d", labelID, workflowID)
2216
}
2317
return nil
@@ -40,10 +34,11 @@ type dbLabel struct {
4034
func LoadLabels(db gorp.SqlExecutor, workflowIDs ...int64) ([]sdk.Label, error) {
4135
var labels []dbLabel
4236
query := `
43-
SELECT project_label.*, project_label_workflow.workflow_id
44-
FROM project_label
45-
JOIN project_label_workflow ON project_label.id = project_label_workflow.label_id
46-
WHERE project_label_workflow.workflow_id = ANY($1)`
37+
SELECT project_label.*, project_label_workflow.workflow_id
38+
FROM project_label
39+
JOIN project_label_workflow ON project_label.id = project_label_workflow.label_id
40+
WHERE project_label_workflow.workflow_id = ANY($1)
41+
`
4742

4843
if _, err := db.Select(&labels, query, pq.Int64Array(workflowIDs)); err != nil {
4944
if err == sql.ErrNoRows {

0 commit comments

Comments
 (0)