fix: remove required from entities' id

also adds "Global" entity for storing global configuration
This commit is contained in:
2025-12-16 04:01:45 +01:00
parent efb8a41065
commit eebc5f1d6d
15 changed files with 1627 additions and 1537 deletions

View File

@@ -17,6 +17,7 @@ public class ApplicationDbContext : DbContext
public DbSet<Artist> Artists => Set<Artist>(); public DbSet<Artist> Artists => Set<Artist>();
public DbSet<Genre> Genres => Set<Genre>(); public DbSet<Genre> Genres => Set<Genre>();
public DbSet<GenreSong> GenreSongs => Set<GenreSong>(); public DbSet<GenreSong> GenreSongs => Set<GenreSong>();
public DbSet<Global> Globals => Set<Global>();
public DbSet<Image> Images => Set<Image>(); public DbSet<Image> Images => Set<Image>();
public DbSet<Playlist> Playlists => Set<Playlist>(); public DbSet<Playlist> Playlists => Set<Playlist>();
public DbSet<PlaylistSong> PlaylistSongs => Set<PlaylistSong>(); public DbSet<PlaylistSong> PlaylistSongs => Set<PlaylistSong>();
@@ -52,6 +53,9 @@ public class ApplicationDbContext : DbContext
builder.Entity<Genre>(g => { builder.Entity<Genre>(g => {
g.HasIndex(g => g.NormalizedName).IsUnique(); g.HasIndex(g => g.NormalizedName).IsUnique();
}); });
builder.Entity<Global>(c => {
c.HasIndex(c => c.Key).IsUnique();
});
builder.Entity<Playlist>(p => { builder.Entity<Playlist>(p => {
p.HasIndex(p => p.Uri).IsUnique(); p.HasIndex(p => p.Uri).IsUnique();
}); });

View File

