2022-09-01 11:45:35 +02:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/leporo/sqlf"
|
|
|
|
)
|
|
|
|
|
|
|
|
// SearchParser returns the SQL syntax for the database search based on the search arguments
|
2022-10-14 06:25:07 +02:00
|
|
|
func searchParser(args []string, start, limit int) *sqlf.Stmt {
|
|
|
|
if limit == 0 {
|
|
|
|
limit = 50
|
|
|
|
}
|
|
|
|
|
2022-09-01 11:45:35 +02:00
|
|
|
q := sqlf.From("mailbox").
|
2023-05-30 06:51:34 +02:00
|
|
|
Select(`Created, ID, MessageID, Subject, Metadata, Size, Attachments, Read, Tags,
|
2023-05-04 11:48:09 +02:00
|
|
|
IFNULL(json_extract(Metadata, '$.To'), '{}') as ToJSON,
|
|
|
|
IFNULL(json_extract(Metadata, '$.From'), '{}') as FromJSON,
|
|
|
|
IFNULL(json_extract(Metadata, '$.Cc'), '{}') as CcJSON,
|
|
|
|
IFNULL(json_extract(Metadata, '$.Bcc'), '{}') as BccJSON
|
2022-09-01 11:45:35 +02:00
|
|
|
`).
|
2023-05-04 11:48:09 +02:00
|
|
|
OrderBy("Created DESC").
|
2022-10-14 06:25:07 +02:00
|
|
|
Limit(limit).
|
|
|
|
Offset(start)
|
|
|
|
|
|
|
|
if limit > 0 {
|
|
|
|
q = q.Limit(limit)
|
|
|
|
}
|
2022-09-01 11:45:35 +02:00
|
|
|
|
|
|
|
for _, w := range args {
|
|
|
|
if cleanString(w) == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
exclude := false
|
|
|
|
// search terms starting with a `-` or `!` imply an exclude
|
|
|
|
if len(w) > 1 && (strings.HasPrefix(w, "-") || strings.HasPrefix(w, "!")) {
|
|
|
|
exclude = true
|
|
|
|
w = w[1:]
|
|
|
|
}
|
|
|
|
|
|
|
|
re := regexp.MustCompile(`[a-zA-Z0-9]+`)
|
|
|
|
if !re.MatchString(w) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if strings.HasPrefix(w, "to:") {
|
|
|
|
w = cleanString(w[3:])
|
|
|
|
if w != "" {
|
|
|
|
if exclude {
|
|
|
|
q.Where("ToJSON NOT LIKE ?", "%"+escPercentChar(w)+"%")
|
|
|
|
} else {
|
|
|
|
q.Where("ToJSON LIKE ?", "%"+escPercentChar(w)+"%")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if strings.HasPrefix(w, "from:") {
|
|
|
|
w = cleanString(w[5:])
|
|
|
|
if w != "" {
|
|
|
|
if exclude {
|
|
|
|
q.Where("FromJSON NOT LIKE ?", "%"+escPercentChar(w)+"%")
|
|
|
|
} else {
|
|
|
|
q.Where("FromJSON LIKE ?", "%"+escPercentChar(w)+"%")
|
|
|
|
}
|
|
|
|
}
|
2023-02-11 11:50:14 +02:00
|
|
|
} else if strings.HasPrefix(w, "cc:") {
|
|
|
|
w = cleanString(w[3:])
|
|
|
|
if w != "" {
|
|
|
|
if exclude {
|
|
|
|
q.Where("CcJSON NOT LIKE ?", "%"+escPercentChar(w)+"%")
|
|
|
|
} else {
|
|
|
|
q.Where("CcJSON LIKE ?", "%"+escPercentChar(w)+"%")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if strings.HasPrefix(w, "bcc:") {
|
|
|
|
w = cleanString(w[4:])
|
|
|
|
if w != "" {
|
|
|
|
if exclude {
|
|
|
|
q.Where("BccJSON NOT LIKE ?", "%"+escPercentChar(w)+"%")
|
|
|
|
} else {
|
|
|
|
q.Where("BccJSON LIKE ?", "%"+escPercentChar(w)+"%")
|
|
|
|
}
|
|
|
|
}
|
2022-09-01 11:45:35 +02:00
|
|
|
} else if strings.HasPrefix(w, "subject:") {
|
|
|
|
w = cleanString(w[8:])
|
|
|
|
if w != "" {
|
|
|
|
if exclude {
|
|
|
|
q.Where("Subject NOT LIKE ?", "%"+escPercentChar(w)+"%")
|
|
|
|
} else {
|
|
|
|
q.Where("Subject LIKE ?", "%"+escPercentChar(w)+"%")
|
|
|
|
}
|
|
|
|
}
|
2023-05-04 11:48:09 +02:00
|
|
|
} else if strings.HasPrefix(w, "message-id:") {
|
|
|
|
w = cleanString(w[11:])
|
|
|
|
if w != "" {
|
|
|
|
if exclude {
|
|
|
|
q.Where("MessageID NOT LIKE ?", "%"+escPercentChar(w)+"%")
|
|
|
|
} else {
|
|
|
|
q.Where("MessageID LIKE ?", "%"+escPercentChar(w)+"%")
|
|
|
|
}
|
|
|
|
}
|
2022-11-13 05:45:54 +02:00
|
|
|
} else if strings.HasPrefix(w, "tag:") {
|
|
|
|
w = cleanString(w[4:])
|
|
|
|
if w != "" {
|
|
|
|
if exclude {
|
|
|
|
q.Where("Tags NOT LIKE ?", "%\""+escPercentChar(w)+"\"%")
|
|
|
|
} else {
|
|
|
|
q.Where("Tags LIKE ?", "%\""+escPercentChar(w)+"\"%")
|
|
|
|
}
|
|
|
|
}
|
2022-09-01 11:45:35 +02:00
|
|
|
} else if w == "is:read" {
|
|
|
|
if exclude {
|
|
|
|
q.Where("Read = 0")
|
|
|
|
} else {
|
|
|
|
q.Where("Read = 1")
|
|
|
|
}
|
|
|
|
} else if w == "is:unread" {
|
|
|
|
if exclude {
|
|
|
|
q.Where("Read = 1")
|
|
|
|
} else {
|
|
|
|
q.Where("Read = 0")
|
|
|
|
}
|
|
|
|
} else if w == "has:attachment" || w == "has:attachments" {
|
|
|
|
if exclude {
|
|
|
|
q.Where("Attachments = 0")
|
|
|
|
} else {
|
|
|
|
q.Where("Attachments > 0")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// search text
|
|
|
|
if exclude {
|
2023-05-04 11:48:09 +02:00
|
|
|
q.Where("SearchText NOT LIKE ?", "%"+cleanString(escPercentChar(w))+"%")
|
2022-09-01 11:45:35 +02:00
|
|
|
} else {
|
2023-05-04 11:48:09 +02:00
|
|
|
q.Where("SearchText LIKE ?", "%"+cleanString(escPercentChar(w))+"%")
|
2022-09-01 11:45:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return q
|
|
|
|
}
|