Example #1
0
        protected override async Task <ResultWithMetrologyProperties <Result> > DoRunAsync(Request request)
        {
            var card = await DbContext.CardsInDecks.SingleAsync(card => card.DeckId.Equals(request.DeckId) && card.CardId.Equals(request.CardId));

            var lastLearnUtcTime = runDate == null ? DateTime.UtcNow : runDate;

            if (request.TargetHeap != CardInDeck.UnknownHeap)
            {
                if (request.TargetHeap == card.CurrentHeap)
                {
                    return(new ResultWithMetrologyProperties <Result>(new Result(), ("DeckId", request.DeckId.ToString()), ("CardId", request.CardId.ToString()), ("TargetHeap", request.TargetHeap.ToString()), ("CardWasAlreadyInHeap", true.ToString()))); //This could happen due to connection problems on client side, or to multiple sessions
                }
                if (request.TargetHeap < card.CurrentHeap || request.TargetHeap - card.CurrentHeap > 1)
                {
                    throw new InvalidOperationException($"Invalid move request (request heap: {request.TargetHeap}, current heap: {card.CurrentHeap}, card: {request.CardId}, last learn UTC time: {card.LastLearnUtcTime})");
                }

                var heapingAlgorithm = await HeapingAlgorithm.OfDeckAsync(DbContext, request.DeckId);

                card.ExpiryUtcTime = heapingAlgorithm.ExpiryUtcDate(request.TargetHeap, lastLearnUtcTime.Value);

                if (request.TargetHeap > card.BiggestHeapReached)
                {
                    card.BiggestHeapReached = request.TargetHeap;
                }
            }
            else
            {
                card.ExpiryUtcTime = DateTime.MinValue.ToUniversalTime(); //Setting this is useless for normal operations, but would help detect any misuse of this field (bugs)

                if (card.CurrentHeap != CardInDeck.UnknownHeap)
                {
                    card.NbTimesInNotLearnedHeap++;
                }
            }

            card.LastLearnUtcTime = lastLearnUtcTime.Value;
            card.CurrentHeap      = request.TargetHeap;

            await DbContext.SaveChangesAsync();

            return(new ResultWithMetrologyProperties <Result>(new Result(), ("DeckId", request.DeckId.ToString()), ("CardId", request.CardId.ToString()), ("TargetHeap", request.TargetHeap.ToString()), ("CardWasAlreadyInHeap", false.ToString())));
        }
Example #2
0
        protected override async Task <ResultWithMetrologyProperties <Result> > DoRunAsync(Request request)
        {
            var heapingAlgorithm = await HeapingAlgorithm.OfDeckAsync(DbContext, request.DeckId);

            var cardsInDecks = DbContext.CardsInDecks.Where(card => card.DeckId.Equals(request.DeckId) && request.CardIds.Any(cardId => cardId == card.CardId)).ToImmutableDictionary(c => c.CardId, c => c);

            if (request.CardIds.Any(cardId => !cardsInDecks.ContainsKey(cardId)))
            {
                throw new InvalidOperationException("One card is not in the deck");
            }

            foreach (var cardInDeck in cardsInDecks.Values)
            {
                if (cardInDeck.CurrentHeap != request.TargetHeap)
                {
                    if (cardInDeck.BiggestHeapReached < request.TargetHeap)
                    {
                        cardInDeck.BiggestHeapReached = request.TargetHeap;
                    }

                    if (request.TargetHeap == CardInDeck.UnknownHeap)
                    {
                        cardInDeck.NbTimesInNotLearnedHeap++;
                        cardInDeck.ExpiryUtcTime = DateTime.MinValue.ToUniversalTime(); //Setting this is useless for normal operations, but would help detect any misuse of this field (bugs)
                    }
                    else
                    {
                        cardInDeck.ExpiryUtcTime = heapingAlgorithm.ExpiryUtcDate(request.TargetHeap, cardInDeck.LastLearnUtcTime);
                    }

                    cardInDeck.CurrentHeap = request.TargetHeap;
                }
            }

            await DbContext.SaveChangesAsync();

            return(new ResultWithMetrologyProperties <Result>(new Result(), ("DeckId", request.DeckId.ToString()), ("TargetHeap", request.TargetHeap.ToString()), ("CardCount", request.CardIds.Count().ToString())));
        }