Check-in [e1327afe6c]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added repository for MessageReferences.
Timelines: family | ancestors | descendants | both | dotnet
Files: files | file ages | folders
SHA1: e1327afe6c4252659c937c713326595f74eab5f9
User & Date: tinus 2019-09-10 19:32:56
Wiki:dotnet
Context
2019-09-13
18:54
Move retrieval of existing messageIDs to FolderMessages repository. check-in: b5185ef288 user: tinus tags: dotnet
2019-09-10
19:32
Added repository for MessageReferences. check-in: e1327afe6c user: tinus tags: dotnet
19:08
Updated TODO.md. check-in: a0bfc52b64 user: tinus tags: dotnet
Changes

Changes to MailSynchronizer.cs.

719
720
721
722
723
724
725
726
727
728

729
730
731
732
733
734
735
...
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
        private async Task PopulateReferencesAsync(UnitOfWork work, Message targetMsg, MimeMessage sourceMsg)
        {
            // Include the In-Reply-To header in the list of references
            var sourceReferences = new List<string>(sourceMsg.References);
            if (!string.IsNullOrWhiteSpace(sourceMsg.InReplyTo) && !sourceReferences.Contains(sourceMsg.InReplyTo))
                sourceReferences.Insert(0, sourceMsg.InReplyTo);

            var dbMessageRefs = await work.DB.MessageReferences
                .Where(mr => mr.Message == targetMsg)
                .ToDictionaryAsync(mr => mr.ReferencedRfcMessageID, _cancellationToken);

            var dbReferencedMessageIDs = work.Messages
                .GetLookup(m => sourceReferences.Contains(m.RfcMessageID),
                           m => m.RfcMessageID,
                           m => m?.ID);
            int index = 0;
            foreach (string mailRef in sourceReferences)
            {
................................................................................
                long? dbMessageID = null;
                if (dbReferencedMessageIDs.Contains(mailRef))
                {
                    dbMessageID = dbReferencedMessageIDs[mailRef].FirstOrDefault(id => id.HasValue);
                }
                if (dbReference == null)
                {
                    await work.DB.MessageReferences.AddAsync(new MessageReference
                    {
                        Message = targetMsg,
                        ReferencedRfcMessageID = mailRef,
                        InReplyTo = mailRef == sourceMsg.InReplyTo,
                        Order = index,
                        ReferencedMessageID = dbMessageID,
                    }, _cancellationToken);
                }
                else
                {
                    dbReference.Order = index;
                    dbReference.ReferencedMessageID = dbMessageID;
                    dbMessageRefs.Remove(mailRef);
                }
            }

            // Any remaining references are no longer in use, so delete them
            work.DB.MessageReferences.RemoveRange(dbMessageRefs.Values);

            // Find any existing references to targetMsg, and fill them in
            if (targetMsg.RfcMessageID != null)
            {
                var previousReferences = work.DB.MessageReferences
                    .Where(mr => mr.ReferencedRfcMessageID == targetMsg.RfcMessageID && mr.Message == null);
                foreach (var dbReference in previousReferences)
                {
                    dbReference.Message = targetMsg;
                }
            }

            await work.SaveChangesAsync();







|
|
|
>







 







|






|










|




|
|







719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
...
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
        private async Task PopulateReferencesAsync(UnitOfWork work, Message targetMsg, MimeMessage sourceMsg)
        {
            // Include the In-Reply-To header in the list of references
            var sourceReferences = new List<string>(sourceMsg.References);
            if (!string.IsNullOrWhiteSpace(sourceMsg.InReplyTo) && !sourceReferences.Contains(sourceMsg.InReplyTo))
                sourceReferences.Insert(0, sourceMsg.InReplyTo);

            var dbMessageRefs = await work.MessageReferences
                .GetDictionaryAsync(mr => mr.Message == targetMsg,
                                    mr => mr.ReferencedRfcMessageID,
                                    mr => mr);
            var dbReferencedMessageIDs = work.Messages
                .GetLookup(m => sourceReferences.Contains(m.RfcMessageID),
                           m => m.RfcMessageID,
                           m => m?.ID);
            int index = 0;
            foreach (string mailRef in sourceReferences)
            {
................................................................................
                long? dbMessageID = null;
                if (dbReferencedMessageIDs.Contains(mailRef))
                {
                    dbMessageID = dbReferencedMessageIDs[mailRef].FirstOrDefault(id => id.HasValue);
                }
                if (dbReference == null)
                {
                    await work.MessageReferences.AddAsync(new MessageReference
                    {
                        Message = targetMsg,
                        ReferencedRfcMessageID = mailRef,
                        InReplyTo = mailRef == sourceMsg.InReplyTo,
                        Order = index,
                        ReferencedMessageID = dbMessageID,
                    });
                }
                else
                {
                    dbReference.Order = index;
                    dbReference.ReferencedMessageID = dbMessageID;
                    dbMessageRefs.Remove(mailRef);
                }
            }

            // Any remaining references are no longer in use, so delete them
            work.MessageReferences.Delete(dbMessageRefs.Values);

            // Find any existing references to targetMsg, and fill them in
            if (targetMsg.RfcMessageID != null)
            {
                var previousReferences = work.MessageReferences
                    .GetList(mr => mr.ReferencedRfcMessageID == targetMsg.RfcMessageID && mr.Message == null);
                foreach (var dbReference in previousReferences)
                {
                    dbReference.Message = targetMsg;
                }
            }

            await work.SaveChangesAsync();

Added Repositories/MessageReferencesRepository.cs.

























>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
using System.Threading;
using MailJanitor.Models;

namespace MailJanitor.Repositories
{
    public class MessageReferencesRepository : Repository<MessageReference>
    {
        public MessageReferencesRepository(MailJanitorContext db, CancellationToken cancellationToken = default(CancellationToken)) : base(db, cancellationToken)
        {
        }
    }
}

Changes to UnitOfWork.cs.

21
22
23
24
25
26
27

28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
            _db.ChangeTracker.LazyLoadingEnabled = false;
            Accounts = new AccountsRepository(_db, _cancellationToken);
            Folders = new FoldersRepository(_db, _cancellationToken);
            FolderMessages = new FolderMessagesRepository(_db, _cancellationToken);
            Messages = new MessagesRepository(_db, _cancellationToken);
            Participants = new ParticipantsRepository(_db, _cancellationToken);
            Keywords = new KeywordsRepository(_db, _cancellationToken);

        }

        public AccountsRepository Accounts { get; private set; }
        public FoldersRepository Folders { get; private set; }
        public FolderMessagesRepository FolderMessages { get; private set; }
        public MessagesRepository Messages { get; private set; }
        public ParticipantsRepository Participants { get; private set; }
        public KeywordsRepository Keywords { get; private set; }


        public void LoadProperty<T, TProperty>(T entity, Expression<Func<T, IEnumerable<TProperty>>> propertyExpression) where T : class where TProperty : class
        {
            _db.Entry<T>(entity).Collection<TProperty>(propertyExpression);
        }
        public void LoadProperty<T, TProperty>(T entity, Expression<Func<T, TProperty>> propertyExpression) where T : class where TProperty : class
        {







>








>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
            _db.ChangeTracker.LazyLoadingEnabled = false;
            Accounts = new AccountsRepository(_db, _cancellationToken);
            Folders = new FoldersRepository(_db, _cancellationToken);
            FolderMessages = new FolderMessagesRepository(_db, _cancellationToken);
            Messages = new MessagesRepository(_db, _cancellationToken);
            Participants = new ParticipantsRepository(_db, _cancellationToken);
            Keywords = new KeywordsRepository(_db, _cancellationToken);
            MessageReferences = new MessageReferencesRepository(_db, _cancellationToken);
        }

        public AccountsRepository Accounts { get; private set; }
        public FoldersRepository Folders { get; private set; }
        public FolderMessagesRepository FolderMessages { get; private set; }
        public MessagesRepository Messages { get; private set; }
        public ParticipantsRepository Participants { get; private set; }
        public KeywordsRepository Keywords { get; private set; }
        public MessageReferencesRepository MessageReferences { get; private set; }

        public void LoadProperty<T, TProperty>(T entity, Expression<Func<T, IEnumerable<TProperty>>> propertyExpression) where T : class where TProperty : class
        {
            _db.Entry<T>(entity).Collection<TProperty>(propertyExpression);
        }
        public void LoadProperty<T, TProperty>(T entity, Expression<Func<T, TProperty>> propertyExpression) where T : class where TProperty : class
        {