From 0e37cbf71243126851632bc00389f851ad139b90 Mon Sep 17 00:00:00 2001 From: daniel-c-harvey Date: Sat, 30 Aug 2025 21:48:21 -0400 Subject: [PATCH] Inital DeepDrftWeb Entity Framework setup - DeepDrft DbContext - Inital Migration for Track Entity model - Track Repository - Full CRUD --- .../Data/Configurations/TrackConfiguration.cs | 49 ++++++++++++ .../DeepDrftWeb/Data/DeepDrftContext.cs | 21 +++++ .../Data/DeepDrftContextFactory.cs | 24 ++++++ .../20250831000622_Initial.Designer.cs | 74 ++++++++++++++++++ .../Data/Migrations/20250831000622_Initial.cs | 41 ++++++++++ .../DeepDrftContextModelSnapshot.cs | 71 +++++++++++++++++ .../Data/Repositories/TrackRepository.cs | 76 +++++++++++++++++++ 7 files changed, 356 insertions(+) create mode 100644 DeepDrftWeb/DeepDrftWeb/Data/Configurations/TrackConfiguration.cs create mode 100644 DeepDrftWeb/DeepDrftWeb/Data/DeepDrftContext.cs create mode 100644 DeepDrftWeb/DeepDrftWeb/Data/DeepDrftContextFactory.cs create mode 100644 DeepDrftWeb/DeepDrftWeb/Data/Migrations/20250831000622_Initial.Designer.cs create mode 100644 DeepDrftWeb/DeepDrftWeb/Data/Migrations/20250831000622_Initial.cs create mode 100644 DeepDrftWeb/DeepDrftWeb/Data/Migrations/DeepDrftContextModelSnapshot.cs create mode 100644 DeepDrftWeb/DeepDrftWeb/Data/Repositories/TrackRepository.cs diff --git a/DeepDrftWeb/DeepDrftWeb/Data/Configurations/TrackConfiguration.cs b/DeepDrftWeb/DeepDrftWeb/Data/Configurations/TrackConfiguration.cs new file mode 100644 index 0000000..2286f7a --- /dev/null +++ b/DeepDrftWeb/DeepDrftWeb/Data/Configurations/TrackConfiguration.cs @@ -0,0 +1,49 @@ +using DeepDrftModels.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace DeepDrftWeb.Data.Configurations; + +public class TrackConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("track"); + + builder.HasKey(x => x.Id); + + builder.Property(x => x.Id) + .HasColumnName("id") + .IsRequired(); + + builder.Property(x => x.MediaPath) + .HasColumnName("media_path") + .IsRequired() + .HasMaxLength(500); + + builder.Property(x => x.TrackName) + .HasColumnName("track_name") + .IsRequired() + .HasMaxLength(200); + + builder.Property(x => x.Artist) + .HasColumnName("artist") + .IsRequired() + .HasMaxLength(200); + + builder.Property(x => x.Album) + .HasColumnName("album") + .HasMaxLength(200); + + builder.Property(x => x.Genre) + .HasColumnName("genre") + .HasMaxLength(100); + + builder.Property(x => x.ReleaseDate) + .HasColumnName("release_date"); + + builder.Property(x => x.ImagePath) + .HasColumnName("image_path") + .HasMaxLength(500); + } +} \ No newline at end of file diff --git a/DeepDrftWeb/DeepDrftWeb/Data/DeepDrftContext.cs b/DeepDrftWeb/DeepDrftWeb/Data/DeepDrftContext.cs new file mode 100644 index 0000000..0f40498 --- /dev/null +++ b/DeepDrftWeb/DeepDrftWeb/Data/DeepDrftContext.cs @@ -0,0 +1,21 @@ +using DeepDrftModels.Entities; +using DeepDrftWeb.Data.Configurations; +using Microsoft.EntityFrameworkCore; + +namespace DeepDrftWeb.Data; + +public class DeepDrftContext : DbContext +{ + public DeepDrftContext(DbContextOptions options) : base(options) + { + } + + public DbSet Tracks { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.ApplyConfiguration(new TrackConfiguration()); + } +} \ No newline at end of file diff --git a/DeepDrftWeb/DeepDrftWeb/Data/DeepDrftContextFactory.cs b/DeepDrftWeb/DeepDrftWeb/Data/DeepDrftContextFactory.cs new file mode 100644 index 0000000..f60571b --- /dev/null +++ b/DeepDrftWeb/DeepDrftWeb/Data/DeepDrftContextFactory.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; + +namespace DeepDrftWeb.Data; + +public static class DeepDrftContextFactory +{ + public class Factory : IDesignTimeDbContextFactory + { + public DeepDrftContext CreateDbContext(string[] args) + { + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: true) + .Build(); + + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlite(configuration.GetConnectionString("DefaultConnection")); + + return new DeepDrftContext(optionsBuilder.Options); + } + } +} \ No newline at end of file diff --git a/DeepDrftWeb/DeepDrftWeb/Data/Migrations/20250831000622_Initial.Designer.cs b/DeepDrftWeb/DeepDrftWeb/Data/Migrations/20250831000622_Initial.Designer.cs new file mode 100644 index 0000000..30bb5df --- /dev/null +++ b/DeepDrftWeb/DeepDrftWeb/Data/Migrations/20250831000622_Initial.Designer.cs @@ -0,0 +1,74 @@ +// +using System; +using DeepDrftWeb.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DeepDrftWeb.Data.Migrations +{ + [DbContext(typeof(DeepDrftContext))] + [Migration("20250831000622_Initial")] + partial class Initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.8"); + + modelBuilder.Entity("DeepDrftModels.Entities.TrackEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("Album") + .HasMaxLength(200) + .HasColumnType("TEXT") + .HasColumnName("album"); + + b.Property("Artist") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT") + .HasColumnName("artist"); + + b.Property("Genre") + .HasMaxLength(100) + .HasColumnType("TEXT") + .HasColumnName("genre"); + + b.Property("ImagePath") + .HasMaxLength(500) + .HasColumnType("TEXT") + .HasColumnName("image_path"); + + b.Property("MediaPath") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT") + .HasColumnName("media_path"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT") + .HasColumnName("release_date"); + + b.Property("TrackName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT") + .HasColumnName("track_name"); + + b.HasKey("Id"); + + b.ToTable("track", (string)null); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DeepDrftWeb/DeepDrftWeb/Data/Migrations/20250831000622_Initial.cs b/DeepDrftWeb/DeepDrftWeb/Data/Migrations/20250831000622_Initial.cs new file mode 100644 index 0000000..686709b --- /dev/null +++ b/DeepDrftWeb/DeepDrftWeb/Data/Migrations/20250831000622_Initial.cs @@ -0,0 +1,41 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DeepDrftWeb.Data.Migrations +{ + /// + public partial class Initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "track", + columns: table => new + { + id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + media_path = table.Column(type: "TEXT", maxLength: 500, nullable: false), + track_name = table.Column(type: "TEXT", maxLength: 200, nullable: false), + artist = table.Column(type: "TEXT", maxLength: 200, nullable: false), + album = table.Column(type: "TEXT", maxLength: 200, nullable: true), + genre = table.Column(type: "TEXT", maxLength: 100, nullable: true), + release_date = table.Column(type: "TEXT", nullable: true), + image_path = table.Column(type: "TEXT", maxLength: 500, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_track", x => x.id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "track"); + } + } +} diff --git a/DeepDrftWeb/DeepDrftWeb/Data/Migrations/DeepDrftContextModelSnapshot.cs b/DeepDrftWeb/DeepDrftWeb/Data/Migrations/DeepDrftContextModelSnapshot.cs new file mode 100644 index 0000000..43167ad --- /dev/null +++ b/DeepDrftWeb/DeepDrftWeb/Data/Migrations/DeepDrftContextModelSnapshot.cs @@ -0,0 +1,71 @@ +// +using System; +using DeepDrftWeb.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DeepDrftWeb.Data.Migrations +{ + [DbContext(typeof(DeepDrftContext))] + partial class DeepDrftContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.8"); + + modelBuilder.Entity("DeepDrftModels.Entities.TrackEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("Album") + .HasMaxLength(200) + .HasColumnType("TEXT") + .HasColumnName("album"); + + b.Property("Artist") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT") + .HasColumnName("artist"); + + b.Property("Genre") + .HasMaxLength(100) + .HasColumnType("TEXT") + .HasColumnName("genre"); + + b.Property("ImagePath") + .HasMaxLength(500) + .HasColumnType("TEXT") + .HasColumnName("image_path"); + + b.Property("MediaPath") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT") + .HasColumnName("media_path"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT") + .HasColumnName("release_date"); + + b.Property("TrackName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT") + .HasColumnName("track_name"); + + b.HasKey("Id"); + + b.ToTable("track", (string)null); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DeepDrftWeb/DeepDrftWeb/Data/Repositories/TrackRepository.cs b/DeepDrftWeb/DeepDrftWeb/Data/Repositories/TrackRepository.cs new file mode 100644 index 0000000..d0a13f6 --- /dev/null +++ b/DeepDrftWeb/DeepDrftWeb/Data/Repositories/TrackRepository.cs @@ -0,0 +1,76 @@ +using DeepDrftModels.Entities; +using DeepDrftModels.Models; +using Microsoft.EntityFrameworkCore; + +namespace DeepDrftWeb.Data.Repositories; + +public class TrackRepository +{ + private readonly DeepDrftContext _db; + + public TrackRepository(DeepDrftContext db) + { + _db = db; + } + + public async Task GetById(long id) + { + return await _db.Tracks.FindAsync(id); + } + + public async Task> GetAll() + { + return await _db.Tracks.ToListAsync(); + } + + public async Task> GetPage(PagingParameters pageParameters) + { + var count = await _db.Tracks.CountAsync(); + + var page = await _db.Tracks + .OrderBy(pageParameters.OrderBy ?? (t => t.Id)) + .Skip((pageParameters.Page - 1) * pageParameters.PageSize) + .Take(pageParameters.PageSize) + .ToListAsync(); + + return new PagedResult(page, count, pageParameters.Page, pageParameters.PageSize); + } + + public async Task Create(TrackEntity newTrack) + { + var track = _db.Tracks.Add(newTrack); + await _db.SaveChangesAsync(); + return track.Entity; + } + + public async Task Update(TrackEntity track) + { + var trackEntity = await GetById(track.Id); + + if (trackEntity == null) + { + return await Create(track); + } + + trackEntity.Album = track.Album; + trackEntity.Artist = track.Artist; + trackEntity.Genre = track.Genre; + trackEntity.ImagePath = track.ImagePath; + trackEntity.MediaPath = track.MediaPath; + trackEntity.ReleaseDate = track.ReleaseDate; + trackEntity.TrackName = track.TrackName; + + await _db.SaveChangesAsync(); + return trackEntity; + } + + public async Task Delete(long id) + { + var track = await GetById(id); + if (track != null) + { + _db.Tracks.Remove(track); + await _db.SaveChangesAsync(); + } + } +} \ No newline at end of file