This repository has been archived by the owner on Jun 22, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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.
- Loading branch information
1 parent
910c18c
commit d3b4923
Showing
8 changed files
with
185 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
|
||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
|
||
} | ||
} | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.