so far, working

This commit is contained in:
Sagar Ramsaransing 2019-07-01 20:42:41 -03:00
parent 5fa84e866f
commit cf1cfdfd79
13 changed files with 31 additions and 540 deletions

View File

@ -11,18 +11,20 @@ include_directories(
add_executable(park
main.cpp
data.cpp
headers/data.h
Customer.cpp
headers/Customer.h
Park_spot.cpp
headers/Park_spot.h
Park_time.cpp
headers/Park_time.h
encrypt.cpp
headers/encrypt.h
Query.cpp
headers/Query.h
# Customer.cpp
# headers/Customer.h
# Park_spot.cpp
# headers/Park_spot.h
# Park_time.cpp
# headers/Park_time.h
# Query.cpp
# headers/Query.h
)
@ -34,7 +36,7 @@ if (UNIX)
sqlite3
pthread
dl
libsodium
sodium
)
elseif (MSYS OR MINGW)
target_link_libraries(park

View File

@ -1,87 +0,0 @@
#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;
save_db();
}
Customer::Customer(int id_, string name_, string password_,
Verhicle_type verhicle_, vector<Park_time> instances)
:id{id_},
name{name_},
password{password_},
verhicle{verhicle_},
park_instances{instances} {}
// clock in/out methods
// ====================================================================================
/*
Create a p_time object with start=now and adds to vector
*/
void Customer::clock_in(int s_id) {
Park_time pt{id, s_id};
park_instances.push_back(pt);
}
// edit last p_time object so end=now
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;
}
cout << "-------------------------------------------------\n\n";
}
//================================================================================================
// functions that interact with the database
void Customer::save_db() {
string statement{"insert into Customer values (, '', '', );"};
// after ( = 28)
statement.insert(38, to_string(int(verhicle)));
statement.insert(36, password);
statement.insert(32, name);
statement.insert(29, to_string(id));
SQLite::Transaction transaction(data::db);
data::db.exec(statement);
transaction.commit();
}
void Customer::update_db() {
string statement =
"UPDATE Customer SET name = '', card_code = '' where id = '';";
statement.insert(58, to_string(id));
statement.insert(44, password);
statement.insert(28, name);
data::db.exec(statement);
}
void Customer::delete_db() {
string statement = "delete from Customer where id= ;";
statement.insert(statement.length() - 2, to_string(id));
SQLite::Transaction transaction(data::db);
data::db.exec(statement);
transaction.commit();
}
int Customer::auto_increment_db() {
SQLite::Statement max_id(data::db, "select max(id) from Customer;");
int id = 0;
max_id.executeStep();
id = max_id.getColumn(0);
max_id.reset();
return id;
}

View File

@ -1,76 +0,0 @@
#include "headers/Park_spot.h"
// constructors
Park_spot::Park_spot()
: parked{nullptr}, id{auto_increment_db() + 1}, taken{false} {
save_db();
}
Park_spot::Park_spot(Customer* parked_, int id_, bool taken_)
: parked{nullptr},
id{id_},
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) {
if (!taken) {
parked = c_customer;
taken = true;
parked->clock_in(id);
update_db();
} else {
taken = false;
parked->clock_out(id);
parked = nullptr;
update_db();
}
}
// --------------------- db functs
void Park_spot::update_db() {
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->id));
statement.insert(30, "1");
} else {
statement.insert(49, "NULL");
statement.insert(30, "0");
}
data::db.exec(statement);
}
void Park_spot::save_db() {
//(int id, bool taken, int customer_id)
string statement{"insert into Park_spot values ( , , );"};
// after ( = 28)
statement.insert(34, "NULL");
statement.insert(32, "0");
statement.insert(30, to_string(id));
SQLite::Transaction transaction(data::db);
data::db.exec(statement);
transaction.commit();
}
void Park_spot::delete_db() {
string statement = "delete from Park_spot where id= ;";
statement.insert(statement.length() - 2, to_string(id));
SQLite::Transaction transaction(data::db);
data::db.exec(statement);
transaction.commit();
}
int Park_spot::auto_increment_db() {
SQLite::Statement max_id(data::db, "select max(id) from Park_spot;");
int id = 0;
max_id.executeStep();
id = max_id.getColumn(0);
max_id.reset();
return id;
}

View File