@@ -1,7 +1,7 @@
namespace Shadow.Entities; namespace Shadow.Entities;
public class Album public class Album
{ {
required public int Id { get; set; } public int Id { get; set; }
public required string Name { get; set; } public required string Name { get; set; }
public required string Uri { get; set; } public required string Uri { get; set; }
public int State { get; set; } = 0; public int State { get; set; } = 0;

View File

@@ -1,7 +1,7 @@
namespace Shadow.Entities; namespace Shadow.Entities;
public class AlbumInteraction public class AlbumInteraction
{ {
required public int Id { get; set; } public int Id { get; set; }
required public int AlbumId { get; set; } required public int AlbumId { get; set; }
required public int UserId { get; set; } required public int UserId { get; set; }
public DateTime? PlayDate { get; set; } = null; public DateTime? PlayDate { get; set; } = null;

View File

@@ -1,7 +1,7 @@
namespace Shadow.Entities; namespace Shadow.Entities;
public class Artist public class Artist
{ {
required public int Id { get; set; } public int Id { get; set; }
required public string Name { get; set; } required public string Name { get; set; }
required public string NormalizedName { get; set; } required public string NormalizedName { get; set; }

View File

@@ -1,7 +1,7 @@
namespace Shadow.Entities; namespace Shadow.Entities;
public class Genre public class Genre
{ {
required public int Id { get; set; } public int Id { get; set; }
required public string Name { get; set; } required public string Name { get; set; }
required public string NormalizedName { get; set; } required public string NormalizedName { get; set; }

View File

@@ -2,7 +2,7 @@ namespace Shadow.Entities;
public class GenreSong public class GenreSong
{ {
// Composite keys // Composite keys
required public int GenreId { get; set; } public int GenreId { get; set; }
required public int SongId { get; set; } required public int SongId { get; set; }
required public Genre Genre { get; set; } required public Genre Genre { get; set; }

7
Entities/Global.cs Normal file
View File

@@ -0,0 +1,7 @@
namespace Shadow.Entities;
public class Global
{
public int Id { get; set; }
required public string Key { get; set; }
public string? Value { get; set; } = null;
}

View File

@@ -1,8 +1,9 @@
namespace Shadow.Entities; namespace Shadow.Entities;
public class Image public class Image
{ {
required public int Id { get; set; } public int Id { get; set; }
required public string Uri { get; set; } required public string Uri { get; set; }
required public string Filetype { get; set; }
public int State { get; set; } public int State { get; set; }
public int? SongId { get; set; } = null; public int? SongId { get; set; } = null;

View File

@@ -1,7 +1,7 @@
namespace Shadow.Entities; namespace Shadow.Entities;
public class Playlist public class Playlist
{ {
required public int Id { get; set; } public int Id { get; set; }
required public string Name { get; set; } required public string Name { get; set; }
required public string Uri { get; set; } required public string Uri { get; set; }
required public string Description { get; set; } required public string Description { get; set; }

View File

@@ -1,7 +1,7 @@
namespace Shadow.Entities; namespace Shadow.Entities;
public class Radio public class Radio
{ {
required public int Id { get; set; } public int Id { get; set; }
required public string Name { get; set; } required public string Name { get; set; }
required public string NormalizedName { get; set; } required public string NormalizedName { get; set; }
public string? Homepage { get; set; } = null; public string? Homepage { get; set; } = null;

View File

@@ -1,608 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Shadow.Data;
#nullable disable
namespace Shadow.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20251209000751_InitialMigration")]
partial class InitialMigration
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Shadow.Entities.Album", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("ArtistId")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("State")
.HasColumnType("integer");
b.Property<string>("Uri")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("ArtistId");
b.HasIndex("Uri")
.IsUnique();
b.ToTable("Albums");
});
modelBuilder.Entity("Shadow.Entities.AlbumInteraction", b =>
{
b.Property<int>("AlbumId")
.HasColumnType("integer");
b.Property<int>("UserId")
.HasColumnType("integer");
b.Property<int>("Id")
.HasColumnType("integer");
b.Property<DateTime?>("PlayDate")
.HasColumnType("timestamp with time zone");
b.Property<bool>("Starred")
.HasColumnType("boolean");
b.HasKey("AlbumId", "UserId");
b.HasIndex("UserId");
b.ToTable("AlbumInteractions");
});
modelBuilder.Entity("Shadow.Entities.Artist", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("NormalizedName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique();
b.ToTable("Artists");
});
modelBuilder.Entity("Shadow.Entities.Genre", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("NormalizedName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique();
b.ToTable("Genres");
});
modelBuilder.Entity("Shadow.Entities.GenreSong", b =>
{
b.Property<int>("GenreId")
.HasColumnType("integer");
b.Property<int>("SongId")
.HasColumnType("integer");
b.HasKey("GenreId", "SongId");
b.HasIndex("SongId");
b.ToTable("GenreSongs");
});
modelBuilder.Entity("Shadow.Entities.Image", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("SongId")
.HasColumnType("integer");
b.Property<int>("State")
.HasColumnType("integer");
b.Property<string>("Uri")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("SongId")
.IsUnique();
b.ToTable("Images");
});
modelBuilder.Entity("Shadow.Entities.Playlist", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("CreatorId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Uri")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("CreatorId");
b.HasIndex("Uri")
.IsUnique();
b.ToTable("Playlists");
});
modelBuilder.Entity("Shadow.Entities.PlaylistSong", b =>
{
b.Property<int>("PlaylistId")
.HasColumnType("integer");
b.Property<int>("SongId")
.HasColumnType("integer");
b.Property<int>("Index")
.HasColumnType("integer");
b.HasKey("PlaylistId", "SongId");
b.HasIndex("SongId");
b.ToTable("PlaylistSongs");
});
modelBuilder.Entity("Shadow.Entities.PlaylistUser", b =>
{
b.Property<int>("PlaylistId")
.HasColumnType("integer");
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("PlaylistId", "UserId");
b.HasIndex("UserId");
b.ToTable("PlaylistUsers");
});
modelBuilder.Entity("Shadow.Entities.Radio", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Homepage")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("NormalizedName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text");
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique();
b.HasIndex("UserId");
b.ToTable("Radios");
});
modelBuilder.Entity("Shadow.Entities.Song", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AlbumId")
.HasColumnType("integer");
b.Property<int>("ArtistId")
.HasColumnType("integer");
b.Property<int?>("BitDepth")
.HasColumnType("integer");
b.Property<int>("Bitrate")
.HasColumnType("integer");
b.Property<int>("Channels")
.HasColumnType("integer");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<int?>("DiscNumber")
.HasColumnType("integer");
b.Property<int>("Duration")
.HasColumnType("integer");
b.Property<string>("Filepath")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Filetype")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("ImageId")
.HasColumnType("integer");
b.Property<int>("Index")
.HasColumnType("integer");
b.Property<int>("SamplingRate")
.HasColumnType("integer");
b.Property<int>("Size")
.HasColumnType("integer");
b.Property<int>("State")
.HasColumnType("integer");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("TrackNumber")
.HasColumnType("integer");
b.Property<string>("Uri")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AlbumId");
b.HasIndex("ArtistId");
b.HasIndex("Uri")
.IsUnique();
b.ToTable("Songs");
});
modelBuilder.Entity("Shadow.Entities.SongInteraction", b =>
{
b.Property<int>("SongId")
.HasColumnType("integer");
b.Property<int>("UserId")
.HasColumnType("integer");
b.Property<int>("Id")
.HasColumnType("integer");
b.Property<int>("PlayCount")
.HasColumnType("integer");
b.Property<int>("Rating")
.HasColumnType("integer");
b.Property<bool?>("Starred")
.HasColumnType("boolean");
b.HasKey("SongId", "UserId");
b.HasIndex("UserId");
b.ToTable("SongInteractions");
});
modelBuilder.Entity("Shadow.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("NormalizedName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Users");
});
modelBuilder.Entity("Shadow.Entities.Album", b =>
{
b.HasOne("Shadow.Entities.Artist", "Artist")
.WithMany("Albums")
.HasForeignKey("ArtistId");
b.Navigation("Artist");
});
modelBuilder.Entity("Shadow.Entities.AlbumInteraction", b =>
{
b.HasOne("Shadow.Entities.Album", "Album")
.WithMany()
.HasForeignKey("AlbumId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Shadow.Entities.User", "User")
.WithMany("AlbumInteractions")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Album");
b.Navigation("User");
});
modelBuilder.Entity("Shadow.Entities.GenreSong", b =>
{
b.HasOne("Shadow.Entities.Genre", "Genre")
.WithMany("GenreSongPair")
.HasForeignKey("GenreId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Shadow.Entities.Song", "Song")
.WithMany("GenreSongPair")
.HasForeignKey("SongId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Genre");
b.Navigation("Song");
});
modelBuilder.Entity("Shadow.Entities.Image", b =>
{
b.HasOne("Shadow.Entities.Song", "Song")
.WithOne("Image")
.HasForeignKey("Shadow.Entities.Image", "SongId");
b.Navigation("Song");
});
modelBuilder.Entity("Shadow.Entities.Playlist", b =>
{
b.HasOne("Shadow.Entities.User", "Creator")
.WithMany("Playlists")
.HasForeignKey("CreatorId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Creator");
});
modelBuilder.Entity("Shadow.Entities.PlaylistSong", b =>
{
b.HasOne("Shadow.Entities.Playlist", "Playlist")
.WithMany()
.HasForeignKey("PlaylistId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Shadow.Entities.Song", "Song")
.WithMany()
.HasForeignKey("SongId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Playlist");
b.Navigation("Song");
});
modelBuilder.Entity("Shadow.Entities.PlaylistUser", b =>
{
b.HasOne("Shadow.Entities.Playlist", "Playlist")
.WithMany("AuthorizedPlaylistUsers")
.HasForeignKey("PlaylistId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Shadow.Entities.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Playlist");
b.Navigation("User");
});
modelBuilder.Entity("Shadow.Entities.Radio", b =>
{
b.HasOne("Shadow.Entities.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("Shadow.Entities.Song", b =>
{
b.HasOne("Shadow.Entities.Album", "Album")
.WithMany("Songs")
.HasForeignKey("AlbumId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Shadow.Entities.Artist", "Artist")
.WithMany("Songs")
.HasForeignKey("ArtistId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Album");
b.Navigation("Artist");
});
modelBuilder.Entity("Shadow.Entities.SongInteraction", b =>
{
b.HasOne("Shadow.Entities.Song", "Song")
.WithMany()
.HasForeignKey("SongId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Shadow.Entities.User", "User")
.WithMany("SongInteractions")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Song");
b.Navigation("User");
});
modelBuilder.Entity("Shadow.Entities.Album", b =>
{
b.Navigation("Songs");
});
modelBuilder.Entity("Shadow.Entities.Artist", b =>
{
b.Navigation("Albums");
b.Navigation("Songs");
});
modelBuilder.Entity("Shadow.Entities.Genre", b =>
{
b.Navigation("GenreSongPair");
});
modelBuilder.Entity("Shadow.Entities.Playlist", b =>
{
b.Navigation("AuthorizedPlaylistUsers");
});
modelBuilder.Entity("Shadow.Entities.Song", b =>
{
b.Navigation("GenreSongPair");
b.Navigation("Image");
});
modelBuilder.Entity("Shadow.Entities.User", b =>
{
b.Navigation("AlbumInteractions");
b.Navigation("Playlists");
b.Navigation("SongInteractions");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,458 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Shadow.Migrations
{
/// <inheritdoc />
public partial class InitialMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Artists",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
NormalizedName = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Artists", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Genres",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
NormalizedName = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Genres", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
NormalizedName = table.Column<string>(type: "text", nullable: false),
Password = table.Column<string>(type: "text", nullable: false),
Role = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Albums",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
Uri = table.Column<string>(type: "text", nullable: false),
State = table.Column<int>(type: "integer", nullable: false),
ArtistId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Albums", x => x.Id);
table.ForeignKey(
name: "FK_Albums_Artists_ArtistId",
column: x => x.ArtistId,
principalTable: "Artists",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "Playlists",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
Uri = table.Column<string>(type: "text", nullable: false),
Description = table.Column<string>(type: "text", nullable: false),
CreatorId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Playlists", x => x.Id);
table.ForeignKey(
name: "FK_Playlists_Users_CreatorId",
column: x => x.CreatorId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Radios",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
NormalizedName = table.Column<string>(type: "text", nullable: false),
Homepage = table.Column<string>(type: "text", nullable: true),
Url = table.Column<string>(type: "text", nullable: false),
UserId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Radios", x => x.Id);
table.ForeignKey(
name: "FK_Radios_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AlbumInteractions",
columns: table => new
{
AlbumId = table.Column<int>(type: "integer", nullable: false),
UserId = table.Column<int>(type: "integer", nullable: false),
Id = table.Column<int>(type: "integer", nullable: false),
PlayDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
Starred = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AlbumInteractions", x => new { x.AlbumId, x.UserId });
table.ForeignKey(
name: "FK_AlbumInteractions_Albums_AlbumId",
column: x => x.AlbumId,
principalTable: "Albums",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AlbumInteractions_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Songs",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Title = table.Column<string>(type: "text", nullable: false),
Uri = table.Column<string>(type: "text", nullable: false),
Filepath = table.Column<string>(type: "text", nullable: false),
State = table.Column<int>(type: "integer", nullable: false),
Filetype = table.Column<string>(type: "text", nullable: false),
Date = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
Duration = table.Column<int>(type: "integer", nullable: false),
Bitrate = table.Column<int>(type: "integer", nullable: false),
Size = table.Column<int>(type: "integer", nullable: false),
Comment = table.Column<string>(type: "text", nullable: true),
Channels = table.Column<int>(type: "integer", nullable: false),
SamplingRate = table.Column<int>(type: "integer", nullable: false),
BitDepth = table.Column<int>(type: "integer", nullable: true),
Index = table.Column<int>(type: "integer", nullable: false),
TrackNumber = table.Column<int>(type: "integer", nullable: true),
DiscNumber = table.Column<int>(type: "integer", nullable: true),
AlbumId = table.Column<int>(type: "integer", nullable: false),
ArtistId = table.Column<int>(type: "integer", nullable: false),
ImageId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Songs", x => x.Id);
table.ForeignKey(
name: "FK_Songs_Albums_AlbumId",
column: x => x.AlbumId,
principalTable: "Albums",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Songs_Artists_ArtistId",
column: x => x.ArtistId,
principalTable: "Artists",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "PlaylistUsers",
columns: table => new
{
PlaylistId = table.Column<int>(type: "integer", nullable: false),
UserId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PlaylistUsers", x => new { x.PlaylistId, x.UserId });
table.ForeignKey(
name: "FK_PlaylistUsers_Playlists_PlaylistId",
column: x => x.PlaylistId,
principalTable: "Playlists",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_PlaylistUsers_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "GenreSongs",
columns: table => new
{
GenreId = table.Column<int>(type: "integer", nullable: false),
SongId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_GenreSongs", x => new { x.GenreId, x.SongId });
table.ForeignKey(
name: "FK_GenreSongs_Genres_GenreId",
column: x => x.GenreId,
principalTable: "Genres",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_GenreSongs_Songs_SongId",
column: x => x.SongId,
principalTable: "Songs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Images",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Uri = table.Column<string>(type: "text", nullable: false),
State = table.Column<int>(type: "integer", nullable: false),
SongId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Images", x => x.Id);
table.ForeignKey(
name: "FK_Images_Songs_SongId",
column: x => x.SongId,
principalTable: "Songs",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "PlaylistSongs",
columns: table => new
{
PlaylistId = table.Column<int>(type: "integer", nullable: false),
SongId = table.Column<int>(type: "integer", nullable: false),
Index = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PlaylistSongs", x => new { x.PlaylistId, x.SongId });
table.ForeignKey(
name: "FK_PlaylistSongs_Playlists_PlaylistId",
column: x => x.PlaylistId,
principalTable: "Playlists",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_PlaylistSongs_Songs_SongId",
column: x => x.SongId,
principalTable: "Songs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "SongInteractions",
columns: table => new
{
SongId = table.Column<int>(type: "integer", nullable: false),
UserId = table.Column<int>(type: "integer", nullable: false),
Id = table.Column<int>(type: "integer", nullable: false),
PlayCount = table.Column<int>(type: "integer", nullable: false),
Starred = table.Column<bool>(type: "boolean", nullable: true),
Rating = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_SongInteractions", x => new { x.SongId, x.UserId });
table.ForeignKey(
name: "FK_SongInteractions_Songs_SongId",
column: x => x.SongId,
principalTable: "Songs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_SongInteractions_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AlbumInteractions_UserId",
table: "AlbumInteractions",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Albums_ArtistId",
table: "Albums",
column: "ArtistId");
migrationBuilder.CreateIndex(
name: "IX_Albums_Uri",
table: "Albums",
column: "Uri",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Artists_NormalizedName",
table: "Artists",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Genres_NormalizedName",
table: "Genres",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_GenreSongs_SongId",
table: "GenreSongs",
column: "SongId");
migrationBuilder.CreateIndex(
name: "IX_Images_SongId",
table: "Images",
column: "SongId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Playlists_CreatorId",
table: "Playlists",
column: "CreatorId");
migrationBuilder.CreateIndex(
name: "IX_Playlists_Uri",
table: "Playlists",
column: "Uri",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_PlaylistSongs_SongId",
table: "PlaylistSongs",
column: "SongId");
migrationBuilder.CreateIndex(
name: "IX_PlaylistUsers_UserId",
table: "PlaylistUsers",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Radios_NormalizedName",
table: "Radios",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Radios_UserId",
table: "Radios",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_SongInteractions_UserId",
table: "SongInteractions",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Songs_AlbumId",
table: "Songs",
column: "AlbumId");
migrationBuilder.CreateIndex(
name: "IX_Songs_ArtistId",
table: "Songs",
column: "ArtistId");
migrationBuilder.CreateIndex(
name: "IX_Songs_Uri",
table: "Songs",
column: "Uri",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Users_Name",
table: "Users",
column: "Name",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AlbumInteractions");
migrationBuilder.DropTable(
name: "GenreSongs");
migrationBuilder.DropTable(
name: "Images");
migrationBuilder.DropTable(
name: "PlaylistSongs");
migrationBuilder.DropTable(
name: "PlaylistUsers");
migrationBuilder.DropTable(
name: "Radios");
migrationBuilder.DropTable(
name: "SongInteractions");
migrationBuilder.DropTable(
name: "Genres");
migrationBuilder.DropTable(
name: "Playlists");
migrationBuilder.DropTable(
name: "Songs");
migrationBuilder.DropTable(
name: "Users");
migrationBuilder.DropTable(
name: "Albums");
migrationBuilder.DropTable(
name: "Artists");
}
}
}

View File

@@ -0,0 +1,635 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Shadow.Data;
#nullable disable
namespace Shadow.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20251216025633_InitialMigration")]
partial class InitialMigration
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.1")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Shadow.Entities.Album", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("ArtistId")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("State")
.HasColumnType("integer");
b.Property<string>("Uri")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("ArtistId");
b.HasIndex("Uri")
.IsUnique();
b.ToTable("Albums");
});
modelBuilder.Entity("Shadow.Entities.AlbumInteraction", b =>
{
b.Property<int>("AlbumId")
.HasColumnType("integer");
b.Property<int>("UserId")
.HasColumnType("integer");
b.Property<int>("Id")
.HasColumnType("integer");
b.Property<DateTime?>("PlayDate")
.HasColumnType("timestamp with time zone");
b.Property<bool>("Starred")
.HasColumnType("boolean");
b.HasKey("AlbumId", "UserId");
b.HasIndex("UserId");
b.ToTable("AlbumInteractions");
});
modelBuilder.Entity("Shadow.Entities.Artist", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("NormalizedName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique();
b.ToTable("Artists");
});
modelBuilder.Entity("Shadow.Entities.Genre", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("NormalizedName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique();
b.ToTable("Genres");
});
modelBuilder.Entity("Shadow.Entities.GenreSong", b =>
{
b.Property<int>("GenreId")
.HasColumnType("integer");
b.Property<int>("SongId")
.HasColumnType("integer");
b.HasKey("GenreId", "SongId");
b.HasIndex("SongId");
b.ToTable("GenreSongs");
});
modelBuilder.Entity("Shadow.Entities.Global", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Key")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Value")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Key")
.IsUnique();
b.ToTable("Globals");
});
modelBuilder.Entity("Shadow.Entities.Image", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Filetype")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("SongId")
.HasColumnType("integer");
b.Property<int>("State")
.HasColumnType("integer");
b.Property<string>("Uri")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("SongId")
.IsUnique();
b.ToTable("Images");
});
modelBuilder.Entity("Shadow.Entities.Playlist", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("CreatorId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Uri")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("CreatorId");
b.HasIndex("Uri")
.IsUnique();
b.ToTable("Playlists");
});
modelBuilder.Entity("Shadow.Entities.PlaylistSong", b =>
{
b.Property<int>("PlaylistId")
.HasColumnType("integer");
b.Property<int>("SongId")
.HasColumnType("integer");
b.Property<int>("Index")
.HasColumnType("integer");
b.HasKey("PlaylistId", "SongId");
b.HasIndex("SongId");
b.ToTable("PlaylistSongs");
});
modelBuilder.Entity("Shadow.Entities.PlaylistUser", b =>
{
b.Property<int>("PlaylistId")
.HasColumnType("integer");
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("PlaylistId", "UserId");
b.HasIndex("UserId");
b.ToTable("PlaylistUsers");
});
modelBuilder.Entity("Shadow.Entities.Radio", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Homepage")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("NormalizedName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text");
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique();
b.HasIndex("UserId");
b.ToTable("Radios");
});
modelBuilder.Entity("Shadow.Entities.Song", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AlbumId")
.HasColumnType("integer");
b.Property<int>("ArtistId")
.HasColumnType("integer");
b.Property<int?>("BitDepth")
.HasColumnType("integer");
b.Property<int>("Bitrate")
.HasColumnType("integer");
b.Property<int>("Channels")
.HasColumnType("integer");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<int?>("DiscNumber")
.HasColumnType("integer");
b.Property<int>("Duration")
.HasColumnType("integer");
b.Property<string>("Filepath")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Filetype")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("ImageId")
.HasColumnType("integer");
b.Property<int>("Index")
.HasColumnType("integer");
b.Property<int>("SamplingRate")
.HasColumnType("integer");
b.Property<int>("Size")
.HasColumnType("integer");
b.Property<int>("State")
.HasColumnType("integer");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("TrackNumber")
.HasColumnType("integer");
b.Property<string>("Uri")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AlbumId");
b.HasIndex("ArtistId");
b.HasIndex("Uri")
.IsUnique();
b.ToTable("Songs");
});
modelBuilder.Entity("Shadow.Entities.SongInteraction", b =>
{
b.Property<int>("SongId")
.HasColumnType("integer");
b.Property<int>("UserId")
.HasColumnType("integer");
b.Property<int>("Id")
.HasColumnType("integer");
b.Property<int>("PlayCount")
.HasColumnType("integer");
b.Property<int>("Rating")
.HasColumnType("integer");
b.Property<bool?>("Starred")
.HasColumnType("boolean");
b.HasKey("SongId", "UserId");
b.HasIndex("UserId");
b.ToTable("SongInteractions");
});
modelBuilder.Entity("Shadow.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("NormalizedName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Users");
});
modelBuilder.Entity("Shadow.Entities.Album", b =>
{
b.HasOne("Shadow.Entities.Artist", "Artist")
.WithMany("Albums")
.HasForeignKey("ArtistId");
b.Navigation("Artist");
});
modelBuilder.Entity("Shadow.Entities.AlbumInteraction", b =>
{
b.HasOne("Shadow.Entities.Album", "Album")
.WithMany()
.HasForeignKey("AlbumId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Shadow.Entities.User", "User")
.WithMany("AlbumInteractions")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Album");
b.Navigation("User");
});
modelBuilder.Entity("Shadow.Entities.GenreSong", b =>
{
b.HasOne("Shadow.Entities.Genre", "Genre")
.WithMany("GenreSongPair")
.HasForeignKey("GenreId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Shadow.Entities.Song", "Song")
.WithMany("GenreSongPair")
.HasForeignKey("SongId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Genre");
b.Navigation("Song");
});
modelBuilder.Entity("Shadow.Entities.Image", b =>
{
b.HasOne("Shadow.Entities.Song", "Song")
.WithOne("Image")
.HasForeignKey("Shadow.Entities.Image", "SongId");
b.Navigation("Song");
});
modelBuilder.Entity("Shadow.Entities.Playlist", b =>
{
b.HasOne("Shadow.Entities.User", "Creator")
.WithMany("Playlists")
.HasForeignKey("CreatorId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Creator");
});
modelBuilder.Entity("Shadow.Entities.PlaylistSong", b =>
{
b.HasOne("Shadow.Entities.Playlist", "Playlist")
.WithMany()
.HasForeignKey("PlaylistId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Shadow.Entities.Song", "Song")
.WithMany()
.HasForeignKey("SongId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Playlist");
b.Navigation("Song");
});
modelBuilder.Entity("Shadow.Entities.PlaylistUser", b =>
{
b.HasOne("Shadow.Entities.Playlist", "Playlist")
.WithMany("AuthorizedPlaylistUsers")
.HasForeignKey("PlaylistId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Shadow.Entities.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Playlist");
b.Navigation("User");
});
modelBuilder.Entity("Shadow.Entities.Radio", b =>
{
b.HasOne("Shadow.Entities.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("Shadow.Entities.Song", b =>
{
b.HasOne("Shadow.Entities.Album", "Album")
.WithMany("Songs")
.HasForeignKey("AlbumId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Shadow.Entities.Artist", "Artist")
.WithMany("Songs")
.HasForeignKey("ArtistId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Album");
b.Navigation("Artist");
});
modelBuilder.Entity("Shadow.Entities.SongInteraction", b =>
{
b.HasOne("Shadow.Entities.Song", "Song")
.WithMany()
.HasForeignKey("SongId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Shadow.Entities.User", "User")
.WithMany("SongInteractions")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Song");
b.Navigation("User");
});
modelBuilder.Entity("Shadow.Entities.Album", b =>
{
b.Navigation("Songs");
});
modelBuilder.Entity("Shadow.Entities.Artist", b =>
{
b.Navigation("Albums");
b.Navigation("Songs");
});
modelBuilder.Entity("Shadow.Entities.Genre", b =>
{
b.Navigation("GenreSongPair");
});
modelBuilder.Entity("Shadow.Entities.Playlist", b =>
{
b.Navigation("AuthorizedPlaylistUsers");
});
modelBuilder.Entity("Shadow.Entities.Song", b =>
{
b.Navigation("GenreSongPair");
b.Navigation("Image");
});
modelBuilder.Entity("Shadow.Entities.User", b =>
{
b.Navigation("AlbumInteractions");
b.Navigation("Playlists");
b.Navigation("SongInteractions");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,482 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Shadow.Migrations
{
/// <inheritdoc />
public partial class InitialMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Artists",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
NormalizedName = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Artists", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Genres",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
NormalizedName = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Genres", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Globals",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Key = table.Column<string>(type: "text", nullable: false),
Value = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Globals", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
NormalizedName = table.Column<string>(type: "text", nullable: false),
Password = table.Column<string>(type: "text", nullable: false),
Role = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Albums",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
Uri = table.Column<string>(type: "text", nullable: false),
State = table.Column<int>(type: "integer", nullable: false),
ArtistId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Albums", x => x.Id);
table.ForeignKey(
name: "FK_Albums_Artists_ArtistId",
column: x => x.ArtistId,
principalTable: "Artists",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "Playlists",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
Uri = table.Column<string>(type: "text", nullable: false),
Description = table.Column<string>(type: "text", nullable: false),
CreatorId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Playlists", x => x.Id);
table.ForeignKey(
name: "FK_Playlists_Users_CreatorId",
column: x => x.CreatorId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Radios",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
NormalizedName = table.Column<string>(type: "text", nullable: false),
Homepage = table.Column<string>(type: "text", nullable: true),
Url = table.Column<string>(type: "text", nullable: false),
UserId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Radios", x => x.Id);
table.ForeignKey(
name: "FK_Radios_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AlbumInteractions",
columns: table => new
{
AlbumId = table.Column<int>(type: "integer", nullable: false),
UserId = table.Column<int>(type: "integer", nullable: false),
Id = table.Column<int>(type: "integer", nullable: false),
PlayDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
Starred = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AlbumInteractions", x => new { x.AlbumId, x.UserId });
table.ForeignKey(
name: "FK_AlbumInteractions_Albums_AlbumId",
column: x => x.AlbumId,
principalTable: "Albums",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AlbumInteractions_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Songs",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Title = table.Column<string>(type: "text", nullable: false),
Uri = table.Column<string>(type: "text", nullable: false),
Filepath = table.Column<string>(type: "text", nullable: false),
State = table.Column<int>(type: "integer", nullable: false),
Filetype = table.Column<string>(type: "text", nullable: false),
Date = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
Duration = table.Column<int>(type: "integer", nullable: false),
Bitrate = table.Column<int>(type: "integer", nullable: false),
Size = table.Column<int>(type: "integer", nullable: false),
Comment = table.Column<string>(type: "text", nullable: true),
Channels = table.Column<int>(type: "integer", nullable: false),
SamplingRate = table.Column<int>(type: "integer", nullable: false),
BitDepth = table.Column<int>(type: "integer", nullable: true),
Index = table.Column<int>(type: "integer", nullable: false),
TrackNumber = table.Column<int>(type: "integer", nullable: true),
DiscNumber = table.Column<int>(type: "integer", nullable: true),
AlbumId = table.Column<int>(type: "integer", nullable: false),
ArtistId = table.Column<int>(type: "integer", nullable: false),
ImageId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Songs", x => x.Id);
table.ForeignKey(
name: "FK_Songs_Albums_AlbumId",
column: x => x.AlbumId,
principalTable: "Albums",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Songs_Artists_ArtistId",
column: x => x.ArtistId,
principalTable: "Artists",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "PlaylistUsers",
columns: table => new
{
PlaylistId = table.Column<int>(type: "integer", nullable: false),
UserId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PlaylistUsers", x => new { x.PlaylistId, x.UserId });
table.ForeignKey(
name: "FK_PlaylistUsers_Playlists_PlaylistId",
column: x => x.PlaylistId,
principalTable: "Playlists",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_PlaylistUsers_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "GenreSongs",
columns: table => new
{
GenreId = table.Column<int>(type: "integer", nullable: false),
SongId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_GenreSongs", x => new { x.GenreId, x.SongId });
table.ForeignKey(
name: "FK_GenreSongs_Genres_GenreId",
column: x => x.GenreId,
principalTable: "Genres",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_GenreSongs_Songs_SongId",
column: x => x.SongId,
principalTable: "Songs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Images",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Uri = table.Column<string>(type: "text", nullable: false),
Filetype = table.Column<string>(type: "text", nullable: false),
State = table.Column<int>(type: "integer", nullable: false),
SongId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Images", x => x.Id);
table.ForeignKey(
name: "FK_Images_Songs_SongId",
column: x => x.SongId,
principalTable: "Songs",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "PlaylistSongs",
columns: table => new
{
PlaylistId = table.Column<int>(type: "integer", nullable: false),
SongId = table.Column<int>(type: "integer", nullable: false),
Index = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PlaylistSongs", x => new { x.PlaylistId, x.SongId });
table.ForeignKey(
name: "FK_PlaylistSongs_Playlists_PlaylistId",
column: x => x.PlaylistId,
principalTable: "Playlists",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_PlaylistSongs_Songs_SongId",
column: x => x.SongId,
principalTable: "Songs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "SongInteractions",
columns: table => new
{
SongId = table.Column<int>(type: "integer", nullable: false),
UserId = table.Column<int>(type: "integer", nullable: false),
Id = table.Column<int>(type: "integer", nullable: false),
PlayCount = table.Column<int>(type: "integer", nullable: false),
Starred = table.Column<bool>(type: "boolean", nullable: true),
Rating = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_SongInteractions", x => new { x.SongId, x.UserId });
table.ForeignKey(
name: "FK_SongInteractions_Songs_SongId",
column: x => x.SongId,
principalTable: "Songs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_SongInteractions_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AlbumInteractions_UserId",
table: "AlbumInteractions",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Albums_ArtistId",
table: "Albums",
column: "ArtistId");
migrationBuilder.CreateIndex(
name: "IX_Albums_Uri",
table: "Albums",
column: "Uri",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Artists_NormalizedName",
table: "Artists",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Genres_NormalizedName",
table: "Genres",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_GenreSongs_SongId",
table: "GenreSongs",
column: "SongId");
migrationBuilder.CreateIndex(
name: "IX_Globals_Key",
table: "Globals",
column: "Key",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Images_SongId",
table: "Images",
column: "SongId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Playlists_CreatorId",
table: "Playlists",
column: "CreatorId");
migrationBuilder.CreateIndex(
name: "IX_Playlists_Uri",
table: "Playlists",
column: "Uri",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_PlaylistSongs_SongId",
table: "PlaylistSongs",
column: "SongId");
migrationBuilder.CreateIndex(
name: "IX_PlaylistUsers_UserId",
table: "PlaylistUsers",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Radios_NormalizedName",
table: "Radios",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Radios_UserId",
table: "Radios",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_SongInteractions_UserId",
table: "SongInteractions",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Songs_AlbumId",
table: "Songs",
column: "AlbumId");
migrationBuilder.CreateIndex(
name: "IX_Songs_ArtistId",
table: "Songs",
column: "ArtistId");
migrationBuilder.CreateIndex(
name: "IX_Songs_Uri",
table: "Songs",
column: "Uri",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Users_Name",
table: "Users",
column: "Name",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AlbumInteractions");
migrationBuilder.DropTable(
name: "GenreSongs");
migrationBuilder.DropTable(
name: "Globals");
migrationBuilder.DropTable(
name: "Images");
migrationBuilder.DropTable(
name: "PlaylistSongs");
migrationBuilder.DropTable(
name: "PlaylistUsers");
migrationBuilder.DropTable(
name: "Radios");
migrationBuilder.DropTable(
name: "SongInteractions");
migrationBuilder.DropTable(
name: "Genres");
migrationBuilder.DropTable(
name: "Playlists");
migrationBuilder.DropTable(
name: "Songs");
migrationBuilder.DropTable(
name: "Users");
migrationBuilder.DropTable(
name: "Albums");
migrationBuilder.DropTable(
name: "Artists");
}
}
}

File diff suppressed because it is too large Load Diff