Example #1
0
        /// <summary>
        /// Filters set of data of type <see cref="VisitTariff"/>. Returns filtered data set. Throws an exception if <paramref name="predicate"/> is null,
        /// or if cannot filter data due to any internal problem.
        /// </summary>
        /// <typeparam name="T">The type of entity to set be filtered.</typeparam>
        /// <param name="predicate">A function to test each element for a condition.</param>
        /// <returns>Filterd <see cref="VisitTariff"/> set.</returns>
        /// <exception cref="ArgumentNullException">Argument <paramref name="predicate"/> is null.</exception>
        /// <exception cref="InvalidOperationException">Cannot filter data.</exception>
        /// <exception cref="InternalDbServiceException">The resource does not exist or has a null value or any
        /// other problems with retrieving data from database occurred.</exception>
        public async Task <IEnumerable <VisitTariff> > GetByAsync(Expression <Func <VisitTariff, bool> > predicate)
        {
            _logger.LogInformation($"Starting method '{nameof(GetByAsync)}'.");

            await EnsureDatabaseCreatedAsync();

            _ = _context?.VisitTariffs ?? throw new InternalDbServiceException($"Table of type '{typeof(VisitTariff).Name}' is null.");

            try
            {
                var result = GetByPredicate <VisitTariff>(predicate) as IEnumerable <VisitTariff>;
                _logger.LogInformation($"Finished method '{nameof(GetByAsync)}'.");
                return(result);
            }
            catch (ArgumentNullException)
            {
                _logger.LogError($"Argument '{nameof(predicate)}' cannot be null.");
                throw;
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - {ex.Message} See the exception for more details.");
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when retrieving sightseeing tariffs from database using {nameof(predicate)}. See the inner excpetion for more details.", ex);
                throw internalException;
            }
        }
        /// <summary>
        /// Asynchronously adds <see cref="SightseeingGroup"/> entity. If <paramref name="isRestrict"/> set to false then no restrictions will be used. If set to true then the restricted mode will be used.
        /// It will check if in database is entity with the same 'SightseeingDate' value.
        /// </summary>
        /// <param name="group"><see cref="SightseeingGroup"/> to be added.</param>
        /// <param name="isRestrict">If set to false then no restrictions will be used and update allow entirely entity updating. If set to true then the restricted mode will be used.
        /// It will check if in database is entity with the same 'SightseeingDate' value.</param>
        /// <returns>Added <see cref="SightseeingGroup"/> entity.</returns>
        private async Task <SightseeingGroup> AddBaseAsync(SightseeingGroup group, bool isRestrict = false)
        {
            _logger.LogDebug($"Starting method '{nameof(AddBaseAsync)}'.");

            if (group is null)
            {
                throw new ArgumentNullException($"Argument '{nameof(group)}' cannot be null.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _context?.Groups ?? throw new InternalDbServiceException($"Table of type '{typeof(SightseeingGroup).Name}' is null.");

            try
            {
                if (isRestrict)
                {
                    // Resticted add mode that use custom equality comparer. The sightseeing tariffs are equal if they have the same SightseeingDate.

                    // Check if exist in db tariff with the same 'SightseeingDate' as adding.
                    if (await IsEntityAlreadyExistsAsync(group))
                    {
                        throw new InvalidOperationException($"There is already the same element in the database as the one to be added. The value of '{nameof(group.SightseeingDate)}' is not unique.");
                    }
                }
                else
                {
                    // Normal add mode without any additional restrictions.
                    if (_context.Groups.Contains(group))
                    {
                        throw new InvalidOperationException($"There is already the same element in the database as the one to be added. Id of this element: '{group.Id}'.");
                    }
                }

                _logger.LogDebug($"Starting add sightseeing group with id '{group.Id}'.");
                var addedGroup = _context.Groups.Add(group).Entity;
                await _context.TrySaveChangesAsync();

                _logger.LogDebug("Add data succeeded.");
                _logger.LogDebug($"Finished method '{nameof(AddBaseAsync)}'.");
                return(addedGroup);
            }
            catch (DbUpdateException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - Changes made by add operations cannot be saved properly. See the inner exception for more details. Operation failed.", ex);
                var internalException = new InternalDbServiceException("Changes made by add operations cannot be saved properly. See the inner exception for more details.", ex);
                throw internalException;
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - {ex.Message}", ex);
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when adding sighseeing group with id: '{group.Id}' to the database. See the inner excpetion for more details.", ex);
                throw internalException;
            }
        }
Example #3
0
        /// <summary>
        /// Asynchronously retrieves <see cref="VisitTariff"/> entities with specified page size and page number.
        /// Throws an exception if arguments is out of range or any problem with retrieving occurred.
        /// </summary>
        /// <param name="pageNumber">Page number that will be retrieved. Must be greater than 0.</param>
        /// <param name="pageSize">Page size. Must be a positive number.</param>
        /// <returns>Set of <see cref="VisitTariff"/> entities.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="pageSize"/> is a negative number or <paramref name="pageNumber"/> is less than 1.</exception>
        /// <exception cref="InternalDbServiceException">The resource does not exist or has a null value or any
        /// other problems with retrieving data from database occurred.</exception>
        public async Task <IEnumerable <VisitTariff> > GetWithPaginationAsync(int pageNumber = 1, int pageSize = 30)
        {
            _logger.LogInformation($"Starting method '{nameof(GetWithPaginationAsync)}'.");

            if (pageNumber < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(pageNumber), $"'{pageNumber}' is not valid value for argument '{nameof(pageNumber)}'. Only number greater or equal to 1 are valid.");
            }

            if (pageSize < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(pageSize), $"'{pageSize}' is not valid value for argument '{nameof(pageSize)}'. Only number greater or equal to 0 are valid.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _context?.VisitTariffs ?? throw new InternalDbServiceException($"Table of type '{typeof(VisitTariff).Name}' is null.");

            try
            {
                IEnumerable <VisitTariff> tariffs = Enumerable.Empty <VisitTariff>();
                int maxNumberOfPageWithData;

                int numberOfResourceElements = await _context.VisitTariffs.CountAsync();

                int numberOfElementsOnLastPage = numberOfResourceElements % pageSize;
                int numberOfFullPages          = (numberOfResourceElements - numberOfElementsOnLastPage) / pageSize;

                if (numberOfElementsOnLastPage > 0)
                {
                    maxNumberOfPageWithData = ++numberOfFullPages;
                    _logger.LogWarning($"Last page of data contain {numberOfElementsOnLastPage} elements which is less than specified in '{nameof(pageSize)}': {pageSize}.");
                }
                else
                {
                    maxNumberOfPageWithData = numberOfFullPages;
                }

                if (numberOfResourceElements == 0 || pageSize == 0 || pageNumber > maxNumberOfPageWithData)
                {
                    _logger.LogInformation($"Finished method '{nameof(GetWithPaginationAsync)}'. Returning {tariffs.Count()} elements.");
                    return(tariffs);
                }

                _logger.LogDebug($"Starting retrieve data. '{nameof(pageNumber)}': {pageNumber.ToString()}, '{nameof(pageSize)}': {pageSize.ToString()}.");
                tariffs = _context.VisitTariffs.Include(x => x.TicketTariffs).Skip(pageSize * (pageNumber - 1)).Take(pageSize);
                _logger.LogDebug("Retrieve data succeeded.");
                _logger.LogInformation($"Finished method '{nameof(GetWithPaginationAsync)}'.");
                return(tariffs);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when retrieving sightseeing tariffs from database. See the inner excpetion for more details.", ex);
                throw internalException;
            }
        }
Example #4
0
 /// <summary>
 /// Asynchronously lookups if <see cref="Customer"/> with passed id exist in the database. Throws exception if resource does not exist.
 /// </summary>
 /// <param name="id"></param>
 /// <returns>True if <see cref="Customer"/> with passed id exist. Otherwise false.</returns>
 /// <exception cref="InternalDbServiceException">Resource with <see cref="Customer"/> entities does not exist.</exception>
 public async Task <bool> IsCustomerExistAsync(Customer customer)
 {
     try
     {
         return(await _context.Customers.ContainsAsync(customer));
     }
     catch (ArgumentNullException ex)
     {
         _logger.LogError($"Resource '{nameof(_context.Customers)}' does not exist.");
         var exception = new InternalDbServiceException($"Resource '{nameof(_context.Customers)}' does not exist.", ex);
         throw exception;
     }
 }
Example #5
0
        /// <summary>
        /// Asynchronously adds <see cref="Ticket"/> entity to the database. Throws an exception if
        /// already there is the same entity in database or any problem with saving changes occurred.
        /// </summary>
        /// <param name="ticket">The ticket to be added. Cannot be null.</param>
        /// <returns>The added entity.</returns>
        /// <exception cref="ArgumentNullException">The value of <paramref name="ticket"/> to be added is null.</exception>
        /// <exception cref="InvalidOperationException">There is the same entity that one to be added in the database.</exception>
        /// <exception cref="InternalDbServiceException">The table with <see cref="Ticket"/> entities does not exist or it is null or
        /// cannot save properly any changes made by add operation.</exception>
        public async Task <Ticket> AddAsync(Ticket ticket)
        {
            _logger.LogDebug($"Starting method '{nameof(AddAsync)}'.");

            if (ticket is null)
            {
                throw new ArgumentNullException($"Argument '{nameof(ticket)}' cannot be null.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _dbContext?.Tickets ?? throw new InternalDbServiceException($"Table of type '{typeof(Ticket).Name}' is null.");

            // Set TicketUniqueId for new ticket. It's set only internally.
            ticket.TicketUniqueId = Guid.NewGuid().ToString();

            try
            {
                // Only Id and TicketUniqueId cannot be the same.
                if (_dbContext.Tickets.Any(x => x.TicketUniqueId.Equals(ticket.TicketUniqueId)) || _dbContext.Tickets.Contains(ticket))
                {
                    throw new InvalidOperationException($"There is already the same element in the database as the one to be added. " +
                                                        $"{nameof(Ticket.TicketUniqueId)} of this element: '{ticket.TicketUniqueId}'.");
                }

                _logger.LogDebug($"Starting add ticket with id '{ticket.Id}'.");
                var addedTicket = _dbContext.Tickets.Add(ticket).Entity;
                await _dbContext.TrySaveChangesAsync();

                _logger.LogDebug("Add data succeeded.");
                _logger.LogDebug($"Finished method '{nameof(AddAsync)}'.");
                return(addedTicket);
            }
            catch (DbUpdateException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - Changes made by add operations cannot be saved properly. See the inner exception for more details. Operation failed.", ex);
                var internalException = new InternalDbServiceException("Changes made by add operations cannot be saved properly. See the inner exception for more details.", ex);
                throw internalException;
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - {ex.Message}", ex);
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when adding ticket ticketf with id: '{ticket.Id}' to the database. See the inner excpetion for more details.", ex);
                throw internalException;
            }
        }
Example #6
0
        /// <summary>
        /// Asynchronously deletes <see cref="RefreshToken"/> token from the database.
        /// Throws an exception if cannot found the token to be deleted or any problem with saving changes occurred.
        /// </summary>
        /// <param name="refreshToken">The refresh token to be deleted. Cannot be null.</param>
        /// <exception cref="ArgumentNullException">Argument <paramref name="refreshToken"/> is null.</exception>
        /// <exception cref="InvalidOperationException">Cannot found specified refresh token.</exception>
        /// <exception cref="InternalDbServiceException">The table with <see cref="RefreshToken"/> entities does not exist or it is null or
        /// cannot save properly any changes made by add operation.</exception>
        public async Task DeleteRefreshTokenAsync(RefreshToken refreshToken)
        {
            _logger.LogInformation($"Starting method '{nameof(DeleteRefreshTokenAsync)}'.");

            if (refreshToken is null)
            {
                throw new ArgumentNullException($"Argument '{nameof(refreshToken)}' cannot be null.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _dbContext?.RefreshTokens ?? throw new InternalDbServiceException($"Table of type '{typeof(RefreshToken).Name}' is null.");

            try
            {
                if (_dbContext.RefreshTokens.Count() == 0)
                {
                    throw new InvalidOperationException($"Cannot found refresh token with token value '{refreshToken.Token}'. Resource {_dbContext.RefreshTokens.GetType().Name} does not contain " +
                                                        $"any element.");
                }

                if (!await IsEntityAlreadyExistsAsync(refreshToken))
                {
                    throw new InvalidOperationException($"Cannot found refresh token with token value '{refreshToken.Token}'. Any element does not match to the one to be updated.");
                }

                var tokenToBeDeleted = await _dbContext.RefreshTokens.SingleAsync(x => x.Token.Equals(refreshToken.Token));

                _logger.LogDebug($"Starting remove refresh token with id '{tokenToBeDeleted.Id}'.");
                _dbContext.RefreshTokens.Remove(tokenToBeDeleted);
                await _dbContext.TrySaveChangesAsync();

                _logger.LogDebug("Remove data succeeded.");
                _logger.LogInformation($"Finished method '{nameof(DeleteRefreshTokenAsync)}'.");
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - Cannot found element. See the exception for more details. Operation failed.");
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when removing refresh token with token values '{refreshToken.Token}' from the database. " +
                                                                       $"See the inner exception for more details.", ex);
                throw internalException;
            }
        }
        /// <summary>
        /// Asynchronously adds <see cref="ActivityLog"/> entity to the database. Throws an exception if
        /// already there is the same entity in database or any problem with saving changes occurred.
        /// </summary>
        /// <param name="log">The activity log to be added. Cannot be null.</param>
        /// <returns>The added entity.</returns>
        /// <exception cref="ArgumentNullException">The value of <paramref name="log"/> to be added is null.</exception>
        /// <exception cref="InvalidOperationException">There is the same entity that one to be added in database.</exception>
        /// <exception cref="InternalDbServiceException">The table with <see cref="log"/> entities does not exist or it is null or
        /// cannot save properly any changes made by add operation.</exception>
        public async Task <ActivityLog> AddAsync(ActivityLog log)
        {
            _logger.LogInformation($"Starting method '{nameof(AddAsync)}'.");

            if (log is null)
            {
                throw new ArgumentNullException($"Argument '{nameof(log)}' cannot be null.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _dbContext?.ActivityLogs ?? throw new InternalDbServiceException($"Table of type '{typeof(ActivityLog).Name}' is null.");

            try
            {
                if (_dbContext.ActivityLogs.Contains(log))
                {
                    throw new InvalidOperationException($"There is already the same element in the database as the one to be added. Id of this element: '{log.Id}'.");
                }

                _logger.LogDebug($"Starting add activity log with id '{log.Id}'.");
                var addedlog = _dbContext.ActivityLogs.Add(log).Entity;
                await _dbContext.TrySaveChangesAsync();

                _logger.LogDebug("Add data succeeded.");
                _logger.LogInformation($"Finished method '{nameof(AddAsync)}'.");
                return(addedlog);
            }
            catch (DbUpdateException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - Changes made by add operations cannot be saved properly. See the inner exception for more details. Operation failed.", ex);
                var internalException = new InternalDbServiceException("Changes made by add operations cannot be saved properly. See the inner exception for more details.", ex);
                throw internalException;
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - {ex.Message}", ex);
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when adding an activity log with id: '{log?.Id}' to the database. See the inner excpetion for more details.", ex);
                throw internalException;
            }
        }
Example #8
0
        /// <summary>
        /// Asynchronously deletes <see cref="VisitTariff"/> entity from the database. Throws an exception if cannot found entity
        /// to be deleted or any problem with saving changes occurred.
        /// </summary>
        /// <param name="id">The id of entity to be deleted. Cannot be null or empty.</param>
        /// <exception cref="ArgumentException">Argument <paramref name="id"/> is null or empty string.</exception>
        /// <exception cref="InvalidOperationException">Cannot found entity with given <paramref name="id"/> for delete.</exception>
        /// <exception cref="InternalDbServiceException">The table with <see cref="VisitTariff"/> entities does not exist or it is null or
        /// cannot save properly any changes made by add operation.</exception>
        public async Task DeleteAsync(string id)
        {
            _logger.LogInformation($"Starting method '{nameof(DeleteAsync)}'.");

            if (string.IsNullOrEmpty(id))
            {
                throw new ArgumentException($"Argument '{nameof(id)}' cannot be null or empty.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _context?.VisitTariffs ?? throw new InternalDbServiceException($"Table of type '{typeof(VisitTariff).Name}' is null.");

            try
            {
                if (await _context.VisitTariffs.AnyAsync(x => x.Id.Equals(id)) == false)
                {
                    if (_context.VisitTariffs.Count() == 0)
                    {
                        throw new InvalidOperationException($"Cannot found element with id '{id}'. Resource {_context.VisitTariffs.GetType().Name} does not contain any element.");
                    }

                    throw new InvalidOperationException($"Cannot found element with id '{id}'. Any element does not match to the one to be updated.");
                }

                var tariffToBeDeleted = await _context.VisitTariffs.SingleAsync(x => x.Id.Equals(id));

                _logger.LogDebug($"Starting remove sightseeing tariff with id '{tariffToBeDeleted.Id}'.");
                _context.VisitTariffs.Remove(tariffToBeDeleted);
                await _context.TrySaveChangesAsync();

                _logger.LogDebug("Remove data succeeded.");
                _logger.LogInformation($"Finished method '{nameof(DeleteAsync)}'.");
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - Cannot found element. Operation failed.");
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when removing sightseeing tariff with id '{id}' from database. See the inner excpetion for more details.", ex);
                throw internalException;
            }
        }
Example #9
0
        /// <summary>
        /// Asynchronously adds <see cref="RefreshToken"/> token to the database.
        /// Throws an exception if already there is the same token in database or any problem with saving changes occurred.
        /// </summary>
        /// <param name="refreshToken">The refresh token to be added. Cannot be null.</param>
        /// <returns>The added entity.</returns>
        /// <exception cref="ArgumentNullException">The value of <paramref name="refreshToken"/> to be added is null.</exception>
        /// <exception cref="InvalidOperationException">There is the same token that one to be added in database.</exception>
        /// <exception cref="InternalDbServiceException">The table with <see cref="Article"/> entities does not exist or it is null or
        /// cannot save properly any changes made by add operation.</exception>
        public async Task AddRefreshTokenAsync(RefreshToken refreshToken)
        {
            _logger.LogInformation($"Starting method '{nameof(AddRefreshTokenAsync)}'.");

            if (refreshToken is null)
            {
                throw new ArgumentNullException($"Argument '{nameof(refreshToken)}' cannot be null.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _dbContext?.RefreshTokens ?? throw new InternalDbServiceException($"Table of type '{typeof(RefreshToken).Name}' is null.");

            try
            {
                if (await IsEntityAlreadyExistsAsync(refreshToken))
                {
                    throw new InvalidOperationException($"There is already the same token in the database as the one to be added.");
                }

                _logger.LogDebug($"Starting add refresh token with id '{refreshToken.Id}'.");
                _dbContext.RefreshTokens.Add(refreshToken);
                await _dbContext.TrySaveChangesAsync();

                _logger.LogDebug("Add data succeeded.");
                _logger.LogInformation($"Finished method '{nameof(AddRefreshTokenAsync)}'.");
            }
            catch (DbUpdateException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - Changes made by add operations cannot be saved properly. See the inner exception for more details. Operation failed.", ex);
                var internalException = new InternalDbServiceException("Changes made by add operations cannot be saved properly. See the inner exception for more details.", ex);
                throw internalException;
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - {ex.Message}", ex);
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when adding a refresh token with id: '{refreshToken?.Id}' to the database. See the inner excpetion for more details.", ex);
                throw internalException;
            }
        }
Example #10
0
        /// <summary>
        /// Asynchronously retrieves <see cref="RefreshToken"/> token saved in the database.
        /// Throws an exception if cannot found token or any problem with retrieving occurred.
        /// </summary>
        /// <param name="refreshToken">The refresh token to be retrived. Cannot be null.</param>
        /// <returns>The refresh token.</returns>
        /// <exception cref="ArgumentNullException">Argument <paramref name="refreshToken"/> is null.</exception>
        /// <exception cref="InvalidOperationException">Cannot found token.</exception>
        /// <exception cref="InternalDbServiceException">The resource does not exist or has a null value or any
        /// other problems with retrieving data from database occurred.</exception>
        public async Task <RefreshToken> GetSavedRefreshTokenAsync(string refreshToken)
        {
            _logger.LogInformation($"Starting method '{nameof(GetSavedRefreshTokenAsync)}'.");

            if (string.IsNullOrEmpty(refreshToken))
            {
                throw new ArgumentException($"Argument '{nameof(refreshToken)}' cannot be null or empty.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _dbContext?.RefreshTokens ?? throw new InternalDbServiceException($"Table of type '{typeof(RefreshToken).Name}' is null.");

            try
            {
                _logger.LogDebug($"Starting retrieve refresh token with token value: '{refreshToken}' from the database.");
                var token = await _dbContext.RefreshTokens.SingleAsync(x => x.Token.Equals(refreshToken));

                _logger.LogDebug("Retrieve data succeeded.");
                _logger.LogInformation($"Finished method '{nameof(GetSavedRefreshTokenAsync)}'.");
                return(token);
            }
            catch (InvalidOperationException ex)
            {
                string message = _dbContext.RefreshTokens.Count() == 0 ? $"Token not found because resource {_dbContext.RefreshTokens.GetType().Name} does contain any elements. " +
                                 $"See the inner exception for more details." : "Token not found. See the inner exception for more details.";
                _logger.LogError(ex, $"{ex.GetType().Name} - {message} Operation failed.");
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when retriving refresh token with token value '{refreshToken}' from the database. " +
                                                                       $"See the inner exception for more details.", ex);
                throw internalException;
            }
        }
Example #11
0
        /// <summary>
        /// Asynchronously retrievs all <see cref="Ticket"/> entities from the database.
        /// Throws an exception if any problem with retrieving occurred.
        /// </summary>
        /// <returns>Set of all <see cref="Ticket"/> entities from database.</returns>
        /// <exception cref="InternalDbServiceException">The resource does not exist or has a null value or any
        /// other problems with retrieving data from database occurred.</exception>
        public async Task <IEnumerable <Ticket> > GetAllAsync()
        {
            _logger.LogInformation($"Starting method '{nameof(GetAllAsync)}'.");

            await EnsureDatabaseCreatedAsync();

            _ = _dbContext?.Tickets ?? throw new InternalDbServiceException($"Table of type '{typeof(Ticket).Name}' is null.");

            try
            {
                _logger.LogDebug($"Starting retrieve all tickets from the database.");
                var tickets = await _dbContext.Tickets.IncludeDetails().ToArrayAsync();

                _logger.LogDebug("Retrieve data succeeded.");
                _logger.LogInformation($"Finished method '{nameof(GetAllAsync)}'. Returning {tickets.Count()} elements.");
                return(tickets.AsEnumerable());
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when retrieving all tickets from the database. See the inner exception for more details.", ex);
                throw internalException;
            }
        }
Example #12
0
        /// <summary>
        /// Asynchronously retrieves <see cref="VisitTariff"/> entity with given <paramref name="id"/> from the database.
        /// Throws an exception if cannot found entity or any problem with retrieving occurred.
        /// </summary>
        /// <param name="id">The id of entity to be retrived. Cannot be nul or empty.</param>
        /// <returns>The entity with given <paramref name="id"/>.</returns>
        /// <exception cref="ArgumentException">Argument <paramref name="id"/> is null or empty string.</exception>
        /// <exception cref="InvalidOperationException">Cannot found entity with given <paramref name="id"/>.</exception>
        /// <exception cref="InternalDbServiceException">The resource does not exist or has a null value or any
        /// other problems with retrieving data from database occurred.</exception>
        public async Task <VisitTariff> GetAsync(string id)
        {
            _logger.LogInformation($"Starting method '{nameof(GetAsync)}'.");

            if (string.IsNullOrEmpty(id))
            {
                throw new ArgumentException($"Argument '{nameof(id)}' cannot be null or empty.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _context?.VisitTariffs ?? throw new InternalDbServiceException($"Table of type '{typeof(VisitTariff).Name}' is null.");

            try
            {
                _logger.LogDebug($"Starting retrieve sighseeing tariff with id: '{id}' from database.");
                var tariff = await _context.VisitTariffs.Include(x => x.TicketTariffs).SingleAsync(x => x.Id.Equals(id));

                _logger.LogDebug("Retrieve data succeeded.");
                _logger.LogInformation($"Finished method '{nameof(GetAsync)}'.");
                return(tariff);
            }
            catch (InvalidOperationException ex)
            {
                string message = _context.VisitTariffs.Count() == 0 ? $"Element not found because resource '{_context.VisitTariffs.GetType().Name}' does contain any elements."
                    : "Element not found";
                _logger.LogError(ex, $"{ex.GetType().Name} - {message} Operation failed.");
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when retriving sighseeing tariff with id '{id}' from database. See the inner exception for more details.", ex);
                throw internalException;
            }
        }
Example #13
0
        /// <summary>
        /// Asynchronously retrievs all <see cref="VisitTariff"/> entities from the database.
        /// Throws an exception if any problem with retrieving occurred.
        /// </summary>
        /// <returns>Set of all <see cref="VisitTariff"/> entities from database.</returns>
        /// <exception cref="InternalDbServiceException">The resource does not exist or has a null value or any
        /// other problems with retrieving data from database occurred.</exception>
        public async Task <IEnumerable <VisitTariff> > GetAllAsync()
        {
            _logger.LogInformation($"Starting method '{nameof(GetAllAsync)}'.");

            await EnsureDatabaseCreatedAsync();

            _ = _context?.VisitTariffs ?? throw new InternalDbServiceException($"Table of type '{typeof(VisitTariff).Name}' is null.");

            try
            {
                _logger.LogDebug($"Starting retrieve all sightseeing tariffs from database.");
                var tariffs = await _context.VisitTariffs.Include(x => x.TicketTariffs).ToArrayAsync();

                _logger.LogDebug("Retrieve data succeeded.");
                _logger.LogInformation($"Finished method '{nameof(GetAllAsync)}'. Returning '{tariffs.Count()}' elements.");
                return(tariffs.AsEnumerable());
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when retrieving all sightseeing tariffs from database. See inner excpetion for more details.", ex);
                throw internalException;
            }
        }
Example #14
0
        /// <summary>
        /// Asynchronously adds <see cref="Article"/> entity. If <paramref name="isRestrict"/> set to false then no restrictions will be used. If set to true then the restricted mode will be used.
        /// It will check if in database is entity with the same 'Title', 'Text' and 'Author' value.
        /// </summary>
        /// <param name="article"><see cref="Article"/> to be added.</param>
        /// <param name="isRestrict">If set to false then no restrictions will be used and update allow entirely entity updating. If set to true then the restricted mode will be used.
        /// It will check if in database is entity with the same 'Title', 'Text' and 'Author' value.</param>
        /// <returns>Added <see cref="Article"/> entity.</returns>
        private async Task <Article> AddBaseAsync(Article article, bool isRestrict = false)
        {
            _logger.LogInformation($"Starting method '{nameof(AddBaseAsync)}'.");

            if (article is null)
            {
                throw new ArgumentNullException($"Argument '{nameof(article)}' cannot be null.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _context?.Articles ?? throw new InternalDbServiceException($"Table of type '{typeof(Article).Name}' is null.");

            try
            {
                if (isRestrict)
                {
                    // Resticted add mode that use custom equality comparer. Articles are equal if they have the same Title, Text and Author.

                    // Check if exist in db article with the same Title, Text and Author as adding.
                    if (await IsEntityAlreadyExistsAsync(article))
                    {
                        throw new InvalidOperationException($"There is already the same element in the database as the one to be added. The value of '{nameof(article.Title)}', " +
                                                            $"'{nameof(article.Text)}' and '{nameof(article.Author)}' are not unique.");
                    }
                }
                else
                {
                    // Normal add mode without any additional restrictions.
                    if (_context.Articles.Contains(article))
                    {
                        throw new InvalidOperationException($"There is already the same element in the database as the one to be added. Id of this element: '{article.Id}'.");
                    }
                }

                _logger.LogDebug($"Starting add tariff with id '{article.Id}'.");
                var addedArticle = _context.Articles.Add(article).Entity;
                await _context.TrySaveChangesAsync();

                _logger.LogDebug("Add data succeeded.");
                _logger.LogInformation($"Finished method '{nameof(AddBaseAsync)}'.");
                return(addedArticle);
            }
            catch (DbUpdateException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - Changes made by add operations cannot be saved properly. See the inner exception for more details. Operation failed.", ex);
                var internalException = new InternalDbServiceException("Changes made by add operations cannot be saved properly. See the inner exception for more details.", ex);
                throw internalException;
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - {ex.Message}", ex);
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when adding an article with id: '{article?.Id}' to the database. See the inner excpetion for more details.", ex);
                throw internalException;
            }
        }
Example #15
0
        /// <summary>
        /// Asynchronously adds <see cref="VisitTariff"/> entity. If <paramref name="isRestrict"/> set to false then no restrictions will be used. If set to true then the restricted mode will be used.
        /// It will check if in database is entity with the same 'Name' value. Moreover it will does not allow to add navigation property while adding <see cref="VisitTariff"/>.
        /// </summary>
        /// <param name="tariff"><see cref="VisitTariff"/> to be added.</param>
        /// <param name="isRestrict">If set to false then no restrictions will be used and update allow entirely entity updating. If set to true then the restricted mode will be used.
        /// It will check if in database is entity with the same 'Name' value. Moreover it will does not allow to add navigation property while adding <see cref="VisitTariff"/>.</param>
        /// <returns>Added <see cref="VisitTariff"/> entity.</returns>
        private async Task <VisitTariff> AddBaseAsync(VisitTariff tariff, bool isRestrict = false)
        {
            _logger.LogDebug($"Starting method '{nameof(AddBaseAsync)}'.");

            if (tariff is null)
            {
                throw new ArgumentNullException($"Argument '{nameof(tariff)}' cannot be null.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _context?.VisitTariffs ?? throw new InternalDbServiceException($"Table of type '{typeof(VisitTariff).Name}' is null.");

            try
            {
                if (isRestrict)
                {
                    // Resticted add mode that use custom equality comparer. The sightseeing tariffs are equal if they have the same Name.
                    // Moreover this mode does not allow adding navigation property togather with parent entity (SightseeinTariff -> TicketTariffs).
                    tariff.TicketTariffs = null;

                    // Check if exist in db tariff with the same 'Name' as adding.
                    if (await IsEntityAlreadyExistsAsync(tariff))
                    {
                        throw new InvalidOperationException($"There is already the same element in the database as the one to be added. The value of '{nameof(tariff.Name)}' is not unique.");
                    }
                }
                else
                {
                    // Normal add mode without any additional restrictions.
                    if (_context.VisitTariffs.Contains(tariff))
                    {
                        throw new InvalidOperationException($"There is already the same element in the database as the one to be added. Id of this element: '{tariff.Id}'.");
                    }
                }

                _logger.LogDebug($"Starting add tariff with id '{tariff.Id}'.");
                var addedTariff = _context.VisitTariffs.Add(tariff).Entity;
                await _context.TrySaveChangesAsync();

                _logger.LogDebug("Add data succeeded.");
                _logger.LogDebug($"Finished method '{nameof(AddBaseAsync)}'.");
                return(addedTariff);
            }
            catch (DbUpdateException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - Changes made by add operations cannot be saved properly. See the inner exception for more details. Operation failed.", ex);
                var internalException = new InternalDbServiceException("Changes made by add operations cannot be saved properly. See the inner exception for more details.", ex);
                throw internalException;
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - {ex.Message}", ex);
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when adding sighseeing tarifff to the database. See the inner excpetion for more details.", ex);
                throw internalException;
            }
        }
Example #16
0
        /// <summary>
        /// Asynchronously updates <see cref="VisitTariff"/> entity. If <paramref name="isRestrict"/> set to false then no restrictions will be used and update allow entirely entity updating.
        /// Otherwise the restricted mode will be using. It will ignore updating some read-only properties.
        /// </summary>
        /// <param name="tariff">VisitTariff To be updated</param>
        /// <param name="isRestrict">If set to false then no restrictions will be used and update allow entirely entity updating. If set to true then the restricted mode will be used.
        /// It will ignore some read-only properties changes.</param>
        /// <returns>Updated <see cref="VisitTariff"/> entity.</returns>
        private async Task <VisitTariff> UpdateBaseAsync(VisitTariff tariff, bool isRestrict = false)
        {
            _logger.LogDebug($"Starting method '{nameof(UpdateBaseAsync)}'.");

            _ = tariff ?? throw new ArgumentNullException(nameof(tariff), $"Argument '{nameof(tariff)}' cannot be null.");

            if (string.IsNullOrEmpty(tariff.Id))
            {
                throw new ArgumentException($"Argument '{nameof(tariff.Id)}' cannot be null or empty.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _context?.VisitTariffs ?? throw new InternalDbServiceException($"Table of type '{typeof(VisitTariff).Name}' is null.");

            try
            {
                if (_context.VisitTariffs.Count() == 0)
                {
                    throw new InvalidOperationException($"Cannot found element with id '{tariff.Id}' for update. Resource {_context.Groups.GetType().Name} does not contain any element.");
                }

                if (await _context.VisitTariffs.ContainsAsync(tariff) == false)
                {
                    throw new InvalidOperationException($"Cannot found element with id '{tariff.Id}' for update. Any element does not match to the one to be updated.");
                }

                _logger.LogDebug($"Starting update tariff with id '{tariff.Id}'.");

                VisitTariff updatedTariff = null;
                tariff.UpdatedAt = DateTime.UtcNow;

                if (isRestrict)
                {
                    // Resticted update mode that ignores all changes in read-only properties like Id, CreatedAt, UpdatedAt, ConcurrencyToken and navigation properties like TicketTariffs.
                    var originalTariff = await _context.VisitTariffs.SingleAsync(x => x.Id.Equals(tariff.Id));

                    // Set the TicketTariffs navigation property to the original value, because restricted update mode does not allow updating of TicketTariffs.
                    // For any changes from the client in TicketTariff objects, use the TicketTairiffsController methods.
                    tariff.TicketTariffs = originalTariff.TicketTariffs;

                    updatedTariff = BasicRestrictedUpdate(originalTariff, tariff) as VisitTariff;
                }
                else
                {
                    // Normal update mode without any additional restrictions.
                    updatedTariff = _context.VisitTariffs.Update(tariff).Entity;
                }

                await _context.TrySaveChangesAsync();

                _logger.LogDebug($"Update data succeeded.");
                _logger.LogDebug($"Finished method '{nameof(UpdateBaseAsync)}'.");
                return(updatedTariff);
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} Cannot found element for update. See exception for more details. Operation failed.");
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when updating sighseeing tariff with id '{tariff.Id}'. See inner excpetion for more details.", ex);
                throw internalException;
            }
        }
Example #17
0
        /// <summary>
        /// Asynchronously updates <see cref="VisitInfo"/> entity. If <paramref name="isRestrict"/> set to false then no restrictions will be used and update allow entirely entity updating.
        /// Otherwise the restricted mode will be using. It will ignore updating some read-only properties.
        /// </summary>
        /// <param name="info"><see cref="VisitInfo"/> to be updated.</param>
        /// <param name="isRestrict">If set to false then no restrictions will be used and update allow entirely entity updating. If set to true then the restricted mode will be used.
        /// It will ignore some read-only properties changes.</param>
        /// <returns>Updated <see cref="Customer"/> entity.</returns>
        private async Task <VisitInfo> UpdateBaseAsync(VisitInfo info, bool isRestrict = false)
        {
            _logger.LogDebug($"Starting method '{nameof(UpdateBaseAsync)}'.");

            _ = info ?? throw new ArgumentNullException(nameof(info), $"Argument '{nameof(info)}' cannot be null.");

            if (string.IsNullOrEmpty(info.Id))
            {
                throw new ArgumentException($"Argument '{nameof(info.Id)}' cannot be null or empty.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _context?.Info ?? throw new InternalDbServiceException($"Table of type '{typeof(VisitInfo).Name}' is null.");

            try
            {
                if (_context.Info.Count() == 0)
                {
                    throw new InvalidOperationException($"Cannot found element with id '{info.Id}' for update. Resource {_context.Info.GetType().Name} does not contain any element.");
                }

                if (await _context.Info.ContainsAsync(info) == false)
                {
                    throw new InvalidOperationException($"Cannot found element with id '{info.Id}' for update. Any element does not match to the one to be updated.");
                }

                _logger.LogDebug($"Starting update customer with id '{info.Id}'.");

                VisitInfo updatedInfo = null;
                info.UpdatedAt = DateTime.UtcNow;

                if (isRestrict)
                {
                    // Restricted update mode that ignores all changes in read-only properties like Id, CreatedAt, UpdatedAt, ConcurrencyToken.
                    var originalInfo = await _context.Info.Include(x => x.OpeningHours).SingleAsync(x => x.Id.Equals(info.Id));

                    updatedInfo = BasicRestrictedUpdate(originalInfo, info) as VisitInfo;
                }
                else
                {
                    // Normal update mode without any additional restrictions.
                    updatedInfo = _context.Info.Update(info).Entity;
                }

                await _context.TrySaveChangesAsync();

                _logger.LogDebug($"Update data succeeded.");
                _logger.LogDebug($"Finished method '{nameof(UpdateBaseAsync)}'.");
                return(updatedInfo);
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - Cannot found element for update. See exception for more details. Operation failed.");
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when updating general sightseing info with id '{info.Id}'. See the inner exception for more details.", ex);
                throw internalException;
            }
        }
Example #18
0
        /// <summary>
        /// Asynchronously adds <see cref="VisitInfo"/> entity. If <paramref name="isRestrict"/> set to false then no restrictions will be used. If set to true then the restricted mode will be used.
        /// It will check if in database is entity with the same Description, OpeningHour, MaxAllowedGroupSize and MaxChildAge values.
        /// </summary>
        /// <param name="info"><see cref="VisitInfo"/> to be added.</param>
        /// <param name="isRestrict">If set to false then no restrictions will be used and update allow entirely entity updating. If set to true then the restricted mode will be used.
        /// It will check if in database is entity with the same Description, OpeningHour, MaxAllowedGroupSize and MaxChildAge values. </param>
        /// <returns>Added <see cref="VisitInfo"/> entity.</returns>
        private async Task <VisitInfo> AddBaseAsync(VisitInfo info, bool isRestrict = false)
        {
            _logger.LogDebug($"Starting method '{nameof(AddBaseAsync)}'.");

            if (info is null)
            {
                throw new ArgumentNullException($"Argument '{nameof(info)}' cannot be null.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _context?.Info ?? throw new InternalDbServiceException($"Table of type '{typeof(VisitInfo).Name}' is null.");

            try
            {
                if (isRestrict)
                {
                    // Restricted add mode that use custom equality comparer. Discounts are equal if they have the same Description, DiscountValueInPercentage, GroupSizeForDiscount and Type.

                    // Check if exist in db disount with the same properties as adding.
                    if (await IsEntityAlreadyExistsAsync(info))
                    {
                        throw new InvalidOperationException($"There is already the same element in the database as the one to be added. " +
                                                            $"The value of '{nameof(info.Description)}', '{nameof(info.MaxChildAge)}', '{nameof(info.OpeningHours)}'" +
                                                            $"'{nameof(info.MaxAllowedGroupSize)}' are not unique.");
                    }
                }
                else
                {
                    // Normal add mode without any additional restrictions.
                    if (_context.Info.Contains(info))
                    {
                        throw new InvalidOperationException($"There is already the same element in the database as the one to be added. Id of this element: '{info.Id}'.");
                    }
                }

                _logger.LogDebug($"Starting add general sightseeing info with id '{info.Id}'.");
                var addedInfo = _context.Info.Add(info).Entity;
                await _context.TrySaveChangesAsync();

                _logger.LogDebug("Add data succeeded.");
                _logger.LogInformation($"Finished method '{nameof(AddAsync)}'.");
                return(addedInfo);
            }
            catch (DbUpdateException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - Changes made by add operations cannot be saved properly. See the inner exception for more details. Operation failed.", ex);
                var internalException = new InternalDbServiceException("Changes made by add operations cannot be saved properly. See the inner exception for more details.", ex);
                throw internalException;
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError($"{ex.GetType().Name} - There is already the same element in the database as the one to be added. Id of this element: '{info.Id}'.", ex);
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when adding disount with id '{info.Id}' to database. See the inner exception for more details.", ex);
                throw internalException;
            }
        }
Example #19
0
        /// <summary>
        /// Asynchronously updates <see cref="Article"/> entity. If <paramref name="isRestrict"/> set to false then no restrictions will be used and update allow entirely entity updating.
        /// Otherwise the restricted mode will be using. It will ignore updating some read-only properties.
        /// </summary>
        /// <param name="article"><see cref="Article"/> to be updated.</param>
        /// <param name="isRestrict">If set to false then no restrictions will be used and update allow entirely entity updating. If set to true then the restricted mode will be used.
        /// It will ignore some read-only properties changes.</param>
        /// <returns>Updated <see cref="Article"/> entity.</returns>
        private async Task <Article> UpdateBaseAsync(Article article, bool isRestrict = false)
        {
            _logger.LogDebug($"Starting method '{nameof(UpdateBaseAsync)}'.");

            _ = article ?? throw new ArgumentNullException(nameof(article), $"Argument '{nameof(article)}' cannot be null.");

            if (string.IsNullOrEmpty(article.Id))
            {
                throw new ArgumentException($"Argument '{nameof(article.Id)}' cannot be null or empty.");
            }

            await EnsureDatabaseCreatedAsync();

            _ = _context?.Articles ?? throw new InternalDbServiceException($"Table of type '{typeof(Article).Name}' is null.");

            try
            {
                if (_context.Articles.Count() == 0)
                {
                    throw new InvalidOperationException($"Cannot found element with id '{article.Id}' for update. Resource {_context.Articles.GetType().Name} does not contain any element.");
                }

                if (await _context.Articles.ContainsAsync(article) == false)
                {
                    throw new InvalidOperationException($"Cannot found element with id '{article.Id}' for update. Any element does not match to the one to be updated.");
                }

                _logger.LogDebug($"Starting update article with id '{article.Id}'.");

                Article updatedArticle = null;
                article.UpdatedAt = DateTime.UtcNow;

                if (isRestrict)
                {
                    // Resticted update mode that ignores all changes in read-only properties like Id, CreatedAt, UpdatedAt, ConcurrencyToken.
                    var originalArticle = await _context.Articles.SingleAsync(x => x.Id.Equals(article.Id));

                    updatedArticle = BasicRestrictedUpdate(originalArticle, article) as Article;
                }
                else
                {
                    // Normal update mode without any additional restrictions.
                    updatedArticle = _context.Articles.Update(article).Entity;
                }

                await _context.TrySaveChangesAsync();

                _logger.LogDebug($"Update data succeeded.");
                _logger.LogDebug($"Finished method '{nameof(UpdateBaseAsync)}'.");
                return(updatedArticle);
            }
            catch (InvalidOperationException ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} Cannot found element for update. See exception for more details. Operation failed.");
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{ex.GetType().Name} - {ex.Message}");
                var internalException = new InternalDbServiceException($"Encountered problem when updating article with id '{article.Id}'. See inner excpetion for more details.", ex);
                throw internalException;
            }
        }