Skip to content

Commit 2285197

Browse files
committed
add milestone labels
1 parent 7690de5 commit 2285197

File tree

17 files changed

+1249
-6
lines changed

17 files changed

+1249
-6
lines changed

models/issues/label.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ type Label struct {
8282
Color string `xorm:"VARCHAR(7)"`
8383
NumIssues int
8484
NumClosedIssues int
85+
NumMilestones int
8586
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
8687
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
8788

@@ -556,6 +557,13 @@ func updateLabelCols(ctx context.Context, l *Label, cols ...string) error {
556557
"issue.is_closed": true,
557558
}),
558559
).
560+
SetExpr("num_milestones",
561+
builder.Select("count(*)").From("milestone_label").
562+
InnerJoin("milestone", "milestone_label.milestone_id = milestone.id").
563+
Where(builder.Eq{
564+
"milestone_label.milestone_id": l.ID,
565+
}),
566+
).
559567
Cols(cols...).Update(l)
560568
return err
561569
}

models/issues/milestone.go

Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ func (err ErrMilestoneNotExist) Error() string {
4343
type Milestone struct {
4444
ID int64 `xorm:"pk autoincr"`
4545
RepoID int64 `xorm:"INDEX"`
46+
OwnerID int64 `xorm:"INDEX"`
4647
Repo *repo_model.Repository `xorm:"-"`
48+
Labels []*Label `xorm:"-"`
4749
Name string
4850
Content string `xorm:"TEXT"`
4951
RenderedContent string `xorm:"-"`
@@ -118,6 +120,28 @@ func NewMilestone(m *Milestone) (err error) {
118120
return err
119121
}
120122

123+
sess := db.GetEngine(db.DefaultContext)
124+
125+
if len(m.Labels) > 0 {
126+
// During the session, SQLite3 driver cannot handle retrieve objects after update something.
127+
// So we have to get all needed labels first.
128+
labels := m.Labels
129+
if err = sess.Find(&m.Labels); err != nil {
130+
return fmt.Errorf("find all labels [label_ids: %v]: %v", m.Labels, err)
131+
}
132+
133+
for _, label := range labels {
134+
// Silently drop invalid labels.
135+
if label.RepoID != m.RepoID && label.OrgID != m.OwnerID {
136+
continue
137+
}
138+
139+
if err = m.addLabel(ctx, label, nil); err != nil {
140+
return fmt.Errorf("addLabel [id: %d]: %v", label.ID, err)
141+
}
142+
}
143+
}
144+
121145
if _, err = db.Exec(ctx, "UPDATE `repository` SET num_milestones = num_milestones + 1 WHERE id = ?", m.RepoID); err != nil {
122146
return err
123147
}
@@ -138,20 +162,44 @@ func GetMilestoneByRepoID(ctx context.Context, repoID, id int64) (*Milestone, er
138162
} else if !has {
139163
return nil, ErrMilestoneNotExist{ID: id, RepoID: repoID}
140164
}
165+
var labels []*Label
166+
labels, err = GetLabelsByMilestoneID(m.ID)
167+
m.Labels = labels
168+
if err != nil {
169+
return nil, err
170+
}
171+
if m.Repo == nil {
172+
m.Repo, err = repo_model.GetRepositoryByID(repoID)
173+
if err != nil {
174+
return nil, err
175+
}
176+
}
141177
return m, nil
142178
}
143179

144180
// GetMilestoneByRepoIDANDName return a milestone if one exist by name and repo
145181
func GetMilestoneByRepoIDANDName(repoID int64, name string) (*Milestone, error) {
146-
var mile Milestone
147-
has, err := db.GetEngine(db.DefaultContext).Where("repo_id=? AND name=?", repoID, name).Get(&mile)
182+
var m Milestone
183+
has, err := db.GetEngine(db.DefaultContext).Where("repo_id=? AND name=?", repoID, name).Get(&m)
148184
if err != nil {
149185
return nil, err
150186
}
151187
if !has {
152188
return nil, ErrMilestoneNotExist{Name: name, RepoID: repoID}
153189
}
154-
return &mile, nil
190+
var labels []*Label
191+
labels, err = GetLabelsByMilestoneID(m.ID)
192+
m.Labels = labels
193+
if err != nil {
194+
return nil, err
195+
}
196+
if m.Repo == nil {
197+
m.Repo, err = repo_model.GetRepositoryByID(repoID)
198+
if err != nil {
199+
return nil, err
200+
}
201+
}
202+
return &m, nil
155203
}
156204

157205
// UpdateMilestone updates information of given milestone.
@@ -177,6 +225,42 @@ func UpdateMilestone(m *Milestone, oldIsClosed bool) error {
177225
}
178226
}
179227

