From d3b49239060111b9244413d2cee8b0d7147abb5e Mon Sep 17 00:00:00 2001 From: Pj Metz <65838556+MetzinAround@users.noreply.github.com> Date: Sun, 8 Nov 2020 13:51:49 -0500 Subject: [PATCH] Created abstract class BaseDatabase to use for inheritence This is the first step in creating a new table for the database so we can reduce the code on the index page. --- .../Database/BaseDatabase.cs | 144 ++++++++++++++++ .../Database/PoemDatabase.cs | 156 ++---------------- .../Models/IDatabaseModel.cs | 17 ++ Your New Favorite Poem/Models/Poem.cs | 7 +- .../Pages/AddPoet.cshtml.cs | 2 +- Your New Favorite Poem/Pages/Index.cshtml | 2 +- Your New Favorite Poem/Pages/Index.cshtml.cs | 8 +- Your New Favorite Poem/Pages/Poets.cshtml.cs | 4 +- 8 files changed, 185 insertions(+), 155 deletions(-) create mode 100644 Your New Favorite Poem/Database/BaseDatabase.cs create mode 100644 Your New Favorite Poem/Models/IDatabaseModel.cs diff --git a/Your New Favorite Poem/Database/BaseDatabase.cs b/Your New Favorite Poem/Database/BaseDatabase.cs new file mode 100644 index 0000000..e3614f2 --- /dev/null +++ b/Your New Favorite Poem/Database/BaseDatabase.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Your_New_Favorite_Poem.Constants; +using Your_New_Favorite_Poem.Models; + +namespace Your_New_Favorite_Poem.Database +{ + public abstract class BaseDatabase where T : class, IDatabaseModel + { + readonly static string _connectionString = GetConnectionString(); + public abstract Task PatchData(T data); + public List GetAllData(Func wherePredicate) + { + using var connection = new DatabaseContext(); + + return connection.Data?.Where(wherePredicate).ToList() ?? new List(); + } + + public List GetAllData() => GetAllData(x => true); + + public Task GetData(string id) + { + return PerformDatabaseFunction(getDataFunction); + + Task getDataFunction(DatabaseContext dataContext) => dataContext.Data.SingleAsync(x => x.Id.Equals(id)); + } + + public Task InsertData(T data) + { + return PerformDatabaseFunction(insertDataFunction); + + async Task insertDataFunction(DatabaseContext dataContext) + { + data.Id = Guid.NewGuid(); + + data.CreatedAt = DateTimeOffset.UtcNow; + data.UpdatedAt = DateTimeOffset.UtcNow; + + await dataContext.AddAsync(data).ConfigureAwait(false); + + return data; + } + } + + + + public Task DeleteData(string id) + { + return PerformDatabaseFunction(deleteDataFunction); + + async Task deleteDataFunction(DatabaseContext dataContext) + { + var dataFromDatabase = await dataContext.Data.SingleAsync(y => y.Id.Equals(id)).ConfigureAwait(false); + + dataFromDatabase.IsDeleted = true; + + return await PatchData(dataFromDatabase).ConfigureAwait(false); + } + } + + public Task RemoveData(string id) + { + return PerformDatabaseFunction(removeDataDatabaseFunction); + + async Task removeDataDatabaseFunction(DatabaseContext dataContext) + { + var dataFromDatabase = await dataContext.Data.SingleAsync(x => x.Id.Equals(id)).ConfigureAwait(false); + + dataContext.Remove(dataFromDatabase); + + return dataFromDatabase; + } + } + + protected static async Task PerformDatabaseFunction(Func> databaseFunction) where TResult : class + { + using var connection = new DatabaseContext(); + + try + { + var result = await databaseFunction.Invoke(connection).ConfigureAwait(false); + await connection.SaveChangesAsync().ConfigureAwait(false); + + return result; + } + catch (Exception e) + { + Debug.WriteLine(""); + Debug.WriteLine(e.Message); + Debug.WriteLine(e.ToString()); + Debug.WriteLine(""); + + throw; + } + } + + //https://stackoverflow.com/a/43740589/13741035 + static string GetConnectionString() + { + var connectionStringFromEnvironmentVariable = Environment.GetEnvironmentVariable("MYSQLCONNSTR_localdb") ?? string.Empty; + var connArray = Regex.Split(connectionStringFromEnvironmentVariable, ";"); + + var connectionstring = string.Empty; + for (int i = 0; i < connArray.Length; i++) + { + + if (i is 1) + { + string[] datasource = Regex.Split(connArray[i], ":"); + connectionstring += datasource[0] + string.Format(";port={0};", datasource[1]); + } + else + { + connectionstring += connArray[i] + ";"; + } + } + + return connectionstring; + } + + protected class DatabaseContext : DbContext + { + public DatabaseContext() + { + Database.EnsureCreated(); + + } + public DbSet? Data { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseMySQL(_connectionString); + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().Property(b => b.CreatedAt).HasDefaultValue(DateTimeOffset.UtcNow); + modelBuilder.Entity().Property(b => b.UpdatedAt).HasDefaultValue(DateTimeOffset.UtcNow); + + } + } + } +} \ No newline at end of file diff --git a/Your New Favorite Poem/Database/PoemDatabase.cs b/Your New Favorite Poem/Database/PoemDatabase.cs index 569d6da..df19f60 100644 --- a/Your New Favorite Poem/Database/PoemDatabase.cs +++ b/Your New Favorite Poem/Database/PoemDatabase.cs @@ -1,64 +1,28 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; -using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; -using Your_New_Favorite_Poem.Constants; +using Your_New_Favorite_Poem.Database; using Your_New_Favorite_Poem.Models; namespace Your_New_Favorite_Poem.Database { - public class PoemDatabase + public class PoemDatabase : BaseDatabase { - readonly static string _connectionString = GetConnectionString(); - - public List GetAllPoems(Func wherePredicate) - { - using var connection = new PoemDatabaseContext(); - - return connection.Poems?.Where(wherePredicate).ToList() ?? new List(); - } - - public List GetAllPoems() => GetAllPoems(x => true); - - public Task GetPoem(string id) - { - return PerformDatabaseFunction(getPoemFunction); - - Task getPoemFunction(PoemDatabaseContext dataContext) => dataContext.Poems.SingleAsync(x => x.Id.Equals(id)); - } - - public Task InsertPoems(Poem poem) - { - return PerformDatabaseFunction(insertPoemFunction); - - async Task insertPoemFunction(PoemDatabaseContext dataContext) - { - poem.Id = Guid.NewGuid(); - - poem.CreatedAt = DateTimeOffset.UtcNow; - poem.UpdatedAt = DateTimeOffset.UtcNow; - - await dataContext.AddAsync(poem).ConfigureAwait(false); - - return poem; - } - } - - public Task PatchPoem(Poem poem) + public override Task PatchData(Poem data) { return PerformDatabaseFunction(patchPoemFunction); - async Task patchPoemFunction(PoemDatabaseContext dataContext) + async Task patchPoemFunction(DatabaseContext dataContext) { - var poemFromDatabase = await dataContext.Poems.SingleAsync(y => y.Id.Equals(poem.Id)).ConfigureAwait(false); + var poemFromDatabase = await dataContext.Data.SingleAsync(y => y.Id.Equals(data.Id)).ConfigureAwait(false); - poemFromDatabase.Author = poem.Author; - poemFromDatabase.Title = poem.Title; - poemFromDatabase.URL = poem.URL; - poemFromDatabase.IsDeleted = poem.IsDeleted; + poemFromDatabase.Author = data.Author; + poemFromDatabase.Title = data.Title; + poemFromDatabase.URL = data.URL; + poemFromDatabase.IsVerified = data.IsVerified; + poemFromDatabase.IsDeleted = data.IsDeleted; poemFromDatabase.UpdatedAt = DateTimeOffset.UtcNow; dataContext.Update(poemFromDatabase); @@ -66,102 +30,6 @@ async Task patchPoemFunction(PoemDatabaseContext dataContext) return poemFromDatabase; } } - - public Task DeletePoem(string id) - { - return PerformDatabaseFunction(deletePoemFunction); - - async Task deletePoemFunction(PoemDatabaseContext dataContext) - { - var poemFromDatabase = await dataContext.Poems.SingleAsync(y => y.Id.Equals(id)).ConfigureAwait(false); - - poemFromDatabase.IsDeleted = true; - - return await PatchPoem(poemFromDatabase).ConfigureAwait(false); - } - } - - public Task RemovePoem(string id) - { - return PerformDatabaseFunction(removePoemDatabaseFunction); - - async Task removePoemDatabaseFunction(PoemDatabaseContext dataContext) - { - var poemFromDatabase = await dataContext.Poems.SingleAsync(x => x.Id.Equals(id)).ConfigureAwait(false); - - dataContext.Remove(poemFromDatabase); - - return poemFromDatabase; - } - } - - static async Task PerformDatabaseFunction(Func> databaseFunction) where TResult : class - { - using var connection = new PoemDatabaseContext(); - - try - { - var result = await databaseFunction.Invoke(connection).ConfigureAwait(false); - await connection.SaveChangesAsync().ConfigureAwait(false); - - return result; - } - catch (Exception e) - { - Debug.WriteLine(""); - Debug.WriteLine(e.Message); - Debug.WriteLine(e.ToString()); - Debug.WriteLine(""); - - throw; - } - } - - //https://stackoverflow.com/a/43740589/13741035 - static string GetConnectionString() - { - var connectionStringFromEnvironmentVariable = Environment.GetEnvironmentVariable("MYSQLCONNSTR_localdb") ?? string.Empty; - var connArray = Regex.Split(connectionStringFromEnvironmentVariable, ";"); - - var connectionstring = string.Empty; - for (int i = 0; i < connArray.Length; i++) - { - - if (i is 1) - { - string[] datasource = Regex.Split(connArray[i], ":"); - connectionstring += datasource[0] + string.Format(";port={0};", datasource[1]); - } - else - { - connectionstring += connArray[i] + ";"; - } - } - - return connectionstring; - } - - class PoemDatabaseContext : DbContext - { - public PoemDatabaseContext() - { - Database.EnsureCreated(); - if (!Poems.Any()) - { - Poems?.AddRange(PoemsConstants.PoemList); - SaveChanges(); - } - } - - public DbSet? Poems { get; set; } - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseMySQL(_connectionString); - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().Property(b => b.CreatedAt).HasDefaultValue(DateTimeOffset.UtcNow); - modelBuilder.Entity().Property(b => b.UpdatedAt).HasDefaultValue(DateTimeOffset.UtcNow); - - } - } } -} \ No newline at end of file +} + diff --git a/Your New Favorite Poem/Models/IDatabaseModel.cs b/Your New Favorite Poem/Models/IDatabaseModel.cs new file mode 100644 index 0000000..87fe0a6 --- /dev/null +++ b/Your New Favorite Poem/Models/IDatabaseModel.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Your_New_Favorite_Poem.Models +{ + //Interface to force classes to include properties needed in database + public interface IDatabaseModel + { + public Guid Id { get; set; } + public bool IsDeleted { get; set; } + public DateTimeOffset CreatedAt { get; set; } + public DateTimeOffset UpdatedAt { get; set; } + public bool IsVerified { get; set; } + } +} diff --git a/Your New Favorite Poem/Models/Poem.cs b/Your New Favorite Poem/Models/Poem.cs index 972ee23..a8f63dc 100644 --- a/Your New Favorite Poem/Models/Poem.cs +++ b/Your New Favorite Poem/Models/Poem.cs @@ -7,17 +7,18 @@ namespace Your_New_Favorite_Poem.Models { - public class Poem + [Table("poems")] + public class Poem : IDatabaseModel { public Poem() { } - public Poem( string author, string title, Uri url) + public Poem(string author, string title, Uri url) { Author = author; Title = title; - URL = url; + URL = url; } [Key, DatabaseGenerat‌ed(DatabaseGeneratedOp‌​tion.Identity)] public Guid Id { get; set; } diff --git a/Your New Favorite Poem/Pages/AddPoet.cshtml.cs b/Your New Favorite Poem/Pages/AddPoet.cshtml.cs index db54cc8..4eb532d 100644 --- a/Your New Favorite Poem/Pages/AddPoet.cshtml.cs +++ b/Your New Favorite Poem/Pages/AddPoet.cshtml.cs @@ -24,7 +24,7 @@ public async Task OnPostSubmit(string author, string poem, string poemName) { try { - await _poemDatabase.InsertPoems(new Poem(author, poemName, poemUri)); + await _poemDatabase.InsertData(new Poem(author, poemName, poemUri)); SubmissionResult = "We did it! Submission Accepted. Check back soon!"; } catch diff --git a/Your New Favorite Poem/Pages/Index.cshtml b/Your New Favorite Poem/Pages/Index.cshtml index e3e5661..fdeee36 100644 --- a/Your New Favorite Poem/Pages/Index.cshtml +++ b/Your New Favorite Poem/Pages/Index.cshtml @@ -24,7 +24,7 @@
- +
diff --git a/Your New Favorite Poem/Pages/Index.cshtml.cs b/Your New Favorite Poem/Pages/Index.cshtml.cs index 5515c90..3543796 100644 --- a/Your New Favorite Poem/Pages/Index.cshtml.cs +++ b/Your New Favorite Poem/Pages/Index.cshtml.cs @@ -18,7 +18,7 @@ public class IndexModel : PageModel public string Home { get; set; } = "Home"; public IActionResult OnPostRandomPoem() { - + var rnd = new Random(); var index = rnd.Next(0, PoemsFromDatabase.Count); @@ -32,8 +32,8 @@ public IndexModel(ILogger logger, PoemDatabase poemDatabase) { _logger = logger; _poemDatabase = poemDatabase; - PoemsFromDatabase = poemDatabase.GetAllPoems(); + PoemsFromDatabase = poemDatabase.GetAllData(); } private readonly PoemDatabase _poemDatabase; - } -} + } +} diff --git a/Your New Favorite Poem/Pages/Poets.cshtml.cs b/Your New Favorite Poem/Pages/Poets.cshtml.cs index 9da5766..daa69df 100644 --- a/Your New Favorite Poem/Pages/Poets.cshtml.cs +++ b/Your New Favorite Poem/Pages/Poets.cshtml.cs @@ -7,7 +7,7 @@ namespace Your_New_Favorite_Poem.Pages { - + public class PoetsModel : PageModel { public IReadOnlyList PoemsFromDatabase { get; } @@ -16,7 +16,7 @@ public PoetsModel(ILogger logger, PoemDatabase poemDatabase) { Logger = logger; _poemDatabase = poemDatabase; - PoemsFromDatabase = poemDatabase.GetAllPoems(); + PoemsFromDatabase = poemDatabase.GetAllData(); }