public Task AddResultAsync(IPostBasket <Types.MatingEvent, string> basket, IVisit visit)
        {
            // get what we need out of the basket so that a response can be generated
            var male   = basket.DescentPayload.Male;
            var female = basket.DescentPayload.Female;
            var date   = basket.DescentPayload.Date;

            // we're going to patch the male and female, so there is a record of them mating
            var modifiedProps = new Dictionary <string, object> {
                { nameof(Types.Frog.DateLastMated), date }
            };

            var patchMaleBasket = new PatchBasket <int, Types.Frog, int>(
                new PatchRequest <int, Types.Frog>(new Delta <int, Types.Frog>(male.Id, modifiedProps)), basket);

            var patchFemaleBaset = new PatchBasket <int, Types.Frog, int>(
                new PatchRequest <int, Types.Frog>(new Delta <int, Types.Frog>(female.Id, modifiedProps)), basket);

            // generate some children for the male and female
            var tadpoleBaskets = GenerateTadpoles(basket, female, male, date);

            Task.WaitAll(_frogMine.SendAsync(patchMaleBasket), _frogMine.SendAsync(patchFemaleBaset));

            var tadpoleCount = tadpoleBaskets.Select(t => t.AscentPayload).Count();

            // the result of this operation is a string
            basket.AscentPayload = $"[{date:d}] {male.Name} and {female.Name} had {tadpoleCount} children";

            return(Task.CompletedTask);
        }
示例#2
0
        /// <summary>
        /// After a "Post" request has been processed and the response basket has ascended to here
        /// any cached collection which is now invalid (i.e. does not contain the object but now should)
        /// is removed from the cache
        /// </summary>
        /// <param name="basket">The response</param>
        /// <param name="visit">The visit the basket is currently making</param>
        /// <returns>A Task that may be awaited</returns>
        public Task AscendFromAsync(IPostBasket <T, TId> basket, IVisit visit)
        {
            // always remove items from cache on way back up, otherwise another thread
            // may repopulate the cache before the decent is complete
            Cache.RemoveCollection();

            return(Task.CompletedTask);
        }
示例#3
0
        /// <summary>
        /// Inserts the requested T into the database and sets the baskets AscentPayload to new records identity
        /// </summary>
        /// <param name="basket">A basket</param>
        /// <param name="visit">The visit the basket is currently making</param>
        /// <returns>A Task that may be awaited</returns>
        public async Task AddResultAsync(IPostBasket <T, TId> basket, IVisit visit)
        {
            if (basket == null)
            {
                throw new ArgumentNullException(nameof(basket));
            }

            var statement = GetInsertDbStatement(basket.DescentPayload);

            visit.Log(statement.ToString());

            var id = await DbInterface.ExecuteScalarAsync(statement).ConfigureAwait(false);

            basket.AscentPayload = Descriptor.ProjectColumnValue <TId>(id);
        }
示例#4
0
        public Task AscendFromAsync(IPostBasket <Types.MatingEvent, string> basket, IVisit visit)
        {
            // grab baskets on the way up and translate their contents
            var message = basket.AscentPayload;

            if (!string.IsNullOrWhiteSpace(message))
            {
                message = message
                          .Replace("and", "y")
                          .Replace("had", "tienen")
                          .Replace("children", "niños");

                basket.AscentPayload = message;
            }

            return(Task.CompletedTask);
        }
