using System; using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using SQLitePCL.pretty; namespace Emby.Server.Implementations.Data { /// /// Class SQLiteDisplayPreferencesRepository /// public class SqliteDisplayPreferencesRepository : BaseSqliteRepository, IDisplayPreferencesRepository { private readonly IMemoryStreamFactory _memoryStreamProvider; public SqliteDisplayPreferencesRepository(ILogger logger, IJsonSerializer jsonSerializer, IApplicationPaths appPaths, IMemoryStreamFactory memoryStreamProvider) : base(logger) { _jsonSerializer = jsonSerializer; _memoryStreamProvider = memoryStreamProvider; DbFilePath = Path.Combine(appPaths.DataPath, "displaypreferences.db"); } /// /// Gets the name of the repository /// /// The name. public string Name { get { return "SQLite"; } } /// /// The _json serializer /// private readonly IJsonSerializer _jsonSerializer; /// /// Opens the connection to the database /// /// Task. public void Initialize() { using (var connection = CreateConnection()) { RunDefaultInitialization(connection); string[] queries = { "create table if not exists userdisplaypreferences (id GUID, userId GUID, client text, data BLOB)", "create unique index if not exists userdisplaypreferencesindex on userdisplaypreferences (id, userId, client)" }; connection.RunQueries(queries); } } /// /// Save the display preferences associated with an item in the repo /// /// The display preferences. /// The user id. /// The client. /// The cancellation token. /// Task. /// item public async Task SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client, CancellationToken cancellationToken) { if (displayPreferences == null) { throw new ArgumentNullException("displayPreferences"); } if (string.IsNullOrWhiteSpace(displayPreferences.Id)) { throw new ArgumentNullException("displayPreferences.Id"); } cancellationToken.ThrowIfCancellationRequested(); using (WriteLock.Write()) { using (var connection = CreateConnection()) { connection.RunInTransaction(db => { SaveDisplayPreferences(displayPreferences, userId, client, db); }, TransactionMode); } } } private void SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client, IDatabaseConnection connection) { var serialized = _jsonSerializer.SerializeToBytes(displayPreferences, _memoryStreamProvider); using (var statement = connection.PrepareStatement("replace into userdisplaypreferences (id, userid, client, data) values (@id, @userId, @client, @data)")) { statement.TryBind("@id", displayPreferences.Id.ToGuidParamValue()); statement.TryBind("@userId", userId.ToGuidParamValue()); statement.TryBind("@client", client); statement.TryBind("@data", serialized); statement.MoveNext(); } } /// /// Save all display preferences associated with a user in the repo /// /// The display preferences. /// The user id. /// The cancellation token. /// Task. /// item public async Task SaveAllDisplayPreferences(IEnumerable displayPreferences, Guid userId, CancellationToken cancellationToken) { if (displayPreferences == null) { throw new ArgumentNullException("displayPreferences"); } cancellationToken.ThrowIfCancellationRequested(); using (WriteLock.Write()) { using (var connection = CreateConnection()) { connection.RunInTransaction(db => { foreach (var displayPreference in displayPreferences) { SaveDisplayPreferences(displayPreference, userId, displayPreference.Client, db); } }, TransactionMode); } } } /// /// Gets the display preferences. /// /// The display preferences id. /// The user id. /// The client. /// Task{DisplayPreferences}. /// item public DisplayPreferences GetDisplayPreferences(string displayPreferencesId, Guid userId, string client) { if (string.IsNullOrWhiteSpace(displayPreferencesId)) { throw new ArgumentNullException("displayPreferencesId"); } var guidId = displayPreferencesId.GetMD5(); using (WriteLock.Read()) { using (var connection = CreateConnection(true)) { using (var statement = connection.PrepareStatement("select data from userdisplaypreferences where id = @id and userId=@userId and client=@client")) { statement.TryBind("@id", guidId.ToGuidParamValue()); statement.TryBind("@userId", userId.ToGuidParamValue()); statement.TryBind("@client", client); foreach (var row in statement.ExecuteQuery()) { return Get(row); } } return new DisplayPreferences { Id = guidId.ToString("N") }; } } } /// /// Gets all display preferences for the given user. /// /// The user id. /// Task{DisplayPreferences}. /// item public IEnumerable GetAllDisplayPreferences(Guid userId) { var list = new List(); using (WriteLock.Read()) { using (var connection = CreateConnection(true)) { using (var statement = connection.PrepareStatement("select data from userdisplaypreferences where userId=@userId")) { statement.TryBind("@userId", userId.ToGuidParamValue()); foreach (var row in statement.ExecuteQuery()) { list.Add(Get(row)); } } } } return list; } private DisplayPreferences Get(IReadOnlyList row) { using (var stream = _memoryStreamProvider.CreateNew(row[0].ToBlob())) { stream.Position = 0; return _jsonSerializer.DeserializeFromStream(stream); } } public Task SaveDisplayPreferences(DisplayPreferences displayPreferences, string userId, string client, CancellationToken cancellationToken) { return SaveDisplayPreferences(displayPreferences, new Guid(userId), client, cancellationToken); } public DisplayPreferences GetDisplayPreferences(string displayPreferencesId, string userId, string client) { return GetDisplayPreferences(displayPreferencesId, new Guid(userId), client); } } }