MigrateActivityLogDb.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #pragma warning disable CS1591
  2. using System;
  3. using System.IO;
  4. using Emby.Server.Implementations.Data;
  5. using Jellyfin.Data.Entities;
  6. using Jellyfin.Server.Implementations;
  7. using MediaBrowser.Controller;
  8. using Microsoft.EntityFrameworkCore;
  9. using Microsoft.Extensions.Logging;
  10. using SQLitePCL.pretty;
  11. namespace Jellyfin.Server.Migrations.Routines
  12. {
  13. public class MigrateActivityLogDb : IMigrationRoutine
  14. {
  15. private const string DbFilename = "activitylog.db";
  16. private readonly ILogger<MigrateActivityLogDb> _logger;
  17. private readonly JellyfinDbProvider _provider;
  18. private readonly IServerApplicationPaths _paths;
  19. public MigrateActivityLogDb(ILogger<MigrateActivityLogDb> logger, IServerApplicationPaths paths, JellyfinDbProvider provider)
  20. {
  21. _logger = logger;
  22. _provider = provider;
  23. _paths = paths;
  24. }
  25. public Guid Id => Guid.Parse("3793eb59-bc8c-456c-8b9f-bd5a62a42978");
  26. public string Name => "MigrateActivityLogDatabase";
  27. public void Perform()
  28. {
  29. var dataPath = _paths.DataPath;
  30. using (var connection = SQLite3.Open(
  31. Path.Combine(dataPath, DbFilename),
  32. ConnectionFlags.ReadOnly,
  33. null))
  34. {
  35. _logger.LogInformation("Migrating the database may take a while, do not stop Jellyfin.");
  36. using var dbContext = _provider.CreateContext();
  37. var queryResult = connection.Query("SELECT * FROM ActivityLog ORDER BY Id ASC");
  38. // Make sure that the database is empty in case of failed migration due to power outages, etc.
  39. dbContext.ActivityLogs.RemoveRange(dbContext.ActivityLogs);
  40. dbContext.SaveChanges();
  41. // Reset the autoincrement counter
  42. dbContext.Database.ExecuteSqlRaw("UPDATE sqlite_sequence SET seq = 0 WHERE name = 'ActivityLog';");
  43. dbContext.SaveChanges();
  44. foreach (var entry in queryResult)
  45. {
  46. var newEntry = new ActivityLog(
  47. entry[1].ToString(),
  48. entry[4].ToString(),
  49. entry[6].SQLiteType == SQLiteType.Null ? Guid.Empty : Guid.Parse(entry[6].ToString()),
  50. entry[7].ReadDateTime(),
  51. ParseLogLevel(entry[8].ToString()));
  52. if (entry[2].SQLiteType != SQLiteType.Null)
  53. {
  54. newEntry.Overview = entry[2].ToString();
  55. }
  56. if (entry[3].SQLiteType != SQLiteType.Null)
  57. {
  58. newEntry.ShortOverview = entry[3].ToString();
  59. }
  60. if (entry[5].SQLiteType != SQLiteType.Null)
  61. {
  62. newEntry.ItemId = entry[5].ToString();
  63. }
  64. dbContext.ActivityLogs.Add(newEntry);
  65. dbContext.SaveChanges();
  66. }
  67. }
  68. try
  69. {
  70. File.Move(Path.Combine(dataPath, DbFilename), Path.Combine(dataPath, DbFilename + ".old"));
  71. }
  72. catch (IOException e)
  73. {
  74. _logger.LogError(e, "Error renaming legacy activity log database to 'activitylog.db.old'");
  75. }
  76. }
  77. private LogLevel ParseLogLevel(string entry)
  78. {
  79. if (string.Equals(entry, "Debug", StringComparison.OrdinalIgnoreCase))
  80. {
  81. return LogLevel.Debug;
  82. }
  83. if (string.Equals(entry, "Information", StringComparison.OrdinalIgnoreCase)
  84. || string.Equals(entry, "Info", StringComparison.OrdinalIgnoreCase))
  85. {
  86. return LogLevel.Information;
  87. }
  88. if (string.Equals(entry, "Warning", StringComparison.OrdinalIgnoreCase)
  89. || string.Equals(entry, "Warn", StringComparison.OrdinalIgnoreCase))
  90. {
  91. return LogLevel.Warning;
  92. }
  93. if (string.Equals(entry, "Error", StringComparison.OrdinalIgnoreCase))
  94. {
  95. return LogLevel.Error;
  96. }
  97. return LogLevel.Trace;
  98. }
  99. }
  100. }