10 Commits

23 changed files with 551 additions and 150 deletions

View File

@ -5,7 +5,7 @@ IndentWidth: 4
Language: Cpp
PointerAlignment: Left
ColumnLimit: 80
ColumnLimit: 100
AlignAfterOpenBracket: Align
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true

36
Admin.cpp Normal file
View File

@ -0,0 +1,36 @@
#include "headers/Admin.h"
using std::to_string;
Admin::Admin(string name_, string password_)
: id{auto_increment_db() + 1}, name{name_}, password{hash_password(password_)} {
save_db();
}
Admin::Admin(int id_, string name_, string password_) : id{id_}, name{name_}, password{password_} {}
void Admin::save_db() {
string statement{"insert into Admin values (, '', '');"};
statement.insert(33, password);
statement.insert(29, name);
statement.insert(26, to_string(id));
SQLite::Transaction transaction(data::db);
data::db.exec(statement);
transaction.commit();
}
void Admin::update_db() {
string statement = "UPDATE Admin SET name = '', password = '' where id = '';";
statement.insert(54, to_string(id));
statement.insert(40, password);
statement.insert(25, name);
data::db.exec(statement);
}
int Admin::auto_increment_db() {
SQLite::Statement max_id(data::db, "select max(id) from Admin;");
int id = 0;
max_id.executeStep();
id = max_id.getColumn(0);
max_id.reset();
return id;
}

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.11)
cmake_minimum_required(VERSION 3.10)
project(park)
set(CMAKE_CXX_STANDARD 11)
@ -23,8 +23,12 @@ add_executable(park
headers/Park_spot.h
Park_time.cpp
headers/Park_time.h
Admin.cpp
headers/Admin.h
Query.cpp
headers/Query.h
Interface.cpp
headers/Interface.h
)

View File

