/// <summary> /// Updates the user/forum/thread statistics after a message insert. Also makes sure if the thread isn't in a queue and the forum has a default support /// queue that the thread is added to that queue /// </summary> /// <param name="threadId">The thread ID.</param> /// <param name="userId">The user ID.</param> /// <param name="newMessageId">The message id of the new message posted in the thread with threadid. If 0 or lower it's ignored and threadstatistics /// aren't updated. This is the case for when a new thread: the first message insert already inserted a correct threadstatistics object. </param> /// <param name="adapter">The adapter to use, which is assumed to have a live transaction active</param> /// <param name="postingDate">The posting date.</param> /// <param name="addToQueueIfRequired">if set to true, the thread will be added to the default queue of the forum the thread is in, if the forum /// has a default support queue and the thread isn't already in a queue.</param> /// <param name="subscribeToThread">if set to <c>true</c> [subscribe to thread].</param> /// <remarks> /// Leaves the passed in transaction open, so it doesn't commit/rollback, it just performs a set of actions inside the /// passed in transaction. /// </remarks> internal static async Task UpdateStatisticsAfterMessageInsert(int threadId, int userId, int newMessageId, IDataAccessAdapter adapter, DateTime postingDate, bool addToQueueIfRequired, bool subscribeToThread) { // user statistics var userUpdater = new UserEntity(); // set the amountofpostings field to an expression so it will be increased with 1. Update the entity directly in the DB userUpdater.Fields[(int)UserFieldIndex.AmountOfPostings].ExpressionToApply = (UserFields.AmountOfPostings + 1); await adapter.UpdateEntitiesDirectlyAsync(userUpdater, new RelationPredicateBucket(UserFields.UserID.Equal(userId))) .ConfigureAwait(false); if (newMessageId > 0) { // thread statistics. Create a single Update query which updates the messageid and increases the number of messages value with 1 var threadStatisticsUpdater = new ThreadStatisticsEntity { LastMessageID = newMessageId }; threadStatisticsUpdater.Fields[(int)ThreadStatisticsFieldIndex.NumberOfMessages].ExpressionToApply = (ThreadStatisticsFields.NumberOfMessages + 1); await adapter.UpdateEntitiesDirectlyAsync(threadStatisticsUpdater, new RelationPredicateBucket(ThreadStatisticsFields.ThreadID.Equal(threadId))) .ConfigureAwait(false); } // unmark the thread as done if it's done var threadUpdater = new ThreadEntity() { MarkedAsDone = false }; await adapter.UpdateEntitiesDirectlyAsync(threadUpdater, new RelationPredicateBucket(ThreadFields.ThreadID.Equal(threadId))) .ConfigureAwait(false); // forum statistics. Load the forum from the DB, as we need it later on. Use a nested query to fetch the forum as we don't know the // forumID as we haven't fetched the thread var qf = new QueryFactory(); var q = qf.Forum .Where(ForumFields.ForumID.In(qf.Create() .Select(ThreadFields.ForumID) .Where(ThreadFields.ThreadID.Equal(threadId)))); var containingForum = await adapter.FetchFirstAsync(q).ConfigureAwait(false); if (containingForum != null) { containingForum.ForumLastPostingDate = postingDate; // save the forum. await adapter.SaveEntityAsync(containingForum, true).ConfigureAwait(false); if (addToQueueIfRequired && containingForum.DefaultSupportQueueID.HasValue) { // If the thread involved isn't in a queue, place it in the default queue of the forum (if applicable) var containingQueue = await SupportQueueGuiHelper.GetQueueOfThreadAsync(threadId, adapter); if (containingQueue == null) { // not in a queue, and the forum has a default queue. Add the thread to the queue of the forum await SupportQueueManager.AddThreadToQueueAsync(threadId, containingForum.DefaultSupportQueueID.Value, userId, adapter); } } } //subscribe to thread if indicated if (subscribeToThread) { await UserManager.AddThreadToSubscriptionsAsync(threadId, userId, adapter); } }