private static void UpdateMessageChainFlag(IDaoFactory daoFactory, int tenant, string user, int messageId, string fieldFrom, string fieldTo) { var daoMail = daoFactory.CreateMailDao(tenant, user); var mail = daoMail.GetMail(new ConcreteUserMessageExp(messageId, tenant, user)); if (mail == null) { return; } var daoMailInfo = daoFactory.CreateMailInfoDao(tenant, user); var maxValue = daoMailInfo.GetFieldMaxValue <bool>( SimpleMessagesExp.CreateBuilder(tenant, user) .SetChainId(mail.ChainId) .SetMailboxId(mail.MailboxId) .SetFolder((int)mail.Folder) .Build(), fieldFrom); var daoChain = daoFactory.CreateChainDao(tenant, user); daoChain.SetFieldValue( SimpleConversationsExp.CreateBuilder(tenant, user) .SetChainId(mail.ChainId) .SetMailboxId(mail.MailboxId) .SetFolder((int)mail.Folder) .Build(), fieldTo, maxValue); }
public void UpdateChainFields(IDaoFactory daoFactory, int tenant, string user, List <int> ids) { var daoMailInfo = daoFactory.CreateMailInfoDao(tenant, user); var mailInfoList = daoMailInfo.GetMailInfoList( SimpleMessagesExp.CreateBuilder(tenant, user, null) .SetMessageIds(ids) .Build()) .ConvertAll(x => new { id_mailbox = x.MailboxId, chain_id = x.ChainId, folder = x.Folder }); if (!mailInfoList.Any()) { return; } foreach (var info in mailInfoList.GroupBy(t => new { t.id_mailbox, t.chain_id, t.folder })) { uint?userFolder = null; if (info.Key.folder == FolderType.UserFolder) { var userFolderXmailDao = daoFactory.CreateUserFolderXMailDao(Tenant, User); var item = userFolderXmailDao.Get(ids.First()); userFolder = item == null ? (uint?)null : item.FolderId; } UpdateChain(daoFactory, info.Key.chain_id, info.Key.folder, userFolder, info.Key.id_mailbox, tenant, user); } }
public void DeleteMessageAttachments(int tenant, string user, int messageId, List <int> attachmentIds) { var engine = new EngineFactory(tenant, user); long usedQuota; int attachCount; using (var daoFactory = new DaoFactory()) { using (var tx = daoFactory.DbManager.BeginTransaction(IsolationLevel.ReadUncommitted)) { var exp = new ConcreteMessageAttachmentsExp(messageId, tenant, user, attachmentIds, onlyEmbedded: null); var daoAttachment = daoFactory.CreateAttachmentDao(tenant, user); usedQuota = daoAttachment.GetAttachmentsSize(exp); daoAttachment.SetAttachmnetsRemoved(exp); attachCount = daoAttachment.GetAttachmentsCount( new ConcreteMessageAttachmentsExp(messageId, tenant, user)); var daoMailInfo = daoFactory.CreateMailInfoDao(tenant, user); daoMailInfo.SetFieldValue( SimpleMessagesExp.CreateBuilder(tenant, user) .SetMessageId(messageId) .Build(), MailTable.Columns.AttachCount, attachCount); engine.ChainEngine.UpdateMessageChainAttachmentsFlag(daoFactory, tenant, user, messageId); tx.Commit(); } } if (attachCount == 0) { var data = new MailWrapper { HasAttachments = false }; engine.IndexEngine.Update(data, s => s.Where(m => m.Id, messageId), wrapper => wrapper.HasAttachments); } if (usedQuota <= 0) { return; } engine.QuotaEngine.QuotaUsedDelete(usedQuota); }
// Constructor public MailboxMessagesIterator(MailBoxData mailBoxData) { MailEngine = new EngineFactory(mailBoxData.TenantId, mailBoxData.UserId); var range = MailEngine .MessageEngine .GetRangeMessages( SimpleMessagesExp.CreateBuilder(mailBoxData.TenantId) .SetMailboxId(mailBoxData.MailBoxId) .Build()); _minMessageId = range.Item1; _maxMessageId = range.Item2; }
public List <MailInfo> GetChainedMessagesInfo(DaoFactory daoFactory, List <int> ids) { var daoMailInfo = daoFactory.CreateMailInfoDao(Tenant, User); var chainsInfo = daoMailInfo.GetMailInfoList( SimpleMessagesExp.CreateBuilder(Tenant, User) .SetMessageIds(ids) .Build()); var chainArray = chainsInfo.Select(r => r.ChainId).Distinct().ToArray(); const int max_query_count = 25; var i = 0; var unsortedMessages = new List <MailInfo>(); do { var partChains = chainArray.Skip(i).Take(max_query_count).ToList(); if (!partChains.Any()) { break; } var selectedMessages = daoMailInfo.GetMailInfoList( SimpleMessagesExp.CreateBuilder(Tenant, User) .SetChainIds(partChains) .Build()); unsortedMessages.AddRange(selectedMessages); i += max_query_count; } while (true); var result = unsortedMessages .Where(r => chainsInfo.FirstOrDefault(c => c.ChainId == r.ChainId && c.MailboxId == r.MailboxId && ((r.Folder == FolderType.Inbox || r.Folder == FolderType.Sent) ? c.Folder == FolderType.Inbox || c.Folder == FolderType.Sent : c.Folder == r.Folder)) != null) .ToList(); return(result); }
private void GetValidForUserMessages(IDaoFactory daoFactory, List <int> messagesIds, out List <int> validIds, out List <ChainInfo> chains) { var daoMailInfo = daoFactory.CreateMailInfoDao(Tenant, User); var mailInfoList = daoMailInfo.GetMailInfoList( SimpleMessagesExp.CreateBuilder(Tenant, User) .SetMessageIds(messagesIds) .Build()); validIds = new List <int>(); chains = new List <ChainInfo>(); foreach (var mailInfo in mailInfoList) { validIds.Add(mailInfo.Id); chains.Add(new ChainInfo { Id = mailInfo.ChainId, Folder = mailInfo.Folder, MailboxId = mailInfo.MailboxId }); } }
public MailMessage Save(MailComposeBase compose) { var embededAttachmentsForSaving = FixHtmlBodyWithEmbeddedAttachments(compose); var message = compose.ToMailMessage(); var engine = new EngineFactory(compose.Mailbox.TenantId, compose.Mailbox.UserId); var addIndex = compose.Id == 0; var attachmentsToRestore = message.Attachments.Where(att => att.streamId != message.StreamId || att.isTemp).ToList(); var needRestoreAttachments = attachmentsToRestore.Any(); if (needRestoreAttachments) { message.Attachments.ForEach( attachment => engine.AttachmentEngine.StoreAttachmentCopy(compose.Mailbox.TenantId, compose.Mailbox.UserId, attachment, compose.StreamId)); } MessageEngine.StoreMailBody(compose.Mailbox, message, Log); long usedQuota; using (var daoFactory = new DaoFactory()) { var db = daoFactory.DbManager; using (var tx = db.BeginTransaction(IsolationLevel.ReadUncommitted)) { compose.Id = engine.MessageEngine.MailSave(daoFactory, compose.Mailbox, message, compose.Id, message.Folder, message.Folder, null, string.Empty, string.Empty, false, out usedQuota); message.Id = compose.Id; if (compose.AccountChanged) { engine.ChainEngine.UpdateChain(daoFactory, message.ChainId, message.Folder, null, compose.PreviousMailboxId, compose.Mailbox.TenantId, compose.Mailbox.UserId); } var daoMailInfo = daoFactory.CreateMailInfoDao(compose.Mailbox.TenantId, compose.Mailbox.UserId); if (compose.Id > 0 && needRestoreAttachments) { var daoAttachment = daoFactory.CreateAttachmentDao(compose.Mailbox.TenantId, compose.Mailbox.UserId); var existingAttachments = daoAttachment.GetAttachments( new ConcreteMessageAttachmentsExp(compose.Id, compose.Mailbox.TenantId, compose.Mailbox.UserId)); foreach (var attachment in message.Attachments) { if (existingAttachments.Any(x => x.Id == attachment.fileId)) { continue; } var attach = attachment.ToAttachmnet(compose.Id); attach.Id = 0; var newId = daoAttachment.SaveAttachment(attach); attachment.fileId = newId; } if (message.Attachments.Any()) { var count = daoAttachment.GetAttachmentsCount( new ConcreteMessageAttachmentsExp(compose.Id, compose.Mailbox.TenantId, compose.Mailbox.UserId)); daoMailInfo.SetFieldValue( SimpleMessagesExp.CreateBuilder(compose.Mailbox.TenantId, compose.Mailbox.UserId) .SetMessageId(compose.Id) .Build(), MailTable.Columns.AttachCount, count); } } if (compose.Id > 0 && embededAttachmentsForSaving.Any()) { var daoAttachment = daoFactory.CreateAttachmentDao(compose.Mailbox.TenantId, compose.Mailbox.UserId); foreach (var attachment in embededAttachmentsForSaving) { var newId = daoAttachment.SaveAttachment(attachment.ToAttachmnet(compose.Id)); attachment.fileId = newId; } if (message.Attachments.Any()) { var count = daoAttachment.GetAttachmentsCount( new ConcreteMessageAttachmentsExp(compose.Id, compose.Mailbox.TenantId, compose.Mailbox.UserId)); daoMailInfo.SetFieldValue( SimpleMessagesExp.CreateBuilder(compose.Mailbox.TenantId, compose.Mailbox.UserId) .SetMessageId(compose.Id) .Build(), MailTable.Columns.AttachCount, count); } } engine.ChainEngine.UpdateChain(daoFactory, message.ChainId, message.Folder, null, compose.Mailbox.MailBoxId, compose.Mailbox.TenantId, compose.Mailbox.UserId); if (compose.AccountChanged) { var daoCrmLink = daoFactory.CreateCrmLinkDao(compose.Mailbox.TenantId, compose.Mailbox.UserId); daoCrmLink.UpdateCrmLinkedMailboxId(message.ChainId, compose.PreviousMailboxId, compose.Mailbox.MailBoxId); } tx.Commit(); } } if (usedQuota > 0) { engine.QuotaEngine.QuotaUsedDelete(usedQuota); } if (addIndex) { engine.IndexEngine.Add(message.ToMailWrapper(compose.Mailbox.TenantId, new Guid(compose.Mailbox.UserId))); } else { engine.IndexEngine.Update(new List <MailWrapper> { message.ToMailWrapper(compose.Mailbox.TenantId, new Guid(compose.Mailbox.UserId)) }); } try { var tempStorage = MailDataStore.GetDataStore(compose.Mailbox.TenantId); tempStorage.DeleteDirectory("attachments_temp", compose.Mailbox.UserId + "/" + compose.StreamId + "/"); } catch (Exception ex) { Log.ErrorFormat("Clearing temp storage failed with exception: {0}", ex.ToString()); } return(message); }
public MailAttachmentData AttachFile(int tenant, string user, MailMessageData message, string name, Stream inputStream, long contentLength, string contentType = null, bool needSaveToTemp = false) { if (message == null) { throw new AttachmentsException(AttachmentsException.Types.MessageNotFound, "Message not found."); } if (string.IsNullOrEmpty(message.StreamId)) { throw new AttachmentsException(AttachmentsException.Types.MessageNotFound, "StreamId is empty."); } var messageId = message.Id; var engine = new EngineFactory(tenant, user); var totalSize = engine.AttachmentEngine.GetAttachmentsSize(new ConcreteMessageAttachmentsExp(messageId, tenant, user)); totalSize += contentLength; if (totalSize > Defines.ATTACHMENTS_TOTAL_SIZE_LIMIT) { throw new AttachmentsException(AttachmentsException.Types.TotalSizeExceeded, "Total size of all files exceeds limit!"); } var fileNumber = engine.AttachmentEngine.GetAttachmentNextFileNumber(new ConcreteMessageAttachmentsExp(messageId, tenant, user)); var attachment = new MailAttachmentData { fileName = name, contentType = string.IsNullOrEmpty(contentType) ? MimeMapping.GetMimeMapping(name) : contentType, needSaveToTemp = needSaveToTemp, fileNumber = fileNumber, size = contentLength, data = inputStream.ReadToEnd(), streamId = message.StreamId, tenant = tenant, user = user, mailboxId = message.MailboxId }; engine.QuotaEngine.QuotaUsedAdd(contentLength); try { var storage = new StorageManager(tenant, user); storage.StoreAttachmentWithoutQuota(attachment); } catch { engine.QuotaEngine.QuotaUsedDelete(contentLength); throw; } if (!needSaveToTemp) { int attachCount; using (var daoFactory = new DaoFactory()) { var db = daoFactory.DbManager; using (var tx = db.BeginTransaction()) { var daoAttachment = daoFactory.CreateAttachmentDao(tenant, user); attachment.fileId = daoAttachment.SaveAttachment(attachment.ToAttachmnet(messageId)); attachCount = daoAttachment.GetAttachmentsCount( new ConcreteMessageAttachmentsExp(messageId, tenant, user)); var daoMailInfo = daoFactory.CreateMailInfoDao(tenant, user); daoMailInfo.SetFieldValue( SimpleMessagesExp.CreateBuilder(tenant, user) .SetMessageId(messageId) .Build(), MailTable.Columns.AttachCount, attachCount); engine.ChainEngine.UpdateMessageChainAttachmentsFlag(daoFactory, tenant, user, messageId); tx.Commit(); } } if (attachCount == 1) { var data = new MailWrapper { HasAttachments = true }; engine.IndexEngine.Update(data, s => s.Where(m => m.Id, messageId), wrapper => wrapper.HasAttachments); } } return(attachment); }
private void ReleaseSendingDraftOnSuccess(MailDraftData draft, MailMessage message) { var engine = new EngineFactory(draft.Mailbox.TenantId, draft.Mailbox.UserId); using (var daoFactory = new DaoFactory()) { var db = daoFactory.DbManager; using (var tx = db.BeginTransaction(IsolationLevel.ReadUncommitted)) { // message was correctly send - lets update its chains id var draftChainId = message.ChainId; // before moving message from draft to sent folder - lets recalculate its correct chain id var chainInfo = engine.MessageEngine.DetectChain(daoFactory, draft.Mailbox, message.MimeMessageId, message.MimeReplyToId, message.Subject); message.ChainId = chainInfo.Id; if (message.ChainId.Equals(message.MimeMessageId)) { message.MimeReplyToId = null; } var daoMailInfo = daoFactory.CreateMailInfoDao(draft.Mailbox.TenantId, draft.Mailbox.UserId); if (!draftChainId.Equals(message.ChainId)) { daoMailInfo.SetFieldValue( SimpleMessagesExp.CreateBuilder(Tenant, User) .SetMessageId(message.Id) .Build(), MailTable.Columns.ChainId, message.ChainId); engine.ChainEngine.UpdateChain(daoFactory, draftChainId, FolderType.Sending, null, draft.Mailbox.MailBoxId, draft.Mailbox.TenantId, draft.Mailbox.UserId); var daoCrmLink = daoFactory.CreateCrmLinkDao(draft.Mailbox.TenantId, draft.Mailbox.UserId); daoCrmLink.UpdateCrmLinkedChainId(draftChainId, draft.Mailbox.MailBoxId, message.ChainId); } engine.ChainEngine.UpdateChain(daoFactory, message.ChainId, FolderType.Sending, null, draft.Mailbox.MailBoxId, draft.Mailbox.TenantId, draft.Mailbox.UserId); var listObjects = engine.ChainEngine.GetChainedMessagesInfo(daoFactory, new List <int> { draft.Id }); if (!listObjects.Any()) { return; } engine.MessageEngine.SetFolder(daoFactory, listObjects, FolderType.Sent); daoMailInfo.SetFieldValue( SimpleMessagesExp.CreateBuilder(Tenant, User) .SetMessageId(draft.Id) .Build(), MailTable.Columns.FolderRestore, FolderType.Sent); tx.Commit(); } } }
private List <MailMessageData> GetFilteredConversations(IDaoFactory daoFactory, MailSearchFilterData filter, out bool hasMore) { var conversations = new List <MailMessageData>(); var skipFlag = false; var chunkIndex = 0; if (filter.FromDate.HasValue && filter.FromMessage.HasValue && filter.FromMessage.Value > 0) { skipFlag = true; } var prevFlag = filter.PrevFlag.GetValueOrDefault(false); var tenantInfo = CoreContext.TenantManager.GetTenant(Tenant); var utcNow = DateTime.UtcNow; var pageSize = filter.PageSize.GetValueOrDefault(25); var daoMailInfo = daoFactory.CreateMailInfoDao(Tenant, User); while (conversations.Count < pageSize + 1) { filter.PageSize = CHUNK_SIZE * pageSize; IMessagesExp exp = null; if (!filter.IsDefault() && FactoryIndexer <MailWrapper> .Support && FactoryIndexer.CheckState(false)) { filter.Page = chunkIndex * CHUNK_SIZE * pageSize; // Elastic Limit from {index of last message} to {count of messages} List <MailWrapper> mailWrappers; if (FilterChainMessagesExp.TryGetFullTextSearchChains(filter, User, out mailWrappers)) { if (!mailWrappers.Any()) { break; } var ids = mailWrappers.Select(c => c.Id).ToList(); var query = SimpleMessagesExp.CreateBuilder(Tenant, User) .SetMessageIds(ids) .SetOrderBy(filter.Sort); if (prevFlag) { query.SetOrderAsc(!(filter.SortOrder == Defines.ASCENDING)); } else { query.SetOrderAsc(filter.SortOrder == Defines.ASCENDING); } exp = query .Build(); } } else { filter.Page = chunkIndex; // MySQL Limit from {page by size} to {size} exp = new FilterChainMessagesExp(filter, Tenant, User); } chunkIndex++; var listMessages = daoMailInfo.GetMailInfoList(exp, true) .ConvertAll(m => MessageEngine.ToMailMessage(m, tenantInfo, utcNow)); if (0 == listMessages.Count) { break; } if (skipFlag && filter.FromMessage.HasValue) { var messageData = listMessages.FirstOrDefault(m => m.Id == filter.FromMessage.Value); if (messageData != null) { // Skip chain messages by FromMessage. listMessages = listMessages.Where( m => !(m.ChainId.Equals(messageData.ChainId) && m.MailboxId == messageData.MailboxId)) .ToList(); } skipFlag = false; } foreach (var messageData in listMessages) { var existingChainIndex = conversations.FindIndex( c => c.ChainId == messageData.ChainId && c.MailboxId == messageData.MailboxId); if (existingChainIndex > -1) { if (conversations[existingChainIndex].Date < messageData.Date) { conversations[existingChainIndex] = messageData; } } else { conversations.Add(messageData); } } if (conversations.Count > pageSize) { break; } } hasMore = conversations.Count > pageSize; if (hasMore) { conversations = conversations.Take(pageSize).ToList(); } if (prevFlag) { conversations.Reverse(); } return(conversations); }
// Method for updating chain flags, date and length. public void UpdateChain(IDaoFactory daoFactory, string chainId, FolderType folder, uint?userFolderId, int mailboxId, int tenant, string user) { if (string.IsNullOrEmpty(chainId)) { return; } var db = daoFactory.DbManager; var engine = new EngineFactory(tenant, user, Log); var daoMailInfo = daoFactory.CreateMailInfoDao(tenant, user); const string m_alias = "m"; var getChainQuery = new SqlQuery(MailTable.TABLE_NAME.Alias(m_alias)) .SelectCount() .SelectMax(MailTable.Columns.DateSent.Prefix(m_alias)) .SelectMax(MailTable.Columns.Unread.Prefix(m_alias)) .SelectMax(MailTable.Columns.AttachCount.Prefix(m_alias)) .SelectMax(MailTable.Columns.Importance.Prefix(m_alias)) .Where(MailTable.Columns.Tenant.Prefix(m_alias), tenant) .Where(MailTable.Columns.User.Prefix(m_alias), user) .Where(MailTable.Columns.IsRemoved.Prefix(m_alias), 0) .Where(MailTable.Columns.ChainId.Prefix(m_alias), chainId) .Where(MailTable.Columns.MailboxId.Prefix(m_alias), mailboxId) .Where(MailTable.Columns.Folder.Prefix(m_alias), (int)folder); var chainInfo = db.ExecuteList(getChainQuery) .ConvertAll(x => new { length = Convert.ToInt32(x[0]), date = Convert.ToDateTime(x[1]), unread = Convert.ToBoolean(x[2]), attach_count = Convert.ToInt32(x[3]), importance = Convert.ToBoolean(x[4]) }) .FirstOrDefault(); if (chainInfo == null) { throw new InvalidDataException("Conversation is absent in MAIL_MAIL"); } var daoChain = daoFactory.CreateChainDao(tenant, user); var query = SimpleConversationsExp.CreateBuilder(tenant, user) .SetMailboxId(mailboxId) .SetChainId(chainId) .SetFolder((int)folder) .Build(); var storedChainInfo = daoChain.GetChains(query); var chainUnreadFlag = storedChainInfo.Any(c => c.Unread); if (0 == chainInfo.length) { var deletQuery = SimpleConversationsExp.CreateBuilder(tenant, user) .SetFolder((int)folder) .SetMailboxId(mailboxId) .SetChainId(chainId) .Build(); var result = daoChain.Delete(deletQuery); Log.DebugFormat( "UpdateChain() row deleted from chain table tenant='{0}', user_id='{1}', id_mailbox='{2}', folder='{3}', chain_id='{4}' result={5}", tenant, user, mailboxId, folder, chainId, result); var unreadConvDiff = chainUnreadFlag ? -1 : (int?)null; engine.FolderEngine.ChangeFolderCounters(daoFactory, folder, userFolderId, unreadConvDiff: unreadConvDiff, totalConvDiff: -1); } else { //var updateMailQuery = new SqlUpdate(MailTable.TABLE_NAME) // .Where(MailTable.Columns.Tenant, tenant) // .Where(MailTable.Columns.User, user) // .Where(MailTable.Columns.IsRemoved, 0) // .Where(MailTable.Columns.ChainId, chainId) // .Where(MailTable.Columns.MailboxId, mailboxId) // .Where(MailTable.Columns.Folder, (int) folder) // // Folder condition important because chain has different dates in different folders(Ex: Sent and Inbox). // .Set(MailTable.Columns.ChainDate, chainInfo.date); //db.ExecuteNonQuery(updateMailQuery); var updateQuery = SimpleMessagesExp.CreateBuilder(tenant, user) .SetChainId(chainId) .SetMailboxId(mailboxId) .SetFolder((int)folder) .Build(); daoMailInfo.SetFieldValue(updateQuery, MailTable.Columns.ChainDate, chainInfo.date); var tags = GetChainTags(daoFactory, chainId, folder, mailboxId, tenant, user); var chain = new Chain { Id = chainId, Tenant = tenant, User = user, MailboxId = mailboxId, Folder = folder, Length = chainInfo.length, Unread = chainInfo.unread, HasAttachments = chainInfo.attach_count > 0, Importance = chainInfo.importance, Tags = tags }; var result = daoChain.SaveChain(chain); if (result <= 0) { throw new InvalidOperationException(string.Format("Invalid insert into {0}", ChainTable.TABLE_NAME)); } Log.DebugFormat( "UpdateChain() row inserted to chain table tenant='{0}', user_id='{1}', id_mailbox='{2}', folder='{3}', chain_id='{4}'", tenant, user, mailboxId, folder, chainId); var unreadConvDiff = (int?)null; var totalConvDiff = (int?)null; if (!storedChainInfo.Any()) { totalConvDiff = 1; unreadConvDiff = chainInfo.unread ? 1 : (int?)null; } else { if (chainUnreadFlag != chainInfo.unread) { unreadConvDiff = chainInfo.unread ? 1 : -1; } } engine.FolderEngine.ChangeFolderCounters(daoFactory, folder, userFolderId, unreadConvDiff: unreadConvDiff, totalConvDiff: totalConvDiff); } }
public void SetConversationsImportanceFlags(int tenant, string user, bool important, List <int> ids) { List <MailInfo> mailInfos; using (var daoFactory = new DaoFactory()) { mailInfos = GetChainedMessagesInfo(daoFactory, ids); var chainsInfo = mailInfos .Select(m => new { m.ChainId, m.MailboxId, m.Folder }) .Distinct().ToList(); if (!chainsInfo.Any()) { throw new Exception("no chain messages belong to current user"); } using (var tx = daoFactory.DbManager.BeginTransaction(IsolationLevel.ReadUncommitted)) { var daoMailInfo = daoFactory.CreateMailInfoDao(tenant, user); var exp = Exp.Empty; var сhains = new List <Tuple <int, string> >(); foreach (var chain in chainsInfo) { var key = new Tuple <int, string>(chain.MailboxId, chain.ChainId); if (сhains.Any() && сhains.Contains(key) && (chain.Folder == FolderType.Inbox || chain.Folder == FolderType.Sent)) { continue; } var innerWhere = Exp.And( Exp.Eq(MailTable.Columns.ChainId.Prefix(MM_ALIAS), chain.ChainId), Exp.Eq(MailTable.Columns.MailboxId.Prefix(MM_ALIAS), chain.MailboxId)); if (chain.Folder == FolderType.Inbox || chain.Folder == FolderType.Sent) { innerWhere &= Exp.Or( Exp.Eq(MailTable.Columns.Folder.Prefix(MM_ALIAS), (int)FolderType.Inbox), Exp.Eq(MailTable.Columns.Folder.Prefix(MM_ALIAS), (int)FolderType.Sent)); сhains.Add(key); } else { innerWhere &= Exp.Eq(MailTable.Columns.Folder.Prefix(MM_ALIAS), (int)chain.Folder); } exp |= innerWhere; } daoMailInfo.SetFieldValue( SimpleMessagesExp.CreateBuilder(tenant, user) .SetExp(exp) .Build(), MailTable.Columns.Importance, important); var daoChain = daoFactory.CreateChainDao(tenant, user); foreach (var chain in chainsInfo) { daoChain.SetFieldValue( SimpleConversationsExp.CreateBuilder(tenant, user) .SetChainId(chain.ChainId) .SetMailboxId(chain.MailboxId) .SetFolder((int)chain.Folder) .Build(), ChainTable.Columns.Importance, important); } tx.Commit(); } } var factory = new EngineFactory(Tenant, User); var data = new MailWrapper { Importance = important }; factory.IndexEngine.Update(data, s => s.In(m => m.Id, mailInfos.Select(o => o.Id).ToArray()), wrapper => wrapper.Importance); }
public List <MailMessageData> GetConversationMessages(int tenant, string user, int messageId, bool loadAllContent, bool needProxyHttp, bool needMailSanitazer, bool markRead = false) { var engine = new EngineFactory(tenant, user); using (var daoFactory = new DaoFactory()) { var db = daoFactory.DbManager; var daoMailInfo = daoFactory.CreateMailInfoDao(tenant, user); var messageInfo = daoMailInfo.GetMailInfoList( SimpleMessagesExp.CreateBuilder(tenant, user) .SetMessageId(messageId) .Build()) .SingleOrDefault(); if (messageInfo == null) { throw new ArgumentException("Message Id not found"); } var searchFolders = new List <int>(); if (messageInfo.Folder == FolderType.Inbox || messageInfo.Folder == FolderType.Sent) { searchFolders.AddRange(new[] { (int)FolderType.Inbox, (int)FolderType.Sent }); } else { searchFolders.Add((int)messageInfo.Folder); } var exp = SimpleMessagesExp.CreateBuilder(tenant, user) .SetMailboxId(messageInfo.MailboxId) .SetChainId(messageInfo.ChainId) .SetFoldersIds(searchFolders) .Build(); var mailInfoList = daoMailInfo.GetMailInfoList(exp); var ids = mailInfoList.Select(m => m.Id).ToList(); var messages = ids.Select( (id, i) => engine.MessageEngine.GetMessage(daoFactory, id, new MailMessageData.Options { LoadImages = false, LoadBody = loadAllContent || (id == messageId), NeedProxyHttp = needProxyHttp, NeedSanitizer = needMailSanitazer })) .Where(mailInfo => mailInfo != null) .OrderBy(m => m.Date) .ToList(); if (!markRead) { return(messages); } var unreadMessages = messages.Where(message => message.WasNew).ToList(); if (!unreadMessages.Any()) { return(messages); } var unreadMessagesCountByFolder = new Dictionary <FolderType, int>(); foreach (var message in unreadMessages) { if (unreadMessagesCountByFolder.ContainsKey(message.Folder)) { unreadMessagesCountByFolder[message.Folder] += 1; } else { unreadMessagesCountByFolder.Add(message.Folder, 1); } } var userFolderXmailDao = daoFactory.CreateUserFolderXMailDao(tenant, user); uint?userFolder = null; if (unreadMessagesCountByFolder.Keys.Any(k => k == FolderType.UserFolder)) { var item = userFolderXmailDao.Get(ids.First()); userFolder = item == null ? (uint?)null : item.FolderId; } List <int> ids2Update; using (var tx = db.BeginTransaction()) { ids2Update = unreadMessages.Select(x => x.Id).ToList(); daoMailInfo.SetFieldValue( SimpleMessagesExp.CreateBuilder(tenant, user) .SetMessageIds(ids2Update) .Build(), MailTable.Columns.Unread, false); var daoChain = daoFactory.CreateChainDao(tenant, user); foreach (var keyPair in unreadMessagesCountByFolder) { var folderType = keyPair.Key; var unreadMessDiff = keyPair.Value != 0 ? keyPair.Value * (-1) : (int?)null; engine.FolderEngine.ChangeFolderCounters(daoFactory, folderType, userFolder, unreadMessDiff, unreadConvDiff: -1); daoChain.SetFieldValue( SimpleConversationsExp.CreateBuilder(tenant, user) .SetChainId(messageInfo.ChainId) .SetMailboxId(messageInfo.MailboxId) .SetFolder((int)keyPair.Key) .Build(), ChainTable.Columns.Unread, false); } if (userFolder.HasValue) { var userFoldersIds = userFolderXmailDao.GetList(mailIds: ids) .Select(ufxm => (int)ufxm.FolderId) .Distinct() .ToList(); engine.UserFolderEngine.RecalculateCounters(daoFactory, userFoldersIds); } tx.Commit(); } var data = new MailWrapper { Unread = false }; engine.IndexEngine.Update(data, s => s.In(m => m.Id, ids2Update.ToArray()), wrapper => wrapper.Unread); return(messages); } }
public void LinkChainToCrm(int messageId, List <CrmContactData> contactIds, string httpContextScheme) { using (var scope = DIHelper.Resolve()) { var factory = scope.Resolve <CRM.Core.Dao.DaoFactory>(); foreach (var crmContactEntity in contactIds) { switch (crmContactEntity.Type) { case CrmContactData.EntityTypes.Contact: var crmContact = factory.ContactDao.GetByID(crmContactEntity.Id); CRMSecurity.DemandAccessTo(crmContact); break; case CrmContactData.EntityTypes.Case: var crmCase = factory.CasesDao.GetByID(crmContactEntity.Id); CRMSecurity.DemandAccessTo(crmCase); break; case CrmContactData.EntityTypes.Opportunity: var crmOpportunity = factory.DealDao.GetByID(crmContactEntity.Id); CRMSecurity.DemandAccessTo(crmOpportunity); break; } } } using (var daoFactory = new DaoFactory()) { var db = daoFactory.DbManager; var daoMail = daoFactory.CreateMailDao(Tenant, User); var mail = daoMail.GetMail(new ConcreteUserMessageExp(messageId, Tenant, User)); var daoMailInfo = daoFactory.CreateMailInfoDao(Tenant, User); var chainedMessages = daoMailInfo.GetMailInfoList( SimpleMessagesExp.CreateBuilder(Tenant, User) .SetChainId(mail.ChainId) .Build()); if (!chainedMessages.Any()) { return; } var linkingMessages = new List <MailMessageData>(); var engine = new EngineFactory(Tenant, User); foreach (var chainedMessage in chainedMessages) { var message = engine.MessageEngine.GetMessage(chainedMessage.Id, new MailMessageData.Options { LoadImages = true, LoadBody = true, NeedProxyHttp = false }); message.LinkedCrmEntityIds = contactIds; linkingMessages.Add(message); } var daoCrmLink = daoFactory.CreateCrmLinkDao(Tenant, User); using (var tx = db.BeginTransaction(IsolationLevel.ReadUncommitted)) { daoCrmLink.SaveCrmLinks(mail.ChainId, mail.MailboxId, contactIds); foreach (var message in linkingMessages) { try { AddRelationshipEvents(message, httpContextScheme); } catch (ApiHelperException ex) { if (!ex.Message.Equals("Already exists")) { throw; } } } tx.Commit(); } } }
public void RecalculateFolders(Action <MailOperationRecalculateMailboxProgress> callback = null) { using (var db = new DbManager(Defines.CONNECTION_STRING_NAME, Defines.RecalculateFoldersTimeout)) { var daoFactory = new DaoFactory(db); var daoFolder = daoFactory.CreateFolderDao(Tenant, User); using (var tx = db.BeginTransaction(IsolationLevel.ReadUncommitted)) { var folderTypes = Enum.GetValues(typeof(FolderType)).Cast <int>(); var daoMailInfo = daoFactory.CreateMailInfoDao(Tenant, User); if (callback != null) { callback(MailOperationRecalculateMailboxProgress.CountUnreadMessages); } var unreadMessagesCountByFolder = daoMailInfo.GetMailCount( SimpleMessagesExp.CreateBuilder(Tenant, User) .SetUnread(true) .Build()); if (callback != null) { callback(MailOperationRecalculateMailboxProgress.CountTotalMessages); } var totalMessagesCountByFolder = daoMailInfo.GetMailCount( SimpleMessagesExp.CreateBuilder(Tenant, User) .Build()); var daoChain = daoFactory.CreateChainDao(Tenant, User); if (callback != null) { callback(MailOperationRecalculateMailboxProgress.CountUreadConversation); } var unreadConversationsCountByFolder = daoChain.GetChainCount( SimpleConversationsExp.CreateBuilder(Tenant, User) .SetUnread(true) .Build()); if (callback != null) { callback(MailOperationRecalculateMailboxProgress.CountTotalConversation); } var totalConversationsCountByFolder = daoChain.GetChainCount( SimpleConversationsExp.CreateBuilder(Tenant, User) .Build()); if (callback != null) { callback(MailOperationRecalculateMailboxProgress.UpdateFoldersCounters); } var now = DateTime.UtcNow; var folders = (from folderId in folderTypes let unreadMessCount = unreadMessagesCountByFolder.ContainsKey(folderId) ? unreadMessagesCountByFolder[folderId] : 0 let totalMessCount = totalMessagesCountByFolder.ContainsKey(folderId) ? totalMessagesCountByFolder[folderId] : 0 let unreadConvCount = unreadConversationsCountByFolder.ContainsKey(folderId) ? unreadConversationsCountByFolder[folderId] : 0 let totalConvCount = totalConversationsCountByFolder.ContainsKey(folderId) ? totalConversationsCountByFolder[folderId] : 0 select new Folder { FolderType = (FolderType)folderId, Tenant = Tenant, UserId = User, UnreadCount = unreadMessCount, UnreadChainCount = unreadConvCount, TotalCount = totalMessCount, TotalChainCount = totalConvCount, TimeModified = now }) .ToList(); foreach (var folder in folders) { daoFolder.Save(folder); } var userFolder = folders.FirstOrDefault(f => f.FolderType == FolderType.UserFolder); if (userFolder != null) { var daoUserFolder = daoFactory.CreateUserFolderDao(Tenant, User); var userFolders = daoUserFolder.GetList( SimpleUserFoldersExp.CreateBuilder(Tenant, User) .Build()); if (userFolders.Any()) { var totalMessagesCountByUserFolder = daoMailInfo.GetMailUserFolderCount(); if (callback != null) { callback(MailOperationRecalculateMailboxProgress.CountTotalUserFolderMessages); } var unreadMessagesCountByUserFolder = daoMailInfo.GetMailUserFolderCount(true); if (callback != null) { callback(MailOperationRecalculateMailboxProgress.CountUnreadUserFolderMessages); } var totalConversationsCountByUserFolder = daoChain.GetChainUserFolderCount(); if (callback != null) { callback(MailOperationRecalculateMailboxProgress.CountTotalUserFolderConversation); } var unreadConversationsCountByUserFolder = daoChain.GetChainUserFolderCount(true); if (callback != null) { callback(MailOperationRecalculateMailboxProgress.CountUreadUserFolderConversation); } var newUserFolders = (from folder in userFolders let unreadMessCount = unreadMessagesCountByUserFolder.ContainsKey(folder.Id) ? unreadMessagesCountByUserFolder[folder.Id] : 0 let totalMessCount = totalMessagesCountByUserFolder.ContainsKey(folder.Id) ? totalMessagesCountByUserFolder[folder.Id] : 0 let unreadConvCount = unreadConversationsCountByUserFolder.ContainsKey(folder.Id) ? unreadConversationsCountByUserFolder[folder.Id] : 0 let totalConvCount = totalConversationsCountByUserFolder.ContainsKey(folder.Id) ? totalConversationsCountByUserFolder[folder.Id] : 0 select new UserFolder { Id = folder.Id, ParentId = folder.ParentId, Name = folder.Name, FolderCount = folder.FolderCount, Tenant = Tenant, User = User, UnreadCount = unreadMessCount, UnreadChainCount = unreadConvCount, TotalCount = totalMessCount, TotalChainCount = totalConvCount, TimeModified = now }) .ToList(); if (callback != null) { callback(MailOperationRecalculateMailboxProgress.UpdateUserFoldersCounters); } foreach (var folder in newUserFolders) { daoUserFolder.Save(folder); } } } tx.Commit(); } } }
/// <summary> /// Set mailbox removed /// </summary> /// <param name="daoFactory"></param> /// <param name="mailBoxData"></param> /// <returns>Return freed quota value</returns> private static long RemoveMailBoxInfo(IDaoFactory daoFactory, MailBoxData mailBoxData) { if (mailBoxData.MailBoxId <= 0) { throw new Exception("MailBox id is 0"); } var daoMailbox = daoFactory.CreateMailboxDao(); var mailbox = daoMailbox.GetMailBox( new СoncreteUserMailboxExp(mailBoxData.MailBoxId, mailBoxData.TenantId, mailBoxData.UserId, null)); if (mailbox == null) { throw new Exception(string.Format("MailBox with id = {0} (Tenant={1}, User='******') not found", mailBoxData.MailBoxId, mailBoxData.TenantId, mailBoxData.UserId)); } daoMailbox.SetMailboxRemoved(mailbox); var daoChain = daoFactory.CreateChainDao(mailBoxData.TenantId, mailBoxData.UserId); var folderTypes = Enum.GetValues(typeof(FolderType)).Cast <int>().ToList(); daoChain.Delete( SimpleConversationsExp.CreateBuilder(mailBoxData.TenantId, mailBoxData.UserId) .SetFoldersIds(folderTypes) .SetMailboxId(mailBoxData.MailBoxId) .Build()); var daoCrmLink = daoFactory.CreateCrmLinkDao(mailBoxData.TenantId, mailBoxData.UserId); daoCrmLink.RemoveCrmLinks(mailBoxData.MailBoxId); var daoMailInfo = daoFactory.CreateMailInfoDao(mailBoxData.TenantId, mailBoxData.UserId); daoMailInfo.SetFieldValue( SimpleMessagesExp.CreateBuilder(mailBoxData.TenantId, mailBoxData.UserId) .SetMailboxId(mailBoxData.MailBoxId) .Build(), MailTable.Columns.IsRemoved, true); var exp = new ConcreteMailboxAttachmentsExp(mailBoxData.MailBoxId, mailBoxData.TenantId, mailBoxData.UserId, onlyEmbedded: null); var daoAttachment = daoFactory.CreateAttachmentDao(mailBoxData.TenantId, mailBoxData.UserId); var totalAttachmentsSize = daoAttachment.GetAttachmentsSize(exp); daoAttachment.SetAttachmnetsRemoved(exp); var tagDao = daoFactory.CreateTagDao(mailBoxData.TenantId, mailBoxData.UserId); var tagMailDao = daoFactory.CreateTagMailDao(mailBoxData.TenantId, mailBoxData.UserId); var tagIds = tagMailDao.GetTagIds(mailBoxData.MailBoxId); tagMailDao.DeleteByMailboxId(mailBoxData.MailBoxId); foreach (var tagId in tagIds) { var tag = tagDao.GetTag(tagId); if (tag == null) { continue; } var count = tagMailDao.CalculateTagCount(tag.Id); tag.Count = count; tagDao.SaveTag(tag); } daoFactory.CreateMailboxSignatureDao(mailBoxData.TenantId, mailBoxData.UserId).DeleteSignature(mailBoxData.MailBoxId); daoFactory.CreateMailboxAutoreplyDao(mailBoxData.TenantId, mailBoxData.UserId) .DeleteAutoreply(mailBoxData.MailBoxId); daoFactory.CreateMailboxAutoreplyHistoryDao(mailBoxData.TenantId, mailBoxData.UserId).DeleteAutoreplyHistory(mailBoxData.MailBoxId); daoFactory.CreateAlertDao(mailBoxData.TenantId, mailBoxData.UserId).DeleteAlerts(mailBoxData.MailBoxId); daoFactory.CreateUserFolderXMailDao(mailBoxData.TenantId, mailBoxData.UserId) .RemoveByMailbox(mailBoxData.MailBoxId); return(totalAttachmentsSize); }
public MailMessage Save(MailComposeBase draft) { var embededAttachmentsForSaving = FixHtmlBodyWithEmbeddedAttachments(draft); var message = draft.ToMailMessage(); var engine = new EngineFactory(draft.Mailbox.TenantId, draft.Mailbox.UserId); var addIndex = draft.Id == 0; var needRestoreAttachments = draft.Id == 0 && message.Attachments.Any(); if (needRestoreAttachments) { message.Attachments.ForEach( attachment => engine.AttachmentEngine.StoreAttachmentCopy(draft.Mailbox.TenantId, draft.Mailbox.UserId, attachment, draft.StreamId)); } MessageEngine.StoreMailBody(draft.Mailbox, message, Log); long usedQuota; using (var daoFactory = new DaoFactory()) { var db = daoFactory.DbManager; using (var tx = db.BeginTransaction(IsolationLevel.ReadUncommitted)) { draft.Id = engine.MessageEngine.MailSave(daoFactory, draft.Mailbox, message, draft.Id, message.Folder, message.Folder, null, string.Empty, string.Empty, false, out usedQuota); message.Id = draft.Id; if (draft.AccountChanged) { engine.ChainEngine.UpdateChain(daoFactory, message.ChainId, message.Folder, null, draft.PreviousMailboxId, draft.Mailbox.TenantId, draft.Mailbox.UserId); } var daoMailInfo = daoFactory.CreateMailInfoDao(draft.Mailbox.TenantId, draft.Mailbox.UserId); if (draft.Id > 0 && needRestoreAttachments) { var daoAttachment = daoFactory.CreateAttachmentDao(draft.Mailbox.TenantId, draft.Mailbox.UserId); foreach (var attachment in message.Attachments) { var attach = attachment.ToAttachmnet(draft.Id); attach.Id = 0; var newId = daoAttachment.SaveAttachment(attach); attachment.fileId = newId; } if (message.Attachments.Any()) { var count = daoAttachment.GetAttachmentsCount( new ConcreteMessageAttachmentsExp(draft.Id, draft.Mailbox.TenantId, draft.Mailbox.UserId)); daoMailInfo.SetFieldValue( SimpleMessagesExp.CreateBuilder(draft.Mailbox.TenantId, draft.Mailbox.UserId) .SetMessageId(draft.Id) .Build(), MailTable.Columns.AttachCount, count); } } if (draft.Id > 0 && embededAttachmentsForSaving.Any()) { var daoAttachment = daoFactory.CreateAttachmentDao(draft.Mailbox.TenantId, draft.Mailbox.UserId); foreach (var attachment in embededAttachmentsForSaving) { var newId = daoAttachment.SaveAttachment(attachment.ToAttachmnet(draft.Id)); attachment.fileId = newId; } if (message.Attachments.Any()) { var count = daoAttachment.GetAttachmentsCount( new ConcreteMessageAttachmentsExp(draft.Id, draft.Mailbox.TenantId, draft.Mailbox.UserId)); daoMailInfo.SetFieldValue( SimpleMessagesExp.CreateBuilder(draft.Mailbox.TenantId, draft.Mailbox.UserId) .SetMessageId(draft.Id) .Build(), MailTable.Columns.AttachCount, count); } } engine.ChainEngine.UpdateChain(daoFactory, message.ChainId, message.Folder, null, draft.Mailbox.MailBoxId, draft.Mailbox.TenantId, draft.Mailbox.UserId); if (draft.AccountChanged) { var daoCrmLink = daoFactory.CreateCrmLinkDao(draft.Mailbox.TenantId, draft.Mailbox.UserId); daoCrmLink.UpdateCrmLinkedMailboxId(message.ChainId, draft.PreviousMailboxId, draft.Mailbox.MailBoxId); } tx.Commit(); } } if (usedQuota > 0) { engine.QuotaEngine.QuotaUsedDelete(usedQuota); } if (addIndex) { engine.IndexEngine.Add(message.ToMailWrapper(draft.Mailbox.TenantId, new Guid(draft.Mailbox.UserId))); } else { engine.IndexEngine.Update(new List <MailWrapper> { message.ToMailWrapper(draft.Mailbox.TenantId, new Guid(draft.Mailbox.UserId)) }); } return(message); }