mirror of
https://github.com/axllent/mailpit.git
synced 2026-06-27 22:46:09 +00:00
Chore: Optimize tag retrieval by batching message IDs in List and Search functions
This commit is contained in:
@@ -278,8 +278,19 @@ func List(start int, beforeTS int64, limit int) ([]MessageSummary, error) {
|
||||
}
|
||||
|
||||
// set tags for listed messages only
|
||||
for i, m := range results {
|
||||
results[i].Tags = getMessageTags(m.ID)
|
||||
if len(results) > 0 {
|
||||
ids := make([]string, len(results))
|
||||
for i, m := range results {
|
||||
ids[i] = m.ID
|
||||
}
|
||||
tagMap := getTagsForIDs(ids)
|
||||
for i, m := range results {
|
||||
if tags, ok := tagMap[m.ID]; ok {
|
||||
results[i].Tags = tags
|
||||
} else {
|
||||
results[i].Tags = []string{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbLastAction = time.Now()
|
||||
|
||||
@@ -86,8 +86,19 @@ func Search(search, timezone string, start int, beforeTS int64, limit int) ([]Me
|
||||
}
|
||||
|
||||
// set tags for listed messages only
|
||||
for i, m := range results {
|
||||
results[i].Tags = getMessageTags(m.ID)
|
||||
if len(results) > 0 {
|
||||
ids := make([]string, len(results))
|
||||
for i, m := range results {
|
||||
ids[i] = m.ID
|
||||
}
|
||||
tagMap := getTagsForIDs(ids)
|
||||
for i, m := range results {
|
||||
if tags, ok := tagMap[m.ID]; ok {
|
||||
results[i].Tags = tags
|
||||
} else {
|
||||
results[i].Tags = []string{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elapsed := time.Since(tsStart)
|
||||
|
||||
@@ -340,6 +340,43 @@ func (d Metadata) tagsFromPlusAddresses() []string {
|
||||
return tools.SetTagCasing(tags)
|
||||
}
|
||||
|
||||
// getTagsForIDs fetches tags for a set of message IDs in a single query,
|
||||
// returning a map of message ID to tag names.
|
||||
func getTagsForIDs(ids []string) map[string][]string {
|
||||
result := make(map[string][]string, len(ids))
|
||||
if len(ids) == 0 {
|
||||
return result
|
||||
}
|
||||
|
||||
args := make([]any, len(ids))
|
||||
for i, id := range ids {
|
||||
args[i] = id
|
||||
}
|
||||
|
||||
query := fmt.Sprintf(
|
||||
`SELECT mt.ID, t.Name FROM %s t JOIN %s mt ON t.ID = mt.TagID WHERE mt.ID IN (?%s) ORDER BY mt.ID, t.Name`,
|
||||
tenant("Tags"), tenant("message_tags"), strings.Repeat(",?", len(ids)-1),
|
||||
) // #nosec
|
||||
|
||||
rows, err := db.Query(query, args...)
|
||||
if err != nil {
|
||||
logger.Log().Errorf("[tags] %s", err.Error())
|
||||
return result
|
||||
}
|
||||
defer func() { _ = rows.Close() }()
|
||||
|
||||
for rows.Next() {
|
||||
var id, name string
|
||||
if err := rows.Scan(&id, &name); err != nil {
|
||||
logger.Log().Errorf("[tags] %s", err.Error())
|
||||
return result
|
||||
}
|
||||
result[id] = append(result[id], name)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Get message tags from the database for a given database ID
|
||||
// Used when parsing a raw email.
|
||||
func getMessageTags(id string) []string {
|
||||
|
||||
Reference in New Issue
Block a user