aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-06-17 09:06:13 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-06-17 09:06:13 -0400
commitf9847be17c5037671b622b61df9aaa113723f318 (patch)
tree3cdd29229f24f21beafb526a5fd13de9d336fb9f
parentbcfe86dd16e66e2e0510b1e752b4067c3fa991d3 (diff)
update item by name queries
-rw-r--r--MediaBrowser.Api/StartupWizardService.cs2
-rw-r--r--MediaBrowser.Api/UserLibrary/ArtistsService.cs40
-rw-r--r--MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs134
-rw-r--r--MediaBrowser.Api/UserLibrary/GameGenresService.cs25
-rw-r--r--MediaBrowser.Api/UserLibrary/GenresService.cs61
-rw-r--r--MediaBrowser.Api/UserLibrary/MusicGenresService.cs17
-rw-r--r--MediaBrowser.Api/UserLibrary/StudiosService.cs11
-rw-r--r--MediaBrowser.Controller/Entities/Audio/Audio.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicArtist.cs10
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicGenre.cs11
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs4
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs8
-rw-r--r--MediaBrowser.Controller/Entities/GameGenre.cs11
-rw-r--r--MediaBrowser.Controller/Entities/Genre.cs11
-rw-r--r--MediaBrowser.Controller/Entities/Person.cs11
-rw-r--r--MediaBrowser.Controller/Entities/Studio.cs11
-rw-r--r--MediaBrowser.Controller/Entities/Video.cs3
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs8
-rw-r--r--MediaBrowser.Controller/Persistence/IItemRepository.cs8
-rw-r--r--MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj3
-rw-r--r--MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj3
-rw-r--r--MediaBrowser.Model/Dto/ItemCounts.cs1
-rw-r--r--MediaBrowser.Model/Entities/MediaUrl.cs1
-rw-r--r--MediaBrowser.Model/Entities/VideoSize.cs8
-rw-r--r--MediaBrowser.Model/MediaBrowser.Model.csproj1
-rw-r--r--MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs3
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs96
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs2
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj4
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs24
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs348
-rw-r--r--MediaBrowser.Server.Implementations/packages.config2
33 files changed, 733 insertions, 153 deletions
diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs
index f4aee080a..e4949b4d8 100644
--- a/MediaBrowser.Api/StartupWizardService.cs
+++ b/MediaBrowser.Api/StartupWizardService.cs
@@ -114,7 +114,7 @@ namespace MediaBrowser.Api
config.EnableStandaloneMusicKeys = true;
config.EnableCaseSensitiveItemIds = true;
config.EnableFolderView = true;
- config.SchemaVersion = 92;
+ config.SchemaVersion = 95;
}
public void Post(UpdateStartupConfiguration request)
diff --git a/MediaBrowser.Api/UserLibrary/ArtistsService.cs b/MediaBrowser.Api/UserLibrary/ArtistsService.cs
index cde5eade5..df73ef720 100644
--- a/MediaBrowser.Api/UserLibrary/ArtistsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ArtistsService.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Dto;
+using System;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
@@ -8,6 +9,8 @@ using MediaBrowser.Model.Dto;
using ServiceStack;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Api.UserLibrary
{
@@ -100,7 +103,12 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>System.Object.</returns>
public object Get(GetArtists request)
{
- var result = GetResult(request);
+ if (string.IsNullOrWhiteSpace(request.IncludeItemTypes))
+ {
+ //request.IncludeItemTypes = "Audio,MusicVideo";
+ }
+
+ var result = GetResultSlim(request);
return ToOptimizedResult(result);
}
@@ -112,11 +120,26 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>System.Object.</returns>
public object Get(GetAlbumArtists request)
{
- var result = GetResult(request);
+ if (string.IsNullOrWhiteSpace(request.IncludeItemTypes))
+ {
+ //request.IncludeItemTypes = "Audio,MusicVideo";
+ }
+
+ var result = GetResultSlim(request);
return ToOptimizedResult(result);
}
+ protected override QueryResult<Tuple<BaseItem, ItemCounts>> GetItems(GetItemsByName request, InternalItemsQuery query)
+ {
+ if (request is GetAlbumArtists)
+ {
+ return LibraryManager.GetAlbumArtists(query);
+ }
+
+ return LibraryManager.GetArtists(query);
+ }
+
/// <summary>
/// Gets all items.
/// </summary>
@@ -125,16 +148,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
{
- if (request is GetAlbumArtists)
- {
- return LibraryManager.GetAlbumArtists(items
- .Where(i => !i.IsFolder)
- .OfType<IHasAlbumArtist>());
- }
-
- return LibraryManager.GetArtists(items
- .Where(i => !i.IsFolder)
- .OfType<IHasArtist>());
+ throw new NotImplementedException();
}
}
}
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
index 18dec3253..9465d1fdc 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
@@ -8,6 +8,7 @@ using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Model.Dto;
namespace MediaBrowser.Api.UserLibrary
{
@@ -83,6 +84,137 @@ namespace MediaBrowser.Api.UserLibrary
return null;
}
+ protected ItemsResult GetResultSlim(GetItemsByName request)
+ {
+ var dtoOptions = GetDtoOptions(request);
+
+ User user = null;
+ BaseItem parentItem;
+
+ if (!string.IsNullOrWhiteSpace(request.UserId))
+ {
+ user = UserManager.GetUserById(request.UserId);
+ parentItem = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : LibraryManager.GetItemById(request.ParentId);
+ }
+ else
+ {
+ parentItem = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.RootFolder : LibraryManager.GetItemById(request.ParentId);
+ }
+
+ var excludeItemTypes = request.GetExcludeItemTypes();
+ var includeItemTypes = request.GetIncludeItemTypes();
+ var mediaTypes = request.GetMediaTypes();
+
+ var query = new InternalItemsQuery(user)
+ {
+ ExcludeItemTypes = excludeItemTypes,
+ IncludeItemTypes = includeItemTypes,
+ MediaTypes = mediaTypes,
+ StartIndex = request.StartIndex,
+ Limit = request.Limit,
+ IsFavorite = request.IsFavorite,
+ NameLessThan = request.NameLessThan,
+ NameStartsWith = request.NameStartsWith,
+ NameStartsWithOrGreater = request.NameStartsWithOrGreater,
+ AlbumArtistStartsWithOrGreater = request.AlbumArtistStartsWithOrGreater,
+ Tags = request.GetTags(),
+ OfficialRatings = request.GetOfficialRatings(),
+ Genres = request.GetGenres(),
+ GenreIds = request.GetGenreIds(),
+ Studios = request.GetStudios(),
+ StudioIds = request.GetStudioIds(),
+ Person = request.Person,
+ PersonIds = request.GetPersonIds(),
+ PersonTypes = request.GetPersonTypes(),
+ Years = request.GetYears(),
+ MinCommunityRating = request.MinCommunityRating
+ };
+
+ if (!string.IsNullOrWhiteSpace(request.ParentId))
+ {
+ if (parentItem is Folder)
+ {
+ query.AncestorIds = new[] { request.ParentId };
+ }
+ else
+ {
+ query.ItemIds = new[] { request.ParentId };
+ }
+ }
+
+ foreach (var filter in request.GetFilters())
+ {
+ switch (filter)
+ {
+ case ItemFilter.Dislikes:
+ query.IsLiked = false;
+ break;
+ case ItemFilter.IsFavorite:
+ query.IsFavorite = true;
+ break;
+ case ItemFilter.IsFavoriteOrLikes:
+ query.IsFavoriteOrLiked = true;
+ break;
+ case ItemFilter.IsFolder:
+ query.IsFolder = true;
+ break;
+ case ItemFilter.IsNotFolder:
+ query.IsFolder = false;
+ break;
+ case ItemFilter.IsPlayed:
+ query.IsPlayed = true;
+ break;
+ case ItemFilter.IsRecentlyAdded:
+ break;
+ case ItemFilter.IsResumable:
+ query.IsResumable = true;
+ break;
+ case ItemFilter.IsUnplayed:
+ query.IsPlayed = false;
+ break;
+ case ItemFilter.Likes:
+ query.IsLiked = true;
+ break;
+ }
+ }
+
+ var result = GetItems(request, query);
+
+ var dtos = result.Items.Select(i =>
+ {
+ var dto = DtoService.GetItemByNameDto(i.Item1, dtoOptions, null, user);
+
+ if (!string.IsNullOrWhiteSpace(request.IncludeItemTypes))
+ {
+ SetItemCounts(dto, i.Item2);
+ }
+ return dto;
+ });
+
+ return new ItemsResult
+ {
+ Items = dtos.ToArray(),
+ TotalRecordCount = result.TotalRecordCount
+ };
+ }
+
+ protected virtual QueryResult<Tuple<BaseItem, ItemCounts>> GetItems(GetItemsByName request, InternalItemsQuery query)
+ {
+ return new QueryResult<Tuple<BaseItem, ItemCounts>>();
+ }
+
+ private void SetItemCounts(BaseItemDto dto, ItemCounts counts)
+ {
+ dto.ChildCount = counts.ItemCount;
+ dto.SeriesCount = counts.SeriesCount;
+ dto.EpisodeCount = counts.EpisodeCount;
+ dto.MovieCount = counts.MovieCount;
+ dto.TrailerCount = counts.TrailerCount;
+ dto.AlbumCount = counts.AlbumCount;
+ dto.SongCount = counts.SongCount;
+ dto.GameCount = counts.GameCount;
+ }
+
/// <summary>
/// Gets the specified request.
/// </summary>
@@ -374,7 +506,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <param name="includeItemTypes">The include item types.</param>
/// <param name="mediaTypes">The media types.</param>
/// <returns>IEnumerable{BaseItem}.</returns>
- protected bool FilterItem(GetItemsByName request, BaseItem f, string[] excludeItemTypes, string[] includeItemTypes, string[] mediaTypes)
+ private bool FilterItem(GetItemsByName request, BaseItem f, string[] excludeItemTypes, string[] includeItemTypes, string[] mediaTypes)
{
// Exclude item types
if (excludeItemTypes.Length > 0)
diff --git a/MediaBrowser.Api/UserLibrary/GameGenresService.cs b/MediaBrowser.Api/UserLibrary/GameGenresService.cs
index 58237f80f..ebc9a970d 100644
--- a/MediaBrowser.Api/UserLibrary/GameGenresService.cs
+++ b/MediaBrowser.Api/UserLibrary/GameGenresService.cs
@@ -9,6 +9,7 @@ using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Api.UserLibrary
{
@@ -87,11 +88,16 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>System.Object.</returns>
public object Get(GetGameGenres request)
{
- var result = GetResult(request);
+ var result = GetResultSlim(request);
return ToOptimizedSerializedResultUsingCache(result);
}
+ protected override QueryResult<Tuple<BaseItem, ItemCounts>> GetItems(GetItemsByName request, InternalItemsQuery query)
+ {
+ return LibraryManager.GetGameGenres(query);
+ }
+
/// <summary>
/// Gets all items.
/// </summary>
@@ -100,22 +106,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
{
- return items
- .SelectMany(i => i.Genres)
- .DistinctNames()
- .Select(name =>
- {
- try
- {
- return LibraryManager.GetGameGenre(name);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error getting genre {0}", ex, name);
- return null;
- }
- })
- .Where(i => i != null);
+ throw new NotImplementedException();
}
}
}
diff --git a/MediaBrowser.Api/UserLibrary/GenresService.cs b/MediaBrowser.Api/UserLibrary/GenresService.cs
index d383bd0ad..57c11a1fa 100644
--- a/MediaBrowser.Api/UserLibrary/GenresService.cs
+++ b/MediaBrowser.Api/UserLibrary/GenresService.cs
@@ -9,6 +9,7 @@ using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Api.UserLibrary
{
@@ -92,65 +93,37 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>System.Object.</returns>
public object Get(GetGenres request)
{
- var result = GetResult(request);
+ var result = GetResultSlim(request);
return ToOptimizedSerializedResultUsingCache(result);
}
- /// <summary>
- /// Gets all items.
- /// </summary>
- /// <param name="request">The request.</param>
- /// <param name="items">The items.</param>
- /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
- protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+ protected override QueryResult<Tuple<BaseItem, ItemCounts>> GetItems(GetItemsByName request, InternalItemsQuery query)
{
var viewType = GetParentItemViewType(request);
if (string.Equals(viewType, CollectionType.Music) || string.Equals(viewType, CollectionType.MusicVideos))
{
- return items
- .SelectMany(i => i.Genres)
- .DistinctNames()
- .Select(name => LibraryManager.GetMusicGenre(name));
+ return LibraryManager.GetMusicGenres(query);
}
if (string.Equals(viewType, CollectionType.Games))
{
- return items
- .SelectMany(i => i.Genres)
- .DistinctNames()
- .Select(name =>
- {
- try
- {
- return LibraryManager.GetGameGenre(name);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error getting genre {0}", ex, name);
- return null;
- }
- })
- .Where(i => i != null);
+ return LibraryManager.GetGameGenres(query);
}
- return items
- .SelectMany(i => i.Genres)
- .DistinctNames()
- .Select(name =>
- {
- try
- {
- return LibraryManager.GetGenre(name);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error getting genre {0}", ex, name);
- return null;
- }
- })
- .Where(i => i != null);
+ return LibraryManager.GetGenres(query);
+ }
+
+ /// <summary>
+ /// Gets all items.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <param name="items">The items.</param>
+ /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
+ protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+ {
+ throw new NotImplementedException();
}
}
}
diff --git a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs
index 12cb62fac..f02136e05 100644
--- a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs
+++ b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Dto;
+using System;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
@@ -8,6 +9,8 @@ using MediaBrowser.Model.Dto;
using ServiceStack;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Api.UserLibrary
{
@@ -86,11 +89,16 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>System.Object.</returns>
public object Get(GetMusicGenres request)
{
- var result = GetResult(request);
+ var result = GetResultSlim(request);
return ToOptimizedSerializedResultUsingCache(result);
}
+ protected override QueryResult<Tuple<BaseItem, ItemCounts>> GetItems(GetItemsByName request, InternalItemsQuery query)
+ {
+ return LibraryManager.GetMusicGenres(query);
+ }
+
/// <summary>
/// Gets all items.
/// </summary>
@@ -99,10 +107,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
{
- return items
- .SelectMany(i => i.Genres)
- .DistinctNames()
- .Select(name => LibraryManager.GetMusicGenre(name));
+ throw new NotImplementedException();
}
}
}
diff --git a/MediaBrowser.Api/UserLibrary/StudiosService.cs b/MediaBrowser.Api/UserLibrary/StudiosService.cs
index 2cdabf721..9e9c25d78 100644
--- a/MediaBrowser.Api/UserLibrary/StudiosService.cs
+++ b/MediaBrowser.Api/UserLibrary/StudiosService.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Dto;
+using System;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
@@ -7,6 +8,7 @@ using MediaBrowser.Model.Dto;
using ServiceStack;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Api.UserLibrary
{
@@ -90,11 +92,16 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>System.Object.</returns>
public object Get(GetStudios request)
{
- var result = GetResult(request);
+ var result = GetResultSlim(request);
return ToOptimizedSerializedResultUsingCache(result);
}
+ protected override QueryResult<Tuple<BaseItem, ItemCounts>> GetItems(GetItemsByName request, InternalItemsQuery query)
+ {
+ return LibraryManager.GetStudios(query);
+ }
+
/// <summary>
/// Gets all items.
/// </summary>
diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs
index 06710b030..b3df34c4d 100644
--- a/MediaBrowser.Controller/Entities/Audio/Audio.cs
+++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs
@@ -26,8 +26,6 @@ namespace MediaBrowser.Controller.Entities.Audio
{
public List<ChannelMediaInfo> ChannelMediaSources { get; set; }
- public long? Size { get; set; }
- public string Container { get; set; }
public int? TotalBitrate { get; set; }
public ExtraType? ExtraType { get; set; }
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
index 950701687..6790a1bcf 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
@@ -9,6 +9,7 @@ using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Common.Extensions;
namespace MediaBrowser.Controller.Entities.Audio
{
@@ -165,10 +166,17 @@ namespace MediaBrowser.Controller.Entities.Audio
list.Add("Artist-Musicbrainz-" + id);
}
- list.Add("Artist-" + item.Name);
+ list.Add("Artist-" + (item.Name ?? string.Empty).RemoveDiacritics());
return list;
}
+ public override string PresentationUniqueKey
+ {
+ get
+ {
+ return "Artist-" + (Name ?? string.Empty).RemoveDiacritics();
+ }
+ }
protected override bool GetBlockUnratedValue(UserPolicy config)
{
return config.BlockUnratedItems.Contains(UnratedItem.Music);
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
index 77cf0cc49..798bc79fb 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
+using MediaBrowser.Common.Extensions;
namespace MediaBrowser.Controller.Entities.Audio
{
@@ -14,10 +15,18 @@ namespace MediaBrowser.Controller.Entities.Audio
{
var list = base.GetUserDataKeys();
- list.Insert(0, "MusicGenre-" + Name);
+ list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
return list;
}
+ public override string PresentationUniqueKey
+ {
+ get
+ {
+ return GetUserDataKeys()[0];
+ }
+ }
+
[IgnoreDataMember]
public override bool SupportsAddingToPlaylist
{
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 33fd03e15..ed838ab31 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -69,6 +69,10 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember]
public string PreferredMetadataLanguage { get; set; }
+ public long? Size { get; set; }
+ public string Container { get; set; }
+ public string ShortOverview { get; set; }
+
public List<ItemImageInfo> ImageInfos { get; set; }
[IgnoreDataMember]
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index e3841099e..91ca1f009 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -216,7 +216,7 @@ namespace MediaBrowser.Controller.Entities
{
get
{
- return LoadChildren().Select(LibraryManager.GetItemById).Where(i => i != null);
+ return LoadChildren();
}
}
@@ -270,7 +270,7 @@ namespace MediaBrowser.Controller.Entities
/// Loads our children. Validation will occur externally.
/// We want this sychronous.
/// </summary>
- protected virtual IEnumerable<Guid> LoadChildren()
+ protected virtual IEnumerable<BaseItem> LoadChildren()
{
//just load our children from the repo - the library will be validated and maintained in other processes
return GetCachedChildren();
@@ -657,9 +657,9 @@ namespace MediaBrowser.Controller.Entities
/// Get our children from the repo - stubbed for now
/// </summary>
/// <returns>IEnumerable{BaseItem}.</returns>
- protected IEnumerable<Guid> GetCachedChildren()
+ protected IEnumerable<BaseItem> GetCachedChildren()
{
- return ItemRepository.GetItemIdsList(new InternalItemsQuery
+ return ItemRepository.GetItemList(new InternalItemsQuery
{
ParentId = Id,
GroupByPresentationUniqueKey = false
diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs
index 7c1e88cb1..45e766c0f 100644
--- a/MediaBrowser.Controller/Entities/GameGenre.cs
+++ b/MediaBrowser.Controller/Entities/GameGenre.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
+using MediaBrowser.Common.Extensions;
namespace MediaBrowser.Controller.Entities
{
@@ -11,10 +12,18 @@ namespace MediaBrowser.Controller.Entities
{
var list = base.GetUserDataKeys();
- list.Insert(0, "GameGenre-" + Name);
+ list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
return list;
}
+ public override string PresentationUniqueKey
+ {
+ get
+ {
+ return GetUserDataKeys()[0];
+ }
+ }
+
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs
index c87d4daaf..cc5aebb2a 100644
--- a/MediaBrowser.Controller/Entities/Genre.cs
+++ b/MediaBrowser.Controller/Entities/Genre.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities.Audio;
using System;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Common.Extensions;
namespace MediaBrowser.Controller.Entities
{
@@ -15,10 +16,18 @@ namespace MediaBrowser.Controller.Entities
{
var list = base.GetUserDataKeys();
- list.Insert(0, "Genre-" + Name);
+ list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
return list;
}
+ public override string PresentationUniqueKey
+ {
+ get
+ {
+ return GetUserDataKeys()[0];
+ }
+ }
+
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs
index 2b099e3d5..8ef0d70bf 100644
--- a/MediaBrowser.Controller/Entities/Person.cs
+++ b/MediaBrowser.Controller/Entities/Person.cs
@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Entities
@@ -22,10 +23,18 @@ namespace MediaBrowser.Controller.Entities
{
var list = base.GetUserDataKeys();
- list.Insert(0, "Person-" + Name);
+ list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
return list;
}
+ public override string PresentationUniqueKey
+ {
+ get
+ {
+ return GetUserDataKeys()[0];
+ }
+ }
+
public PersonLookupInfo GetLookupInfo()
{
return GetItemLookupInfo<PersonLookupInfo>();
diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs
index e46978af3..762798b55 100644
--- a/MediaBrowser.Controller/Entities/Studio.cs
+++ b/MediaBrowser.Controller/Entities/Studio.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
+using MediaBrowser.Common.Extensions;
namespace MediaBrowser.Controller.Entities
{
@@ -14,10 +15,18 @@ namespace MediaBrowser.Controller.Entities
{
var list = base.GetUserDataKeys();
- list.Insert(0, "Studio-" + Name);
+ list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
return list;
}
+ public override string PresentationUniqueKey
+ {
+ get
+ {
+ return GetUserDataKeys()[0];
+ }
+ }
+
/// <summary>
/// Returns the folder containing the item.
/// If the item is a folder, it returns the folder itself
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index 2502033c8..73c893dd6 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -58,10 +58,7 @@ namespace MediaBrowser.Controller.Entities
}
}
- public long? Size { get; set; }
- public string Container { get; set; }
public int? TotalBitrate { get; set; }
- public string ShortOverview { get; set; }
public ExtraType? ExtraType { get; set; }
/// <summary>
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 1d0e06482..4e641b005 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -11,6 +11,7 @@ using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Model.Dto;
namespace MediaBrowser.Controller.Library
{
@@ -567,5 +568,12 @@ namespace MediaBrowser.Controller.Library
void RemoveVirtualFolder(string name, bool refreshLibrary);
void AddMediaPath(string virtualFolderName, string path);
void RemoveMediaPath(string virtualFolderName, string path);
+
+ QueryResult<Tuple<BaseItem, ItemCounts>> GetGenres(InternalItemsQuery query);
+ QueryResult<Tuple<BaseItem, ItemCounts>> GetMusicGenres(InternalItemsQuery query);
+ QueryResult<Tuple<BaseItem, ItemCounts>> GetGameGenres(InternalItemsQuery query);
+ QueryResult<Tuple<BaseItem, ItemCounts>> GetStudios(InternalItemsQuery query);
+ QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query);
+ QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query);
}
} \ No newline at end of file
diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs
index 80a6e4042..2ef8b70f0 100644
--- a/MediaBrowser.Controller/Persistence/IItemRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs
@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Querying;
namespace MediaBrowser.Controller.Persistence
@@ -161,6 +162,13 @@ namespace MediaBrowser.Controller.Persistence
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
Task UpdateInheritedValues(CancellationToken cancellationToken);
+
+ QueryResult<Tuple<BaseItem, ItemCounts>> GetGenres(InternalItemsQuery query);
+ QueryResult<Tuple<BaseItem, ItemCounts>> GetMusicGenres(InternalItemsQuery query);
+ QueryResult<Tuple<BaseItem, ItemCounts>> GetGameGenres(InternalItemsQuery query);
+ QueryResult<Tuple<BaseItem, ItemCounts>> GetStudios(InternalItemsQuery query);
+ QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query);
+ QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query);
}
}
diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
index f759ffeae..f9d28605e 100644
--- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
+++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
@@ -599,9 +599,6 @@
<Compile Include="..\MediaBrowser.Model\Entities\Video3DFormat.cs">
<Link>Entities\Video3DFormat.cs</Link>
</Compile>
- <Compile Include="..\MediaBrowser.Model\Entities\VideoSize.cs">
- <Link>Entities\VideoSize.cs</Link>
- </Compile>
<Compile Include="..\MediaBrowser.Model\Entities\VideoType.cs">
<Link>Entities\VideoType.cs</Link>
</Compile>
diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
index 05bbeb50e..edaa0e027 100644
--- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
+++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
@@ -573,9 +573,6 @@
<Compile Include="..\MediaBrowser.Model\Entities\Video3DFormat.cs">
<Link>Entities\Video3DFormat.cs</Link>
</Compile>
- <Compile Include="..\MediaBrowser.Model\Entities\VideoSize.cs">
- <Link>Entities\VideoSize.cs</Link>
- </Compile>
<Compile Include="..\MediaBrowser.Model\Entities\VideoType.cs">
<Link>Entities\VideoType.cs</Link>
</Compile>
diff --git a/MediaBrowser.Model/Dto/ItemCounts.cs b/MediaBrowser.Model/Dto/ItemCounts.cs
index a3a00c341..07ddfa1ac 100644
--- a/MediaBrowser.Model/Dto/ItemCounts.cs
+++ b/MediaBrowser.Model/Dto/ItemCounts.cs
@@ -60,5 +60,6 @@
/// </summary>
/// <value>The book count.</value>
public int BookCount { get; set; }
+ public int ItemCount { get; set; }
}
}
diff --git a/MediaBrowser.Model/Entities/MediaUrl.cs b/MediaBrowser.Model/Entities/MediaUrl.cs
index 24e3b1492..2e17bba8a 100644
--- a/MediaBrowser.Model/Entities/MediaUrl.cs
+++ b/MediaBrowser.Model/Entities/MediaUrl.cs
@@ -5,6 +5,5 @@ namespace MediaBrowser.Model.Entities
{
public string Url { get; set; }
public string Name { get; set; }
- public VideoSize? VideoSize { get; set; }
}
}
diff --git a/MediaBrowser.Model/Entities/VideoSize.cs b/MediaBrowser.Model/Entities/VideoSize.cs
deleted file mode 100644
index 0100f3b90..000000000
--- a/MediaBrowser.Model/Entities/VideoSize.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace MediaBrowser.Model.Entities
-{
- public enum VideoSize
- {
- StandardDefinition,
- HighDefinition
- }
-} \ No newline at end of file
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 522b7d38d..7c9f132db 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -227,7 +227,6 @@
<Compile Include="Entities\ProviderIdsExtensions.cs" />
<Compile Include="Entities\ScrollDirection.cs" />
<Compile Include="Entities\SortOrder.cs" />
- <Compile Include="Entities\VideoSize.cs" />
<Compile Include="Events\GenericEventArgs.cs" />
<Compile Include="Extensions\DoubleHelper.cs" />
<Compile Include="Extensions\IHasPropertyChangedEvent.cs" />
diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
index 3b3065893..a6b6de7e5 100644
--- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
+++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
@@ -326,8 +326,7 @@ namespace MediaBrowser.Providers.Movies
hasTrailers.RemoteTrailers = movieData.trailers.youtube.Select(i => new MediaUrl
{
Url = string.Format("https://www.youtube.com/watch?v={0}", i.source),
- Name = i.name,
- VideoSize = string.Equals("hd", i.size, StringComparison.OrdinalIgnoreCase) ? VideoSize.HighDefinition : VideoSize.StandardDefinition
+ Name = i.name
}).ToList();
}
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index 95a235109..bb9fcc924 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -418,7 +418,7 @@ namespace MediaBrowser.Server.Implementations.Dto
var dto = GetBaseItemDtoInternal(item, options, GetSyncedItemProgressDictionary(syncProgress), user);
- if (options.Fields.Contains(ItemFields.ItemCounts))
+ if (taggedItems != null && options.Fields.Contains(ItemFields.ItemCounts))
{
SetItemByNameInfo(item, dto, taggedItems, user);
}
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index c0c40aa5b..09dc0400c 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -33,6 +33,7 @@ using System.Net;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Library;
using MediaBrowser.Model.Net;
@@ -1278,7 +1279,7 @@ namespace MediaBrowser.Server.Implementations.Library
private bool EnableCaching
{
- get { return true; }
+ get { return false; }
}
public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query)
@@ -1326,6 +1327,99 @@ namespace MediaBrowser.Server.Implementations.Library
return ItemRepository.GetItemIdsList(query);
}
+ public QueryResult<Tuple<BaseItem, ItemCounts>> GetStudios(InternalItemsQuery query)
+ {
+ if (query.User != null)
+ {
+ AddUserToQuery(query, query.User);
+ }
+
+ SetTopParentOrAncestorIds(query);
+ return ItemRepository.GetStudios(query);
+ }
+
+ public QueryResult<Tuple<BaseItem, ItemCounts>> GetGenres(InternalItemsQuery query)
+ {
+ if (query.User != null)
+ {
+ AddUserToQuery(query, query.User);
+ }
+
+ SetTopParentOrAncestorIds(query);
+ return ItemRepository.GetGenres(query);
+ }
+
+ public QueryResult<Tuple<BaseItem, ItemCounts>> GetGameGenres(InternalItemsQuery query)
+ {
+ if (query.User != null)
+ {
+ AddUserToQuery(query, query.User);
+ }
+
+ SetTopParentOrAncestorIds(query);
+ return ItemRepository.GetGameGenres(query);
+ }
+
+ public QueryResult<Tuple<BaseItem, ItemCounts>> GetMusicGenres(InternalItemsQuery query)
+ {
+ if (query.User != null)
+ {
+ AddUserToQuery(query, query.User);
+ }
+
+ SetTopParentOrAncestorIds(query);
+ return ItemRepository.GetMusicGenres(query);
+ }
+
+ public QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query)
+ {
+ if (query.User != null)
+ {
+ AddUserToQuery(query, query.User);
+ }
+
+ SetTopParentOrAncestorIds(query);
+ return ItemRepository.GetArtists(query);
+ }
+
+ private void SetTopParentOrAncestorIds(InternalItemsQuery query)
+ {
+ if (query.AncestorIds.Length == 0)
+ {
+ return;
+ }
+
+ var parents = query.AncestorIds.Select(i => GetItemById(new Guid(i))).ToList();
+
+ if (parents.All(i =>
+ {
+ if (i is ICollectionFolder || i is UserView)
+ {
+ return true;
+ }
+
+ _logger.Debug("Query requires ancestor query due to type: " + i.GetType().Name);
+ return false;
+
+ }))
+ {
+ // Optimize by querying against top level views
+ query.TopParentIds = parents.SelectMany(i => GetTopParentsForQuery(i, query.User)).Select(i => i.Id.ToString("N")).ToArray();
+ query.AncestorIds = new string[] { };
+ }
+ }
+
+ public QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query)
+ {
+ if (query.User != null)
+ {
+ AddUserToQuery(query, query.User);
+ }
+
+ SetTopParentOrAncestorIds(query);
+ return ItemRepository.GetAlbumArtists(query);
+ }
+
public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, IEnumerable<string> parentIds)
{
var parents = parentIds.Select(i => GetItemById(new Guid(i))).Where(i => i != null).ToList();
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
index 9edd3f83f..703a33856 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
@@ -126,7 +126,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
}
else
{
- var videoInfo = parser.ResolveFile(args.Path);
+ var videoInfo = parser.Resolve(args.Path, false, false);
if (videoInfo == null)
{
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index 066a8c3ca..c69c788c8 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -56,8 +56,8 @@
<Reference Include="Interfaces.IO">
<HintPath>..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll</HintPath>
</Reference>
- <Reference Include="MediaBrowser.Naming, Version=1.0.5996.42016, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\MediaBrowser.Naming.1.0.0.51\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath>
+ <Reference Include="MediaBrowser.Naming, Version=1.0.6012.15754, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\packages\MediaBrowser.Naming.1.0.0.52\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MoreLinq">
diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
index 2a2f9a09d..b11a3e496 100644
--- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
@@ -15,6 +15,7 @@ using System.Threading.Tasks;
using CommonIO;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Net;
using MediaBrowser.Server.Implementations.ScheduledTasks;
@@ -145,7 +146,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
var itemIds = _libraryManager.GetItemIds(new InternalItemsQuery
{
- IsCurrentSchema = false
+ IsCurrentSchema = false,
+ ExcludeItemTypes = new[] { typeof(LiveTvProgram).Name }
});
var numComplete = 0;
@@ -236,14 +238,14 @@ namespace MediaBrowser.Server.Implementations.Persistence
// These have their own cleanup routines
ExcludeItemTypes = new[]
{
- typeof(Person).Name,
- typeof(Genre).Name,
- typeof(MusicGenre).Name,
- typeof(GameGenre).Name,
- typeof(Studio).Name,
- typeof(Year).Name,
- typeof(Channel).Name,
- typeof(AggregateFolder).Name,
+ typeof(Person).Name,
+ typeof(Genre).Name,
+ typeof(MusicGenre).Name,
+ typeof(GameGenre).Name,
+ typeof(Studio).Name,
+ typeof(Year).Name,
+ typeof(Channel).Name,
+ typeof(AggregateFolder).Name,
typeof(CollectionFolder).Name
}
});
@@ -313,8 +315,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
public IEnumerable<ITaskTrigger> GetDefaultTriggers()
{
- return new ITaskTrigger[]
- {
+ return new ITaskTrigger[]
+ {
new IntervalTrigger{ Interval = TimeSpan.FromHours(24)}
};
}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index 437d16974..121074a6e 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -22,6 +22,7 @@ using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Playlists;
+using MediaBrowser.Model.Dto;
using MediaBrowser.Model.LiveTv;
namespace MediaBrowser.Server.Implementations.Persistence
@@ -94,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
private IDbCommand _updateInheritedRatingCommand;
private IDbCommand _updateInheritedTagsCommand;
- public const int LatestSchemaVersion = 92;
+ public const int LatestSchemaVersion = 95;
/// <summary>
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
@@ -157,7 +158,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
"create table if not exists UserDataKeys (ItemId GUID, UserDataKey TEXT, PRIMARY KEY (ItemId, UserDataKey))",
"create index if not exists idx_UserDataKeys1 on UserDataKeys(ItemId)",
- "create table if not exists ItemValues (ItemId GUID, Type INT, Value TEXT)",
+ "create table if not exists ItemValues (ItemId GUID, Type INT, Value TEXT, CleanValue TEXT)",
"create index if not exists idx_ItemValues on ItemValues(ItemId)",
"create index if not exists idx_ItemValues2 on ItemValues(ItemId,Type)",
@@ -263,6 +264,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
_connection.AddColumn(Logger, "TypedBaseItems", "SeriesName", "Text");
_connection.AddColumn(Logger, "UserDataKeys", "Priority", "INT");
+ _connection.AddColumn(Logger, "ItemValues", "CleanValue", "Text");
string[] postQueries =
{
@@ -568,10 +570,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
_deleteItemValuesCommand.Parameters.Add(_deleteItemValuesCommand, "@Id");
_saveItemValuesCommand = _connection.CreateCommand();
- _saveItemValuesCommand.CommandText = "insert into ItemValues (ItemId, Type, Value) values (@ItemId, @Type, @Value)";
+ _saveItemValuesCommand.CommandText = "insert into ItemValues (ItemId, Type, Value, CleanValue) values (@ItemId, @Type, @Value, @CleanValue)";
_saveItemValuesCommand.Parameters.Add(_saveItemValuesCommand, "@ItemId");
_saveItemValuesCommand.Parameters.Add(_saveItemValuesCommand, "@Type");
_saveItemValuesCommand.Parameters.Add(_saveItemValuesCommand, "@Value");
+ _saveItemValuesCommand.Parameters.Add(_saveItemValuesCommand, "@CleanValue");
// provider ids
_deleteProviderIdsCommand = _connection.CreateCommand();
@@ -905,7 +908,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
UpdateUserDataKeys(item.Id, item.GetUserDataKeys().Distinct(StringComparer.OrdinalIgnoreCase).ToList(), transaction);
UpdateImages(item.Id, item.ImageInfos, transaction);
UpdateProviderIds(item.Id, item.ProviderIds, transaction);
- UpdateItemValues(item.Id, GetItemValues(item), transaction);
+ UpdateItemValues(item.Id, GetItemValuesToSave(item), transaction);
}
transaction.Commit();
@@ -2019,7 +2022,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
if (string.Equals(name, ItemSortBy.SeriesDatePlayed, StringComparison.OrdinalIgnoreCase))
{
- return new Tuple<string, bool>("(Select MAX(LastPlayedDate) from TypedBaseItems B"+ GetJoinUserDataText(query) + " where B.Guid in (Select ItemId from AncestorIds where AncestorId in (select guid from typedbaseitems c where C.Type = 'MediaBrowser.Controller.Entities.TV.Series' And C.Guid in (Select AncestorId from AncestorIds where ItemId=A.Guid))))", false);
+ return new Tuple<string, bool>("(Select MAX(LastPlayedDate) from TypedBaseItems B" + GetJoinUserDataText(query) + " where B.Guid in (Select ItemId from AncestorIds where AncestorId in (select guid from typedbaseitems c where C.Type = 'MediaBrowser.Controller.Entities.TV.Series' And C.Guid in (Select AncestorId from AncestorIds where ItemId=A.Guid))))", false);
}
return new Tuple<string, bool>(name, false);
@@ -2245,7 +2248,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
}
- private List<string> GetWhereClauses(InternalItemsQuery query, IDbCommand cmd)
+ private List<string> GetWhereClauses(InternalItemsQuery query, IDbCommand cmd, string paramSuffix = "")
{
var whereClauses = new List<string>();
@@ -2321,8 +2324,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
var includeTypes = query.IncludeItemTypes.SelectMany(MapIncludeItemTypes).ToArray();
if (includeTypes.Length == 1)
{
- whereClauses.Add("type=@type");
- cmd.Parameters.Add(cmd, "@type", DbType.String).Value = includeTypes[0];
+ whereClauses.Add("type=@type" + paramSuffix);
+ cmd.Parameters.Add(cmd, "@type" + paramSuffix, DbType.String).Value = includeTypes[0];
}
else if (includeTypes.Length > 1)
{
@@ -2626,8 +2629,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
var index = 0;
foreach (var artist in query.ArtistNames)
{
- clauses.Add("@ArtistName" + index + " in (select value from itemvalues where ItemId=Guid and Type <= 1)");
- cmd.Parameters.Add(cmd, "@ArtistName" + index, DbType.String).Value = artist;
+ clauses.Add("@ArtistName" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type <= 1)");
+ cmd.Parameters.Add(cmd, "@ArtistName" + index, DbType.String).Value = artist.RemoveDiacritics();
index++;
}
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
@@ -2640,8 +2643,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
var index = 0;
foreach (var item in query.Genres)
{
- clauses.Add("@Genre" + index + " in (select value from itemvalues where ItemId=Guid and Type=2)");
- cmd.Parameters.Add(cmd, "@Genre" + index, DbType.String).Value = item;
+ clauses.Add("@Genre" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=2)");
+ cmd.Parameters.Add(cmd, "@Genre" + index, DbType.String).Value = item.RemoveDiacritics();
index++;
}
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
@@ -2654,8 +2657,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
var index = 0;
foreach (var item in query.Tags)
{
- clauses.Add("@Tag" + index + " in (select value from itemvalues where ItemId=Guid and Type=4)");
- cmd.Parameters.Add(cmd, "@Tag" + index, DbType.String).Value = item;
+ clauses.Add("@Tag" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=4)");
+ cmd.Parameters.Add(cmd, "@Tag" + index, DbType.String).Value = item.RemoveDiacritics();
index++;
}
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
@@ -2668,8 +2671,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
var index = 0;
foreach (var item in query.Studios)
{
- clauses.Add("@Studio" + index + " in (select value from itemvalues where ItemId=Guid and Type=3)");
- cmd.Parameters.Add(cmd, "@Studio" + index, DbType.String).Value = item;
+ clauses.Add("@Studio" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=3)");
+ cmd.Parameters.Add(cmd, "@Studio" + index, DbType.String).Value = item.RemoveDiacritics();
index++;
}
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
@@ -2682,8 +2685,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
var index = 0;
foreach (var item in query.Keywords)
{
- clauses.Add("@Keyword" + index + " in (select value from itemvalues where ItemId=Guid and Type=5)");
- cmd.Parameters.Add(cmd, "@Keyword" + index, DbType.String).Value = item;
+ clauses.Add("@Keyword" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=5)");
+ cmd.Parameters.Add(cmd, "@Keyword" + index, DbType.String).Value = item.RemoveDiacritics();
index++;
}
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
@@ -2812,6 +2815,20 @@ namespace MediaBrowser.Server.Implementations.Persistence
whereClauses.Add("MediaType in (" + val + ")");
}
+ if (query.ItemIds.Length > 0)
+ {
+ var excludeIds = new List<string>();
+
+ var index = 0;
+ foreach (var id in query.ItemIds)
+ {
+ excludeIds.Add("Guid = @IncludeId" + index);
+ cmd.Parameters.Add(cmd, "@IncludeId" + index, DbType.Guid).Value = new Guid(id);
+ index++;
+ }
+
+ whereClauses.Add(string.Join(" OR ", excludeIds.ToArray()));
+ }
if (query.ExcludeItemIds.Length > 0)
{
var excludeIds = new List<string>();
@@ -3478,7 +3495,292 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
}
- private List<Tuple<int, string>> GetItemValues(BaseItem item)
+ public QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query)
+ {
+ return GetItemValues(query, 0, typeof(MusicArtist).FullName);
+ }
+
+ public QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query)
+ {
+ return GetItemValues(query, 1, typeof(MusicArtist).FullName);
+ }
+
+ public QueryResult<Tuple<BaseItem, ItemCounts>> GetStudios(InternalItemsQuery query)
+ {
+ return GetItemValues(query, 3, typeof(Studio).FullName);
+ }
+
+ public QueryResult<Tuple<BaseItem, ItemCounts>> GetGenres(InternalItemsQuery query)
+ {
+ return GetItemValues(query, 2, typeof(Genre).FullName);
+ }
+
+ public QueryResult<Tuple<BaseItem, ItemCounts>> GetGameGenres(InternalItemsQuery query)
+ {
+ return GetItemValues(query, 2, typeof(GameGenre).FullName);
+ }
+
+ public QueryResult<Tuple<BaseItem, ItemCounts>> GetMusicGenres(InternalItemsQuery query)
+ {
+ return GetItemValues(query, 2, typeof(MusicGenre).FullName);
+ }
+
+ private QueryResult<Tuple<BaseItem, ItemCounts>> GetItemValues(InternalItemsQuery query, int itemValueType, string returnType)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException("query");
+ }
+
+ if (!query.Limit.HasValue)
+ {
+ query.EnableTotalRecordCount = false;
+ }
+
+ CheckDisposed();
+
+ var now = DateTime.UtcNow;
+
+ using (var cmd = _connection.CreateCommand())
+ {
+ var itemCountColumns = new List<Tuple<string, string>>();
+
+ var typesToCount = query.IncludeItemTypes.ToList();
+
+ if (typesToCount.Count == 0)
+ {
+ //typesToCount.Add("Item");
+ }
+
+ foreach (var type in typesToCount)
+ {
+ var itemCountColumnQuery = "Select Count(Value) from ItemValues where ItemValues.CleanValue=CleanName AND Type=@ItemValueType AND ItemId in (";
+ itemCountColumnQuery += "select guid" + GetFromText();
+
+ var typeSubQuery = new InternalItemsQuery(query.User)
+ {
+ ExcludeItemTypes = query.ExcludeItemTypes,
+ MediaTypes = query.MediaTypes,
+ AncestorIds = query.AncestorIds,
+ ExcludeItemIds = query.ExcludeItemIds,
+ ItemIds = query.ItemIds,
+ TopParentIds = query.TopParentIds,
+ ParentId = query.ParentId,
+ IsPlayed = query.IsPlayed
+ };
+ if (string.Equals(type, "Item", StringComparison.OrdinalIgnoreCase))
+ {
+ typeSubQuery.IncludeItemTypes = query.IncludeItemTypes;
+ }
+ else
+ {
+ typeSubQuery.IncludeItemTypes = new[] { type };
+ }
+ var whereClauses = GetWhereClauses(typeSubQuery, cmd, type);
+
+ var typeWhereText = whereClauses.Count == 0 ?
+ string.Empty :
+ " where " + string.Join(" AND ", whereClauses.ToArray());
+
+ itemCountColumnQuery += typeWhereText;
+
+ itemCountColumnQuery += ")";
+
+ var columnName = type + "Count";
+
+ itemCountColumns.Add(new Tuple<string, string>(columnName, "(" + itemCountColumnQuery + ") as " + columnName));
+ }
+
+ var columns = _retriveItemColumns.ToList();
+ columns.AddRange(itemCountColumns.Select(i => i.Item2).ToArray());
+
+ cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, columns.ToArray(), cmd)) + GetFromText();
+ cmd.CommandText += GetJoinUserDataText(query);
+
+ var innerQuery = new InternalItemsQuery(query.User)
+ {
+ ExcludeItemTypes = query.ExcludeItemTypes,
+ IncludeItemTypes = query.IncludeItemTypes,
+ MediaTypes = query.MediaTypes,
+ AncestorIds = query.AncestorIds,
+ ExcludeItemIds = query.ExcludeItemIds,
+ ItemIds = query.ItemIds,
+ TopParentIds = query.TopParentIds,
+ ParentId = query.ParentId,
+ IsPlayed = query.IsPlayed
+ };
+
+ var innerWhereClauses = GetWhereClauses(innerQuery, cmd);
+
+ var innerWhereText = innerWhereClauses.Count == 0 ?
+ string.Empty :
+ " where " + string.Join(" AND ", innerWhereClauses.ToArray());
+
+ var whereText = " where Type=@SelectType";
+ whereText += " And CleanName In (Select CleanValue from ItemValues where Type=@ItemValueType AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))";
+ cmd.CommandText += whereText;
+
+ var outerQuery = new InternalItemsQuery(query.User)
+ {
+ IsFavorite = query.IsFavorite,
+ IsFavoriteOrLiked = query.IsFavoriteOrLiked,
+ IsLiked = query.IsLiked,
+ IsLocked = query.IsLocked,
+ NameLessThan = query.NameLessThan,
+ NameStartsWith = query.NameStartsWith,
+ NameStartsWithOrGreater = query.NameStartsWithOrGreater,
+ AlbumArtistStartsWithOrGreater = query.AlbumArtistStartsWithOrGreater,
+ Tags = query.Tags,
+ OfficialRatings = query.OfficialRatings,
+ Genres = query.GenreIds,
+ Years = query.Years
+ };
+
+ var outerWhereClauses = GetWhereClauses(outerQuery, cmd);
+
+ var outerWhereText = outerWhereClauses.Count == 0 ?
+ string.Empty :
+ " AND " + string.Join(" AND ", outerWhereClauses.ToArray());
+ cmd.CommandText += outerWhereText;
+
+ cmd.Parameters.Add(cmd, "@SelectType", DbType.String).Value = returnType;
+ cmd.Parameters.Add(cmd, "@ItemValueType", DbType.Int32).Value = itemValueType;
+
+ if (EnableJoinUserData(query))
+ {
+ cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = query.User.Id;
+ }
+
+ //cmd.CommandText += GetGroupBy(query);
+ cmd.CommandText += " group by PresentationUniqueKey";
+
+ cmd.CommandText += " order by SortName";
+
+ if (query.Limit.HasValue || query.StartIndex.HasValue)
+ {
+ var limit = query.Limit ?? int.MaxValue;
+
+ cmd.CommandText += " LIMIT " + limit.ToString(CultureInfo.InvariantCulture);
+
+ if (query.StartIndex.HasValue)
+ {
+ cmd.CommandText += " OFFSET " + query.StartIndex.Value.ToString(CultureInfo.InvariantCulture);
+ }
+ }
+
+ cmd.CommandText += ";";
+
+ var isReturningZeroItems = query.Limit.HasValue && query.Limit <= 0;
+
+ if (isReturningZeroItems)
+ {
+ cmd.CommandText = "";
+ }
+
+ if (query.EnableTotalRecordCount)
+ {
+ cmd.CommandText += "select count (guid)" + GetFromText();
+
+ cmd.CommandText += GetJoinUserDataText(query);
+ cmd.CommandText += whereText;
+ }
+ else
+ {
+ cmd.CommandText = cmd.CommandText.TrimEnd(';');
+ }
+
+ var list = new List<Tuple<BaseItem, ItemCounts>>();
+ var count = 0;
+
+ var commandBehavior = isReturningZeroItems || !query.EnableTotalRecordCount
+ ? (CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)
+ : CommandBehavior.SequentialAccess;
+
+ using (var reader = cmd.ExecuteReader(commandBehavior))
+ {
+ LogQueryTime("GetItemValues", cmd, now);
+
+ if (isReturningZeroItems)
+ {
+ if (reader.Read())
+ {
+ count = reader.GetInt32(0);
+ }
+ }
+ else
+ {
+ while (reader.Read())
+ {
+ var item = GetItem(reader);
+ if (item != null)
+ {
+ var countStartColumn = columns.Count - typesToCount.Count;
+
+ list.Add(new Tuple<BaseItem, ItemCounts>(item, GetItemCounts(reader, countStartColumn, typesToCount)));
+ }
+ }
+
+ if (reader.NextResult() && reader.Read())
+ {
+ count = reader.GetInt32(0);
+ }
+ }
+ }
+
+ if (count == 0)
+ {
+ count = list.Count;
+ }
+
+ return new QueryResult<Tuple<BaseItem, ItemCounts>>
+ {
+ Items = list.ToArray(),
+ TotalRecordCount = count
+ };
+
+ }
+ }
+
+ private ItemCounts GetItemCounts(IDataReader reader, int countStartColumn, List<string> typesToCount)
+ {
+ var counts = new ItemCounts();
+
+ for (var i = 0; i < typesToCount.Count; i++)
+ {
+ var value = reader.GetInt32(countStartColumn + i);
+
+ var type = typesToCount[i];
+ if (string.Equals(type, "Series", StringComparison.OrdinalIgnoreCase))
+ {
+ counts.SeriesCount = value;
+ }
+ else if (string.Equals(type, "Episode", StringComparison.OrdinalIgnoreCase))
+ {
+ counts.EpisodeCount = value;
+ }
+ else if (string.Equals(type, "Movie", StringComparison.OrdinalIgnoreCase))
+ {
+ counts.MovieCount = value;
+ }
+ else if (string.Equals(type, "MusicAlbum", StringComparison.OrdinalIgnoreCase))
+ {
+ counts.AlbumCount = value;
+ }
+ else if (string.Equals(type, "Audio", StringComparison.OrdinalIgnoreCase))
+ {
+ counts.SongCount = value;
+ }
+ else if (string.Equals(type, "Game", StringComparison.OrdinalIgnoreCase))
+ {
+ counts.GameCount = value;
+ }
+ counts.ItemCount += value;
+ }
+
+ return counts;
+ }
+
+ private List<Tuple<int, string>> GetItemValuesToSave(BaseItem item)
{
var list = new List<Tuple<int, string>>();
@@ -3604,6 +3906,14 @@ namespace MediaBrowser.Server.Implementations.Persistence
_saveItemValuesCommand.GetParameter(0).Value = itemId;
_saveItemValuesCommand.GetParameter(1).Value = pair.Item1;
_saveItemValuesCommand.GetParameter(2).Value = pair.Item2;
+ if (pair.Item2 == null)
+ {
+ _saveItemValuesCommand.GetParameter(3).Value = null;
+ }
+ else
+ {
+ _saveItemValuesCommand.GetParameter(3).Value = pair.Item2.RemoveDiacritics();
+ }
_saveItemValuesCommand.Transaction = transaction;
_saveItemValuesCommand.ExecuteNonQuery();
diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config
index 42fc51a63..326721ff3 100644
--- a/MediaBrowser.Server.Implementations/packages.config
+++ b/MediaBrowser.Server.Implementations/packages.config
@@ -4,7 +4,7 @@
<package id="Emby.XmlTv" version="1.0.0.53" targetFramework="net45" />
<package id="ini-parser" version="2.3.0" targetFramework="net45" />
<package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" />
- <package id="MediaBrowser.Naming" version="1.0.0.51" targetFramework="net45" />
+ <package id="MediaBrowser.Naming" version="1.0.0.52" targetFramework="net45" />
<package id="Mono.Nat" version="1.2.24.0" targetFramework="net45" />
<package id="morelinq" version="1.4.0" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />