Browse Source

item filter will match project/requirement tags.

master
Gisle Aune 1 year ago
parent
commit
14f3f7dc49
  1. 96
      ports/mysql/items.go

96
ports/mysql/items.go

@ -65,51 +65,6 @@ func (r *itemRepository) Fetch(ctx context.Context, filter models.ItemFilter) ([
return []entities.Item{}, nil
}
// For tags, use the ID filter to avoid making too much of a messy query below.
if filter.Tags != nil {
query, args, err := squirrel.Select("object_id, tag_name").
From("tag").
Where(squirrel.Eq{"tag_name": filter.Tags, "object_kind": tagObjectKindItem}).
ToSql()
if err != nil {
return nil, err
}
rows, err := r.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, err
}
ids := make([]int, 0, 16)
matches := make(map[int]int, 64)
for rows.Next() {
var objectID int
var tagName string
err := rows.Scan(&objectID, &tagName)
if err != nil {
return nil, err
}
if matches[objectID] == 0 {
ids = append(ids, objectID)
}
matches[objectID] += 1
}
err = rows.Close()
if err != nil {
return nil, err
}
if filter.IDs == nil {
filter.IDs = ids
}
filter.IDs = genutils.RetainInPlace(filter.IDs, func(id int) bool {
return matches[id] == len(filter.Tags)
})
if len(filter.IDs) == 0 {
return []entities.Item{}, nil
}
}
sq := squirrel.Select(
"i.id, i.scope_id, i.project_requirement_id, pr.project_id, i.owner_id, i.name," +
" i.description, i.created_time, i.acquired_time, i.scheduled_date",
@ -181,6 +136,10 @@ func (r *itemRepository) Fetch(ctx context.Context, filter models.ItemFilter) ([
seen := make(map[int]bool, 32)
res := make([]entities.Item, 0, 32)
ids := genutils.Set[int]{}
projectIDs := genutils.Set[int]{}
requirementIDs := genutils.Set[int]{}
for rows.Next() {
item := entities.Item{}
@ -218,14 +177,16 @@ func (r *itemRepository) Fetch(ctx context.Context, filter models.ItemFilter) ([
item.ScheduledDate = scheduledDate.AsPtr()
item.Tags = []string{}
ids.Add(item.ID)
if item.ProjectID != nil {
projectIDs.Add(*item.ProjectID)
requirementIDs.Add(*item.RequirementID)
}
res = append(res, item)
}
// Fill tags
ids := genutils.Map(res, func(i entities.Item) int {
return i.ID
})
err = fetchTags(ctx, r.db, tagObjectKindItem, ids, func(id int, tag string) {
err = fetchTags(ctx, r.db, tagObjectKindItem, ids.Values(), func(id int, tag string) {
for i := range res {
if id == res[i].ID {
res[i].Tags = append(res[i].Tags, tag)
@ -236,6 +197,41 @@ func (r *itemRepository) Fetch(ctx context.Context, filter models.ItemFilter) ([
return nil, err
}
if len(filter.Tags) > 0 {
projectTagMap := make(map[int][]string, 64)
err = fetchTags(ctx, r.db, tagObjectKindProject, projectIDs.Values(), func(id int, tag string) {
projectTagMap[id] = append(projectTagMap[id], tag)
})
if err != nil {
return nil, err
}
requirementTagMap := make(map[int][]string, 64)
err = fetchTags(ctx, r.db, tagObjectKindRequirement, requirementIDs.Values(), func(id int, tag string) {
requirementTagMap[id] = append(requirementTagMap[id], tag)
})
if err != nil {
return nil, err
}
res = genutils.RetainInPlace(res, func(item entities.Item) bool {
for _, tag := range filter.Tags {
if !item.HasTag(tag) {
if item.RequirementID != nil {
if !genutils.Contains(requirementTagMap[*item.RequirementID], tag) &&
!genutils.Contains(projectTagMap[*item.ProjectID], tag) {
return false
}
} else {
return false
}
}
}
return true
})
}
sort.Slice(res, func(i, j int) bool {
// Acquired time, descending
ati, atj := res[i].AcquiredTime, res[j].AcquiredTime

Loading…
Cancel
Save