forked from Silverfish/proton-bridge
Cache body structure in order to reduce network traffic
This commit is contained in:
@ -20,6 +20,7 @@ package store
|
||||
import (
|
||||
"net/mail"
|
||||
|
||||
backendMessage "github.com/ProtonMail/proton-bridge/pkg/message"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
)
|
||||
@ -119,3 +120,31 @@ func (message *Message) SetContentTypeAndHeader(mimeType string, header mail.Hea
|
||||
}
|
||||
return message.store.db.Update(txUpdate)
|
||||
}
|
||||
|
||||
// SetBodyStructure stores serialized body structure in database
|
||||
func (message *Message) SetBodyStructure(bs *backendMessage.BodyStructure) error {
|
||||
txUpdate := func(tx *bolt.Tx) error {
|
||||
return message.store.txPutBodyStructure(
|
||||
tx.Bucket(bodystructureBucket),
|
||||
message.ID(), bs,
|
||||
)
|
||||
}
|
||||
return message.store.db.Update(txUpdate)
|
||||
}
|
||||
|
||||
// GetBodyStructure deserialize body structure from database. If body structure
|
||||
// is not in database it returns nil error and nil body structure. If error
|
||||
// occurs it returns nil body structure.
|
||||
func (message *Message) GetBodyStructure() (bs *backendMessage.BodyStructure, err error) {
|
||||
txRead := func(tx *bolt.Tx) error {
|
||||
bs, err = message.store.txGetBodyStructure(
|
||||
tx.Bucket(bodystructureBucket),
|
||||
message.ID(),
|
||||
)
|
||||
return err
|
||||
}
|
||||
if err = message.store.db.View(txRead); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bs, nil
|
||||
}
|
||||
|
||||
@ -71,16 +71,17 @@ var (
|
||||
// * {messageID} -> uint32 imapUID
|
||||
// * deleted_ids (can be missing or have no keys)
|
||||
// * {messageID} -> true
|
||||
metadataBucket = []byte("metadata") //nolint[gochecknoglobals]
|
||||
countsBucket = []byte("counts") //nolint[gochecknoglobals]
|
||||
addressInfoBucket = []byte("address_info") //nolint[gochecknoglobals]
|
||||
addressModeBucket = []byte("address_mode") //nolint[gochecknoglobals]
|
||||
syncStateBucket = []byte("sync_state") //nolint[gochecknoglobals]
|
||||
mailboxesBucket = []byte("mailboxes") //nolint[gochecknoglobals]
|
||||
imapIDsBucket = []byte("imap_ids") //nolint[gochecknoglobals]
|
||||
apiIDsBucket = []byte("api_ids") //nolint[gochecknoglobals]
|
||||
deletedIDsBucket = []byte("deleted_ids") //nolint[gochecknoglobals]
|
||||
mboxVersionBucket = []byte("mailboxes_version") //nolint[gochecknoglobals]
|
||||
metadataBucket = []byte("metadata") //nolint[gochecknoglobals]
|
||||
bodystructureBucket = []byte("bodystructure") //nolint[gochecknoglobals]
|
||||
countsBucket = []byte("counts") //nolint[gochecknoglobals]
|
||||
addressInfoBucket = []byte("address_info") //nolint[gochecknoglobals]
|
||||
addressModeBucket = []byte("address_mode") //nolint[gochecknoglobals]
|
||||
syncStateBucket = []byte("sync_state") //nolint[gochecknoglobals]
|
||||
mailboxesBucket = []byte("mailboxes") //nolint[gochecknoglobals]
|
||||
imapIDsBucket = []byte("imap_ids") //nolint[gochecknoglobals]
|
||||
apiIDsBucket = []byte("api_ids") //nolint[gochecknoglobals]
|
||||
deletedIDsBucket = []byte("deleted_ids") //nolint[gochecknoglobals]
|
||||
mboxVersionBucket = []byte("mailboxes_version") //nolint[gochecknoglobals]
|
||||
|
||||
// ErrNoSuchAPIID when mailbox does not have API ID.
|
||||
ErrNoSuchAPIID = errors.New("no such api id") //nolint[gochecknoglobals]
|
||||
@ -193,6 +194,10 @@ func openBoltDatabase(filePath string) (db *bolt.DB, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = tx.CreateBucketIfNotExists(bodystructureBucket); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = tx.CreateBucketIfNotExists(countsBucket); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||
backendMessage "github.com/ProtonMail/proton-bridge/pkg/message"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -170,6 +171,26 @@ func (store *Store) txPutMessage(metaBucket *bolt.Bucket, onlyMeta *pmapi.Messag
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *Store) txPutBodyStructure(bsBucket *bolt.Bucket, msgID string, bs *backendMessage.BodyStructure) error {
|
||||
raw, err := bs.Serialize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = bsBucket.Put([]byte(msgID), raw)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cannot put bodystructure bucket")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *Store) txGetBodyStructure(bsBucket *bolt.Bucket, msgID string) (*backendMessage.BodyStructure, error) {
|
||||
raw := bsBucket.Get([]byte(msgID))
|
||||
if len(raw) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return backendMessage.DeserializeBodyStructure(raw)
|
||||
}
|
||||
|
||||
// createOrUpdateMessageEvent is helper to create only one message with
|
||||
// createOrUpdateMessagesEvent.
|
||||
func (store *Store) createOrUpdateMessageEvent(msg *pmapi.Message) error {
|
||||
|
||||
Reference in New Issue
Block a user