aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Server
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Server')
-rw-r--r--Jellyfin.Server/Jellyfin.Server.csproj7
-rw-r--r--Jellyfin.Server/Migrations/MigrationRunner.cs3
-rw-r--r--Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs109
3 files changed, 118 insertions, 1 deletions
diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj
index 88114d999..4194070aa 100644
--- a/Jellyfin.Server/Jellyfin.Server.csproj
+++ b/Jellyfin.Server/Jellyfin.Server.csproj
@@ -13,6 +13,9 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>
+
+ <!-- Used for generating migrations for EF Core -->
+ <GenerateRuntimeConfigurationFiles>True</GenerateRuntimeConfigurationFiles>
</PropertyGroup>
<ItemGroup>
@@ -41,6 +44,10 @@
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.7.82" />
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.3">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+ </PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.3" />
<PackageReference Include="prometheus-net" Version="3.5.0" />
diff --git a/Jellyfin.Server/Migrations/MigrationRunner.cs b/Jellyfin.Server/Migrations/MigrationRunner.cs
index b5ea04dca..82e304586 100644
--- a/Jellyfin.Server/Migrations/MigrationRunner.cs
+++ b/Jellyfin.Server/Migrations/MigrationRunner.cs
@@ -16,7 +16,8 @@ namespace Jellyfin.Server.Migrations
internal static readonly IMigrationRoutine[] Migrations =
{
new Routines.DisableTranscodingThrottling(),
- new Routines.CreateUserLoggingConfigFile()
+ new Routines.CreateUserLoggingConfigFile(),
+ new Routines.MigrateActivityLogDb()
};
/// <summary>
diff --git a/Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs
new file mode 100644
index 000000000..9f1f5b92e
--- /dev/null
+++ b/Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs
@@ -0,0 +1,109 @@
+#pragma warning disable CS1591
+
+using System;
+using System.IO;
+using Emby.Server.Implementations.Data;
+using Jellyfin.Data.Entities;
+using Jellyfin.Server.Implementations;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using SQLitePCL.pretty;
+
+namespace Jellyfin.Server.Migrations.Routines
+{
+ public class MigrateActivityLogDb : IMigrationRoutine
+ {
+ private const string DbFilename = "activitylog.db";
+
+ public Guid Id => Guid.Parse("3793eb59-bc8c-456c-8b9f-bd5a62a42978");
+
+ public string Name => "MigrateActivityLogDatabase";
+
+ public void Perform(CoreAppHost host, ILogger logger)
+ {
+ var dataPath = host.ServerConfigurationManager.ApplicationPaths.DataPath;
+ using (var connection = SQLite3.Open(
+ Path.Combine(dataPath, DbFilename),
+ ConnectionFlags.ReadOnly,
+ null))
+ {
+ logger.LogInformation("Migrating the database may take a while, do not stop Jellyfin.");
+ using var dbContext = host.ServiceProvider.GetService<JellyfinDb>();
+
+ var queryResult = connection.Query("SELECT * FROM ActivityLog ORDER BY Id ASC");
+
+ // Make sure that the database is empty in case of failed migration due to power outages, etc.
+ dbContext.ActivityLogs.RemoveRange(dbContext.ActivityLogs);
+ dbContext.SaveChanges();
+ // Reset the autoincrement counter
+ dbContext.Database.ExecuteSqlRaw("UPDATE sqlite_sequence SET seq = 0 WHERE name = 'ActivityLog';");
+ dbContext.SaveChanges();
+
+ foreach (var entry in queryResult)
+ {
+ var newEntry = new ActivityLog(
+ entry[1].ToString(),
+ entry[4].ToString(),
+ entry[6].SQLiteType == SQLiteType.Null ? Guid.Empty : Guid.Parse(entry[6].ToString()),
+ entry[7].ReadDateTime(),
+ ParseLogLevel(entry[8].ToString()));
+
+ if (entry[2].SQLiteType != SQLiteType.Null)
+ {
+ newEntry.Overview = entry[2].ToString();
+ }
+
+ if (entry[3].SQLiteType != SQLiteType.Null)
+ {
+ newEntry.ShortOverview = entry[3].ToString();
+ }
+
+ if (entry[5].SQLiteType != SQLiteType.Null)
+ {
+ newEntry.ItemId = entry[5].ToString();
+ }
+
+ dbContext.ActivityLogs.Add(newEntry);
+ dbContext.SaveChanges();
+ }
+ }
+
+ try
+ {
+ File.Move(Path.Combine(dataPath, DbFilename), Path.Combine(dataPath, DbFilename + ".old"));
+ }
+ catch (IOException e)
+ {
+ logger.LogError(e, "Error renaming legacy activity log database to 'activitylog.db.old'");
+ }
+ }
+
+ private LogLevel ParseLogLevel(string entry)
+ {
+ if (string.Equals(entry, "Debug", StringComparison.OrdinalIgnoreCase))
+ {
+ return LogLevel.Debug;
+ }
+
+ if (string.Equals(entry, "Information", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(entry, "Info", StringComparison.OrdinalIgnoreCase))
+ {
+ return LogLevel.Information;
+ }
+
+ if (string.Equals(entry, "Warning", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(entry, "Warn", StringComparison.OrdinalIgnoreCase))
+ {
+ return LogLevel.Warning;
+ }
+
+ if (string.Equals(entry, "Error", StringComparison.OrdinalIgnoreCase))
+ {
+ return LogLevel.Error;
+ }
+
+ return LogLevel.Trace;
+ }
+ }
+}