Merge branch 'refactor' of AP-CT/Parkmanne into sqlitecpp

This commit is contained in:
Sagar Ramsaransing 2019-06-30 13:12:37 +00:00 committed by Gitea
commit 0674aacbeb
12 changed files with 294 additions and 157 deletions

View File

@ -1,12 +1,22 @@
BasedOnStyle: LLVM BasedOnStyle: LLVM
IndentWidth: 4 IndentWidth: 4
#-------------
#--- cpp
Language: Cpp Language: Cpp
PointerAlignment: Left PointerAlignment: Left
ColumnLimit: 120 ColumnLimit: 80
AllowAllArgumentsOnNextLine: true AlignAfterOpenBracket: Align
BreakConstructorInitializersStyle : BCIS_AfterColon AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
BinPackArguments: false
BreakConstructorInitializers: BeforeColon
ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerAllOnOneLineOrOnePerLine: true
Cpp11BracedListStyle: true Cpp11BracedListStyle: true
IncludeBlocks: Regroup
#---

View File

@ -9,7 +9,17 @@ 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) 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
)

View File

@ -1,84 +1,82 @@
#include "headers/Customer.h" #include "headers/Customer.h"
#include <iostream>
// constructors // constructors
Customer::Customer(string name_, Verhicle_type verhicle_, SQLite::Database& db): Customer::Customer(string name_, Verhicle_type verhicle_)
name{name_}, verhicle{verhicle_}, : name{name_}, verhicle{verhicle_}, card_code{gen_cardcode()} {
card_code{gen_cardcode()} id = auto_increment_db() + 1;
{ save_db();
id = auto_increment_db(db) + 1;
save_db(db);
} }
Customer::Customer(int id_, string name_, string card_code_, Verhicle_type verhicle_, vector<Park_time> instances) Customer::Customer(int id_, string name_, string card_code_,
: name{name_}, Verhicle_type verhicle_, vector<Park_time> instances)
card_code{card_code_}, : name{name_},
verhicle{verhicle_}, card_code{card_code_},
park_instances{instances} verhicle{verhicle_},
{ park_instances{instances} {}
} Customer::~Customer() { update_db(); }
// clock in/out methods
// ====================================================================================
// clock methods ====================================================================================
/* /*
creert een park_time object met start time= nu, en voegt t toe aan een vector. Create a p_time object with start=now and adds to vector
*/ */
void Customer::clock_in(int s_id) { void Customer::clock_in(int s_id) {
Park_time pt{id, s_id}; Park_time pt{id, s_id};
park_instances.push_back(pt); park_instances.push_back(pt);
} }
// edit de laatste park_time obj in de vector zodat de end_time = now. // 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); } void Customer::clock_out(int s_id) {
park_instances[park_instances.size() - 1].clock_out(id, s_id);
}
// report gen // report gen
void Customer::gen_monthly() { void Customer::gen_monthly() {
std::cout << "NAME: " << name << " card code: " << card_code << "\n"; cout << "NAME: " << name << " card code: " << card_code << "\n";
std::cout << "-------------------------------------------------\n"; cout << "-------------------------------------------------\n";
for (auto& i : park_instances) { for (auto& i : park_instances) {
// TODO: need some logic to only include from this month // TODO: need some logic to only include from this month. scratch that,
std::cout << i; // need to remove gen monthly
cout << i;
} }
std::cout << "-------------------------------------------------\n\n"; cout << "-------------------------------------------------\n\n";
} }
//================================================================================================ //================================================================================================
// functions that interact with the database // functions that interact with the database
void Customer::save_db(SQLite::Database& database) { void Customer::save_db() {
string statement{"insert into Customer values (, '', '', );"}; string statement{"insert into Customer values (, '', '', );"};
// after ( = 28) // after ( = 28)
statement.insert(38, std::to_string(int(verhicle))); statement.insert(38, to_string(int(verhicle)));
statement.insert(36, card_code); statement.insert(36, card_code);
statement.insert(32, name); statement.insert(32, name);
statement.insert(29, "null"); statement.insert(29, to_string(id));
SQLite::Transaction transaction(database); SQLite::Transaction transaction(data::db);
database.exec(statement); data::db.exec(statement);
transaction.commit(); transaction.commit();
} }
void Customer::update_db(SQLite::Database& database) { void Customer::update_db() {
string statement = "UPDATE Customer SET name = \"\", card_code = \"\" where id = '';"; string statement =
statement.insert(58, std::to_string(id)); "UPDATE Customer SET name = '', card_code = '' where id = '';";
statement.insert(58, to_string(id));
statement.insert(44, card_code); statement.insert(44, card_code);
statement.insert(28, name); statement.insert(28, name);
// std::cout << statement; TODO: set some logging here data::db.exec(statement);
database.exec(statement);
} }
void Customer::delete_db(SQLite::Database& database) { void Customer::delete_db() {
string statement = "delete from Customer where id= ;"; string statement = "delete from Customer where id= ;";
statement.insert(statement.length() - 2, std::to_string(id)); statement.insert(statement.length() - 2, to_string(id));
// std::cout << statement; SQLite::Transaction transaction(data::db);
SQLite::Transaction transaction(database); data::db.exec(statement);
database.exec(statement);
transaction.commit(); transaction.commit();
} }
int Customer::auto_increment_db(SQLite::Database& database) { int Customer::auto_increment_db() {
SQLite::Statement max_id(database, "select max(id) from Customer;"); SQLite::Statement max_id(data::db, "select max(id) from Customer;");
int id = 0; int id = 0;
max_id.executeStep(); max_id.executeStep();
id = max_id.getColumn(0); id = max_id.getColumn(0);

View File

@ -1,21 +1,77 @@
#include "headers/Park_spot.h" #include "headers/Park_spot.h"
Park_spot::Park_spot(int id_){ // constructors
parked = nullptr;
id = id_; Park_spot::Park_spot()
taken = false; : parked{nullptr}, id{auto_increment_db() + 1}, taken{false} {
save_db();
} }
// clock in en out, calls de juist(in/out) van de customer aan de hand van internal state van taken Park_spot::Park_spot(Customer* parked_, int id_, bool taken_)
void Park_spot::clock(Customer* c_customer){ : parked{nullptr},
if (!taken){ id{id_},
taken{taken_} // TODO: think about how init parked?
{}
Park_spot::~Park_spot() { update_db(); }
// 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; parked = c_customer;
taken = true; taken = true;
parked->clock_in(id); parked->clock_in(id);
} update_db();
else{ } else {
taken = false; taken = false;
parked->clock_out(id); parked->clock_out(id);
parked = nullptr; 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, "true");
} else {
statement.insert(49, "NULL");
statement.insert(30, "false");
}
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, "false");
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,39 +1,49 @@
#include"headers/Park_time.h" #include "headers/Park_time.h"
#include <iostream>
#include <ctime>
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},
, duration { 0 } duration{0},
, start { high_resolution_clock::now() } start{high_resolution_clock::now()},
{ id{auto_increment_db() + 1} {
save_db();
} }
void Park_time::clock_out(int c_id, int s_id) 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_));
}
Park_time::~Park_time() { update_db(); }
void Park_time::clock_out(int c_id, int s_id) {
if (c_id != customer_id) { if (c_id != customer_id) {
std::cout << "wrong customer id, you are at the wrong location"; cout << "wrong customer id, you are at the wrong location";
return; return;
} }
if (s_id != spot_id) { if (s_id != spot_id) {
std::cout << "Wrong spot id, you're at the wrong location"; cout << "Wrong spot id, you're at the wrong location";
return; return;
} }
if (!duration) { if (!duration) {
end = high_resolution_clock::now(); 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 { } else {
std::cout << "Already clocked out. Something is wrong \n"; cout << "Already clocked out. Something is wrong \n";
} }
} }
std::ostream& operator<<(std::ostream& os, const Park_time& pt) {
std::ostream& operator<<(std::ostream& os, const Park_time & pt){
std::time_t start_ = system_clock::to_time_t(pt.start); std::time_t start_ = system_clock::to_time_t(pt.start);
std::time_t end_ = system_clock::to_time_t(pt.end); std::time_t end_ = system_clock::to_time_t(pt.end);
os << "- - - - - - - - - - - - - - - - - - - -\n"; os << "- - - - - - - - - - - - - - - - - - - -\n";
@ -44,13 +54,44 @@ std::ostream& operator<<(std::ostream& os, const Park_time & pt){
return os; return os;
} }
void Park_time::debug() { 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 = std::chrono::duration_cast<std::chrono::seconds>(start_to_epoch); auto start_value = duration_cast<seconds>(start_to_epoch);
int start_seconds = start_value.count(); int start_seconds = start_value.count();
return start_seconds;
}
auto end_to_epoch = end.time_since_epoch(); // db funcs
auto end_value = std::chrono::duration_cast<std::chrono::seconds>(start_to_epoch); // -----------------------------------------------------------------------------
int end_seconds = end_value.count();
std::cout << "<" << start_seconds << "-" << end_seconds << ">" ; 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

@ -2,12 +2,20 @@
namespace data { namespace data {
SQLite::Database start_db() { SQLite::Database
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); start_db() {
SQLite::Database db("test.db3",
SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
db.exec("create table if not exists Customer (id integer primary key, name text, card_code varchar(20), verhicle int)"); db.exec(
db.exec("create table if not exists Park_spot (id integer primary key, taken boolean, customer_id int)"); "create table if not exists Customer (id integer primary key, name "
db.exec("create table if not exists Park_time (id integer primary key, customer_id int, spot_id int, start real, end real, duration real)"); "text, card_code varchar(20), verhicle int)");
db.exec(
"create table if not exists Park_spot (id integer primary key, taken "
"boolean, customer_id 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)");
return db; return db;
} }

View File

@ -1,37 +1,35 @@
#ifndef CUSTOMER_H #ifndef CUSTOMER_H
#define CUSTOMER_H #define CUSTOMER_H
#pragma once #pragma once
#include "../thirdparty/SQLiteCpp/include/SQLiteCpp/SQLiteCpp.h"
#include "Park_time.h" #include "Park_time.h"
#include <ctime> #include "data.h"
#include <random> #include <random>
#include <string>
#include <vector> #include <vector>
using std::string;
using std::vector; using std::vector;
// enum type is basically een manier om categories te representen als een integer in the background, maar om t in code // will make it easy to represent it in the database while making it easy to use
// aan te geven als de actual category. // while programming
enum class Verhicle_type { enum class Verhicle_type { bike = 1, small_car = 2, suv = 3, pickup = 4 };
small = 1,
medium = 2,
large = 3,
};
/* /*
card code is een randomly generated string moeten zijn, die je bv. op een nfc card zou opslaan en zo zou card code is een randomly generated string moeten zijn, die je bv. op een nfc
authenticaten bij je parking spot. We kunnen dit ipv of samen met een password gebruiken. card zou opslaan en zo zou authenticaten bij je parking spot. We kunnen dit ipv
clock in en out creeert en compleet een park_time object. Voegt het toe aan een vector. 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 { class Customer {
public: public:
Customer(string name_, Verhicle_type verhicle_, SQLite::Database& db); Customer(string name_, Verhicle_type verhicle_);
Customer(int id_, string name_, string card_code_, Verhicle_type verhicle_, Customer(int id_, string name_, // needed to construct from db
vector<Park_time> instances); // needed to construct from db string card_code_,
// potentially: add a destructor that calls update_db() before being destroyed Verhicle_type verhicle_, // TODO: how init. p_time instances?
vector<Park_time> instances);
~Customer();
int id; int id;
string name; string name;
string card_code; string card_code;
@ -39,20 +37,18 @@ class Customer {
void clock_in(int s_id); void clock_in(int s_id);
void clock_out(int s_id); void clock_out(int s_id);
void update_db(SQLite::Database& database); void update_db();
void delete_db(SQLite::Database& database); void delete_db();
// void gen_weekly(); TODO: this void gen_monthly(); // remove, make it a function in data
void gen_monthly();
private: private:
Verhicle_type verhicle; Verhicle_type verhicle;
vector<Park_time> park_instances; vector<Park_time> park_instances;
string gen_cardcode(); string gen_cardcode();
void save_db();
void save_db(SQLite::Database& database); int auto_increment_db();
int auto_increment_db(SQLite::Database& database);
}; };
#endif // CUSTOMER_H #endif // CUSTOMER_H

View File

@ -1,21 +1,33 @@
#include "Customer.h" #include "Customer.h"
/* /*
db representation: db representation:
int id not null int id not null
bool taken not null bool taken not null
int customer_id (null) (many to one, foreign key, whatever) 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. Dit representeert een parkeerplaats. Het heeft als internal state alleen dat t
bezet is of niet.
*/ */
class Park_spot { class Park_spot {
public: public:
int id; int id;
bool taken; bool taken;
Customer* parked; //TODO: think about memory management Customer* parked;
Park_spot(int id_); Park_spot();
void clock(Customer* c_customer); Park_spot(Customer* parked_, int id_, bool taken_);
private: ~Park_spot();
void
clock(Customer* c_customer);
private:
void
save_db();
void
update_db();
void
delete_db();
int
auto_increment_db();
}; };

View File

@ -2,43 +2,44 @@
#define PARK_TIME_H #define PARK_TIME_H
#pragma once #pragma once
#include <chrono> #include "data.h"
#include <iostream>
#include <chrono>
#include <ctime>
#include <iostream>
#include <string>
using namespace std::chrono; using namespace std::chrono;
using std::cout;
using std::string;
using std::to_string;
/* /*
db repr of Park_time
int id (not null, auto increment)
int customer_id (not null) (many to one or something like that)
int spot_id (not null, many to one or something like that)
int duration
datetime start (not null)
datetime end
Dit is gewoon een record van hoe lang, wie en waar iemand parkeert. Basically, een component van
de internal state van customer. Record of who parked at what park_spot and at what time.
*/ */
class Park_time { class Park_time {
public: 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 id;
int customer_id; int customer_id;
int spot_id; int spot_id;
int duration; int duration;
Park_time(int c_id, int s_id);
void clock_out(int c_id, int s_id);
friend std::ostream& operator<<(std::ostream& os, const Park_time & pt);
void debug();
private: 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 start;
high_resolution_clock::time_point end; high_resolution_clock::time_point end;
//TODO: discuss pros cons of using chrono, ctime, or 3th party lib void save_db();
void update_db();
int auto_increment_db(); // helper
int start_to_int(); // helper
}; };
#endif // Park_time #endif // Park_time

View File

@ -1,6 +1,12 @@
#ifndef DATA_H
#define DATA_H
#pragma once
#include "../thirdparty/SQLiteCpp/include/SQLiteCpp/SQLiteCpp.h" #include "../thirdparty/SQLiteCpp/include/SQLiteCpp/SQLiteCpp.h"
#include "Customer.h"
namespace data { namespace data {
SQLite::Database start_db(); SQLite::Database
start_db();
static SQLite::Database db = start_db();
} } // namespace data
#endif

View File

@ -1,8 +1,6 @@
#include "headers/Park_spot.h" #include "headers/Park_spot.h"
#include "headers/data.h"
#include <iostream> #include <thread>
#include <thread> // to make pausing work, not sure if i need chrono, or this, or both
#include <vector>
/* /*
Code strucure like this: Code strucure like this:
@ -19,7 +17,8 @@ record die zegt dat een customer voor x tijd geparkeert heeft bij spot x, enz.
De client clockt in en uit bij een spot. De client clockt in en uit bij een spot.
*/ */
void Wait(int sec) void
Wait(int sec)
/* /*
a wait function where 1 sec represents 1 hour irl. a wait function where 1 sec represents 1 hour irl.
*/ */
@ -27,14 +26,14 @@ a wait function where 1 sec represents 1 hour irl.
std::this_thread::sleep_for(seconds{sec}); std::this_thread::sleep_for(seconds{sec});
} }
using std::cout; int
main() {
int main() { class Customer sagar {
"Sagar Ramsaransing", Verhicle_type::bike
SQLite::Database db = data::start_db(); };
// see implementation of update_db, save_db and delete_db of customer to see how queries and statements work sagar.update_db();
Customer sagar{"Sagar Winston Ramsaransing", Verhicle_type::medium, db}; Park_spot p1;
sagar.update_db(db); p1.clock(&sagar);
cout << "THIS WRKS"; Wait(2);
// sagar.delete_db(db); // p1.clock(&sagar);
} }

BIN
test.db3

Binary file not shown.