Skip to content
This repository has been archived by the owner on Jun 22, 2021. It is now read-only.

Commit

Permalink
Created abstract class BaseDatabase to use for inheritence
Browse files Browse the repository at this point in the history
This is the first step in creating a new table for the database so we can reduce the code on the index page.
  • Loading branch information
MetzinAround committed Nov 8, 2020
1 parent 910c18c commit d3b4923
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 155 deletions.
144 changes: 144 additions & 0 deletions Your New Favorite Poem/Database/BaseDatabase.cs
Original file line number Diff line number Diff line change
@@ -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<T> where T : class, IDatabaseModel
{
readonly static string _connectionString = GetConnectionString();
public abstract Task<T> PatchData(T data);
public List<T> GetAllData(Func<T, bool> wherePredicate)
{
using var connection = new DatabaseContext();

return connection.Data?.Where(wherePredicate).ToList() ?? new List<T>();
}

public List<T> GetAllData() => GetAllData(x => true);

public Task<T> GetData(string id)
{
return PerformDatabaseFunction(getDataFunction);

Task<T> getDataFunction(DatabaseContext dataContext) => dataContext.Data.SingleAsync(x => x.Id.Equals(id));
}

public Task<T> InsertData(T data)
{
return PerformDatabaseFunction(insertDataFunction);

async Task<T> 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<T> DeleteData(string id)
{
return PerformDatabaseFunction(deleteDataFunction);

async Task<T> 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<T> RemoveData(string id)
{
return PerformDatabaseFunction(removeDataDatabaseFunction);

async Task<T> 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<TResult> PerformDatabaseFunction<TResult>(Func<DatabaseContext, Task<TResult>> 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<T>? Data { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseMySQL(_connectionString);
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<T>().Property(b => b.CreatedAt).HasDefaultValue(DateTimeOffset.UtcNow);
modelBuilder.Entity<T>().Property(b => b.UpdatedAt).HasDefaultValue(DateTimeOffset.UtcNow);

}
}
}
}
156 changes: 12 additions & 144 deletions Your New Favorite Poem/Database/PoemDatabase.cs
Original file line number Diff line number Diff line change
@@ -1,167 +1,35 @@
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<Poem>
{
readonly static string _connectionString = GetConnectionString();

public List<Poem> GetAllPoems(Func<Poem, bool> wherePredicate)
{
using var connection = new PoemDatabaseContext();

return connection.Poems?.Where(wherePredicate).ToList() ?? new List<Poem>();
}

public List<Poem> GetAllPoems() => GetAllPoems(x => true);

public Task<Poem> GetPoem(string id)
{
return PerformDatabaseFunction(getPoemFunction);

Task<Poem> getPoemFunction(PoemDatabaseContext dataContext) => dataContext.Poems.SingleAsync(x => x.Id.Equals(id));
}

public Task<Poem> InsertPoems(Poem poem)
{
return PerformDatabaseFunction(insertPoemFunction);

async Task<Poem> 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<Poem> PatchPoem(Poem poem)
public override Task<Poem> PatchData(Poem data)
{
return PerformDatabaseFunction(patchPoemFunction);

async Task<Poem> patchPoemFunction(PoemDatabaseContext dataContext)
async Task<Poem> 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);

return poemFromDatabase;
}
}

public Task<Poem> DeletePoem(string id)
{
return PerformDatabaseFunction(deletePoemFunction);

async Task<Poem> 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<Poem> RemovePoem(string id)
{
return PerformDatabaseFunction(removePoemDatabaseFunction);

async Task<Poem> removePoemDatabaseFunction(PoemDatabaseContext dataContext)
{
var poemFromDatabase = await dataContext.Poems.SingleAsync(x => x.Id.Equals(id)).ConfigureAwait(false);

dataContext.Remove(poemFromDatabase);

return poemFromDatabase;
}
}

static async Task<TResult> PerformDatabaseFunction<TResult>(Func<PoemDatabaseContext, Task<TResult>> 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<Poem>? Poems { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseMySQL(_connectionString);
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Poem>().Property(b => b.CreatedAt).HasDefaultValue(DateTimeOffset.UtcNow);
modelBuilder.Entity<Poem>().Property(b => b.UpdatedAt).HasDefaultValue(DateTimeOffset.UtcNow);

}
}
}
}
}

17 changes: 17 additions & 0 deletions Your New Favorite Poem/Models/IDatabaseModel.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
}
7 changes: 4 additions & 3 deletions Your New Favorite Poem/Models/Poem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
2 changes: 1 addition & 1 deletion Your New Favorite Poem/Pages/AddPoet.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Your New Favorite Poem/Pages/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

<div class="buttonmove">
<form method="post" asp-page="Index">
<input class="button" type="submit" value="Generate Random Poem" asp-page-handler="RandomPoem" formtarget="_blank" />
<input class="button" type="submit" value="Read Random Poem" asp-page-handler="RandomPoem" formtarget="_blank" />
</form>
</div>
<!--Ocean Vuong Poems-->
Expand Down
Loading

0 comments on commit d3b4923

Please sign in to comment.