UserDataMigration.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. using MediaBrowser.Controller.Entities;
  2. using MediaBrowser.Model.Logging;
  3. using MediaBrowser.Model.Serialization;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Data;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Threading.Tasks;
  10. namespace MediaBrowser.Server.Implementations.Persistence
  11. {
  12. public static class UserDataMigration
  13. {
  14. /// <summary>
  15. /// Migrates the specified old file.
  16. /// </summary>
  17. /// <param name="oldFile">The old file.</param>
  18. /// <param name="newDatabase">The new database.</param>
  19. /// <param name="logger">The logger.</param>
  20. /// <param name="json">The json.</param>
  21. /// <returns>Task.</returns>
  22. public static async Task Migrate(string oldFile, IDbConnection newDatabase, ILogger logger, IJsonSerializer json)
  23. {
  24. var oldDb = await SqliteExtensions.ConnectToDb(oldFile).ConfigureAwait(false);
  25. using (oldDb)
  26. {
  27. IDbTransaction transaction = null;
  28. var data = GetAllUserData(oldDb, json).ToList();
  29. try
  30. {
  31. transaction = newDatabase.BeginTransaction();
  32. foreach (var userdata in data)
  33. {
  34. PersistUserData(userdata, newDatabase, transaction);
  35. }
  36. transaction.Commit();
  37. }
  38. catch (OperationCanceledException)
  39. {
  40. if (transaction != null)
  41. {
  42. transaction.Rollback();
  43. }
  44. throw;
  45. }
  46. catch (Exception e)
  47. {
  48. logger.ErrorException("Failed to save user data:", e);
  49. if (transaction != null)
  50. {
  51. transaction.Rollback();
  52. }
  53. throw;
  54. }
  55. finally
  56. {
  57. if (transaction != null)
  58. {
  59. transaction.Dispose();
  60. }
  61. }
  62. }
  63. File.Move(oldFile, Path.Combine(Path.GetDirectoryName(oldFile), "userdata_v1.db"));
  64. }
  65. /// <summary>
  66. /// Gets all user data.
  67. /// </summary>
  68. /// <param name="oldDatabase">The old database.</param>
  69. /// <param name="jsonSerializer">The json serializer.</param>
  70. /// <returns>IEnumerable{UserItemData}.</returns>
  71. private static IEnumerable<UserItemData> GetAllUserData(IDbConnection oldDatabase, IJsonSerializer jsonSerializer)
  72. {
  73. using (var cmd = oldDatabase.CreateCommand())
  74. {
  75. cmd.CommandText = "select userId,key,data from userdata";
  76. using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
  77. {
  78. while (reader.Read())
  79. {
  80. var userId = reader.GetGuid(0);
  81. var key = reader.GetString(1);
  82. using (var stream = reader.GetMemoryStream(2))
  83. {
  84. var userData = jsonSerializer.DeserializeFromStream<UserItemData>(stream);
  85. userData.UserId = userId;
  86. userData.Key = key;
  87. yield return userData;
  88. }
  89. }
  90. }
  91. }
  92. }
  93. /// <summary>
  94. /// Persists the user data.
  95. /// </summary>
  96. /// <param name="userData">The user data.</param>
  97. /// <param name="database">The database.</param>
  98. /// <param name="transaction">The transaction.</param>
  99. private static void PersistUserData(UserItemData userData, IDbConnection database, IDbTransaction transaction)
  100. {
  101. using (var cmd = database.CreateCommand())
  102. {
  103. cmd.CommandText = "replace into userdata (key, userId, rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate) values (@key, @userId, @rating,@played,@playCount,@isFavorite,@playbackPositionTicks,@lastPlayedDate)";
  104. cmd.Parameters.Add(cmd, "@key", DbType.String).Value = userData.Key;
  105. cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userData.UserId;
  106. cmd.Parameters.Add(cmd, "@rating", DbType.Double).Value = userData.Rating;
  107. cmd.Parameters.Add(cmd, "@played", DbType.Boolean).Value = userData.Played;
  108. cmd.Parameters.Add(cmd, "@playCount", DbType.Int32).Value = userData.PlayCount;
  109. cmd.Parameters.Add(cmd, "@isFavorite", DbType.Boolean).Value = userData.IsFavorite;
  110. cmd.Parameters.Add(cmd, "@playbackPositionTicks", DbType.Int64).Value = userData.PlaybackPositionTicks;
  111. cmd.Parameters.Add(cmd, "@lastPlayedDate", DbType.DateTime).Value = userData.LastPlayedDate;
  112. cmd.Transaction = transaction;
  113. cmd.ExecuteNonQuery();
  114. }
  115. }
  116. }
  117. }