aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Server.Implementations')
-rw-r--r--MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Channels/ChannelManager.cs12
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs24
-rw-r--r--MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserDataManager.cs42
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs12
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj6
-rw-r--r--MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs (renamed from MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs)46
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs10
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs204
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Session/SessionManager.cs25
-rw-r--r--MediaBrowser.Server.Implementations/Social/SharingRepository.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs10
-rw-r--r--MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncManager.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncRepository.cs4
-rw-r--r--MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs84
27 files changed, 330 insertions, 210 deletions
diff --git a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs
index 85ab761823..b0e05a5bc8 100644
--- a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs
+++ b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs
@@ -27,11 +27,11 @@ namespace MediaBrowser.Server.Implementations.Activity
_appPaths = appPaths;
}
- public async Task Initialize()
+ public async Task Initialize(IDbConnector dbConnector)
{
var dbFile = Path.Combine(_appPaths.DataPath, "activitylog.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
+ _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
string[] queries = {
diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
index c9956c68a5..6a9842cb2e 100644
--- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
+++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
@@ -133,7 +133,7 @@ namespace MediaBrowser.Server.Implementations.Channels
if (query.IsFavorite.HasValue)
{
var val = query.IsFavorite.Value;
- channels = channels.Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite == val)
+ channels = channels.Where(i => _userDataManager.GetUserData(user, i).IsFavorite == val)
.ToList();
}
@@ -1437,7 +1437,7 @@ namespace MediaBrowser.Server.Implementations.Channels
case ItemFilter.IsFavoriteOrLikes:
return items.Where(item =>
{
- var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
+ var userdata = _userDataManager.GetUserData(user, item);
if (userdata == null)
{
@@ -1453,7 +1453,7 @@ namespace MediaBrowser.Server.Implementations.Channels
case ItemFilter.Likes:
return items.Where(item =>
{
- var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
+ var userdata = _userDataManager.GetUserData(user, item);
return userdata != null && userdata.Likes.HasValue && userdata.Likes.Value;
});
@@ -1461,7 +1461,7 @@ namespace MediaBrowser.Server.Implementations.Channels
case ItemFilter.Dislikes:
return items.Where(item =>
{
- var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
+ var userdata = _userDataManager.GetUserData(user, item);
return userdata != null && userdata.Likes.HasValue && !userdata.Likes.Value;
});
@@ -1469,7 +1469,7 @@ namespace MediaBrowser.Server.Implementations.Channels
case ItemFilter.IsFavorite:
return items.Where(item =>
{
- var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
+ var userdata = _userDataManager.GetUserData(user, item);
return userdata != null && userdata.IsFavorite;
});
@@ -1477,7 +1477,7 @@ namespace MediaBrowser.Server.Implementations.Channels
case ItemFilter.IsResumable:
return items.Where(item =>
{
- var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
+ var userdata = _userDataManager.GetUserData(user, item);
return userdata != null && userdata.PlaybackPositionTicks > 0;
});
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index 7adde5c273..e8af0c3cb6 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -487,7 +487,7 @@ namespace MediaBrowser.Server.Implementations.Dto
{
if (item.IsFolder)
{
- var userData = _userDataRepository.GetUserData(user.Id, item.GetUserDataKey());
+ var userData = _userDataRepository.GetUserData(user, item);
// Skip the user data manager because we've already looped through the recursive tree and don't want to do it twice
// TODO: Improve in future
@@ -1363,9 +1363,10 @@ namespace MediaBrowser.Server.Implementations.Dto
if (fields.Contains(ItemFields.MediaSourceCount))
{
- if (video.MediaSourceCount != 1)
+ var mediaSourceCount = video.MediaSourceCount;
+ if (mediaSourceCount != 1)
{
- dto.MediaSourceCount = video.MediaSourceCount;
+ dto.MediaSourceCount = mediaSourceCount;
}
}
@@ -1686,7 +1687,7 @@ namespace MediaBrowser.Server.Implementations.Dto
dateLastMediaAdded = new[] { dateLastMediaAdded.Value, child.DateCreated }.Max();
}
- var userdata = _userDataRepository.GetUserData(user.Id, child.GetUserDataKey());
+ var userdata = _userDataRepository.GetUserData(user, child);
recursiveItemCount++;
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index e1bcfa861e..87fdc56b36 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -522,29 +522,7 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentNullException("items");
}
- var dict = new Dictionary<Guid, BaseItem>();
-
- foreach (var item in items)
- {
- var video = item as Video;
-
- if (video != null)
- {
- if (video.PrimaryVersionId.HasValue)
- {
- var primary = GetItemById(video.PrimaryVersionId.Value) as Video;
-
- if (primary != null)
- {
- dict[primary.Id] = primary;
- continue;
- }
- }
- }
- dict[item.Id] = item;
- }
-
- return dict.Values;
+ return items.DistinctBy(i => i.PresentationUniqueKey, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
index 092b797ce7..a47fcdf4f8 100644
--- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
@@ -267,7 +267,7 @@ namespace MediaBrowser.Server.Implementations.Library
private void SetUserProperties(IHasUserData item, MediaSourceInfo source, User user)
{
- var userData = item == null ? new UserItemData() : _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
+ var userData = item == null ? new UserItemData() : _userDataManager.GetUserData(user, item);
var allowRememberingSelection = item == null || item.EnableRememberingTrackSelections;
diff --git a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs
index ae737d2446..98f8abd405 100644
--- a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs
@@ -56,27 +56,30 @@ namespace MediaBrowser.Server.Implementations.Library
cancellationToken.ThrowIfCancellationRequested();
- var key = item.GetUserDataKey();
+ var keys = item.GetUserDataKeys();
- try
+ foreach (var key in keys)
{
- await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);
+ try
+ {
+ await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);
- var newValue = userData;
+ var newValue = userData;
- // Once it succeeds, put it into the dictionary to make it available to everyone else
- _userData.AddOrUpdate(GetCacheKey(userId, key), newValue, delegate { return newValue; });
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error saving user data", ex);
+ // Once it succeeds, put it into the dictionary to make it available to everyone else
+ _userData.AddOrUpdate(GetCacheKey(userId, key), newValue, delegate { return newValue; });
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error saving user data", ex);
- throw;
+ throw;
+ }
}
EventHelper.FireEventIfNotNull(UserDataSaved, this, new UserDataSaveEventArgs
{
- Key = key,
+ Keys = keys,
UserData = userData,
SaveReason = reason,
UserId = userId,
@@ -172,6 +175,21 @@ namespace MediaBrowser.Server.Implementations.Library
return userId + key;
}
+ public UserItemData GetUserData(IHasUserData user, IHasUserData item)
+ {
+ return GetUserData(user.Id, item.GetUserDataKey());
+ }
+
+ public UserItemData GetUserData(string userId, IHasUserData item)
+ {
+ return GetUserData(userId, item.GetUserDataKey());
+ }
+
+ public UserItemData GetUserData(Guid userId, IHasUserData item)
+ {
+ return GetUserData(userId, item.GetUserDataKey());
+ }
+
public UserItemDataDto GetUserDataDto(IHasUserData item, User user)
{
var userData = GetUserData(user.Id, item.GetUserDataKey());
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index ab2b59d482..eec8328f89 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -164,7 +164,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var val = query.IsFavorite.Value;
channels = channels
- .Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite == val);
+ .Where(i => _userDataManager.GetUserData(user, i).IsFavorite == val);
}
if (query.IsLiked.HasValue)
@@ -174,7 +174,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
channels = channels
.Where(i =>
{
- var likes = _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).Likes;
+ var likes = _userDataManager.GetUserData(user, i).Likes;
return likes.HasValue && likes.Value == val;
});
@@ -187,7 +187,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
channels = channels
.Where(i =>
{
- var likes = _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).Likes;
+ var likes = _userDataManager.GetUserData(user, i).Likes;
return likes.HasValue && likes.Value != val;
});
@@ -200,7 +200,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
if (enableFavoriteSorting)
{
- var userData = _userDataManager.GetUserData(user.Id, i.GetUserDataKey());
+ var userData = _userDataManager.GetUserData(user, i);
if (userData.IsFavorite)
{
@@ -1005,7 +1005,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var channel = GetInternalChannel(program.ChannelId);
- var channelUserdata = _userDataManager.GetUserData(userId, channel.GetUserDataKey());
+ var channelUserdata = _userDataManager.GetUserData(userId, channel);
if (channelUserdata.Likes ?? false)
{
@@ -1036,7 +1036,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
if (genres.TryGetValue(i, out genre))
{
- var genreUserdata = _userDataManager.GetUserData(userId, genre.GetUserDataKey());
+ var genreUserdata = _userDataManager.GetUserData(userId, genre);
if (genreUserdata.Likes ?? false)
{
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index 43f5d741b4..aff3a5e160 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -78,9 +78,6 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
- <Reference Include="System.Data.SQLite">
- <HintPath>..\ThirdParty\System.Data.SQLite.ManagedOnly\1.0.94.0\System.Data.SQLite.dll</HintPath>
- </Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net" />
@@ -261,6 +258,8 @@
<Compile Include="Notifications\IConfigurableNotificationService.cs" />
<Compile Include="Persistence\BaseSqliteRepository.cs" />
<Compile Include="Persistence\CleanDatabaseScheduledTask.cs" />
+ <Compile Include="Persistence\DataExtensions.cs" />
+ <Compile Include="Persistence\IDbConnector.cs" />
<Compile Include="Persistence\MediaStreamColumns.cs" />
<Compile Include="Social\SharingManager.cs" />
<Compile Include="Social\SharingRepository.cs" />
@@ -275,7 +274,6 @@
<Compile Include="Notifications\InternalNotificationService.cs" />
<Compile Include="Notifications\NotificationConfigurationFactory.cs" />
<Compile Include="Notifications\NotificationManager.cs" />
- <Compile Include="Persistence\SqliteExtensions.cs" />
<Compile Include="Persistence\SqliteFileOrganizationRepository.cs" />
<Compile Include="Notifications\SqliteNotificationsRepository.cs" />
<Compile Include="Persistence\SqliteProviderInfoRepository.cs" />
diff --git a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs
index 7302431e17..cecf03ddfe 100644
--- a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs
+++ b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs
@@ -32,11 +32,11 @@ namespace MediaBrowser.Server.Implementations.Notifications
_appPaths = appPaths;
}
- public async Task Initialize()
+ public async Task Initialize(IDbConnector dbConnector)
{
var dbFile = Path.Combine(_appPaths.DataPath, "notifications.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
+ _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
string[] queries = {
diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
index 031333f2c6..2a2f9a09d3 100644
--- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
@@ -110,6 +110,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
_config.SaveConfiguration();
}
+ if (_config.Configuration.SchemaVersion < SqliteItemRepository.LatestSchemaVersion)
+ {
+ _config.Configuration.SchemaVersion = SqliteItemRepository.LatestSchemaVersion;
+ _config.SaveConfiguration();
+ }
+
if (EnableUnavailableMessage)
{
EnableUnavailableMessage = false;
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs
index 4fb1e07dd7..103b75f840 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs
@@ -3,16 +3,12 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using System;
using System.Data;
-using System.Data.SQLite;
using System.IO;
using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.Persistence
{
- /// <summary>
- /// Class SQLiteExtensions
- /// </summary>
- static class SqliteExtensions
+ static class DataExtensions
{
/// <summary>
/// Determines whether the specified conn is open.
@@ -28,11 +24,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
return (IDataParameter)cmd.Parameters[index];
}
-
+
public static IDataParameter Add(this IDataParameterCollection paramCollection, IDbCommand cmd, string name, DbType type)
{
var param = cmd.CreateParameter();
-
+
param.ParameterName = name;
param.DbType = type;
@@ -48,11 +44,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
param.ParameterName = name;
paramCollection.Add(param);
-
+
return param;
}
-
+
/// <summary>
/// Gets a stream from a DataReader at a given ordinal
/// </summary>
@@ -122,38 +118,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
}
- /// <summary>
- /// Connects to db.
- /// </summary>
- /// <param name="dbPath">The db path.</param>
- /// <param name="logger">The logger.</param>
- /// <returns>Task{IDbConnection}.</returns>
- /// <exception cref="System.ArgumentNullException">dbPath</exception>
- public static async Task<IDbConnection> ConnectToDb(string dbPath, ILogger logger)
- {
- if (string.IsNullOrEmpty(dbPath))
- {
- throw new ArgumentNullException("dbPath");
- }
-
- logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath);
-
- var connectionstr = new SQLiteConnectionStringBuilder
- {
- PageSize = 4096,
- CacheSize = 2000,
- SyncMode = SynchronizationModes.Full,
- DataSource = dbPath,
- JournalMode = SQLiteJournalModeEnum.Wal
- };
-
- var connection = new SQLiteConnection(connectionstr.ConnectionString);
-
- await connection.OpenAsync().ConfigureAwait(false);
-
- return connection;
- }
-
public static void Attach(IDbConnection db, string path, string alias)
{
using (var cmd = db.CreateCommand())
diff --git a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs
new file mode 100644
index 0000000000..cac9fe9835
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs
@@ -0,0 +1,10 @@
+using System.Data;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Persistence
+{
+ public interface IDbConnector
+ {
+ Task<IDbConnection> Connect(string dbPath);
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs
index 45e0304c1c..6077cfdba4 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs
@@ -52,11 +52,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
/// Opens the connection to the database
/// </summary>
/// <returns>Task.</returns>
- public async Task Initialize()
+ public async Task Initialize(IDbConnector dbConnector)
{
var dbFile = Path.Combine(_appPaths.DataPath, "displaypreferences.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
+ _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
string[] queries = {
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs
index 2d5aad04df..037776997e 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs
@@ -35,11 +35,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
/// Opens the connection to the database
/// </summary>
/// <returns>Task.</returns>
- public async Task Initialize()
+ public async Task Initialize(IDbConnector dbConnector)
{
var dbFile = Path.Combine(_appPaths.DataPath, "fileorganization.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
+ _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
string[] queries = {
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index a44d66c739..6959de8e6b 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -20,6 +20,7 @@ using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Playlists;
using MediaBrowser.Model.LiveTv;
@@ -55,7 +56,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
/// <summary>
/// The _app paths
/// </summary>
- private readonly IApplicationPaths _appPaths;
+ private readonly IServerConfigurationManager _config;
/// <summary>
/// The _save item command
@@ -81,35 +82,31 @@ namespace MediaBrowser.Server.Implementations.Persistence
private IDbCommand _updateInheritedRatingCommand;
private IDbCommand _updateInheritedTagsCommand;
- private const int LatestSchemaVersion = 65;
+ public const int LatestSchemaVersion = 68;
/// <summary>
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
/// </summary>
- /// <param name="appPaths">The app paths.</param>
- /// <param name="jsonSerializer">The json serializer.</param>
- /// <param name="logManager">The log manager.</param>
- /// <exception cref="System.ArgumentNullException">
/// appPaths
/// or
/// jsonSerializer
/// </exception>
- public SqliteItemRepository(IApplicationPaths appPaths, IJsonSerializer jsonSerializer, ILogManager logManager)
+ public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogManager logManager)
: base(logManager)
{
- if (appPaths == null)
+ if (config == null)
{
- throw new ArgumentNullException("appPaths");
+ throw new ArgumentNullException("config");
}
if (jsonSerializer == null)
{
throw new ArgumentNullException("jsonSerializer");
}
- _appPaths = appPaths;
+ _config = config;
_jsonSerializer = jsonSerializer;
- _criticReviewsPath = Path.Combine(_appPaths.DataPath, "critic-reviews");
+ _criticReviewsPath = Path.Combine(_config.ApplicationPaths.DataPath, "critic-reviews");
}
private const string ChaptersTableName = "Chapters2";
@@ -118,11 +115,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
/// Opens the connection to the database
/// </summary>
/// <returns>Task.</returns>
- public async Task Initialize()
+ public async Task Initialize(IDbConnector dbConnector)
{
- var dbFile = Path.Combine(_appPaths.DataPath, "library.db");
+ var dbFile = Path.Combine(_config.ApplicationPaths.DataPath, "library.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
+ _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
var 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, PRIMARY KEY (ItemId, StreamIndex))";
@@ -228,18 +225,27 @@ namespace MediaBrowser.Server.Implementations.Persistence
_connection.AddColumn(Logger, "TypedBaseItems", "DateModifiedDuringLastRefresh", "DATETIME");
_connection.AddColumn(Logger, "TypedBaseItems", "InheritedTags", "Text");
_connection.AddColumn(Logger, "TypedBaseItems", "CleanName", "Text");
+ _connection.AddColumn(Logger, "TypedBaseItems", "PresentationUniqueKey", "Text");
+
+ string[] postQueries =
+ {
+ "create index if not exists idx_PresentationUniqueKey on TypedBaseItems(PresentationUniqueKey)",
+ "create index if not exists idx_Type on TypedBaseItems(Type)"
+ };
+
+ _connection.RunQueries(postQueries, Logger);
PrepareStatements();
new MediaStreamColumns(_connection, Logger).AddColumns();
- var chapterDbFile = Path.Combine(_appPaths.DataPath, "chapters.db");
+ var chapterDbFile = Path.Combine(_config.ApplicationPaths.DataPath, "chapters.db");
if (File.Exists(chapterDbFile))
{
MigrateChapters(chapterDbFile);
}
- var mediaStreamsDbFile = Path.Combine(_appPaths.DataPath, "mediainfo.db");
+ var mediaStreamsDbFile = Path.Combine(_config.ApplicationPaths.DataPath, "mediainfo.db");
if (File.Exists(mediaStreamsDbFile))
{
MigrateMediaStreams(mediaStreamsDbFile);
@@ -252,7 +258,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
var backupFile = file + ".bak";
File.Copy(file, backupFile, true);
- SqliteExtensions.Attach(_connection, backupFile, "MediaInfoOld");
+ DataExtensions.Attach(_connection, backupFile, "MediaInfoOld");
var columns = string.Join(",", _mediaStreamSaveColumns);
@@ -278,7 +284,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
var backupFile = file + ".bak";
File.Copy(file, backupFile, true);
- SqliteExtensions.Attach(_connection, backupFile, "ChaptersOld");
+ DataExtensions.Attach(_connection, backupFile, "ChaptersOld");
string[] queries = {
"REPLACE INTO "+ChaptersTableName+"(ItemId, ChapterIndex, StartPositionTicks, Name, ImagePath) SELECT ItemId, ChapterIndex, StartPositionTicks, Name, ImagePath FROM ChaptersOld.Chapters;"
@@ -469,7 +475,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
"CriticRatingSummary",
"DateModifiedDuringLastRefresh",
"InheritedTags",
- "CleanName"
+ "CleanName",
+ "PresentationUniqueKey"
};
_saveItemCommand = _connection.CreateCommand();
_saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
@@ -803,6 +810,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
_saveItemCommand.GetParameter(index++).Value = item.Name.RemoveDiacritics();
}
+ _saveItemCommand.GetParameter(index++).Value = item.PresentationUniqueKey;
_saveItemCommand.Transaction = transaction;
@@ -1463,6 +1471,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
CheckDisposed();
+ var now = DateTime.UtcNow;
+
using (var cmd = _connection.CreateCommand())
{
cmd.CommandText = "select " + string.Join(",", _retriveItemColumns) + " from TypedBaseItems";
@@ -1475,6 +1485,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.CommandText += whereText;
+ if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
+ {
+ cmd.CommandText += " Group by PresentationUniqueKey";
+ }
+
cmd.CommandText += GetOrderByText(query);
if (query.Limit.HasValue)
@@ -1482,10 +1497,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture);
}
- //Logger.Debug(cmd.CommandText);
-
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
{
+ Logger.Debug("GetItemList query time: {0}ms. Query: {1}",
+ Convert.ToInt32((DateTime.UtcNow - now).TotalMilliseconds),
+ cmd.CommandText);
+
while (reader.Read())
{
var item = GetItem(reader);
@@ -1507,6 +1524,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
CheckDisposed();
+ var now = DateTime.UtcNow;
+
using (var cmd = _connection.CreateCommand())
{
cmd.CommandText = "select " + string.Join(",", _retriveItemColumns) + " from TypedBaseItems";
@@ -1525,6 +1544,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.CommandText += whereText;
+ if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
+ {
+ cmd.CommandText += " Group by PresentationUniqueKey";
+ }
+
cmd.CommandText += GetOrderByText(query);
if (query.Limit.HasValue)
@@ -1532,15 +1556,24 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture);
}
- cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging;
-
- //Logger.Debug(cmd.CommandText);
+ if (_config.Configuration.SchemaVersion >= 66)
+ {
+ cmd.CommandText += "; select count (distinct PresentationUniqueKey) from TypedBaseItems" + whereTextWithoutPaging;
+ }
+ else
+ {
+ cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging;
+ }
var list = new List<BaseItem>();
var count = 0;
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
{
+ Logger.Debug("GetItems query time: {0}ms. Query: {1}",
+ Convert.ToInt32((DateTime.UtcNow - now).TotalMilliseconds),
+ cmd.CommandText);
+
while (reader.Read())
{
var item = GetItem(reader);
@@ -1608,6 +1641,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
CheckDisposed();
+ var now = DateTime.UtcNow;
+
using (var cmd = _connection.CreateCommand())
{
cmd.CommandText = "select guid from TypedBaseItems";
@@ -1620,6 +1655,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.CommandText += whereText;
+ if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
+ {
+ cmd.CommandText += " Group by PresentationUniqueKey";
+ }
+
cmd.CommandText += GetOrderByText(query);
if (query.Limit.HasValue)
@@ -1629,10 +1669,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
var list = new List<Guid>();
- //Logger.Debug(cmd.CommandText);
-
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
{
+ Logger.Debug("GetItemIdsList query time: {0}ms. Query: {1}",
+ Convert.ToInt32((DateTime.UtcNow - now).TotalMilliseconds),
+ cmd.CommandText);
+
while (reader.Read())
{
list.Add(reader.GetGuid(0));
@@ -1662,7 +1704,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
- whereClauses = GetWhereClauses(query, cmd, true);
+ whereClauses = GetWhereClauses(query, cmd, true, false);
var whereText = whereClauses.Count == 0 ?
string.Empty :
@@ -1670,6 +1712,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.CommandText += whereText;
+ if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
+ {
+ cmd.CommandText += " Group by PresentationUniqueKey";
+ }
+
cmd.CommandText += GetOrderByText(query);
if (query.Limit.HasValue)
@@ -1721,6 +1768,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
CheckDisposed();
+ var now = DateTime.UtcNow;
+
using (var cmd = _connection.CreateCommand())
{
cmd.CommandText = "select guid from TypedBaseItems";
@@ -1739,6 +1788,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.CommandText += whereText;
+ if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
+ {
+ cmd.CommandText += " Group by PresentationUniqueKey";
+ }
+
cmd.CommandText += GetOrderByText(query);
if (query.Limit.HasValue)
@@ -1746,15 +1800,24 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture);
}
- cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging;
+ if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
+ {
+ cmd.CommandText += "; select count (distinct PresentationUniqueKey) from TypedBaseItems" + whereTextWithoutPaging;
+ }
+ else
+ {
+ cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging;
+ }
var list = new List<Guid>();
var count = 0;
- //Logger.Debug(cmd.CommandText);
-
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
{
+ Logger.Debug("GetItemIds query time: {0}ms. Query: {1}",
+ Convert.ToInt32((DateTime.UtcNow - now).TotalMilliseconds),
+ cmd.CommandText);
+
while (reader.Read())
{
list.Add(reader.GetGuid(0));
@@ -1774,7 +1837,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
}
- private List<string> GetWhereClauses(InternalItemsQuery query, IDbCommand cmd, bool addPaging)
+ private List<string> GetWhereClauses(InternalItemsQuery query, IDbCommand cmd, bool addPaging, bool enablePresentationUniqueKey = true)
{
var whereClauses = new List<string>();
@@ -1873,6 +1936,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.Parameters.Add(cmd, "@Path", DbType.String).Value = query.Path;
}
+ if (!string.IsNullOrWhiteSpace(query.PresentationUniqueKey))
+ {
+ whereClauses.Add("PresentationUniqueKey=@PresentationUniqueKey");
+ cmd.Parameters.Add(cmd, "@PresentationUniqueKey", DbType.String).Value = query.PresentationUniqueKey;
+ }
+
if (query.MinCommunityRating.HasValue)
{
whereClauses.Add("CommunityRating>=@MinCommunityRating");
@@ -1998,9 +2067,40 @@ namespace MediaBrowser.Server.Implementations.Persistence
if (!string.IsNullOrWhiteSpace(query.NameContains))
{
- whereClauses.Add("CleanName like @NameContains");
+ if (_config.Configuration.SchemaVersion >= 66)
+ {
+ whereClauses.Add("CleanName like @NameContains");
+ }
+ else
+ {
+ whereClauses.Add("Name like @NameContains");
+ }
cmd.Parameters.Add(cmd, "@NameContains", DbType.String).Value = "%" + query.NameContains + "%";
}
+ if (!string.IsNullOrWhiteSpace(query.NameStartsWith))
+ {
+ if (_config.Configuration.SchemaVersion >= 66)
+ {
+ whereClauses.Add("CleanName like @NameStartsWith");
+ }
+ else
+ {
+ whereClauses.Add("Name like @NameStartsWith");
+ }
+ cmd.Parameters.Add(cmd, "@NameStartsWith", DbType.String).Value = query.NameStartsWith + "%";
+ }
+ if (!string.IsNullOrWhiteSpace(query.NameStartsWithOrGreater))
+ {
+ whereClauses.Add("SortName >= @NameStartsWithOrGreater");
+ // lowercase this because SortName is stored as lowercase
+ cmd.Parameters.Add(cmd, "@NameStartsWithOrGreater", DbType.String).Value = query.NameStartsWithOrGreater.ToLower();
+ }
+ if (!string.IsNullOrWhiteSpace(query.NameLessThan))
+ {
+ whereClauses.Add("SortName < @NameLessThan");
+ // lowercase this because SortName is stored as lowercase
+ cmd.Parameters.Add(cmd, "@NameLessThan", DbType.String).Value = query.NameLessThan.ToLower();
+ }
if (query.Genres.Length > 0)
{
@@ -2134,7 +2234,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
whereClauses.Add("MediaType in (" + val + ")");
}
- var enableItemsByName = query.IncludeItemsByName ?? query.IncludeItemTypes.Length > 0;
+ //var enableItemsByName = query.IncludeItemsByName ?? query.IncludeItemTypes.Length > 0;
+ var enableItemsByName = query.IncludeItemsByName ?? false;
if (query.TopParentIds.Length == 1)
{
@@ -2197,7 +2298,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
excludeTagIndex = 0;
foreach (var excludeTag in query.ExcludeInheritedTags)
{
- whereClauses.Add("(InheritedTags is null OR InheritedTags not like @excludeInheritedTag" + excludeTagIndex +")");
+ whereClauses.Add("(InheritedTags is null OR InheritedTags not like @excludeInheritedTag" + excludeTagIndex + ")");
cmd.Parameters.Add(cmd, "@excludeInheritedTag" + excludeTagIndex, DbType.String).Value = "%" + excludeTag + "%";
excludeTagIndex++;
}
@@ -2210,6 +2311,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
+ if (enablePresentationUniqueKey && EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
+ {
+ pagingWhereText += " Group by PresentationUniqueKey";
+ }
+
var orderBy = GetOrderByText(query);
whereClauses.Add(string.Format("guid NOT IN (SELECT guid FROM TypedBaseItems {0}" + orderBy + " LIMIT {1})",
@@ -2221,6 +2327,34 @@ namespace MediaBrowser.Server.Implementations.Persistence
return whereClauses;
}
+ private bool EnableGroupByPresentationUniqueKey(InternalItemsQuery query)
+ {
+ if (!string.IsNullOrWhiteSpace(query.PresentationUniqueKey))
+ {
+ return false;
+ }
+
+ if (query.IncludeItemTypes.Length == 0)
+ {
+ return true;
+ }
+
+ var types = new[] {
+ typeof(Episode).Name,
+ typeof(Video).Name ,
+ typeof(Movie).Name ,
+ typeof(MusicVideo).Name ,
+ typeof(Series).Name ,
+ typeof(Season).Name };
+
+ if (types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase)))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
private static readonly Type[] KnownTypes =
{
typeof(LiveTvProgram),
@@ -2299,7 +2433,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
try
{
transaction = _connection.BeginTransaction();
-
+
foreach (var item in newValues)
{
_updateInheritedTagsCommand.GetParameter(0).Value = item.Item1;
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs
index dbceda727b..40d5c9586e 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs
@@ -39,11 +39,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
/// Opens the connection to the database
/// </summary>
/// <returns>Task.</returns>
- public async Task Initialize()
+ public async Task Initialize(IDbConnector dbConnector)
{
var dbFile = Path.Combine(_appPaths.DataPath, "refreshinfo.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
+ _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
string[] queries = {
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
index 63c41c71fe..33a2b11877 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
@@ -37,11 +37,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
/// Opens the connection to the database
/// </summary>
/// <returns>Task.</returns>
- public async Task Initialize()
+ public async Task Initialize(IDbConnector dbConnector)
{
var dbFile = Path.Combine(_appPaths.DataPath, "userdata_v2.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
+ _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
string[] queries = {
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs
index 9bd7e47f39..f7ca39a548 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs
@@ -43,12 +43,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
/// Opens the connection to the database
/// </summary>
/// <returns>Task.</returns>
- public async Task Initialize()
+ public async Task Initialize(IDbConnector dbConnector)
{
var dbFile = Path.Combine(_appPaths.DataPath, "users.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
-
+ _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
+
string[] queries = {
"create table if not exists users (guid GUID primary key, data BLOB)",
diff --git a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs b/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs
index b932f0cac4..e8d9814ecb 100644
--- a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs
+++ b/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs
@@ -27,11 +27,11 @@ namespace MediaBrowser.Server.Implementations.Security
_appPaths = appPaths;
}
- public async Task Initialize()
+ public async Task Initialize(IDbConnector dbConnector)
{
var dbFile = Path.Combine(_appPaths.DataPath, "authentication.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
+ _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
string[] queries = {
diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
index 88f11c3685..014e8babf9 100644
--- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs
+++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
@@ -601,11 +601,9 @@ namespace MediaBrowser.Server.Implementations.Session
if (libraryItem != null)
{
- var key = libraryItem.GetUserDataKey();
-
foreach (var user in users)
{
- await OnPlaybackStart(user.Id, key, libraryItem).ConfigureAwait(false);
+ await OnPlaybackStart(user.Id, libraryItem).ConfigureAwait(false);
}
}
@@ -632,12 +630,11 @@ namespace MediaBrowser.Server.Implementations.Session
/// Called when [playback start].
/// </summary>
/// <param name="userId">The user identifier.</param>
- /// <param name="userDataKey">The user data key.</param>
/// <param name="item">The item.</param>
/// <returns>Task.</returns>
- private async Task OnPlaybackStart(Guid userId, string userDataKey, IHasUserData item)
+ private async Task OnPlaybackStart(Guid userId, IHasUserData item)
{
- var data = _userDataRepository.GetUserData(userId, userDataKey);
+ var data = _userDataRepository.GetUserData(userId, item);
data.PlayCount++;
data.LastPlayedDate = DateTime.UtcNow;
@@ -676,11 +673,9 @@ namespace MediaBrowser.Server.Implementations.Session
if (libraryItem != null)
{
- var key = libraryItem.GetUserDataKey();
-
foreach (var user in users)
{
- await OnPlaybackProgress(user, key, libraryItem, info).ConfigureAwait(false);
+ await OnPlaybackProgress(user, libraryItem, info).ConfigureAwait(false);
}
}
@@ -714,9 +709,9 @@ namespace MediaBrowser.Server.Implementations.Session
StartIdleCheckTimer();
}
- private async Task OnPlaybackProgress(User user, string userDataKey, BaseItem item, PlaybackProgressInfo info)
+ private async Task OnPlaybackProgress(User user, BaseItem item, PlaybackProgressInfo info)
{
- var data = _userDataRepository.GetUserData(user.Id, userDataKey);
+ var data = _userDataRepository.GetUserData(user.Id, item);
var positionTicks = info.PositionTicks;
@@ -811,11 +806,9 @@ namespace MediaBrowser.Server.Implementations.Session
if (libraryItem != null)
{
- var key = libraryItem.GetUserDataKey();
-
foreach (var user in users)
{
- playedToCompletion = await OnPlaybackStopped(user.Id, key, libraryItem, info.PositionTicks, info.Failed).ConfigureAwait(false);
+ playedToCompletion = await OnPlaybackStopped(user.Id, libraryItem, info.PositionTicks, info.Failed).ConfigureAwait(false);
}
}
@@ -848,13 +841,13 @@ namespace MediaBrowser.Server.Implementations.Session
await SendPlaybackStoppedNotification(session, CancellationToken.None).ConfigureAwait(false);
}
- private async Task<bool> OnPlaybackStopped(Guid userId, string userDataKey, BaseItem item, long? positionTicks, bool playbackFailed)
+ private async Task<bool> OnPlaybackStopped(Guid userId, BaseItem item, long? positionTicks, bool playbackFailed)
{
bool playedToCompletion = false;
if (!playbackFailed)
{
- var data = _userDataRepository.GetUserData(userId, userDataKey);
+ var data = _userDataRepository.GetUserData(userId, item);
if (positionTicks.HasValue)
{
diff --git a/MediaBrowser.Server.Implementations/Social/SharingRepository.cs b/MediaBrowser.Server.Implementations/Social/SharingRepository.cs
index d6d7f021a3..317743eb1b 100644
--- a/MediaBrowser.Server.Implementations/Social/SharingRepository.cs
+++ b/MediaBrowser.Server.Implementations/Social/SharingRepository.cs
@@ -26,11 +26,11 @@ namespace MediaBrowser.Server.Implementations.Social
/// Opens the connection to the database
/// </summary>
/// <returns>Task.</returns>
- public async Task Initialize()
+ public async Task Initialize(IDbConnector dbConnector)
{
var dbFile = Path.Combine(_appPaths.DataPath, "shares.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
+ _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
string[] queries = {
diff --git a/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs b/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs
index 70cf805cf1..91abbe34c9 100644
--- a/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs
+++ b/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs
@@ -49,8 +49,8 @@ namespace MediaBrowser.Server.Implementations.Sorting
private int Compare(Episode x, Episode y)
{
- var isXSpecial = (x.PhysicalSeasonNumber ?? -1) == 0;
- var isYSpecial = (y.PhysicalSeasonNumber ?? -1) == 0;
+ var isXSpecial = (x.ParentIndexNumber ?? -1) == 0;
+ var isYSpecial = (y.ParentIndexNumber ?? -1) == 0;
if (isXSpecial && isYSpecial)
{
@@ -74,7 +74,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
{
// http://thetvdb.com/wiki/index.php?title=Special_Episodes
- var xSeason = x.PhysicalSeasonNumber ?? -1;
+ var xSeason = x.ParentIndexNumber ?? -1;
var ySeason = y.AirsAfterSeasonNumber ?? y.AirsBeforeSeasonNumber ?? -1;
if (xSeason != ySeason)
@@ -142,8 +142,8 @@ namespace MediaBrowser.Server.Implementations.Sorting
private int CompareEpisodes(Episode x, Episode y)
{
- var xValue = (x.PhysicalSeasonNumber ?? -1) * 1000 + (x.IndexNumber ?? -1);
- var yValue = (y.PhysicalSeasonNumber ?? -1) * 1000 + (y.IndexNumber ?? -1);
+ var xValue = (x.ParentIndexNumber ?? -1) * 1000 + (x.IndexNumber ?? -1);
+ var yValue = (y.ParentIndexNumber ?? -1) * 1000 + (y.IndexNumber ?? -1);
return xValue.CompareTo(yValue);
}
diff --git a/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs b/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs
index c881591beb..3edf23020a 100644
--- a/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs
+++ b/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs
@@ -47,7 +47,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
/// <returns>DateTime.</returns>
private DateTime GetDate(BaseItem x)
{
- var userdata = UserDataRepository.GetUserData(User.Id, x.GetUserDataKey());
+ var userdata = UserDataRepository.GetUserData(User, x);
if (userdata != null && userdata.LastPlayedDate.HasValue)
{
diff --git a/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs b/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs
index 1bc5261b44..8b14efffcf 100644
--- a/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs
+++ b/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs
@@ -34,7 +34,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
/// <returns>DateTime.</returns>
private int GetValue(BaseItem x)
{
- var userdata = UserDataRepository.GetUserData(User.Id, x.GetUserDataKey());
+ var userdata = UserDataRepository.GetUserData(User, x);
return userdata == null ? 0 : userdata.PlayCount;
}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
index fe1a7fb28f..38edc30240 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
@@ -687,7 +687,7 @@ namespace MediaBrowser.Server.Implementations.Sync
private Task ReportOfflinePlayedItem(UserAction action)
{
var item = _libraryManager.GetItemById(action.ItemId);
- var userData = _userDataManager.GetUserData(new Guid(action.UserId), item.GetUserDataKey());
+ var userData = _userDataManager.GetUserData(action.UserId, item);
userData.LastPlayedDate = action.Date;
_userDataManager.UpdatePlayState(item, userData, action.PositionTicks);
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
index 965c081ebd..6d31663b97 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
@@ -39,11 +39,11 @@ namespace MediaBrowser.Server.Implementations.Sync
_appPaths = appPaths;
}
- public async Task Initialize()
+ public async Task Initialize(IDbConnector dbConnector)
{
var dbFile = Path.Combine(_appPaths.DataPath, "sync14.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
+ _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
string[] queries = {
diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs
index 3e43ebe9b8..ec91dc1b71 100644
--- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs
+++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs
@@ -36,10 +36,25 @@ namespace MediaBrowser.Server.Implementations.TV
? new string[] { }
: new[] { request.ParentId };
+ string presentationUniqueKey = null;
+ int? limit = null;
+ if (!string.IsNullOrWhiteSpace(request.SeriesId))
+ {
+ var series = _libraryManager.GetItemById(request.SeriesId);
+
+ if (series != null)
+ {
+ presentationUniqueKey = series.PresentationUniqueKey;
+ limit = 1;
+ }
+ }
+
var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
IncludeItemTypes = new[] { typeof(Series).Name },
- SortOrder = SortOrder.Ascending
+ SortOrder = SortOrder.Ascending,
+ PresentationUniqueKey = presentationUniqueKey,
+ Limit = limit
}, parentIds).Cast<Series>();
@@ -58,10 +73,25 @@ namespace MediaBrowser.Server.Implementations.TV
throw new ArgumentException("User not found");
}
+ string presentationUniqueKey = null;
+ int? limit = null;
+ if (!string.IsNullOrWhiteSpace(request.SeriesId))
+ {
+ var series = _libraryManager.GetItemById(request.SeriesId);
+
+ if (series != null)
+ {
+ presentationUniqueKey = series.PresentationUniqueKey;
+ limit = 1;
+ }
+ }
+
var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
IncludeItemTypes = new[] { typeof(Series).Name },
- SortOrder = SortOrder.Ascending
+ SortOrder = SortOrder.Ascending,
+ PresentationUniqueKey = presentationUniqueKey,
+ Limit = limit
}, parentsFolders.Select(i => i.Id.ToString("N"))).Cast<Series>();
@@ -76,30 +106,30 @@ namespace MediaBrowser.Server.Implementations.TV
// Avoid implicitly captured closure
var currentUser = user;
- return FilterSeries(request, series)
+ return series
.AsParallel()
.Select(i => GetNextUp(i, currentUser))
// Include if an episode was found, and either the series is not unwatched or the specific series was requested
.Where(i => i.Item1 != null && (!i.Item3 || !string.IsNullOrWhiteSpace(request.SeriesId)))
- .OrderByDescending(i =>
- {
- var episode = i.Item1;
+ //.OrderByDescending(i =>
+ //{
+ // var episode = i.Item1;
- var seriesUserData = _userDataManager.GetUserData(user.Id, episode.Series.GetUserDataKey());
+ // var seriesUserData = _userDataManager.GetUserData(user, episode.Series);
- if (seriesUserData.IsFavorite)
- {
- return 2;
- }
+ // if (seriesUserData.IsFavorite)
+ // {
+ // return 2;
+ // }
- if (seriesUserData.Likes.HasValue)
- {
- return seriesUserData.Likes.Value ? 1 : -1;
- }
+ // if (seriesUserData.Likes.HasValue)
+ // {
+ // return seriesUserData.Likes.Value ? 1 : -1;
+ // }
- return 0;
- })
- .ThenByDescending(i => i.Item2)
+ // return 0;
+ //})
+ .OrderByDescending(i => i.Item2)
.ThenByDescending(i => i.Item1.PremiereDate ?? DateTime.MinValue)
.Select(i => i.Item1);
}
@@ -128,7 +158,7 @@ namespace MediaBrowser.Server.Implementations.TV
// Go back starting with the most recent episodes
foreach (var episode in allEpisodes)
{
- var userData = _userDataManager.GetUserData(user.Id, episode.GetUserDataKey());
+ var userData = _userDataManager.GetUserData(user, episode);
if (userData.Played)
{
@@ -142,7 +172,7 @@ namespace MediaBrowser.Server.Implementations.TV
}
else
{
- if (!episode.IsVirtualUnaired && (!episode.IsMissingEpisode || includeMissing))
+ if (!episode.IsVirtualUnaired && (includeMissing || !episode.IsMissingEpisode))
{
nextUp = episode;
}
@@ -154,24 +184,12 @@ namespace MediaBrowser.Server.Implementations.TV
return new Tuple<Episode, DateTime, bool>(nextUp, lastWatchedDate, false);
}
- var firstEpisode = allEpisodes.LastOrDefault(i => !i.IsVirtualUnaired && (!i.IsMissingEpisode || includeMissing) && !i.IsPlayed(user));
+ var firstEpisode = allEpisodes.LastOrDefault(i => !i.IsVirtualUnaired && (includeMissing || !i.IsMissingEpisode) && !i.IsPlayed(user));
// Return the first episode
return new Tuple<Episode, DateTime, bool>(firstEpisode, DateTime.MinValue, true);
}
- private IEnumerable<Series> FilterSeries(NextUpQuery request, IEnumerable<Series> items)
- {
- if (!string.IsNullOrWhiteSpace(request.SeriesId))
- {
- var id = new Guid(request.SeriesId);
-
- items = items.Where(i => i.Id == id);
- }
-
- return items;
- }
-
private QueryResult<BaseItem> GetResult(IEnumerable<BaseItem> items, int? totalRecordLimit, NextUpQuery query)
{
var itemsArray = totalRecordLimit.HasValue ? items.Take(totalRecordLimit.Value).ToArray() : items.ToArray();