Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 218 additions & 0 deletions Controllers/DatabaseController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
using Dapper;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.Configuration;
using Spectre.Console;
using System.Data;
using System.Text;

internal class DatabaseController
{
private static string _tableName = "Sessions";
private static readonly IConfiguration _configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
private static string connectionString = _configuration.GetConnectionString("Default");

public static void StartConnection()
{
using(var connection = new SqliteConnection(connectionString))
{
try
{
connection.Open();
var tableCmd = connection.CreateCommand();

tableCmd.CommandText = @$"CREATE TABLE IF NOT EXISTS {_tableName}(
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Name TEXT,
Date TEXT,
Start TEXT,
End TEXT,
Duration TEXT
);";

tableCmd.ExecuteNonQuery();
}
catch (SqliteException)
{
AnsiConsole.Write("An error occured! Could not create table.");
AnsiConsole.Prompt(new SelectionPrompt<string>().AddChoices("Return"));
}
finally
{
connection.Close();
}
}
}

public static void AddRecord(CodingSession record)
{
using(var connection = new SqliteConnection(connectionString))
{
try
{
connection.Open();
var tableCmd = $@"INSERT INTO {_tableName} (name, date, start, end, duration)
VALUES (@name, @date, @start, @end, @duration)";
connection.Execute(tableCmd, new { name = record.RecordName, date = record.Date, start = record.StartTime, end = record.EndTime, duration = record.Duration });
}
catch (SqliteException)
{
AnsiConsole.Write("An error occured! Could not add record.");
AnsiConsole.Prompt(new SelectionPrompt<string>().AddChoices("Return"));
}
finally
{
connection.Close();
}
}
}

public static List<string> GetRecords(List<FilterCondition> filters)
{
var readerCmd = $"SELECT * FROM {_tableName} ";
var filterCommands = new List<string>();
var table = new DataTable();

foreach (FilterCondition filter in filters)
{
filterCommands.Add($" {filter.Type} {filter.Relational} \"{filter.ComparedTo}\" ");
}

if (filters.Count > 0)
{
readerCmd += $"WHERE " + string.Join("AND", filterCommands) + ";";
}

using (var connection = new SqliteConnection(connectionString))
{
try
{
connection.Open();
var reader = connection.ExecuteReader(readerCmd);

table.Load(reader);
}
catch (SqliteException)
{
AnsiConsole.Clear();
AnsiConsole.Write("An error occured! Could not retrieve records.");
AnsiConsole.Prompt(new SelectionPrompt<string>().AddChoices("Return"));
}
finally
{
connection.Close();
}
}

var allRows = new List<string>();

foreach (DataRow rows in table.Rows)
{
StringBuilder output = new StringBuilder();

foreach (DataColumn column in table.Columns)
{
output.AppendFormat("{0} ", rows[column]);
}
allRows.Add(output.ToString());
}

return allRows;
}

public static void RemoveRecord(CodingSession record)
{
using (var connection = new SqliteConnection(connectionString))
{
try
{
connection.Open();

var removeCmd = @$"DELETE FROM {_tableName} WHERE
id = @id AND
name = @name AND
date = @date AND
start = @start AND
end = @end AND
duration = @duration;";

connection.Execute(removeCmd, new { id = record.Id,
name = record.RecordName,
date = record.Date,
start = record.StartTime,
end = record.EndTime,
duration = record.Duration});

}
catch (SqliteException ex)
{
AnsiConsole.Clear();
AnsiConsole.WriteLine("Something went wrong! Could not remove record! " + ex);
AnsiConsole.Prompt(new SelectionPrompt<string>().AddChoices("Return"));
}
finally
{
connection.Close();
}

}
}

