aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Data
diff options
context:
space:
mode:
authorcrobibero <cody@robibe.ro>2020-06-20 15:56:42 -0600
committercrobibero <cody@robibe.ro>2020-06-20 15:56:42 -0600
commit3329b08b40bb7d7e98264969c1b4c9e356fbdec2 (patch)
treefbbaa4e95adf35533f037ae18490d908eff5a608 /Emby.Server.Implementations/Data
parent7a77b9928f2c8326e85629d3c900e86c3b26342a (diff)
parent576ffeb2a99e79caf0035eb9166436d1e0161d2c (diff)
Merge remote-tracking branch 'upstream/api-migration' into api-playlist
Diffstat (limited to 'Emby.Server.Implementations/Data')
-rw-r--r--Emby.Server.Implementations/Data/BaseSqliteRepository.cs4
-rw-r--r--Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs2
-rw-r--r--Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs2
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs64
-rw-r--r--Emby.Server.Implementations/Data/SqliteUserDataRepository.cs11
-rw-r--r--Emby.Server.Implementations/Data/SqliteUserRepository.cs240
6 files changed, 54 insertions, 269 deletions
diff --git a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
index 0654132f4..f816fd54f 100644
--- a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
+++ b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
@@ -17,7 +17,7 @@ namespace Emby.Server.Implementations.Data
/// Initializes a new instance of the <see cref="BaseSqliteRepository"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
- protected BaseSqliteRepository(ILogger logger)
+ protected BaseSqliteRepository(ILogger<BaseSqliteRepository> logger)
{
Logger = logger;
}
@@ -32,7 +32,7 @@ namespace Emby.Server.Implementations.Data
/// Gets the logger.
/// </summary>
/// <value>The logger.</value>
- protected ILogger Logger { get; }
+ protected ILogger<BaseSqliteRepository> Logger { get; }
/// <summary>
/// Gets the default connection flags.
diff --git a/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs b/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
index 37c678a5d..6c9bcff0f 100644
--- a/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
+++ b/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
@@ -12,7 +12,7 @@ namespace Emby.Server.Implementations.Data
public class CleanDatabaseScheduledTask : ILibraryPostScanTask
{
private readonly ILibraryManager _libraryManager;
- private readonly ILogger _logger;
+ private readonly ILogger<CleanDatabaseScheduledTask> _logger;
public CleanDatabaseScheduledTask(ILibraryManager libraryManager, ILogger<CleanDatabaseScheduledTask> logger)
{
diff --git a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs
index d474f1c6b..63d0321b7 100644
--- a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using System;
using System.Collections.Generic;
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 33ff74bb5..43a593f11 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -33,18 +35,17 @@ using SQLitePCL.pretty;
namespace Emby.Server.Implementations.Data
{
/// <summary>
- /// Class SQLiteItemRepository
+ /// Class SQLiteItemRepository.
/// </summary>
public class SqliteItemRepository : BaseSqliteRepository, IItemRepository
{
private const string ChaptersTableName = "Chapters2";
- /// <summary>
- /// The _app paths
- /// </summary>
private readonly IServerConfigurationManager _config;
private readonly IServerApplicationHost _appHost;
private readonly ILocalizationManager _localization;
+ // TODO: Remove this dependency. GetImageCacheTag() is the only method used and it can be converted to a static helper method
+ private readonly IImageProcessor _imageProcessor;
private readonly TypeMapper _typeMapper;
private readonly JsonSerializerOptions _jsonOptions;
@@ -71,7 +72,8 @@ namespace Emby.Server.Implementations.Data
IServerConfigurationManager config,
IServerApplicationHost appHost,
ILogger<SqliteItemRepository> logger,
- ILocalizationManager localization)
+ ILocalizationManager localization,
+ IImageProcessor imageProcessor)
: base(logger)
{
if (config == null)
@@ -82,6 +84,7 @@ namespace Emby.Server.Implementations.Data
_config = config;
_appHost = appHost;
_localization = localization;
+ _imageProcessor = imageProcessor;
_typeMapper = new TypeMapper();
_jsonOptions = JsonDefaults.GetOptions();
@@ -98,8 +101,6 @@ namespace Emby.Server.Implementations.Data
/// <inheritdoc />
protected override TempStoreMode TempStore => TempStoreMode.Memory;
- public IImageProcessor ImageProcessor { get; set; }
-
/// <summary>
/// Opens the connection to the database
/// </summary>
@@ -1142,24 +1143,24 @@ namespace Emby.Server.Implementations.Data
public string ToValueString(ItemImageInfo image)
{
- var delimeter = "*";
+ const string Delimeter = "*";
- var path = image.Path;
-
- if (path == null)
- {
- path = string.Empty;
- }
+ var path = image.Path ?? string.Empty;
+ var hash = image.BlurHash ?? string.Empty;
return GetPathToSave(path) +
- delimeter +
+ Delimeter +
image.DateModified.Ticks.ToString(CultureInfo.InvariantCulture) +
- delimeter +
+ Delimeter +
image.Type +
- delimeter +
+ Delimeter +
image.Width.ToString(CultureInfo.InvariantCulture) +
- delimeter +
- image.Height.ToString(CultureInfo.InvariantCulture);
+ Delimeter +
+ image.Height.ToString(CultureInfo.InvariantCulture) +
+ Delimeter +
+ // Replace delimiters with other characters.
+ // This can be removed when we migrate to a proper DB.
+ hash.Replace('*', '/').Replace('|', '\\');
}
public ItemImageInfo ItemImageInfoFromValueString(string value)
@@ -1193,6 +1194,11 @@ namespace Emby.Server.Implementations.Data
image.Width = width;
image.Height = height;
}
+
+ if (parts.Length >= 6)
+ {
+ image.BlurHash = parts[5].Replace('/', '*').Replace('\\', '|');
+ }
}
return image;
@@ -1620,11 +1626,11 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
- IEnumerable<MetadataFields> GetLockedFields(string s)
+ IEnumerable<MetadataField> GetLockedFields(string s)
{
foreach (var i in s.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
{
- if (Enum.TryParse(i, true, out MetadataFields parsedValue))
+ if (Enum.TryParse(i, true, out MetadataField parsedValue))
{
yield return parsedValue;
}
@@ -1972,6 +1978,7 @@ namespace Emby.Server.Implementations.Data
/// Gets the chapter.
/// </summary>
/// <param name="reader">The reader.</param>
+ /// <param name="item">The item.</param>
/// <returns>ChapterInfo.</returns>
private ChapterInfo GetChapter(IReadOnlyList<IResultSetValue> reader, BaseItem item)
{
@@ -1991,7 +1998,14 @@ namespace Emby.Server.Implementations.Data
if (!string.IsNullOrEmpty(chapter.ImagePath))
{
- chapter.ImageTag = ImageProcessor.GetImageCacheTag(item, chapter);
+ try
+ {
+ chapter.ImageTag = _imageProcessor.GetImageCacheTag(item, chapter);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError(ex, "Failed to create image cache tag.");
+ }
}
}
@@ -2720,7 +2734,7 @@ namespace Emby.Server.Implementations.Data
foreach (var providerId in newItem.ProviderIds)
{
- if (providerId.Key == MetadataProviders.TmdbCollection.ToString())
+ if (providerId.Key == MetadataProvider.TmdbCollection.ToString())
{
continue;
}
@@ -4310,7 +4324,7 @@ namespace Emby.Server.Implementations.Data
var index = 0;
foreach (var pair in query.ExcludeProviderIds)
{
- if (string.Equals(pair.Key, MetadataProviders.TmdbCollection.ToString(), StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(pair.Key, MetadataProvider.TmdbCollection.ToString(), StringComparison.OrdinalIgnoreCase))
{
continue;
}
@@ -4339,7 +4353,7 @@ namespace Emby.Server.Implementations.Data
var index = 0;
foreach (var pair in query.HasAnyProviderId)
{
- if (string.Equals(pair.Key, MetadataProviders.TmdbCollection.ToString(), StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(pair.Key, MetadataProvider.TmdbCollection.ToString(), StringComparison.OrdinalIgnoreCase))
{
continue;
}
diff --git a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
index 22955850a..b99b74ef8 100644
--- a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
+using Jellyfin.Data.Entities;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
@@ -375,5 +376,15 @@ namespace Emby.Server.Implementations.Data
return userData;
}
+
+ /// <inheritdoc/>
+ /// <remarks>
+ /// There is nothing to dispose here since <see cref="BaseSqliteRepository.WriteLock"/> and
+ /// <see cref="BaseSqliteRepository.WriteConnection"/> are managed by <see cref="SqliteItemRepository"/>.
+ /// See <see cref="Initialize(IUserManager, SemaphoreSlim, SQLiteDatabaseConnection)"/>.
+ /// </remarks>
+ protected override void Dispose(bool dispose)
+ {
+ }
}
}
diff --git a/Emby.Server.Implementations/Data/SqliteUserRepository.cs b/Emby.Server.Implementations/Data/SqliteUserRepository.cs
deleted file mode 100644
index 0c3f26974..000000000
--- a/Emby.Server.Implementations/Data/SqliteUserRepository.cs
+++ /dev/null
@@ -1,240 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text.Json;
-using MediaBrowser.Common.Json;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Persistence;
-using Microsoft.Extensions.Logging;
-using SQLitePCL.pretty;
-
-namespace Emby.Server.Implementations.Data
-{
- /// <summary>
- /// Class SQLiteUserRepository
- /// </summary>
- public class SqliteUserRepository : BaseSqliteRepository, IUserRepository
- {
- private readonly JsonSerializerOptions _jsonOptions;
-
- public SqliteUserRepository(
- ILogger<SqliteUserRepository> logger,
- IServerApplicationPaths appPaths)
- : base(logger)
- {
- _jsonOptions = JsonDefaults.GetOptions();
-
- DbFilePath = Path.Combine(appPaths.DataPath, "users.db");
- }
-
- /// <summary>
- /// Gets the name of the repository
- /// </summary>
- /// <value>The name.</value>
- public string Name => "SQLite";
-
- /// <summary>
- /// Opens the connection to the database.
- /// </summary>
- public void Initialize()
- {
- using (var connection = GetConnection())
- {
- var localUsersTableExists = TableExists(connection, "LocalUsersv2");
-
- connection.RunQueries(new[] {
- "create table if not exists LocalUsersv2 (Id INTEGER PRIMARY KEY, guid GUID NOT NULL, data BLOB NOT NULL)",
- "drop index if exists idx_users"
- });
-
- if (!localUsersTableExists && TableExists(connection, "Users"))
- {
- TryMigrateToLocalUsersTable(connection);
- }
-
- RemoveEmptyPasswordHashes(connection);
- }
- }
-
- private void TryMigrateToLocalUsersTable(ManagedConnection connection)
- {
- try
- {
- connection.RunQueries(new[]
- {
- "INSERT INTO LocalUsersv2 (guid, data) SELECT guid,data from users"
- });
- }
- catch (Exception ex)
- {
- Logger.LogError(ex, "Error migrating users database");
- }
- }
-
- private void RemoveEmptyPasswordHashes(ManagedConnection connection)
- {
- foreach (var user in RetrieveAllUsers(connection))
- {
- // If the user password is the sha1 hash of the empty string, remove it
- if (!string.Equals(user.Password, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal)
- && !string.Equals(user.Password, "$SHA1$DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal))
- {
- continue;
- }
-
- user.Password = null;
- var serialized = JsonSerializer.SerializeToUtf8Bytes(user, _jsonOptions);
-
- connection.RunInTransaction(db =>
- {
- using (var statement = db.PrepareStatement("update LocalUsersv2 set data=@data where Id=@InternalId"))
- {
- statement.TryBind("@InternalId", user.InternalId);
- statement.TryBind("@data", serialized);
- statement.MoveNext();
- }
- }, TransactionMode);
- }
- }
-
- /// <summary>
- /// Save a user in the repo
- /// </summary>
- public void CreateUser(User user)
- {
- if (user == null)
- {
- throw new ArgumentNullException(nameof(user));
- }
-
- var serialized = JsonSerializer.SerializeToUtf8Bytes(user, _jsonOptions);
-
- using (var connection = GetConnection())
- {
- connection.RunInTransaction(db =>
- {
- using (var statement = db.PrepareStatement("insert into LocalUsersv2 (guid, data) values (@guid, @data)"))
- {
- statement.TryBind("@guid", user.Id.ToByteArray());
- statement.TryBind("@data", serialized);
-
- statement.MoveNext();
- }
-
- var createdUser = GetUser(user.Id, connection);
-
- if (createdUser == null)
- {
- throw new ApplicationException("created user should never be null");
- }
-
- user.InternalId = createdUser.InternalId;
-
- }, TransactionMode);
- }
- }
-
- public void UpdateUser(User user)
- {
- if (user == null)
- {
- throw new ArgumentNullException(nameof(user));
- }
-
- var serialized = JsonSerializer.SerializeToUtf8Bytes(user, _jsonOptions);
-
- using (var connection = GetConnection())
- {
- connection.RunInTransaction(db =>
- {
- using (var statement = db.PrepareStatement("update LocalUsersv2 set data=@data where Id=@InternalId"))
- {
- statement.TryBind("@InternalId", user.InternalId);
- statement.TryBind("@data", serialized);
- statement.MoveNext();
- }
-
- }, TransactionMode);
- }
- }
-
- private User GetUser(Guid guid, ManagedConnection connection)
- {
- using (var statement = connection.PrepareStatement("select id,guid,data from LocalUsersv2 where guid=@guid"))
- {
- statement.TryBind("@guid", guid);
-
- foreach (var row in statement.ExecuteQuery())
- {
- return GetUser(row);
- }
- }
-
- return null;
- }
-
- private User GetUser(IReadOnlyList<IResultSetValue> row)
- {
- var id = row[0].ToInt64();
- var guid = row[1].ReadGuidFromBlob();
-
- var user = JsonSerializer.Deserialize<User>(row[2].ToBlob(), _jsonOptions);
- user.InternalId = id;
- user.Id = guid;
- return user;
- }
-
- /// <summary>
- /// Retrieve all users from the database
- /// </summary>
- /// <returns>IEnumerable{User}.</returns>
- public List<User> RetrieveAllUsers()
- {
- using (var connection = GetConnection(true))
- {
- return new List<User>(RetrieveAllUsers(connection));
- }
- }
-
- /// <summary>
- /// Retrieve all users from the database
- /// </summary>
- /// <returns>IEnumerable{User}.</returns>
- private IEnumerable<User> RetrieveAllUsers(ManagedConnection connection)
- {
- foreach (var row in connection.Query("select id,guid,data from LocalUsersv2"))
- {
- yield return GetUser(row);
- }
- }
-
- /// <summary>
- /// Deletes the user.
- /// </summary>
- /// <param name="user">The user.</param>
- /// <returns>Task.</returns>
- /// <exception cref="ArgumentNullException">user</exception>
- public void DeleteUser(User user)
- {
- if (user == null)
- {
- throw new ArgumentNullException(nameof(user));
- }
-
- using (var connection = GetConnection())
- {
- connection.RunInTransaction(db =>
- {
- using (var statement = db.PrepareStatement("delete from LocalUsersv2 where Id=@id"))
- {
- statement.TryBind("@id", user.InternalId);
- statement.MoveNext();
- }
- }, TransactionMode);
- }
- }
- }
-}