Skip to content

Commit 00fc29a

Browse files
authored
Refactor issue label selection (#31497)
Follow #26460
1 parent a88f718 commit 00fc29a

File tree

2 files changed

+26
-30
lines changed

2 files changed

+26
-30
lines changed

models/issues/issue_search.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -118,29 +118,29 @@ func applyLabelsCondition(sess *xorm.Session, opts *IssuesOptions) {
118118
if opts.LabelIDs[0] == 0 {
119119
sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_label)")
120120
} else {
121-
// We sort and deduplicate the labels' ids
122-
IncludedLabelIDs := make(container.Set[int64])
123-
ExcludedLabelIDs := make(container.Set[int64])
121+
// deduplicate the label IDs for inclusion and exclusion
122+
includedLabelIDs := make(container.Set[int64])
123+
excludedLabelIDs := make(container.Set[int64])
124124
for _, labelID := range opts.LabelIDs {
125125
if labelID > 0 {
126-
IncludedLabelIDs.Add(labelID)
126+
includedLabelIDs.Add(labelID)
127127
} else if labelID < 0 { // 0 is not supported here, so just ignore it
128-
ExcludedLabelIDs.Add(-labelID)
128+
excludedLabelIDs.Add(-labelID)
129129
}
130130
}
131131
// ... and use them in a subquery of the form :
132132
// where (select count(*) from issue_label where issue_id=issue.id and label_id in (2, 4, 6)) = 3
133133
// This equality is guaranteed thanks to unique index (issue_id,label_id) on table issue_label.
134-
if len(IncludedLabelIDs) > 0 {
135-
subquery := builder.Select("count(*)").From("issue_label").Where(builder.Expr("issue_id = issue.id")).
136-
And(builder.In("label_id", IncludedLabelIDs.Values()))
137-
sess.Where(builder.Eq{strconv.Itoa(len(IncludedLabelIDs)): subquery})
134+
if len(includedLabelIDs) > 0 {
135+
subQuery := builder.Select("count(*)").From("issue_label").Where(builder.Expr("issue_id = issue.id")).
136+
And(builder.In("label_id", includedLabelIDs.Values()))
137+
sess.Where(builder.Eq{strconv.Itoa(len(includedLabelIDs)): subQuery})
138138
}
139139
// or (select count(*)...) = 0 for excluded labels
140-
if len(ExcludedLabelIDs) > 0 {
141-
subquery := builder.Select("count(*)").From("issue_label").Where(builder.Expr("issue_id = issue.id")).
142-
And(builder.In("label_id", ExcludedLabelIDs.Values()))
143-
sess.Where(builder.Eq{"0": subquery})
140+
if len(excludedLabelIDs) > 0 {
141+
subQuery := builder.Select("count(*)").From("issue_label").Where(builder.Expr("issue_id = issue.id")).
142+
And(builder.In("label_id", excludedLabelIDs.Values()))
143+
sess.Where(builder.Eq{"0": subQuery})
144144
}
145145
}
146146
}

models/issues/label.go

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"strings"
1313

1414
"code.gitea.io/gitea/models/db"
15+
"code.gitea.io/gitea/modules/container"
1516
"code.gitea.io/gitea/modules/label"
1617
"code.gitea.io/gitea/modules/optional"
1718
"code.gitea.io/gitea/modules/timeutil"
@@ -143,37 +144,32 @@ func (l *Label) CalOpenOrgIssues(ctx context.Context, repoID, labelID int64) {
143144

144145
// LoadSelectedLabelsAfterClick calculates the set of selected labels when a label is clicked
145146
func (l *Label) LoadSelectedLabelsAfterClick(currentSelectedLabels []int64, currentSelectedExclusiveScopes []string) {
146-
labelQuerySlice := []int64{}
147+
labelQueryParams := container.Set[string]{}
147148
labelSelected := false
148-
labelScope := l.ExclusiveScope()
149-
for i, s := range currentSelectedLabels {
150-
if s == l.ID {
149+
exclusiveScope := l.ExclusiveScope()
150+
for i, curSel := range currentSelectedLabels {
151+
if curSel == l.ID {
151152
labelSelected = true
152-
} else if -s == l.ID {
153+
} else if -curSel == l.ID {
153154
labelSelected = true
154155
l.IsExcluded = true
155-
} else if s != 0 {
156+
} else if curSel != 0 {
156157
// Exclude other labels in the same scope from selection
157-
if s < 0 || labelScope == "" || labelScope != currentSelectedExclusiveScopes[i] {
158-
labelQuerySlice = append(labelQuerySlice, s)
158+
if curSel < 0 || exclusiveScope == "" || exclusiveScope != currentSelectedExclusiveScopes[i] {
159+
labelQueryParams.Add(strconv.FormatInt(curSel, 10))
159160
}
160161
}
161162
}
162163

163164
if !labelSelected {
164-
labelQuerySlice = append(labelQuerySlice, l.ID)
165+
labelQueryParams.Add(strconv.FormatInt(l.ID, 10))
165166
}
166167
l.IsSelected = labelSelected
167168

168169
// Sort and deduplicate the ids to avoid the crawlers asking for the
169170
// same thing with simply a different order of parameters
170-
slices.Sort(labelQuerySlice)
171-
labelQuerySlice = slices.Compact(labelQuerySlice)
172-
// Quick conversion (strings.Join() doesn't accept slices of Int64)
173-
labelQuerySliceStrings := make([]string, len(labelQuerySlice))
174-
for i, x := range labelQuerySlice {
175-
labelQuerySliceStrings[i] = strconv.FormatInt(x, 10)
176-
}
171+
labelQuerySliceStrings := labelQueryParams.Values()
172+
slices.Sort(labelQuerySliceStrings) // the sort is still needed because the underlying map of Set doesn't guarantee order
177173
l.QueryString = strings.Join(labelQuerySliceStrings, ",")
178174
}
179175

@@ -187,7 +183,7 @@ func (l *Label) BelongsToRepo() bool {
187183
return l.RepoID > 0
188184
}
189185

190-
// Return scope substring of label name, or empty string if none exists
186+
// ExclusiveScope returns scope substring of label name, or empty string if none exists
191187
func (l *Label) ExclusiveScope() string {
192188
if !l.Exclusive {
193189
return ""

0 commit comments

Comments
 (0)