@ -1,20 +1,24 @@
#include "headers/Customer.h"
// constructors
Customer::Customer(string name_, string password_, Verhicle_type verhicle_)
: name{name_}, verhicle{verhicle_}, password{hash_password(password_)} {
id = auto_increment_db() + 1;
Customer::Customer(string name_, string password_, Vehicle_type vehicle_, string telephone_)
: id{auto_increment_db() + 1},
name{name_},
password{hash_password(password_)},
vehicle{vehicle_},
telephone{telephone_} {
save_db();
}
Customer::Customer(int id_, string name_, string password_,
Verhicle_type verhicle_, vector<Park_time> instances)
:id{id_},
name{name_},
Customer::Customer(int id_, string name_, string password_, Vehicle_type vehicle_,
vector<Park_time> instances, string telephone_)
: id{id_},
name{name_},
password{password_},
verhicle{verhicle_},
park_instances{instances} {}
vehicle{vehicle_},
park_instances{instances},
telephone{telephone_} {}
// clock in/out methods
// ====================================================================================
@ -31,28 +35,33 @@ void Customer::clock_out(int s_id) {
park_instances[park_instances.size() - 1].clock_out(id, s_id);
}
// report gen
void Customer::gen_monthly() {
cout << "NAME: " << name << "\n";
cout << "-------------------------------------------------\n";
for (auto& i : park_instances) {
// TODO: need some logic to only include from this month. scratch that,
// need to remove gen monthly
cout << i;
bool Customer::parked() {
if (!park_instances.size()) {
return false;
}
if ((park_instances[park_instances.size() - 1].duration)) {
// if duration of the last parktime == 0, meaning
// that the customer has not clocked out
return false;
} else {
return true;
}
cout << "-------------------------------------------------\n\n";
}
int Customer::parked_at() { return park_instances[park_instances.size() - 1].spot_id; }
//================================================================================================
// functions that interact with the database
void Customer::save_db() {
string statement{"insert into Customer values (, '', '', );"};
string statement{"insert into Customer values (, '', '', ,'');"};
// after ( = 28)
statement.insert(38, to_string(int(verhicle)));
statement.insert(41, telephone);
statement.insert(38, to_string(int(vehicle)));
statement.insert(36, password);
statement.insert(32, name);
statement.insert(29, to_string(id));
// cout << statement;
SQLite::Transaction transaction(data::db);
data::db.exec(statement);
transaction.commit();
@ -60,10 +69,14 @@ void Customer::save_db() {
void Customer::update_db() {
string statement =
"UPDATE Customer SET name = '', card_code = '' where id = '';";
statement.insert(58, to_string(id));
statement.insert(44, password);
"UPDATE Customer SET name = '', password = '', "
"vehicle = '', telephone = '' where id = '';";
statement.insert(87, to_string(id));
statement.insert(73, telephone);
statement.insert(57, to_string(int(vehicle)));
statement.insert(43, password);
statement.insert(28, name);
// cout << statement;
data::db.exec(statement);
}
@ -83,5 +96,3 @@ int Customer::auto_increment_db() {
max_id.reset();
return id;
}

218
Interface.cpp Normal file
View File

@ -0,0 +1,218 @@
#include "headers/Interface.h"
// I added it to pass spots, because the parking options need it to check where
// is free parking_spots is declared in main, and if i declare it
// liberal use of
// cin.ignore(10000, '\n');
// so it skips to the next newline, in essence clearing the cin buffer
void interface(vector<Park_spot>& spots) {
int selector;
cout << "\nHello and welcome to the parking spot! Please select a suitable "
"option:";
cout << "\n[1]Log in as member";
cout << "\n[2]Log in as administrator";
cin >> selector;
cin.ignore(10000, '\n');
switch (selector) {
case 1: {
interface_member(spots);
break;
}
case 2: {
interface_admin(spots);
break;
}
}
}
void interface_member(vector<Park_spot>& spots) {
int id;
string password;
cout << "\nPlease input id:";
cin >> id;
cin.ignore(10000, '\n');
Customer c = query_customer_with_id(id);
cout << "\nPlease input password:";
std::getline(cin, password);
while (!(verify_password(c.password, password))) {
cout << "ERROR: wrong password. Please retype your password:\n";
std::getline(cin, password);
}
cout << "Logged in succesfully\n";
cout << "select an option\n [1] Parking options\n[2]monthy report\n";
int option;
cin >> option;
cin.ignore(10000, '\n');
switch (option) {
case 1: {
park(c, spots);
break;
}
case 2: {
cout << "Has not been implemented yet\n";
break;
}
default:
break;
}
}
void interface_admin(vector<Park_spot>& spots) {
int id;
string password;
cout << "\nPlease input id:";
cin >> id;
cin.ignore(10000, '\n');
cin.clear();
Admin admin = query_admin_with_id(id);
cout << "\nPlease input password:";
std::getline(cin, password);
while (!(verify_password(admin.password, password))) {
cout << "ERROR: wrong password. Please retype your password:\n";
std::getline(cin, password);
}
cout << "Logged in succesfully\n";
cout << "Welcome to the admin interface. It is not completely ready yet.\n";
cout << "[1] See monthly report of ALL parking spots\n";
cout << "[2] See weekly report of ALL parking spots\n";
cout << "[3] See monthly report of a specific parking spot\n";
cout << "[4] See weekly report of a specific parking spot\n";
cout << "[5] See current status of parking spots\n";
cout << "[6] Make new customer\n";
cout << "[7] Make new parking spot\n";
cout << "[8] Make new Admin\n";
cout << "option[1-8]:";
int option;
cin >> option;
cin.ignore(10000, '\n');
switch (option) {
case 1: {
reports_from_allparkspots();
break;
}
case 2: {
reports_from_allparkspots(true);
break;
}
case 3: {
cout << "Which parking spot would you like a report on?ID:";
int spotid;
cin >> spotid;
cin.ignore(10000, '\n');
reports_from_parkspot(spotid);
break;
}
case 4: {
cout << "Which parking spot would you like a report on?ID:";
int spotid;
cin >> spotid;
cin.ignore(10000, '\n');
reports_from_parkspot(spotid, true);
break;
}
case 5: {
current_status_parkspots(spots);
break;
}
case 6: {
new_customer();
break;
}
case 7: {
new_parkspot(spots);
break;
}
case 8: {
new_admin();
break;
}
default:
break;
}
}
// --------- individual things.
void park(Customer& c, vector<Park_spot>& spots) {
cout << "You have selected parking option";
if (!(c.parked())) {
cout << "The following spots[which can fit your vehicle] are "
"available: ";
for (Park_spot i : spots) {
if (i.v_type == c.vehicle && !(i.taken)) {
cout << i.id << ", ";
}
}
cout << "where do you want to park?";
int parkid;
cin >> parkid;
cin.ignore(10000, '\n');
for (Park_spot& i : spots) {
if (i.id == parkid) {
i.clock(c);
cout << "You have parked sucessfully";
}
}
} else {
cout << "You are parked at spot " << c.parked_at()
<< ", do you want to clock out?\n enter [1] for yes and [0] for no";
int answer = 0;
cin >> answer;
cin.ignore(10000, '\n');
if (answer) {
query_parkspot_with_id(c.parked_at(), spots).clock(c);
cout << "You have sucessfully clocked out.";
} else {
cout << "OK, have a nice day";
}
}
}
void new_customer() {
int vtype;
string name;
string password;
string telephone;
cout << "What's the name of the customer? ";
std::getline(cin, name);
cout << "What's the vehicle type? [1]twoweeler, [2] fourweeler: ";
cin >> vtype;
cin.ignore(10000, '\n');
cout << "What's the telephone number? ";
std::getline(cin, telephone);
cout << "What's the password?";
std::getline(cin, password);
Customer newcustomer{name, password, Vehicle_type(vtype), telephone};
cout << "New customer sucessfully created\n";
newcustomer.update_db();
}
void new_admin() {
string name;
string password;
cout << "What's the name of the admin? ";
std::getline(cin, name);
cout << "What's the password?";
std::getline(cin, password);
Admin newadmin{name, password};
cout << "New admin sucessfully created\n";
newadmin.update_db();
}
void new_parkspot(vector<Park_spot>& spots) {
cout << "What type of parking spot? [1] twoweeler, [2] fourweeler: ";
int vtype;
cin >> vtype;
cin.ignore(10000, '\n');
Park_spot newspot{Vehicle_type(vtype)};
spots.push_back(newspot);
cout << "new parking spot sucessfully created.\n";
}

View File

@ -2,18 +2,18 @@
// constructors
Park_spot::Park_spot()
: parked_customer{0}, id{auto_increment_db() + 1}, taken{false} {
Park_spot::Park_spot(Vehicle_type v_type_)
: parked_customer{0}, id{auto_increment_db() + 1}, taken{false}, v_type{v_type_} {
save_db();
}
Park_spot::Park_spot(int id_, bool taken_, int parked)
Park_spot::Park_spot(int id_, bool taken_, int parked, Vehicle_type v_type_)
: parked_customer{parked},
id{id_},
v_type{v_type_},
taken{taken_} // TODO: think about how init parked?
{}
// clock in en out, calls de juist(in/out) van de customer aan de hand van
// internal state van taken
void Park_spot::clock(Customer& c_customer) {
@ -33,8 +33,7 @@ void Park_spot::clock(Customer& c_customer) {
// --------------------- db functs
void Park_spot::update_db() {
string statement =
"UPDATE Park_spot SET taken = '', customer_id = '' where id = '';";
string statement = "UPDATE Park_spot SET taken = '', customer_id = '' where id = '';";
statement.insert(63, to_string(id));
if (taken) {
statement.insert(49, to_string(parked_customer));
@ -48,8 +47,9 @@ void Park_spot::update_db() {
void Park_spot::save_db() {
//(int id, bool taken, int customer_id)
string statement{"insert into Park_spot values ( , , );"};
string statement{"insert into Park_spot values ( , , , );"};
// after ( = 28)
statement.insert(36, to_string(int(v_type)));
statement.insert(34, "NULL");
statement.insert(32, "0");
statement.insert(30, to_string(id));

View File

@ -17,14 +17,11 @@ Park_time::Park_time(int c_id, int s_id)
save_db();
}
/*
this one initializes with data from the database. should probably only be used in the query functions.
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_,
int duration_)
: id{id_},
customer_id{customer_id_},
spot_id{spot_id_},
duration{duration_} {
Park_time::Park_time(int id_, int customer_id_, int spot_id_, int start_, int duration_)
: id{id_}, customer_id{customer_id_}, spot_id{spot_id_}, duration{duration_} {
start = time_point<system_clock>(seconds(start_));
end = time_point<system_clock>(seconds(start_ + duration_));
}
@ -48,8 +45,7 @@ void Park_time::clock_out(int c_id, int s_id) {
if (!duration) {
end = high_resolution_clock::now();
duration =
duration_cast<seconds>(end - start).count(); // use mins later
duration = duration_cast<seconds>(end - start).count(); // use mins later
update_db();
} else {
@ -61,6 +57,7 @@ std::ostream& operator<<(std::ostream& os, const Park_time& pt) {
std::time_t start_ = system_clock::to_time_t(pt.start);
std::time_t end_ = system_clock::to_time_t(pt.end);
os << "- - - - - - - - - - - - - - - - - - - -\n";
os << "Customer # " << pt.customer_id << "at parking spot " << pt.spot_id << "\n";
os << "Clocked in :" << std::ctime(&start_);
os << "clocked out : " << std::ctime(&end_);
os << "duration : " << pt.duration << "\n";
@ -96,8 +93,7 @@ void Park_time::save_db() {
}
// same as above
void Park_time::update_db() {
string statement =
"UPDATE Park_time SET end = , duration = where id = '';";
string statement = "UPDATE Park_time SET end = , duration = where id = '';";
statement.insert(53, to_string(id));
statement.insert(40, to_string(duration));
statement.insert(27, to_string(start_to_int() + duration));
@ -113,3 +109,16 @@ int Park_time::auto_increment_db() {
max_id.reset();
return id;
}
//------------------ test function to help test this
void Wait(int sec)
{
/*
a wait function where 1 sec represents 1 hour irl. It has been used for testing
purposes mostly. TODO: Needs to be removed at completion of project, or seperated in a test
cpp/header
*/
std::this_thread::sleep_for(seconds{sec});
}

128
Query.cpp
View File

@ -1,6 +1,5 @@
#include "headers/Query.h"
vector<Park_time> query_parktimes_for_customer(int cid) {
/*
This is needed to initialize the park_instances for the customer constructor
@ -9,8 +8,7 @@ vector<Park_time> query_parktimes_for_customer(int cid) {
*/
vector<Park_time> park_times;
SQLite::Statement query(data::db,
"SELECT * FROM Park_time WHERE customer_id = ?;");
SQLite::Statement query(data::db, "SELECT * FROM Park_time WHERE customer_id = ?;");
query.bind(1, cid);
while (query.executeStep()) {
int id = query.getColumn(0);
@ -25,10 +23,8 @@ vector<Park_time> query_parktimes_for_customer(int cid) {
return park_times;
}
//--------------------------------------------- customers
vector<Customer> query_customer_with_name(string name) {
/*
We use this instead of plain customers because:
@ -36,18 +32,18 @@ vector<Customer> query_customer_with_name(string name) {
2. multiple customers could be returned with the same name.
*/
vector<Customer> result;
SQLite::Statement query(
data::db,
"SELECT id, name, password, verhicle FROM Customer WHERE name = ?;");
SQLite::Statement query(data::db,
"SELECT id, name, password, vehicle FROM Customer WHERE name = ?;");
query.bind(1, name);
while (query.executeStep()) {
int id = query.getColumn(0);
string name_ = query.getColumn(1);
string password = query.getColumn(2);
int verhicle = query.getColumn(3); // cast to verhicle
int vehicle = query.getColumn(3); // cast to vehicle
string telephone = query.getColumn(4);
vector<Park_time> park_instances = query_parktimes_for_customer(id);
result.push_back(Customer{
id, name_, password, Verhicle_type(verhicle), park_instances});
result.push_back(
Customer{id, name_, password, Vehicle_type(vehicle), park_instances, telephone});
}
return result;
}
@ -65,24 +61,118 @@ Customer query_customer_with_id(int id) {
while (query.executeStep()) {
string name = query.getColumn(1);
string password = query.getColumn(2);
int verhicle = query.getColumn(3); // cast to verhicle
int vehicle = query.getColumn(3); // cast to vehicle
string telephone = query.getColumn(4);
vector<Park_time> park_instances = query_parktimes_for_customer(id);
Customer result{
id, name, password, Verhicle_type(verhicle), park_instances};
// DEBUG
// cout << "{" << result.id << "," <<result.password <<"," << int(verhicle) << "}\n";
Customer result{id, name, password, Vehicle_type(vehicle), park_instances, telephone};
return result;
}
}
//----------------- ADMIN
Admin query_admin_with_id(int id) {
SQLite::Statement query(data::db, "SELECT * FROM Customer WHERE id = ?;");
query.bind(1, id);
while (query.executeStep()) {
string name = query.getColumn(1);
string password = query.getColumn(2);
Admin result{id, name, password};
return result;
}
}
//------------------------------- parkspot info
Park_spot query_parkspot_with_id(int id, vector<Park_spot>& parkspots) {
for (Park_spot& i : parkspots) {
if (i.id == id) {
return i;
}
}
}
void reports_from_parkspot(int spotid, bool weekly) {
std::time_t t = std::time(0); // get time now
std::tm* now = std::localtime(&t);
if (weekly) {
now->tm_wday = 1;
} else {
now->tm_mday = 1;
}
int s_since_epoch = mktime(now);
vector<Park_time> park_times;
SQLite::Statement query(data::db, "SELECT * FROM Park_time WHERE spot_id = ? AND start > ?;");
query.bind(1, spotid);
query.bind(2, s_since_epoch);
while (query.executeStep()) {
int id = query.getColumn(0);
int cid = query.getColumn(1);
int start = query.getColumn(3);
int duration = query.getColumn(5);
Park_time result{id, cid, spotid, start, duration};
park_times.push_back(result);
}
query.reset();
for (auto i : park_times) {
cout << i;
}
}
void reports_from_allparkspots(bool weekly) {
std::time_t t = std::time(0); // get time now
std::tm* now = std::localtime(&t);
if (weekly) {
now->tm_wday = 1;
} else {
now->tm_mday = 1;
}
int s_since_epoch = mktime(now);
vector<Park_time> park_times;
SQLite::Statement query(data::db, "SELECT * FROM Park_time WHERE start > ?;");
query.bind(1, s_since_epoch);
while (query.executeStep()) {
int id = query.getColumn(0);
int cid = query.getColumn(1);
int spotid = query.getColumn(2);
int start = query.getColumn(3);
int duration = query.getColumn(5);
Park_time result{id, cid, spotid, start, duration};
park_times.push_back(result);
}
query.reset();
for (auto i : park_times) {
cout << i;
}
}
void current_status_parkspots(vector<Park_spot>& spots) {
for (auto& i : spots) {
cout << "---------------------------\n";
cout << "PS #" << i.id << "\n";
cout << "Taken: " << ((i.taken) ? "true" : "false") << "\n";
if (i.taken) {
cout << "Customer#" << i.parked_customer << " parked there\n";
}
}
}
// -------------- paroking spots
// vector<Park_spot> populate_spots(){
// vector<Park_spot> spots;
// SQLite::Statement query(data::db, "SELECT * FROM Park_spot WHERE id > 0;");
// SQLite::Statement query(data::db, "SELECT * FROM Park_spot WHERE id >
// 0;");
// // query.bind(1, 2);
// while (query.executeStep()) {
// int id = query.getColumn(0);

View File

@ -6,8 +6,7 @@ SQLite::Database start_db() {
/*
Opens the database, creates it if it can't find the file.
*/
SQLite::Database db("test.db3",
SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
while (sodium_init() < 0) {
std::cout << "SODIUM NOT WORKING";
/*
@ -17,17 +16,16 @@ SQLite::Database start_db() {
with any libsodium function.
*/
}
//sql syntax is surprisingly readable.
db.exec(
"create table if not exists Customer (id integer primary key, name "
"text, password text, verhicle int)");
// getting errors when using bool, so i used an int instead.
"text, password text, vehicle int, telephone text);");
db.exec(
"create table if not exists Park_spot (id integer primary key, taken "
"int, customer_id int)");
"int, customer_id int, vehicle_type int);");
db.exec(
"create table if not exists Park_time (id integer primary key, "
"customer_id int, spot_id int, start int, end int, duration int)");
"customer_id int, spot_id int, start int, end int, duration int);");
db.exec("create table if not exists Admin (id int primary key, name text, password text);");
return db;
}

View File

@ -15,11 +15,8 @@ string hash_password(string password) {
int memory_limit = 3.2e+7; // 3.2e7 = 32e6 = 32 mb
int cpu_limit = 1; // this is n_threads
int result = crypto_pwhash_str(hashed_password_,
password_,
strlen(password_),
cpu_limit,
memory_limit);
int result =
crypto_pwhash_str(hashed_password_, password_, strlen(password_), cpu_limit, memory_limit);
string hashed_password{hashed_password_};
return hashed_password;
@ -32,8 +29,7 @@ bool verify_password(string hashed_password, string unhashed_password) {
const char* password_ = unhashed_password.c_str();
const char* hashed_password_ = hashed_password.c_str();
if (crypto_pwhash_str_verify(
hashed_password_, password_, strlen(password_)) != 0) {
if (crypto_pwhash_str_verify(hashed_password_, password_, strlen(password_)) != 0) {
return false;
} else {
return true;

BIN
graph.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

21
headers/Admin.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef ADMIN_H
#define ADMIN_H
#pragma once
#include "data.h"
class Admin {
public:
int id;
string name;
string password;
Admin(string name_, string password_);
Admin(int id_, string name_, string password);
// private:
void update_db();
void save_db();
int auto_increment_db();
};
#endif // CUSTOMER_H

View File

@ -3,7 +3,6 @@
#pragma once
#include "Park_time.h"
#include "data.h"
#include <vector>
@ -11,12 +10,12 @@ using std::vector;
/*
enum classes make it easy to represent categories.
So you can use something like Verhicle_type::car instead of 2. but under the
So you can use something like Vehicle_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 Vehicle_type { twoweeler = 1, fourweeler = 2 };
/*
Customer constructors do the same stuff as all the other constructors.
@ -38,18 +37,19 @@ class Customer {
int id;
string name;
string password;
Customer(string name_, string password_, Verhicle_type verhicle_);
Customer(int id_, string name_, string password_, Verhicle_type verhicle_,
vector<Park_time> instances);
Vehicle_type vehicle;
string telephone;
Customer(string name_, string password_, Vehicle_type vehicle_, string telephone_);
Customer(int id_, string name_, string password_, Vehicle_type vehicle_,
vector<Park_time> instances, string telephone_);
void clock_in(int s_id);
void clock_out(int s_id);
bool parked();
int parked_at();
void update_db();
void delete_db();
void gen_monthly();
Verhicle_type verhicle;
private:
vector<Park_time> park_instances;
void save_db();

14
headers/Interface.h Normal file
View File

@ -0,0 +1,14 @@
#include "Query.h"
using std::cin;
void interface(vector<Park_spot>& spots);
void interface_member(vector<Park_spot>& spots);
void interface_admin(vector<Park_spot>& spots);
void park(Customer& c, vector<Park_spot>& spots);
void new_customer();
void new_parkspot(vector<Park_spot>& spots);
void new_admin();

View File

@ -18,8 +18,10 @@ class Park_spot {
int id;
bool taken;
int parked_customer;
Park_spot();
Park_spot(int id_, bool taken_, int parked);
Vehicle_type v_type;
Park_spot(Vehicle_type v_type_);
Park_spot(int id_, bool taken_, int parked, Vehicle_type v_type_);
void clock(Customer& c_customer);
private:

View File

@ -8,6 +8,7 @@
#include <ctime>
#include <iostream>
#include <string>
#include <thread>
using namespace std::chrono;
using std::cout;
@ -31,21 +32,21 @@ 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.
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.
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 {
public:
Park_time(int c_id, int s_id);
Park_time(int id_, int customer_id_, int spot_id_, int start_,
int duration_);
Park_time(int id_, int customer_id_, int spot_id_, int start_, int duration_);
int id;
int customer_id;
int spot_id;
@ -63,4 +64,7 @@ class Park_time {
int start_to_int(); // helper
};
// test funciton
void Wait(int sec);
#endif // Park_time

View File

@ -3,6 +3,7 @@
#pragma once
#include "Park_spot.h"
#include "Admin.h"
/*these are the functions that search the database and create objects from it.
@ -25,7 +26,7 @@ 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.
I dont want to bombard you with more new concepts than needed.
so now you'd do
vector<Customer> test = query_customer_with_name("Testman");
@ -46,8 +47,6 @@ 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);
@ -55,6 +54,11 @@ vector<Park_time> query_parktimes_for_customer(int cid);
vector<Customer> query_customer_with_name(string name);
Customer query_customer_with_id(int id);
vector<Park_spot> populate_spots();
Admin query_admin_with_id(int id);
vector<Park_spot> populate_spots();
Park_spot query_parkspot_with_id(int id, vector<Park_spot>& parkspots);
void reports_from_parkspot(int spotid, bool weekly = false);
void reports_from_allparkspots(bool weekly = false);
void current_status_parkspots(vector<Park_spot>& spots);
#endif // CUSTOMER_H

View File

@ -12,9 +12,9 @@ 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.
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);

View File

@ -1,9 +1,5 @@
#include "headers/Query.h"
#include <thread>
using namespace std::chrono;
#include "headers/Interface.h"
#include "headers/Admin.h"
/*
Code structure is like this:
@ -44,43 +40,16 @@ headers. Explanations of how the member functions work(Or how I intended for
them to work) are in the respective .cpp files. void Wait(int sec)
*/
void Wait(int sec)
{
/*
a wait function where 1 sec represents 1 hour irl. It has been used for testing
purposes mostly.
TODO: Needs to be removed at completion of project, or seperated in a test
cpp/header
*/
std::this_thread::sleep_for(seconds{sec});
}
static vector<Park_spot> parking_spots = populate_spots();
// this queries the db for all the saved parking_spots and initializes them
static vector<Customer> park_customers;
/*
This was meant for an older implementation. park_time objects used to store
pointers to customers and in order to not get dangling pointers(dangerous!) I
had to have a way to store the customers the pointer pointed to so they didn't
get destroyed prematurely(I could've used the lower-level, more dangerous new,
or worse, malloc, but that's ugly).
For now, it's just here in case you want an easy way to store customers.
*/
int main() {
Customer sagar = query_customer_with_name("stefan udit")[0];
Customer sagar1 = query_customer_with_id(2);
cout << sagar.id << "," << sagar.name << "," << sagar.password << "\n";
cout << sagar1.id << "," << sagar1.name << "," << sagar1.password;
cout << parking_spots.size();
for (auto i : parking_spots) {
cout << "\n" << i.id << "," << i.parked_customer;
}
populate_spots();
// state of db:
// er zijn 5 parkspots, 2 met 2weeler en 4 met 4weeler
// er zijn customers met password "password"
// er is een admin id=1 met password PASSWORD
interface(parking_spots);
}
/*
@ -91,13 +60,12 @@ concurrency issue. Do not move this.
vector<Park_spot> populate_spots() {
vector<Park_spot> spots;
SQLite::Statement query(data::db, "SELECT * FROM Park_spot WHERE id > 0;");
// query.bind(1, 2);
while (query.executeStep()) {
int id = query.getColumn(0);
int taken = query.getColumn(1);
int cid = query.getColumn(2);
// park_customers.push_back(query_customer_with_id(cid));
spots.push_back({id, taken, cid});
Vehicle_type vtype = Vehicle_type(int(query.getColumn(3)));
spots.push_back({id, taken, cid, vtype});
}
return spots;
}

Binary file not shown.

View File

@ -11,4 +11,30 @@ Or click the build icon in vscode *shrugs*
# Parkmanne
## A stroll in the park
Parkmanne aims to achieve provisionary effectiveness in the sector of parking. This problem had.
#TODO
1. fix password of admin(probably buffer of input cusing the problem)
2. add adress to customer
3. billing
4. delete/edit admin
This is a graph of how everything is connected.
If you need to add functionality that doesn't fall in any of these, and you're unsure of what to include, you can decide something like this:
Take my customer class for example.
It needs to be able to save to db, so it needs data.
It needs to modify and save park_time objects, so it needs those.
It needs to encrypt and decrypt passwords. BUT since data already includes encrypt, it doesn't have to be encrypted.
So customer includes those.
Another example is Parkspot.
It needs information about both customers and save to the database.
Since customer also includes data, i don't have to include it again.
Last example:
![header includes](graph.png)

BIN
test.db3

Binary file not shown.