public async Task <GenreDetail> GetAsync(string genre, PublishStatus?contentPublicationFlags = null)
        {
            PublishedStatusEnumMapper statusMapper       = new PublishedStatusEnumMapper();
            DbPublishedStatus         contentStatusFlags = statusMapper.GetAllDbFlags();

            if (contentPublicationFlags.HasValue)
            {
                contentStatusFlags = statusMapper.Map(contentPublicationFlags.Value);
            }
            var dbGenre = await _context.Genres.SingleOrDefaultAsync(x => x.Name == genre);

            if (dbGenre != null)
            {
                var numAlbums = await _context.Genres.Where(g => g.Name == genre).SelectMany(x => x.AlbumGenres).CountAsync(x => x.Album.PublishStatus == DbPublishedStatus.PUBLISHED);

                var numArtists = await _context.Genres.Where(g => g.Name == genre).SelectMany(x => x.ArtistGenres).CountAsync(x => x.Artist.PublishStatus == DbPublishedStatus.PUBLISHED);

                GenreDetail result = new GenreDetail()
                {
                    Name         = dbGenre.Name,
                    TotalAlbums  = numAlbums,
                    TotalArtists = numArtists,
                    Created      = new DateTime(dbGenre.CreatedUtc.Ticks, DateTimeKind.Utc)
                };
                return(result);
            }
            else
            {
                return(null);
            }
        }
        public async Task <ArtistList> ListAsync(int pageIndex, int pageSize, PublishStatus statusFlags = PublishStatus.PUBLISHED)
        {
            pageSize = Math.Min(pageSize, _maxPageSize);
            ArtistList result = new ArtistList()
            {
                PageIndex  = pageIndex,
                PageSize   = pageSize,
                TotalItems = 0
            };
            PublishedStatusEnumMapper statusMapper       = new PublishedStatusEnumMapper();
            DbPublishedStatus         contentStatusFlags = statusMapper.Map(statusFlags);
            var artistsQuery = this._context.Artists.AsQueryable();

            // bitwise & the status flags and check the result is not 0 to get any records matching flags
            artistsQuery = artistsQuery.Where(a => (a.PublishStatus & contentStatusFlags) != 0);

            int totalRecords = await artistsQuery.CountAsync();

            artistsQuery = artistsQuery.Skip(pageSize * pageIndex).Take(pageSize);

            var dbArtists = await artistsQuery
                            .Include(x => x.ArtistGenres)
                            .ThenInclude(x => x.Genre)
                            .ToListAsync();

            result.TotalItems = totalRecords;
            result.Items      = dbArtists.Select(a => _mapper.MapToDetailRep(a)).ToList();
            return(result);
        }
