예제 #1
0
        /// <summary>
        /// Synchronizes the items that exist in the source only.
        /// </summary>
        /// <param name="batchKeys">The keys of the items.</param>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
        /// <returns></returns>
        private async Task SyncItemsInSourceOnlyBatchAsync(List <TKey> batchKeys, CancellationToken cancellationToken)
        {
            if (!batchKeys.Any())
            {
                return;
            }

            switch (Configurations.SyncMode.ItemsInSourceOnly)
            {
            case SyncItemOperation.None:      // do nothing
                break;

            case SyncItemOperation.Add:
                var comparisonResult = new ComparisonResult <TItem>();
                comparisonResult.ItemsInSourceOnly.AddRange(await SourceProvider.GetAsync(batchKeys, cancellationToken).ConfigureAwait(false));
                await SyncAsync(comparisonResult, cancellationToken).ConfigureAwait(false);

                break;

            case SyncItemOperation.Delete:
                BeforeDeletingItemsFromSourceAction?.Invoke(batchKeys);
                await SourceProvider.DeleteAsync(batchKeys, cancellationToken).ConfigureAwait(false);

                break;

            default:
                throw new NotSupportedException($"Not supported source {nameof(SyncItemOperation)} '{Configurations.SyncMode.ItemsInSourceOnly.ToString()}'.");
            }
        }
예제 #2
0
        /// <summary>
        /// Compares the source and destination keys, and returns the comparison result.
        /// </summary>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
        /// <returns>The comparison result.</returns>
        public async Task <KeysComparisonResult <TKey> > CompareAsync(CancellationToken cancellationToken)
        {
            Validate();

            var comparisonResult       = new KeysComparisonResult <TKey>();
            SortedSet <TKey> sourceSet = new SortedSet <TKey>()
            , destinationSet           = new SortedSet <TKey>();

            // Get entries from source and destination at the same time
            var tskSrc  = Task.Run(async() => AddKeysToSet(sourceSet, await SourceProvider.GetAsync(cancellationToken).ConfigureAwait(false), "source list"), cancellationToken);
            var tskDest = Task.Run(async() => AddKeysToSet(destinationSet, await DestinationProvider.GetAsync(cancellationToken).ConfigureAwait(false), "destination list"), cancellationToken);

            await Task.WhenAll(tskSrc, tskDest).ConfigureAwait(false);

            // Compare keys
            foreach (var srcKey in sourceSet)
            {
                if (destinationSet.Remove(srcKey))
                {
                    comparisonResult.Matches.Add(srcKey);
                }
                else
                {
                    comparisonResult.KeysInSourceOnly.Add(srcKey);
                }
            }

            foreach (var destKey in destinationSet)
            {
                comparisonResult.KeysInDestinationOnly.Add(destKey);
            }

            return(comparisonResult);
        }
예제 #3
0
        /// <summary>
        /// Synchronizes the items that exist in the source and destination.
        /// </summary>
        /// <param name="batchKeys">The keys of the items.</param>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
        /// <returns></returns>
        private async Task SyncMatchesBatchAsync(List <TKey> batchKeys, CancellationToken cancellationToken)
        {
            var srcTask = SourceProvider.GetAsync(batchKeys, cancellationToken);
            var dstTask = DestinationProvider.GetAsync(batchKeys, cancellationToken);

            await Task.WhenAll(srcTask, dstTask);

            // Compare
            var comparisonResult = await ComparerAgent <TKey, TItem> .Create()
                                   .Configure((c) =>
            {
                c.AllowDuplicateItems = RuleAllowanceType.None;
                c.AllowDuplicateKeys  = RuleAllowanceType.None;
                c.AllowNullableItems  = RuleAllowanceType.None;
            })
                                   .SetKeySelector(KeySelector)
                                   .SetCompareItemFunc(CompareItemFunc)
                                   .SetSourceProvider(srcTask.Result)
                                   .SetDestinationProvider(dstTask.Result)
                                   .CompareAsync(cancellationToken).ConfigureAwait(false);

            // Sync
            await SyncAsync(comparisonResult, cancellationToken).ConfigureAwait(false);
        }
예제 #4
0
        /// <summary>
        /// Compares the source and destination items, and returns the comparison result.
        /// </summary>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
        /// <returns>The comparison result.</returns>
        public async Task <ComparisonResult <TItem> > CompareAsync(CancellationToken cancellationToken)
        {
            Validate();

            var comparisonResult = new ComparisonResult <TItem>();
            Dictionary <TKey, List <TItem> > dicSrc = new Dictionary <TKey, List <TItem> >()
            , dicDest = new Dictionary <TKey, List <TItem> >();

            List <TItem> nullableKeysSrcItems = new List <TItem>()
            , nullableKeysDestItems           = new List <TItem>();

            // Get entries from source and destination at the same time
            var tskSrc  = Task.Run(async() => AddItemsToDictionary(dicSrc, nullableKeysSrcItems, await SourceProvider.GetAsync(cancellationToken).ConfigureAwait(false)), cancellationToken);
            var tskDest = Task.Run(async() => AddItemsToDictionary(dicDest, nullableKeysDestItems, await DestinationProvider.GetAsync(cancellationToken).ConfigureAwait(false)), cancellationToken);

            await Task.WhenAll(tskSrc, tskDest).ConfigureAwait(false);

            Validate(dicSrc, dicDest, nullableKeysSrcItems, nullableKeysDestItems);

            // Compare items that don't have null-able keys
            foreach (var srcKey in dicSrc.Keys)
            {
                var srcItems = dicSrc[srcKey];

                if (dicDest.TryGetValue(srcKey, out var destItems))
                {
                    MatchItemsWithTheSameKey(comparisonResult, srcItems, destItems);
                }
                else
                {
                    comparisonResult.ItemsInSourceOnly.AddRange(srcItems);
                }
            }

            var remainingDestItems = dicDest.Values.SelectMany(x => x).ToArray();

            if (remainingDestItems.Any())
            {
                comparisonResult.ItemsInDestinationOnly.AddRange(remainingDestItems);
            }

            // Compare items that have null-able keys
            MatchItemsWithTheSameKey(comparisonResult, nullableKeysSrcItems, nullableKeysDestItems);

            return(comparisonResult);
        }