Merge branch 'newMain'

This commit is contained in:
Lunastra 2022-01-04 13:58:51 -08:00
commit 271f2df7f9
9 changed files with 311 additions and 118 deletions

View File

@ -3,12 +3,18 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TeamHobby.HobbyProjectGenerator.Logging.Contracts;
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
{
public interface ILogger
public interface ILogger
{
bool Log(LogEntry log);
// private IDataSource<string> _datasource = T;
// attempts to connect to the data source provided by the type T
// returns true if the connection is successful
// public bool Connect();
public bool Log(LogEntry Log);
// IList<string> GetAllLogs();

View File

@ -8,9 +8,9 @@ namespace TeamHobby.HobbyProjectGenerator.ServiceLayer.Contracts
{
public interface ILoggerFactory
{
ILogger CreateLogger()
{
return new DBLogger();
}
ILogger CreateLogger();
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TeamHobby.HobbyProjectGenerator.Logging.Contracts;
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
{

View File

@ -1,24 +1,200 @@
using System;
using System.Data.Odbc;
using TeamHobby.HobbyProjectGenerator.DataAccessLayer;
using TeamHobby.HobbyProjectGenerator.Logging.Contracts;
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
{
public class DBLogger : ILogger
public class DBLogger : ILogger
{
private SqlDAO _datasource;
public DBLogger()
{
}
public IList<string> GetAllLogs()
{
throw new NotImplementedException();
// SELECT * FROM log
// public IList<LogEntry> GetAllLogs()
// {
// throw new NotImplementedException();
// }
//INSERT INTO log(LvName, catName, userOP, logMessage) VALUES ('Debug','Data', 'SYSTEM', 'testing insert method')
// public bool Connect(SqlDAO logDatabase) {
//
// }
public bool IsActive() {
string dbInfo = "DRIVER={MariaDB ODBC 3.1 Driver};" +
"TCPIP=1;" +
"SERVER=ocalhost;" +
"DATABASE=hbby;" +
"UID=ot;" + // omit password to force SQLException for incorrect passeword
"PASSWORD=wrong" +
"OPTION=3";
// bool isActive = true;
OdbcConnection active = new OdbcConnection(dbInfo);
try {
active.Open();
return false;
}
catch (OdbcException ex) {
// Console.WriteLine(ex.Message);
if (ex.ErrorCode == -2146232009 ) {
//Console.WriteLine(ex.ErrorCode);
Console.WriteLine("Database is active");
return true;
}
else {
Console.WriteLine("Database is inactive");
return false;
}
}
finally {
// Console.WriteLine("closed1");
active.Close();
}
// return false;
}
public bool IsAccessible() {
string dbInfo = "DRIVER={MariaDB ODBC 3.1 Driver};" +
"TCPIP=1;" +
"SERVER=localhost;" +
"DATABASE=hobby;" +
"UID=root;" +
"PASSWORD=Teamhobby;" +
"OPTION=3";
OdbcConnection access = new OdbcConnection(dbInfo);
try {
access.Open();
Console.WriteLine("Database is active and accessible by the system");
return true;
}
catch {
Console.WriteLine("Database is active but inaccessible to the system at this time.");
return false;
}
finally {
access.Close();
}
}
public bool HasCapacity() {
string dbInfo = "DRIVER={MariaDB ODBC 3.1 Driver};" +
"TCPIP=1;" +
"SERVER=localhost;" +
"DATABASE=hobby;" +
"UID=root;" +
"PASSWORD=Teamhobby;" +
"OPTION=3";
OdbcConnection conn = new OdbcConnection(dbInfo);
// get the current capacity of the database in MB using the query:
// SELECT SUM(storage.MB) as CURRENT_CAPACITY_MB FROM (SELECT table_schema as name, ROUND(SUM(data_length + index_length)/1024/1024,1) as MB FROM information_schema.tables GROUP BY table_schema) as storage;
string sqlCurrentCap = $"SELECT SUM(storage.mb) as currentCap FROM (SELECT table_schema as name, ROUND(SUM(data_length + index_length)/1024/1024,1) as mb FROM information_schema.tables GROUP BY table_schema) as storage;";
// get the max capacity in GB; too big to be shown as MB
string sqlMaxCap = $"SELECT SUM(storage.mb) as maxCap FROM (SELECT table_schema as name, ROUND(SUM(max_data_length + max_index_length)/1024,1) as mb FROM information_schema.tables GROUP BY table_schema) as storage;";
// query the data base to get currentCap; the current storage capacity of the system's database (in megabytes)
conn.Open();
OdbcCommand command1 = new OdbcCommand(sqlCurrentCap, conn);
OdbcDataReader result1 = command1.ExecuteReader();
double currentCap = 0;
while (result1.Read()) {
//Console.WriteLine(result1[0].GetType());
//Console.WriteLine("currentCap = {0}", result1[0]);
currentCap = result1.GetDouble(0);
}
// Console.WriteLine(currentCap);
//float currentCap1 = (float) currentCap;
result1.Close();
command1.Dispose();
conn.Close();
// Console.WriteLine("close conn");
// query the data base again to get maxCap; the maximum possible storage capacity of the system's database (in megabytes)
conn.Open();
// Console.WriteLine("open conn");
OdbcCommand command2 = new OdbcCommand(sqlMaxCap, conn);
OdbcDataReader result2 = command2.ExecuteReader();
// Console.WriteLine("open reader 1");
double maxCap = 0;
try {
while (result2.Read()) {
//Console.WriteLine(result2[0].GetType());
maxCap = result2.GetDouble(0);
// Console.WriteLine("maxCap = {0}", result2[0]);
}
// compare currentCap to maxCap
// return true if there is at least 1MB of free space available
// decrement max by 1 MB to allow for any required space from new logs
if ( (currentCap * 1024) < (maxCap - 1024) ) {
// Console.WriteLine(maxCap);
Console.WriteLine("Database has sufficient storage capacity to be written to at this time.\n Current Capacity: {0} MB\n Max Capacity: {1} MB\n", currentCap, maxCap);
}
}
catch {
Console.WriteLine("Insufficient Storage Capacity to log entry to database.\n Current Capacity: {0} MB \n Max Capacity: {1} MB \n", currentCap, maxCap);
return false;
}
finally {
result2.Close();
command2.Dispose();
conn.Close();
}
return false;
}
//Console.WriteLine("close conn 2");
//Console.WriteLine(maxCap);
public bool Log(LogEntry log)
{
throw new NotImplementedException();
log.ShowLog();
//bool status = HasCapacity();
if ( (IsActive() == false || IsAccessible() == false) || (HasCapacity() == false) ) {
return false;
}
else {
// SqlDAO sqlDS = (SqlDAO)_datasource;
string dbInfo = "DRIVER={MariaDB ODBC 3.1 Driver};" +
"TCPIP=1;" +
"SERVER=localhost;" +
"DATABASE=hobby;" +
"UID=root;" +
"PASSWORD=Teamhobby;" +
"OPTION=3";
_datasource = new SqlDAO(dbInfo);
//bool storage = HasCapacity();
try
{
// once connection is confirmed, try inserting the log via SQL statements
string sqlLog = $"INSERT INTO log (Lvname, catName, userOP, logMessage) VALUES ('{log.GetLevel()}','{log.GetCategory()}', " + $"'{log.GetUser()}', '{log.GetDescription()}');";
bool insertNewLog = _datasource.WriteData(sqlLog);
//Console.WriteLine($"Logging Succeeded: The following entry was written to the database: {log}");
// Console.WriteLine(_datasource.ReadData($"SELECT * FROM log;"));
return insertNewLog;
}
// if failed, that means the connection was a sucess but actually writing to the database failed
catch
{
Console.WriteLine("Failed to write log to database; likely due to error in SQL syntax");
return false;
}
}
}
}
}

View File

@ -11,9 +11,10 @@ namespace TeamHobby.HobbyProjectGenerator.ServiceLayer.Implementations
{
public DBLoggerFactory()
{
//this._logDatabase = logDatabase;
}
public ILogger CreateLogger()
{
public ILogger CreateLogger() {
return new DBLogger();
}
}

View File

@ -1,4 +1,5 @@
using System;
using TeamHobby.HobbyProjectGenerator.Logging.Contracts;
using TeamHobby.HobbyProjectGenerator.ServiceLayer.Contracts;
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer

View File

@ -1,59 +0,0 @@
using System;
using System.Collections.Generic;
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
{
// implementation of ILogger that stores logs as they initialize
public class InMemoryLogger : ILogger
{
// make readonly to prevent it from being changed somewhere other than in the constructor
private readonly IList<string> _logStore;
public InMemoryLogger()
{
// list of current logs
_logStore = new List<string>();
}
public InMemoryLogger(IList<string> logStore)
{
_logStore = logStore;
}
public bool Log(LogEntry entry)
{
if (entry is null)
{
throw new ArgumentNullException(nameof(entry));
}
try
{
// string interpolation to add UTC timestamp to log description
//_logStore.Add($"{DateTime.UtcNow}-> {description}");
return true;
}
catch
{
return false;
}
}
public IList<string> GetAllLogs()
{
return _logStore;
}
public override bool Equals(object? obj)
{
return obj is InMemoryLogger logger &&
EqualityComparer<IList<string>>.Default.Equals(_logStore, logger._logStore);
}
public override int GetHashCode()
{
return HashCode.Combine(_logStore);
}
}
}

View File

@ -4,9 +4,8 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
{
public enum LogLevel
public enum LogLevel
{
Info, Debug, Warning, Error
}
@ -16,38 +15,60 @@ namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
View, Business, Server, Data, Datastore
}
namespace TeamHobby.HobbyProjectGenerator.Logging.Contracts
{
// LogEntry is a record type with init properties for each field
// ensures that log entries are immutable after initialization
// LogEntry is a record type with init properties for each field
// ensures that log entries are immutable after initialization
public record LogEntry
{
public LogLevel level { get; init; }
public LogCategory category { get; init; }
public string user { get; init; }
public string description { get; init; }
public DateTime timestamp { get; init; }
private LogLevel _level { get; init; }
private LogCategory _category { get; init; }
private string _user { get; init; }
private string _description { get; init; }
// Constructor requireing only the description as an arg
// Assigns default values for LogLevel (Info), LogCategory (Server), user ("System"), and the UTC time at initialization for timestamp
public LogEntry(string description)
{
this.level = LogLevel.Info;
this.category = LogCategory.Server;
this.user = "System";
this.description = description;
this.timestamp = DateTime.UtcNow;
}
// Constructor with args for all fields except timestamp
// timestamp is always set to the UTC time at the time of initialization
public LogEntry(LogLevel level, string user, LogCategory category, string description)
public LogEntry(LogLevel level, LogCategory category, string user, string description)
{
this.level = level;
this.category = category;
this.user = user;
this.description = description;
this.timestamp = DateTime.UtcNow;
this._level = level;
this._category = category;
this._user = user;
this._description = description;
}
// Constructor requiring only the description as an arg
// Assigns default values for LogLevel (Info), LogCategory (Server), user ("System"), and the UTC time at initialization for timestamp
// public LogEntry(string description)
// {
// this._level = LogLevel.Debug;
// this._category = LogCategory.Server;
// this._user = "SYSTEM";
// this._description = description;
// }
public LogLevel GetLevel() {
return this._level;
}
public LogCategory GetCategory() {
return this._category;
}
public string GetUser() {
return this._user;
}
public string GetDescription() {
return this._description;
}
public void ShowLog() {
Console.WriteLine("Timestamp: {0} | Level: {1}, | Category: {2}, | User: {3}, | Description: '{4}' ", DateTime.Now, this._level.ToString(),this._category.ToString(), this._user, this._description);
}
}
}

View File

@ -4,42 +4,88 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TeamHobby.HobbyProjectGenerator.DataAccessLayer;
using TeamHobby.HobbyProjectGenerator.Logging.Contracts;
using TeamHobby.HobbyProjectGenerator.ServiceLayer.Contracts;
using TeamHobby.HobbyProjectGenerator.ServiceLayer.Implementations;
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
{
internal class LoggingManager
public class LoggingManager
{
private readonly IDataSource<string> _conn;
private readonly ILogger _logger;
private readonly ILoggerFactory _factory;
private readonly LogEntry _logEntry;
// private static IDataSource<string> _datasource;
private ILogger _logger;
private ILoggerFactory _factory;
private LogEntry _logEntry;
// assign default values for LogEntry fields
// these are not readonly because they can be overwritten to specify logging at specific field(s) from the main controller by using the public setters for each field
private LogLevel _level = LogLevel.Debug;
private LogCategory _category = LogCategory.Server;
private string _user = "System";
// Both Constructors take an IDataSource arg to make logging extensible to future data sources
// first constructor has no additional args - defaults to using the DBFactiry implementation
public LoggingManager(IDataSource<string> dataSource)
// first constructor has no additional args - defaults to using a DBLoggerFactory to log to database
public LoggingManager()
{
_conn = dataSource;
// _datasource = datasource;
_logEntry = new LogEntry(_level, _category, _user, "Logging Manager instantiated");
_factory = new DBLoggerFactory();
_logger = _factory.CreateLogger();
}
// second constructor takes an additional ILoggerFactory arg - allows for extensible logger types
public LoggingManager(IDataSource<string> dataSource, ILoggerFactory factory)
public LoggingManager(ILoggerFactory factory)
{
_conn = dataSource;
//_datasource = datasource;
_logEntry = new LogEntry(_level, _category, _user, "Logging Manager instantiated");
_factory = factory;
_logger = _factory.CreateLogger();
}
public void Process()
{
_logger.Log(_logEntry);
// // used to create a template entry with the desired fields to write entries at
// public void CreateLog(LogLevel level, LogCategory category, string user, string description) {
// _logEntry = new LogEntry(level,
// category, user, description);
// _logger.Log(_logEntry);
// }
// creates a LogEntry object using a description arg
// uses whateever the current assignments for the other fields ares
public bool CreateLog(string description) {
// creates a LogEntry using the passed in description and current assignements from the necessary fields
_logEntry = new LogEntry(_level, _category, _user, description);
// attempt to log the LogEntry by calling the _logger's Log() method
try {
_logger.Log(_logEntry);
return true;
}
catch {
return false;
}
}
public void Level(LogLevel level) {
this._level = level;
}
public void Category(LogCategory category) {
this._category = category;
}
public void User(string user) {
this._user = user;
}
// public static void Source(IDataSource<string> datasource) {
// _datasource = datasource;
// }
// public static IDataSource<string> GetDataSource() {
// return _datasource;
// }
}
}