From 4ee545e4bb950422a84c7fa1cbd7ec21508e10c4 Mon Sep 17 00:00:00 2001 From: Dominic Maas Date: Mon, 10 Jul 2023 21:17:55 +1200 Subject: [PATCH] Quick and dirty database support --- src/Website/Common/DatabaseContext.cs | 16 ++++++++ .../20230710082646_InitialCreate.Designer.cs | 37 +++++++++++++++++++ .../20230710082646_InitialCreate.cs | 33 +++++++++++++++++ .../DatabaseContextModelSnapshot.cs | 34 +++++++++++++++++ src/Website/Models/Database/ShortLink.cs | 10 +++++ src/Website/Pages/Fw.cshtml.cs | 23 +++++------- src/Website/Program.cs | 17 +++++++++ src/Website/Website.csproj | 5 +++ src/Website/appsettings.Development.json | 3 ++ 9 files changed, 165 insertions(+), 13 deletions(-) create mode 100644 src/Website/Common/DatabaseContext.cs create mode 100644 src/Website/Migrations/20230710082646_InitialCreate.Designer.cs create mode 100644 src/Website/Migrations/20230710082646_InitialCreate.cs create mode 100644 src/Website/Migrations/DatabaseContextModelSnapshot.cs create mode 100644 src/Website/Models/Database/ShortLink.cs diff --git a/src/Website/Common/DatabaseContext.cs b/src/Website/Common/DatabaseContext.cs new file mode 100644 index 00000000..303d0425 --- /dev/null +++ b/src/Website/Common/DatabaseContext.cs @@ -0,0 +1,16 @@ +using Microsoft.EntityFrameworkCore; +using Website.Models.Database; + +namespace Website.Common; + +public class DatabaseContext : DbContext +{ + public DbSet ShortLinks { get; set; } + + public DatabaseContext() + { } + + public DatabaseContext(DbContextOptions options) : base(options) + { + } +} diff --git a/src/Website/Migrations/20230710082646_InitialCreate.Designer.cs b/src/Website/Migrations/20230710082646_InitialCreate.Designer.cs new file mode 100644 index 00000000..6f9497d7 --- /dev/null +++ b/src/Website/Migrations/20230710082646_InitialCreate.Designer.cs @@ -0,0 +1,37 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Website.Common; + +#nullable disable + +namespace Website.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20230710082646_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.8"); + + modelBuilder.Entity("Website.Models.Database.ShortLink", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("RedirectLink") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ShortLinks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Website/Migrations/20230710082646_InitialCreate.cs b/src/Website/Migrations/20230710082646_InitialCreate.cs new file mode 100644 index 00000000..0e625d04 --- /dev/null +++ b/src/Website/Migrations/20230710082646_InitialCreate.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Website.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "ShortLinks", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + RedirectLink = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ShortLinks", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ShortLinks"); + } + } +} diff --git a/src/Website/Migrations/DatabaseContextModelSnapshot.cs b/src/Website/Migrations/DatabaseContextModelSnapshot.cs new file mode 100644 index 00000000..1fd46b15 --- /dev/null +++ b/src/Website/Migrations/DatabaseContextModelSnapshot.cs @@ -0,0 +1,34 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Website.Common; + +#nullable disable + +namespace Website.Migrations +{ + [DbContext(typeof(DatabaseContext))] + partial class DatabaseContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.8"); + + modelBuilder.Entity("Website.Models.Database.ShortLink", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("RedirectLink") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ShortLinks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Website/Models/Database/ShortLink.cs b/src/Website/Models/Database/ShortLink.cs new file mode 100644 index 00000000..04a721c8 --- /dev/null +++ b/src/Website/Models/Database/ShortLink.cs @@ -0,0 +1,10 @@ +#nullable disable + +namespace Website.Models.Database; + +public class ShortLink +{ + public string Id { get; set; } + + public string RedirectLink { get; set; } +} diff --git a/src/Website/Pages/Fw.cshtml.cs b/src/Website/Pages/Fw.cshtml.cs index 065a6174..875b032f 100644 --- a/src/Website/Pages/Fw.cshtml.cs +++ b/src/Website/Pages/Fw.cshtml.cs @@ -1,27 +1,24 @@ using Microsoft.AspNetCore.Mvc.RazorPages; +using Website.Common; namespace Website.Pages; public class FwModel : PageModel { + private readonly DatabaseContext _databaseContext; + public string? RequestedUri { get; set; } public string? Message { get; set; } public bool IsSuccess { get; set; } - private readonly Dictionary _links = new() + public FwModel(DatabaseContext databaseContext) { - { "4toUN4j53iK", "https://github.com/DominicMaas/SpaceChunks" }, - { "yENyTb", "https://twitter.com/SoundByteUWP" }, - { "Y5jGLtoFXs", "https://dominicmaas.co.nz/privacy" }, - { "GvC5iXmJSo", "https://dominicmaas.co.nz/projects/soundbyte" }, - - { "github", "https://github.com/DominicMaas" }, - { "twitter", "https://twitter.com/dominicjmaas" } - }; + _databaseContext = databaseContext; + } - public void OnGet(string? id) + public async Task OnGetAsync(string? id) { if (string.IsNullOrEmpty(id)) { @@ -31,9 +28,9 @@ public void OnGet(string? id) return; } - var url = _links.GetValueOrDefault(id); + var link = await _databaseContext.ShortLinks.FindAsync(id); - if (string.IsNullOrEmpty(url)) + if (link == null || string.IsNullOrEmpty(link.RedirectLink)) { // This URI does not exist RequestedUri = string.Empty; @@ -42,7 +39,7 @@ public void OnGet(string? id) return; } - RequestedUri = url; + RequestedUri = link.RedirectLink; IsSuccess = true; } } diff --git a/src/Website/Program.cs b/src/Website/Program.cs index ec7f93dc..a5e77658 100644 --- a/src/Website/Program.cs +++ b/src/Website/Program.cs @@ -3,6 +3,7 @@ using Azure.Security.KeyVault.Secrets; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Mvc.ApplicationModels; +using Microsoft.EntityFrameworkCore; using Website.Common; using Website.Services; @@ -34,6 +35,10 @@ }); } +// Database +services.AddDbContext(options => + options.UseSqlite(config.GetConnectionString("WebsiteDatabase"))); + services.AddMvc(); // Services @@ -61,6 +66,10 @@ app.UseExceptionHandler("/error/500"); app.UseHsts(); } +else +{ + app.UseDeveloperExceptionPage(); +} app.UseStatusCodePagesWithReExecute("/error/{0}"); @@ -84,4 +93,12 @@ await next(); }); + +// Run our migrations on start up +using (var serviceScope = app.Services.GetService()!.CreateScope()) +{ + var context = serviceScope.ServiceProvider.GetRequiredService(); + context.Database.Migrate(); +} + app.Run(); \ No newline at end of file diff --git a/src/Website/Website.csproj b/src/Website/Website.csproj index 4a0a3d9b..ddb6525a 100644 --- a/src/Website/Website.csproj +++ b/src/Website/Website.csproj @@ -15,6 +15,11 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/src/Website/appsettings.Development.json b/src/Website/appsettings.Development.json index e203e940..4fe4483f 100644 --- a/src/Website/appsettings.Development.json +++ b/src/Website/appsettings.Development.json @@ -5,5 +5,8 @@ "System": "Information", "Microsoft": "Information" } + }, + "ConnectionStrings": { + "WebsiteDatabase": "Data Source=local.db" } }