Fixed: Faster artist endpoint (#874)

* Fixed: Speed up AllArtist API endpoint

* New: Display UI before artists have loaded

* Add test of new repository methods
This commit is contained in:
ta264 2019-08-17 08:04:59 +01:00 committed by GitHub
commit 0352f8d3ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 158 additions and 31 deletions

View file

@ -184,11 +184,13 @@ namespace Lidarr.Api.V1.Artist
private void LinkNextPreviousAlbums(params ArtistResource[] artists)
{
var nextAlbums = _albumService.GetNextAlbumsByArtistMetadataId(artists.Select(x => x.ArtistMetadataId));
var lastAlbums = _albumService.GetLastAlbumsByArtistMetadataId(artists.Select(x => x.ArtistMetadataId));
foreach (var artistResource in artists)
{
var artistAlbums = _albumService.GetAlbumsByArtist(artistResource.Id).OrderBy(s=>s.ReleaseDate);
artistResource.NextAlbum = artistAlbums.Where(s => s.ReleaseDate >= DateTime.UtcNow && s.Monitored).FirstOrDefault();
artistResource.LastAlbum = artistAlbums.Where(s => s.ReleaseDate <= DateTime.UtcNow && s.Monitored).LastOrDefault();
artistResource.NextAlbum = nextAlbums.FirstOrDefault(x => x.ArtistMetadataId == artistResource.ArtistMetadataId);
artistResource.LastAlbum = lastAlbums.FirstOrDefault(x => x.ArtistMetadataId == artistResource.ArtistMetadataId);
}
}

View file

@ -5,6 +5,7 @@ using NzbDrone.Common.Extensions;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Music;
using Lidarr.Http.REST;
using Newtonsoft.Json;
namespace Lidarr.Api.V1.Artist
{
@ -14,6 +15,8 @@ namespace Lidarr.Api.V1.Artist
//Todo: Is there an easy way to keep IgnoreArticlesWhenSorting in sync between, Series, History, Missing?
//Todo: We should get the entire Profile instead of ID and Name separately
[JsonIgnore]
public int ArtistMetadataId { get; set; }
public ArtistStatusType Status { get; set; }
public bool Ended => Status == ArtistStatusType.Ended;
@ -70,6 +73,7 @@ namespace Lidarr.Api.V1.Artist
return new ArtistResource
{
Id = model.Id,
ArtistMetadataId = model.ArtistMetadataId,
ArtistName = model.Name,
//AlternateTitles

View file

@ -3,7 +3,9 @@ using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Music;
using NzbDrone.Core.Test.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
namespace NzbDrone.Core.Test.MusicTests.AlbumRepositoryTests
{
@ -13,6 +15,7 @@ namespace NzbDrone.Core.Test.MusicTests.AlbumRepositoryTests
private Artist _artist;
private Album _album;
private Album _albumSpecial;
private List<Album> _albums;
private AlbumRelease _release;
private AlbumRepository _albumRepo;
private ReleaseRepository _releaseRepo;
@ -150,5 +153,47 @@ namespace NzbDrone.Core.Test.MusicTests.AlbumRepositoryTests
album.Should().BeNull();
}
private void GivenMultipleAlbums()
{
_albums = Builder<Album>.CreateListOfSize(4)
.All()
.With(x => x.Id = 0)
.With(x => x.Artist = _artist)
.With(x => x.ArtistMetadataId = _artist.ArtistMetadataId)
.TheFirst(1)
// next
.With(x => x.ReleaseDate = DateTime.UtcNow.AddDays(1))
.TheNext(1)
// another future one
.With(x => x.ReleaseDate = DateTime.UtcNow.AddDays(2))
.TheNext(1)
// most recent
.With(x => x.ReleaseDate = DateTime.UtcNow.AddDays(-1))
.TheNext(1)
// an older one
.With(x => x.ReleaseDate = DateTime.UtcNow.AddDays(-2))
.BuildList();
_albumRepo.InsertMany(_albums);
}
[Test]
public void get_next_albums_should_return_next_album()
{
GivenMultipleAlbums();
var result = _albumRepo.GetNextAlbums(new [] { _artist.ArtistMetadataId });
result.Should().BeEquivalentTo(_albums.Take(1));
}
[Test]
public void get_last_albums_should_return_next_album()
{
GivenMultipleAlbums();
var result = _albumRepo.GetLastAlbums(new [] { _artist.ArtistMetadataId });
result.Should().BeEquivalentTo(_albums.Skip(2).Take(1));
}
}
}

View file

@ -58,7 +58,7 @@ namespace NzbDrone.Core.Datastore
public IEnumerable<TModel> All()
{
return DataMapper.Query<TModel>().ToList();
return Query.ToList();
}
public int Count()

View file

@ -14,6 +14,8 @@ namespace NzbDrone.Core.Music
public interface IAlbumRepository : IBasicRepository<Album>
{
List<Album> GetAlbums(int artistId);
List<Album> GetLastAlbums(IEnumerable<int> artistMetadataIds);
List<Album> GetNextAlbums(IEnumerable<int> artistMetadataIds);
List<Album> GetAlbumsByArtistMetadataId(int artistMetadataId);
List<Album> GetAlbumsForRefresh(int artistId, IEnumerable<string> foreignIds);
Album FindByTitle(int artistMetadataId, string title);
@ -47,6 +49,32 @@ namespace NzbDrone.Core.Music
.Where<Artist>(a => a.Id == artistId).ToList();
}
public List<Album> GetLastAlbums(IEnumerable<int> artistMetadataIds)
{
string query = string.Format("SELECT Albums.* " +
"FROM Albums " +
"WHERE Albums.ArtistMetadataId IN ({0}) " +
"AND Albums.ReleaseDate < datetime('now') " +
"GROUP BY Albums.ArtistMetadataId " +
"HAVING Albums.ReleaseDate = MAX(Albums.ReleaseDate)",
string.Join(", ", artistMetadataIds));
return Query.QueryText(query);
}
public List<Album> GetNextAlbums(IEnumerable<int> artistMetadataIds)
{
string query = string.Format("SELECT Albums.* " +
"FROM Albums " +
"WHERE Albums.ArtistMetadataId IN ({0}) " +
"AND Albums.ReleaseDate > datetime('now') " +
"GROUP BY Albums.ArtistMetadataId " +
"HAVING Albums.ReleaseDate = MIN(Albums.ReleaseDate)",
string.Join(", ", artistMetadataIds));
return Query.QueryText(query);
}
public List<Album> GetAlbumsByArtistMetadataId(int artistMetadataId)
{
return Query.Where(s => s.ArtistMetadataId == artistMetadataId);

View file

@ -15,6 +15,8 @@ namespace NzbDrone.Core.Music
Album GetAlbum(int albumId);
List<Album> GetAlbums(IEnumerable<int> albumIds);
List<Album> GetAlbumsByArtist(int artistId);
List<Album> GetNextAlbumsByArtistMetadataId(IEnumerable<int> artistMetadataIds);
List<Album> GetLastAlbumsByArtistMetadataId(IEnumerable<int> artistMetadataIds);
List<Album> GetAlbumsByArtistMetadataId(int artistMetadataId);
List<Album> GetAlbumsForRefresh(int artistMetadataId, IEnumerable<string> foreignIds);
Album AddAlbum(Album newAlbum);
@ -170,6 +172,16 @@ namespace NzbDrone.Core.Music
return _albumRepository.GetAlbums(artistId).ToList();
}
public List<Album> GetNextAlbumsByArtistMetadataId(IEnumerable<int> artistMetadataIds)
{
return _albumRepository.GetNextAlbums(artistMetadataIds).ToList();
}
public List<Album> GetLastAlbumsByArtistMetadataId(IEnumerable<int> artistMetadataIds)
{
return _albumRepository.GetLastAlbums(artistMetadataIds).ToList();
}
public List<Album> GetAlbumsByArtistMetadataId(int artistMetadataId)
{
return _albumRepository.GetAlbumsByArtistMetadataId(artistMetadataId).ToList();