Simplify db code

This commit is contained in:
Bond-009 2019-02-20 14:26:49 +01:00 committed by Bond_009
parent b3b08fecb2
commit cec22ad10d
9 changed files with 621 additions and 959 deletions

View file

@ -57,7 +57,7 @@ namespace Emby.Server.Implementations.Activity
} }
} }
private void TryMigrate(ManagedConnection connection) private void TryMigrate(SQLiteDatabaseConnection connection)
{ {
try try
{ {
@ -85,7 +85,6 @@ namespace Emby.Server.Implementations.Activity
throw new ArgumentNullException(nameof(entry)); throw new ArgumentNullException(nameof(entry));
} }
using (WriteLock.Write())
using (var connection = CreateConnection()) using (var connection = CreateConnection())
{ {
connection.RunInTransaction(db => connection.RunInTransaction(db =>
@ -124,7 +123,6 @@ namespace Emby.Server.Implementations.Activity
throw new ArgumentNullException(nameof(entry)); throw new ArgumentNullException(nameof(entry));
} }
using (WriteLock.Write())
using (var connection = CreateConnection()) using (var connection = CreateConnection())
{ {
connection.RunInTransaction(db => connection.RunInTransaction(db =>
@ -159,7 +157,6 @@ namespace Emby.Server.Implementations.Activity
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit) public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
{ {
using (WriteLock.Read())
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
var commandText = BaseActivitySelectText; var commandText = BaseActivitySelectText;

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using SQLitePCL; using SQLitePCL;
using SQLitePCL.pretty; using SQLitePCL.pretty;
@ -12,15 +13,12 @@ namespace Emby.Server.Implementations.Data
public abstract class BaseSqliteRepository : IDisposable public abstract class BaseSqliteRepository : IDisposable
{ {
protected string DbFilePath { get; set; } protected string DbFilePath { get; set; }
protected ReaderWriterLockSlim WriteLock;
protected ILogger Logger { get; private set; } protected ILogger Logger { get; private set; }
protected BaseSqliteRepository(ILogger logger) protected BaseSqliteRepository(ILogger logger)
{ {
Logger = logger; Logger = logger;
WriteLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
} }
protected TransactionMode TransactionMode => TransactionMode.Deferred; protected TransactionMode TransactionMode => TransactionMode.Deferred;
@ -31,130 +29,96 @@ namespace Emby.Server.Implementations.Data
static BaseSqliteRepository() static BaseSqliteRepository()
{ {
SQLite3.EnableSharedCache = false;
int rc = raw.sqlite3_config(raw.SQLITE_CONFIG_MEMSTATUS, 0);
//CheckOk(rc);
rc = raw.sqlite3_config(raw.SQLITE_CONFIG_MULTITHREAD, 1);
//rc = raw.sqlite3_config(raw.SQLITE_CONFIG_SINGLETHREAD, 1);
//rc = raw.sqlite3_config(raw.SQLITE_CONFIG_SERIALIZED, 1);
//CheckOk(rc);
rc = raw.sqlite3_enable_shared_cache(1);
ThreadSafeMode = raw.sqlite3_threadsafe(); ThreadSafeMode = raw.sqlite3_threadsafe();
} }
private static bool _versionLogged; private static bool _versionLogged;
private string _defaultWal; private string _defaultWal;
protected ManagedConnection _connection;
protected virtual bool EnableSingleConnection => true; protected SQLiteDatabaseConnection CreateConnection(bool isReadOnly = false)
protected ManagedConnection CreateConnection(bool isReadOnly = false)
{ {
if (_connection != null) if (!_versionLogged)
{ {
return _connection; _versionLogged = true;
Logger.LogInformation("Sqlite version: " + SQLite3.Version);
Logger.LogInformation("Sqlite compiler options: " + string.Join(",", SQLite3.CompilerOptions));
} }
lock (WriteLock) ConnectionFlags connectionFlags;
if (isReadOnly)
{ {
if (!_versionLogged) //Logger.LogInformation("Opening read connection");
//connectionFlags = ConnectionFlags.Create;
connectionFlags = ConnectionFlags.ReadOnly;
}
else
{
//Logger.LogInformation("Opening write connection");
connectionFlags = ConnectionFlags.Create;
connectionFlags |= ConnectionFlags.ReadWrite;
}
connectionFlags |= ConnectionFlags.SharedCached;
connectionFlags |= ConnectionFlags.FullMutex;
var db = SQLite3.Open(DbFilePath, connectionFlags, null);
try
{
if (string.IsNullOrWhiteSpace(_defaultWal))
{ {
_versionLogged = true; _defaultWal = db.Query("PRAGMA journal_mode").SelectScalarString().First();
Logger.LogInformation("Sqlite version: " + SQLite3.Version);
Logger.LogInformation("Sqlite compiler options: " + string.Join(",", SQLite3.CompilerOptions.ToArray())); Logger.LogInformation("Default journal_mode for {0} is {1}", DbFilePath, _defaultWal);
} }
ConnectionFlags connectionFlags; var queries = new List<string>
if (isReadOnly)
{ {
//Logger.LogInformation("Opening read connection"); //"PRAGMA cache size=-10000"
//connectionFlags = ConnectionFlags.ReadOnly; //"PRAGMA read_uncommitted = true",
connectionFlags = ConnectionFlags.Create; //"PRAGMA synchronous=Normal"
connectionFlags |= ConnectionFlags.ReadWrite; };
if (CacheSize.HasValue)
{
queries.Add("PRAGMA cache_size=" + CacheSize.Value.ToString(CultureInfo.InvariantCulture));
}
if (EnableTempStoreMemory)
{
queries.Add("PRAGMA temp_store = memory");
} }
else else
{ {
//Logger.LogInformation("Opening write connection"); queries.Add("PRAGMA temp_store = file");
connectionFlags = ConnectionFlags.Create;
connectionFlags |= ConnectionFlags.ReadWrite;
} }
if (EnableSingleConnection) foreach (var query in queries)
{ {
connectionFlags |= ConnectionFlags.PrivateCache; db.Execute(query);
} }
else
{
connectionFlags |= ConnectionFlags.SharedCached;
}
connectionFlags |= ConnectionFlags.NoMutex;
var db = SQLite3.Open(DbFilePath, connectionFlags, null);
try
{
if (string.IsNullOrWhiteSpace(_defaultWal))
{
_defaultWal = db.Query("PRAGMA journal_mode").SelectScalarString().First();
Logger.LogInformation("Default journal_mode for {0} is {1}", DbFilePath, _defaultWal);
}
var queries = new List<string>
{
//"PRAGMA cache size=-10000"
//"PRAGMA read_uncommitted = true",
"PRAGMA synchronous=Normal"
};
if (CacheSize.HasValue)
{
queries.Add("PRAGMA cache_size=" + CacheSize.Value.ToString(CultureInfo.InvariantCulture));
}
if (EnableTempStoreMemory)
{
queries.Add("PRAGMA temp_store = memory");
}
else
{
queries.Add("PRAGMA temp_store = file");
}
foreach (var query in queries)
{
db.Execute(query);
}
}
catch
{
using (db)
{
}
throw;
}
_connection = new ManagedConnection(db, false);
return _connection;
} }
catch
{
using (db)
{
}
throw;
}
return db;
} }
public IStatement PrepareStatement(ManagedConnection connection, string sql) public IStatement PrepareStatement(SQLiteDatabaseConnection connection, string sql)
{ {
return connection.PrepareStatement(sql); return connection.PrepareStatement(sql);
} }
public IStatement PrepareStatementSafe(ManagedConnection connection, string sql) public IStatement PrepareStatementSafe(SQLiteDatabaseConnection connection, string sql)
{ {
return connection.PrepareStatement(sql); return connection.PrepareStatement(sql);
} }
@ -179,7 +143,7 @@ namespace Emby.Server.Implementations.Data
return sql.Select(connection.PrepareStatement).ToList(); return sql.Select(connection.PrepareStatement).ToList();
} }
protected bool TableExists(ManagedConnection connection, string name) protected bool TableExists(SQLiteDatabaseConnection connection, string name)
{ {
return connection.RunInTransaction(db => return connection.RunInTransaction(db =>
{ {
@ -199,7 +163,7 @@ namespace Emby.Server.Implementations.Data
}, ReadTransactionMode); }, ReadTransactionMode);
} }
protected void RunDefaultInitialization(ManagedConnection db) protected void RunDefaultInitialization(SQLiteDatabaseConnection db)
{ {
var queries = new List<string> var queries = new List<string>
{ {
@ -243,7 +207,7 @@ namespace Emby.Server.Implementations.Data
public void Dispose() public void Dispose()
{ {
_disposed = true;
Dispose(true); Dispose(true);
} }
@ -255,42 +219,13 @@ namespace Emby.Server.Implementations.Data
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool dispose) protected virtual void Dispose(bool dispose)
{ {
if (dispose) if (_disposed)
{ {
DisposeConnection(); return;
} }
}
private void DisposeConnection()
{
try
{
lock (_disposeLock)
{
using (WriteLock.Write())
{
if (_connection != null)
{
using (_connection)
{
_connection.Close();
}
_connection = null;
}
CloseConnection();
}
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Error disposing database");
}
}
protected virtual void CloseConnection()
{
_disposed = true;
} }
protected List<string> GetColumnNames(IDatabaseConnection connection, string table) protected List<string> GetColumnNames(IDatabaseConnection connection, string table)
@ -320,60 +255,4 @@ namespace Emby.Server.Implementations.Data
connection.Execute("alter table " + table + " add column " + columnName + " " + type + " NULL"); connection.Execute("alter table " + table + " add column " + columnName + " " + type + " NULL");
} }
} }
public static class ReaderWriterLockSlimExtensions
{
private sealed class ReadLockToken : IDisposable
{
private ReaderWriterLockSlim _sync;
public ReadLockToken(ReaderWriterLockSlim sync)
{
_sync = sync;
sync.EnterReadLock();
}
public void Dispose()
{
if (_sync != null)
{
_sync.ExitReadLock();
_sync = null;
}
}
}
private sealed class WriteLockToken : IDisposable
{
private ReaderWriterLockSlim _sync;
public WriteLockToken(ReaderWriterLockSlim sync)
{
_sync = sync;
sync.EnterWriteLock();
}
public void Dispose()
{
if (_sync != null)
{
_sync.ExitWriteLock();
_sync = null;
}
}
}
public static IDisposable Read(this ReaderWriterLockSlim obj)
{
//if (BaseSqliteRepository.ThreadSafeMode > 0)
//{
// return new DummyToken();
//}
return new WriteLockToken(obj);
}
public static IDisposable Write(this ReaderWriterLockSlim obj)
{
//if (BaseSqliteRepository.ThreadSafeMode > 0)
//{
// return new DummyToken();
//}
return new WriteLockToken(obj);
}
}
} }

View file

@ -1,79 +0,0 @@
using System;
using System.Collections.Generic;
using SQLitePCL.pretty;
namespace Emby.Server.Implementations.Data
{
public class ManagedConnection : IDisposable
{
private SQLiteDatabaseConnection db;
private readonly bool _closeOnDispose;
public ManagedConnection(SQLiteDatabaseConnection db, bool closeOnDispose)
{
this.db = db;
_closeOnDispose = closeOnDispose;
}
public IStatement PrepareStatement(string sql)
{
return db.PrepareStatement(sql);
}
public IEnumerable<IStatement> PrepareAll(string sql)
{
return db.PrepareAll(sql);
}
public void ExecuteAll(string sql)
{
db.ExecuteAll(sql);
}
public void Execute(string sql, params object[] values)
{
db.Execute(sql, values);
}
public void RunQueries(string[] sql)
{
db.RunQueries(sql);
}
public void RunInTransaction(Action<IDatabaseConnection> action, TransactionMode mode)
{
db.RunInTransaction(action, mode);
}
public T RunInTransaction<T>(Func<IDatabaseConnection, T> action, TransactionMode mode)
{
return db.RunInTransaction(action, mode);
}
public IEnumerable<IReadOnlyList<IResultSetValue>> Query(string sql)
{
return db.Query(sql);
}
public IEnumerable<IReadOnlyList<IResultSetValue>> Query(string sql, params object[] values)
{
return db.Query(sql, values);
}
public void Close()
{
using (db)
{
}
}
public void Dispose()
{
if (_closeOnDispose)
{
Close();
}
}
}
}

View file

@ -98,15 +98,12 @@ namespace Emby.Server.Implementations.Data
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
using (WriteLock.Write()) using (var connection = CreateConnection())
{ {
using (var connection = CreateConnection()) connection.RunInTransaction(db =>
{ {
connection.RunInTransaction(db => SaveDisplayPreferences(displayPreferences, userId, client, db);
{ }, TransactionMode);
SaveDisplayPreferences(displayPreferences, userId, client, db);
}, TransactionMode);
}
} }
} }
@ -142,18 +139,15 @@ namespace Emby.Server.Implementations.Data
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
using (WriteLock.Write()) using (var connection = CreateConnection())
{ {
using (var connection = CreateConnection()) connection.RunInTransaction(db =>
{ {
connection.RunInTransaction(db => foreach (var displayPreference in displayPreferences)
{ {
foreach (var displayPreference in displayPreferences) SaveDisplayPreferences(displayPreference, userId, displayPreference.Client, db);
{ }
SaveDisplayPreferences(displayPreference, userId, displayPreference.Client, db); }, TransactionMode);
}
}, TransactionMode);
}
} }
} }
@ -174,27 +168,24 @@ namespace Emby.Server.Implementations.Data
var guidId = displayPreferencesId.GetMD5(); var guidId = displayPreferencesId.GetMD5();
using (WriteLock.Read()) using (var connection = CreateConnection(true))
{ {
using (var connection = CreateConnection(true)) using (var statement = connection.PrepareStatement("select data from userdisplaypreferences where id = @id and userId=@userId and client=@client"))
{ {
using (var statement = connection.PrepareStatement("select data from userdisplaypreferences where id = @id and userId=@userId and client=@client")) statement.TryBind("@id", guidId.ToGuidBlob());
{ statement.TryBind("@userId", userId.ToGuidBlob());
statement.TryBind("@id", guidId.ToGuidBlob()); statement.TryBind("@client", client);
statement.TryBind("@userId", userId.ToGuidBlob());
statement.TryBind("@client", client);
foreach (var row in statement.ExecuteQuery()) foreach (var row in statement.ExecuteQuery())
{ {
return Get(row); return Get(row);
}
} }
return new DisplayPreferences
{
Id = guidId.ToString("N")
};
} }
return new DisplayPreferences
{
Id = guidId.ToString("N")
};
} }
} }
@ -208,18 +199,15 @@ namespace Emby.Server.Implementations.Data
{ {
var list = new List<DisplayPreferences>(); var list = new List<DisplayPreferences>();
using (WriteLock.Read()) using (var connection = CreateConnection(true))
{ {
using (var connection = CreateConnection(true)) using (var statement = connection.PrepareStatement("select data from userdisplaypreferences where userId=@userId"))
{ {
using (var statement = connection.PrepareStatement("select data from userdisplaypreferences where userId=@userId")) statement.TryBind("@userId", userId.ToGuidBlob());
{
statement.TryBind("@userId", userId.ToGuidBlob());
foreach (var row in statement.ExecuteQuery()) foreach (var row in statement.ExecuteQuery())
{ {
list.Add(Get(row)); list.Add(Get(row));
}
} }
} }
} }

View file

@ -141,7 +141,7 @@ namespace Emby.Server.Implementations.Data
} }
} }
public static void Attach(ManagedConnection db, string path, string alias) public static void Attach(SQLiteDatabaseConnection db, string path, string alias)
{ {
var commandText = string.Format("attach @path as {0};", alias); var commandText = string.Format("attach @path as {0};", alias);

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,6 @@ using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.IO;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using SQLitePCL.pretty; using SQLitePCL.pretty;
@ -33,13 +32,8 @@ namespace Emby.Server.Implementations.Data
/// Opens the connection to the database /// Opens the connection to the database
/// </summary> /// </summary>
/// <returns>Task.</returns> /// <returns>Task.</returns>
public void Initialize(ReaderWriterLockSlim writeLock, ManagedConnection managedConnection, IUserManager userManager) public void Initialize(IUserManager userManager)
{ {
_connection = managedConnection;
WriteLock.Dispose();
WriteLock = writeLock;
using (var connection = CreateConnection()) using (var connection = CreateConnection())
{ {
var userDatasTableExists = TableExists(connection, "UserDatas"); var userDatasTableExists = TableExists(connection, "UserDatas");
@ -178,15 +172,12 @@ namespace Emby.Server.Implementations.Data
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
using (WriteLock.Write()) using (var connection = CreateConnection())
{ {
using (var connection = CreateConnection()) connection.RunInTransaction(db =>
{ {
connection.RunInTransaction(db => SaveUserData(db, internalUserId, key, userData);
{ }, TransactionMode);
SaveUserData(db, internalUserId, key, userData);
}, TransactionMode);
}
} }
} }
@ -249,18 +240,15 @@ namespace Emby.Server.Implementations.Data
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
using (WriteLock.Write()) using (var connection = CreateConnection())
{ {
using (var connection = CreateConnection()) connection.RunInTransaction(db =>
{ {
connection.RunInTransaction(db => foreach (var userItemData in userDataList)
{ {
foreach (var userItemData in userDataList) SaveUserData(db, internalUserId, userItemData.Key, userItemData);
{ }
SaveUserData(db, internalUserId, userItemData.Key, userItemData); }, TransactionMode);
}
}, TransactionMode);
}
} }
} }
@ -281,28 +269,26 @@ namespace Emby.Server.Implementations.Data
{ {
throw new ArgumentNullException(nameof(internalUserId)); throw new ArgumentNullException(nameof(internalUserId));
} }
if (string.IsNullOrEmpty(key)) if (string.IsNullOrEmpty(key))
{ {
throw new ArgumentNullException(nameof(key)); throw new ArgumentNullException(nameof(key));
} }
using (WriteLock.Read()) using (var connection = CreateConnection(true))
{ {
using (var connection = CreateConnection(true)) using (var statement = connection.PrepareStatement("select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex from UserDatas where key =@Key and userId=@UserId"))
{ {
using (var statement = connection.PrepareStatement("select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex from UserDatas where key =@Key and userId=@UserId")) statement.TryBind("@UserId", internalUserId);
statement.TryBind("@Key", key);
foreach (var row in statement.ExecuteQuery())
{ {
statement.TryBind("@UserId", internalUserId); return ReadRow(row);
statement.TryBind("@Key", key);
foreach (var row in statement.ExecuteQuery())
{
return ReadRow(row);
}
} }
return null;
} }
return null;
} }
} }
@ -335,18 +321,15 @@ namespace Emby.Server.Implementations.Data
var list = new List<UserItemData>(); var list = new List<UserItemData>();
using (WriteLock.Read()) using (var connection = CreateConnection())
{ {
using (var connection = CreateConnection()) using (var statement = connection.PrepareStatement("select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex from UserDatas where userId=@UserId"))
{ {
using (var statement = connection.PrepareStatement("select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex from UserDatas where userId=@UserId")) statement.TryBind("@UserId", internalUserId);
{
statement.TryBind("@UserId", internalUserId);
foreach (var row in statement.ExecuteQuery()) foreach (var row in statement.ExecuteQuery())
{ {
list.Add(ReadRow(row)); list.Add(ReadRow(row));
}
} }
} }
} }
@ -397,10 +380,5 @@ namespace Emby.Server.Implementations.Data
{ {
// handled by library database // handled by library database
} }
protected override void CloseConnection()
{
// handled by library database
}
} }
} }

