SqliteUserRepository.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6. using MediaBrowser.Controller;
  7. using MediaBrowser.Controller.Entities;
  8. using MediaBrowser.Controller.Persistence;
  9. using MediaBrowser.Model.IO;
  10. using MediaBrowser.Model.Logging;
  11. using MediaBrowser.Model.Serialization;
  12. using SQLitePCL.pretty;
  13. namespace Emby.Server.Implementations.Data
  14. {
  15. /// <summary>
  16. /// Class SQLiteUserRepository
  17. /// </summary>
  18. public class SqliteUserRepository : BaseSqliteRepository, IUserRepository
  19. {
  20. private readonly IJsonSerializer _jsonSerializer;
  21. private readonly IMemoryStreamFactory _memoryStreamProvider;
  22. public SqliteUserRepository(ILogger logger, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer, IMemoryStreamFactory memoryStreamProvider)
  23. : base(logger)
  24. {
  25. _jsonSerializer = jsonSerializer;
  26. _memoryStreamProvider = memoryStreamProvider;
  27. DbFilePath = Path.Combine(appPaths.DataPath, "users.db");
  28. }
  29. /// <summary>
  30. /// Gets the name of the repository
  31. /// </summary>
  32. /// <value>The name.</value>
  33. public string Name
  34. {
  35. get
  36. {
  37. return "SQLite";
  38. }
  39. }
  40. /// <summary>
  41. /// Opens the connection to the database
  42. /// </summary>
  43. /// <returns>Task.</returns>
  44. public void Initialize()
  45. {
  46. using (var connection = CreateConnection())
  47. {
  48. connection.ExecuteAll(string.Join(";", new[]
  49. {
  50. "PRAGMA page_size=4096",
  51. "pragma default_temp_store = memory",
  52. "pragma temp_store = memory"
  53. }));
  54. string[] queries = {
  55. "create table if not exists users (guid GUID primary key, data BLOB)",
  56. "create index if not exists idx_users on users(guid)",
  57. "create table if not exists schema_version (table_name primary key, version)",
  58. "pragma shrink_memory"
  59. };
  60. connection.RunQueries(queries);
  61. }
  62. }
  63. /// <summary>
  64. /// Save a user in the repo
  65. /// </summary>
  66. /// <param name="user">The user.</param>
  67. /// <param name="cancellationToken">The cancellation token.</param>
  68. /// <returns>Task.</returns>
  69. /// <exception cref="System.ArgumentNullException">user</exception>
  70. public async Task SaveUser(User user, CancellationToken cancellationToken)
  71. {
  72. if (user == null)
  73. {
  74. throw new ArgumentNullException("user");
  75. }
  76. cancellationToken.ThrowIfCancellationRequested();
  77. var serialized = _jsonSerializer.SerializeToBytes(user, _memoryStreamProvider);
  78. cancellationToken.ThrowIfCancellationRequested();
  79. using (var connection = CreateConnection())
  80. {
  81. using (WriteLock.Write())
  82. {
  83. connection.RunInTransaction(db =>
  84. {
  85. using (var statement = db.PrepareStatement("replace into users (guid, data) values (@guid, @data)"))
  86. {
  87. statement.TryBind("@guid", user.Id.ToGuidParamValue());
  88. statement.TryBind("@data", serialized);
  89. statement.MoveNext();
  90. }
  91. }, TransactionMode);
  92. }
  93. }
  94. }
  95. /// <summary>
  96. /// Retrieve all users from the database
  97. /// </summary>
  98. /// <returns>IEnumerable{User}.</returns>
  99. public IEnumerable<User> RetrieveAllUsers()
  100. {
  101. var list = new List<User>();
  102. using (var connection = CreateConnection(true))
  103. {
  104. using (WriteLock.Read())
  105. {
  106. foreach (var row in connection.Query("select guid,data from users"))
  107. {
  108. var id = row[0].ReadGuid();
  109. using (var stream = _memoryStreamProvider.CreateNew(row[1].ToBlob()))
  110. {
  111. stream.Position = 0;
  112. var user = _jsonSerializer.DeserializeFromStream<User>(stream);
  113. user.Id = id;
  114. list.Add(user);
  115. }
  116. }
  117. }
  118. }
  119. return list;
  120. }
  121. /// <summary>
  122. /// Deletes the user.
  123. /// </summary>
  124. /// <param name="user">The user.</param>
  125. /// <param name="cancellationToken">The cancellation token.</param>
  126. /// <returns>Task.</returns>
  127. /// <exception cref="System.ArgumentNullException">user</exception>
  128. public async Task DeleteUser(User user, CancellationToken cancellationToken)
  129. {
  130. if (user == null)
  131. {
  132. throw new ArgumentNullException("user");
  133. }
  134. cancellationToken.ThrowIfCancellationRequested();
  135. using (var connection = CreateConnection())
  136. {
  137. using (WriteLock.Write())
  138. {
  139. connection.RunInTransaction(db =>
  140. {
  141. using (var statement = db.PrepareStatement("delete from users where guid=@id"))
  142. {
  143. statement.TryBind("@id", user.Id.ToGuidParamValue());
  144. statement.MoveNext();
  145. }
  146. }, TransactionMode);
  147. }
  148. }
  149. }
  150. }
  151. }