Documentation added
This commit is contained in:
		@@ -1,5 +1,13 @@
 | 
				
			|||||||
#include "headers/Park_time.h"
 | 
					#include "headers/Park_time.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					initializes everything, id is auto incremented from what's stored in the db.
 | 
				
			||||||
 | 
					inmediately saves to db upon creation.
 | 
				
			||||||
 | 
					Also, this weird syntax is called an initializer list, and is the preffered
 | 
				
			||||||
 | 
					method of how to initialize members. It has a measurable performance increase
 | 
				
			||||||
 | 
					because it uses move semantics instead of copy semantics.
 | 
				
			||||||
 | 
					https://www.geeksforgeeks.org/when-do-we-use-initializer-list-in-c/
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
Park_time::Park_time(int c_id, int s_id)
 | 
					Park_time::Park_time(int c_id, int s_id)
 | 
				
			||||||
    : customer_id{c_id},
 | 
					    : customer_id{c_id},
 | 
				
			||||||
      spot_id{s_id},
 | 
					      spot_id{s_id},
 | 
				
			||||||
@@ -8,7 +16,9 @@ Park_time::Park_time(int c_id, int s_id)
 | 
				
			|||||||
      id{auto_increment_db() + 1} {
 | 
					      id{auto_increment_db() + 1} {
 | 
				
			||||||
    save_db();
 | 
					    save_db();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					this one initializes with data from the database. should probably only be used in the query functions.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
Park_time::Park_time(int id_, int customer_id_, int spot_id_, int start_,
 | 
					Park_time::Park_time(int id_, int customer_id_, int spot_id_, int start_,
 | 
				
			||||||
                     int duration_)
 | 
					                     int duration_)
 | 
				
			||||||
    : id{id_},
 | 
					    : id{id_},
 | 
				
			||||||
@@ -19,7 +29,12 @@ Park_time::Park_time(int id_, int customer_id_, int spot_id_, int start_,
 | 
				
			|||||||
    end = time_point<system_clock>(seconds(start_ + duration_));
 | 
					    end = time_point<system_clock>(seconds(start_ + duration_));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					simple checking if customer is clocking out at the right spot.
 | 
				
			||||||
 | 
					sets end(time of clocking out) and calculates the duration.
 | 
				
			||||||
 | 
					updates the info in the database.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void Park_time::clock_out(int c_id, int s_id) {
 | 
					void Park_time::clock_out(int c_id, int s_id) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (c_id != customer_id) {
 | 
					    if (c_id != customer_id) {
 | 
				
			||||||
@@ -52,7 +67,8 @@ std::ostream& operator<<(std::ostream& os, const Park_time& pt) {
 | 
				
			|||||||
    os << "- - - - - - - - - - - - - - - - - - - -\n";
 | 
					    os << "- - - - - - - - - - - - - - - - - - - -\n";
 | 
				
			||||||
    return os;
 | 
					    return os;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					// mostly a helper function to ease the conversion from timepoint to int
 | 
				
			||||||
 | 
					// for storing in the db
 | 
				
			||||||
int Park_time::start_to_int() {
 | 
					int Park_time::start_to_int() {
 | 
				
			||||||
    auto start_to_epoch = start.time_since_epoch();
 | 
					    auto start_to_epoch = start.time_since_epoch();
 | 
				
			||||||
    auto start_value = duration_cast<seconds>(start_to_epoch);
 | 
					    auto start_value = duration_cast<seconds>(start_to_epoch);
 | 
				
			||||||
@@ -64,6 +80,9 @@ int Park_time::start_to_int() {
 | 
				
			|||||||
// -----------------------------------------------------------------------------
 | 
					// -----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Park_time::save_db() {
 | 
					void Park_time::save_db() {
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					    this creates a sql statement and then executes it
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    string statement{"insert into Park_time values ( , , , , , );"};
 | 
					    string statement{"insert into Park_time values ( , , , , , );"};
 | 
				
			||||||
    statement.insert(41, "NULL");
 | 
					    statement.insert(41, "NULL");
 | 
				
			||||||
    statement.insert(39, "NULL");
 | 
					    statement.insert(39, "NULL");
 | 
				
			||||||
@@ -75,7 +94,7 @@ void Park_time::save_db() {
 | 
				
			|||||||
    data::db.exec(statement);
 | 
					    data::db.exec(statement);
 | 
				
			||||||
    transaction.commit();
 | 
					    transaction.commit();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					// same as above
 | 
				
			||||||
void Park_time::update_db() {
 | 
					void Park_time::update_db() {
 | 
				
			||||||
    string statement =
 | 
					    string statement =
 | 
				
			||||||
        "UPDATE Park_time SET end = , duration =  where id = '';";
 | 
					        "UPDATE Park_time SET end = , duration =  where id = '';";
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								data.cpp
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								data.cpp
									
									
									
									
									
								
							@@ -3,15 +3,25 @@
 | 
				
			|||||||
namespace data {
 | 
					namespace data {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SQLite::Database start_db() {
 | 
					SQLite::Database start_db() {
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					    Opens the database, creates it if it can't find the file.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    SQLite::Database db("test.db3",
 | 
					    SQLite::Database db("test.db3",
 | 
				
			||||||
                        SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
 | 
					                        SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
 | 
				
			||||||
    while (sodium_init() < 0) {
 | 
					    while (sodium_init() < 0) {
 | 
				
			||||||
        std::cout << "SODIUM NOT WORKING";
 | 
					        std::cout << "SODIUM NOT WORKING";
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					        This shouldn't be here, really, but I can't think of a better place
 | 
				
			||||||
 | 
					        where it runs at least once. This seeds the random generator needed for
 | 
				
			||||||
 | 
					        salts and other stuff, and needs to be run at least once when working
 | 
				
			||||||
 | 
					        with any libsodium function.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    //sql syntax is surprisingly readable.
 | 
				
			||||||
    db.exec(
 | 
					    db.exec(
 | 
				
			||||||
        "create table if not exists Customer (id integer primary key, name "
 | 
					        "create table if not exists Customer (id integer primary key, name "
 | 
				
			||||||
        "text, password text, verhicle int)");
 | 
					        "text, password text, verhicle int)");
 | 
				
			||||||
 | 
					        // getting errors when using bool, so i used an int instead.
 | 
				
			||||||
    db.exec(
 | 
					    db.exec(
 | 
				
			||||||
        "create table if not exists Park_spot (id integer primary key, taken "
 | 
					        "create table if not exists Park_spot (id integer primary key, taken "
 | 
				
			||||||
        "int, customer_id int)");
 | 
					        "int, customer_id int)");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,14 @@
 | 
				
			|||||||
#include "headers/encrypt.h"
 | 
					#include "headers/encrypt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
string hash_password(string password) {
 | 
					string hash_password(string password) {
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
    Passing strings and converting to char* because I do not want to be forced
 | 
					    Passing strings and converting to char* because I do not want to be forced
 | 
				
			||||||
    to use char * whenever I want to call the function. Low level stuff in the
 | 
					    to use char * whenever I want to call the function. Low level stuff in the
 | 
				
			||||||
    function, the least possible low level stuff outside.
 | 
					    function, the least possible low level stuff outside.
 | 
				
			||||||
 | 
					    This uses the password hashing algorithm Argon2 implemented by libsodium.
 | 
				
			||||||
 | 
					    DO NOT MODIFY memory_limit and cpu_limit after you add customers to the db.
 | 
				
			||||||
 | 
					    When you do that, the hashed passwords can't be decrypted, and that would be
 | 
				
			||||||
 | 
					    BAD
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    const char* password_ = password.c_str();
 | 
					    const char* password_ = password.c_str();
 | 
				
			||||||
    char hashed_password_[crypto_pwhash_STRBYTES];
 | 
					    char hashed_password_[crypto_pwhash_STRBYTES];
 | 
				
			||||||
@@ -23,6 +26,9 @@ string hash_password(string password) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool verify_password(string hashed_password, string unhashed_password) {
 | 
					bool verify_password(string hashed_password, string unhashed_password) {
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					    this verifies the password. It's encryption magic and don't question it.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    const char* password_ = unhashed_password.c_str();
 | 
					    const char* password_ = unhashed_password.c_str();
 | 
				
			||||||
    const char* hashed_password_ = hashed_password.c_str();
 | 
					    const char* hashed_password_ = hashed_password.c_str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,17 +9,29 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using std::vector;
 | 
					using std::vector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// will make it easy to represent it in the database while making it easy to use
 | 
					/*
 | 
				
			||||||
// while programming
 | 
					enum classes make it easy to represent categories.
 | 
				
			||||||
 | 
					So you can use something like Verhicle_type::car instead of 2. but under the
 | 
				
			||||||
 | 
					hood, it's still an int. This is here so you won't have to have global variables
 | 
				
			||||||
 | 
					for these categories, or worse, use magic numbers in the code.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
enum class Verhicle_type { bike = 1, small_car = 2, suv = 3, pickup = 4 };
 | 
					enum class Verhicle_type { bike = 1, small_car = 2, suv = 3, pickup = 4 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
card code is een randomly generated string moeten zijn, die je bv. op een nfc
 | 
					Customer constructors do the same stuff as all the other constructors.
 | 
				
			||||||
card zou opslaan en zo zou authenticaten bij je parking spot. We kunnen dit ipv
 | 
					clock_in and out create and modify park_time objects and store them to
 | 
				
			||||||
of samen met een password gebruiken. clock in en out creeert en compleet een
 | 
					park_instances. Technically, now that we have a working db, we don't need it.
 | 
				
			||||||
park_time object. Voegt het toe aan een vector.
 | 
					TODO: fix this.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*/
 | 
					gen_monthly just prints out all the park_time objects in park_instances.
 | 
				
			||||||
 | 
					It should (and can safely) be removed, but it's here as a quick example of
 | 
				
			||||||
 | 
					report generation It has no logic to speak of that only generates report of
 | 
				
			||||||
 | 
					ptime objects of this month.
 | 
				
			||||||
 | 
					TODO: remove when have seperate report generation functions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					save, update, delete and auto increment are the same as in park_time.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Customer {
 | 
					class Customer {
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
@@ -27,9 +39,7 @@ class Customer {
 | 
				
			|||||||
    string name;
 | 
					    string name;
 | 
				
			||||||
    string password;
 | 
					    string password;
 | 
				
			||||||
    Customer(string name_, string password_, Verhicle_type verhicle_);
 | 
					    Customer(string name_, string password_, Verhicle_type verhicle_);
 | 
				
			||||||
    Customer(int id_, string name_, // needed to construct from db
 | 
					    Customer(int id_, string name_, string password_, Verhicle_type verhicle_,
 | 
				
			||||||
             string password_,
 | 
					 | 
				
			||||||
             Verhicle_type verhicle_, // TODO: how init. p_time instances?
 | 
					 | 
				
			||||||
             vector<Park_time> instances);
 | 
					             vector<Park_time> instances);
 | 
				
			||||||
    void clock_in(int s_id);
 | 
					    void clock_in(int s_id);
 | 
				
			||||||
    void clock_out(int s_id);
 | 
					    void clock_out(int s_id);
 | 
				
			||||||
@@ -37,7 +47,7 @@ class Customer {
 | 
				
			|||||||
    void update_db();
 | 
					    void update_db();
 | 
				
			||||||
    void delete_db();
 | 
					    void delete_db();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void gen_monthly(); // remove, make it a function in data
 | 
					    void gen_monthly();
 | 
				
			||||||
    Verhicle_type verhicle;
 | 
					    Verhicle_type verhicle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private:
 | 
					  private:
 | 
				
			||||||
@@ -46,5 +56,4 @@ class Customer {
 | 
				
			|||||||
    int auto_increment_db();
 | 
					    int auto_increment_db();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif // CUSTOMER_H
 | 
					#endif // CUSTOMER_H
 | 
				
			||||||
@@ -17,6 +17,28 @@ using std::to_string;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Record of who parked at what park_spot and at what time.
 | 
					Record of who parked at what park_spot and at what time.
 | 
				
			||||||
 | 
					public interface-------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The constructors. one for creating new customers, the other one used by the
 | 
				
			||||||
 | 
					query functions to construct the object from information stored in the database.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					clock_out is the function that gets called from customer.clock_out().
 | 
				
			||||||
 | 
					It verifies that the customer is clocking out at the correct parkspot, and saves
 | 
				
			||||||
 | 
					the current time of clocking out in end. It also calculates duration so it
 | 
				
			||||||
 | 
					doesn't have to be calculated more than once.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					operator<< is << overload, can(should) be used for report generation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// implementation stuff------------------------
 | 
				
			||||||
 | 
					start and end are time points representing when someone clocks in and out. they're from the chrono namespace.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					save and update save and update info in the database.
 | 
				
			||||||
 | 
					auto_increment pulls the highest id stored in the db, to be used in the constructor.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					start_to_int() is used to convert the start timepoint to an integer that can be saved in the database
 | 
				
			||||||
 | 
					SQL datetime and chrono datetime don't seem the most compatible.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Park_time {
 | 
					class Park_time {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,17 +4,57 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "Park_spot.h"
 | 
					#include "Park_spot.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <array>
 | 
					/*these are the functions that search the database and create objects from it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					query_parktimes_for_customer searches for the parktimes  that are needed in
 | 
				
			||||||
 | 
					customer initialisaiton. generally, i see no use outside of that.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					query_customer_with_name searches for customer data by name.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					query_customer_with_id does what the above does, but with id.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					populate_spots is used to query for all the park_spots and return them as
 | 
				
			||||||
 | 
					objects.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The design desision to use vector<T> instead of <T> is for the following
 | 
				
			||||||
 | 
					reasons:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. some of these can potentially return more than one object. For example, 2
 | 
				
			||||||
 | 
					customers who have the same name.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. I have no clue how many of you have done error handling in c++
 | 
				
			||||||
 | 
					(try/catch/finally).
 | 
				
			||||||
 | 
					Ya boi is nice and doesn't want to bombard you with more new concepts than needed.
 | 
				
			||||||
 | 
					so now you'd do 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vector<Customer> test = query_customer_with_name("Testman");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!test.size()) {print no customers found, do stuff}
 | 
				
			||||||
 | 
					else if (test.size() > 1) { do stuff to get the right one if you only need one
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instead of 
 | 
				
			||||||
 | 
					try {
 | 
				
			||||||
 | 
					    customer test = query_customer_with_name("Testman");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					catch(someException.probablycalled_not_found) {do_Stuff};
 | 
				
			||||||
 | 
					catch(...) {
 | 
				
			||||||
 | 
					    do stuff
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					finally{
 | 
				
			||||||
 | 
					    do more stuff
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. Ya boi needs to brush up on how to create custom exceptions class, and it will complicate code furhter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vector<Park_time> query_parktimes_for_customer(int cid);
 | 
					vector<Park_time> query_parktimes_for_customer(int cid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vector<Customer> query_customer_with_name(string name);
 | 
					vector<Customer> query_customer_with_name(string name);
 | 
				
			||||||
Customer query_customer_with_id(int id);
 | 
					Customer query_customer_with_id(int id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// vector<Park_spot> query_all_parking_spots(); // used for initializing the parking spots at start of the program
 | 
					 | 
				
			||||||
vector<Park_spot> populate_spots();
 | 
					vector<Park_spot> populate_spots();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif // CUSTOMER_H
 | 
					#endif // CUSTOMER_H
 | 
				
			||||||
@@ -5,8 +5,13 @@
 | 
				
			|||||||
#include "encrypt.h"
 | 
					#include "encrypt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace data {
 | 
					namespace data {
 | 
				
			||||||
SQLite::Database start_db();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					start_db is the function that opens the database, and
 | 
				
			||||||
 | 
					if the necesary tables are not there, creates them. 
 | 
				
			||||||
 | 
					db is the database, and is static to avoid multiple redefinition errors. 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					SQLite::Database start_db();
 | 
				
			||||||
static SQLite::Database db = start_db();
 | 
					static SQLite::Database db = start_db();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace data
 | 
					} // namespace data
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,12 +2,20 @@
 | 
				
			|||||||
#define ENCRYPT_H
 | 
					#define ENCRYPT_H
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include <cstring>
 | 
					#include <cstring>
 | 
				
			||||||
#include <sodium.h>
 | 
					 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <sodium.h>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using std::string;
 | 
					using std::string;
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					hash_password takes the password, and encrypts it. This needs to be done,
 | 
				
			||||||
 | 
					because storing passwords in plaintext is BAD! 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					verify_password takes in a password and the hashed password, and then does magic encryption stuff(no, not
 | 
				
			||||||
 | 
					really. It basically hashes the password with the same salt and other
 | 
				
			||||||
 | 
					parameters) and to see if the password stored and the given password match.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
string hash_password(string password);
 | 
					string hash_password(string password);
 | 
				
			||||||
bool verify_password(string hashed_password, string unhashed_password);
 | 
					bool verify_password(string hashed_password, string unhashed_password);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user