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.cs548
1 files changed, 270 insertions, 278 deletions
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 1cefcec7c..31a661c5d 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -5,8 +5,11 @@ using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
using System.Threading;
using Emby.Server.Implementations.Playlists;
+using MediaBrowser.Common.Json;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
@@ -38,14 +41,6 @@ namespace Emby.Server.Implementations.Data
{
private const string ChaptersTableName = "Chapters2";
- private readonly TypeMapper _typeMapper;
-
- /// <summary>
- /// Gets the json serializer.
- /// </summary>
- /// <value>The json serializer.</value>
- private readonly IJsonSerializer _jsonSerializer;
-
/// <summary>
/// The _app paths
/// </summary>
@@ -53,33 +48,31 @@ namespace Emby.Server.Implementations.Data
private readonly IServerApplicationHost _appHost;
private readonly ILocalizationManager _localization;
+ private readonly TypeMapper _typeMapper;
+ private readonly JsonSerializerOptions _jsonOptions;
+
/// <summary>
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
/// </summary>
public SqliteItemRepository(
IServerConfigurationManager config,
IServerApplicationHost appHost,
- IJsonSerializer jsonSerializer,
- ILoggerFactory loggerFactory,
+ ILogger<SqliteItemRepository> logger,
ILocalizationManager localization)
- : base(loggerFactory.CreateLogger(nameof(SqliteItemRepository)))
+ : base(logger)
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
- if (jsonSerializer == null)
- {
- throw new ArgumentNullException(nameof(jsonSerializer));
- }
-
- _appHost = appHost;
_config = config;
- _jsonSerializer = jsonSerializer;
- _typeMapper = new TypeMapper();
+ _appHost = appHost;
_localization = localization;
+ _typeMapper = new TypeMapper();
+ _jsonOptions = JsonDefaults.GetOptions();
+
DbFilePath = Path.Combine(_config.ApplicationPaths.DataPath, "library.db");
}
@@ -99,35 +92,114 @@ namespace Emby.Server.Implementations.Data
/// </summary>
public void Initialize(SqliteUserDataRepository userDataRepo, IUserManager userManager)
{
- using (var connection = GetConnection())
- {
- const string createMediaStreamsTableCommand
+ const string CreateMediaStreamsTableCommand
= "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, CodecTag TEXT NULL, Comment TEXT NULL, NalLengthSize TEXT NULL, IsAvc BIT NULL, Title TEXT NULL, TimeBase TEXT NULL, CodecTimeBase TEXT NULL, ColorPrimaries TEXT NULL, ColorSpace TEXT NULL, ColorTransfer TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))";
- string[] queries = {
- "PRAGMA locking_mode=EXCLUSIVE",
+ string[] queries =
+ {
+ "PRAGMA locking_mode=EXCLUSIVE",
- "create table if not exists TypedBaseItems (guid GUID primary key NOT NULL, type TEXT NOT NULL, data BLOB NULL, ParentId GUID NULL, Path TEXT NULL)",
+ "create table if not exists TypedBaseItems (guid GUID primary key NOT NULL, type TEXT NOT NULL, data BLOB NULL, ParentId GUID NULL, Path TEXT NULL)",
- "create table if not exists AncestorIds (ItemId GUID NOT NULL, AncestorId GUID NOT NULL, AncestorIdText TEXT NOT NULL, PRIMARY KEY (ItemId, AncestorId))",
- "create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
- "create index if not exists idx_AncestorIds5 on AncestorIds(AncestorIdText,ItemId)",
+ "create table if not exists AncestorIds (ItemId GUID NOT NULL, AncestorId GUID NOT NULL, AncestorIdText TEXT NOT NULL, PRIMARY KEY (ItemId, AncestorId))",
+ "create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
+ "create index if not exists idx_AncestorIds5 on AncestorIds(AncestorIdText,ItemId)",
- "create table if not exists ItemValues (ItemId GUID NOT NULL, Type INT NOT NULL, Value TEXT NOT NULL, CleanValue TEXT NOT NULL)",
+ "create table if not exists ItemValues (ItemId GUID NOT NULL, Type INT NOT NULL, Value TEXT NOT NULL, CleanValue TEXT NOT NULL)",
- "create table if not exists People (ItemId GUID, Name TEXT NOT NULL, Role TEXT, PersonType TEXT, SortOrder int, ListOrder int)",
+ "create table if not exists People (ItemId GUID, Name TEXT NOT NULL, Role TEXT, PersonType TEXT, SortOrder int, ListOrder int)",
- "drop index if exists idxPeopleItemId",
- "create index if not exists idxPeopleItemId1 on People(ItemId,ListOrder)",
- "create index if not exists idxPeopleName on People(Name)",
+ "drop index if exists idxPeopleItemId",
+ "create index if not exists idxPeopleItemId1 on People(ItemId,ListOrder)",
+ "create index if not exists idxPeopleName on People(Name)",
- "create table if not exists " + ChaptersTableName + " (ItemId GUID, ChapterIndex INT NOT NULL, StartPositionTicks BIGINT NOT NULL, Name TEXT, ImagePath TEXT, PRIMARY KEY (ItemId, ChapterIndex))",
+ "create table if not exists " + ChaptersTableName + " (ItemId GUID, ChapterIndex INT NOT NULL, StartPositionTicks BIGINT NOT NULL, Name TEXT, ImagePath TEXT, PRIMARY KEY (ItemId, ChapterIndex))",
- createMediaStreamsTableCommand,
+ CreateMediaStreamsTableCommand,
+
+ "pragma shrink_memory"
+ };
- "pragma shrink_memory"
- };
+ string[] postQueries =
+ {
+ // obsolete
+ "drop index if exists idx_TypedBaseItems",
+ "drop index if exists idx_mediastreams",
+ "drop index if exists idx_mediastreams1",
+ "drop index if exists idx_"+ChaptersTableName,
+ "drop index if exists idx_UserDataKeys1",
+ "drop index if exists idx_UserDataKeys2",
+ "drop index if exists idx_TypeTopParentId3",
+ "drop index if exists idx_TypeTopParentId2",
+ "drop index if exists idx_TypeTopParentId4",
+ "drop index if exists idx_Type",
+ "drop index if exists idx_TypeTopParentId",
+ "drop index if exists idx_GuidType",
+ "drop index if exists idx_TopParentId",
+ "drop index if exists idx_TypeTopParentId6",
+ "drop index if exists idx_ItemValues2",
+ "drop index if exists Idx_ProviderIds",
+ "drop index if exists idx_ItemValues3",
+ "drop index if exists idx_ItemValues4",
+ "drop index if exists idx_ItemValues5",
+ "drop index if exists idx_UserDataKeys3",
+ "drop table if exists UserDataKeys",
+ "drop table if exists ProviderIds",
+ "drop index if exists Idx_ProviderIds1",
+ "drop table if exists Images",
+ "drop index if exists idx_Images",
+ "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)",
+
+ "create index if not exists idx_PresentationUniqueKey on TypedBaseItems(PresentationUniqueKey)",
+ "create index if not exists idx_GuidTypeIsFolderIsVirtualItem on TypedBaseItems(Guid,Type,IsFolder,IsVirtualItem)",
+ "create index if not exists idx_CleanNameType on TypedBaseItems(CleanName,Type)",
+
+ // covering index
+ "create index if not exists idx_TopParentIdGuid on TypedBaseItems(TopParentId,Guid)",
+
+ // series
+ "create index if not exists idx_TypeSeriesPresentationUniqueKey1 on TypedBaseItems(Type,SeriesPresentationUniqueKey,PresentationUniqueKey,SortName)",
+
+ // series counts
+ // seriesdateplayed sort order
+ "create index if not exists idx_TypeSeriesPresentationUniqueKey3 on TypedBaseItems(SeriesPresentationUniqueKey,Type,IsFolder,IsVirtualItem)",
+
+ // live tv programs
+ "create index if not exists idx_TypeTopParentIdStartDate on TypedBaseItems(Type,TopParentId,StartDate)",
+
+ // covering index for getitemvalues
+ "create index if not exists idx_TypeTopParentIdGuid on TypedBaseItems(Type,TopParentId,Guid)",
+
+ // used by movie suggestions
+ "create index if not exists idx_TypeTopParentIdGroup on TypedBaseItems(Type,TopParentId,PresentationUniqueKey)",
+ "create index if not exists idx_TypeTopParentId5 on TypedBaseItems(TopParentId,IsVirtualItem)",
+
+ // latest items
+ "create index if not exists idx_TypeTopParentId9 on TypedBaseItems(TopParentId,Type,IsVirtualItem,PresentationUniqueKey,DateCreated)",
+ "create index if not exists idx_TypeTopParentId8 on TypedBaseItems(TopParentId,IsFolder,IsVirtualItem,PresentationUniqueKey,DateCreated)",
+
+ // resume
+ "create index if not exists idx_TypeTopParentId7 on TypedBaseItems(TopParentId,MediaType,IsVirtualItem,PresentationUniqueKey)",
+
+ // 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)",
+
+ // Used to update inherited tags
+ "create index if not exists idx_ItemValues8 on ItemValues(Type, ItemId, Value)",
+ };
+
+ using (var connection = GetConnection())
+ {
connection.RunQueries(queries);
connection.RunInTransaction(db =>
@@ -235,83 +307,6 @@ namespace Emby.Server.Implementations.Data
}, TransactionMode);
- string[] postQueries =
- {
- // obsolete
- "drop index if exists idx_TypedBaseItems",
- "drop index if exists idx_mediastreams",
- "drop index if exists idx_mediastreams1",
- "drop index if exists idx_"+ChaptersTableName,
- "drop index if exists idx_UserDataKeys1",
- "drop index if exists idx_UserDataKeys2",
- "drop index if exists idx_TypeTopParentId3",
- "drop index if exists idx_TypeTopParentId2",
- "drop index if exists idx_TypeTopParentId4",
- "drop index if exists idx_Type",
- "drop index if exists idx_TypeTopParentId",
- "drop index if exists idx_GuidType",
- "drop index if exists idx_TopParentId",
- "drop index if exists idx_TypeTopParentId6",
- "drop index if exists idx_ItemValues2",
- "drop index if exists Idx_ProviderIds",
- "drop index if exists idx_ItemValues3",
- "drop index if exists idx_ItemValues4",
- "drop index if exists idx_ItemValues5",
- "drop index if exists idx_UserDataKeys3",
- "drop table if exists UserDataKeys",
- "drop table if exists ProviderIds",
- "drop index if exists Idx_ProviderIds1",
- "drop table if exists Images",
- "drop index if exists idx_Images",
- "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)",
-
- "create index if not exists idx_PresentationUniqueKey on TypedBaseItems(PresentationUniqueKey)",
- "create index if not exists idx_GuidTypeIsFolderIsVirtualItem on TypedBaseItems(Guid,Type,IsFolder,IsVirtualItem)",
- "create index if not exists idx_CleanNameType on TypedBaseItems(CleanName,Type)",
-
- // covering index
- "create index if not exists idx_TopParentIdGuid on TypedBaseItems(TopParentId,Guid)",
-
- // series
- "create index if not exists idx_TypeSeriesPresentationUniqueKey1 on TypedBaseItems(Type,SeriesPresentationUniqueKey,PresentationUniqueKey,SortName)",
-
- // series counts
- // seriesdateplayed sort order
- "create index if not exists idx_TypeSeriesPresentationUniqueKey3 on TypedBaseItems(SeriesPresentationUniqueKey,Type,IsFolder,IsVirtualItem)",
-
- // live tv programs
- "create index if not exists idx_TypeTopParentIdStartDate on TypedBaseItems(Type,TopParentId,StartDate)",
-
- // covering index for getitemvalues
- "create index if not exists idx_TypeTopParentIdGuid on TypedBaseItems(Type,TopParentId,Guid)",
-
- // used by movie suggestions
- "create index if not exists idx_TypeTopParentIdGroup on TypedBaseItems(Type,TopParentId,PresentationUniqueKey)",
- "create index if not exists idx_TypeTopParentId5 on TypedBaseItems(TopParentId,IsVirtualItem)",
-
- // latest items
- "create index if not exists idx_TypeTopParentId9 on TypedBaseItems(TopParentId,Type,IsVirtualItem,PresentationUniqueKey,DateCreated)",
- "create index if not exists idx_TypeTopParentId8 on TypedBaseItems(TopParentId,IsFolder,IsVirtualItem,PresentationUniqueKey,DateCreated)",
-
- // resume
- "create index if not exists idx_TypeTopParentId7 on TypedBaseItems(TopParentId,MediaType,IsVirtualItem,PresentationUniqueKey)",
-
- // 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)",
-
- // Used to update inherited tags
- "create index if not exists idx_ItemValues8 on ItemValues(Type, ItemId, Value)",
- };
-
connection.RunQueries(postQueries);
}
@@ -669,7 +664,7 @@ namespace Emby.Server.Implementations.Data
if (TypeRequiresDeserialization(item.GetType()))
{
- saveItemStatement.TryBind("@data", _jsonSerializer.SerializeToBytes(item));
+ saveItemStatement.TryBind("@data", JsonSerializer.SerializeToUtf8Bytes(item, _jsonOptions));
}
else
{
@@ -696,7 +691,7 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBindNull("@EndDate");
}
- saveItemStatement.TryBind("@ChannelId", item.ChannelId.Equals(Guid.Empty) ? null : item.ChannelId.ToString("N"));
+ saveItemStatement.TryBind("@ChannelId", item.ChannelId.Equals(Guid.Empty) ? null : item.ChannelId.ToString("N", CultureInfo.InvariantCulture));
if (item is IHasProgramAttributes hasProgramAttributes)
{
@@ -851,7 +846,7 @@ namespace Emby.Server.Implementations.Data
}
else
{
- saveItemStatement.TryBind("@TopParentId", topParent.Id.ToString("N"));
+ saveItemStatement.TryBind("@TopParentId", topParent.Id.ToString("N", CultureInfo.InvariantCulture));
}
if (item is Trailer trailer && trailer.TrailerTypes.Length > 0)
@@ -977,7 +972,7 @@ namespace Emby.Server.Implementations.Data
}
string artists = null;
- if (item is IHasArtist hasArtists && hasArtists.Artists.Length > 0)
+ if (item is IHasArtist hasArtists && hasArtists.Artists.Count > 0)
{
artists = string.Join("|", hasArtists.Artists);
}
@@ -985,7 +980,7 @@ namespace Emby.Server.Implementations.Data
string albumArtists = null;
if (item is IHasAlbumArtist hasAlbumArtists
- && hasAlbumArtists.AlbumArtists.Length > 0)
+ && hasAlbumArtists.AlbumArtists.Count > 0)
{
albumArtists = string.Join("|", hasAlbumArtists.AlbumArtists);
}
@@ -1298,18 +1293,13 @@ namespace Emby.Server.Implementations.Data
if (TypeRequiresDeserialization(type))
{
- using (var stream = new MemoryStream(reader[1].ToBlob()))
+ try
{
- stream.Position = 0;
-
- try
- {
- item = _jsonSerializer.DeserializeFromStream(stream, type) as BaseItem;
- }
- catch (SerializationException ex)
- {
- Logger.LogError(ex, "Error deserializing item");
- }
+ item = JsonSerializer.Deserialize(reader[1].ToBlob(), type, _jsonOptions) as BaseItem;
+ }
+ catch (JsonException ex)
+ {
+ Logger.LogError(ex, "Error deserializing item with JSON: {Data}", reader.GetString(1));
}
}
@@ -1999,14 +1989,14 @@ namespace Emby.Server.Implementations.Data
throw new ArgumentNullException(nameof(chapters));
}
+ var idBlob = id.ToGuidBlob();
+
using (var connection = GetConnection())
{
connection.RunInTransaction(db =>
{
- var idBlob = id.ToGuidBlob();
-
- // First delete chapters
- db.Execute("delete from " + ChaptersTableName + " where ItemId=@ItemId", idBlob);
+ // First delete chapters
+ db.Execute("delete from " + ChaptersTableName + " where ItemId=@ItemId", idBlob);
InsertChapters(idBlob, chapters, db);
@@ -2535,6 +2525,7 @@ namespace Emby.Server.Implementations.Data
commandText += " where " + string.Join(" AND ", whereClauses);
}
+ int count;
using (var connection = GetConnection(true))
{
using (var statement = PrepareStatement(connection, commandText))
@@ -2550,11 +2541,12 @@ namespace Emby.Server.Implementations.Data
// Running this again will bind the params
GetWhereClauses(query, statement);
- var count = statement.ExecuteQuery().SelectScalarInt().First();
- LogQueryTime("GetCount", commandText, now);
- return count;
+ count = statement.ExecuteQuery().SelectScalarInt().First();
}
}
+
+ LogQueryTime("GetCount", commandText, now);
+ return count;
}
public List<BaseItem> GetItemList(InternalItemsQuery query)
@@ -2604,10 +2596,9 @@ namespace Emby.Server.Implementations.Data
}
}
+ var items = new List<BaseItem>();
using (var connection = GetConnection(true))
{
- var items = new List<BaseItem>();
-
using (var statement = PrepareStatement(connection, commandText))
{
if (EnableJoinUserData(query))
@@ -2658,11 +2649,11 @@ namespace Emby.Server.Implementations.Data
items = newList;
}
+ }
- LogQueryTime("GetItemList", commandText, now);
+ LogQueryTime("GetItemList", commandText, now);
- return items;
- }
+ return items;
}
private string FixUnicodeChars(string buffer)
@@ -2726,7 +2717,7 @@ namespace Emby.Server.Implementations.Data
if (elapsed >= SlowThreshold)
{
- Logger.LogWarning(
+ Logger.LogDebug(
"{Method} query time (slow): {ElapsedMs}ms. Query: {Query}",
methodName,
elapsed,
@@ -2748,15 +2739,13 @@ namespace Emby.Server.Implementations.Data
var returnList = GetItemList(query);
return new QueryResult<BaseItem>
{
- Items = returnList.ToArray(),
+ Items = returnList,
TotalRecordCount = returnList.Count
};
}
var now = DateTime.UtcNow;
- var list = new List<BaseItem>();
-
// Hack for right now since we currently don't support filtering out these duplicates within a query
if (query.Limit.HasValue && query.EnableGroupByMetadataKey)
{
@@ -2822,11 +2811,13 @@ namespace Emby.Server.Implementations.Data
statementTexts.Add(commandText);
}
+ var list = new List<BaseItem>();
+ var result = new QueryResult<BaseItem>();
using (var connection = GetConnection(true))
{
- return connection.RunInTransaction(db =>
+ connection.RunInTransaction(db =>
{
- var result = new QueryResult<BaseItem>();
+
var statements = PrepareAll(db, statementTexts).ToList();
if (!isReturningZeroItems)
@@ -2881,14 +2872,12 @@ namespace Emby.Server.Implementations.Data
result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
}
}
-
- LogQueryTime("GetItems", commandText, now);
-
- result.Items = list.ToArray();
- return result;
-
}, ReadTransactionMode);
}
+
+ LogQueryTime("GetItems", commandText, now);
+ result.Items = list;
+ return result;
}
private string GetOrderByText(InternalItemsQuery query)
@@ -3054,10 +3043,9 @@ namespace Emby.Server.Implementations.Data
}
}
+ var list = new List<Guid>();
using (var connection = GetConnection(true))
{
- var list = new List<Guid>();
-
using (var statement = PrepareStatement(connection, commandText))
{
if (EnableJoinUserData(query))
@@ -3076,11 +3064,10 @@ namespace Emby.Server.Implementations.Data
list.Add(row[0].ReadGuidFromBlob());
}
}
-
- LogQueryTime("GetItemList", commandText, now);
-
- return list;
}
+
+ LogQueryTime("GetItemList", commandText, now);
+ return list;
}
public List<Tuple<Guid, string>> GetItemIdsWithPath(InternalItemsQuery query)
@@ -3142,6 +3129,7 @@ namespace Emby.Server.Implementations.Data
{
path = row.GetString(1);
}
+
list.Add(new Tuple<Guid, string>(id, path));
}
}
@@ -3166,7 +3154,7 @@ namespace Emby.Server.Implementations.Data
var returnList = GetItemIdsList(query);
return new QueryResult<Guid>
{
- Items = returnList.ToArray(),
+ Items = returnList,
TotalRecordCount = returnList.Count
};
}
@@ -3203,7 +3191,7 @@ namespace Emby.Server.Implementations.Data
}
}
- var list = new List<Guid>();
+
var isReturningZeroItems = query.Limit.HasValue && query.Limit <= 0;
var statementTexts = new List<string>();
@@ -3233,12 +3221,12 @@ namespace Emby.Server.Implementations.Data
statementTexts.Add(commandText);
}
+ var list = new List<Guid>();
+ var result = new QueryResult<Guid>();
using (var connection = GetConnection(true))
{
- return connection.RunInTransaction(db =>
+ connection.RunInTransaction(db =>
{
- var result = new QueryResult<Guid>();
-
var statements = PrepareAll(db, statementTexts).ToList();
if (!isReturningZeroItems)
@@ -3281,14 +3269,13 @@ namespace Emby.Server.Implementations.Data
result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
}
}
-
- LogQueryTime("GetItemIds", commandText, now);
-
- result.Items = list.ToArray();
- return result;
-
}, ReadTransactionMode);
}
+
+ LogQueryTime("GetItemIds", commandText, now);
+
+ result.Items = list;
+ return result;
}
private bool IsAlphaNumeric(string str)
@@ -3548,12 +3535,12 @@ namespace Emby.Server.Implementations.Data
whereClauses.Add("ChannelId=@ChannelId");
if (statement != null)
{
- statement.TryBind("@ChannelId", query.ChannelIds[0].ToString("N"));
+ statement.TryBind("@ChannelId", query.ChannelIds[0].ToString("N", CultureInfo.InvariantCulture));
}
}
else if (query.ChannelIds.Length > 1)
{
- var inClause = string.Join(",", query.ChannelIds.Select(i => "'" + i.ToString("N") + "'"));
+ var inClause = string.Join(",", query.ChannelIds.Select(i => "'" + i.ToString("N", CultureInfo.InvariantCulture) + "'"));
whereClauses.Add($"ChannelId in ({inClause})");
}
@@ -4537,12 +4524,12 @@ namespace Emby.Server.Implementations.Data
}
if (statement != null)
{
- statement.TryBind("@TopParentId", queryTopParentIds[0].ToString("N"));
+ statement.TryBind("@TopParentId", queryTopParentIds[0].ToString("N", CultureInfo.InvariantCulture));
}
}
else if (queryTopParentIds.Length > 1)
{
- var val = string.Join(",", queryTopParentIds.Select(i => "'" + i.ToString("N") + "'"));
+ var val = string.Join(",", queryTopParentIds.Select(i => "'" + i.ToString("N", CultureInfo.InvariantCulture) + "'"));
if (enableItemsByName && includedItemByNameTypes.Count == 1)
{
@@ -4574,7 +4561,7 @@ namespace Emby.Server.Implementations.Data
}
if (query.AncestorIds.Length > 1)
{
- var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + i.ToString("N") + "'"));
+ var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + i.ToString("N", CultureInfo.InvariantCulture) + "'"));
whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorIdText in ({0}))", inClause));
}
if (!string.IsNullOrWhiteSpace(query.AncestorWithPresentationUniqueKey))
@@ -4637,7 +4624,7 @@ namespace Emby.Server.Implementations.Data
foreach (var folderId in query.BoxSetLibraryFolders)
{
- folderIdQueries.Add("data like '%" + folderId.ToString("N") + "%'");
+ folderIdQueries.Add("data like '%" + folderId.ToString("N", CultureInfo.InvariantCulture) + "%'");
}
whereClauses.Add("(" + string.Join(" OR ", folderIdQueries) + ")");
@@ -4864,22 +4851,25 @@ namespace Emby.Server.Implementations.Data
private void UpdateInheritedTags(CancellationToken cancellationToken)
{
- using (var connection = GetConnection())
- {
- connection.RunInTransaction(db =>
+ string sql = string.Join(
+ ";",
+ new string[]
{
- connection.ExecuteAll(string.Join(";", new string[]
- {
- "delete from itemvalues where type = 6",
+ "delete from itemvalues where type = 6",
- "insert into itemvalues (ItemId, Type, Value, CleanValue) select ItemId, 6, Value, CleanValue from ItemValues where Type=4",
+ "insert into itemvalues (ItemId, Type, Value, CleanValue) select ItemId, 6, Value, CleanValue from ItemValues where Type=4",
- @"insert into itemvalues (ItemId, Type, Value, CleanValue) select AncestorIds.itemid, 6, ItemValues.Value, ItemValues.CleanValue
+ @"insert into itemvalues (ItemId, Type, Value, CleanValue) select AncestorIds.itemid, 6, ItemValues.Value, ItemValues.CleanValue
FROM AncestorIds
LEFT JOIN ItemValues ON (AncestorIds.AncestorId = ItemValues.ItemId)
where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type = 4 "
+ });
- }));
+ using (var connection = GetConnection())
+ {
+ connection.RunInTransaction(db =>
+ {
+ connection.ExecuteAll(sql);
}, TransactionMode);
}
@@ -4933,23 +4923,23 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
var idBlob = id.ToGuidBlob();
- // Delete people
- ExecuteWithSingleParam(db, "delete from People where ItemId=@Id", idBlob);
+ // Delete people
+ ExecuteWithSingleParam(db, "delete from People where ItemId=@Id", idBlob);
- // Delete chapters
- ExecuteWithSingleParam(db, "delete from " + ChaptersTableName + " where ItemId=@Id", idBlob);
+ // Delete chapters
+ ExecuteWithSingleParam(db, "delete from " + ChaptersTableName + " where ItemId=@Id", idBlob);
- // Delete media streams
- ExecuteWithSingleParam(db, "delete from mediastreams where ItemId=@Id", idBlob);
+ // Delete media streams
+ ExecuteWithSingleParam(db, "delete from mediastreams where ItemId=@Id", idBlob);
- // Delete ancestors
- ExecuteWithSingleParam(db, "delete from AncestorIds where ItemId=@Id", idBlob);
+ // Delete ancestors
+ ExecuteWithSingleParam(db, "delete from AncestorIds where ItemId=@Id", idBlob);
- // Delete item values
- ExecuteWithSingleParam(db, "delete from ItemValues where ItemId=@Id", idBlob);
+ // Delete item values
+ ExecuteWithSingleParam(db, "delete from ItemValues where ItemId=@Id", idBlob);
- // Delete the item
- ExecuteWithSingleParam(db, "delete from TypedBaseItems where guid=@Id", idBlob);
+ // Delete the item
+ ExecuteWithSingleParam(db, "delete from TypedBaseItems where guid=@Id", idBlob);
}, TransactionMode);
}
}
@@ -4997,6 +4987,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
list.Add(row.GetString(0));
}
}
+
return list;
}
}
@@ -5161,7 +5152,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
var ancestorId = ancestorIds[i];
statement.TryBind("@AncestorId" + index, ancestorId.ToGuidBlob());
- statement.TryBind("@AncestorIdText" + index, ancestorId.ToString("N"));
+ statement.TryBind("@AncestorIdText" + index, ancestorId.ToString("N", CultureInfo.InvariantCulture));
}
statement.Reset();
@@ -5247,10 +5238,9 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
commandText += " Group By CleanValue";
+ var list = new List<string>();
using (var connection = GetConnection(true))
{
- var list = new List<string>();
-
using (var statement = PrepareStatement(connection, commandText))
{
foreach (var row in statement.ExecuteQuery())
@@ -5262,10 +5252,10 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
}
}
- LogQueryTime("GetItemValueNames", commandText, now);
-
- return list;
}
+
+ LogQueryTime("GetItemValueNames", commandText, now);
+ return list;
}
private QueryResult<(BaseItem, ItemCounts)> GetItemValues(InternalItemsQuery query, int[] itemValueTypes, string returnType)
@@ -5422,6 +5412,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
statementTexts.Add(commandText);
}
+
if (query.EnableTotalRecordCount)
{
var countText = "select "
@@ -5433,98 +5424,98 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
statementTexts.Add(countText);
}
+ var list = new List<(BaseItem, ItemCounts)>();
+ var result = new QueryResult<(BaseItem, ItemCounts)>();
using (var connection = GetConnection(true))
{
- return connection.RunInTransaction(db =>
- {
- var list = new List<(BaseItem, ItemCounts)>();
- var result = new QueryResult<(BaseItem, ItemCounts)>();
-
- var statements = PrepareAll(db, statementTexts).ToList();
-
- if (!isReturningZeroItems)
+ connection.RunInTransaction(
+ db =>
{
- using (var statement = statements[0])
+ var statements = PrepareAll(db, statementTexts).ToList();
+
+ if (!isReturningZeroItems)
{
- statement.TryBind("@SelectType", returnType);
- if (EnableJoinUserData(query))
+ using (var statement = statements[0])
{
- statement.TryBind("@UserId", query.User.InternalId);
- }
+ statement.TryBind("@SelectType", returnType);
+ if (EnableJoinUserData(query))
+ {
+ statement.TryBind("@UserId", query.User.InternalId);
+ }
- if (typeSubQuery != null)
- {
- GetWhereClauses(typeSubQuery, null);
- }
- BindSimilarParams(query, statement);
- BindSearchParams(query, statement);
- GetWhereClauses(innerQuery, statement);
- GetWhereClauses(outerQuery, statement);
+ if (typeSubQuery != null)
+ {
+ GetWhereClauses(typeSubQuery, null);
+ }
- var hasEpisodeAttributes = HasEpisodeAttributes(query);
- var hasProgramAttributes = HasProgramAttributes(query);
- var hasServiceName = HasServiceName(query);
- var hasStartDate = HasStartDate(query);
- var hasTrailerTypes = HasTrailerTypes(query);
- var hasArtistFields = HasArtistFields(query);
- var hasSeriesFields = HasSeriesFields(query);
+ BindSimilarParams(query, statement);
+ BindSearchParams(query, statement);
+ GetWhereClauses(innerQuery, statement);
+ GetWhereClauses(outerQuery, statement);
- foreach (var row in statement.ExecuteQuery())
- {
- var item = GetItem(row, query, hasProgramAttributes, hasEpisodeAttributes, hasServiceName, hasStartDate, hasTrailerTypes, hasArtistFields, hasSeriesFields);
- if (item != null)
+ var hasEpisodeAttributes = HasEpisodeAttributes(query);
+ var hasProgramAttributes = HasProgramAttributes(query);
+ var hasServiceName = HasServiceName(query);
+ var hasStartDate = HasStartDate(query);
+ var hasTrailerTypes = HasTrailerTypes(query);
+ var hasArtistFields = HasArtistFields(query);
+ var hasSeriesFields = HasSeriesFields(query);
+
+ foreach (var row in statement.ExecuteQuery())
{
- var countStartColumn = columns.Count - 1;
+ var item = GetItem(row, query, hasProgramAttributes, hasEpisodeAttributes, hasServiceName, hasStartDate, hasTrailerTypes, hasArtistFields, hasSeriesFields);
+ if (item != null)
+ {
+ var countStartColumn = columns.Count - 1;
- list.Add((item, GetItemCounts(row, countStartColumn, typesToCount)));
+ list.Add((item, GetItemCounts(row, countStartColumn, typesToCount)));
+ }
}
}
-
- LogQueryTime("GetItemValues", commandText, now);
}
- }
- if (query.EnableTotalRecordCount)
- {
- commandText = "select "
- + string.Join(",", GetFinalColumnsToSelect(query, new[] { "count (distinct PresentationUniqueKey)" }))
- + GetFromText()
- + GetJoinUserDataText(query)
- + whereText;
-
- using (var statement = statements[statements.Count - 1])
+ if (query.EnableTotalRecordCount)
{
- statement.TryBind("@SelectType", returnType);
- if (EnableJoinUserData(query))
- {
- statement.TryBind("@UserId", query.User.InternalId);
- }
+ commandText = "select "
+ + string.Join(",", GetFinalColumnsToSelect(query, new[] { "count (distinct PresentationUniqueKey)" }))
+ + GetFromText()
+ + GetJoinUserDataText(query)
+ + whereText;
- if (typeSubQuery != null)
+ using (var statement = statements[statements.Count - 1])
{
- GetWhereClauses(typeSubQuery, null);
- }
- BindSimilarParams(query, statement);
- BindSearchParams(query, statement);
- GetWhereClauses(innerQuery, statement);
- GetWhereClauses(outerQuery, statement);
+ statement.TryBind("@SelectType", returnType);
+ if (EnableJoinUserData(query))
+ {
+ statement.TryBind("@UserId", query.User.InternalId);
+ }
- result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
+ if (typeSubQuery != null)
+ {
+ GetWhereClauses(typeSubQuery, null);
+ }
+ BindSimilarParams(query, statement);
+ BindSearchParams(query, statement);
+ GetWhereClauses(innerQuery, statement);
+ GetWhereClauses(outerQuery, statement);
- LogQueryTime("GetItemValues", commandText, now);
+ result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
+ }
}
- }
-
- if (result.TotalRecordCount == 0)
- {
- result.TotalRecordCount = list.Count;
- }
- result.Items = list.ToArray();
+ },
+ ReadTransactionMode);
+ }
- return result;
+ LogQueryTime("GetItemValues", commandText, now);
- }, ReadTransactionMode);
+ if (result.TotalRecordCount == 0)
+ {
+ result.TotalRecordCount = list.Count;
}
+
+ result.Items = list;
+
+ return result;
}
private ItemCounts GetItemCounts(IReadOnlyList<IResultSetValue> reader, int countStartColumn, string[] typesToCount)
@@ -5579,6 +5570,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
counts.TrailerCount = value;
}
+
counts.ItemCount += value;
}
@@ -5706,8 +5698,8 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
var itemIdBlob = itemId.ToGuidBlob();
- // First delete chapters
- db.Execute("delete from People where ItemId=@ItemId", itemIdBlob);
+ // First delete chapters
+ db.Execute("delete from People where ItemId=@ItemId", itemIdBlob);
InsertPeople(itemIdBlob, people, db);
@@ -5732,7 +5724,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
if (isSubsequentRow)
{
- insertText.Append(",");
+ insertText.Append(',');
}
insertText.AppendFormat("(@ItemId, @Name{0}, @Role{0}, @PersonType{0}, @SortOrder{0}, @ListOrder{0})", i.ToString(CultureInfo.InvariantCulture));
@@ -5867,8 +5859,8 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
var itemIdBlob = id.ToGuidBlob();
- // First delete chapters
- db.Execute("delete from mediastreams where ItemId=@ItemId", itemIdBlob);
+ // First delete chapters
+ db.Execute("delete from mediastreams where ItemId=@ItemId", itemIdBlob);
InsertMediaStreams(itemIdBlob, streams, db);