MigrateUserData.cs 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using System;
  2. using System.Collections.Immutable;
  3. using System.IO;
  4. using System.Linq;
  5. using Emby.Server.Implementations.Data;
  6. using Jellyfin.Data.Entities;
  7. using Jellyfin.Server.Implementations;
  8. using MediaBrowser.Controller;
  9. using Microsoft.Data.Sqlite;
  10. using Microsoft.EntityFrameworkCore;
  11. using Microsoft.Extensions.Logging;
  12. namespace Jellyfin.Server.Migrations.Routines;
  13. /// <summary>
  14. /// The migration routine for migrating the userdata database to EF Core.
  15. /// </summary>
  16. public class MigrateUserData : IMigrationRoutine
  17. {
  18. private const string DbFilename = "library.db";
  19. private readonly ILogger<MigrateUserDb> _logger;
  20. private readonly IServerApplicationPaths _paths;
  21. private readonly IDbContextFactory<JellyfinDbContext> _provider;
  22. /// <summary>
  23. /// Initializes a new instance of the <see cref="MigrateUserData"/> class.
  24. /// </summary>
  25. /// <param name="logger">The logger.</param>
  26. /// <param name="provider">The database provider.</param>
  27. /// <param name="paths">The server application paths.</param>
  28. public MigrateUserData(
  29. ILogger<MigrateUserDb> logger,
  30. IDbContextFactory<JellyfinDbContext> provider,
  31. IServerApplicationPaths paths)
  32. {
  33. _logger = logger;
  34. _provider = provider;
  35. _paths = paths;
  36. }
  37. /// <inheritdoc/>
  38. public Guid Id => Guid.Parse("5bcb4197-e7c0-45aa-9902-963bceab5798");
  39. /// <inheritdoc/>
  40. public string Name => "MigrateUserData";
  41. /// <inheritdoc/>
  42. public bool PerformOnNewInstall => false;
  43. /// <inheritdoc/>
  44. public void Perform()
  45. {
  46. _logger.LogInformation("Migrating the userdata from library.db may take a while, do not stop Jellyfin.");
  47. var dataPath = _paths.DataPath;
  48. using var connection = new SqliteConnection($"Filename={Path.Combine(dataPath, DbFilename)}");
  49. connection.Open();
  50. using var dbContext = _provider.CreateDbContext();
  51. var queryResult = connection.Query("SELECT key, userId, rating, played, playCount, isFavorite, playbackPositionTicks, lastPlayedDate, AudioStreamIndex, SubtitleStreamIndex FROM UserDatas");
  52. dbContext.UserData.ExecuteDelete();
  53. var users = dbContext.Users.AsNoTracking().ToImmutableArray();
  54. foreach (SqliteDataReader dto in queryResult)
  55. {
  56. var entity = new UserData()
  57. {
  58. Key = dto.GetString(0),
  59. UserId = users.ElementAt(dto.GetInt32(1)).Id,
  60. Rating = dto.IsDBNull(2) ? null : dto.GetDouble(2),
  61. Played = dto.GetBoolean(3),
  62. PlayCount = dto.GetInt32(4),
  63. IsFavorite = dto.GetBoolean(5),
  64. PlaybackPositionTicks = dto.GetInt64(6),
  65. LastPlayedDate = dto.IsDBNull(7) ? null : dto.GetDateTime(7),
  66. AudioStreamIndex = dto.IsDBNull(8) ? null : dto.GetInt32(8),
  67. SubtitleStreamIndex = dto.IsDBNull(9) ? null : dto.GetInt32(9),
  68. };
  69. dbContext.UserData.Add(entity);
  70. }
  71. dbContext.SaveChanges();
  72. }
  73. }