mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-09-06 11:34:57 +02:00
Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser
This commit is contained in:
commit
f4d846dc77
7 changed files with 166 additions and 227 deletions
|
@ -279,7 +279,6 @@ namespace MediaBrowser.Controller.Providers.TV
|
||||||
n = n.SelectSingleNode("./BannerPath");
|
n = n.SelectSingleNode("./BannerPath");
|
||||||
if (n != null)
|
if (n != null)
|
||||||
{
|
{
|
||||||
if (season.BackdropImagePaths == null) season.BackdropImagePaths = new List<string>();
|
|
||||||
season.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(season, TVUtils.BannerUrl + n.InnerText, "backdrop" + Path.GetExtension(n.InnerText), ConfigurationManager.Configuration.SaveLocalMeta, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false));
|
season.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(season, TVUtils.BannerUrl + n.InnerText, "backdrop" + Path.GetExtension(n.InnerText), ConfigurationManager.Configuration.SaveLocalMeta, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -525,7 +525,7 @@ namespace MediaBrowser.Controller.Providers.TV
|
||||||
|
|
||||||
if (series.BackdropImagePaths.Count < ConfigurationManager.Configuration.MaxBackdrops)
|
if (series.BackdropImagePaths.Count < ConfigurationManager.Configuration.MaxBackdrops)
|
||||||
{
|
{
|
||||||
var bdNo = 0;
|
var bdNo = series.BackdropImagePaths.Count;
|
||||||
var xmlNodeList = images.SelectNodes("//Banner[BannerType='fanart']");
|
var xmlNodeList = images.SelectNodes("//Banner[BannerType='fanart']");
|
||||||
if (xmlNodeList != null)
|
if (xmlNodeList != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,18 +33,6 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether [enable delayed commands].
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if [enable delayed commands]; otherwise, <c>false</c>.</value>
|
|
||||||
protected override bool EnableDelayedCommands
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _json serializer
|
/// The _json serializer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -132,13 +120,13 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
using (var cmd = connection.CreateCommand())
|
using (var cmd = Connection.CreateCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = "replace into displaypreferences (id, data) values (@1, @2)";
|
cmd.CommandText = "replace into displaypreferences (id, data) values (@1, @2)";
|
||||||
cmd.AddParam("@1", displayPreferences.Id);
|
cmd.AddParam("@1", displayPreferences.Id);
|
||||||
cmd.AddParam("@2", serialized);
|
cmd.AddParam("@2", serialized);
|
||||||
|
|
||||||
using (var tran = connection.BeginTransaction())
|
using (var tran = Connection.BeginTransaction())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -174,7 +162,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
throw new ArgumentNullException("displayPreferencesId");
|
throw new ArgumentNullException("displayPreferencesId");
|
||||||
}
|
}
|
||||||
|
|
||||||
var cmd = connection.CreateCommand();
|
var cmd = Connection.CreateCommand();
|
||||||
cmd.CommandText = "select data from displaypreferences where id = @id";
|
cmd.CommandText = "select data from displaypreferences where id = @id";
|
||||||
|
|
||||||
var idParam = cmd.Parameters.Add("@id", DbType.Guid);
|
var idParam = cmd.Parameters.Add("@id", DbType.Guid);
|
||||||
|
|
|
@ -8,6 +8,7 @@ using MediaBrowser.Server.Implementations.Reflection;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.Data.SQLite;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -53,6 +54,19 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IApplicationPaths _appPaths;
|
private readonly IApplicationPaths _appPaths;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _save item command
|
||||||
|
/// </summary>
|
||||||
|
private SQLiteCommand _saveItemCommand;
|
||||||
|
/// <summary>
|
||||||
|
/// The _delete children command
|
||||||
|
/// </summary>
|
||||||
|
private SQLiteCommand _deleteChildrenCommand;
|
||||||
|
/// <summary>
|
||||||
|
/// The _save children command
|
||||||
|
/// </summary>
|
||||||
|
private SQLiteCommand _saveChildrenCommand;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SQLiteUserDataRepository" /> class.
|
/// Initializes a new instance of the <see cref="SQLiteUserDataRepository" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -100,6 +114,8 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
};
|
};
|
||||||
|
|
||||||
RunQueries(queries);
|
RunQueries(queries);
|
||||||
|
|
||||||
|
PrepareStatements();
|
||||||
}
|
}
|
||||||
|
|
||||||
//cascade delete triggers
|
//cascade delete triggers
|
||||||
|
@ -116,6 +132,39 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
DELETE FROM children WHERE children.child = old.child;
|
DELETE FROM children WHERE children.child = old.child;
|
||||||
END";
|
END";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _write lock
|
||||||
|
/// </summary>
|
||||||
|
private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1,1);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Prepares the statements.
|
||||||
|
/// </summary>
|
||||||
|
private void PrepareStatements()
|
||||||
|
{
|
||||||
|
_saveItemCommand = new SQLiteCommand
|
||||||
|
{
|
||||||
|
CommandText = "replace into items (guid, obj_type, data) values (@1, @2, @3)"
|
||||||
|
};
|
||||||
|
|
||||||
|
_saveItemCommand.Parameters.Add(new SQLiteParameter("@1"));
|
||||||
|
_saveItemCommand.Parameters.Add(new SQLiteParameter("@2"));
|
||||||
|
_saveItemCommand.Parameters.Add(new SQLiteParameter("@3"));
|
||||||
|
|
||||||
|
_deleteChildrenCommand = new SQLiteCommand
|
||||||
|
{
|
||||||
|
CommandText = "delete from children where guid = @guid"
|
||||||
|
};
|
||||||
|
_deleteChildrenCommand.Parameters.Add(new SQLiteParameter("@guid"));
|
||||||
|
|
||||||
|
_saveChildrenCommand = new SQLiteCommand
|
||||||
|
{
|
||||||
|
CommandText = "replace into children (guid, child) values (@guid, @child)"
|
||||||
|
};
|
||||||
|
_saveChildrenCommand.Parameters.Add(new SQLiteParameter("@guid"));
|
||||||
|
_saveChildrenCommand.Parameters.Add(new SQLiteParameter("@child"));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Save a standard item in the repo
|
/// Save a standard item in the repo
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -123,7 +172,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
/// <exception cref="System.ArgumentNullException">item</exception>
|
/// <exception cref="System.ArgumentNullException">item</exception>
|
||||||
public Task SaveItem(BaseItem item, CancellationToken cancellationToken)
|
public async Task SaveItem(BaseItem item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
|
@ -137,19 +186,51 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
return Task.Run(() =>
|
var serialized = _jsonSerializer.SerializeToBytes(item);
|
||||||
|
|
||||||
|
await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
SQLiteTransaction transaction = null;
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var serialized = _jsonSerializer.SerializeToBytes(item);
|
transaction = Connection.BeginTransaction();
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
_saveItemCommand.Parameters[0].Value = item.Id;
|
||||||
|
_saveItemCommand.Parameters[1].Value = item.GetType().FullName;
|
||||||
|
_saveItemCommand.Parameters[2].Value = serialized;
|
||||||
|
|
||||||
var cmd = connection.CreateCommand();
|
_saveItemCommand.Transaction = transaction;
|
||||||
cmd.CommandText = "replace into items (guid, obj_type, data) values (@1, @2, @3)";
|
|
||||||
cmd.AddParam("@1", item.Id);
|
await _saveItemCommand.ExecuteNonQueryAsync(cancellationToken);
|
||||||
cmd.AddParam("@2", item.GetType().FullName);
|
|
||||||
cmd.AddParam("@3", serialized);
|
transaction.Commit();
|
||||||
QueueCommand(cmd);
|
}
|
||||||
});
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.ErrorException("Failed to save item:", e);
|
||||||
|
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
transaction.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
_writeLock.Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -157,6 +238,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">The id.</param>
|
/// <param name="id">The id.</param>
|
||||||
/// <returns>BaseItem.</returns>
|
/// <returns>BaseItem.</returns>
|
||||||
|
/// <exception cref="System.ArgumentNullException">id</exception>
|
||||||
/// <exception cref="System.ArgumentException"></exception>
|
/// <exception cref="System.ArgumentException"></exception>
|
||||||
public BaseItem GetItem(Guid id)
|
public BaseItem GetItem(Guid id)
|
||||||
{
|
{
|
||||||
|
@ -189,6 +271,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">The id.</param>
|
/// <param name="id">The id.</param>
|
||||||
/// <returns>BaseItem.</returns>
|
/// <returns>BaseItem.</returns>
|
||||||
|
/// <exception cref="System.ArgumentNullException">id</exception>
|
||||||
/// <exception cref="System.ArgumentException"></exception>
|
/// <exception cref="System.ArgumentException"></exception>
|
||||||
protected BaseItem RetrieveItemInternal(Guid id)
|
protected BaseItem RetrieveItemInternal(Guid id)
|
||||||
{
|
{
|
||||||
|
@ -197,7 +280,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
throw new ArgumentNullException("id");
|
throw new ArgumentNullException("id");
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var cmd = connection.CreateCommand())
|
using (var cmd = Connection.CreateCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = "select obj_type,data from items where guid = @guid";
|
cmd.CommandText = "select obj_type,data from items where guid = @guid";
|
||||||
var guidParam = cmd.Parameters.Add("@guid", DbType.Guid);
|
var guidParam = cmd.Parameters.Add("@guid", DbType.Guid);
|
||||||
|
@ -240,7 +323,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
throw new ArgumentNullException();
|
throw new ArgumentNullException();
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var cmd = connection.CreateCommand())
|
using (var cmd = Connection.CreateCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = "select obj_type,data from items where guid in (select child from children where guid = @guid)";
|
cmd.CommandText = "select obj_type,data from items where guid in (select child from children where guid = @guid)";
|
||||||
var guidParam = cmd.Parameters.Add("@guid", DbType.Guid);
|
var guidParam = cmd.Parameters.Add("@guid", DbType.Guid);
|
||||||
|
@ -281,7 +364,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
/// <exception cref="System.ArgumentNullException">id</exception>
|
/// <exception cref="System.ArgumentNullException">id</exception>
|
||||||
public Task SaveChildren(Guid id, IEnumerable<BaseItem> children, CancellationToken cancellationToken)
|
public async Task SaveChildren(Guid id, IEnumerable<BaseItem> children, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (id == Guid.Empty)
|
if (id == Guid.Empty)
|
||||||
{
|
{
|
||||||
|
@ -300,27 +383,57 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
return Task.Run(() =>
|
await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
SQLiteTransaction transaction = null;
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var cmd = connection.CreateCommand();
|
transaction = Connection.BeginTransaction();
|
||||||
|
|
||||||
cmd.CommandText = "delete from children where guid = @guid";
|
// Delete exising children
|
||||||
cmd.AddParam("@guid", id);
|
_deleteChildrenCommand.Parameters[0].Value = id;
|
||||||
|
_deleteChildrenCommand.Transaction = transaction;
|
||||||
QueueCommand(cmd);
|
await _deleteChildrenCommand.ExecuteNonQueryAsync(cancellationToken);
|
||||||
|
|
||||||
|
// Save new children
|
||||||
foreach (var child in children)
|
foreach (var child in children)
|
||||||
{
|
{
|
||||||
var guid = child.Id;
|
_saveChildrenCommand.Transaction = transaction;
|
||||||
cmd = connection.CreateCommand();
|
|
||||||
cmd.AddParam("@guid", id);
|
_saveChildrenCommand.Parameters[0].Value = id;
|
||||||
cmd.CommandText = "replace into children (guid, child) values (@guid, @child)";
|
_saveChildrenCommand.Parameters[1].Value = child.Id;
|
||||||
var childParam = cmd.Parameters.Add("@child", DbType.Guid);
|
|
||||||
|
|
||||||
childParam.Value = guid;
|
await _saveChildrenCommand.ExecuteNonQueryAsync(cancellationToken);
|
||||||
QueueCommand(cmd);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.ErrorException("Failed to save item:", e);
|
||||||
|
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
transaction.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
_writeLock.Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -18,24 +18,11 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The db file name
|
/// The db file name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected string dbFileName;
|
protected string DbFileName;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The connection
|
/// The connection
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected SQLiteConnection connection;
|
protected SQLiteConnection Connection;
|
||||||
/// <summary>
|
|
||||||
/// The delayed commands
|
|
||||||
/// </summary>
|
|
||||||
protected ConcurrentQueue<SQLiteCommand> delayedCommands = new ConcurrentQueue<SQLiteCommand>();
|
|
||||||
/// <summary>
|
|
||||||
/// The flush interval
|
|
||||||
/// </summary>
|
|
||||||
private const int FlushInterval = 2000;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The flush timer
|
|
||||||
/// </summary>
|
|
||||||
private Timer FlushTimer;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the logger.
|
/// Gets the logger.
|
||||||
|
@ -43,18 +30,6 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// <value>The logger.</value>
|
/// <value>The logger.</value>
|
||||||
protected ILogger Logger { get; private set; }
|
protected ILogger Logger { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether [enable delayed commands].
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if [enable delayed commands]; otherwise, <c>false</c>.</value>
|
|
||||||
protected virtual bool EnableDelayedCommands
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SqliteRepository" /> class.
|
/// Initializes a new instance of the <see cref="SqliteRepository" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -83,7 +58,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
throw new ArgumentNullException("dbPath");
|
throw new ArgumentNullException("dbPath");
|
||||||
}
|
}
|
||||||
|
|
||||||
dbFileName = dbPath;
|
DbFileName = dbPath;
|
||||||
var connectionstr = new SQLiteConnectionStringBuilder
|
var connectionstr = new SQLiteConnectionStringBuilder
|
||||||
{
|
{
|
||||||
PageSize = 4096,
|
PageSize = 4096,
|
||||||
|
@ -93,15 +68,9 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
JournalMode = SQLiteJournalModeEnum.Memory
|
JournalMode = SQLiteJournalModeEnum.Memory
|
||||||
};
|
};
|
||||||
|
|
||||||
connection = new SQLiteConnection(connectionstr.ConnectionString);
|
Connection = new SQLiteConnection(connectionstr.ConnectionString);
|
||||||
|
|
||||||
await connection.OpenAsync().ConfigureAwait(false);
|
await Connection.OpenAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
if (EnableDelayedCommands)
|
|
||||||
{
|
|
||||||
// Run once
|
|
||||||
FlushTimer = new Timer(Flush, null, TimeSpan.FromMilliseconds(FlushInterval), TimeSpan.FromMilliseconds(-1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -117,11 +86,11 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
throw new ArgumentNullException("queries");
|
throw new ArgumentNullException("queries");
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var tran = connection.BeginTransaction())
|
using (var tran = Connection.BeginTransaction())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var cmd = connection.CreateCommand())
|
using (var cmd = Connection.CreateCommand())
|
||||||
{
|
{
|
||||||
foreach (var query in queries)
|
foreach (var query in queries)
|
||||||
{
|
{
|
||||||
|
@ -165,26 +134,15 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
{
|
{
|
||||||
lock (_disposeLock)
|
lock (_disposeLock)
|
||||||
{
|
{
|
||||||
if (connection != null)
|
if (Connection != null)
|
||||||
{
|
{
|
||||||
if (EnableDelayedCommands)
|
if (Connection.IsOpen())
|
||||||
{
|
{
|
||||||
FlushOnDispose();
|
Connection.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connection.IsOpen())
|
Connection.Dispose();
|
||||||
{
|
Connection = null;
|
||||||
connection.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
connection.Dispose();
|
|
||||||
connection = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FlushTimer != null)
|
|
||||||
{
|
|
||||||
FlushTimer.Dispose();
|
|
||||||
FlushTimer = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,101 +153,6 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Flushes the on dispose.
|
|
||||||
/// </summary>
|
|
||||||
private void FlushOnDispose()
|
|
||||||
{
|
|
||||||
// If we're not already flushing, do it now
|
|
||||||
if (!_isFlushing)
|
|
||||||
{
|
|
||||||
Flush(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't dispose in the middle of a flush
|
|
||||||
while (_isFlushing)
|
|
||||||
{
|
|
||||||
Thread.Sleep(25);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queues the command.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="cmd">The CMD.</param>
|
|
||||||
/// <exception cref="System.ArgumentNullException">cmd</exception>
|
|
||||||
protected void QueueCommand(SQLiteCommand cmd)
|
|
||||||
{
|
|
||||||
if (cmd == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("cmd");
|
|
||||||
}
|
|
||||||
|
|
||||||
delayedCommands.Enqueue(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The is flushing
|
|
||||||
/// </summary>
|
|
||||||
private bool _isFlushing;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Flushes the specified sender.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender">The sender.</param>
|
|
||||||
private void Flush(object sender)
|
|
||||||
{
|
|
||||||
// Cannot call Count on a ConcurrentQueue since it's an O(n) operation
|
|
||||||
// Use IsEmpty instead
|
|
||||||
if (delayedCommands.IsEmpty)
|
|
||||||
{
|
|
||||||
FlushTimer.Change(TimeSpan.FromMilliseconds(FlushInterval), TimeSpan.FromMilliseconds(-1));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_isFlushing)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_isFlushing = true;
|
|
||||||
var numCommands = 0;
|
|
||||||
|
|
||||||
using (var tran = connection.BeginTransaction())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
while (!delayedCommands.IsEmpty)
|
|
||||||
{
|
|
||||||
SQLiteCommand command;
|
|
||||||
|
|
||||||
delayedCommands.TryDequeue(out command);
|
|
||||||
|
|
||||||
command.Connection = connection;
|
|
||||||
command.Transaction = tran;
|
|
||||||
|
|
||||||
command.ExecuteNonQuery();
|
|
||||||
|
|
||||||
command.Dispose();
|
|
||||||
|
|
||||||
numCommands++;
|
|
||||||
}
|
|
||||||
|
|
||||||
tran.Commit();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Logger.ErrorException("Failed to commit transaction.", e);
|
|
||||||
tran.Rollback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.Debug("SQL Delayed writer executed " + numCommands + " commands");
|
|
||||||
|
|
||||||
FlushTimer.Change(TimeSpan.FromMilliseconds(FlushInterval), TimeSpan.FromMilliseconds(-1));
|
|
||||||
_isFlushing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Executes the command.
|
/// Executes the command.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -303,11 +166,11 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
throw new ArgumentNullException("cmd");
|
throw new ArgumentNullException("cmd");
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var tran = connection.BeginTransaction())
|
using (var tran = Connection.BeginTransaction())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
cmd.Connection = connection;
|
cmd.Connection = Connection;
|
||||||
cmd.Transaction = tran;
|
cmd.Transaction = tran;
|
||||||
|
|
||||||
await cmd.ExecuteNonQueryAsync().ConfigureAwait(false);
|
await cmd.ExecuteNonQueryAsync().ConfigureAwait(false);
|
||||||
|
|
|
@ -36,18 +36,6 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether [enable delayed commands].
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if [enable delayed commands]; otherwise, <c>false</c>.</value>
|
|
||||||
protected override bool EnableDelayedCommands
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly IJsonSerializer _jsonSerializer;
|
private readonly IJsonSerializer _jsonSerializer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -184,14 +172,14 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
using (var cmd = connection.CreateCommand())
|
using (var cmd = Connection.CreateCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = "replace into userdata (key, userId, data) values (@1, @2, @3)";
|
cmd.CommandText = "replace into userdata (key, userId, data) values (@1, @2, @3)";
|
||||||
cmd.AddParam("@1", key);
|
cmd.AddParam("@1", key);
|
||||||
cmd.AddParam("@2", userId);
|
cmd.AddParam("@2", userId);
|
||||||
cmd.AddParam("@3", serialized);
|
cmd.AddParam("@3", serialized);
|
||||||
|
|
||||||
using (var tran = connection.BeginTransaction())
|
using (var tran = Connection.BeginTransaction())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -247,7 +235,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// <returns>Task{UserItemData}.</returns>
|
/// <returns>Task{UserItemData}.</returns>
|
||||||
private async Task<UserItemData> RetrieveUserData(Guid userId, string key)
|
private async Task<UserItemData> RetrieveUserData(Guid userId, string key)
|
||||||
{
|
{
|
||||||
using (var cmd = connection.CreateCommand())
|
using (var cmd = Connection.CreateCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = "select data from userdata where key = @key and userId=@userId";
|
cmd.CommandText = "select data from userdata where key = @key and userId=@userId";
|
||||||
|
|
||||||
|
|
|
@ -45,18 +45,6 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IApplicationPaths _appPaths;
|
private readonly IApplicationPaths _appPaths;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether [enable delayed commands].
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if [enable delayed commands]; otherwise, <c>false</c>.</value>
|
|
||||||
protected override bool EnableDelayedCommands
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SQLiteUserDataRepository" /> class.
|
/// Initializes a new instance of the <see cref="SQLiteUserDataRepository" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -127,13 +115,13 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
using (var cmd = connection.CreateCommand())
|
using (var cmd = Connection.CreateCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = "replace into users (guid, data) values (@1, @2)";
|
cmd.CommandText = "replace into users (guid, data) values (@1, @2)";
|
||||||
cmd.AddParam("@1", user.Id);
|
cmd.AddParam("@1", user.Id);
|
||||||
cmd.AddParam("@2", serialized);
|
cmd.AddParam("@2", serialized);
|
||||||
|
|
||||||
using (var tran = connection.BeginTransaction())
|
using (var tran = Connection.BeginTransaction())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -162,7 +150,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// <returns>IEnumerable{User}.</returns>
|
/// <returns>IEnumerable{User}.</returns>
|
||||||
public IEnumerable<User> RetrieveAllUsers()
|
public IEnumerable<User> RetrieveAllUsers()
|
||||||
{
|
{
|
||||||
using (var cmd = connection.CreateCommand())
|
using (var cmd = Connection.CreateCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = "select data from users";
|
cmd.CommandText = "select data from users";
|
||||||
|
|
||||||
|
@ -201,7 +189,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
using (var cmd = connection.CreateCommand())
|
using (var cmd = Connection.CreateCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = "delete from users where guid=@guid";
|
cmd.CommandText = "delete from users where guid=@guid";
|
||||||
var guidParam = cmd.Parameters.Add("@guid", DbType.Guid);
|
var guidParam = cmd.Parameters.Add("@guid", DbType.Guid);
|
||||||
|
|
Loading…
Reference in a new issue