Repository navigation
Changes made #294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes made #294
Changes from all commits
01509e3
9dc06ad
ca600d7
34ea82f
d28b99e
7c62a32
55d8f2b
f9256cd
b0d0698
be75cf6
6725636
7059ad2
e9ddc66
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| { | ||
| // Use IntelliSense to learn about possible attributes. | ||
| // Hover to view descriptions of existing attributes. | ||
| // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
| "version": "0.2.0", | ||
| "configurations": [ | ||
| { | ||
| "name": "External Terminal, .NET Core Launch (console)", | ||
| "type": "coreclr", | ||
| "request": "launch", | ||
| "preLaunchTask": "${defaultBuildTask}", | ||
| "program": "C:/Users/j_men/Coding-Tracker/Coding-Tracker/bin/debug/net10.0/Coding-Tracker.dll", | ||
| "args": [], | ||
| "cwd": "${workspaceFolder}/Coding-tracker", | ||
| "stopAtEntry": false, | ||
| "console": "externalTerminal" | ||
| } | ||
| ], | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| Coding tracker | ||
|
|
||
| I was tasked with creating a coding tracker, an application that allows the user to Create, View/Read, Update and Delete any record that users enter. | ||
|
|
||
| I needed four classes and a program file that acts as the entry point for the program. | ||
|
|
||
| The coding tracker differs from the habit tracker in a few areas, the habit tracker used ADO.NET to write to the databse and to view the database we used an external terminal. | ||
|
|
||
| The habit tracker also holds all the data in one class (program.cs) whereas the coding tracker uses separation of concerns to split the different functions into classes. | ||
|
|
||
| An appsettings.json file was created so I could place the database connectionstring inside of it, to access the string I created a configuration builder which adds the file and builds it | ||
|
|
||
| we store our new configuration as connectionstring, so whenever our database needs accessing we call on "connectionstring" which holds the data source of our database. | ||
|
|
||
|
|
||
| CodingController | ||
| The coding controller class is responsible for database operations this is where we make use of Dapper and Spectre. | ||
| Dapper is used to simplify the commands we need to communicate with our database. | ||
| Spectre was used in this project to present our data in a table in the terminal which makes viewing our user input neater and more presentable. | ||
|
|
||
|
|
||
| I created a CreateTable Method that uses the Dapper syntax to execute the SQL to create the table with the variables I chose, ID, StartTime, EndTime and duration. We use the connectionstring we created to create a variable that will communicate with the database. | ||
|
|
||
| Create table is called as we need to create the table before anything happens. | ||
| I needed to create a method called viewRecords that contained my initial record viewer method GETallrecords as I faced issues with user input. | ||
| The method calls get all records then asks the user to "Press any key to return to main menu" followed by a readkey that exits the method. | ||
|
|
||
| Getallrecords clears the console, uses connectionstring to create connectionString to create a connection to the SQLite database. It maps each row from the table to the coding tracker object. | ||
|
|
||
| The returned collection is converted into a List<CodingTracker> and stored in the tableData variable. | ||
|
|
||
| I created a new table and added columns for each variable where each variable would go. | ||
| we use a foreach loop to add rows, we convert the output tostring and write them to the table. | ||
|
|
||
| The Insert, Delete and update methods in coding controller rely on variables being passed in. | ||
|
|
||
| The insert method needs two variables startime and endtime as we need the two to calculate duration | ||
| The delete method needs an id to delete so we must pass in an id. | ||
| The update method needs id , startTime and datetime to overwrite the initial values. | ||
|
|
||
| The variables being passed into the controller methods rely on user input. | ||
|
|
||
| UserInput | ||
|
|
||
| User input has methods that take the users input and pass them into our controller class methods to do calculations and to insert, delete or update records before putting them into the database. | ||
|
|
||
| GeTimeInput - used to gather users input for StartTime and End Time methods. | ||
| The method is designed to write a question, collect users input and return the input after being validated. | ||
| The ValidateTime method from the Validation class is used here | ||
|
|
||
| The variable we use to gather the users input is passed into ValidateTime | ||
|
|
||
| This method has a string parameter that asks the user what to enter | ||
| When called upon we must write the question we are asking the user for example in InsertInput; | ||
|
|
||
| startTime = GeTimeInput("Please enter the start Time Format: (HH:mm), Or enter 0 to exit."); | ||
| endTime = GeTimeInput("Please enter the end Time Format: (HH:mm), Or enter 0 to exit."); | ||
|
|
||
| Then inside InsertInput when we call input " CodingController.Insert(startTime, endTime);" | ||
|
|
||
| startTime and EndTime were passed into the method. | ||
|
|
||
| InsertInput - Used to pass user input into the insert method | ||
|
|
||
| DeleteInput - Used to pass user input into the delete method | ||
| clear the console | ||
| call the records | ||
| ask the record that we want to delete | ||
| collect it pass the input into our validation method | ||
| pass the collected input into the delete method. | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <TargetFramework>net10.0</TargetFramework> | ||
| <RootNamespace>Coding_Tracker</RootNamespace> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
|
|
||
| <None Update="appsettings.json"> | ||
| <CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||
| </None> | ||
|
|
||
|
|
||
| <PackageReference Include="Dapper" Version="2.1.79" /> | ||
| <PackageReference Include="Microsoft.Data.Sqlite" Version="10.0.8" /> | ||
| <PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.8" /> | ||
| <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.8" /> | ||
| <PackageReference Include="Spectre.Console" Version="0.55.2" /> | ||
| </ItemGroup> | ||
|
|
||
|
|
||
|
|
||
|
|
||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
|
|
||
| using Microsoft.Data.Sqlite; | ||
| using Microsoft.Extensions.Configuration; | ||
| using Dapper; | ||
| using Spectre.Console; | ||
|
|
||
| class CodingController | ||
| { | ||
| // CodingController.cs — database operations | ||
|
|
||
| static string connectionString = new ConfigurationBuilder() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For a private static string the general naming convention would be to have a '_' in front of the name like |
||
| .AddJsonFile("appsettings.json") | ||
| .Build() | ||
| .GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string not found."); | ||
|
|
||
|
|
||
| public static void CreateTable() | ||
| { | ||
| using (var connection = new SqliteConnection(connectionString)) | ||
| { | ||
| connection.Execute(@"CREATE TABLE IF NOT EXISTS coding_tracker ( | ||
| Id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
| StartTime TEXT, | ||
| EndTime TEXT, | ||
| Duration TEXT | ||
| )"); | ||
| } | ||
| } | ||
|
|
||
| public static void ViewRecords() | ||
| { | ||
| GetAllRecords(); | ||
| Console.WriteLine(); | ||
| Console.ReadKey(); | ||
| } | ||
|
|
||
| public static void GetAllRecords() | ||
| { | ||
| Console.Clear(); | ||
| using (var connection = new SqliteConnection(connectionString)) | ||
| { | ||
| List<Codingtracker> tabledata = connection.Query<Codingtracker>("SELECT * FROM coding_tracker").ToList(); | ||
|
|
||
| var table = new Table(); | ||
|
|
||
| table.AddColumn("Id"); | ||
| table.AddColumn("Start Time"); | ||
| table.AddColumn("End Time"); | ||
| table.AddColumn("Duration"); | ||
|
|
||
| foreach (var session in tabledata) | ||
| { | ||
| table.AddRow( | ||
| session.Id.ToString(), | ||
| session.StartTime.ToString(), | ||
| session.EndTime.ToString(), | ||
| session.Duration.ToString() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the |
||
| ); | ||
| } | ||
|
|
||
| AnsiConsole.Write(table); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| public static void Insert(DateTime startTime, DateTime endTime) | ||
| { | ||
|
|
||
| string duration = (endTime - startTime).ToString(); | ||
|
|
||
| using (var connection = new SqliteConnection(connectionString)) | ||
| { | ||
| int rowsAffected = connection.Execute("INSERT INTO coding_tracker (StartTime, EndTime, Duration) VALUES (@StartTime, @EndTime, @Duration)", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| new { StartTime = startTime, EndTime = endTime, Duration = duration }); | ||
| Console.WriteLine("Record Inserted.\nPress any key to return to main menu."); | ||
| Console.ReadKey(); | ||
| } | ||
| } | ||
|
|
||
| public static void Delete(int id) | ||
| { | ||
|
|
||
| using (var connection = new SqliteConnection(connectionString)) | ||
| { | ||
| int rowsAffected = connection.Execute("DELETE FROM coding_tracker WHERE Id = @Id", new { Id = id }); | ||
|
|
||
| if (rowsAffected == 0) | ||
| Console.WriteLine("No record found with that ID."); | ||
| else | ||
| Console.WriteLine("Record Deleted.\nPress any key to return to main menu."); | ||
|
|
||
| Console.ReadKey(); | ||
| } | ||
| } | ||
|
|
||
| public static void Update(int ID, DateTime startTime, DateTime endTime, string duration) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The parameter |
||
| { | ||
|
|
||
|
|
||
| using (var connection = new SqliteConnection(connectionString)) | ||
| { | ||
|
|
||
| int rowsAffected = connection.Execute("UPDATE coding_tracker SET StartTime = @StartTime, EndTime = @EndTime, Duration = @Duration WHERE ID = @Id", | ||
| new { Id = ID, StartTime = startTime, EndTime = endTime, Duration = duration }); | ||
|
|
||
| if (rowsAffected == 0) | ||
| { | ||
| Console.WriteLine("No record found with that ID."); | ||
| } | ||
| else | ||
| Console.WriteLine("Record Updated.\nPress any key to return to main menu."); | ||
|
|
||
| Console.ReadKey(); | ||
|
|
||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| // CodingSession.cs — the model | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment isn't necessary and can be removed to keep clutter to a minimum |
||
|
|
||
| public class Codingtracker | ||
| { | ||
| public int Id { get; set; } | ||
|
|
||
| public DateTime StartTime { get; set; } | ||
|
|
||
| public DateTime EndTime { get; set; } | ||
|
|
||
| public string Duration { get; set; } | ||
|
|
||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| using Microsoft.Data.Sqlite; | ||
| using Dapper; | ||
| using Spectre.Console; | ||
|
Comment on lines
+1
to
+3
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These using statements are never used and can be safely removed from this file |
||
|
|
||
| class Program1 | ||
| { | ||
| static string connectionString = @"Data Source=habit-Tracker.db"; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This variable is never used and can be safely removed |
||
|
|
||
| static void Main(string[] args) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No arguments are used in this method so the optional |
||
| { | ||
| { | ||
| CodingController.CreateTable(); | ||
| Input.GetUserInput(); | ||
| Console.ReadLine(); | ||
| } | ||
| } | ||
|
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is unnecessary and mostly adds clutter to the code. A good rule of thumb for something like this is that the class should be named something to where it's easy to understand the purpose of the class, that way you don't have to add a comment explaining what the class should do