Esempio n. 1
0
        /// <summary>
        /// Deletes the messages matching the messagefilter passed in
        /// </summary>
        /// <param name="messageFilter">The message filter.</param>
        /// <param name="adapter">The adapter to use for persistence activity.</param>
        /// <remarks>The caller has to have started a transaction on the passed in adapter</remarks>
        private static async Task DeleteMessagesAsync(IPredicate messageFilter, IDataAccessAdapter adapter)
        {
            // first delete all audit info for these message. This isn't done by a batch call directly on the db, as this is a targetperentity hierarchy
            // which can't be deleted directly into the database in all cases, so we first fetch the entities to delete.
            var qf = new QueryFactory();
            var q  = qf.AuditDataMessageRelated.Where(AuditDataMessageRelatedFields.MessageID.In(qf.Create()
                                                                                                 .Select(MessageFields.MessageID)
                                                                                                 .Where(messageFilter)));
            var messageAudits = await adapter.FetchQueryAsync(q).ConfigureAwait(false);

            await adapter.DeleteEntityCollectionAsync(messageAudits).ConfigureAwait(false);

            // Threadstatistics are already considered removed.

            // delete all attachments for this message. This can be done directly onto the db.
            await adapter.DeleteEntitiesDirectlyAsync(typeof(AttachmentEntity),
                                                      new RelationPredicateBucket(AttachmentFields.MessageID.In(qf.Create()
                                                                                                                .Select(MessageFields.MessageID)
                                                                                                                .Where(messageFilter))))
            .ConfigureAwait(false);

            await adapter.DeleteEntitiesDirectlyAsync(typeof(MessageEntity), new RelationPredicateBucket(messageFilter)).ConfigureAwait(false);

            // don't commit the transaction, leave that to the caller.
        }
Esempio n. 2
0
        /// <summary>
        /// Deletes the threads matching the passed in filter, inside the transaction specified.
        /// </summary>
        /// <param name="threadFilter">The thread filter.</param>
        /// <param name="adapter">The adapter to use in this method, has a live transaction.</param>
        private static async Task DeleteThreadsAsync(PredicateExpression threadFilter, IDataAccessAdapter adapter)
        {
            var qf = new QueryFactory();

            // we've to perform a set of actions in a given order to make sure we're not violating FK constraints in the DB.
            // First thread statistics for the threads matching the specified threadfilter.
            await adapter.DeleteEntitiesDirectlyAsync(typeof(ThreadStatisticsEntity),
                                                      new RelationPredicateBucket(ThreadStatisticsFields.ThreadID.In(qf.Thread.Where(threadFilter)
                                                                                                                     .Select(ThreadFields.ThreadID))))
            .ConfigureAwait(false);

            // then the messages, which refer to threads
            await MessageManager.DeleteAllMessagesInThreadsAsync(threadFilter, adapter);

            // delete bookmarks (if exists) of the threads to be deleted
            await adapter.DeleteEntitiesDirectlyAsync(typeof(BookmarkEntity),
                                                      new RelationPredicateBucket(BookmarkFields.ThreadID.In(qf.Thread.Where(threadFilter)
                                                                                                             .Select(ThreadFields.ThreadID))))
            .ConfigureAwait(false);

            // delete audit info related to this thread. Can't be done directly on the db due to the fact the entities are in a TargetPerEntity hierarchy, which
            // can't be deleted directly on the db, so we've to fetch the entities first.
            var q = qf.AuditDataThreadRelated.Where(AuditDataThreadRelatedFields.ThreadID.In(qf.Thread.Where(threadFilter).Select(ThreadFields.ThreadID)));
            var threadAuditData = await adapter.FetchQueryAsync(q).ConfigureAwait(false);

            await adapter.DeleteEntityCollectionAsync(threadAuditData).ConfigureAwait(false);

            // delete support queue thread entity for this thread (if any)
            await adapter.DeleteEntitiesDirectlyAsync(typeof(SupportQueueThreadEntity),
                                                      new RelationPredicateBucket(SupportQueueThreadFields.ThreadID.In(qf.Thread.Where(threadFilter)
                                                                                                                       .Select(ThreadFields.ThreadID))))
            .ConfigureAwait(false);

            // delete threadsubscription entities
            await adapter.DeleteEntitiesDirectlyAsync(typeof(ThreadSubscriptionEntity),
                                                      new RelationPredicateBucket(ThreadSubscriptionFields.ThreadID.In(qf.Thread.Where(threadFilter)
                                                                                                                       .Select(ThreadFields.ThreadID))))
            .ConfigureAwait(false);

            // delete the threads themselves, using the filter passed in
            await adapter.DeleteEntitiesDirectlyAsync(typeof(ThreadEntity), new RelationPredicateBucket(threadFilter)).ConfigureAwait(false);

            // don't commit the transaction, that's up to the caller.
        }