228+
var dbLabels []*Label
229+
dbLabels, err = GetLabelsByMilestoneID(m.ID)
230+
if err != nil {
231+
return err
232+
}
233+
// delete from db missing labels associated with repo and milestone
234+
for _, dbLabel := range dbLabels {
235+
labelOnMilestone := false
236+
for _, msLabel := range m.Labels {
237+
if msLabel.ID == dbLabel.ID {
238+
labelOnMilestone = true
239+
break
240+
}
241+
}
242+
if labelOnMilestone == false {
243+
if err = deleteMilestoneLabel(ctx, m, dbLabel, nil); err != nil {
244+
return fmt.Errorf("deleteMilestoneLabel [id: %d]: %v", dbLabel.ID, err)
245+
}
246+
}
247+
}
248+
// add to db new labels associated with repo and milestone
249+
for _, msLabel := range m.Labels {
250+
labelInDatabase := false
251+
for _, dbLabel := range dbLabels {
252+
if msLabel.ID == dbLabel.ID {
253+
labelInDatabase = true
254+
break
255+
}
256+
}
257+
if labelInDatabase == false {
258+
if err = m.addLabel(ctx, msLabel, nil); err != nil {
259+
return fmt.Errorf("addLabel [id: %d]: %v", msLabel.ID, err)
260+
}
261+
}
262+
}
263+
180264
return committer.Commit()
181265
}
182266

@@ -270,7 +354,7 @@ func changeMilestoneStatus(ctx context.Context, m *Milestone, isClosed bool) err
270354
return updateRepoMilestoneNum(ctx, m.RepoID)
271355
}
272356

273-
// DeleteMilestoneByRepoID deletes a milestone from a repository.
357+
// DeleteMilestoneByRepoID deletes a milestone and associated labels from a repository.
274358
func DeleteMilestoneByRepoID(repoID, id int64) error {
275359
m, err := GetMilestoneByRepoID(db.DefaultContext, repoID, id)
276360
if err != nil {
@@ -321,6 +405,12 @@ func DeleteMilestoneByRepoID(repoID, id int64) error {
321405
if _, err = db.Exec(ctx, "UPDATE `issue` SET milestone_id = 0 WHERE milestone_id = ?", m.ID); err != nil {
322406
return err
323407
}
408+
409+
for _, label := range m.Labels {
410+
if err = deleteMilestoneLabel(ctx, m, label, nil); err != nil {
411+
return err
412+
}
413+
}
324414
return committer.Commit()
325415
}
326416

@@ -394,6 +484,13 @@ func GetMilestones(opts GetMilestonesOption) (MilestoneList, int64, error) {
394484

395485
miles := make([]*Milestone, 0, opts.PageSize)
396486
total, err := sess.FindAndCount(&miles)
487+
488+
for _, m := range miles {
489+
var labels []*Label
490+
labels, err = GetLabelsByMilestoneID(m.ID)
491+
m.Labels = labels
492+
}
493+
397494
return miles, total, err
398495
}
399496

0 commit comments

Comments
 (0)