diff options
Diffstat (limited to 'Emby.Server.Implementations/Data/SqliteUserRepository.cs')
| -rw-r--r-- | Emby.Server.Implementations/Data/SqliteUserRepository.cs | 141 |
1 files changed, 106 insertions, 35 deletions
diff --git a/Emby.Server.Implementations/Data/SqliteUserRepository.cs b/Emby.Server.Implementations/Data/SqliteUserRepository.cs index e89de11c6..da828aa11 100644 --- a/Emby.Server.Implementations/Data/SqliteUserRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserRepository.cs @@ -18,13 +18,11 @@ namespace Emby.Server.Implementations.Data public class SqliteUserRepository : BaseSqliteRepository, IUserRepository { private readonly IJsonSerializer _jsonSerializer; - private readonly IMemoryStreamFactory _memoryStreamProvider; - public SqliteUserRepository(ILogger logger, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer, IMemoryStreamFactory memoryStreamProvider) + public SqliteUserRepository(ILogger logger, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer) : base(logger) { _jsonSerializer = jsonSerializer; - _memoryStreamProvider = memoryStreamProvider; DbFilePath = Path.Combine(appPaths.DataPath, "users.db"); } @@ -51,37 +49,83 @@ namespace Emby.Server.Implementations.Data { RunDefaultInitialization(connection); - string[] queries = { + var localUsersTableExists = TableExists(connection, "LocalUsersv2"); - "create table if not exists users (guid GUID primary key NOT NULL, data BLOB NOT NULL)", - "create index if not exists idx_users on users(guid)", + connection.RunQueries(new[] { + "create table if not exists LocalUsersv2 (Id INTEGER PRIMARY KEY, guid GUID NOT NULL, data BLOB NOT NULL)", + "drop index if exists idx_users" + }); - "pragma shrink_memory" - }; + if (!localUsersTableExists && TableExists(connection, "Users")) + { + TryMigrateToLocalUsersTable(connection); + } + } + } - connection.RunQueries(queries); + private void TryMigrateToLocalUsersTable(ManagedConnection connection) + { + try + { + connection.RunQueries(new[] + { + "INSERT INTO LocalUsersv2 (guid, data) SELECT guid,data from users" + }); + } + catch (Exception ex) + { + Logger.ErrorException("Error migrating users database", ex); } } /// <summary> /// Save a user in the repo /// </summary> - /// <param name="user">The user.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - /// <exception cref="System.ArgumentNullException">user</exception> - public void SaveUser(User user, CancellationToken cancellationToken) + public void CreateUser(User user) { if (user == null) { throw new ArgumentNullException("user"); } - cancellationToken.ThrowIfCancellationRequested(); + var serialized = _jsonSerializer.SerializeToBytes(user); + + using (WriteLock.Write()) + { + using (var connection = CreateConnection()) + { + connection.RunInTransaction(db => + { + using (var statement = db.PrepareStatement("insert into LocalUsersv2 (guid, data) values (@guid, @data)")) + { + statement.TryBind("@guid", user.Id.ToGuidBlob()); + statement.TryBind("@data", serialized); + + statement.MoveNext(); + } - var serialized = _jsonSerializer.SerializeToBytes(user, _memoryStreamProvider); + var createdUser = GetUser(user.Id, false); - cancellationToken.ThrowIfCancellationRequested(); + if (createdUser == null) + { + throw new ApplicationException("created user should never be null"); + } + + user.InternalId = createdUser.InternalId; + + }, TransactionMode); + } + } + } + + public void UpdateUser(User user) + { + if (user == null) + { + throw new ArgumentNullException("user"); + } + + var serialized = _jsonSerializer.SerializeToBytes(user); using (WriteLock.Write()) { @@ -89,22 +133,59 @@ namespace Emby.Server.Implementations.Data { connection.RunInTransaction(db => { - using (var statement = db.PrepareStatement("replace into users (guid, data) values (@guid, @data)")) + using (var statement = db.PrepareStatement("update LocalUsersv2 set data=@data where Id=@InternalId")) { - statement.TryBind("@guid", user.Id.ToGuidBlob()); + statement.TryBind("@InternalId", user.InternalId); statement.TryBind("@data", serialized); statement.MoveNext(); } + }, TransactionMode); } } } + private User GetUser(Guid guid, bool openLock) + { + using (openLock ? WriteLock.Read() : null) + { + using (var connection = CreateConnection(true)) + { + using (var statement = connection.PrepareStatement("select id,guid,data from LocalUsersv2 where guid=@guid")) + { + statement.TryBind("@guid", guid); + + foreach (var row in statement.ExecuteQuery()) + { + return GetUser(row); + } + } + } + } + + return null; + } + + private User GetUser(IReadOnlyList<IResultSetValue> row) + { + var id = row[0].ToInt64(); + var guid = row[1].ReadGuidFromBlob(); + + using (var stream = new MemoryStream(row[2].ToBlob())) + { + stream.Position = 0; + var user = _jsonSerializer.DeserializeFromStream<User>(stream); + user.InternalId = id; + user.Id = guid; + return user; + } + } + /// <summary> /// Retrieve all users from the database /// </summary> /// <returns>IEnumerable{User}.</returns> - public IEnumerable<User> RetrieveAllUsers() + public List<User> RetrieveAllUsers() { var list = new List<User>(); @@ -112,17 +193,9 @@ namespace Emby.Server.Implementations.Data { using (var connection = CreateConnection(true)) { - foreach (var row in connection.Query("select guid,data from users")) + foreach (var row in connection.Query("select id,guid,data from LocalUsersv2")) { - var id = row[0].ReadGuidFromBlob(); - - using (var stream = _memoryStreamProvider.CreateNew(row[1].ToBlob())) - { - stream.Position = 0; - var user = _jsonSerializer.DeserializeFromStream<User>(stream); - user.Id = id; - list.Add(user); - } + list.Add(GetUser(row)); } } } @@ -137,24 +210,22 @@ namespace Emby.Server.Implementations.Data /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> /// <exception cref="System.ArgumentNullException">user</exception> - public void DeleteUser(User user, CancellationToken cancellationToken) + public void DeleteUser(User user) { if (user == null) { throw new ArgumentNullException("user"); } - cancellationToken.ThrowIfCancellationRequested(); - using (WriteLock.Write()) { using (var connection = CreateConnection()) { connection.RunInTransaction(db => { - using (var statement = db.PrepareStatement("delete from users where guid=@id")) + using (var statement = db.PrepareStatement("delete from LocalUsersv2 where Id=@id")) { - statement.TryBind("@id", user.Id.ToGuidBlob()); + statement.TryBind("@id", user.InternalId); statement.MoveNext(); } }, TransactionMode); |