View file

@ -60,7 +60,7 @@ namespace Emby.Server.Implementations.Data
} }
} }
private void TryMigrateToLocalUsersTable(ManagedConnection connection) private void TryMigrateToLocalUsersTable(SQLiteDatabaseConnection connection)
{ {
try try
{ {
@ -119,31 +119,28 @@ namespace Emby.Server.Implementations.Data
var serialized = _jsonSerializer.SerializeToBytes(user); var serialized = _jsonSerializer.SerializeToBytes(user);
using (WriteLock.Write()) using (var connection = CreateConnection())
{ {
using (var connection = CreateConnection()) connection.RunInTransaction(db =>
{ {
connection.RunInTransaction(db => using (var statement = db.PrepareStatement("insert into LocalUsersv2 (guid, data) values (@guid, @data)"))
{ {
using (var statement = db.PrepareStatement("insert into LocalUsersv2 (guid, data) values (@guid, @data)")) statement.TryBind("@guid", user.Id.ToGuidBlob());
{ statement.TryBind("@data", serialized);
statement.TryBind("@guid", user.Id.ToGuidBlob());
statement.TryBind("@data", serialized);
statement.MoveNext(); statement.MoveNext();
} }
var createdUser = GetUser(user.Id, false); var createdUser = GetUser(user.Id, connection);
if (createdUser == null) if (createdUser == null)
{ {
throw new ApplicationException("created user should never be null"); throw new ApplicationException("created user should never be null");
} }
user.InternalId = createdUser.InternalId; user.InternalId = createdUser.InternalId;
}, TransactionMode); }, TransactionMode);
}
} }
} }
@ -156,39 +153,30 @@ namespace Emby.Server.Implementations.Data
var serialized = _jsonSerializer.SerializeToBytes(user); var serialized = _jsonSerializer.SerializeToBytes(user);
using (WriteLock.Write()) using (var connection = CreateConnection())
{ {
using (var connection = CreateConnection()) connection.RunInTransaction(db =>
{ {
connection.RunInTransaction(db => using (var statement = db.PrepareStatement("update LocalUsersv2 set data=@data where Id=@InternalId"))
{ {
using (var statement = db.PrepareStatement("update LocalUsersv2 set data=@data where Id=@InternalId")) statement.TryBind("@InternalId", user.InternalId);
{ statement.TryBind("@data", serialized);
statement.TryBind("@InternalId", user.InternalId); statement.MoveNext();
statement.TryBind("@data", serialized); }
statement.MoveNext();
}
}, TransactionMode); }, TransactionMode);
}
} }
} }
private User GetUser(Guid guid, bool openLock) private User GetUser(Guid guid, SQLiteDatabaseConnection connection)
{ {
using (openLock ? WriteLock.Read() : null) using (var statement = connection.PrepareStatement("select id,guid,data from LocalUsersv2 where guid=@guid"))
{ {
using (var connection = CreateConnection(true)) statement.TryBind("@guid", guid);
{
using (var statement = connection.PrepareStatement("select id,guid,data from LocalUsersv2 where guid=@guid"))
{
statement.TryBind("@guid", guid);
foreach (var row in statement.ExecuteQuery()) foreach (var row in statement.ExecuteQuery())
{ {
return GetUser(row); return GetUser(row);
}
}
} }
} }
@ -218,14 +206,11 @@ namespace Emby.Server.Implementations.Data
{ {
var list = new List<User>(); var list = new List<User>();
using (WriteLock.Read()) using (var connection = CreateConnection(true))
{ {
using (var connection = CreateConnection(true)) foreach (var row in connection.Query("select id,guid,data from LocalUsersv2"))
{ {
foreach (var row in connection.Query("select id,guid,data from LocalUsersv2")) list.Add(GetUser(row));
{
list.Add(GetUser(row));
}
} }
} }
@ -245,19 +230,16 @@ namespace Emby.Server.Implementations.Data
throw new ArgumentNullException(nameof(user)); throw new ArgumentNullException(nameof(user));
} }
using (WriteLock.Write()) using (var connection = CreateConnection())
{ {
using (var connection = CreateConnection()) connection.RunInTransaction(db =>
{ {
connection.RunInTransaction(db => using (var statement = db.PrepareStatement("delete from LocalUsersv2 where Id=@id"))
{ {
using (var statement = db.PrepareStatement("delete from LocalUsersv2 where Id=@id")) statement.TryBind("@id", user.InternalId);
{ statement.MoveNext();
statement.TryBind("@id", user.InternalId); }
statement.MoveNext(); }, TransactionMode);
}
}, TransactionMode);
}
} }
} }
} }

