diff --git a/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj b/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj
index f0159b15b..6f4df44d0 100644
--- a/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj
+++ b/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj
@@ -2,11 +2,16 @@
net5.0
+ true
-
-
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
diff --git a/ErsatzTV.Infrastructure/Migrations/20210212105010_Initial.Designer.cs b/ErsatzTV.Infrastructure/Migrations/20210212105010_Initial.Designer.cs
new file mode 100644
index 000000000..d58578ac6
--- /dev/null
+++ b/ErsatzTV.Infrastructure/Migrations/20210212105010_Initial.Designer.cs
@@ -0,0 +1,876 @@
+//
+using System;
+using ErsatzTV.Infrastructure.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+namespace ErsatzTV.Infrastructure.Migrations
+{
+ [DbContext(typeof(TvContext))]
+ [Migration("20210212105010_Initial")]
+ partial class Initial
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "5.0.3");
+
+ modelBuilder.Entity("ErsatzTV.Core.AggregateModels.GenericIntegerId", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("INTEGER");
+
+ b.ToTable("GenericIntegerIds");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.AggregateModels.MediaCollectionSummary", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("INTEGER");
+
+ b.Property("IsSimple")
+ .HasColumnType("INTEGER");
+
+ b.Property("ItemCount")
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.ToTable("MediaCollectionSummaries");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("FFmpegProfileId")
+ .HasColumnType("INTEGER");
+
+ b.Property("Logo")
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("Number")
+ .HasColumnType("INTEGER");
+
+ b.Property("StreamingMode")
+ .HasColumnType("INTEGER");
+
+ b.Property("UniqueId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("FFmpegProfileId");
+
+ b.HasIndex("Number")
+ .IsUnique();
+
+ b.ToTable("Channels");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.ConfigElement", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Key")
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Key")
+ .IsUnique();
+
+ b.ToTable("ConfigElements");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.FFmpegProfile", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("AudioBitrate")
+ .HasColumnType("INTEGER");
+
+ b.Property("AudioBufferSize")
+ .HasColumnType("INTEGER");
+
+ b.Property("AudioChannels")
+ .HasColumnType("INTEGER");
+
+ b.Property("AudioCodec")
+ .HasColumnType("TEXT");
+
+ b.Property("AudioSampleRate")
+ .HasColumnType("INTEGER");
+
+ b.Property("AudioVolume")
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("NormalizeAudio")
+ .HasColumnType("INTEGER");
+
+ b.Property("NormalizeAudioCodec")
+ .HasColumnType("INTEGER");
+
+ b.Property("NormalizeResolution")
+ .HasColumnType("INTEGER");
+
+ b.Property("NormalizeVideoCodec")
+ .HasColumnType("INTEGER");
+
+ b.Property("ResolutionId")
+ .HasColumnType("INTEGER");
+
+ b.Property("ThreadCount")
+ .HasColumnType("INTEGER");
+
+ b.Property("Transcode")
+ .HasColumnType("INTEGER");
+
+ b.Property("VideoBitrate")
+ .HasColumnType("INTEGER");
+
+ b.Property("VideoBufferSize")
+ .HasColumnType("INTEGER");
+
+ b.Property("VideoCodec")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ResolutionId");
+
+ b.ToTable("FFmpegProfiles");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.MediaCollection", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("MediaCollections");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("LastWriteTime")
+ .HasColumnType("TEXT");
+
+ b.Property("MediaSourceId")
+ .HasColumnType("INTEGER");
+
+ b.Property("Path")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MediaSourceId");
+
+ b.ToTable("MediaItems");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.MediaSource", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("SourceType")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("MediaSources");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ChannelId")
+ .HasColumnType("INTEGER");
+
+ b.Property("ProgramScheduleId")
+ .HasColumnType("INTEGER");
+
+ b.Property("ProgramSchedulePlayoutType")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ChannelId");
+
+ b.HasIndex("ProgramScheduleId");
+
+ b.ToTable("Playouts");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutItem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Finish")
+ .HasColumnType("TEXT");
+
+ b.Property("MediaItemId")
+ .HasColumnType("INTEGER");
+
+ b.Property("PlayoutId")
+ .HasColumnType("INTEGER");
+
+ b.Property("Start")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MediaItemId");
+
+ b.HasIndex("PlayoutId");
+
+ b.ToTable("PlayoutItems");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutProgramScheduleAnchor", b =>
+ {
+ b.Property("PlayoutId")
+ .HasColumnType("INTEGER");
+
+ b.Property("ProgramScheduleId")
+ .HasColumnType("INTEGER");
+
+ b.Property("MediaCollectionId")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("PlayoutId", "ProgramScheduleId", "MediaCollectionId");
+
+ b.HasIndex("MediaCollectionId");
+
+ b.HasIndex("ProgramScheduleId");
+
+ b.ToTable("PlayoutProgramScheduleItemAnchors");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSourceConnection", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("IsActive")
+ .HasColumnType("INTEGER");
+
+ b.Property("PlexMediaSourceId")
+ .HasColumnType("INTEGER");
+
+ b.Property("Uri")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PlexMediaSourceId");
+
+ b.ToTable("PlexMediaSourceConnections");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSourceLibrary", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Key")
+ .HasColumnType("TEXT");
+
+ b.Property("MediaType")
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("PlexMediaSourceId")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PlexMediaSourceId");
+
+ b.ToTable("PlexMediaSourceLibraries");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramSchedule", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("MediaCollectionPlaybackOrder")
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("ProgramSchedules");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Index")
+ .HasColumnType("INTEGER");
+
+ b.Property("MediaCollectionId")
+ .HasColumnType("INTEGER");
+
+ b.Property("ProgramScheduleId")
+ .HasColumnType("INTEGER");
+
+ b.Property("StartTime")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MediaCollectionId");
+
+ b.HasIndex("ProgramScheduleId");
+
+ b.ToTable("ProgramScheduleItems");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.Resolution", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Height")
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("Width")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("Resolutions");
+ });
+
+ modelBuilder.Entity("MediaItemSimpleMediaCollection", b =>
+ {
+ b.Property("ItemsId")
+ .HasColumnType("INTEGER");
+
+ b.Property("SimpleMediaCollectionsId")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("ItemsId", "SimpleMediaCollectionsId");
+
+ b.HasIndex("SimpleMediaCollectionsId");
+
+ b.ToTable("MediaItemSimpleMediaCollection");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.SimpleMediaCollection", b =>
+ {
+ b.HasBaseType("ErsatzTV.Core.Domain.MediaCollection");
+
+ b.ToTable("SimpleMediaCollections");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.TelevisionMediaCollection", b =>
+ {
+ b.HasBaseType("ErsatzTV.Core.Domain.MediaCollection");
+
+ b.Property("SeasonNumber")
+ .HasColumnType("INTEGER");
+
+ b.Property("ShowTitle")
+ .HasColumnType("TEXT");
+
+ b.HasIndex("ShowTitle", "SeasonNumber")
+ .IsUnique();
+
+ b.ToTable("TelevisionMediaCollections");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.LocalMediaSource", b =>
+ {
+ b.HasBaseType("ErsatzTV.Core.Domain.MediaSource");
+
+ b.Property("Folder")
+ .HasColumnType("TEXT");
+
+ b.Property("MediaType")
+ .HasColumnType("INTEGER");
+
+ b.ToTable("LocalMediaSources");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b =>
+ {
+ b.HasBaseType("ErsatzTV.Core.Domain.MediaSource");
+
+ b.Property("ClientIdentifier")
+ .HasColumnType("TEXT");
+
+ b.Property("ProductVersion")
+ .HasColumnType("TEXT");
+
+ b.ToTable("PlexMediaSources");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", b =>
+ {
+ b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem");
+
+ b.Property("OfflineTail")
+ .HasColumnType("INTEGER");
+
+ b.Property("PlayoutDuration")
+ .HasColumnType("TEXT");
+
+ b.ToTable("ProgramScheduleDurationItems");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", b =>
+ {
+ b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem");
+
+ b.ToTable("ProgramScheduleFloodItems");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", b =>
+ {
+ b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem");
+
+ b.Property("Count")
+ .HasColumnType("INTEGER");
+
+ b.ToTable("ProgramScheduleMultipleItems");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemOne", b =>
+ {
+ b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem");
+
+ b.ToTable("ProgramScheduleOneItems");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.FFmpegProfile", "FFmpegProfile")
+ .WithMany()
+ .HasForeignKey("FFmpegProfileId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("FFmpegProfile");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.FFmpegProfile", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.Resolution", "Resolution")
+ .WithMany()
+ .HasForeignKey("ResolutionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Resolution");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.MediaSource", "Source")
+ .WithMany()
+ .HasForeignKey("MediaSourceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.OwnsOne("ErsatzTV.Core.Domain.MediaMetadata", "Metadata", b1 =>
+ {
+ b1.Property("MediaItemId")
+ .HasColumnType("INTEGER");
+
+ b1.Property("Aired")
+ .HasColumnType("TEXT");
+
+ b1.Property("AudioCodec")
+ .HasColumnType("TEXT");
+
+ b1.Property("ContentRating")
+ .HasColumnType("TEXT");
+
+ b1.Property("Description")
+ .HasColumnType("TEXT");
+
+ b1.Property("DisplayAspectRatio")
+ .HasColumnType("TEXT");
+
+ b1.Property("Duration")
+ .HasColumnType("TEXT");
+
+ b1.Property("EpisodeNumber")
+ .HasColumnType("INTEGER");
+
+ b1.Property("Height")
+ .HasColumnType("INTEGER");
+
+ b1.Property("MediaType")
+ .HasColumnType("INTEGER");
+
+ b1.Property("SampleAspectRatio")
+ .HasColumnType("TEXT");
+
+ b1.Property("SeasonNumber")
+ .HasColumnType("INTEGER");
+
+ b1.Property("Subtitle")
+ .HasColumnType("TEXT");
+
+ b1.Property("Title")
+ .HasColumnType("TEXT");
+
+ b1.Property("VideoCodec")
+ .HasColumnType("TEXT");
+
+ b1.Property("VideoScanType")
+ .HasColumnType("INTEGER");
+
+ b1.Property("Width")
+ .HasColumnType("INTEGER");
+
+ b1.HasKey("MediaItemId");
+
+ b1.ToTable("MediaItems");
+
+ b1.WithOwner()
+ .HasForeignKey("MediaItemId");
+ });
+
+ b.Navigation("Metadata");
+
+ b.Navigation("Source");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.Channel", "Channel")
+ .WithMany("Playouts")
+ .HasForeignKey("ChannelId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule")
+ .WithMany("Playouts")
+ .HasForeignKey("ProgramScheduleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.OwnsOne("ErsatzTV.Core.Domain.PlayoutAnchor", "Anchor", b1 =>
+ {
+ b1.Property("PlayoutId")
+ .HasColumnType("INTEGER");
+
+ b1.Property("NextScheduleItemId")
+ .HasColumnType("INTEGER");
+
+ b1.Property("NextStart")
+ .HasColumnType("TEXT");
+
+ b1.HasKey("PlayoutId");
+
+ b1.HasIndex("NextScheduleItemId");
+
+ b1.ToTable("Playouts");
+
+ b1.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", "NextScheduleItem")
+ .WithMany()
+ .HasForeignKey("NextScheduleItemId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b1.WithOwner()
+ .HasForeignKey("PlayoutId");
+
+ b1.Navigation("NextScheduleItem");
+ });
+
+ b.Navigation("Anchor");
+
+ b.Navigation("Channel");
+
+ b.Navigation("ProgramSchedule");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutItem", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem")
+ .WithMany()
+ .HasForeignKey("MediaItemId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout")
+ .WithMany("Items")
+ .HasForeignKey("PlayoutId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("MediaItem");
+
+ b.Navigation("Playout");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutProgramScheduleAnchor", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.MediaCollection", "MediaCollection")
+ .WithMany()
+ .HasForeignKey("MediaCollectionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout")
+ .WithMany("ProgramScheduleAnchors")
+ .HasForeignKey("PlayoutId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule")
+ .WithMany()
+ .HasForeignKey("ProgramScheduleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.OwnsOne("ErsatzTV.Core.Domain.MediaCollectionEnumeratorState", "EnumeratorState", b1 =>
+ {
+ b1.Property("PlayoutProgramScheduleAnchorPlayoutId")
+ .HasColumnType("INTEGER");
+
+ b1.Property("PlayoutProgramScheduleAnchorProgramScheduleId")
+ .HasColumnType("INTEGER");
+
+ b1.Property("PlayoutProgramScheduleAnchorMediaCollectionId")
+ .HasColumnType("INTEGER");
+
+ b1.Property("Index")
+ .HasColumnType("INTEGER");
+
+ b1.Property("Seed")
+ .HasColumnType("INTEGER");
+
+ b1.HasKey("PlayoutProgramScheduleAnchorPlayoutId", "PlayoutProgramScheduleAnchorProgramScheduleId", "PlayoutProgramScheduleAnchorMediaCollectionId");
+
+ b1.ToTable("PlayoutProgramScheduleItemAnchors");
+
+ b1.WithOwner()
+ .HasForeignKey("PlayoutProgramScheduleAnchorPlayoutId", "PlayoutProgramScheduleAnchorProgramScheduleId", "PlayoutProgramScheduleAnchorMediaCollectionId");
+ });
+
+ b.Navigation("EnumeratorState");
+
+ b.Navigation("MediaCollection");
+
+ b.Navigation("Playout");
+
+ b.Navigation("ProgramSchedule");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSourceConnection", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.PlexMediaSource", null)
+ .WithMany("Connections")
+ .HasForeignKey("PlexMediaSourceId");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSourceLibrary", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.PlexMediaSource", null)
+ .WithMany("Libraries")
+ .HasForeignKey("PlexMediaSourceId");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItem", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.MediaCollection", "MediaCollection")
+ .WithMany()
+ .HasForeignKey("MediaCollectionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule")
+ .WithMany("Items")
+ .HasForeignKey("ProgramScheduleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("MediaCollection");
+
+ b.Navigation("ProgramSchedule");
+ });
+
+ modelBuilder.Entity("MediaItemSimpleMediaCollection", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.MediaItem", null)
+ .WithMany()
+ .HasForeignKey("ItemsId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ErsatzTV.Core.Domain.SimpleMediaCollection", null)
+ .WithMany()
+ .HasForeignKey("SimpleMediaCollectionsId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.SimpleMediaCollection", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.MediaCollection", null)
+ .WithOne()
+ .HasForeignKey("ErsatzTV.Core.Domain.SimpleMediaCollection", "Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.TelevisionMediaCollection", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.MediaCollection", null)
+ .WithOne()
+ .HasForeignKey("ErsatzTV.Core.Domain.TelevisionMediaCollection", "Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.LocalMediaSource", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.MediaSource", null)
+ .WithOne()
+ .HasForeignKey("ErsatzTV.Core.Domain.LocalMediaSource", "Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.MediaSource", null)
+ .WithOne()
+ .HasForeignKey("ErsatzTV.Core.Domain.PlexMediaSource", "Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null)
+ .WithOne()
+ .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", "Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null)
+ .WithOne()
+ .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", "Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null)
+ .WithOne()
+ .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", "Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemOne", b =>
+ {
+ b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null)
+ .WithOne()
+ .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemOne", "Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b =>
+ {
+ b.Navigation("Playouts");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b =>
+ {
+ b.Navigation("Items");
+
+ b.Navigation("ProgramScheduleAnchors");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramSchedule", b =>
+ {
+ b.Navigation("Items");
+
+ b.Navigation("Playouts");
+ });
+
+ modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b =>
+ {
+ b.Navigation("Connections");
+
+ b.Navigation("Libraries");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/ErsatzTV.Infrastructure/Migrations/20210212105010_Initial.cs b/ErsatzTV.Infrastructure/Migrations/20210212105010_Initial.cs
new file mode 100644
index 000000000..c1281deb4
--- /dev/null
+++ b/ErsatzTV.Infrastructure/Migrations/20210212105010_Initial.cs
@@ -0,0 +1,718 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace ErsatzTV.Infrastructure.Migrations
+{
+ public partial class Initial : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ "ConfigElements",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Key = table.Column("TEXT", nullable: true),
+ Value = table.Column("TEXT", nullable: true)
+ },
+ constraints: table => { table.PrimaryKey("PK_ConfigElements", x => x.Id); });
+
+ migrationBuilder.CreateTable(
+ "GenericIntegerIds",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ },
+ constraints: table => { });
+
+ migrationBuilder.CreateTable(
+ "MediaCollections",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column("TEXT", nullable: true)
+ },
+ constraints: table => { table.PrimaryKey("PK_MediaCollections", x => x.Id); });
+
+ migrationBuilder.CreateTable(
+ "MediaCollectionSummaries",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false),
+ Name = table.Column("TEXT", nullable: true),
+ ItemCount = table.Column("INTEGER", nullable: false),
+ IsSimple = table.Column("INTEGER", nullable: false)
+ },
+ constraints: table => { });
+
+ migrationBuilder.CreateTable(
+ "MediaSources",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ SourceType = table.Column("INTEGER", nullable: false),
+ Name = table.Column("TEXT", nullable: true)
+ },
+ constraints: table => { table.PrimaryKey("PK_MediaSources", x => x.Id); });
+
+ migrationBuilder.CreateTable(
+ "ProgramSchedules",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column("TEXT", nullable: true),
+ MediaCollectionPlaybackOrder = table.Column("INTEGER", nullable: false)
+ },
+ constraints: table => { table.PrimaryKey("PK_ProgramSchedules", x => x.Id); });
+
+ migrationBuilder.CreateTable(
+ "Resolutions",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column("TEXT", nullable: true),
+ Height = table.Column("INTEGER", nullable: false),
+ Width = table.Column("INTEGER", nullable: false)
+ },
+ constraints: table => { table.PrimaryKey("PK_Resolutions", x => x.Id); });
+
+ migrationBuilder.CreateTable(
+ "SimpleMediaCollections",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_SimpleMediaCollections", x => x.Id);
+ table.ForeignKey(
+ "FK_SimpleMediaCollections_MediaCollections_Id",
+ x => x.Id,
+ "MediaCollections",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "TelevisionMediaCollections",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ ShowTitle = table.Column("TEXT", nullable: true),
+ SeasonNumber = table.Column("INTEGER", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_TelevisionMediaCollections", x => x.Id);
+ table.ForeignKey(
+ "FK_TelevisionMediaCollections_MediaCollections_Id",
+ x => x.Id,
+ "MediaCollections",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "LocalMediaSources",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ MediaType = table.Column("INTEGER", nullable: false),
+ Folder = table.Column("TEXT", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_LocalMediaSources", x => x.Id);
+ table.ForeignKey(
+ "FK_LocalMediaSources_MediaSources_Id",
+ x => x.Id,
+ "MediaSources",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "MediaItems",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ MediaSourceId = table.Column("INTEGER", nullable: false),
+ Path = table.Column("TEXT", nullable: true),
+ Metadata_Duration = table.Column("TEXT", nullable: true),
+ Metadata_SampleAspectRatio = table.Column("TEXT", nullable: true),
+ Metadata_DisplayAspectRatio = table.Column("TEXT", nullable: true),
+ Metadata_VideoCodec = table.Column("TEXT", nullable: true),
+ Metadata_AudioCodec = table.Column("TEXT", nullable: true),
+ Metadata_MediaType = table.Column("INTEGER", nullable: true),
+ Metadata_Title = table.Column("TEXT", nullable: true),
+ Metadata_Subtitle = table.Column("TEXT", nullable: true),
+ Metadata_Description = table.Column("TEXT", nullable: true),
+ Metadata_SeasonNumber = table.Column("INTEGER", nullable: true),
+ Metadata_EpisodeNumber = table.Column("INTEGER", nullable: true),
+ Metadata_ContentRating = table.Column("TEXT", nullable: true),
+ Metadata_Aired = table.Column("TEXT", nullable: true),
+ Metadata_VideoScanType = table.Column("INTEGER", nullable: true),
+ Metadata_Width = table.Column("INTEGER", nullable: true),
+ Metadata_Height = table.Column("INTEGER", nullable: true),
+ LastWriteTime = table.Column("TEXT", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_MediaItems", x => x.Id);
+ table.ForeignKey(
+ "FK_MediaItems_MediaSources_MediaSourceId",
+ x => x.MediaSourceId,
+ "MediaSources",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "PlexMediaSources",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ ProductVersion = table.Column("TEXT", nullable: true),
+ ClientIdentifier = table.Column("TEXT", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_PlexMediaSources", x => x.Id);
+ table.ForeignKey(
+ "FK_PlexMediaSources_MediaSources_Id",
+ x => x.Id,
+ "MediaSources",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "ProgramScheduleItems",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Index = table.Column("INTEGER", nullable: false),
+ StartTime = table.Column("TEXT", nullable: true),
+ MediaCollectionId = table.Column("INTEGER", nullable: false),
+ ProgramScheduleId = table.Column("INTEGER", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_ProgramScheduleItems", x => x.Id);
+ table.ForeignKey(
+ "FK_ProgramScheduleItems_MediaCollections_MediaCollectionId",
+ x => x.MediaCollectionId,
+ "MediaCollections",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ "FK_ProgramScheduleItems_ProgramSchedules_ProgramScheduleId",
+ x => x.ProgramScheduleId,
+ "ProgramSchedules",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "FFmpegProfiles",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Name = table.Column("TEXT", nullable: true),
+ ThreadCount = table.Column("INTEGER", nullable: false),
+ Transcode = table.Column("INTEGER", nullable: false),
+ ResolutionId = table.Column("INTEGER", nullable: false),
+ NormalizeResolution = table.Column("INTEGER", nullable: false),
+ VideoCodec = table.Column("TEXT", nullable: true),
+ NormalizeVideoCodec = table.Column("INTEGER", nullable: false),
+ VideoBitrate = table.Column("INTEGER", nullable: false),
+ VideoBufferSize = table.Column("INTEGER", nullable: false),
+ AudioCodec = table.Column("TEXT", nullable: true),
+ NormalizeAudioCodec = table.Column("INTEGER", nullable: false),
+ AudioBitrate = table.Column("INTEGER", nullable: false),
+ AudioBufferSize = table.Column("INTEGER", nullable: false),
+ AudioVolume = table.Column("INTEGER", nullable: false),
+ AudioChannels = table.Column("INTEGER", nullable: false),
+ AudioSampleRate = table.Column("INTEGER", nullable: false),
+ NormalizeAudio = table.Column("INTEGER", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_FFmpegProfiles", x => x.Id);
+ table.ForeignKey(
+ "FK_FFmpegProfiles_Resolutions_ResolutionId",
+ x => x.ResolutionId,
+ "Resolutions",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "MediaItemSimpleMediaCollection",
+ table => new
+ {
+ ItemsId = table.Column("INTEGER", nullable: false),
+ SimpleMediaCollectionsId = table.Column("INTEGER", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey(
+ "PK_MediaItemSimpleMediaCollection",
+ x => new { x.ItemsId, x.SimpleMediaCollectionsId });
+ table.ForeignKey(
+ "FK_MediaItemSimpleMediaCollection_MediaItems_ItemsId",
+ x => x.ItemsId,
+ "MediaItems",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ "FK_MediaItemSimpleMediaCollection_SimpleMediaCollections_SimpleMediaCollectionsId",
+ x => x.SimpleMediaCollectionsId,
+ "SimpleMediaCollections",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "PlexMediaSourceConnections",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ IsActive = table.Column("INTEGER", nullable: false),
+ Uri = table.Column("TEXT", nullable: true),
+ PlexMediaSourceId = table.Column("INTEGER", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_PlexMediaSourceConnections", x => x.Id);
+ table.ForeignKey(
+ "FK_PlexMediaSourceConnections_PlexMediaSources_PlexMediaSourceId",
+ x => x.PlexMediaSourceId,
+ "PlexMediaSources",
+ "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ "PlexMediaSourceLibraries",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Key = table.Column("TEXT", nullable: true),
+ Name = table.Column("TEXT", nullable: true),
+ MediaType = table.Column("INTEGER", nullable: false),
+ PlexMediaSourceId = table.Column("INTEGER", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_PlexMediaSourceLibraries", x => x.Id);
+ table.ForeignKey(
+ "FK_PlexMediaSourceLibraries_PlexMediaSources_PlexMediaSourceId",
+ x => x.PlexMediaSourceId,
+ "PlexMediaSources",
+ "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ "ProgramScheduleDurationItems",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ PlayoutDuration = table.Column("TEXT", nullable: false),
+ OfflineTail = table.Column("INTEGER", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_ProgramScheduleDurationItems", x => x.Id);
+ table.ForeignKey(
+ "FK_ProgramScheduleDurationItems_ProgramScheduleItems_Id",
+ x => x.Id,
+ "ProgramScheduleItems",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "ProgramScheduleFloodItems",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_ProgramScheduleFloodItems", x => x.Id);
+ table.ForeignKey(
+ "FK_ProgramScheduleFloodItems_ProgramScheduleItems_Id",
+ x => x.Id,
+ "ProgramScheduleItems",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "ProgramScheduleMultipleItems",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Count = table.Column("INTEGER", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_ProgramScheduleMultipleItems", x => x.Id);
+ table.ForeignKey(
+ "FK_ProgramScheduleMultipleItems_ProgramScheduleItems_Id",
+ x => x.Id,
+ "ProgramScheduleItems",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "ProgramScheduleOneItems",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_ProgramScheduleOneItems", x => x.Id);
+ table.ForeignKey(
+ "FK_ProgramScheduleOneItems_ProgramScheduleItems_Id",
+ x => x.Id,
+ "ProgramScheduleItems",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "Channels",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ UniqueId = table.Column("TEXT", nullable: false),
+ Number = table.Column("INTEGER", nullable: false),
+ Name = table.Column("TEXT", nullable: true),
+ Logo = table.Column("TEXT", nullable: true),
+ FFmpegProfileId = table.Column("INTEGER", nullable: false),
+ StreamingMode = table.Column("INTEGER", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Channels", x => x.Id);
+ table.ForeignKey(
+ "FK_Channels_FFmpegProfiles_FFmpegProfileId",
+ x => x.FFmpegProfileId,
+ "FFmpegProfiles",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "Playouts",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ ChannelId = table.Column("INTEGER", nullable: false),
+ ProgramScheduleId = table.Column("INTEGER", nullable: false),
+ ProgramSchedulePlayoutType = table.Column("INTEGER", nullable: false),
+ Anchor_NextScheduleItemId = table.Column("INTEGER", nullable: true),
+ Anchor_NextStart = table.Column("TEXT", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Playouts", x => x.Id);
+ table.ForeignKey(
+ "FK_Playouts_Channels_ChannelId",
+ x => x.ChannelId,
+ "Channels",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ "FK_Playouts_ProgramScheduleItems_Anchor_NextScheduleItemId",
+ x => x.Anchor_NextScheduleItemId,
+ "ProgramScheduleItems",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ "FK_Playouts_ProgramSchedules_ProgramScheduleId",
+ x => x.ProgramScheduleId,
+ "ProgramSchedules",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "PlayoutItems",
+ table => new
+ {
+ Id = table.Column("INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ MediaItemId = table.Column("INTEGER", nullable: false),
+ Start = table.Column("TEXT", nullable: false),
+ Finish = table.Column("TEXT", nullable: false),
+ PlayoutId = table.Column("INTEGER", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_PlayoutItems", x => x.Id);
+ table.ForeignKey(
+ "FK_PlayoutItems_MediaItems_MediaItemId",
+ x => x.MediaItemId,
+ "MediaItems",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ "FK_PlayoutItems_Playouts_PlayoutId",
+ x => x.PlayoutId,
+ "Playouts",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ "PlayoutProgramScheduleItemAnchors",
+ table => new
+ {
+ PlayoutId = table.Column("INTEGER", nullable: false),
+ ProgramScheduleId = table.Column("INTEGER", nullable: false),
+ MediaCollectionId = table.Column("INTEGER", nullable: false),
+ EnumeratorState_Seed = table.Column("INTEGER", nullable: true),
+ EnumeratorState_Index = table.Column("INTEGER", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey(
+ "PK_PlayoutProgramScheduleItemAnchors",
+ x => new { x.PlayoutId, x.ProgramScheduleId, x.MediaCollectionId });
+ table.ForeignKey(
+ "FK_PlayoutProgramScheduleItemAnchors_MediaCollections_MediaCollectionId",
+ x => x.MediaCollectionId,
+ "MediaCollections",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ "FK_PlayoutProgramScheduleItemAnchors_Playouts_PlayoutId",
+ x => x.PlayoutId,
+ "Playouts",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ "FK_PlayoutProgramScheduleItemAnchors_ProgramSchedules_ProgramScheduleId",
+ x => x.ProgramScheduleId,
+ "ProgramSchedules",
+ "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateIndex(
+ "IX_Channels_FFmpegProfileId",
+ "Channels",
+ "FFmpegProfileId");
+
+ migrationBuilder.CreateIndex(
+ "IX_Channels_Number",
+ "Channels",
+ "Number",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ "IX_ConfigElements_Key",
+ "ConfigElements",
+ "Key",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ "IX_FFmpegProfiles_ResolutionId",
+ "FFmpegProfiles",
+ "ResolutionId");
+
+ migrationBuilder.CreateIndex(
+ "IX_MediaCollections_Name",
+ "MediaCollections",
+ "Name",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ "IX_MediaItems_MediaSourceId",
+ "MediaItems",
+ "MediaSourceId");
+
+ migrationBuilder.CreateIndex(
+ "IX_MediaItemSimpleMediaCollection_SimpleMediaCollectionsId",
+ "MediaItemSimpleMediaCollection",
+ "SimpleMediaCollectionsId");
+
+ migrationBuilder.CreateIndex(
+ "IX_MediaSources_Name",
+ "MediaSources",
+ "Name",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ "IX_PlayoutItems_MediaItemId",
+ "PlayoutItems",
+ "MediaItemId");
+
+ migrationBuilder.CreateIndex(
+ "IX_PlayoutItems_PlayoutId",
+ "PlayoutItems",
+ "PlayoutId");
+
+ migrationBuilder.CreateIndex(
+ "IX_PlayoutProgramScheduleItemAnchors_MediaCollectionId",
+ "PlayoutProgramScheduleItemAnchors",
+ "MediaCollectionId");
+
+ migrationBuilder.CreateIndex(
+ "IX_PlayoutProgramScheduleItemAnchors_ProgramScheduleId",
+ "PlayoutProgramScheduleItemAnchors",
+ "ProgramScheduleId");
+
+ migrationBuilder.CreateIndex(
+ "IX_Playouts_Anchor_NextScheduleItemId",
+ "Playouts",
+ "Anchor_NextScheduleItemId");
+
+ migrationBuilder.CreateIndex(
+ "IX_Playouts_ChannelId",
+ "Playouts",
+ "ChannelId");
+
+ migrationBuilder.CreateIndex(
+ "IX_Playouts_ProgramScheduleId",
+ "Playouts",
+ "ProgramScheduleId");
+
+ migrationBuilder.CreateIndex(
+ "IX_PlexMediaSourceConnections_PlexMediaSourceId",
+ "PlexMediaSourceConnections",
+ "PlexMediaSourceId");
+
+ migrationBuilder.CreateIndex(
+ "IX_PlexMediaSourceLibraries_PlexMediaSourceId",
+ "PlexMediaSourceLibraries",
+ "PlexMediaSourceId");
+
+ migrationBuilder.CreateIndex(
+ "IX_ProgramScheduleItems_MediaCollectionId",
+ "ProgramScheduleItems",
+ "MediaCollectionId");
+
+ migrationBuilder.CreateIndex(
+ "IX_ProgramScheduleItems_ProgramScheduleId",
+ "ProgramScheduleItems",
+ "ProgramScheduleId");
+
+ migrationBuilder.CreateIndex(
+ "IX_ProgramSchedules_Name",
+ "ProgramSchedules",
+ "Name",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ "IX_TelevisionMediaCollections_ShowTitle_SeasonNumber",
+ "TelevisionMediaCollections",
+ new[] { "ShowTitle", "SeasonNumber" },
+ unique: true);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ "ConfigElements");
+
+ migrationBuilder.DropTable(
+ "GenericIntegerIds");
+
+ migrationBuilder.DropTable(
+ "LocalMediaSources");
+
+ migrationBuilder.DropTable(
+ "MediaCollectionSummaries");
+
+ migrationBuilder.DropTable(
+ "MediaItemSimpleMediaCollection");
+
+ migrationBuilder.DropTable(
+ "PlayoutItems");
+
+ migrationBuilder.DropTable(
+ "PlayoutProgramScheduleItemAnchors");
+
+ migrationBuilder.DropTable(
+ "PlexMediaSourceConnections");
+
+ migrationBuilder.DropTable(
+ "PlexMediaSourceLibraries");
+
+ migrationBuilder.DropTable(
+ "ProgramScheduleDurationItems");
+
+ migrationBuilder.DropTable(
+ "ProgramScheduleFloodItems");
+
+ migrationBuilder.DropTable(
+ "ProgramScheduleMultipleItems");
+
+ migrationBuilder.DropTable(
+ "ProgramScheduleOneItems");
+
+ migrationBuilder.DropTable(
+ "TelevisionMediaCollections");
+
+ migrationBuilder.DropTable(
+ "SimpleMediaCollections");
+
+ migrationBuilder.DropTable(
+ "MediaItems");
+
+ migrationBuilder.DropTable(
+ "Playouts");
+
+ migrationBuilder.DropTable(
+ "PlexMediaSources");
+
+ migrationBuilder.DropTable(
+ "Channels");
+
+ migrationBuilder.DropTable(
+ "ProgramScheduleItems");
+
+ migrationBuilder.DropTable(
+ "MediaSources");
+
+ migrationBuilder.DropTable(
+ "FFmpegProfiles");
+
+ migrationBuilder.DropTable(
+ "MediaCollections");
+
+ migrationBuilder.DropTable(
+ "ProgramSchedules");
+
+ migrationBuilder.DropTable(
+ "Resolutions");
+ }
+ }
+}
diff --git a/ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs b/ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs
new file mode 100644
index 000000000..252da1d5b
--- /dev/null
+++ b/ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs
@@ -0,0 +1,978 @@
+//
+
+using System;
+using ErsatzTV.Infrastructure.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+
+namespace ErsatzTV.Infrastructure.Migrations
+{
+ [DbContext(typeof(TvContext))]
+ internal class TvContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "5.0.3");
+
+ modelBuilder.Entity(
+ "ErsatzTV.Core.AggregateModels.GenericIntegerId",
+ b =>
+ {
+ b.Property("Id")
+ .HasColumnType("INTEGER");
+
+ b.ToTable("GenericIntegerIds");
+ });
+
+ modelBuilder.Entity(
+ "ErsatzTV.Core.AggregateModels.MediaCollectionSummary",
+ b =>
+ {
+ b.Property("Id")
+ .HasColumnType("INTEGER");
+
+ b.Property("IsSimple")
+ .HasColumnType("INTEGER");
+
+ b.Property("ItemCount")
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.ToTable("MediaCollectionSummaries");
+ });
+
+ modelBuilder.Entity(
+ "ErsatzTV.Core.Domain.Channel",
+ b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("FFmpegProfileId")
+ .HasColumnType("INTEGER");
+
+ b.Property("Logo")
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("Number")
+ .HasColumnType("INTEGER");
+
+ b.Property("StreamingMode")
+ .HasColumnType("INTEGER");
+
+ b.Property("UniqueId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("FFmpegProfileId");
+
+ b.HasIndex("Number")
+ .IsUnique();
+
+ b.ToTable("Channels");
+ });
+
+ modelBuilder.Entity(
+ "ErsatzTV.Core.Domain.ConfigElement",
+ b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Key")
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Key")
+ .IsUnique();
+
+ b.ToTable("ConfigElements");
+ });
+
+ modelBuilder.Entity(
+ "ErsatzTV.Core.Domain.FFmpegProfile",
+ b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("AudioBitrate")
+ .HasColumnType("INTEGER");
+
+ b.Property("AudioBufferSize")
+ .HasColumnType("INTEGER");
+
+ b.Property("AudioChannels")
+ .HasColumnType("INTEGER");
+
+ b.Property("AudioCodec")
+ .HasColumnType("TEXT");
+
+ b.Property("AudioSampleRate")
+ .HasColumnType("INTEGER");
+
+ b.Property("AudioVolume")
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("NormalizeAudio")
+ .HasColumnType("INTEGER");
+
+ b.Property("NormalizeAudioCodec")
+ .HasColumnType("INTEGER");
+
+ b.Property("NormalizeResolution")
+ .HasColumnType("INTEGER");
+
+ b.Property("NormalizeVideoCodec")
+ .HasColumnType("INTEGER");
+
+ b.Property("ResolutionId")
+ .HasColumnType("INTEGER");
+
+ b.Property("ThreadCount")
+ .HasColumnType("INTEGER");
+
+ b.Property