@@ -43,7 +43,9 @@ func (err ErrMilestoneNotExist) Error() string {
43
43
type Milestone struct {
44
44
ID int64 `xorm:"pk autoincr"`
45
45
RepoID int64 `xorm:"INDEX"`
46
+ OwnerID int64 `xorm:"INDEX"`
46
47
Repo * repo_model.Repository `xorm:"-"`
48
+ Labels []* Label `xorm:"-"`
47
49
Name string
48
50
Content string `xorm:"TEXT"`
49
51
RenderedContent string `xorm:"-"`
@@ -118,6 +120,28 @@ func NewMilestone(m *Milestone) (err error) {
118
120
return err
119
121
}
120
122
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
+
121
145
if _ , err = db .Exec (ctx , "UPDATE `repository` SET num_milestones = num_milestones + 1 WHERE id = ?" , m .RepoID ); err != nil {
122
146
return err
123
147
}
@@ -138,20 +162,44 @@ func GetMilestoneByRepoID(ctx context.Context, repoID, id int64) (*Milestone, er
138
162
} else if ! has {
139
163
return nil , ErrMilestoneNotExist {ID : id , RepoID : repoID }
140
164
}
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
+ }
141
177
return m , nil
142
178
}
143
179
144
180
// GetMilestoneByRepoIDANDName return a milestone if one exist by name and repo
145
181
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 )
148
184
if err != nil {
149
185
return nil , err
150
186
}
151
187
if ! has {
152
188
return nil , ErrMilestoneNotExist {Name : name , RepoID : repoID }
153
189
}
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
155
203
}
156
204
157
205
// UpdateMilestone updates information of given milestone.
@@ -177,6 +225,42 @@ func UpdateMilestone(m *Milestone, oldIsClosed bool) error {
177
225
}
178
226
}
179
227
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
+
180
264
return committer .Commit ()
181
265
}
182
266
@@ -270,7 +354,7 @@ func changeMilestoneStatus(ctx context.Context, m *Milestone, isClosed bool) err
270
354
return updateRepoMilestoneNum (ctx , m .RepoID )
271
355
}
272
356
273
- // DeleteMilestoneByRepoID deletes a milestone from a repository.
357
+ // DeleteMilestoneByRepoID deletes a milestone and associated labels from a repository.
274
358
func DeleteMilestoneByRepoID (repoID , id int64 ) error {
275
359
m , err := GetMilestoneByRepoID (db .DefaultContext , repoID , id )
276
360
if err != nil {
@@ -321,6 +405,12 @@ func DeleteMilestoneByRepoID(repoID, id int64) error {
321
405
if _ , err = db .Exec (ctx , "UPDATE `issue` SET milestone_id = 0 WHERE milestone_id = ?" , m .ID ); err != nil {
322
406
return err
323
407
}
408
+
409
+ for _ , label := range m .Labels {
410
+ if err = deleteMilestoneLabel (ctx , m , label , nil ); err != nil {
411
+ return err
412
+ }
413
+ }
324
414
return committer .Commit ()
325
415
}
326
416
@@ -394,6 +484,13 @@ func GetMilestones(opts GetMilestonesOption) (MilestoneList, int64, error) {
394
484
395
485
miles := make ([]* Milestone , 0 , opts .PageSize )
396
486
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
+
397
494
return miles , total , err
398
495
}
399
496
0 commit comments