View file

@ -48,7 +48,7 @@ namespace Emby.Server.Implementations.Security
} }
} }
private void TryMigrate(ManagedConnection connection, bool tableNewlyCreated) private void TryMigrate(SQLiteDatabaseConnection connection, bool tableNewlyCreated)
{ {
try try
{ {
@ -87,31 +87,28 @@ namespace Emby.Server.Implementations.Security
throw new ArgumentNullException(nameof(info)); throw new ArgumentNullException(nameof(info));
} }
using (WriteLock.Write()) using (var connection = CreateConnection())
{ {
using (var connection = CreateConnection()) connection.RunInTransaction(db =>
{ {
connection.RunInTransaction(db => using (var statement = db.PrepareStatement("insert into Tokens (AccessToken, DeviceId, AppName, AppVersion, DeviceName, UserId, UserName, IsActive, DateCreated, DateLastActivity) values (@AccessToken, @DeviceId, @AppName, @AppVersion, @DeviceName, @UserId, @UserName, @IsActive, @DateCreated, @DateLastActivity)"))
{ {
using (var statement = db.PrepareStatement("insert into Tokens (AccessToken, DeviceId, AppName, AppVersion, DeviceName, UserId, UserName, IsActive, DateCreated, DateLastActivity) values (@AccessToken, @DeviceId, @AppName, @AppVersion, @DeviceName, @UserId, @UserName, @IsActive, @DateCreated, @DateLastActivity)")) statement.TryBind("@AccessToken", info.AccessToken);
{
statement.TryBind("@AccessToken", info.AccessToken);
statement.TryBind("@DeviceId", info.DeviceId); statement.TryBind("@DeviceId", info.DeviceId);
statement.TryBind("@AppName", info.AppName); statement.TryBind("@AppName", info.AppName);
statement.TryBind("@AppVersion", info.AppVersion); statement.TryBind("@AppVersion", info.AppVersion);
statement.TryBind("@DeviceName", info.DeviceName); statement.TryBind("@DeviceName", info.DeviceName);
statement.TryBind("@UserId", (info.UserId.Equals(Guid.Empty) ? null : info.UserId.ToString("N"))); statement.TryBind("@UserId", (info.UserId.Equals(Guid.Empty) ? null : info.UserId.ToString("N")));
statement.TryBind("@UserName", info.UserName); statement.TryBind("@UserName", info.UserName);
statement.TryBind("@IsActive", true); statement.TryBind("@IsActive", true);
statement.TryBind("@DateCreated", info.DateCreated.ToDateTimeParamValue()); statement.TryBind("@DateCreated", info.DateCreated.ToDateTimeParamValue());
statement.TryBind("@DateLastActivity", info.DateLastActivity.ToDateTimeParamValue()); statement.TryBind("@DateLastActivity", info.DateLastActivity.ToDateTimeParamValue());
statement.MoveNext(); statement.MoveNext();
} }
}, TransactionMode); }, TransactionMode);
}
} }
} }
@ -122,31 +119,28 @@ namespace Emby.Server.Implementations.Security
throw new ArgumentNullException(nameof(info)); throw new ArgumentNullException(nameof(info));
} }
using (WriteLock.Write()) using (var connection = CreateConnection())
{ {
using (var connection = CreateConnection()) connection.RunInTransaction(db =>
{ {
connection.RunInTransaction(db => using (var statement = db.PrepareStatement("Update Tokens set AccessToken=@AccessToken, DeviceId=@DeviceId, AppName=@AppName, AppVersion=@AppVersion, DeviceName=@DeviceName, UserId=@UserId, UserName=@UserName, DateCreated=@DateCreated, DateLastActivity=@DateLastActivity where Id=@Id"))
{ {
using (var statement = db.PrepareStatement("Update Tokens set AccessToken=@AccessToken, DeviceId=@DeviceId, AppName=@AppName, AppVersion=@AppVersion, DeviceName=@DeviceName, UserId=@UserId, UserName=@UserName, DateCreated=@DateCreated, DateLastActivity=@DateLastActivity where Id=@Id")) statement.TryBind("@Id", info.Id);
{
statement.TryBind("@Id", info.Id);
statement.TryBind("@AccessToken", info.AccessToken); statement.TryBind("@AccessToken", info.AccessToken);
statement.TryBind("@DeviceId", info.DeviceId); statement.TryBind("@DeviceId", info.DeviceId);
statement.TryBind("@AppName", info.AppName); statement.TryBind("@AppName", info.AppName);
statement.TryBind("@AppVersion", info.AppVersion); statement.TryBind("@AppVersion", info.AppVersion);
statement.TryBind("@DeviceName", info.DeviceName); statement.TryBind("@DeviceName", info.DeviceName);
statement.TryBind("@UserId", (info.UserId.Equals(Guid.Empty) ? null : info.UserId.ToString("N"))); statement.TryBind("@UserId", (info.UserId.Equals(Guid.Empty) ? null : info.UserId.ToString("N")));
statement.TryBind("@UserName", info.UserName); statement.TryBind("@UserName", info.UserName);
statement.TryBind("@DateCreated", info.DateCreated.ToDateTimeParamValue()); statement.TryBind("@DateCreated", info.DateCreated.ToDateTimeParamValue());
statement.TryBind("@DateLastActivity", info.DateLastActivity.ToDateTimeParamValue()); statement.TryBind("@DateLastActivity", info.DateLastActivity.ToDateTimeParamValue());
statement.MoveNext(); statement.MoveNext();
} }
}, TransactionMode); }, TransactionMode);
}
} }
} }
@ -157,20 +151,17 @@ namespace Emby.Server.Implementations.Security
throw new ArgumentNullException(nameof(info)); throw new ArgumentNullException(nameof(info));
} }
using (WriteLock.Write()) using (var connection = CreateConnection())
{ {
using (var connection = CreateConnection()) connection.RunInTransaction(db =>
{ {
connection.RunInTransaction(db => using (var statement = db.PrepareStatement("Delete from Tokens where Id=@Id"))
{ {
using (var statement = db.PrepareStatement("Delete from Tokens where Id=@Id")) statement.TryBind("@Id", info.Id);
{
statement.TryBind("@Id", info.Id);
statement.MoveNext(); statement.MoveNext();
} }
}, TransactionMode); }, TransactionMode);
}
} }
} }
@ -257,45 +248,42 @@ namespace Emby.Server.Implementations.Security
var list = new List<AuthenticationInfo>(); var list = new List<AuthenticationInfo>();
using (WriteLock.Read()) using (var connection = CreateConnection(true))
{ {
using (var connection = CreateConnection(true)) return connection.RunInTransaction(db =>
{ {
return connection.RunInTransaction(db => var result = new QueryResult<AuthenticationInfo>();
var statementTexts = new List<string>();
statementTexts.Add(commandText);
statementTexts.Add("select count (Id) from Tokens" + whereTextWithoutPaging);
var statements = PrepareAllSafe(db, statementTexts)
.ToList();
using (var statement = statements[0])
{ {
var result = new QueryResult<AuthenticationInfo>(); BindAuthenticationQueryParams(query, statement);
var statementTexts = new List<string>(); foreach (var row in statement.ExecuteQuery())
statementTexts.Add(commandText);
statementTexts.Add("select count (Id) from Tokens" + whereTextWithoutPaging);
var statements = PrepareAllSafe(db, statementTexts)
.ToList();
using (var statement = statements[0])
{ {
BindAuthenticationQueryParams(query, statement); list.Add(Get(row));
foreach (var row in statement.ExecuteQuery())
{
list.Add(Get(row));
}
using (var totalCountStatement = statements[1])
{
BindAuthenticationQueryParams(query, totalCountStatement);
result.TotalRecordCount = totalCountStatement.ExecuteQuery()
.SelectScalarInt()
.First();
}
} }
result.Items = list.ToArray(); using (var totalCountStatement = statements[1])
return result; {
BindAuthenticationQueryParams(query, totalCountStatement);
}, ReadTransactionMode); result.TotalRecordCount = totalCountStatement.ExecuteQuery()
} .SelectScalarInt()
.First();
}
}
result.Items = list.ToArray();
return result;
}, ReadTransactionMode);
} }
} }
@ -358,31 +346,28 @@ namespace Emby.Server.Implementations.Security
public DeviceOptions GetDeviceOptions(string deviceId) public DeviceOptions GetDeviceOptions(string deviceId)
{ {
using (WriteLock.Read()) using (var connection = CreateConnection(true))
{ {
using (var connection = CreateConnection(true)) return connection.RunInTransaction(db =>
{ {
return connection.RunInTransaction(db => using (var statement = PrepareStatementSafe(db, "select CustomName from Devices where Id=@DeviceId"))
{ {
using (var statement = PrepareStatementSafe(db, "select CustomName from Devices where Id=@DeviceId")) statement.TryBind("@DeviceId", deviceId);
var result = new DeviceOptions();
foreach (var row in statement.ExecuteQuery())
{ {
statement.TryBind("@DeviceId", deviceId); if (row[0].SQLiteType != SQLiteType.Null)
var result = new DeviceOptions();
foreach (var row in statement.ExecuteQuery())
{ {
if (row[0].SQLiteType != SQLiteType.Null) result.CustomName = row[0].ToString();
{
result.CustomName = row[0].ToString();
}
} }
return result;
} }
}, ReadTransactionMode); return result;
} }
}, ReadTransactionMode);
} }
} }
@ -393,30 +378,27 @@ namespace Emby.Server.Implementations.Security
throw new ArgumentNullException(nameof(options)); throw new ArgumentNullException(nameof(options));
} }
using (WriteLock.Write()) using (var connection = CreateConnection())
{ {
using (var connection = CreateConnection()) connection.RunInTransaction(db =>
{ {
connection.RunInTransaction(db => using (var statement = db.PrepareStatement("replace into devices (Id, CustomName, Capabilities) VALUES (@Id, @CustomName, (Select Capabilities from Devices where Id=@Id))"))
{ {
using (var statement = db.PrepareStatement("replace into devices (Id, CustomName, Capabilities) VALUES (@Id, @CustomName, (Select Capabilities from Devices where Id=@Id))")) statement.TryBind("@Id", deviceId);
if (string.IsNullOrWhiteSpace(options.CustomName))
{ {
statement.TryBind("@Id", deviceId); statement.TryBindNull("@CustomName");
}
if (string.IsNullOrWhiteSpace(options.CustomName)) else
{ {
statement.TryBindNull("@CustomName"); statement.TryBind("@CustomName", options.CustomName);
}
else
{
statement.TryBind("@CustomName", options.CustomName);
}
statement.MoveNext();
} }
}, TransactionMode); statement.MoveNext();
} }
}, TransactionMode);
} }
} }
} }