Add types.Mail

This commit is contained in:
Neil Alexander
2021-07-09 22:25:10 +01:00
parent d290ec1c22
commit a0c2c595f0
4 changed files with 49 additions and 30 deletions

View File

@@ -11,6 +11,7 @@ import (
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/backend/backendutil"
"github.com/emersion/go-message/textproto"
"github.com/neilalexander/yggmail/internal/storage/types"
)
type Mailbox struct {
@@ -115,17 +116,17 @@ func (mbox *Mailbox) ListMessages(uid bool, seqSet *imap.SeqSet, items []imap.Fe
}
for _, id := range ids {
mseq, mid, body, seen, answered, flagged, deleted, datetime, err := mbox.backend.Storage.MailSelect(mbox.name, int(id))
mseq, mail, err := mbox.backend.Storage.MailSelect(mbox.name, int(id))
if err != nil {
continue
}
fetched := imap.NewMessage(uint32(id), items)
fetched.SeqNum = uint32(mseq)
fetched.Uid = uint32(mid)
fetched.Uid = uint32(mail.ID)
get := func() (io.Reader, textproto.Header, error) {
bodyreader := bufio.NewReader(bytes.NewReader(body))
bodyreader := bufio.NewReader(bytes.NewReader(mail.Mail))
hdr, err := textproto.ReadHeader(bodyreader)
if err != nil {
return nil, textproto.Header{}, fmt.Errorf("textproto.ReadHeader: %w", err)
@@ -155,24 +156,24 @@ func (mbox *Mailbox) ListMessages(uid bool, seqSet *imap.SeqSet, items []imap.Fe
case imap.FetchFlags:
fetched.Flags = []string{}
if seen {
if mail.Seen {
fetched.Flags = append(fetched.Flags, "\\Seen")
}
if answered {
if mail.Answered {
fetched.Flags = append(fetched.Flags, "\\Answered")
}
if flagged {
if mail.Flagged {
fetched.Flags = append(fetched.Flags, "\\Flagged")
}
if deleted {
if mail.Deleted {
fetched.Flags = append(fetched.Flags, "\\Deleted")
}
case imap.FetchInternalDate:
fetched.InternalDate = datetime
fetched.InternalDate = mail.Date
case imap.FetchRFC822Size:
fetched.Size = uint32(len(body))
fetched.Size = uint32(len(mail.Mail))
case imap.FetchUid:
fetched.Uid = uint32(id)
@@ -241,11 +242,10 @@ func (mbox *Mailbox) UpdateMessagesFlags(uid bool, seqSet *imap.SeqSet, op imap.
}
for _, id := range ids {
var seen, answered, flagged, deleted bool
var mid int
var mail *types.Mail
if op != imap.SetFlags {
var err error
_, mid, _, seen, answered, flagged, deleted, _, err = mbox.backend.Storage.MailSelect(mbox.name, int(id))
_, mail, err = mbox.backend.Storage.MailSelect(mbox.name, int(id))
if err != nil {
return fmt.Errorf("mbox.backend.Storage.MailSelect: %w", err)
}
@@ -253,18 +253,19 @@ func (mbox *Mailbox) UpdateMessagesFlags(uid bool, seqSet *imap.SeqSet, op imap.
for _, flag := range flags {
switch flag {
case "\\Seen":
seen = op != imap.RemoveFlags
mail.Seen = op != imap.RemoveFlags
case "\\Answered":
answered = op != imap.RemoveFlags
mail.Answered = op != imap.RemoveFlags
case "\\Flagged":
flagged = op != imap.RemoveFlags
mail.Flagged = op != imap.RemoveFlags
case "\\Deleted":
deleted = op != imap.RemoveFlags
mail.Deleted = op != imap.RemoveFlags
}
}
if err := mbox.backend.Storage.MailUpdateFlags(
mbox.name, int(mid), seen, answered, flagged, deleted,
mbox.name, int(mail.ID), mail.Seen,
mail.Answered, mail.Flagged, mail.Deleted,
); err != nil {
return err
}
@@ -283,15 +284,17 @@ func (mbox *Mailbox) CopyMessages(uid bool, seqSet *imap.SeqSet, destName string
}
for _, id := range ids {
_, _, body, seen, answered, flagged, deleted, _, err := mbox.backend.Storage.MailSelect(mbox.name, int(id))
_, mail, err := mbox.backend.Storage.MailSelect(mbox.name, int(id))
if err != nil {
return fmt.Errorf("mbox.backend.Storage.MailSelect: %w", err)
}
pid, err := mbox.backend.Storage.MailCreate(destName, body)
pid, err := mbox.backend.Storage.MailCreate(destName, mail.Mail)
if err != nil {
return fmt.Errorf("mbox.backend.Storage.MailCreate: %w", err)
}
if err = mbox.backend.Storage.MailUpdateFlags(mbox.name, pid, seen, answered, flagged, deleted); err != nil {
if err = mbox.backend.Storage.MailUpdateFlags(
mbox.name, pid, mail.Seen, mail.Answered, mail.Flagged, mail.Deleted,
); err != nil {
return fmt.Errorf("mbox.backend.Storage.MailUpdateFlags: %w", err)
}
}

View File

@@ -4,6 +4,8 @@ import (
"database/sql"
"fmt"
"time"
"github.com/neilalexander/yggmail/internal/storage/types"
)
type TableMails struct {
@@ -35,7 +37,6 @@ const mailsSchema = `
FOREIGN KEY (mailbox) REFERENCES mailboxes(mailbox) ON DELETE CASCADE ON UPDATE CASCADE
);
DROP VIEW IF EXISTS inboxes;
CREATE VIEW IF NOT EXISTS inboxes AS SELECT * FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY mailbox) AS seq, * FROM mails
)
@@ -160,13 +161,14 @@ func (t *TableMails) MailCreate(mailbox string, data []byte) (int, error) {
return id, err
}
func (t *TableMails) MailSelect(mailbox string, id int) (int, int, []byte, bool, bool, bool, bool, time.Time, error) {
var data []byte
var seen, answered, flagged, deleted bool
var ts int64
var seq, pid int
err := t.selectMail.QueryRow(mailbox, id).Scan(&seq, &pid, &data, &ts, &seen, &answered, &flagged, &deleted)
return seq, pid, data, seen, answered, flagged, deleted, time.Unix(ts, 0), err
func (t *TableMails) MailSelect(mailbox string, id int) (int, *types.Mail, error) {
var seq int
mail := &types.Mail{}
err := t.selectMail.QueryRow(mailbox, id).Scan(
&seq, &mail.ID, &mail.Mail, &mail.Date,
&mail.Seen, &mail.Answered, &mail.Flagged, &mail.Deleted,
)
return seq, mail, err
}
func (t *TableMails) MailSearch(mailbox string) ([]uint32, error) {

View File

@@ -1,6 +1,6 @@
package storage
import "time"
import "github.com/neilalexander/yggmail/internal/storage/types"
type Storage interface {
ConfigGet(key string) (string, error)
@@ -19,7 +19,7 @@ type Storage interface {
MailboxSubscribe(name string, subscribed bool) error
MailCreate(mailbox string, data []byte) (int, error)
MailSelect(mailbox string, id int) (int, int, []byte, bool, bool, bool, bool, time.Time, error)
MailSelect(mailbox string, id int) (int, *types.Mail, error)
MailSearch(mailbox string) ([]uint32, error)
MailUpdateFlags(mailbox string, id int, seen, answered, flagged, deleted bool) error
MailDelete(mailbox, id string) error

View File

@@ -0,0 +1,14 @@
package types
import "time"
type Mail struct {
Mailbox string
ID int
Mail []byte
Date time.Time
Seen bool
Answered bool
Flagged bool
Deleted bool
}