@ -1,96 +0,0 @@
#include "headers/Park_time.h"
Park_time::Park_time(int c_id, int s_id)
: customer_id{c_id},
spot_id{s_id},
duration{0},
start{high_resolution_clock::now()},
id{auto_increment_db() + 1} {
save_db();
}
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_));
}
void Park_time::clock_out(int c_id, int s_id) {
if (c_id != customer_id) {
cout << "wrong customer id, you are at the wrong location";
return;
}
if (s_id != spot_id) {
cout << "Wrong spot id, you're at the wrong location";
return;
}
if (!duration) {
end = high_resolution_clock::now();
duration =
duration_cast<seconds>(end - start).count(); // use mins later
update_db();
} else {
cout << "Already clocked out. Something is wrong \n";
}
}
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 << "Clocked in :" << std::ctime(&start_);
os << "clocked out : " << std::ctime(&end_);
os << "duration : " << pt.duration << "\n";
os << "- - - - - - - - - - - - - - - - - - - -\n";
return os;
}
int Park_time::start_to_int() {
auto start_to_epoch = start.time_since_epoch();
auto start_value = duration_cast<seconds>(start_to_epoch);
int start_seconds = start_value.count();
return start_seconds;
}
// db funcs
// -----------------------------------------------------------------------------
void Park_time::save_db() {
string statement{"insert into Park_time values ( , , , , , );"};
statement.insert(41, "NULL");
statement.insert(39, "NULL");
statement.insert(37, to_string(start_to_int()));
statement.insert(35, to_string(spot_id));
statement.insert(33, to_string(customer_id));
statement.insert(31, to_string(id));
SQLite::Transaction transaction(data::db);
data::db.exec(statement);
transaction.commit();
}
void Park_time::update_db() {
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));
data::db.exec(statement);
}
// to get id on first save to db
int Park_time::auto_increment_db() {
SQLite::Statement max_id(data::db, "select max(id) from Park_time;");
int id = 0;
max_id.executeStep();
id = max_id.getColumn(0);
max_id.reset();
return id;
}

View File

@ -1,98 +0,0 @@
#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
that is supposed to create a customer from data in the db.
This should not be called on on it's own outside query_customer();
*/
vector<Park_time> park_times;
SQLite::Statement query(data::db,
"SELECT * FROM Park_time WHERE customer_id = ?;");
query.bind(1, cid);
while (query.executeStep()) {
int id = query.getColumn(0);
int spot_id = query.getColumn(2);
int start = query.getColumn(3);
int duration = query.getColumn(5);
Park_time result{id, cid, spot_id, start, duration};
park_times.push_back(result);
}
query.reset();
return park_times;
}
vector<Customer> query_customer_with_name(string name) {
/*
We use this instead of plain customers because:
1. no error handling needed here if there are no customers
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 = ?;");
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
vector<Park_time> park_instances = query_parktimes_for_customer(id);
result.push_back(Customer{
id, name_, password, Verhicle_type(verhicle), park_instances});
}
return result;
}
Customer query_customer_with_id(int id) {
/* do not call this function if you are not certain a customer with this id
exists.
// the only legitimate caller of this function is query_parkspot_x
// there is no error handling in this function
// for when this function doesn't find the customer with this 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);
int verhicle = query.getColumn(3); // cast to verhicle
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";
return result;
}
}
void query_all_parking_spots() {
SQLite::Statement query(data::db, "SELECT * FROM Park_spot WHERE id > ?;");
query.bind(1, 0);
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));
parking_spots.push_back(
Park_spot{get_customer_ptr_for_parkspot(cid), id, bool(taken)});
}
}
Customer* get_customer_ptr_for_parkspot(int id) {
if (!id) {
return nullptr;
}
for (int i = 0; i < park_customers.size(); i++) {
if (park_customers[i].id == id) {
return &park_customers[i];
}
}
return nullptr;
}

View File

@ -8,6 +8,7 @@ SQLite::Database start_db() {
while (sodium_init() < 0) {
std::cout << "SODIUM NOT WORKING";
}
db.exec(
"create table if not exists Customer (id integer primary key, name "
"text, password text, verhicle int)");
@ -18,6 +19,8 @@ SQLite::Database start_db() {
"create table if not exists Park_time (id integer primary key, "
"customer_id int, spot_id int, start int, end int, duration int)");
return db;
}
} // namespace data

View File

@ -9,8 +9,8 @@ string hash_password(string password) {
*/
const char* password_ = password.c_str();
char hashed_password_[crypto_pwhash_STRBYTES];
int memory_limit = 1.28e+8; // 1.28 e+8 = 128 e6 = 128 mb
int cpu_limit = 2; // this is n_threads
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_,

View File

@ -1,54 +0,0 @@
#ifndef CUSTOMER_H
#define CUSTOMER_H
#pragma once
#include "Park_time.h"
#include "data.h"
#include <vector>
using std::vector;
// will make it easy to represent it in the database while making it easy to use
// while programming
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
card zou opslaan en zo zou authenticaten bij je parking spot. We kunnen dit ipv
of samen met een password gebruiken. clock in en out creeert en compleet een
park_time object. Voegt het toe aan een vector.
*/
class Customer {
public:
int id;
string name;
string password;
Customer(string name_, string password_, Verhicle_type verhicle_);
Customer(int id_, string name_, // needed to construct from db
string password_,
Verhicle_type verhicle_, // TODO: how init. p_time instances?
vector<Park_time> instances);
void clock_in(int s_id);
void clock_out(int s_id);
void update_db();
void delete_db();
void gen_monthly(); // remove, make it a function in data
private:
Verhicle_type verhicle;
vector<Park_time> park_instances;
void save_db();
int auto_increment_db();
};
static vector<Customer> park_customers; // save the customers that are parked in here
// parking_spot uses pointers, so it's better to save the parked customers here
// where we know they'll be destroyed at the end of this scope, instead of too early
// and end up with dangling pointers
#endif // CUSTOMER_H

View File

@ -1,29 +0,0 @@
#include "Customer.h"
/*
db representation:
int id not null
bool taken not null
int customer_id (null) (many to one, foreign key, whatever)
Dit representeert een parkeerplaats. Het heeft als internal state alleen dat t
bezet is of niet.
*/
class Park_spot {
public:
int id;
bool taken;
Customer* parked;
Park_spot();
Park_spot(Customer* parked_, int id_, bool taken_);
void clock(Customer* c_customer);
private:
void save_db();
void update_db();
void delete_db();
int auto_increment_db();
};
static vector<Park_spot> parking_spots; // to save the parking spots in memory

View File

@ -1,44 +0,0 @@
#ifndef PARK_TIME_H
#define PARK_TIME_H
#pragma once
#include "data.h"
#include <chrono>
#include <ctime>
#include <iostream>
#include <string>
using namespace std::chrono;
using std::cout;
using std::string;
using std::to_string;
/*
Record of who parked at what park_spot and at what time.
*/
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_);
int id;
int customer_id;
int spot_id;
int duration;
void clock_out(int c_id, int s_id);
friend std::ostream& operator<<(std::ostream& os, const Park_time& pt);
private:
high_resolution_clock::time_point start;
high_resolution_clock::time_point end;
void save_db();
void update_db();
int auto_increment_db(); // helper
int start_to_int(); // helper
};
#endif // Park_time

