2017-09-04 02:20:56 +00:00
|
|
|
using System;
|
2017-06-28 02:25:51 +00:00
|
|
|
using System.Linq;
|
|
|
|
using Marr.Data.QGen;
|
2017-06-18 02:27:01 +00:00
|
|
|
using NzbDrone.Core.Datastore;
|
2017-07-02 00:21:39 +00:00
|
|
|
using NzbDrone.Core.Datastore.Extensions;
|
2017-06-18 02:27:01 +00:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using NzbDrone.Core.Messaging.Events;
|
2017-07-03 18:39:06 +00:00
|
|
|
using Marr.Data.QGen;
|
2017-06-18 02:27:01 +00:00
|
|
|
|
|
|
|
namespace NzbDrone.Core.Music
|
|
|
|
{
|
|
|
|
public interface IAlbumRepository : IBasicRepository<Album>
|
|
|
|
{
|
|
|
|
bool AlbumPathExists(string path);
|
|
|
|
List<Album> GetAlbums(int artistId);
|
|
|
|
Album FindByName(string cleanTitle);
|
2017-08-14 02:58:42 +00:00
|
|
|
Album FindByTitle(int artistId, string title);
|
2017-07-03 18:39:06 +00:00
|
|
|
Album FindByArtistAndName(string artistName, string cleanTitle);
|
2017-06-18 02:27:01 +00:00
|
|
|
Album FindById(string spotifyId);
|
2017-07-02 00:21:39 +00:00
|
|
|
PagingSpec<Album> AlbumsWithoutFiles(PagingSpec<Album> pagingSpec);
|
2017-06-28 02:25:51 +00:00
|
|
|
List<Album> AlbumsBetweenDates(DateTime startDate, DateTime endDate, bool includeUnmonitored);
|
2017-06-25 13:17:49 +00:00
|
|
|
void SetMonitoredFlat(Album album, bool monitored);
|
2017-09-04 02:20:56 +00:00
|
|
|
void SetMonitored(IEnumerable<int> ids, bool monitored);
|
2017-06-18 02:27:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public class AlbumRepository : BasicRepository<Album>, IAlbumRepository
|
|
|
|
{
|
2017-09-04 02:20:56 +00:00
|
|
|
private readonly IMainDatabase _database;
|
|
|
|
|
2017-06-18 02:27:01 +00:00
|
|
|
public AlbumRepository(IMainDatabase database, IEventAggregator eventAggregator)
|
|
|
|
: base(database, eventAggregator)
|
|
|
|
{
|
2017-09-04 02:20:56 +00:00
|
|
|
_database = database;
|
2017-06-18 02:27:01 +00:00
|
|
|
}
|
2017-10-08 03:01:49 +00:00
|
|
|
|
2017-06-18 02:27:01 +00:00
|
|
|
|
|
|
|
public bool AlbumPathExists(string path)
|
|
|
|
{
|
|
|
|
return Query.Where(c => c.Path == path).Any();
|
|
|
|
}
|
2017-07-03 18:39:06 +00:00
|
|
|
|
2017-06-18 02:27:01 +00:00
|
|
|
public List<Album> GetAlbums(int artistId)
|
|
|
|
{
|
|
|
|
return Query.Where(s => s.ArtistId == artistId).ToList();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Album FindById(string foreignAlbumId)
|
|
|
|
{
|
|
|
|
return Query.Where(s => s.ForeignAlbumId == foreignAlbumId).SingleOrDefault();
|
|
|
|
}
|
|
|
|
|
2017-07-02 00:21:39 +00:00
|
|
|
public PagingSpec<Album> AlbumsWithoutFiles(PagingSpec<Album> pagingSpec)
|
|
|
|
{
|
|
|
|
var currentTime = DateTime.UtcNow;
|
|
|
|
|
2017-07-04 10:49:07 +00:00
|
|
|
//pagingSpec.TotalRecords = GetMissingAlbumsQuery(pagingSpec, currentTime).GetRowCount(); Cant Use GetRowCount with a Manual Query
|
|
|
|
|
|
|
|
pagingSpec.TotalRecords = GetMissingAlbumsQueryCount(pagingSpec, currentTime);
|
2017-07-02 00:21:39 +00:00
|
|
|
pagingSpec.Records = GetMissingAlbumsQuery(pagingSpec, currentTime).ToList();
|
|
|
|
|
|
|
|
return pagingSpec;
|
|
|
|
}
|
|
|
|
|
2017-06-28 02:25:51 +00:00
|
|
|
public List<Album> AlbumsBetweenDates(DateTime startDate, DateTime endDate, bool includeUnmonitored)
|
|
|
|
{
|
|
|
|
var query = Query.Join<Album, Artist>(JoinType.Inner, e => e.Artist, (e, s) => e.ArtistId == s.Id)
|
|
|
|
.Where<Album>(e => e.ReleaseDate >= startDate)
|
|
|
|
.AndWhere(e => e.ReleaseDate <= endDate);
|
|
|
|
|
|
|
|
|
|
|
|
if (!includeUnmonitored)
|
|
|
|
{
|
|
|
|
query.AndWhere(e => e.Monitored)
|
|
|
|
.AndWhere(e => e.Artist.Monitored);
|
|
|
|
}
|
|
|
|
|
|
|
|
return query.ToList();
|
|
|
|
}
|
|
|
|
|
2017-07-04 10:49:07 +00:00
|
|
|
private QueryBuilder<Album> GetMissingAlbumsQuery(PagingSpec<Album> pagingSpec, DateTime currentTime)
|
2017-07-02 00:21:39 +00:00
|
|
|
{
|
2017-07-04 10:49:07 +00:00
|
|
|
string sortKey;
|
2017-10-08 03:01:49 +00:00
|
|
|
string monitored = "(Albums.[Monitored] = 0) OR (Artists.[Monitored] = 0)";
|
2017-07-04 10:49:07 +00:00
|
|
|
|
|
|
|
if (pagingSpec.FilterExpression.ToString().Contains("True"))
|
|
|
|
{
|
2017-10-08 03:01:49 +00:00
|
|
|
monitored = "(Albums.[Monitored] = 1) AND (Artists.[Monitored] = 1)";
|
2017-07-04 10:49:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pagingSpec.SortKey == "releaseDate")
|
|
|
|
{
|
2017-10-08 03:01:49 +00:00
|
|
|
sortKey = "Albums." + pagingSpec.SortKey;
|
2017-07-04 10:49:07 +00:00
|
|
|
}
|
|
|
|
else if (pagingSpec.SortKey == "artist.sortName")
|
|
|
|
{
|
2017-10-08 03:01:49 +00:00
|
|
|
sortKey = "Artists." + pagingSpec.SortKey.Split('.').Last();
|
2017-07-04 10:49:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-10-08 03:01:49 +00:00
|
|
|
sortKey = "Albums.releaseDate";
|
2017-07-04 10:49:07 +00:00
|
|
|
}
|
|
|
|
|
2017-10-08 03:01:49 +00:00
|
|
|
string query = string.Format("SELECT Albums.* FROM (SELECT Tracks.AlbumId, COUNT(*) AS TotalTrackCount," + "" +
|
|
|
|
"SUM(CASE WHEN TrackFileId > 0 THEN 1 ELSE 0 END) AS AvailableTrackCount FROM Tracks GROUP BY Tracks.ArtistId, Tracks.AlbumId) as Tracks" +
|
|
|
|
" LEFT OUTER JOIN Albums ON Tracks.AlbumId == Albums.Id" +
|
|
|
|
" LEFT OUTER JOIN Artists ON Albums.ArtistId == Artists.Id" +
|
|
|
|
" WHERE Tracks.TotalTrackCount != Tracks.AvailableTrackCount AND ({0}) AND {1}" +
|
|
|
|
" GROUP BY Tracks.AlbumId" +
|
|
|
|
" ORDER BY {2} {3} LIMIT {4} OFFSET {5}",
|
|
|
|
monitored, BuildReleaseDateCutoffWhereClause(currentTime), sortKey, pagingSpec.ToSortDirection(), pagingSpec.PageSize, pagingSpec.PagingOffset());
|
2017-07-04 10:49:07 +00:00
|
|
|
|
2017-10-08 03:01:49 +00:00
|
|
|
return Query.QueryText(query);
|
2017-07-04 10:49:07 +00:00
|
|
|
|
|
|
|
//Use Manual Query until we find a way to "NOT EXIST(SELECT 1 from Tracks WHERE [t2].trackFileId <> 0)"
|
2017-10-08 03:01:49 +00:00
|
|
|
|
2017-07-04 10:49:07 +00:00
|
|
|
//return Query.Join<Album, Artist>(JoinType.Inner, e => e.Artist, (e, s) => e.ArtistId == s.Id)
|
|
|
|
// .Where<Album>(pagingSpec.FilterExpression)
|
|
|
|
// .AndWhere(BuildReleaseDateCutoffWhereClause(currentTime))
|
|
|
|
// //.Where<Track>(t => t.TrackFileId == 0)
|
|
|
|
// .OrderBy(pagingSpec.OrderByClause(), pagingSpec.ToSortDirection())
|
|
|
|
// .Skip(pagingSpec.PagingOffset())
|
|
|
|
// .Take(pagingSpec.PageSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
private int GetMissingAlbumsQueryCount(PagingSpec<Album> pagingSpec, DateTime currentTime)
|
|
|
|
{
|
|
|
|
var monitored = 0;
|
|
|
|
|
|
|
|
if (pagingSpec.FilterExpression.ToString().Contains("True"))
|
|
|
|
{
|
|
|
|
monitored = 1;
|
|
|
|
}
|
2017-10-08 03:01:49 +00:00
|
|
|
|
|
|
|
string query = string.Format("SELECT Albums.* FROM (SELECT Tracks.AlbumId, COUNT(*) AS TotalTrackCount," +
|
|
|
|
" SUM(CASE WHEN TrackFileId > 0 THEN 1 ELSE 0 END) AS AvailableTrackCount FROM Tracks GROUP BY Tracks.ArtistId, Tracks.AlbumId) as Tracks" +
|
|
|
|
" LEFT OUTER JOIN Albums ON Tracks.AlbumId == Albums.Id" +
|
|
|
|
" LEFT OUTER JOIN Artists ON Albums.ArtistId == Artists.Id" +
|
|
|
|
" WHERE Tracks.TotalTrackCount != Tracks.AvailableTrackCount AND ({0}) AND {1}" +
|
|
|
|
" GROUP BY Tracks.AlbumId",
|
2017-07-04 10:49:07 +00:00
|
|
|
monitored, BuildReleaseDateCutoffWhereClause(currentTime));
|
|
|
|
|
|
|
|
return Query.QueryText(query).Count();
|
2017-07-02 00:21:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private string BuildReleaseDateCutoffWhereClause(DateTime currentTime)
|
|
|
|
{
|
2017-10-08 03:01:49 +00:00
|
|
|
return string.Format("datetime(strftime('%s', Albums.[ReleaseDate]), 'unixepoch') <= '{0}'",
|
2017-07-02 00:21:39 +00:00
|
|
|
currentTime.ToString("yyyy-MM-dd HH:mm:ss"));
|
|
|
|
}
|
|
|
|
|
2017-06-25 13:17:49 +00:00
|
|
|
public void SetMonitoredFlat(Album album, bool monitored)
|
|
|
|
{
|
|
|
|
album.Monitored = monitored;
|
|
|
|
SetFields(album, p => p.Monitored);
|
|
|
|
}
|
|
|
|
|
2017-09-04 02:20:56 +00:00
|
|
|
public void SetMonitored(IEnumerable<int> ids, bool monitored)
|
|
|
|
{
|
|
|
|
var mapper = _database.GetDataMapper();
|
|
|
|
|
|
|
|
mapper.AddParameter("monitored", monitored);
|
|
|
|
|
|
|
|
var sql = "UPDATE Albums " +
|
|
|
|
"SET Monitored = @monitored " +
|
|
|
|
$"WHERE Id IN ({string.Join(", ", ids)})";
|
|
|
|
|
|
|
|
mapper.ExecuteNonQuery(sql);
|
|
|
|
}
|
|
|
|
|
2017-06-18 02:27:01 +00:00
|
|
|
public Album FindByName(string cleanTitle)
|
|
|
|
{
|
|
|
|
cleanTitle = cleanTitle.ToLowerInvariant();
|
|
|
|
|
|
|
|
return Query.Where(s => s.CleanTitle == cleanTitle)
|
|
|
|
.SingleOrDefault();
|
|
|
|
}
|
2017-07-03 18:39:06 +00:00
|
|
|
|
2017-08-14 02:58:42 +00:00
|
|
|
public Album FindByTitle(int artistId, string title)
|
|
|
|
{
|
2017-10-08 20:07:54 +00:00
|
|
|
title = Parser.Parser.CleanArtistName(title);
|
2017-08-14 02:58:42 +00:00
|
|
|
|
|
|
|
return Query.Where(s => s.CleanTitle == title)
|
|
|
|
.AndWhere(s => s.ArtistId == artistId)
|
2017-09-15 03:33:13 +00:00
|
|
|
.FirstOrDefault();
|
2017-08-14 02:58:42 +00:00
|
|
|
}
|
|
|
|
|
2017-07-03 18:39:06 +00:00
|
|
|
public Album FindByArtistAndName(string artistName, string cleanTitle)
|
|
|
|
{
|
2017-10-08 20:07:54 +00:00
|
|
|
var cleanArtistName = Parser.Parser.CleanArtistName(artistName);
|
2017-07-03 18:39:06 +00:00
|
|
|
cleanTitle = cleanTitle.ToLowerInvariant();
|
|
|
|
var query = Query.Join<Album, Artist>(JoinType.Inner, album => album.Artist, (album, artist) => album.ArtistId == artist.Id)
|
|
|
|
.Where<Artist>(artist => artist.CleanName == cleanArtistName)
|
|
|
|
.Where<Album>(album => album.CleanTitle == cleanTitle);
|
2017-10-08 03:01:49 +00:00
|
|
|
return Query.Join<Album, Artist>(JoinType.Inner, album => album.Artist, (album, artist) => album.ArtistId == artist.Id)
|
2017-07-03 18:39:06 +00:00
|
|
|
.Where<Artist>(artist => artist.CleanName == cleanArtistName)
|
|
|
|
.Where<Album>(album => album.CleanTitle == cleanTitle)
|
|
|
|
.SingleOrDefault();
|
|
|
|
}
|
2017-06-18 02:27:01 +00:00
|
|
|
}
|
|
|
|
}
|