aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Data/SqliteUserRepository.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/Data/SqliteUserRepository.cs')
-rw-r--r--Emby.Server.Implementations/Data/SqliteUserRepository.cs141
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);