aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Data/SqliteItemRepository.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/Data/SqliteItemRepository.cs')
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs462
1 files changed, 204 insertions, 258 deletions
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 528acd069..165d17a57 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -7,6 +7,8 @@ using System.Runtime.Serialization;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Emby.Server.Implementations.Devices;
+using Emby.Server.Implementations.Playlists;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Collections;
using MediaBrowser.Controller.Configuration;
@@ -25,12 +27,11 @@ using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Serialization;
-using MediaBrowser.Server.Implementations.Devices;
-using MediaBrowser.Server.Implementations.Playlists;
using MediaBrowser.Model.Reflection;
using SQLitePCL.pretty;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Threading;
+using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Data
{
@@ -131,8 +132,7 @@ namespace Emby.Server.Implementations.Data
/// <summary>
/// Opens the connection to the database
/// </summary>
- /// <returns>Task.</returns>
- public async Task Initialize(SqliteUserDataRepository userDataRepo)
+ public void Initialize(SqliteUserDataRepository userDataRepo)
{
using (var connection = CreateConnection())
{
@@ -148,7 +148,7 @@ namespace Emby.Server.Implementations.Data
"create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
"create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
- "create index if not exists idx_AncestorIds2 on AncestorIds(AncestorIdText)",
+ "create index if not exists idx_AncestorIds5 on AncestorIds(AncestorIdText,ItemId)",
"create table if not exists ItemValues (ItemId GUID, Type INT, Value TEXT, CleanValue TEXT)",
@@ -190,7 +190,6 @@ namespace Emby.Server.Implementations.Data
AddColumn(db, "TypedBaseItems", "IsLocked", "BIT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "Name", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "OfficialRating", "Text", existingColumnNames);
-
AddColumn(db, "TypedBaseItems", "MediaType", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "Overview", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "ParentIndexNumber", "INT", existingColumnNames);
@@ -200,28 +199,21 @@ namespace Emby.Server.Implementations.Data
AddColumn(db, "TypedBaseItems", "Genres", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "SortName", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "ForcedSortName", "Text", existingColumnNames);
-
AddColumn(db, "TypedBaseItems", "RunTimeTicks", "BIGINT", existingColumnNames);
-
AddColumn(db, "TypedBaseItems", "HomePageUrl", "Text", existingColumnNames);
- AddColumn(db, "TypedBaseItems", "DisplayMediaType", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "DateCreated", "DATETIME", existingColumnNames);
AddColumn(db, "TypedBaseItems", "DateModified", "DATETIME", existingColumnNames);
-
AddColumn(db, "TypedBaseItems", "IsSeries", "BIT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "IsLive", "BIT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "IsNews", "BIT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "IsPremiere", "BIT", existingColumnNames);
-
AddColumn(db, "TypedBaseItems", "EpisodeTitle", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "IsRepeat", "BIT", existingColumnNames);
-
AddColumn(db, "TypedBaseItems", "PreferredMetadataLanguage", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "PreferredMetadataCountryCode", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "IsHD", "BIT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "ExternalEtag", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "DateLastRefreshed", "DATETIME", existingColumnNames);
-
AddColumn(db, "TypedBaseItems", "DateLastSaved", "DATETIME", existingColumnNames);
AddColumn(db, "TypedBaseItems", "IsInMixedFolder", "BIT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "LockedFields", "Text", existingColumnNames);
@@ -235,7 +227,6 @@ namespace Emby.Server.Implementations.Data
AddColumn(db, "TypedBaseItems", "TopParentId", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "TrailerTypes", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "CriticRating", "Float", existingColumnNames);
- AddColumn(db, "TypedBaseItems", "InheritedTags", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "CleanName", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "PresentationUniqueKey", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "OriginalTitle", "Text", existingColumnNames);
@@ -314,6 +305,9 @@ namespace Emby.Server.Implementations.Data
"drop index if exists idx_TypeSeriesPresentationUniqueKey",
"drop index if exists idx_SeriesPresentationUniqueKey",
"drop index if exists idx_TypeSeriesPresentationUniqueKey2",
+ "drop index if exists idx_AncestorIds3",
+ "drop index if exists idx_AncestorIds4",
+ "drop index if exists idx_AncestorIds2",
"create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)",
"create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)",
@@ -352,7 +346,10 @@ namespace Emby.Server.Implementations.Data
// items by name
"create index if not exists idx_ItemValues6 on ItemValues(ItemId,Type,CleanValue)",
- "create index if not exists idx_ItemValues7 on ItemValues(Type,CleanValue,ItemId)"
+ "create index if not exists idx_ItemValues7 on ItemValues(Type,CleanValue,ItemId)",
+
+ // Used to update inherited tags
+ "create index if not exists idx_ItemValues8 on ItemValues(Type, ItemId, Value)",
};
connection.RunQueries(postQueries);
@@ -421,7 +418,6 @@ namespace Emby.Server.Implementations.Data
"ProductionYear",
"OfficialRating",
"HomePageUrl",
- "DisplayMediaType",
"ForcedSortName",
"RunTimeTicks",
"DateCreated",
@@ -449,7 +445,6 @@ namespace Emby.Server.Implementations.Data
"SeriesId",
"PresentationUniqueKey",
"InheritedParentalRatingValue",
- "InheritedTags",
"ExternalSeriesId",
"Tagline",
"ProviderIds",
@@ -539,7 +534,6 @@ namespace Emby.Server.Implementations.Data
"ForcedSortName",
"RunTimeTicks",
"HomePageUrl",
- "DisplayMediaType",
"DateCreated",
"DateModified",
"PreferredMetadataLanguage",
@@ -559,7 +553,6 @@ namespace Emby.Server.Implementations.Data
"TopParentId",
"TrailerTypes",
"CriticRating",
- "InheritedTags",
"CleanName",
"PresentationUniqueKey",
"OriginalTitle",
@@ -606,16 +599,15 @@ namespace Emby.Server.Implementations.Data
/// </summary>
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException">item</exception>
- public Task SaveItem(BaseItem item, CancellationToken cancellationToken)
+ public void SaveItem(BaseItem item, CancellationToken cancellationToken)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
- return SaveItems(new List<BaseItem> { item }, cancellationToken);
+ SaveItems(new List<BaseItem> { item }, cancellationToken);
}
/// <summary>
@@ -623,13 +615,12 @@ namespace Emby.Server.Implementations.Data
/// </summary>
/// <param name="items">The items.</param>
/// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException">
/// items
/// or
/// cancellationToken
/// </exception>
- public async Task SaveItems(List<BaseItem> items, CancellationToken cancellationToken)
+ public void SaveItems(List<BaseItem> items, CancellationToken cancellationToken)
{
if (items == null)
{
@@ -640,7 +631,7 @@ namespace Emby.Server.Implementations.Data
CheckDisposed();
- var tuples = new List<Tuple<BaseItem, List<Guid>, BaseItem, string>>();
+ var tuples = new List<Tuple<BaseItem, List<Guid>, BaseItem, string, List<string>>>();
foreach (var item in items)
{
var ancestorIds = item.SupportsAncestors ?
@@ -650,8 +641,9 @@ namespace Emby.Server.Implementations.Data
var topParent = item.GetTopParent();
var userdataKey = item.GetUserDataKeys().FirstOrDefault();
+ var inheritedTags = item.GetInheritedTags();
- tuples.Add(new Tuple<BaseItem, List<Guid>, BaseItem, string>(item, ancestorIds, topParent, userdataKey));
+ tuples.Add(new Tuple<BaseItem, List<Guid>, BaseItem, string, List<string>>(item, ancestorIds, topParent, userdataKey, inheritedTags));
}
using (WriteLock.Write())
@@ -661,12 +653,13 @@ namespace Emby.Server.Implementations.Data
connection.RunInTransaction(db =>
{
SaveItemsInTranscation(db, tuples);
+
}, TransactionMode);
}
}
}
- private void SaveItemsInTranscation(IDatabaseConnection db, List<Tuple<BaseItem, List<Guid>, BaseItem, string>> tuples)
+ private void SaveItemsInTranscation(IDatabaseConnection db, List<Tuple<BaseItem, List<Guid>, BaseItem, string, List<string>>> tuples)
{
var requiresReset = false;
@@ -697,12 +690,14 @@ namespace Emby.Server.Implementations.Data
SaveItem(item, topParent, userDataKey, saveItemStatement);
//Logger.Debug(_saveItemCommand.CommandText);
+ var inheritedTags = tuple.Item5;
+
if (item.SupportsAncestors)
{
UpdateAncestors(item.Id, tuple.Item2, db, deleteAncestorsStatement, updateAncestorsStatement);
}
- UpdateItemValues(item.Id, GetItemValuesToSave(item), db);
+ UpdateItemValues(item.Id, GetItemValuesToSave(item, inheritedTags), db);
requiresReset = true;
}
@@ -813,7 +808,6 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@RunTimeTicks", item.RunTimeTicks);
saveItemStatement.TryBind("@HomePageUrl", item.HomePageUrl);
- saveItemStatement.TryBind("@DisplayMediaType", item.DisplayMediaType);
saveItemStatement.TryBind("@DateCreated", item.DateCreated);
saveItemStatement.TryBind("@DateModified", item.DateModified);
@@ -842,7 +836,7 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@IsInMixedFolder", item.IsInMixedFolder);
- if (item.LockedFields.Count > 0)
+ if (item.LockedFields.Length > 0)
{
saveItemStatement.TryBind("@LockedFields", string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray()));
}
@@ -851,7 +845,7 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBindNull("@LockedFields");
}
- if (item.Studios.Count > 0)
+ if (item.Studios.Length > 0)
{
saveItemStatement.TryBind("@Studios", string.Join("|", item.Studios.ToArray()));
}
@@ -871,9 +865,9 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@ExternalServiceId", item.ServiceName);
- if (item.Tags.Count > 0)
+ if (item.Tags.Length > 0)
{
- saveItemStatement.TryBind("@Tags", string.Join("|", item.Tags.ToArray()));
+ saveItemStatement.TryBind("@Tags", string.Join("|", item.Tags));
}
else
{
@@ -907,16 +901,6 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@CriticRating", item.CriticRating);
- var inheritedTags = item.InheritedTags;
- if (inheritedTags.Count > 0)
- {
- saveItemStatement.TryBind("@InheritedTags", string.Join("|", inheritedTags.ToArray()));
- }
- else
- {
- saveItemStatement.TryBindNull("@InheritedTags");
- }
-
if (string.IsNullOrWhiteSpace(item.Name))
{
saveItemStatement.TryBindNull("@CleanName");
@@ -1000,16 +984,16 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@ProviderIds", SerializeProviderIds(item));
saveItemStatement.TryBind("@Images", SerializeImages(item));
- if (item.ProductionLocations.Count > 0)
+ if (item.ProductionLocations.Length > 0)
{
- saveItemStatement.TryBind("@ProductionLocations", string.Join("|", item.ProductionLocations.ToArray()));
+ saveItemStatement.TryBind("@ProductionLocations", string.Join("|", item.ProductionLocations));
}
else
{
saveItemStatement.TryBindNull("@ProductionLocations");
}
- if (item.ThemeSongIds.Count > 0)
+ if (item.ThemeSongIds.Length > 0)
{
saveItemStatement.TryBind("@ThemeSongIds", string.Join("|", item.ThemeSongIds.ToArray()));
}
@@ -1018,7 +1002,7 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBindNull("@ThemeSongIds");
}
- if (item.ThemeVideoIds.Count > 0)
+ if (item.ThemeVideoIds.Length > 0)
{
saveItemStatement.TryBind("@ThemeVideoIds", string.Join("|", item.ThemeVideoIds.ToArray()));
}
@@ -1041,9 +1025,9 @@ namespace Emby.Server.Implementations.Data
var hasArtists = item as IHasArtist;
if (hasArtists != null)
{
- if (hasArtists.Artists.Count > 0)
+ if (hasArtists.Artists.Length > 0)
{
- artists = string.Join("|", hasArtists.Artists.ToArray());
+ artists = string.Join("|", hasArtists.Artists);
}
}
saveItemStatement.TryBind("@Artists", artists);
@@ -1052,9 +1036,9 @@ namespace Emby.Server.Implementations.Data
var hasAlbumArtists = item as IHasAlbumArtist;
if (hasAlbumArtists != null)
{
- if (hasAlbumArtists.AlbumArtists.Count > 0)
+ if (hasAlbumArtists.AlbumArtists.Length > 0)
{
- albumArtists = string.Join("|", hasAlbumArtists.AlbumArtists.ToArray());
+ albumArtists = string.Join("|", hasAlbumArtists.AlbumArtists);
}
}
saveItemStatement.TryBind("@AlbumArtists", albumArtists);
@@ -1105,9 +1089,9 @@ namespace Emby.Server.Implementations.Data
private string SerializeImages(BaseItem item)
{
- var images = item.ImageInfos.ToList();
+ var images = item.ImageInfos;
- if (images.Count == 0)
+ if (images.Length == 0)
{
return null;
}
@@ -1124,22 +1108,24 @@ namespace Emby.Server.Implementations.Data
return;
}
- if (item.ImageInfos.Count > 0)
+ if (item.ImageInfos.Length > 0)
{
return;
}
var parts = value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
-
+ var list = new List<ItemImageInfo>();
foreach (var part in parts)
{
var image = ItemImageInfoFromValueString(part);
if (image != null)
{
- item.ImageInfos.Add(image);
+ list.Add(image);
}
}
+
+ item.ImageInfos = list.ToArray(list.Count);
}
public string ToValueString(ItemImageInfo image)
@@ -1228,14 +1214,15 @@ namespace Emby.Server.Implementations.Data
{
return false;
}
- if (type == typeof(Season))
- {
- return false;
- }
- if (type == typeof(MusicArtist))
- {
- return false;
- }
+ }
+
+ if (type == typeof(Season))
+ {
+ return false;
+ }
+ if (type == typeof(MusicArtist))
+ {
+ return false;
}
if (type == typeof(Person))
@@ -1306,16 +1293,13 @@ namespace Emby.Server.Implementations.Data
return false;
}
- if (_config.Configuration.SkipDeserializationForAudio)
+ if (type == typeof(Audio))
{
- if (type == typeof(Audio))
- {
- return false;
- }
- if (type == typeof(MusicAlbum))
- {
- return false;
- }
+ return false;
+ }
+ if (type == typeof(MusicAlbum))
+ {
+ return false;
}
return true;
@@ -1586,15 +1570,6 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (HasField(query, ItemFields.DisplayMediaType))
- {
- if (!reader.IsDBNull(index))
- {
- item.DisplayMediaType = reader.GetString(index);
- }
- index++;
- }
-
if (HasField(query, ItemFields.SortName))
{
if (!reader.IsDBNull(index))
@@ -1690,7 +1665,7 @@ namespace Emby.Server.Implementations.Data
return parsedValue;
}
return (MetadataFields?)null;
- }).Where(i => i.HasValue).Select(i => i.Value).ToList();
+ }).Where(i => i.HasValue).Select(i => i.Value).ToArray();
}
index++;
}
@@ -1699,7 +1674,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
- item.Studios = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+ item.Studios = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
}
index++;
}
@@ -1708,7 +1683,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
- item.Tags = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+ item.Tags = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
}
index++;
}
@@ -1849,15 +1824,6 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (HasField(query, ItemFields.Tags))
- {
- if (!reader.IsDBNull(index))
- {
- item.InheritedTags = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
- }
- index++;
- }
-
if (HasField(query, ItemFields.ExternalSeriesId))
{
if (!reader.IsDBNull(index))
@@ -1895,7 +1861,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
- item.ProductionLocations = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+ item.ProductionLocations = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray();
}
index++;
}
@@ -1904,7 +1870,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
- item.ThemeSongIds = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList();
+ item.ThemeSongIds = SplitToGuids(reader.GetString(index));
}
index++;
}
@@ -1913,7 +1879,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
- item.ThemeVideoIds = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList();
+ item.ThemeVideoIds = SplitToGuids(reader.GetString(index));
}
index++;
}
@@ -1939,14 +1905,14 @@ namespace Emby.Server.Implementations.Data
var hasArtists = item as IHasArtist;
if (hasArtists != null && !reader.IsDBNull(index))
{
- hasArtists.Artists = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+ hasArtists.Artists = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
}
index++;
var hasAlbumArtists = item as IHasAlbumArtist;
if (hasAlbumArtists != null && !reader.IsDBNull(index))
{
- hasAlbumArtists.AlbumArtists = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+ hasAlbumArtists.AlbumArtists = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
}
index++;
}
@@ -1972,45 +1938,36 @@ namespace Emby.Server.Implementations.Data
return item;
}
+ private Guid[] SplitToGuids(string value)
+ {
+ var ids = value.Split('|');
+
+ var result = new Guid[ids.Length];
+
+ for (var i = 0; i < result.Length; i++)
+ {
+ result[i] = new Guid(ids[i]);
+ }
+
+ return result;
+ }
+
/// <summary>
/// Gets the critic reviews.
/// </summary>
/// <param name="itemId">The item id.</param>
- /// <returns>Task{IEnumerable{ItemReview}}.</returns>
- public IEnumerable<ItemReview> GetCriticReviews(Guid itemId)
+ public List<ItemReview> GetCriticReviews(Guid itemId)
{
- try
- {
- var path = Path.Combine(_criticReviewsPath, itemId + ".json");
-
- return _jsonSerializer.DeserializeFromFile<List<ItemReview>>(path);
- }
- catch (FileNotFoundException)
- {
- return new List<ItemReview>();
- }
- catch (IOException)
- {
- return new List<ItemReview>();
- }
+ return new List<ItemReview>();
}
- private readonly Task _cachedTask = Task.FromResult(true);
/// <summary>
/// Saves the critic reviews.
/// </summary>
/// <param name="itemId">The item id.</param>
/// <param name="criticReviews">The critic reviews.</param>
- /// <returns>Task.</returns>
- public Task SaveCriticReviews(Guid itemId, IEnumerable<ItemReview> criticReviews)
+ public void SaveCriticReviews(Guid itemId, IEnumerable<ItemReview> criticReviews)
{
- _fileSystem.CreateDirectory(_criticReviewsPath);
-
- var path = Path.Combine(_criticReviewsPath, itemId + ".json");
-
- _jsonSerializer.SerializeToFile(criticReviews.ToList(), path);
-
- return _cachedTask;
}
/// <summary>
@@ -2019,7 +1976,7 @@ namespace Emby.Server.Implementations.Data
/// <param name="id">The id.</param>
/// <returns>IEnumerable{ChapterInfo}.</returns>
/// <exception cref="System.ArgumentNullException">id</exception>
- public IEnumerable<ChapterInfo> GetChapters(Guid id)
+ public List<ChapterInfo> GetChapters(Guid id)
{
CheckDisposed();
if (id == Guid.Empty)
@@ -2115,18 +2072,7 @@ namespace Emby.Server.Implementations.Data
/// <summary>
/// Saves the chapters.
/// </summary>
- /// <param name="id">The id.</param>
- /// <param name="chapters">The chapters.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
- /// <exception cref="System.ArgumentNullException">
- /// id
- /// or
- /// chapters
- /// or
- /// cancellationToken
- /// </exception>
- public async Task SaveChapters(Guid id, List<ChapterInfo> chapters, CancellationToken cancellationToken)
+ public void SaveChapters(Guid id, List<ChapterInfo> chapters)
{
CheckDisposed();
@@ -2140,8 +2086,6 @@ namespace Emby.Server.Implementations.Data
throw new ArgumentNullException("chapters");
}
- cancellationToken.ThrowIfCancellationRequested();
-
var index = 0;
using (WriteLock.Write())
@@ -2191,8 +2135,7 @@ namespace Emby.Server.Implementations.Data
//return true;
}
- var sortingFields = query.SortBy.ToList();
- sortingFields.AddRange(query.OrderBy.Select(i => i.Item1));
+ var sortingFields = query.OrderBy.Select(i => i.Item1).ToList();
if (sortingFields.Contains(ItemSortBy.IsFavoriteOrLiked, StringComparer.OrdinalIgnoreCase))
{
@@ -2247,7 +2190,7 @@ namespace Emby.Server.Implementations.Data
return false;
}
- private List<ItemFields> allFields = Enum.GetNames(typeof(ItemFields))
+ private readonly List<ItemFields> allFields = Enum.GetNames(typeof(ItemFields))
.Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
.ToList();
@@ -2271,7 +2214,7 @@ namespace Emby.Server.Implementations.Data
}
if (field == ItemFields.Tags)
{
- return new[] { "Tags", "InheritedTags" };
+ return new[] { "Tags" };
}
return new[] { field.ToString() };
@@ -2284,7 +2227,6 @@ namespace Emby.Server.Implementations.Data
switch (name)
{
case ItemFields.HomePageUrl:
- case ItemFields.DisplayMediaType:
case ItemFields.CustomRating:
case ItemFields.ProductionLocations:
case ItemFields.Settings:
@@ -2589,11 +2531,11 @@ namespace Emby.Server.Implementations.Data
}
}
- query.ExcludeItemIds = excludeIds.ToArray();
+ query.ExcludeItemIds = excludeIds.ToArray(excludeIds.Count);
query.ExcludeProviderIds = item.ProviderIds;
}
- return list.ToArray();
+ return list.ToArray(list.Count);
}
private void BindSimilarParams(InternalItemsQuery query, IStatement statement)
@@ -2629,9 +2571,14 @@ namespace Emby.Server.Implementations.Data
groups.Add("PresentationUniqueKey");
}
+ if (query.GroupBySeriesPresentationUniqueKey)
+ {
+ groups.Add("SeriesPresentationUniqueKey");
+ }
+
if (groups.Count > 0)
{
- return " Group by " + string.Join(",", groups.ToArray());
+ return " Group by " + string.Join(",", groups.ToArray(groups.Count));
}
return string.Empty;
@@ -2668,7 +2615,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
- " where " + string.Join(" AND ", whereClauses.ToArray());
+ " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
commandText += whereText;
@@ -2725,7 +2672,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
- " where " + string.Join(" AND ", whereClauses.ToArray());
+ " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
commandText += whereText;
@@ -2845,7 +2792,7 @@ namespace Emby.Server.Implementations.Data
var slowThreshold = 1000;
#if DEBUG
- slowThreshold = 2;
+ slowThreshold = 10;
#endif
if (elapsed >= slowThreshold)
@@ -2878,7 +2825,7 @@ namespace Emby.Server.Implementations.Data
var returnList = GetItemList(query);
return new QueryResult<BaseItem>
{
- Items = returnList.ToArray(),
+ Items = returnList.ToArray(returnList.Count),
TotalRecordCount = returnList.Count
};
}
@@ -2901,7 +2848,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
- " where " + string.Join(" AND ", whereClauses.ToArray());
+ " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
var whereTextWithoutPaging = whereText;
@@ -2941,6 +2888,10 @@ namespace Emby.Server.Implementations.Data
{
commandText += " select count (distinct PresentationUniqueKey)" + GetFromText();
}
+ else if (query.GroupBySeriesPresentationUniqueKey)
+ {
+ commandText += " select count (distinct SeriesPresentationUniqueKey)" + GetFromText();
+ }
else
{
commandText += " select count (guid)" + GetFromText();
@@ -2958,8 +2909,7 @@ namespace Emby.Server.Implementations.Data
return connection.RunInTransaction(db =>
{
var result = new QueryResult<BaseItem>();
- var statements = PrepareAllSafe(db, statementTexts)
- .ToList();
+ var statements = PrepareAllSafe(db, statementTexts);
if (!isReturningZeroItems)
{
@@ -3013,7 +2963,7 @@ namespace Emby.Server.Implementations.Data
LogQueryTime("GetItems", commandText, now);
- result.Items = list.ToArray();
+ result.Items = list.ToArray(list.Count);
return result;
}, ReadTransactionMode);
@@ -3024,16 +2974,7 @@ namespace Emby.Server.Implementations.Data
private string GetOrderByText(InternalItemsQuery query)
{
var orderBy = query.OrderBy.ToList();
- var enableOrderInversion = true;
-
- if (orderBy.Count == 0)
- {
- orderBy.AddRange(query.SortBy.Select(i => new Tuple<string, SortOrder>(i, query.SortOrder)));
- }
- else
- {
- enableOrderInversion = false;
- }
+ var enableOrderInversion = false;
if (query.SimilarTo != null)
{
@@ -3042,12 +2983,10 @@ namespace Emby.Server.Implementations.Data
orderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending));
orderBy.Add(new Tuple<string, SortOrder>("SimilarityScore", SortOrder.Descending));
//orderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending));
- query.SortOrder = SortOrder.Descending;
- enableOrderInversion = false;
}
}
- query.OrderBy = orderBy;
+ query.OrderBy = orderBy.ToArray();
if (orderBy.Count == 0)
{
@@ -3086,6 +3025,11 @@ namespace Emby.Server.Implementations.Data
}
if (string.Equals(name, ItemSortBy.DatePlayed, StringComparison.OrdinalIgnoreCase))
{
+ if (query.GroupBySeriesPresentationUniqueKey)
+ {
+ return new Tuple<string, bool>("MAX(LastPlayedDate)", false);
+ }
+
return new Tuple<string, bool>("LastPlayedDate", false);
}
if (string.Equals(name, ItemSortBy.PlayCount, StringComparison.OrdinalIgnoreCase))
@@ -3160,7 +3104,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
- " where " + string.Join(" AND ", whereClauses.ToArray());
+ " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
commandText += whereText;
@@ -3231,7 +3175,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
- " where " + string.Join(" AND ", whereClauses.ToArray());
+ " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
commandText += whereText;
@@ -3304,7 +3248,7 @@ namespace Emby.Server.Implementations.Data
var returnList = GetItemIdsList(query);
return new QueryResult<Guid>
{
- Items = returnList.ToArray(),
+ Items = returnList.ToArray(returnList.Count),
TotalRecordCount = returnList.Count
};
}
@@ -3319,7 +3263,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
- " where " + string.Join(" AND ", whereClauses.ToArray());
+ " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
var whereTextWithoutPaging = whereText;
@@ -3360,6 +3304,10 @@ namespace Emby.Server.Implementations.Data
{
commandText += " select count (distinct PresentationUniqueKey)" + GetFromText();
}
+ else if (query.GroupBySeriesPresentationUniqueKey)
+ {
+ commandText += " select count (distinct SeriesPresentationUniqueKey)" + GetFromText();
+ }
else
{
commandText += " select count (guid)" + GetFromText();
@@ -3378,8 +3326,7 @@ namespace Emby.Server.Implementations.Data
{
var result = new QueryResult<Guid>();
- var statements = PrepareAllSafe(db, statementTexts)
- .ToList();
+ var statements = PrepareAllSafe(db, statementTexts);
if (!isReturningZeroItems)
{
@@ -3422,7 +3369,7 @@ namespace Emby.Server.Implementations.Data
LogQueryTime("GetItemIds", commandText, now);
- result.Items = list.ToArray();
+ result.Items = list.ToArray(list.Count);
return result;
}, ReadTransactionMode);
@@ -3627,7 +3574,7 @@ namespace Emby.Server.Implementations.Data
}
if (programAttribtues.Count > 0)
{
- whereClauses.Add("(" + string.Join(" OR ", programAttribtues.ToArray()) + ")");
+ whereClauses.Add("(" + string.Join(" OR ", programAttribtues.ToArray(programAttribtues.Count)) + ")");
}
}
@@ -4296,12 +4243,13 @@ namespace Emby.Server.Implementations.Data
whereClauses.Add("ProductionYear in (" + val + ")");
}
- if (query.IsVirtualItem.HasValue)
+ var isVirtualItem = query.IsVirtualItem ?? query.IsMissing;
+ if (isVirtualItem.HasValue)
{
whereClauses.Add("IsVirtualItem=@IsVirtualItem");
if (statement != null)
{
- statement.TryBind("@IsVirtualItem", query.IsVirtualItem.Value);
+ statement.TryBind("@IsVirtualItem", isVirtualItem.Value);
}
}
if (query.IsSpecialSeason.HasValue)
@@ -4326,28 +4274,6 @@ namespace Emby.Server.Implementations.Data
whereClauses.Add("PremiereDate < DATETIME('now')");
}
}
- if (query.IsMissing.HasValue)
- {
- if (query.IsMissing.Value)
- {
- whereClauses.Add("(IsVirtualItem=1 AND PremiereDate < DATETIME('now'))");
- }
- else
- {
- whereClauses.Add("(IsVirtualItem=0 OR PremiereDate >= DATETIME('now'))");
- }
- }
- if (query.IsVirtualUnaired.HasValue)
- {
- if (query.IsVirtualUnaired.Value)
- {
- whereClauses.Add("(IsVirtualItem=1 AND PremiereDate >= DATETIME('now'))");
- }
- else
- {
- whereClauses.Add("(IsVirtualItem=0 OR PremiereDate < DATETIME('now'))");
- }
- }
var queryMediaTypes = query.MediaTypes.Where(IsValidMediaType).ToArray();
if (queryMediaTypes.Length == 1)
{
@@ -4563,26 +4489,12 @@ namespace Emby.Server.Implementations.Data
whereClauses.Add(string.Format("(InheritedParentalRatingValue > 0 or UnratedType not in ({0}))", inClause));
}
- var excludeTagIndex = 0;
- foreach (var excludeTag in query.ExcludeTags)
+ if (query.ExcludeInheritedTags.Length > 0)
{
- whereClauses.Add("(Tags is null OR Tags not like @excludeTag" + excludeTagIndex + ")");
- if (statement != null)
- {
- statement.TryBind("@excludeTag" + excludeTagIndex, "%" + excludeTag + "%");
- }
- excludeTagIndex++;
- }
+ var tagValues = query.ExcludeInheritedTags.Select(i => "'" + GetCleanValue(i) + "'").ToArray();
+ var tagValuesList = string.Join(",", tagValues);
- excludeTagIndex = 0;
- foreach (var excludeTag in query.ExcludeInheritedTags)
- {
- whereClauses.Add("(InheritedTags is null OR InheritedTags not like @excludeInheritedTag" + excludeTagIndex + ")");
- if (statement != null)
- {
- statement.TryBind("@excludeInheritedTag" + excludeTagIndex, "%" + excludeTag + "%");
- }
- excludeTagIndex++;
+ whereClauses.Add("((select CleanValue from itemvalues where ItemId=Guid and Type=6 and cleanvalue in (" + tagValuesList + ")) is null)");
}
return whereClauses;
@@ -4647,6 +4559,11 @@ namespace Emby.Server.Implementations.Data
return false;
}
+ if (query.GroupBySeriesPresentationUniqueKey)
+ {
+ return false;
+ }
+
if (!string.IsNullOrWhiteSpace(query.PresentationUniqueKey))
{
return false;
@@ -4718,48 +4635,72 @@ namespace Emby.Server.Implementations.Data
typeof(AggregateFolder)
};
- public async Task UpdateInheritedValues(CancellationToken cancellationToken)
+ public void UpdateInheritedValues(CancellationToken cancellationToken)
{
- await UpdateInheritedTags(cancellationToken).ConfigureAwait(false);
+ UpdateInheritedTags(cancellationToken);
}
- private async Task UpdateInheritedTags(CancellationToken cancellationToken)
+ private void UpdateInheritedTags(CancellationToken cancellationToken)
{
- var newValues = new List<Tuple<Guid, string>>();
+ var newValues = new List<Tuple<Guid, string[]>>();
- var commandText = "select Guid,InheritedTags,(select group_concat(Tags, '|') from TypedBaseItems where (guid=outer.guid) OR (guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid))) as NewInheritedTags from typedbaseitems as Outer where NewInheritedTags <> InheritedTags";
+ var commandText = @"select guid,
+(select group_concat(Value, '|') from ItemValues where (ItemValues.ItemId = Outer.Guid OR ItemValues.ItemId in ((Select AncestorId from AncestorIds where AncestorIds.ItemId=Outer.guid))) and ItemValues.Type = 4) NewInheritedTags,
+(select group_concat(Value, '|') from ItemValues where ItemValues.ItemId = Outer.Guid and ItemValues.Type = 6) CurrentInheritedTags
+from typedbaseitems as Outer
+where (NewInheritedTags <> CurrentInheritedTags or (NewInheritedTags is null) <> (CurrentInheritedTags is null))
+limit 100";
using (WriteLock.Write())
{
using (var connection = CreateConnection())
{
- foreach (var row in connection.Query(commandText))
+ connection.RunInTransaction(db =>
{
- var id = row.GetGuid(0);
- string value = row.IsDBNull(2) ? null : row.GetString(2);
+ foreach (var row in connection.Query(commandText))
+ {
+ var id = row.GetGuid(0);
+ string value = row.IsDBNull(1) ? null : row.GetString(1);
- newValues.Add(new Tuple<Guid, string>(id, value));
- }
+ var valuesArray = string.IsNullOrWhiteSpace(value) ? new string[] { } : value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
- Logger.Debug("UpdateInheritedTags - {0} rows", newValues.Count);
- if (newValues.Count == 0)
- {
- return;
- }
+ newValues.Add(new Tuple<Guid, string[]>(id, valuesArray));
+ }
- // write lock here
- using (var statement = PrepareStatement(connection, "Update TypedBaseItems set InheritedTags=@InheritedTags where Guid=@Guid"))
- {
- foreach (var item in newValues)
+ Logger.Debug("UpdateInheritedTags - {0} rows", newValues.Count);
+ if (newValues.Count == 0)
{
- var paramList = new List<object>();
+ return;
+ }
- paramList.Add(item.Item1);
- paramList.Add(item.Item2);
+ using (var insertStatement = PrepareStatement(connection, "insert into ItemValues (ItemId, Type, Value, CleanValue) values (@ItemId, 6, @Value, @CleanValue)"))
+ {
+ using (var deleteStatement = PrepareStatement(connection, "delete from ItemValues where ItemId=@ItemId and Type=6"))
+ {
+ foreach (var item in newValues)
+ {
+ var guidBlob = item.Item1.ToGuidBlob();
- statement.Execute(paramList.ToArray());
+ deleteStatement.Reset();
+ deleteStatement.TryBind("@ItemId", guidBlob);
+ deleteStatement.MoveNext();
+
+ foreach (var itemValue in item.Item2)
+ {
+ insertStatement.Reset();
+
+ insertStatement.TryBind("@ItemId", guidBlob);
+ insertStatement.TryBind("@Value", itemValue);
+
+ insertStatement.TryBind("@CleanValue", GetCleanValue(itemValue));
+
+ insertStatement.MoveNext();
+ }
+ }
+ }
}
- }
+
+ }, TransactionMode);
}
}
}
@@ -4794,7 +4735,7 @@ namespace Emby.Server.Implementations.Data
return new[] { value }.Where(IsValidType);
}
- public async Task DeleteItem(Guid id, CancellationToken cancellationToken)
+ public void DeleteItem(Guid id, CancellationToken cancellationToken)
{
if (id == Guid.Empty)
{
@@ -5161,9 +5102,9 @@ namespace Emby.Server.Implementations.Data
var itemCountColumns = new List<Tuple<string, string>>();
- var typesToCount = query.IncludeItemTypes.ToList();
+ var typesToCount = query.IncludeItemTypes;
- if (typesToCount.Count > 0)
+ if (typesToCount.Length > 0)
{
var itemCountColumnQuery = "select group_concat(type, '|')" + GetFromText("B");
@@ -5223,7 +5164,7 @@ namespace Emby.Server.Implementations.Data
var whereText = " where Type=@SelectType";
- if (typesToCount.Count == 0)
+ if (typesToCount.Length == 0)
{
whereText += " And CleanName In (Select CleanValue from ItemValues where " + typeClause + " AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))";
}
@@ -5301,8 +5242,7 @@ namespace Emby.Server.Implementations.Data
var list = new List<Tuple<BaseItem, ItemCounts>>();
var result = new QueryResult<Tuple<BaseItem, ItemCounts>>();
- var statements = PrepareAllSafe(db, statementTexts)
- .ToList();
+ var statements = PrepareAllSafe(db, statementTexts);
if (!isReturningZeroItems)
{
@@ -5377,7 +5317,7 @@ namespace Emby.Server.Implementations.Data
{
result.TotalRecordCount = list.Count;
}
- result.Items = list.ToArray();
+ result.Items = list.ToArray(list.Count);
return result;
@@ -5386,11 +5326,11 @@ namespace Emby.Server.Implementations.Data
}
}
- private ItemCounts GetItemCounts(IReadOnlyList<IResultSetValue> reader, int countStartColumn, List<string> typesToCount)
+ private ItemCounts GetItemCounts(IReadOnlyList<IResultSetValue> reader, int countStartColumn, string[] typesToCount)
{
var counts = new ItemCounts();
- if (typesToCount.Count == 0)
+ if (typesToCount.Length == 0)
{
return counts;
}
@@ -5448,7 +5388,7 @@ namespace Emby.Server.Implementations.Data
return counts;
}
- private List<Tuple<int, string>> GetItemValuesToSave(BaseItem item)
+ private List<Tuple<int, string>> GetItemValuesToSave(BaseItem item, List<string> inheritedTags)
{
var list = new List<Tuple<int, string>>();
@@ -5468,6 +5408,10 @@ namespace Emby.Server.Implementations.Data
list.AddRange(item.Studios.Select(i => new Tuple<int, string>(3, i)));
list.AddRange(item.Tags.Select(i => new Tuple<int, string>(4, i)));
+ // keywords was 5
+
+ list.AddRange(inheritedTags.Select(i => new Tuple<int, string>(6, i)));
+
return list;
}
@@ -5485,8 +5429,10 @@ namespace Emby.Server.Implementations.Data
CheckDisposed();
+ var guidBlob = itemId.ToGuidBlob();
+
// First delete
- db.Execute("delete from ItemValues where ItemId=@Id", itemId.ToGuidBlob());
+ db.Execute("delete from ItemValues where ItemId=@Id", guidBlob);
using (var statement = PrepareStatement(db, "insert into ItemValues (ItemId, Type, Value, CleanValue) values (@ItemId, @Type, @Value, @CleanValue)"))
{
@@ -5502,7 +5448,7 @@ namespace Emby.Server.Implementations.Data
statement.Reset();
- statement.TryBind("@ItemId", itemId.ToGuidBlob());
+ statement.TryBind("@ItemId", guidBlob);
statement.TryBind("@Type", pair.Item1);
statement.TryBind("@Value", itemValue);
@@ -5520,7 +5466,7 @@ namespace Emby.Server.Implementations.Data
}
}
- public async Task UpdatePeople(Guid itemId, List<PersonInfo> people)
+ public void UpdatePeople(Guid itemId, List<PersonInfo> people)
{
if (itemId == Guid.Empty)
{
@@ -5594,7 +5540,7 @@ namespace Emby.Server.Implementations.Data
return item;
}
- public IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query)
+ public List<MediaStream> GetMediaStreams(MediaStreamQuery query)
{
CheckDisposed();
@@ -5650,7 +5596,7 @@ namespace Emby.Server.Implementations.Data
}
}
- public async Task SaveMediaStreams(Guid id, List<MediaStream> streams, CancellationToken cancellationToken)
+ public void SaveMediaStreams(Guid id, List<MediaStream> streams, CancellationToken cancellationToken)
{
CheckDisposed();