Stream source mailbox migration

This commit is contained in:
DonVoo 2026-07-14 17:56:33 +02:00
parent f5f0ff1b8c
commit a52963c380
4 changed files with 179 additions and 33 deletions

View file

@ -36,8 +36,8 @@ type Folder struct {
// SourceMailbox abstrahiert Quelle (IMAP primaer, POP3 Fallback), damit
// 07-migrate.go gegen ein Interface arbeitet.
type SourceMailbox interface {
Folders() ([]Folder, error) // rekursiver Ordnerbaum
Fetch(folder string) ([]RawMessage, error) // BODY[] FLAGS INTERNALDATE
Folders() ([]Folder, error) // rekursiver Ordnerbaum
Fetch(folder string, fn func(RawMessage) error) error // BODY[] FLAGS INTERNALDATE
Close() error
}
@ -75,8 +75,8 @@ func (s *imapSource) Folders() ([]Folder, error) {
return folders, nil
}
func (s *imapSource) Fetch(folder string) ([]RawMessage, error) {
return s.mailbox.fetchAll(folder)
func (s *imapSource) Fetch(folder string, fn func(RawMessage) error) error {
return s.mailbox.fetchEach(folder, fn)
}
func (s *imapSource) Close() error {
@ -136,13 +136,13 @@ func (m *imapClientMailbox) listMailboxes() ([]imapListMailbox, error) {
return out, nil
}
func (m *imapClientMailbox) fetchAll(folder string) ([]RawMessage, error) {
func (m *imapClientMailbox) fetchEach(folder string, fn func(RawMessage) error) error {
selected, err := m.c.Select(folder, &imap.SelectOptions{ReadOnly: true}).Wait()
if err != nil {
return nil, err
return err
}
if selected.NumMessages == 0 {
return nil, nil
return nil
}
section := &imap.FetchItemBodySection{Peek: true}
@ -154,9 +154,7 @@ func (m *imapClientMailbox) fetchAll(folder string) ([]RawMessage, error) {
InternalDate: true,
BodySection: []*imap.FetchItemBodySection{section},
})
defer cmd.Close()
var out []RawMessage
for {
data := cmd.Next()
if data == nil {
@ -164,20 +162,33 @@ func (m *imapClientMailbox) fetchAll(folder string) ([]RawMessage, error) {
}
buf, err := data.Collect()
if err != nil {
return out, err
_ = cmd.Close()
return err
}
body := buf.FindBodySection(section)
if body == nil {
body = []byte{}
}
out = append(out, RawMessage{
if err := fn(RawMessage{
MessageID: messageIDFromFetch(buf, body),
Body: body,
Flags: flagsToStrings(sanitizeIMAPFlags(buf.Flags)),
InternalDate: buf.InternalDate,
})
}); err != nil {
_ = cmd.Close()
return err
}
}
if err := cmd.Close(); err != nil {
return cmd.Close()
}
func (m *imapClientMailbox) fetchAll(folder string) ([]RawMessage, error) {
var out []RawMessage
err := m.fetchEach(folder, func(m RawMessage) error {
out = append(out, m)
return nil
})
if err != nil {
return out, err
}
return out, nil