Add optional zstd mbox archives

This commit is contained in:
DonVoo 2026-07-14 20:20:30 +02:00
parent 21844688ac
commit e612896e06
14 changed files with 620 additions and 39 deletions

View file

@ -118,6 +118,20 @@ func ConnectDB(initDB bool) error {
copied_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE(account_id, folder, message_id)
)`,
`CREATE TABLE IF NOT EXISTS mbox_index(
account_id INTEGER NOT NULL,
folder TEXT NOT NULL,
seq INTEGER NOT NULL,
message_id TEXT NOT NULL,
subject TEXT NOT NULL DEFAULT '',
from_addr TEXT NOT NULL DEFAULT '',
date TEXT NOT NULL DEFAULT '',
file_offset INTEGER NOT NULL,
frame_len INTEGER NOT NULL,
inner_offset INTEGER NOT NULL DEFAULT 0,
inner_len INTEGER NOT NULL,
UNIQUE(account_id, folder, message_id)
)`,
`CREATE TABLE IF NOT EXISTS jobs(
id INTEGER PRIMARY KEY AUTOINCREMENT,
account_id INTEGER NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
@ -500,6 +514,68 @@ func MarkCopied(accountID int64, folder, messageID string) error {
return err
}
type MboxIndexEntry struct {
AccountID int64
Folder string
Seq int
MessageID string
Subject string
From string
Date string
FileOffset int64
FrameLen int64
InnerOffset int64
InnerLen int64
}
func SaveMboxIndex(e MboxIndexEntry) error {
if DB == nil || e.MessageID == "" {
return nil
}
var seq int
if e.Seq > 0 {
seq = e.Seq
} else {
_ = DB.QueryRow(`SELECT COALESCE(MAX(seq), -1) + 1 FROM mbox_index WHERE account_id=? AND folder=?`, e.AccountID, e.Folder).Scan(&seq)
}
_, err := DB.Exec(`INSERT OR IGNORE INTO mbox_index(account_id, folder, seq, message_id, subject, from_addr, date, file_offset, frame_len, inner_offset, inner_len)
VALUES(?,?,?,?,?,?,?,?,?,?,?)`,
e.AccountID, e.Folder, seq, e.MessageID, e.Subject, e.From, e.Date, e.FileOffset, e.FrameLen, e.InnerOffset, e.InnerLen)
return err
}
func ListMboxIndex(accountID int64, folder string) ([]MboxIndexEntry, error) {
if DB == nil || accountID == 0 {
return nil, sql.ErrNoRows
}
rows, err := DB.Query(`SELECT account_id, folder, seq, message_id, subject, from_addr, date, file_offset, frame_len, inner_offset, inner_len
FROM mbox_index WHERE account_id=? AND folder=? ORDER BY seq`, accountID, folder)
if err != nil {
return nil, err
}
defer rows.Close()
var out []MboxIndexEntry
for rows.Next() {
var e MboxIndexEntry
if err := rows.Scan(&e.AccountID, &e.Folder, &e.Seq, &e.MessageID, &e.Subject, &e.From, &e.Date, &e.FileOffset, &e.FrameLen, &e.InnerOffset, &e.InnerLen); err != nil {
return nil, err
}
out = append(out, e)
}
return out, rows.Err()
}
func GetMboxIndex(accountID int64, folder string, seq int) (MboxIndexEntry, error) {
if DB == nil || accountID == 0 {
return MboxIndexEntry{}, sql.ErrNoRows
}
row := DB.QueryRow(`SELECT account_id, folder, seq, message_id, subject, from_addr, date, file_offset, frame_len, inner_offset, inner_len
FROM mbox_index WHERE account_id=? AND folder=? AND seq=?`, accountID, folder, seq)
var e MboxIndexEntry
err := row.Scan(&e.AccountID, &e.Folder, &e.Seq, &e.MessageID, &e.Subject, &e.From, &e.Date, &e.FileOffset, &e.FrameLen, &e.InnerOffset, &e.InnerLen)
return e, err
}
func SeedAccountFromFile(path string) error {
b, err := os.ReadFile(path)
if err != nil {