View File

@ -1,18 +0,0 @@
#ifndef QUERY_H
#define QUERY_H
#pragma once
#include "Park_spot.h"
#include <array>
vector<Park_time> query_parktimes_for_customer(int cid);
vector<Customer> query_customer_with_name(string name);
Customer query_customer_with_id(int id);
Customer* get_customer_ptr_for_parkspot(int id);
void query_all_parking_spots(); // used for initializing the parking spots at start of the program
#endif // CUSTOMER_H

View File

@ -1,8 +1,13 @@
#include "headers/Query.h"
#include "headers/data.h"
#include <array>
#include <chrono>
#include <thread>
#include <vector>
using namespace std::chrono;
/*
Code strucure like this:
class declarations zijn in /headers/class_naam.h, en definitions van de member
@ -18,9 +23,6 @@ record die zegt dat een customer voor x tijd geparkeert heeft bij spot x, enz.
De client clockt in en uit bij een spot.
*/
void Wait(int sec)
/*
a wait function where 1 sec represents 1 hour irl.
@ -29,29 +31,15 @@ a wait function where 1 sec represents 1 hour irl.
std::this_thread::sleep_for(seconds{sec});
}
Customer* get_customer_ptr_for_parkspot(int id);
int main() {
query_all_parking_spots();
Customer p0 = query_customer_with_name("Shaquile")[0];
Customer p1 = query_customer_with_name("Sagar Ramsaransing")[0];
Customer p2 = query_customer_with_name("Joshua karto")[0];
Customer p3 = query_customer_with_name("Stefan udit")[0];
parking_spots[2].clock(&p1);
Wait(2);
parking_spots[2].clock(&p1);
Wait(1);
parking_spots[0].clock(&p2);
Wait(1);
parking_spots[1].clock(&p3);
Wait(1);
parking_spots[0].clock(&p2);
parking_spots[1].clock(&p3);
Wait(1);
parking_spots[1].clock(&p3);
std::vector<string> test {
"werrgwergfwerrfvwerrf", "2rwefeqfeqfqewwfqwdfdwqdfqwdfd",
"qwerfqwefwqddweqdqwdwqed","qwefwqedwqdqwedwqdwqdwqd,",
"qwefqwedfwqdwqeddwqdqwedwqede "
};
#include <iostream>
for (auto i: test){
std::cout << hash_password(i) << "\n";
}
}

BIN
test.db3

Binary file not shown.