File: updates_mailbox.go

package info (click to toggle)
golang-github-protonmail-gluon 0.17.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 16,020 kB
  • sloc: sh: 55; makefile: 5
file content (117 lines) | stat: -rw-r--r-- 3,486 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package state

import (
	"context"

	"github.com/ProtonMail/gluon/db"
	"github.com/ProtonMail/gluon/imap"
	"github.com/ProtonMail/gluon/limits"
	"github.com/bradenaw/juniper/xslices"
)

// Shared code for state and connector updates related to mailbox message operations

// MoveMessagesFromMailbox moves messages from one mailbox to the other.
func MoveMessagesFromMailbox(
	ctx context.Context,
	tx db.Transaction,
	mboxFromID, mboxToID imap.InternalMailboxID,
	messageIDPairs []db.MessageIDPair,
	messageIDsInternal []imap.InternalMessageID,
	s *State,
	imapLimits limits.IMAP,
	removeOldMessages bool,
) ([]db.UIDWithFlags, []Update, error) {
	messageCount, uid, err := tx.GetMailboxMessageCountAndUID(ctx, mboxToID)
	if err != nil {
		return nil, nil, err
	}

	if err := imapLimits.CheckMailBoxMessageCount(messageCount, len(messageIDPairs)); err != nil {
		return nil, nil, err
	}

	if err := imapLimits.CheckUIDCount(uid, len(messageIDPairs)); err != nil {
		return nil, nil, err
	}

	if mboxFromID != mboxToID && removeOldMessages {
		if err := tx.RemoveMessagesFromMailbox(ctx, mboxFromID, messageIDsInternal); err != nil {
			return nil, nil, err
		}
	}

	messageUIDs, err := tx.AddMessagesToMailbox(ctx, mboxToID, messageIDPairs)
	if err != nil {
		return nil, nil, err
	}

	stateUpdates := make([]Update, 0, len(messageIDPairs)+1)
	{
		responders := xslices.Map(messageUIDs, func(uid db.UIDWithFlags) *exists {
			return newExists(db.MessageIDPair{
				InternalID: uid.InternalID,
				RemoteID:   uid.RemoteID,
			}, uid.UID, uid.GetFlagSet())
		})
		stateUpdates = append(stateUpdates, newExistsStateUpdateWithExists(mboxToID, responders, s))
	}

	if removeOldMessages {
		for _, messageID := range messageIDsInternal {
			stateUpdates = append(stateUpdates, NewMessageIDAndMailboxIDResponderStateUpdate(messageID, mboxFromID, NewExpunge(messageID)))
		}
	}

	return messageUIDs, stateUpdates, nil
}

// AddMessagesToMailbox adds the messages to the given mailbox.
func AddMessagesToMailbox(ctx context.Context,
	tx db.Transaction,
	mboxID imap.InternalMailboxID,
	messageIDs []db.MessageIDPair,
	s *State,
	imapLimits limits.IMAP) ([]db.UIDWithFlags, Update, error) {
	messageCount, uid, err := tx.GetMailboxMessageCountAndUID(ctx, mboxID)
	if err != nil {
		return nil, nil, err
	}

	if err := imapLimits.CheckMailBoxMessageCount(messageCount, len(messageIDs)); err != nil {
		return nil, nil, err
	}

	if err := imapLimits.CheckUIDCount(uid, len(messageIDs)); err != nil {
		return nil, nil, err
	}

	messageUIDs, err := tx.AddMessagesToMailbox(ctx, mboxID, messageIDs)
	if err != nil {
		return nil, nil, err
	}

	responders := xslices.Map(messageUIDs, func(uid db.UIDWithFlags) *exists {
		return newExists(db.MessageIDPair{
			InternalID: uid.InternalID,
			RemoteID:   uid.RemoteID,
		}, uid.UID, uid.GetFlagSet())
	})

	return messageUIDs, newExistsStateUpdateWithExists(mboxID, responders, s), nil
}

// RemoveMessagesFromMailbox removes the messages from the given mailbox.
func RemoveMessagesFromMailbox(ctx context.Context, tx db.Transaction, mboxID imap.InternalMailboxID, messageIDs []imap.InternalMessageID) ([]Update, error) {
	if len(messageIDs) > 0 {
		if err := tx.RemoveMessagesFromMailbox(ctx, mboxID, messageIDs); err != nil {
			return nil, err
		}
	}

	stateUpdates := xslices.Map(messageIDs, func(id imap.InternalMessageID) Update {
		return NewMessageIDAndMailboxIDResponderStateUpdate(id, mboxID, NewExpunge(id))
	})

	return stateUpdates, nil
}