aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Server.Implementations
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Server.Implementations')
-rw-r--r--Jellyfin.Server.Implementations/Activity/ActivityManager.cs103
-rw-r--r--Jellyfin.Server.Implementations/JellyfinDb.cs4
-rw-r--r--Jellyfin.Server.Implementations/JellyfinDbProvider.cs33
-rw-r--r--Jellyfin.Server.Implementations/Migrations/20200502231229_InitialSchema.Designer.cs73
-rw-r--r--Jellyfin.Server.Implementations/Migrations/20200502231229_InitialSchema.cs46
-rw-r--r--Jellyfin.Server.Implementations/Migrations/DesignTimeJellyfinDbFactory.cs23
-rw-r--r--Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs68
7 files changed, 350 insertions, 0 deletions
diff --git a/Jellyfin.Server.Implementations/Activity/ActivityManager.cs b/Jellyfin.Server.Implementations/Activity/ActivityManager.cs
new file mode 100644
index 000000000..531b529dc
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Activity/ActivityManager.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Jellyfin.Data.Entities;
+using MediaBrowser.Model.Activity;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Querying;
+
+namespace Jellyfin.Server.Implementations.Activity
+{
+ /// <summary>
+ /// Manages the storage and retrieval of <see cref="ActivityLog"/> instances.
+ /// </summary>
+ public class ActivityManager : IActivityManager
+ {
+ private readonly JellyfinDbProvider _provider;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ActivityManager"/> class.
+ /// </summary>
+ /// <param name="provider">The Jellyfin database provider.</param>
+ public ActivityManager(JellyfinDbProvider provider)
+ {
+ _provider = provider;
+ }
+
+ /// <inheritdoc/>
+ public event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
+
+ /// <inheritdoc/>
+ public void Create(ActivityLog entry)
+ {
+ using var dbContext = _provider.CreateContext();
+ dbContext.ActivityLogs.Add(entry);
+ dbContext.SaveChanges();
+
+ EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(ConvertToOldModel(entry)));
+ }
+
+ /// <inheritdoc/>
+ public async Task CreateAsync(ActivityLog entry)
+ {
+ using var dbContext = _provider.CreateContext();
+ await dbContext.ActivityLogs.AddAsync(entry);
+ await dbContext.SaveChangesAsync().ConfigureAwait(false);
+
+ EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(ConvertToOldModel(entry)));
+ }
+
+ /// <inheritdoc/>
+ public QueryResult<ActivityLogEntry> GetPagedResult(
+ Func<IQueryable<ActivityLog>, IEnumerable<ActivityLog>> func,
+ int? startIndex,
+ int? limit)
+ {
+ using var dbContext = _provider.CreateContext();
+
+ var result = func.Invoke(dbContext.ActivityLogs).AsQueryable();
+
+ if (startIndex.HasValue)
+ {
+ result = result.Where(entry => entry.Id >= startIndex.Value);
+ }
+
+ if (limit.HasValue)
+ {
+ result = result.OrderByDescending(entry => entry.DateCreated).Take(limit.Value);
+ }
+
+ // This converts the objects from the new database model to the old for compatibility with the existing API.
+ var list = result.Select(entry => ConvertToOldModel(entry)).ToList();
+
+ return new QueryResult<ActivityLogEntry>()
+ {
+ Items = list,
+ TotalRecordCount = list.Count
+ };
+ }
+
+ /// <inheritdoc/>
+ public QueryResult<ActivityLogEntry> GetPagedResult(int? startIndex, int? limit)
+ {
+ return GetPagedResult(logs => logs, startIndex, limit);
+ }
+
+ private static ActivityLogEntry ConvertToOldModel(ActivityLog entry)
+ {
+ return new ActivityLogEntry
+ {
+ Id = entry.Id,
+ Name = entry.Name,
+ Overview = entry.Overview,
+ ShortOverview = entry.ShortOverview,
+ Type = entry.Type,
+ ItemId = entry.ItemId,
+ UserId = entry.UserId,
+ Date = entry.DateCreated,
+ Severity = entry.LogSeverity
+ };
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/JellyfinDb.cs b/Jellyfin.Server.Implementations/JellyfinDb.cs
index 76343edf9..6fc8d251b 100644
--- a/Jellyfin.Server.Implementations/JellyfinDb.cs
+++ b/Jellyfin.Server.Implementations/JellyfinDb.cs
@@ -15,6 +15,7 @@ namespace Jellyfin.Server.Implementations
/// <inheritdoc/>
public partial class JellyfinDb : DbContext
{
+ public virtual DbSet<ActivityLog> ActivityLogs { get; set; }
/*public virtual DbSet<Artwork> Artwork { get; set; }
public virtual DbSet<Book> Books { get; set; }
public virtual DbSet<BookMetadata> BookMetadata { get; set; }
@@ -49,6 +50,7 @@ namespace Jellyfin.Server.Implementations
public virtual DbSet<Preference> Preferences { get; set; }
public virtual DbSet<ProviderMapping> ProviderMappings { get; set; }
public virtual DbSet<Rating> Ratings { get; set; }
+
/// <summary>
/// Repository for global::Jellyfin.Data.Entities.RatingSource - This is the entity to
/// store review ratings, not age ratings
@@ -93,8 +95,10 @@ namespace Jellyfin.Server.Implementations
modelBuilder.HasDefaultSchema("jellyfin");
/*modelBuilder.Entity<Artwork>().HasIndex(t => t.Kind);
+
modelBuilder.Entity<Genre>().HasIndex(t => t.Name)
.IsUnique();
+
modelBuilder.Entity<LibraryItem>().HasIndex(t => t.UrlId)
.IsUnique();*/
diff --git a/Jellyfin.Server.Implementations/JellyfinDbProvider.cs b/Jellyfin.Server.Implementations/JellyfinDbProvider.cs
new file mode 100644
index 000000000..8fdeab088
--- /dev/null
+++ b/Jellyfin.Server.Implementations/JellyfinDbProvider.cs
@@ -0,0 +1,33 @@
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Jellyfin.Server.Implementations
+{
+ /// <summary>
+ /// Factory class for generating new <see cref="JellyfinDb"/> instances.
+ /// </summary>
+ public class JellyfinDbProvider
+ {
+ private readonly IServiceProvider _serviceProvider;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="JellyfinDbProvider"/> class.
+ /// </summary>
+ /// <param name="serviceProvider">The application's service provider.</param>
+ public JellyfinDbProvider(IServiceProvider serviceProvider)
+ {
+ _serviceProvider = serviceProvider;
+ serviceProvider.GetService<JellyfinDb>().Database.Migrate();
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="JellyfinDb"/> context.
+ /// </summary>
+ /// <returns>The newly created context.</returns>
+ public JellyfinDb CreateContext()
+ {
+ return _serviceProvider.GetService<JellyfinDb>();
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/20200502231229_InitialSchema.Designer.cs b/Jellyfin.Server.Implementations/Migrations/20200502231229_InitialSchema.Designer.cs
new file mode 100644
index 000000000..e1ee9b34a
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/20200502231229_InitialSchema.Designer.cs
@@ -0,0 +1,73 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1601
+
+// <auto-generated />
+using System;
+using Jellyfin.Server.Implementations;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ [DbContext(typeof(JellyfinDb))]
+ [Migration("20200502231229_InitialSchema")]
+ partial class InitialSchema
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasDefaultSchema("jellyfin")
+ .HasAnnotation("ProductVersion", "3.1.3");
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ActivityLog", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("DateCreated")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("ItemId")
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.Property<int>("LogSeverity")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<string>("Overview")
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("ShortOverview")
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<string>("Type")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("ActivityLog");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/20200502231229_InitialSchema.cs b/Jellyfin.Server.Implementations/Migrations/20200502231229_InitialSchema.cs
new file mode 100644
index 000000000..42fac865c
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/20200502231229_InitialSchema.cs
@@ -0,0 +1,46 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1601
+
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ public partial class InitialSchema : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.EnsureSchema(
+ name: "jellyfin");
+
+ migrationBuilder.CreateTable(
+ name: "ActivityLog",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column<string>(maxLength: 512, nullable: false),
+ Overview = table.Column<string>(maxLength: 512, nullable: true),
+ ShortOverview = table.Column<string>(maxLength: 512, nullable: true),
+ Type = table.Column<string>(maxLength: 256, nullable: false),
+ UserId = table.Column<Guid>(nullable: false),
+ ItemId = table.Column<string>(maxLength: 256, nullable: true),
+ DateCreated = table.Column<DateTime>(nullable: false),
+ LogSeverity = table.Column<int>(nullable: false),
+ RowVersion = table.Column<uint>(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_ActivityLog", x => x.Id);
+ });
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "ActivityLog",
+ schema: "jellyfin");
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/DesignTimeJellyfinDbFactory.cs b/Jellyfin.Server.Implementations/Migrations/DesignTimeJellyfinDbFactory.cs
new file mode 100644
index 000000000..23a0fdc78
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/DesignTimeJellyfinDbFactory.cs
@@ -0,0 +1,23 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1601
+
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Design;
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ /// <summary>
+ /// The design time factory for <see cref="JellyfinDb"/>.
+ /// This is only used for the creation of migrations and not during runtime.
+ /// </summary>
+ internal class DesignTimeJellyfinDbFactory : IDesignTimeDbContextFactory<JellyfinDb>
+ {
+ public JellyfinDb CreateDbContext(string[] args)
+ {
+ var optionsBuilder = new DbContextOptionsBuilder<JellyfinDb>();
+ optionsBuilder.UseSqlite("Data Source=jellyfin.db");
+
+ return new JellyfinDb(optionsBuilder.Options);
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs b/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs
new file mode 100644
index 000000000..27f5fe24b
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs
@@ -0,0 +1,68 @@
+// <auto-generated />
+using System;
+using Jellyfin.Server.Implementations;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ [DbContext(typeof(JellyfinDb))]
+ partial class JellyfinDbModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasDefaultSchema("jellyfin")
+ .HasAnnotation("ProductVersion", "3.1.3");
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ActivityLog", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("DateCreated")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("ItemId")
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.Property<int>("LogSeverity")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<string>("Overview")
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("ShortOverview")
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<string>("Type")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("ActivityLog");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}