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())
{
connection.ExecuteAll(string.Join(";", new[]
{
"PRAGMA page_size=4096",
"pragma default_temp_store = memory",
"pragma temp_store = memory"
}));
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 (var connection = CreateConnection())
{
using (WriteLock.Write())
{
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 (var connection = CreateConnection())
{
using (WriteLock.Write())
{
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 (var connection = CreateConnection(true))
{
using (WriteLock.Read())
{
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 (var connection = CreateConnection(true))
{
using (WriteLock.Read())
{
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);
}
}
}