using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using System; using System.Data; using System.Data.SQLite; using System.IO; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.Persistence { /// /// Class SQLiteDisplayPreferencesRepository /// public class SqliteDisplayPreferencesRepository : SqliteRepository, IDisplayPreferencesRepository { /// /// The repository name /// public const string RepositoryName = "SQLite"; /// /// Gets the name of the repository /// /// The name. public string Name { get { return RepositoryName; } } /// /// The _json serializer /// private readonly IJsonSerializer _jsonSerializer; /// /// The _app paths /// private readonly IApplicationPaths _appPaths; private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1); /// /// Initializes a new instance of the class. /// /// The app paths. /// The json serializer. /// The log manager. /// /// jsonSerializer /// or /// appPaths /// public SqliteDisplayPreferencesRepository(IApplicationPaths appPaths, IJsonSerializer jsonSerializer, ILogManager logManager) : base(logManager) { if (jsonSerializer == null) { throw new ArgumentNullException("jsonSerializer"); } if (appPaths == null) { throw new ArgumentNullException("appPaths"); } _jsonSerializer = jsonSerializer; _appPaths = appPaths; } /// /// Opens the connection to the database /// /// Task. public async Task Initialize() { var dbFile = Path.Combine(_appPaths.DataPath, "displaypreferences.db"); await ConnectToDb(dbFile).ConfigureAwait(false); string[] queries = { "create table if not exists displaypreferences (id GUID, data BLOB)", "create unique index if not exists displaypreferencesindex on displaypreferences (id)", "create table if not exists schema_version (table_name primary key, version)", //pragmas "pragma temp_store = memory" }; RunQueries(queries); } /// /// Save the display preferences associated with an item in the repo /// /// The display preferences. /// The cancellation token. /// Task. /// item public async Task SaveDisplayPreferences(DisplayPreferences displayPreferences, CancellationToken cancellationToken) { if (displayPreferences == null) { throw new ArgumentNullException("displayPreferences"); } if (displayPreferences.Id == Guid.Empty) { throw new ArgumentNullException("displayPreferences.Id"); } if (cancellationToken == null) { throw new ArgumentNullException("cancellationToken"); } cancellationToken.ThrowIfCancellationRequested(); var serialized = _jsonSerializer.SerializeToBytes(displayPreferences); await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); SQLiteTransaction transaction = null; try { transaction = Connection.BeginTransaction(); using (var cmd = Connection.CreateCommand()) { cmd.CommandText = "replace into displaypreferences (id, data) values (@1, @2)"; cmd.AddParam("@1", displayPreferences.Id); cmd.AddParam("@2", serialized); cmd.Transaction = transaction; await cmd.ExecuteNonQueryAsync(cancellationToken); } transaction.Commit(); } catch (OperationCanceledException) { if (transaction != null) { transaction.Rollback(); } throw; } catch (Exception e) { Logger.ErrorException("Failed to save display preferences:", e); if (transaction != null) { transaction.Rollback(); } throw; } finally { if (transaction != null) { transaction.Dispose(); } _writeLock.Release(); } } /// /// Gets the display preferences. /// /// The display preferences id. /// Task{DisplayPreferences}. /// item public async Task GetDisplayPreferences(Guid displayPreferencesId) { if (displayPreferencesId == Guid.Empty) { throw new ArgumentNullException("displayPreferencesId"); } var cmd = Connection.CreateCommand(); cmd.CommandText = "select data from displaypreferences where id = @id"; var idParam = cmd.Parameters.Add("@id", DbType.Guid); idParam.Value = displayPreferencesId; using (var reader = await cmd.ExecuteReaderAsync(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow).ConfigureAwait(false)) { if (reader.Read()) { using (var stream = GetStream(reader, 0)) { return _jsonSerializer.DeserializeFromStream(stream); } } } return null; } } }