示例#5
0
        public Task <IPostBasket <Types.MatingEvent, string> > SendAsync(IPostBasket <Types.MatingEvent, string> basket)
        {
            var shaft = new Shaft <IPostBasket <Types.MatingEvent, string> >(TraceExporter, TerminalLayer,
                                                                             GetStations <IPostBasket <Types.MatingEvent, string> >());

            // Here, based on some "configuration" were injecting functionality into the shaft.
            // The station that is added will be the lowest station in the shaft (but above the terminal),
            // i.e. it will be below the stations from the security layer which was added in the base AppMine
            // class
            if (Language == Languages.Spanish)
            {
                shaft.Add(new SpanishTranslationStation());
            }
            else if (Language == Languages.French)
            {
                shaft.Add(new FrenchTranslationStation());
            }

            return(shaft.SendAsync(basket));
        }
        public async Task AddResultAsync(IPostBasket <Types.MaturationEvent, int> basket, IVisit visit)
        {
            var date   = basket.DescentPayload.Date;
            var filter = new Filter <Types.Tadpole>(new[]
            {
                new FilterTerm(nameof(Types.Tadpole.DateOfBirth), FilterOperators.LessThanOrEqual, date.AddMonths(-2))
            });

            // get all tadpoles who are of a certain age - see filter above
            var getTadpolesBasket =
                new GetCollectionBasket <Types.Tadpole>(new GetCollectionRequest <Types.Tadpole>(filter));

            await _tadpoleMine.SendAsync(getTadpolesBasket).ConfigureAwait(false);

            var tadpoles = getTadpolesBasket.AscentPayload;

            if (tadpoles.Length > 0)
            {
                // covert the retrieved tadpoles into frogs...
                foreach (var tadpole in tadpoles)
                {
                    var frog = tadpole.ToFrog();
                    using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                    {
                        // ... create frog
                        var postFrogBasket = new PostBasket <Types.Frog, int>(frog);
                        var postFrogTask   = _frogMine.SendAsync(postFrogBasket);

                        // ...and get rid of the tapole which has now become a frog
                        var deleteTadpoleBasket = new DeleteBasket <int, Types.Tadpole, int>(tadpole.Id);
                        var deleteTadpoleTask   = _tadpoleMine.SendAsync(deleteTadpoleBasket);

                        Task.WaitAll(postFrogTask, deleteTadpoleTask);

                        scope.Complete();
                    }
                }
            }

            basket.AscentPayload = tadpoles.Length;
        }
        private IPostBasket <Types.Tadpole, int>[] GenerateTadpoles(IBasket parent,
                                                                    Types.Frog mother, Types.Frog father, DateTime date)
        {
            var tadpoleCount = 10;
            var tasks        = new Task[tadpoleCount];
            var baskets      = new IPostBasket <Types.Tadpole, int> [tadpoleCount];

            // generate 10 tadpoles for the mother and father
            var surname = $"{father.Id}-{mother.Id}";
            var eventNo = 1;

            // this is just something to ensure the child has a unique name - it's not important to understand
            if (FamilyEventsEvents.ContainsKey(surname))
            {
                eventNo = FamilyEventsEvents[surname] + 1;
            }

            for (var i = 0; i < tadpoleCount; i++)
            {
                var tadpole = new Types.Tadpole
                {
                    DateOfBirth   = date.AddDays(i),
                    MotherId      = mother.Id,
                    FatherId      = father.Id,
                    LivesInPondId = mother.LivesInPondId,
                    IsMale        = i % 2 == 0,
                    Name          = (i % 2 == 0 ? "M" : "F") + $"{i}:{eventNo}:{surname}"
                };

                var postBasket = new PostBasket <Types.Tadpole, int>(tadpole, parent);

                tasks[i]   = _tadpoleMine.SendAsync(postBasket);
                baskets[i] = postBasket;
            }

            FamilyEventsEvents[surname] = eventNo;

            Task.WaitAll(tasks);
            return(baskets);
        }
示例#8
0
 public Task DescendToAsync(IPostBasket <Types.MatingEvent, string> basket, IVisit visit)
 {
     // just let baskets pass through on the way down
     return(Task.CompletedTask);
 }
示例#9
0
 /// <summary>
 /// No action is performed
 /// </summary>
 /// <param name="basket">The request</param>
 /// <param name="visit">The visit the basket is currently making</param>
 /// <returns>A Task that may be awaited</returns>
 public Task DescendToAsync(IPostBasket <T, TId> basket, IVisit visit)
 {
     return(Task.CompletedTask);
 }
示例#10
0
 public Task <IPostBasket <Types.MaturationEvent, int> > SendAsync(IPostBasket <Types.MaturationEvent, int> basket)
 {
     return(new Shaft <IPostBasket <Types.MaturationEvent, int> >(TraceExporter, TerminalLayer,
                                                                  GetStations <IPostBasket <Types.MaturationEvent, int> >()).SendAsync(basket));
 }
示例#11
0
        public Task AddResultAsync(IPostBasket <Frog, int> basket, IVisit visit)
        {
            basket.AscentPayload = 8;

            return(Task.CompletedTask);
        }
示例#12
0
 public Task <IPostBasket <T, TId> > SendAsync(IPostBasket <T, TId> basket)
 {
     return(new Shaft <IPostBasket <T, TId> >(TraceExporter, TerminalLayer, GetStations <IPostBasket <T, TId> >())
            .SendAsync(basket));
 }
示例#13
0
 public Task <IPostBasket <Frog, int> > SendAsync(IPostBasket <Frog, int> basket)
 {
     return(new Shaft <IPostBasket <Frog, int> >(TerminalLayer)
            .Add(CacheLayer)
            .SendAsync(basket));
 }
示例#14
0
 /// <summary>
 /// Performs no action
 /// </summary>
 /// <param name="basket">A basket</param>
 /// <param name="visit">The visit the basket is currently making</param>
 /// <returns>A Task that may be awaited</returns>
 public Task AscendFromAsync(IPostBasket basket, IVisit visit)
 {
     return(Task.CompletedTask);
 }
示例#15
0
 /// <summary>
 /// If the user is not allowed to "Post" T's then an UnauthorizedAccessException will be thrown.
 /// </summary>
 /// <param name="basket">The request</param>
 /// <param name="visit">The visit the basket is currently making</param>
 /// <returns>A Task that may be awaited</returns>
 public Task DescendToAsync(IPostBasket basket, IVisit visit)
 {
     EnsureOperationAllowed(Operations.Post, basket, visit);
     return(Task.CompletedTask);
 }