public static void EditRecord(CodingSession record, string valueToChange, string newValue)
{
using (var connection = new SqliteConnection(connectionString))
{
try
{
connection.Open();

var editCmd = string.Empty;

if(valueToChange == "start" || valueToChange == "end")
{
editCmd = @$"Update {_tableName} SET {valueToChange} = @value, duration = @duration
WHERE id = @id AND
name = @name AND
date = @date AND
start = @start AND
end = @end";
}
else
{
editCmd = @$"Update {_tableName} SET {valueToChange} = @value
WHERE id = @id AND
name = @name AND
date = @date AND
start = @start AND
end = @end AND
duration = @duration;";
}

connection.Execute(editCmd, new
{
value = newValue,
id = record.Id,
name = record.RecordName,
date = record.Date,
start = record.StartTime,
end = record.EndTime,
duration = record.Duration
});

}
catch (SqliteException ex)
{
AnsiConsole.Clear();
AnsiConsole.WriteLine("Something went wrong! Could not edit record! " + ex);
AnsiConsole.Prompt(new SelectionPrompt<string>().AddChoices("Return"));
}
finally
{
connection.Close();
}

}
}
}
80 changes: 80 additions & 0 deletions Models/CodingSession.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using Spectre.Console;

internal class CodingSession
{
public int Id { get; set; }
public string RecordName { get; set; }
public string Date { get; set; }
public string StartTime { get; set; }
public string EndTime { get; set; }
public string Duration { get; set; }

public CodingSession(string name, string date, string start, string end)
{
this.Id = 0;
this.RecordName = name;
this.Date = date;
this.StartTime = start;
this.EndTime = end;
this.Duration = CalculateDuration();
}

public CodingSession(string record)
{
var recordDetails = record.Split(' ');

try
{
this.Id = Int32.Parse(recordDetails[0]);
this.RecordName = recordDetails[1];
this.Date = recordDetails[2];
this.StartTime = recordDetails[3];
this.EndTime = recordDetails[4];
this.Duration = recordDetails[5];
}
catch (Exception ex)
{
AnsiConsole.WriteLine("Failed! record may be corrupted or in the wrong format");
AnsiConsole.Ask<string>("Press enter to return");
}
}

public void ChangeTime(string start, string end)
{
this.Duration = CalculateDuration(start, end);
}

private string CalculateDuration(string start, string end)
{
var startTime = DateTime.ParseExact(
start,
Globals.TIME_FORMAT,
Globals.CULTURE_INFO);

var endTime = DateTime.ParseExact(
end,
Globals.TIME_FORMAT,
Globals.CULTURE_INFO);

var duration = endTime.Subtract(startTime);

return duration.ToString();
}

private string CalculateDuration()
{
var startTime = DateTime.ParseExact(
this.StartTime,
Globals.TIME_FORMAT,
Globals.CULTURE_INFO);

var endTime = DateTime.ParseExact(
this.EndTime,
Globals.TIME_FORMAT,
Globals.CULTURE_INFO);

var duration = endTime.Subtract(startTime);

return duration.ToString();
}
}
62 changes: 62 additions & 0 deletions Models/FilterCondition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
public class FilterCondition
{
public string ComparedTo { get; set; }
public string Relational { get; set; }
public string Type { get; set; }

public FilterCondition(ConditionType type, RelationalCondition relational, string compare)
{
this.Type = ConvertCondtionType(type);
this.Relational = ConvertRelational(relational);
this.ComparedTo = compare;
}
private string ConvertCondtionType(ConditionType type)
{
switch (type)
{
case ConditionType.Date:
return "date";
case ConditionType.StartTime:
return "start";
case ConditionType.EndTime:
return "end";
case ConditionType.Duration:
return "duration";
default:
return "start";
}
}

private string ConvertRelational(RelationalCondition relational)
{
switch (relational)
{
case RelationalCondition.GreaterThanOrEqual:
return ">=";
case RelationalCondition.LessThanOrEqual:
return "<=";
case RelationalCondition.Exactly:
return "=";
default:
return "=";
}
}

public enum ConditionType
{
Date,
StartTime,
EndTime,
Duration,
None
}

public enum RelationalCondition
{
GreaterThanOrEqual,
LessThanOrEqual,
Exactly,
None
}
}

9 changes: 9 additions & 0 deletions Models/Globals.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Globalization;

public static class Globals
{
public static readonly string DATE_FORMAT = "dd/MM/yyyy";
public static readonly string TIME_FORMAT = "HH:mm:ss";
public static readonly IFormatProvider CULTURE_INFO = new CultureInfo("en-US");
}

Loading