예제 #3
0
        public void MappingToDbEnum_WithMultipleFlags_HasExpectedFlags()
        {
            PublishedStatusEnumMapper mapper = new PublishedStatusEnumMapper();
            DbPublishedStatus         result = mapper.Map(PublishStatus.ARCHIVED | PublishStatus.PUBLISHED);

            Assert.True(result.HasFlag(DbPublishedStatus.ARCHIVED));
            Assert.True(result.HasFlag(DbPublishedStatus.PUBLISHED));
            Assert.False(result.HasFlag(DbPublishedStatus.UNPUBLISHED));
            Assert.False(result.HasFlag(DbPublishedStatus.DELETED));
        }
        public void MapToDetailRep_HasPublishedStatus_WithValidInput(DbPublishedStatus publishedStatusTestCase)
        {
            DbArtist sourceObj = _validDbArtist;

            sourceObj.PublishStatus = publishedStatusTestCase;
            PublishedStatusEnumMapper statusMapper = new PublishedStatusEnumMapper();
            ArtistMapper         mapper            = new ArtistMapper();
            PublishStatus        expetedStatus     = statusMapper.Map(publishedStatusTestCase);
            ArtistDetail         result            = mapper.MapToDetailRep(sourceObj);
            ICollection <string> dbGenres          = _validDbArtist.ArtistGenres.Select(x => x.Genre.Name).ToList();

            Assert.Equal(expetedStatus, result.PublishedStatus);
        }
        public async Task <ArtistDetail> AddAsync(Artist artist)
        {
            PublishedStatusEnumMapper statusMapper = new PublishedStatusEnumMapper();
            var newArtistEntity = new DbArtist()
            {
                CreatedUtc    = DateTime.Now,
                UpdatedUtc    = DateTime.Now,
                Name          = artist.Name,
                BioText       = artist.BioText,
                PublishStatus = statusMapper.Map(artist.PublishedStatus)
            };

            foreach (string genre in artist.Genres)
            {
                var dbGenre = await _context.Genres.SingleOrDefaultAsync(x => x.Name == genre);

                if (dbGenre != null)
                {
                    newArtistEntity.ArtistGenres.Add((new DbArtistGenre()
                    {
                        Genre = dbGenre
                    }));
                }
                else
                {
                    throw new RepositoryException($"The supplied genre '{genre}' does not exist.");
                }
            }
            if (artist.BioImageId.HasValue)
            {
                var img = await this._context.ImageResources.SingleOrDefaultAsync(x => x.Id == artist.BioImageId.Value);

                if (img != null)
                {
                    newArtistEntity.BioImage = img;
                }
                else
                {
                    throw new RepositoryException($"Invalid {nameof(artist.BioImageId)}, no image for ID");
                }
            }
            this._context.Artists.Add(newArtistEntity);
            await this._context.SaveChangesAsync();

            return(_mapper.MapToDetailRep(newArtistEntity));
        }
        public async Task <ICollection <ArtistNameRef> > ListNamesAsync(PublishStatus statusFlags)
        {
            PublishedStatusEnumMapper statusMapper       = new PublishedStatusEnumMapper();
            DbPublishedStatus         contentStatusFlags = statusMapper.Map(statusFlags);
            var artistsQuery = this._context.Artists.AsQueryable();

            // bitwise & the status flags and check the result is not 0 to get any records matching flags
            artistsQuery = artistsQuery.Where(a => (a.PublishStatus & contentStatusFlags) != 0);

            var result = await artistsQuery.Select(x => new ArtistNameRef {
                Id     = x.Id,
                Name   = x.Name,
                Status = statusMapper.Map(x.PublishStatus)
            }).ToListAsync();

            return(result);
        }
        /// <summary>
        /// Gets a list of albums joined against the selected group and ordered by index
        /// </summary>
        public async Task <AlbumList> ListByAlbumGroupKeyAsync(string albumGroupKey, int pageIndex, int pageSize, PublishStatus statusFlags)
        {
            pageSize = Math.Min(pageSize, _maxPageSize);
            if (pageIndex < 0)
            {
                pageIndex = 0;
            }
            PublishedStatusEnumMapper statusMapper       = new PublishedStatusEnumMapper();
            DbPublishedStatus         contentStatusFlags = statusMapper.Map(statusFlags);
            var group = await _context.AlbumGroups.SingleOrDefaultAsync(g => g.Key == albumGroupKey);

            if (group == null)
            {
                throw new EntityNotFoundRepositoryException($"Group with key {albumGroupKey} not found");
            }

            AlbumList result = new AlbumList()
            {
                PageIndex  = pageIndex,
                PageSize   = pageSize,
                TotalItems = 0
            };

            var dbItems = _context.AlbumGroups
                          .Where(g => g.Key == albumGroupKey)
                          .SelectMany(g => g.Items).OrderBy(x => x.PositionIndex)
                          .Include(x => x.Album).ThenInclude(x => x.Artist)
                          .Include(x => x.Album).ThenInclude(x => x.AlbumGenres)
                          .ThenInclude(x => x.Genre)
                          .Include(x => x.Album).ThenInclude(x => x.Tracks);

            result.TotalItems = await dbItems.CountAsync();

            var pageItems = dbItems.Skip(pageSize * pageIndex).Take(pageSize);
            var resultSet = await pageItems
                            .ToListAsync();

            result.Items = resultSet.Select(a => _mapper.MapToDetailRep(a.Album)).ToList();

            return(result);
        }
        public async Task <GenreList> ListAsync(PublishStatus?contentPublicationFlags = null)
        {
            PublishedStatusEnumMapper statusMapper       = new PublishedStatusEnumMapper();
            DbPublishedStatus         contentStatusFlags = statusMapper.GetAllDbFlags();

            if (contentPublicationFlags.HasValue)
            {
                contentStatusFlags = statusMapper.Map(contentPublicationFlags.Value);
            }
            List <GenreDetail> genres = await _context.Genres.Select(g => new GenreDetail {
                Name         = g.Name,
                Created      = new DateTime(g.CreatedUtc.Ticks, DateTimeKind.Utc),
                TotalAlbums  = g.AlbumGenres.Count(x => (x.Album.PublishStatus & contentStatusFlags) != 0),
                TotalArtists = g.ArtistGenres.Count(x => (x.Artist.PublishStatus & contentStatusFlags) != 0)
            }).ToListAsync();

            GenreList result = new GenreList()
            {
                Genres = genres
            };

            return(result);
        }
        private async Task <AlbumList> ListAsyncInternal(int pageIndex, int pageSize, PublishStatus statusFlags, Expression <Func <DbAlbum, bool> > searchExpression = null)
        {
            pageSize = Math.Min(pageSize, _maxPageSize);
            if (pageIndex < 0)
            {
                pageIndex = 0;
            }
            PublishedStatusEnumMapper statusMapper       = new PublishedStatusEnumMapper();
            DbPublishedStatus         contentStatusFlags = statusMapper.Map(statusFlags);
            AlbumList result = new AlbumList()
            {
                PageIndex  = pageIndex,
                PageSize   = pageSize,
                TotalItems = 0
            };
            var dbItems = this._context.Albums.Where(a => (a.PublishStatus & contentStatusFlags) != 0);

            // apply an optional search expression on the list query to filter it
            if (searchExpression != null)
            {
                dbItems = dbItems.Where(searchExpression);
            }

            int totalRecords = await dbItems.CountAsync();

            dbItems = dbItems.Skip(pageSize * pageIndex).Take(pageSize);
            var dbAlbums = await dbItems
                           .Include(x => x.Artist)
                           .Include(x => x.AlbumGenres)
                           .ThenInclude(x => x.Genre)
                           .Include(x => x.Tracks)
                           .ToListAsync();

            result.TotalItems = totalRecords;
            result.Items      = dbAlbums.Select(a => _mapper.MapToDetailRep(a)).ToList();
            return(result);
        }
        public async Task <AlbumDetail> UpdateAsync(int albumId, Album album)
        {
            PublishedStatusEnumMapper statusMapper = new PublishedStatusEnumMapper();
            var dbalbum = await _context.Albums
                          .Include(x => x.Artist)
                          .Include(x => x.AlbumGenres)
                          .ThenInclude(x => x.Genre)
                          .Include(x => x.Tracks)
                          .SingleOrDefaultAsync(x => x.Id == albumId);

            if (dbalbum != null)
            {
                dbalbum.Title                  = album.Title;
                dbalbum.DescriptionText        = album.DescriptionText;
                dbalbum.PublishStatus          = statusMapper.Map(album.PublishedStatus);
                dbalbum.Label                  = album.Label;
                dbalbum.Price                  = album.Price;
                dbalbum.Producer               = album.Producer;
                dbalbum.ReleaseDate            = album.ReleaseDate;
                dbalbum.TotalDurationInSeconds = album.TotalDurationInSeconds;
                dbalbum.ArtistId               = album.ArtistId;

                // remove any existing genres that are not present on input model
                _context.AlbumGenres.RemoveRange(dbalbum.AlbumGenres.Where(x => x.AlbumId == albumId && !album.Genres.Contains(x.Genre.Name)));

                // add any genreas not already in the DB relationship
                foreach (string newGenreName in album.Genres)
                {
                    if (dbalbum.AlbumGenres.FirstOrDefault(x => x.Genre.Name == newGenreName) == null)
                    {
                        var newGenreEntity = await _context.Genres.SingleOrDefaultAsync(x => x.Name == newGenreName);

                        if (newGenreEntity != null)
                        {
                            dbalbum.AlbumGenres.Add(new DbAlbumGenre()
                            {
                                Genre      = newGenreEntity,
                                CreatedUtc = DateTime.UtcNow
                            });
                        }
                        else
                        {
                            // invalid genre
                            throw new RepositoryException($"The supplied genre '{newGenreName}' does not exist.");
                        }
                    }
                }

                if (album.CoverImageId.HasValue)
                {
                    var img = await this._context.ImageResources.SingleOrDefaultAsync(x => x.Id == album.CoverImageId.Value);

                    if (img != null)
                    {
                        dbalbum.AlbumCoverImage = img;
                    }
                    else
                    {
                        throw new RepositoryException($"Invalid {nameof(album.CoverImageId)}, no image for ID");
                    }
                }
                // find any tracks with database ID's and remove anything in the database with an ID not in this list
                List <int> existingTrackIds = album.Tracks.Where(t => t.TrackId.HasValue).Select(t => t.TrackId.Value).ToList();
                _context.Tracks.RemoveRange(dbalbum.Tracks.Where(x => x.AlbumId == albumId && !existingTrackIds.Contains(x.Id)));

                // now that any existing tracks which are not in the supplied model add or update based on the presence of a trackId
                foreach (var t in album.Tracks)
                {
                    DbTrack existingTrack = null;
                    if (t.TrackId.HasValue)
                    {
                        existingTrack = await _context.Tracks.SingleOrDefaultAsync(x => x.Id == t.TrackId.Value && x.AlbumId == albumId);
                    }
                    if (existingTrack != null)
                    {
                        // update track
                        existingTrack.TrackNumber       = t.TrackNumber;
                        existingTrack.Title             = t.Title;
                        existingTrack.DurationInSeconds = t.DurationInSeconds;
                        existingTrack.UpdatedUtc        = DateTime.UtcNow;
                    }
                    else
                    {
                        //create new track
                        dbalbum.Tracks.Add(
                            new DbTrack
                        {
                            CreatedUtc        = DateTime.UtcNow,
                            DurationInSeconds = t.DurationInSeconds,
                            Title             = t.Title,
                            TrackNumber       = t.TrackNumber,
                            UpdatedUtc        = DateTime.UtcNow
                        }
                            );
                    }
                }

                await _context.SaveChangesAsync();

                return(this._mapper.MapToDetailRep(dbalbum));
            }
            else
            {
                throw new EntityNotFoundRepositoryException($"Album with ID {albumId} not found");
            }
        }
        public async Task <AlbumDetail> AddAsync(Album album)
        {
            PublishedStatusEnumMapper statusMapper = new PublishedStatusEnumMapper();
            var newEntity = new DbAlbum()
            {
                CreatedUtc             = DateTime.Now,
                UpdatedUtc             = DateTime.Now,
                Title                  = album.Title,
                DescriptionText        = album.DescriptionText,
                PublishStatus          = statusMapper.Map(album.PublishedStatus),
                Label                  = album.Label,
                Price                  = album.Price,
                Producer               = album.Producer,
                ReleaseDate            = album.ReleaseDate,
                TotalDurationInSeconds = album.TotalDurationInSeconds,
                ArtistId               = album.ArtistId
            };

            foreach (AlbumTrack t in album.Tracks)
            {
                newEntity.Tracks.Add(
                    new DbTrack
                {
                    CreatedUtc        = DateTime.UtcNow,
                    DurationInSeconds = t.DurationInSeconds,
                    Title             = t.Title,
                    TrackNumber       = t.TrackNumber,
                    UpdatedUtc        = DateTime.UtcNow
                }
                    );
            }
            foreach (string genre in album.Genres)
            {
                var dbGenre = await _context.Genres.SingleOrDefaultAsync(x => x.Name == genre);

                if (dbGenre != null)
                {
                    newEntity.AlbumGenres.Add((new DbAlbumGenre()
                    {
                        Genre = dbGenre
                    }));
                }
                else
                {
                    throw new RepositoryException($"The supplied genre '{genre}' does not exist.");
                }
            }
            if (album.CoverImageId.HasValue)
            {
                var img = await this._context.ImageResources.SingleOrDefaultAsync(x => x.Id == album.CoverImageId.Value);

                if (img != null)
                {
                    newEntity.AlbumCoverImage = img;
                }
                else
                {
                    throw new RepositoryException($"Invalid {nameof(album.CoverImageId)}, no image for ID");
                }
            }
            this._context.Albums.Add(newEntity);
            await this._context.SaveChangesAsync();

            return(_mapper.MapToDetailRep(newEntity));
        }
        public async Task <ArtistDetail> UpdateAsync(int artistId, Artist artist)
        {
            PublishedStatusEnumMapper statusMapper = new PublishedStatusEnumMapper();
            var dbartist = await _context.Artists
                           .Include(x => x.ArtistGenres)
                           .ThenInclude(x => x.Genre)
                           .SingleOrDefaultAsync(x => x.Id == artistId);

            if (dbartist != null)
            {
                dbartist.Name          = artist.Name;
                dbartist.UpdatedUtc    = DateTime.UtcNow;
                dbartist.BioText       = artist.BioText;
                dbartist.PublishStatus = statusMapper.Map(artist.PublishedStatus);
                // remove any existing genres that are not present on input model
                _context.ArtistGenres.RemoveRange(dbartist.ArtistGenres.Where(x => x.ArtistId == artistId && !artist.Genres.Contains(x.Genre.Name)));

                // add any genreas not already in the DB relationship
                foreach (string newGenreName in artist.Genres)
                {
                    if (dbartist.ArtistGenres.FirstOrDefault(x => x.Genre.Name == newGenreName) == null)
                    {
                        var newGenreEntity = await _context.Genres.SingleOrDefaultAsync(x => x.Name == newGenreName);

                        if (newGenreEntity != null)
                        {
                            dbartist.ArtistGenres.Add(new DbArtistGenre()
                            {
                                Genre      = newGenreEntity,
                                CreatedUtc = DateTime.UtcNow
                            });
                        }
                        else
                        {
                            // invalid genre
                            throw new RepositoryException($"The supplied genre '{newGenreName}' does not exist.");
                        }
                    }
                }

                if (artist.BioImageId.HasValue)
                {
                    var img = await this._context.ImageResources.SingleOrDefaultAsync(x => x.Id == artist.BioImageId.Value);

                    if (img != null)
                    {
                        dbartist.BioImage = img;
                    }
                    else
                    {
                        throw new RepositoryException($"Invalid {nameof(artist.BioImageId)}, no image for ID");
                    }
                }

                await _context.SaveChangesAsync();

                return(this._mapper.MapToDetailRep(dbartist));
            }
            else
            {
                throw new EntityNotFoundRepositoryException($"Artist with ID {artistId} not found");
            }
        }
예제 #13
0
        public void MappingFromDbEnum_ProducesSameFlagsOnOutput(DbPublishedStatus input, PublishStatus expectedOutput)
        {
            PublishedStatusEnumMapper mapper = new PublishedStatusEnumMapper();

            Assert.Equal(expectedOutput, mapper.Map(input));
        }