From 640a992ae1bd11cc2c812bed8875ea65682f579b Mon Sep 17 00:00:00 2001 From: Tina_Azure <-> Date: Sun, 30 Apr 2023 20:57:00 +0200 Subject: [PATCH] Database Manager refactoring/optimization Some minor general refactoring --- src/database.cpp | 224 ++++----------------- src/databaseStatementConstCollection.cpp | 235 +++++++++++++++++++++++ src/main.cpp | 66 +++++-- src/utilities.cpp | 7 +- 4 files changed, 323 insertions(+), 209 deletions(-) create mode 100644 src/databaseStatementConstCollection.cpp diff --git a/src/database.cpp b/src/database.cpp index 6eaaa71..eba238d 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -1,10 +1,14 @@ #include #include +#include #include #include #include #include #include "crow.h" +#include "databaseStatementConstCollection.cpp" + +using namespace DatabaseStatementConstCollection; /* @@ -14,153 +18,6 @@ namespace Database { //Valid names for the JSON const static std::string JSON_ITEM_NAMES[] ={"id", "customerName", "customerEmailAddress", "customerContactDetails", "freelancerID", "templateID", "currencyPreference", "priceUpFront", "priceOnDeliver", "requestDescription", "accepted", "upFrontInvoiceID", "onDeliverInvoiceID", "upFrontPaid", "onDeliverPaid", "completed"}; - /* - * Name and Statement for prepared statement to insert an item into Requests - */ - const static std::string PREPARED_STATEMENT_INSERT_ITEM_IN_REQUESTS = "insertItemInRequests"; - const static std::string SQL_STATEMENT_INSERT_ITEM_IN_REQUESTS = "INSERT INTO requests(id, customerEmailAddress, freelancerid , templateid , currencyPreference, priceUpFront, priceOnDeliver, requestDescription, accepted, upFrontInvoiceID, onDeliverInvoiceID, upFrontPaid, onDeliverPaid, completed, customerContactDetails, customerName) VALUES(DEFAULT, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15);"; - - /* - * Name and Statement for prepared statement to create a new freelancer - */ - const static std::string PREPARED_STATEMENT_INSERT_NEW_FREELANCER = "insertNewFreelancer"; - const static std::string SQL_STATEMENT_INSERT_NEW_FREELANCER = "INSERT INTO freelancers (emailaddress, name, salt, hash) values($1, $2, $3, $4);"; - - /* - * Name and Statement for prepared statement to select an item based on a given ID - * Case for boolean return values because the default return value is f/t instead of 0/1 or false/true - */ - const static std::string PREPARED_STATEMENT_SELECT_ITEM_BY_ID = "selectItemByID"; - const static std::string SQL_STATEMENT_SELECT_ITEM_BY_ID = "SELECT requests.id , customerEmailAddress, freelancers.name, templates.name, currencyPreference, priceUpFront, priceOnDeliver, requestDescription, (CASE WHEN requests.accepted THEN 1 ELSE 0 END) AS accepted, upFrontInvoiceID, onDeliverInvoiceID, (CASE WHEN requests.upFrontPaid THEN 1 ELSE 0 END) AS upFrontPaid, (CASE WHEN requests.onDeliverPaid THEN 1 ELSE 0 END) AS onDeliverPaid FROM requests INNER JOIN freelancers ON freelancers.id=requests.freelancerID INNER JOIN templates ON templates.id=requests.templateID WHERE requests.id=$1;"; - - /* - * Name and Statement for prepared statement to select a freelancers commission state based on a given id - * 0 == commissions are open - * 1 == commissions are closed - */ - const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_COMMISSION_STATE = "selectFreelancerCommissionState"; - const static std::string SQL_STATEMENT_SELECT_FREELANCER_COMMISSION_STATE = "select (case when (commissionlimit <= (select count(*) as requestCount from requests where requests.accepted = true and requests.freelancerid = id group by freelancerid)) then 1 else 0 end) as commissionsclosed from freelancers where freelancers.id = $1;"; - - /* - * Name and Statement for prepared statement to select a freelancers emailaddress based on a given id - */ - const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL = "selectFreelancerEmailAddress"; - const static std::string SQL_STATEMENT_SELECT_FREELANCER_EMAIL = "select emailaddress from freelancers where id = $1;"; - - /* - * Name and Statement for prepared statement to check if an email is already registered with a freelancer - */ - const static std::string PREPARED_STATEMENT_SELECT_CHECK_EMAIL_EXISTS = "selectCheckEmailExists"; - const static std::string SQL_STATEMENT_SELECT_CHECK_EMAIL_EXISTS = "select count(*) from freelancers where emailaddress = $1;"; - - /* - * Name and Statement for prepared statement to validate if a freelancer is already logged in - */ - const static std::string PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_LOGIN_STATE = "selectCheckFreelancerLoginState"; - const static std::string SQL_STATEMENT_SELECT_CHECK_FREELANCER_LOGIN_STATE = "select count(*) from freelancers where emailaddress = $1 AND loginvalidationkey = $2;"; - - /* - * Name and Statement for prepared statement to get salt using a given email - */ - const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_SALT = "selectFreelancerSalt"; - const static std::string SQL_STATEMENT_SELECT_FREELANCER_SALT = "select salt from freelancers where emailaddress = $1;"; - /* - * Name and Statement for prepared statement to get id using a given email - */ - const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_ID = "selectFreelancerSalt"; - const static std::string SQL_STATEMENT_SELECT_FREELANCER_ID = "select id from freelancers where emailaddress = $1;"; - - /* - * Name and Statement for prepared statement to check if hash is valid - */ - const static std::string PREPARED_STATEMENT_SELECT_CHECK_HASH_VALID = "selectCheckHashValid"; - const static std::string SQL_STATEMENT_SELECT_CHECK_HASH_VALID = "select count(*) from freelancers where emailaddress = $1 AND hash = $2;"; - - /* - * Name and Statement for prepared statement to select a freelancer based on a given id - */ - const static std::string PREPARED_STATEMENT_SELECT_FREELANCER = "selectFreelancer"; - const static std::string SQL_STATEMENT_SELECT_FREELANCER = "select id, name, generalinformation, basicinformation from freelancers WHERE id=$1;"; - - /* - * Name and Statement for prepared statement to select a freelancer based on a given id for presentation to the customer - */ - const static std::string PREPARED_STATEMENT_SELECT_TEMPLATE = "selectTemplate"; - const static std::string SQL_STATEMENT_SELECT_TEMPLATE = "select templates.id as templateid, templates.name as templatename, freelancers.id as freelancerid, freelancers.name as freelancername, contactdata, contactinformation, currencypreference, (coalesce(priceupfront ,0) + coalesce(priceondeliver ,0)) as pricetotal, priceupfront, priceondeliver, content from templates inner join freelancers on freelancers.id=templates.freelancerid where templates.id = $1;"; - - /* - * Name and Statement for prepared statement to select a freelancer based on a given id for usage in a request - */ - const static std::string PREPARED_STATEMENT_SELECT_TEMPLATE_FLAT = "selectTemplateFlat"; - const static std::string SQL_STATEMENT_SELECT_TEMPLATE_FLAT = "select freelancerid, currencypreference, priceupfront, priceondeliver from templates where id = $1;"; - - /* - * Name and Statement for prepared statement to select a freelancers templates based on a given freelancer id - */ - const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_TEMPLATES = "selectFreelancerTemplates"; - const static std::string SQL_STATEMENT_SELECT_FREELANCER_TEMPLATES = "select id, name, content from templates where freelancerid = $1 order by id;"; - - /* - * Name and Statement for prepared statement to select an alias and its route via the alias name - */ - const static std::string PREPARED_STATEMENT_SELECT_ALIAS = "selectAlias"; - const static std::string SQL_STATEMENT_SELECT_ALIAS = "select aliasname, route, routeparameter, routevalue from aliasroutes where aliasname = $1;"; - - /* - * Name and Statement for prepared statement to update the loginvalidationkey of a freelancer via the freelancerID - */ - const static std::string PREPARED_STATEMENT_UPDATE_LOGIN_VALIDATION_KEY = "updateLoginValidationKey"; - const static std::string SQL_STATEMENT_UPDATE_LOGIN_VALIDATION_KEY = "update freelancers set loginvalidationkey = $1 where emailaddress = $2;"; - - /* - * Name and Statement for prepared statement to update the passwordhash of a freelancer via the freelancerEmail - */ - const static std::string PREPARED_STATEMENT_UPDATE_FREELANCER_PASSWORD_HASH = "updateFreelancerPasswordHash"; - const static std::string SQL_STATEMENT_UPDATE_FREELANCER_PASSWORD_HASH = "update freelancers set hash = $1, salt = $2 where emailaddress = $3;"; - - /* - * Name and Statement for prepared statement to check if an email has a reset key - */ - const static std::string PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY = "checkFreelancerResetKey"; - const static std::string SQL_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY = "select count(*) from passwordresetkeys where freelanceremail = $1;"; - - /* - * Name and Statement for prepared statement to select a freelancers emailaddress based on a given password reset key - */ - const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY = "selectFreelancerEmailAddressFromPasswordResetKeys"; - const static std::string SQL_STATEMENT_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY = "select freelanceremail from passwordresetkeys where passwordresetkey = $1;"; - - /* - * Name and Statement for prepared statement to check if an reset key is expired - * returns 0 if key not expired - */ - const static std::string PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED = "checkFreelancerResetKeyExpired"; - const static std::string SQL_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED = "select count(*) from passwordresetkeys where passwordresetkey = $1 and expiration <= CURRENT_TIMESTAMP;"; - - /* - * Name and Statement for prepared statement to create new reset key - * $1 = email, $2 = resetkey - */ - const static std::string PREPARED_STATEMENT_INSERT_FREELANCER_RESET_KEY = "insertFreelancerResetKey"; - const static std::string SQL_STATEMENT_INSERT_FREELANCER_RESET_KEY = "insert into passwordresetkeys values ($1, $2, CURRENT_TIMESTAMP);"; - - /* - * Name and Statement for prepared statement to delete specific reset key of a freelancer - */ - const static std::string PREPARED_STATEMENT_DELETE_FREELANCER_RESET_KEY = "deleteFreelancerResetKey"; - const static std::string SQL_STATEMENT_DELETE_FREELANCER_RESET_KEY = "delete from passwordresetkeys where freelanceremail = $1;"; - - /* - * Statement to remove expired reset keys - */ - const static std::string SQL_STATEMENT_PURGE_EXPIRED_FREELANCER_RESET_KEYS = "delete from passwordresetkeys where expiration <= CURRENT_TIMESTAMP;"; - - /* - * Selects freelancers, their basicInfo and if the commissions are closed/open ordered by name. - * Delivers if the commission limit has been reached and if the commissions are closed based on the accepted/completed state of the freelancers requests - */ - const static std::string SQL_Statement_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE = "select id, name, basicInformation , (case when (commissionlimit <= (select count(*) as requestCount from requests where requests.accepted = true and requests.completed = false and requests.freelancerid = freelancers.id group by freelancers.id)) then 'Closed' else 'Open' end) as commissionsclosed from freelancers order by name;"; - /* * Struct Representing an item in Requests */ @@ -274,7 +131,6 @@ namespace Database { */ int executePreparedStatement_INSERT_ITEM_IN_REQUESTS(pqxx::connection &connection, const requestsItem& item) { try { - connection.prepare(PREPARED_STATEMENT_INSERT_ITEM_IN_REQUESTS, SQL_STATEMENT_INSERT_ITEM_IN_REQUESTS); pqxx::work work(connection); work.exec_prepared(PREPARED_STATEMENT_INSERT_ITEM_IN_REQUESTS, item.customerEmailAddress, item.freelancerID, item.templateID, @@ -294,7 +150,6 @@ namespace Database { std::cerr << e.what() << std::endl; return 2; } - connection.unprepare(PREPARED_STATEMENT_INSERT_ITEM_IN_REQUESTS); return 0; } @@ -308,7 +163,6 @@ namespace Database { */ int executePreparedStatement_INSERT_NEW_FREELANCER(pqxx::connection &connection, const std::string& email, const std::string& name, const std::string& salt, const std::string& hash) { try { - connection.prepare(PREPARED_STATEMENT_INSERT_NEW_FREELANCER, SQL_STATEMENT_INSERT_NEW_FREELANCER); pqxx::work work(connection); work.exec_prepared(PREPARED_STATEMENT_INSERT_NEW_FREELANCER, email, name, salt, hash); work.commit(); @@ -323,7 +177,6 @@ namespace Database { std::cerr << e.what() << std::endl; return 2; } - connection.unprepare(PREPARED_STATEMENT_INSERT_NEW_FREELANCER); return 0; } @@ -354,11 +207,9 @@ namespace Database { * Takes an open pqxx::connection and the id to select by */ pqxx::result executePreparedStatement_SELECT_ITEM_BY_ID(pqxx::connection &connection, int id) { - connection.prepare(PREPARED_STATEMENT_SELECT_ITEM_BY_ID, SQL_STATEMENT_SELECT_ITEM_BY_ID); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_ITEM_BY_ID, id); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_ITEM_BY_ID); return result; } @@ -367,11 +218,9 @@ namespace Database { * Takes an open pqxx::connection and the id to select by */ pqxx::result executePreparedStatement_SELECT_FREELANCER(pqxx::connection &connection, int freelancerID) { - connection.prepare(PREPARED_STATEMENT_SELECT_FREELANCER, SQL_STATEMENT_SELECT_FREELANCER); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCER, freelancerID); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_FREELANCER); return result; } @@ -380,11 +229,9 @@ namespace Database { * Takes an open pqxx::connection and the id to select by */ pqxx::result executePreparedStatement_SELECT_FREELANCER_COMMISSION_STATE(pqxx::connection &connection, int freelancerID) { - connection.prepare(PREPARED_STATEMENT_SELECT_FREELANCER_COMMISSION_STATE, SQL_STATEMENT_SELECT_FREELANCER_COMMISSION_STATE); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCER_COMMISSION_STATE, freelancerID); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_FREELANCER_COMMISSION_STATE); return result; } @@ -393,11 +240,9 @@ namespace Database { * Takes an open pqxx::connection and the id to select by */ pqxx::result executePreparedStatement_SELECT_FREELANCER_EMAIL(pqxx::connection &connection, int freelancerID) { - connection.prepare(PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL, SQL_STATEMENT_SELECT_FREELANCER_EMAIL); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL, freelancerID); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL); return result; } @@ -406,10 +251,8 @@ namespace Database { * Takes an open pqxx::connection and the id to select by */ pqxx::result executePreparedStatement_SELECT_FREELANCER_SALT(pqxx::connection &connection, const std::string& freelancerEmail) { - connection.prepare(PREPARED_STATEMENT_SELECT_FREELANCER_SALT, SQL_STATEMENT_SELECT_FREELANCER_SALT); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCER_SALT, freelancerEmail); - work.commit(); connection.unprepare(PREPARED_STATEMENT_SELECT_FREELANCER_SALT); return result; } @@ -419,11 +262,9 @@ namespace Database { * Takes an open pqxx::connection and the id to select by */ pqxx::result executePreparedStatement_SELECT_FREELANCER_ID(pqxx::connection &connection, const std::string& freelancerEmail) { - connection.prepare(PREPARED_STATEMENT_SELECT_FREELANCER_ID, SQL_STATEMENT_SELECT_FREELANCER_ID); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCER_ID, freelancerEmail); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_FREELANCER_ID); return result; } @@ -433,11 +274,9 @@ namespace Database { * Delivers count of emailaddress occurence 0 for none 1+ for more */ pqxx::result executePreparedStatement_SELECT_CHECK_EMAIL_EXISTS(pqxx::connection &connection, const std::string& freelancerEmail) { - connection.prepare(PREPARED_STATEMENT_SELECT_CHECK_EMAIL_EXISTS, SQL_STATEMENT_SELECT_CHECK_EMAIL_EXISTS); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_CHECK_EMAIL_EXISTS, freelancerEmail); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_CHECK_EMAIL_EXISTS); return result; } @@ -447,11 +286,9 @@ namespace Database { * Delivers count of loginValidationKey occurence 0 for none 1+ for more */ pqxx::result executePreparedStatement_SELECT_CHECK_FREELANCER_LOGIN_STATE(pqxx::connection &connection, const std::string& freelancerEmail, const std::string& loginKey) { - connection.prepare(PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_LOGIN_STATE, SQL_STATEMENT_SELECT_CHECK_FREELANCER_LOGIN_STATE); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_LOGIN_STATE, freelancerEmail, loginKey); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_LOGIN_STATE); return result; } @@ -461,11 +298,9 @@ namespace Database { * Delivers 0 if email + hash are not valid 1 if they are */ pqxx::result executePreparedStatement_SELECT_CHECK_HASH_VALID(pqxx::connection &connection, const std::string& emailAddress, const std::string& hash) { - connection.prepare(PREPARED_STATEMENT_SELECT_CHECK_HASH_VALID, SQL_STATEMENT_SELECT_CHECK_HASH_VALID); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_CHECK_HASH_VALID, emailAddress, hash); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_CHECK_HASH_VALID); return result; } @@ -474,11 +309,9 @@ namespace Database { * Takes an open pqxx::connection and the id to select by */ pqxx::result executePreparedStatement_SELECT_TEMPLATE(pqxx::connection &connection, int templateID) { - connection.prepare(PREPARED_STATEMENT_SELECT_TEMPLATE, SQL_STATEMENT_SELECT_TEMPLATE); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_TEMPLATE, templateID); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_TEMPLATE); return result; } @@ -487,11 +320,9 @@ namespace Database { * Takes an open pqxx::connection and the id to select by */ pqxx::result executePreparedStatement_SELECT_TEMPLATE_FLAT(pqxx::connection &connection, int templateID) { - connection.prepare(PREPARED_STATEMENT_SELECT_TEMPLATE_FLAT, SQL_STATEMENT_SELECT_TEMPLATE_FLAT); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_TEMPLATE_FLAT, templateID); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_TEMPLATE_FLAT); return result; } @@ -500,11 +331,9 @@ namespace Database { * Takes an open pqxx::connection and the id to select by */ pqxx::result executePreparedStatement_SELECT_FREELANCER_TEMPLATES(pqxx::connection &connection, int freelancerID) { - connection.prepare(PREPARED_STATEMENT_SELECT_FREELANCER_TEMPLATES, SQL_STATEMENT_SELECT_FREELANCER_TEMPLATES); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCER_TEMPLATES, freelancerID); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_FREELANCER_TEMPLATES); return result; } @@ -513,11 +342,9 @@ namespace Database { * Takes an open pqxx::connection and the alias name to select by */ pqxx::result executePreparedStatement_SELECT_ALIAS(pqxx::connection &connection, const std::string& aliasName) { - connection.prepare(PREPARED_STATEMENT_SELECT_ALIAS, SQL_STATEMENT_SELECT_ALIAS); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_ALIAS, aliasName); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_ALIAS); return result; } @@ -526,11 +353,9 @@ namespace Database { * Takes an open pqxx::connection, the freelancerID and the loginKey to update the entry */ pqxx::result executePreparedStatement_UPDATE_LOGIN_VALIDATION_KEY(pqxx::connection &connection, const std::string& loginKey, const std::string& freelancerEmail) { - connection.prepare(PREPARED_STATEMENT_UPDATE_LOGIN_VALIDATION_KEY, SQL_STATEMENT_UPDATE_LOGIN_VALIDATION_KEY); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_UPDATE_LOGIN_VALIDATION_KEY, loginKey, freelancerEmail); work.commit(); - connection.unprepare(PREPARED_STATEMENT_UPDATE_LOGIN_VALIDATION_KEY); return result; } @@ -544,7 +369,6 @@ namespace Database { */ int executePreparedStatement_UPDATE_FREELANCER_PASSWORD_HASH(pqxx::connection &connection, const std::string& hash, const std::string& salt, const std::string& freelancerEmail) { try { - connection.prepare(PREPARED_STATEMENT_UPDATE_FREELANCER_PASSWORD_HASH, SQL_STATEMENT_UPDATE_FREELANCER_PASSWORD_HASH); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_UPDATE_FREELANCER_PASSWORD_HASH, hash, salt, freelancerEmail); work.commit(); @@ -559,7 +383,6 @@ namespace Database { std::cerr << e.what() << std::endl; return 2; } - connection.unprepare(PREPARED_STATEMENT_UPDATE_FREELANCER_PASSWORD_HASH); return 0; } @@ -569,11 +392,9 @@ namespace Database { * returns 1 if email has reset key */ pqxx::result executePreparedStatement_SELECT_CHECK_FREELANCER_RESET_KEY(pqxx::connection &connection, const std::string& freelancerEmail) { - connection.prepare(PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY, SQL_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY, freelancerEmail); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY); return result; } @@ -583,11 +404,9 @@ namespace Database { * returns 0 if reset key is not expired */ pqxx::result executePreparedStatement_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED(pqxx::connection &connection, const std::string& freelancerEmail) { - connection.prepare(PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED, SQL_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED, freelancerEmail); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED); return result; } @@ -597,36 +416,59 @@ namespace Database { * returns email if reset key exists */ pqxx::result executePreparedStatement_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY(pqxx::connection &connection, const std::string& passwordResetKey) { - connection.prepare(PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY, SQL_STATEMENT_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY); pqxx::work work(connection); pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY, passwordResetKey); work.commit(); - connection.unprepare(PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY); return result; } /* + * Executes the prepared statement DELETE_FREELANCER_RESET_KEY * Deletes the entry for a reset key based on a freelancer email * Takes an open pqxx::connection and the freelancers email */ void executePreparedStatement_DELETE_FREELANCER_RESET_KEY(pqxx::connection &connection, const std::string& freelancerEmail) { - connection.prepare(PREPARED_STATEMENT_DELETE_FREELANCER_RESET_KEY, SQL_STATEMENT_DELETE_FREELANCER_RESET_KEY); pqxx::work work(connection); work.exec_prepared(PREPARED_STATEMENT_DELETE_FREELANCER_RESET_KEY, freelancerEmail); work.commit(); - connection.unprepare(PREPARED_STATEMENT_DELETE_FREELANCER_RESET_KEY); } /* + * Executes the prepared statement INSERT_FREELANCER_RESET_KEY * Creates a new entry for a password reset key for a freelancer * Takes an open pqxx::connection the freelancers email and the password reset key */ void executePreparedStatement_INSERT_FREELANCER_RESET_KEY(pqxx::connection &connection, const std::string& freelancerEmail, const std::string& passwordResetKey) { - connection.prepare(PREPARED_STATEMENT_INSERT_FREELANCER_RESET_KEY, SQL_STATEMENT_INSERT_FREELANCER_RESET_KEY); pqxx::work work(connection); work.exec_prepared(PREPARED_STATEMENT_INSERT_FREELANCER_RESET_KEY, freelancerEmail, passwordResetKey); work.commit(); - connection.unprepare(PREPARED_STATEMENT_INSERT_FREELANCER_RESET_KEY); + } + + /* + * Prepares a statement based on ID + * Takes an open pqxx::connection, the statement id + */ + void prepareStatement(pqxx::connection &connection, int statementID) { + const std::string& preparedStatementName = preparedStatementNameCollection.at(statementID); + connection.prepare(preparedStatementName, preparedStatementCollection.at(preparedStatementName)); + } + + /* + * Prepares a statement based on Statement name + * Takes an open pqxx::connection, the statement name + */ + void prepareStatement(pqxx::connection &connection, const std::string& PREPARED_STATEMENT) { + connection.prepare(PREPARED_STATEMENT, preparedStatementCollection.at(PREPARED_STATEMENT)); + } + + /* + * Prepares Statements + * ID list is found as consts in DatabaseStatementConstCollection + */ + void prepareStatements(pqxx::connection &connection, const std::vector& statementIDsToPrepare) { + for (int statementID : statementIDsToPrepare) { + prepareStatement(connection, preparedStatementNameCollection.at(statementID)); + } } /* diff --git a/src/databaseStatementConstCollection.cpp b/src/databaseStatementConstCollection.cpp new file mode 100644 index 0000000..c9be68d --- /dev/null +++ b/src/databaseStatementConstCollection.cpp @@ -0,0 +1,235 @@ +#include +#include + +/* + * Database Statement Const Collection + */ +namespace DatabaseStatementConstCollection { + /* + * Name and Statement for prepared statement to insert an item into Requests + */ + const static std::string PREPARED_STATEMENT_INSERT_ITEM_IN_REQUESTS = "insertItemInRequests"; + const static std::string SQL_STATEMENT_INSERT_ITEM_IN_REQUESTS = "INSERT INTO requests(id, customerEmailAddress, freelancerid , templateid , currencyPreference, priceUpFront, priceOnDeliver, requestDescription, accepted, upFrontInvoiceID, onDeliverInvoiceID, upFrontPaid, onDeliverPaid, completed, customerContactDetails, customerName) VALUES(DEFAULT, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15);"; + + /* + * Name and Statement for prepared statement to create a new freelancer + */ + const static std::string PREPARED_STATEMENT_INSERT_NEW_FREELANCER = "insertNewFreelancer"; + const static std::string SQL_STATEMENT_INSERT_NEW_FREELANCER = "INSERT INTO freelancers (emailaddress, name, salt, hash) values($1, $2, $3, $4);"; + + /* + * Name and Statement for prepared statement to select an item based on a given ID + * Case for boolean return values because the default return value is f/t instead of 0/1 or false/true + */ + const static std::string PREPARED_STATEMENT_SELECT_ITEM_BY_ID = "selectItemByID"; + const static std::string SQL_STATEMENT_SELECT_ITEM_BY_ID = "SELECT requests.id , customerEmailAddress, freelancers.name, templates.name, currencyPreference, priceUpFront, priceOnDeliver, requestDescription, (CASE WHEN requests.accepted THEN 1 ELSE 0 END) AS accepted, upFrontInvoiceID, onDeliverInvoiceID, (CASE WHEN requests.upFrontPaid THEN 1 ELSE 0 END) AS upFrontPaid, (CASE WHEN requests.onDeliverPaid THEN 1 ELSE 0 END) AS onDeliverPaid FROM requests INNER JOIN freelancers ON freelancers.id=requests.freelancerID INNER JOIN templates ON templates.id=requests.templateID WHERE requests.id=$1;"; + + /* + * Name and Statement for prepared statement to select a freelancers commission state based on a given id + * 0 == commissions are open + * 1 == commissions are closed + */ + const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_COMMISSION_STATE = "selectFreelancerCommissionState"; + const static std::string SQL_STATEMENT_SELECT_FREELANCER_COMMISSION_STATE = "select (case when (commissionlimit <= (select count(*) as requestCount from requests where requests.accepted = true and requests.freelancerid = id group by freelancerid)) then 1 else 0 end) as commissionsclosed from freelancers where freelancers.id = $1;"; + + /* + * Name and Statement for prepared statement to select a freelancers emailaddress based on a given id + */ + const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL = "selectFreelancerEmailAddress"; + const static std::string SQL_STATEMENT_SELECT_FREELANCER_EMAIL = "select emailaddress from freelancers where id = $1;"; + + /* + * Name and Statement for prepared statement to check if an email is already registered with a freelancer + */ + const static std::string PREPARED_STATEMENT_SELECT_CHECK_EMAIL_EXISTS = "selectCheckEmailExists"; + const static std::string SQL_STATEMENT_SELECT_CHECK_EMAIL_EXISTS = "select count(*) from freelancers where emailaddress = $1;"; + + /* + * Name and Statement for prepared statement to validate if a freelancer is already logged in + */ + const static std::string PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_LOGIN_STATE = "selectCheckFreelancerLoginState"; + const static std::string SQL_STATEMENT_SELECT_CHECK_FREELANCER_LOGIN_STATE = "select count(*) from freelancers where emailaddress = $1 AND loginvalidationkey = $2;"; + + /* + * Name and Statement for prepared statement to get salt using a given email + */ + const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_SALT = "selectFreelancerSalt"; + const static std::string SQL_STATEMENT_SELECT_FREELANCER_SALT = "select salt from freelancers where emailaddress = $1;"; + /* + * Name and Statement for prepared statement to get id using a given email + */ + const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_ID = "selectFreelancerID"; + const static std::string SQL_STATEMENT_SELECT_FREELANCER_ID = "select id from freelancers where emailaddress = $1;"; + + /* + * Name and Statement for prepared statement to check if hash is valid + */ + const static std::string PREPARED_STATEMENT_SELECT_CHECK_HASH_VALID = "selectCheckHashValid"; + const static std::string SQL_STATEMENT_SELECT_CHECK_HASH_VALID = "select count(*) from freelancers where emailaddress = $1 AND hash = $2;"; + + /* + * Name and Statement for prepared statement to select a freelancer based on a given id + */ + const static std::string PREPARED_STATEMENT_SELECT_FREELANCER = "selectFreelancer"; + const static std::string SQL_STATEMENT_SELECT_FREELANCER = "select id, name, generalinformation, basicinformation from freelancers WHERE id=$1;"; + + /* + * Name and Statement for prepared statement to select a freelancer based on a given id for presentation to the customer + */ + const static std::string PREPARED_STATEMENT_SELECT_TEMPLATE = "selectTemplate"; + const static std::string SQL_STATEMENT_SELECT_TEMPLATE = "select templates.id as templateid, templates.name as templatename, freelancers.id as freelancerid, freelancers.name as freelancername, contactdata, contactinformation, currencypreference, (coalesce(priceupfront ,0) + coalesce(priceondeliver ,0)) as pricetotal, priceupfront, priceondeliver, content from templates inner join freelancers on freelancers.id=templates.freelancerid where templates.id = $1;"; + + /* + * Name and Statement for prepared statement to select a freelancer based on a given id for usage in a request + */ + const static std::string PREPARED_STATEMENT_SELECT_TEMPLATE_FLAT = "selectTemplateFlat"; + const static std::string SQL_STATEMENT_SELECT_TEMPLATE_FLAT = "select freelancerid, currencypreference, priceupfront, priceondeliver from templates where id = $1;"; + + /* + * Name and Statement for prepared statement to select a freelancers templates based on a given freelancer id + */ + const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_TEMPLATES = "selectFreelancerTemplates"; + const static std::string SQL_STATEMENT_SELECT_FREELANCER_TEMPLATES = "select id, name, content from templates where freelancerid = $1 order by id;"; + + /* + * Name and Statement for prepared statement to select an alias and its route via the alias name + */ + const static std::string PREPARED_STATEMENT_SELECT_ALIAS = "selectAlias"; + const static std::string SQL_STATEMENT_SELECT_ALIAS = "select aliasname, route, routeparameter, routevalue from aliasroutes where aliasname = $1;"; + + /* + * Name and Statement for prepared statement to update the loginvalidationkey of a freelancer via the freelancerID + */ + const static std::string PREPARED_STATEMENT_UPDATE_LOGIN_VALIDATION_KEY = "updateLoginValidationKey"; + const static std::string SQL_STATEMENT_UPDATE_LOGIN_VALIDATION_KEY = "update freelancers set loginvalidationkey = $1 where emailaddress = $2;"; + + /* + * Name and Statement for prepared statement to update the passwordhash of a freelancer via the freelancerEmail + */ + const static std::string PREPARED_STATEMENT_UPDATE_FREELANCER_PASSWORD_HASH = "updateFreelancerPasswordHash"; + const static std::string SQL_STATEMENT_UPDATE_FREELANCER_PASSWORD_HASH = "update freelancers set hash = $1, salt = $2 where emailaddress = $3;"; + + /* + * Name and Statement for prepared statement to check if an email has a reset key + */ + const static std::string PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY = "checkFreelancerResetKey"; + const static std::string SQL_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY = "select count(*) from passwordresetkeys where freelanceremail = $1;"; + + /* + * Name and Statement for prepared statement to select a freelancers emailaddress based on a given password reset key + */ + const static std::string PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY = "selectFreelancerEmailAddressFromPasswordResetKeys"; + const static std::string SQL_STATEMENT_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY = "select freelanceremail from passwordresetkeys where passwordresetkey = $1;"; + + /* + * Name and Statement for prepared statement to check if an reset key is expired + * returns 0 if key not expired + */ + const static std::string PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED = "checkFreelancerResetKeyExpired"; + const static std::string SQL_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED = "select count(*) from passwordresetkeys where passwordresetkey = $1 and expiration <= CURRENT_TIMESTAMP;"; + + /* + * Name and Statement for prepared statement to create new reset key + * $1 = email, $2 = resetkey + */ + const static std::string PREPARED_STATEMENT_INSERT_FREELANCER_RESET_KEY = "insertFreelancerResetKey"; + const static std::string SQL_STATEMENT_INSERT_FREELANCER_RESET_KEY = "insert into passwordresetkeys values ($1, $2, CURRENT_TIMESTAMP);"; + + /* + * Name and Statement for prepared statement to delete specific reset key of a freelancer + */ + const static std::string PREPARED_STATEMENT_DELETE_FREELANCER_RESET_KEY = "deleteFreelancerResetKey"; + const static std::string SQL_STATEMENT_DELETE_FREELANCER_RESET_KEY = "delete from passwordresetkeys where freelanceremail = $1;"; + + /* + * IDs of prepared statements + */ + const static int ID_INSERT_ITEM_IN_REQUESTS = 0; + const static int ID_INSERT_NEW_FREELANCER = 1; + const static int ID_SELECT_ITEM_BY_ID = 2; + const static int ID_SELECT_FREELANCER_COMMISSION_STATE = 3; + const static int ID_SELECT_FREELANCER_EMAIL = 4; + const static int ID_SELECT_CHECK_EMAIL_EXISTS = 5; + const static int ID_SELECT_CHECK_FREELANCER_LOGIN_STATE = 6; + const static int ID_SELECT_FREELANCER_SALT = 7; + const static int ID_SELECT_FREELANCER_ID = 8; + const static int ID_SELECT_CHECK_HASH_VALID = 9; + const static int ID_SELECT_FREELANCER = 10; + const static int ID_SELECT_TEMPLATE = 11; + const static int ID_SELECT_TEMPLATE_FLAT = 12; + const static int ID_SELECT_FREELANCER_TEMPLATES = 13; + const static int ID_SELECT_ALIAS = 14; + const static int ID_UPDATE_LOGIN_VALIDATION_KEY = 15; + const static int ID_UPDATE_FREELANCER_PASSWORD_HASH = 16; + const static int ID_SELECT_CHECK_FREELANCER_RESET_KEY = 17; + const static int ID_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY = 18; + const static int ID_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED = 19; + const static int ID_INSERT_FREELANCER_RESET_KEY = 20; + const static int ID_DELETE_FREELANCER_RESET_KEY = 21; + + /* + * Easy access to prepared statements via prepared statement name + */ + const static std::map preparedStatementCollection = { + {PREPARED_STATEMENT_INSERT_ITEM_IN_REQUESTS, SQL_STATEMENT_INSERT_ITEM_IN_REQUESTS}, + {PREPARED_STATEMENT_INSERT_NEW_FREELANCER, SQL_STATEMENT_INSERT_NEW_FREELANCER}, + {PREPARED_STATEMENT_SELECT_ITEM_BY_ID, SQL_STATEMENT_SELECT_ITEM_BY_ID}, + {PREPARED_STATEMENT_SELECT_FREELANCER_COMMISSION_STATE, SQL_STATEMENT_SELECT_FREELANCER_COMMISSION_STATE}, + {PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL, SQL_STATEMENT_SELECT_FREELANCER_EMAIL}, + {PREPARED_STATEMENT_SELECT_CHECK_EMAIL_EXISTS, SQL_STATEMENT_SELECT_CHECK_EMAIL_EXISTS}, + {PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_LOGIN_STATE, SQL_STATEMENT_SELECT_CHECK_FREELANCER_LOGIN_STATE}, + {PREPARED_STATEMENT_SELECT_FREELANCER_SALT, SQL_STATEMENT_SELECT_FREELANCER_SALT}, + {PREPARED_STATEMENT_SELECT_FREELANCER_ID, SQL_STATEMENT_SELECT_FREELANCER_ID}, + {PREPARED_STATEMENT_SELECT_CHECK_HASH_VALID, SQL_STATEMENT_SELECT_CHECK_HASH_VALID}, + {PREPARED_STATEMENT_SELECT_FREELANCER, SQL_STATEMENT_SELECT_FREELANCER}, + {PREPARED_STATEMENT_SELECT_TEMPLATE, SQL_STATEMENT_SELECT_TEMPLATE}, + {PREPARED_STATEMENT_SELECT_TEMPLATE_FLAT, SQL_STATEMENT_SELECT_TEMPLATE_FLAT}, + {PREPARED_STATEMENT_SELECT_FREELANCER_TEMPLATES, SQL_STATEMENT_SELECT_FREELANCER_TEMPLATES}, + {PREPARED_STATEMENT_SELECT_ALIAS, SQL_STATEMENT_SELECT_ALIAS}, + {PREPARED_STATEMENT_UPDATE_LOGIN_VALIDATION_KEY, SQL_STATEMENT_UPDATE_LOGIN_VALIDATION_KEY}, + {PREPARED_STATEMENT_UPDATE_FREELANCER_PASSWORD_HASH, SQL_STATEMENT_UPDATE_FREELANCER_PASSWORD_HASH}, + {PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY, SQL_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY}, + {PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY, SQL_STATEMENT_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY}, + {PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED, SQL_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED}, + {PREPARED_STATEMENT_INSERT_FREELANCER_RESET_KEY, SQL_STATEMENT_INSERT_FREELANCER_RESET_KEY}, + {PREPARED_STATEMENT_DELETE_FREELANCER_RESET_KEY, SQL_STATEMENT_DELETE_FREELANCER_RESET_KEY} + }; + /* + * Easy access to prepared statement name via int + */ + const static std::map preparedStatementNameCollection = { + {ID_INSERT_ITEM_IN_REQUESTS, PREPARED_STATEMENT_INSERT_ITEM_IN_REQUESTS}, + {ID_INSERT_NEW_FREELANCER, PREPARED_STATEMENT_INSERT_NEW_FREELANCER}, + {ID_SELECT_ITEM_BY_ID, PREPARED_STATEMENT_SELECT_ITEM_BY_ID}, + {ID_SELECT_FREELANCER_COMMISSION_STATE, PREPARED_STATEMENT_SELECT_FREELANCER_COMMISSION_STATE}, + {ID_SELECT_FREELANCER_EMAIL, PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL}, + {ID_SELECT_CHECK_EMAIL_EXISTS, PREPARED_STATEMENT_SELECT_CHECK_EMAIL_EXISTS}, + {ID_SELECT_CHECK_FREELANCER_LOGIN_STATE, PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_LOGIN_STATE}, + {ID_SELECT_FREELANCER_SALT, PREPARED_STATEMENT_SELECT_FREELANCER_SALT}, + {ID_SELECT_FREELANCER_ID, PREPARED_STATEMENT_SELECT_FREELANCER_ID}, + {ID_SELECT_CHECK_HASH_VALID, PREPARED_STATEMENT_SELECT_CHECK_HASH_VALID}, + {ID_SELECT_FREELANCER, PREPARED_STATEMENT_SELECT_FREELANCER}, + {ID_SELECT_TEMPLATE, PREPARED_STATEMENT_SELECT_TEMPLATE}, + {ID_SELECT_TEMPLATE_FLAT, PREPARED_STATEMENT_SELECT_TEMPLATE_FLAT}, + {ID_SELECT_FREELANCER_TEMPLATES, PREPARED_STATEMENT_SELECT_FREELANCER_TEMPLATES}, + {ID_SELECT_ALIAS, PREPARED_STATEMENT_SELECT_ALIAS}, + {ID_UPDATE_LOGIN_VALIDATION_KEY, PREPARED_STATEMENT_UPDATE_LOGIN_VALIDATION_KEY}, + {ID_UPDATE_FREELANCER_PASSWORD_HASH, PREPARED_STATEMENT_UPDATE_FREELANCER_PASSWORD_HASH}, + {ID_SELECT_CHECK_FREELANCER_RESET_KEY, PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY}, + {ID_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY, PREPARED_STATEMENT_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY}, + {ID_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED, PREPARED_STATEMENT_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED}, + {ID_INSERT_FREELANCER_RESET_KEY, PREPARED_STATEMENT_INSERT_FREELANCER_RESET_KEY}, + {ID_DELETE_FREELANCER_RESET_KEY, PREPARED_STATEMENT_DELETE_FREELANCER_RESET_KEY} + }; + + /* + * Statement to remove expired reset keys + */ + const static std::string SQL_STATEMENT_PURGE_EXPIRED_FREELANCER_RESET_KEYS = "delete from passwordresetkeys where expiration <= CURRENT_TIMESTAMP;"; + + /* + * Selects freelancers, their basicInfo and if the commissions are closed/open ordered by name. + * Delivers if the commission limit has been reached and if the commissions are closed based on the accepted/completed state of the freelancers requests + */ + const static std::string SQL_Statement_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE = "select id, name, basicInformation , (case when (commissionlimit <= (select count(*) as requestCount from requests where requests.accepted = true and requests.completed = false and requests.freelancerid = freelancers.id group by freelancers.id)) then 'Closed' else 'Open' end) as commissionsclosed from freelancers order by name;"; +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 3d33df4..8cf457e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,13 +52,17 @@ int main(int argc, char *argv[]) { //Parses the request body and extracts the specified value int freelancerID = stoi(Utilities::extractSingleValueFromRequestBody(postRequest.body.c_str(), "freelancerID")); pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatements(databaseConnection, { + ID_SELECT_FREELANCER, + ID_SELECT_FREELANCER_TEMPLATES + }); pqxx::result resultFreelancer = Database::executePreparedStatement_SELECT_FREELANCER(databaseConnection, freelancerID); //error handling if invalid ID was delivered string freelancerHTML = "customer_FreelancerListing_NOTFOUND.html"; crow::json::wvalue resultJsonFreelancerTemplate; - if (resultFreelancer.size() != 0){ + if (!resultFreelancer.empty()){ freelancerHTML = "customer_FreelancerListing.html"; pqxx::result resultFreelancerTemplates = Database::executePreparedStatement_SELECT_FREELANCER_TEMPLATES(databaseConnection, freelancerID); resultJsonFreelancerTemplate = Database::convertResultToJSON(resultFreelancerTemplates, "templates"); @@ -67,7 +71,7 @@ int main(int argc, char *argv[]) { auto page = crow::mustache::load(freelancerHTML); crow::mustache::context ctx(resultJsonFreelancerTemplate); - if (resultFreelancer.size() != 0){ + if (!resultFreelancer.empty()){ /* * puts freelancer data into context */ @@ -91,6 +95,10 @@ int main(int argc, char *argv[]) { int templateID = stoi(Utilities::extractSingleValueFromRequestBody(postRequest.body.c_str(), "templateID")); pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatements(databaseConnection, { + ID_SELECT_TEMPLATE, + ID_SELECT_FREELANCER_COMMISSION_STATE + }); pqxx::result resultTemplate = Database::executePreparedStatement_SELECT_TEMPLATE(databaseConnection, templateID); crow::json::wvalue resultJsonTemplate = Database::convertResultRowToJSON(resultTemplate); @@ -101,11 +109,11 @@ int main(int argc, char *argv[]) { crow::mustache::context ctx(resultJsonTemplate); bool commissionState = false; - if (resultTemplate.size() > 0) { + if (!resultTemplate.empty()) { //use freelancerID based on SQL_STATEMENT_SELECT_TEMPLATE pqxx::result resultCommissionState = Database::executePreparedStatement_SELECT_FREELANCER_COMMISSION_STATE(databaseConnection, stoi(resultTemplate.at(0).at(2).c_str())); //the commissionstate - if (resultCommissionState.size() == 0 || stoi(resultCommissionState.at(0).at(0).c_str()) == 1) + if (resultCommissionState.empty() || stoi(resultCommissionState.at(0).at(0).c_str()) == 1) commissionState = true; } ctx["ERROR_COMMISSIONS_CLOSED"] = commissionState; @@ -121,6 +129,7 @@ int main(int argc, char *argv[]) { int templateID = stoi(Utilities::extractSingleValueFromRequestBody(postRequest.body.c_str(), "templateID")); pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatement(databaseConnection, ID_SELECT_TEMPLATE); pqxx::result resultTemplate = Database::executePreparedStatement_SELECT_TEMPLATE(databaseConnection, templateID); crow::json::wvalue resultJsonTemplate = Database::convertResultRowToJSON(resultTemplate); @@ -150,7 +159,7 @@ int main(int argc, char *argv[]) { Utilities::decodeString(postRequestBody); vector splitPostRequestBody = Utilities::splitStringIntoVector(postRequestBody, '&'); bool requestFillCompletion = false; - for (string item : splitPostRequestBody) { + for (const string& item : splitPostRequestBody) { vector splitItem = Utilities::splitStringIntoVector(item, '='); if (splitItem.at(0) == "customername") newRequest.customerName = splitItem.at(1); @@ -166,12 +175,17 @@ int main(int argc, char *argv[]) { if (newRequest.customerName != "" && (newRequest.customerEmailAddress != "" || newRequest.customerContactDetails != "") && newRequest.requestDescription != "" ) requestFillCompletion = true; - - ctx["templateid"] = newRequest.templateID; + Database::prepareStatements(databaseConnection, { + ID_SELECT_TEMPLATE_FLAT, + ID_SELECT_FREELANCER_COMMISSION_STATE, + ID_INSERT_ITEM_IN_REQUESTS, + ID_SELECT_FREELANCER_EMAIL + }); + pqxx::result resultTemplate = Database::executePreparedStatement_SELECT_TEMPLATE_FLAT(databaseConnection, newRequest.templateID); - if (resultTemplate.size() > 0 && requestFillCompletion) { + if (!resultTemplate.empty() && requestFillCompletion) { for (int i = 0; i < resultTemplate.columns(); ++i) { //freelancerid newRequest.freelancerID = stoi(resultTemplate.at(0).at(0).c_str()); @@ -186,7 +200,7 @@ int main(int argc, char *argv[]) { pqxx::result resultCommissionState = Database::executePreparedStatement_SELECT_FREELANCER_COMMISSION_STATE(databaseConnection, newRequest.freelancerID); //the commissionstate - if (resultCommissionState.size() == 0 || stoi(resultCommissionState.at(0).at(0).c_str()) == 1) { + if (resultCommissionState.empty() || stoi(resultCommissionState.at(0).at(0).c_str()) == 1) { ctx["ERROR_COMMISSIONS_CLOSED"] = true; } else { @@ -194,7 +208,7 @@ int main(int argc, char *argv[]) { if (resultInsertOperation == 0) { templateHTML = "customer_Freelancer_Template_Request_Fulfilment.html"; pqxx::result resultEmailAddress = Database::executePreparedStatement_SELECT_FREELANCER_EMAIL(databaseConnection, newRequest.freelancerID); - if (resultEmailAddress.size() > 0) + if (!resultEmailAddress.empty()) Utilities::sendEmail(configuration, resultEmailAddress.at(0).at(0).c_str(), "NEW REQUEST", newRequest.toJSONString()); } else { @@ -243,6 +257,7 @@ int main(int argc, char *argv[]) { string freelancerEmail = ctx.get_cookie("freelancerEmail"); if (!freelancerEmail.empty() && !loginKey.empty()) { if (Utilities::checkFreelancerLoginState(configuration, loginKey, freelancerEmail)) { + Database::prepareStatement(databaseConnection, ID_UPDATE_LOGIN_VALIDATION_KEY); Database::executePreparedStatement_UPDATE_LOGIN_VALIDATION_KEY(databaseConnection, "EXPIRED", freelancerEmail); ctx.set_cookie("loginKey", Utilities::generateExpiredCookie()); ctx.set_cookie("freelancerEmail", Utilities::generateExpiredCookie()); @@ -297,6 +312,12 @@ int main(int argc, char *argv[]) { if (!email.empty()) { pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatements(databaseConnection, { + ID_SELECT_CHECK_EMAIL_EXISTS, + ID_SELECT_CHECK_FREELANCER_RESET_KEY, + ID_DELETE_FREELANCER_RESET_KEY, + ID_INSERT_FREELANCER_RESET_KEY + }); pqxx::result checkFreelancerExists = Database::executePreparedStatement_SELECT_CHECK_EMAIL_EXISTS(databaseConnection, email); int checkFreelancerExistsExtracted = stoi(checkFreelancerExists.at(0).at(0).c_str()); if (checkFreelancerExistsExtracted == 1) { @@ -325,6 +346,7 @@ int main(int argc, char *argv[]) { ([&, configuration](string passwordResetKey) { crow::mustache::context ctx; pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatement(databaseConnection, ID_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY); pqxx::result freelancerEmail = Database::executePreparedStatement_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY(databaseConnection, passwordResetKey); if (!freelancerEmail.empty()) { ctx["freelanceremail"] = freelancerEmail.at(0).at(0).c_str(); @@ -355,8 +377,14 @@ int main(int argc, char *argv[]) { passwordConfirmation = splitItem.at(1); } pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatements(databaseConnection, { + ID_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY, + ID_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED, + ID_DELETE_FREELANCER_RESET_KEY, + ID_UPDATE_FREELANCER_PASSWORD_HASH + }); pqxx::result freelancerEmail = Database::executePreparedStatement_SELECT_FREELANCER_EMAIL_FROM_PASSWORD_RESET_KEY(databaseConnection, passwordResetKey); - if (!freelancerEmail.empty() && !password.empty() && !(password.compare(passwordConfirmation) == 0)) { + if (!freelancerEmail.empty() && !password.empty() && password.compare(passwordConfirmation) != 0) { string email = freelancerEmail.at(0).at(0).c_str(); pqxx::result keyExpiration = Database::executePreparedStatement_SELECT_CHECK_FREELANCER_RESET_KEY_EXPIRED(databaseConnection, email); if (stoi(keyExpiration.at(0).at(0).c_str()) == 0) { @@ -387,7 +415,7 @@ int main(int argc, char *argv[]) { ctx["PASSWORD_EMPTY"] = true; if (freelancerEmail.empty()) ctx["PASSWORD_RESET_DOES_NOT_EXIST"] = true; - if (!(password.compare(passwordConfirmation) == 0)) + if (password.compare(passwordConfirmation) != 0) ctx["PASSWORD_RESET_PASS_CONFIRMATION"] = true; } auto page = crow::mustache::load("passwordReset_Fulfillment.html"); @@ -420,6 +448,12 @@ int main(int argc, char *argv[]) { if (!email.empty() && !password.empty()){ //check if freelancer exists pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatements(databaseConnection, { + ID_SELECT_CHECK_EMAIL_EXISTS, + ID_SELECT_FREELANCER_SALT, + ID_SELECT_CHECK_HASH_VALID, + ID_UPDATE_LOGIN_VALIDATION_KEY + }); pqxx::result checkFreelancerExists = Database::executePreparedStatement_SELECT_CHECK_EMAIL_EXISTS(databaseConnection, email); int checkFreelancerExistsExtracted = stoi(checkFreelancerExists.at(0).at(0).c_str()); if (checkFreelancerExistsExtracted == 1) { @@ -505,12 +539,16 @@ int main(int argc, char *argv[]) { } //check if signup data is complete - if (!email.empty() && !name.empty() && !password.empty() && !(password.compare(passwordConfirmation) == 0)) + if (!email.empty() && !name.empty() && !password.empty() && password.compare(passwordConfirmation) != 0) requestFillCompletion = true; if (requestFillCompletion) { //check if email address hasn't been registered yet pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatements(databaseConnection, { + ID_SELECT_CHECK_EMAIL_EXISTS, + ID_INSERT_NEW_FREELANCER + }); pqxx::result checkResult = Database::executePreparedStatement_SELECT_CHECK_EMAIL_EXISTS(databaseConnection, email); int checkResultExtracted = stoi(checkResult.at(0).at(0).c_str()); @@ -542,7 +580,7 @@ int main(int argc, char *argv[]) { } else { ctx["REGISTRATION_ERROR"] = true; - if (!(password.compare(passwordConfirmation) == 0)) + if (password.compare(passwordConfirmation) != 0) ctx["REGISTRATION_ERROR_PASS_CONFIRMATION"] = true; ctx["REGISTRATION_ERROR_EMAIL_NAME_PASS_NOT_FILLED"] = true; } diff --git a/src/utilities.cpp b/src/utilities.cpp index ff3cd28..becbd25 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -14,6 +14,7 @@ #include "emailTemplateCollection.cpp" using namespace jed_utils::cpp; +using namespace DatabaseStatementConstCollection; /* * Utility Manager @@ -306,6 +307,7 @@ namespace Utilities { */ crow::json::wvalue getAlias(const Utilities::config& configuration, const std::string& alias) { pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatement(databaseConnection, ID_SELECT_ALIAS); pqxx::result resultAlias = Database::executePreparedStatement_SELECT_ALIAS(databaseConnection, alias); crow::json::wvalue resultJsonAlias; if (!resultAlias.empty()) @@ -335,6 +337,7 @@ namespace Utilities { bool loggedIn = false; //check if freelancer exists pqxx::connection databaseConnection(configuration.databaseConnectionString); + Database::prepareStatement(databaseConnection, ID_SELECT_CHECK_FREELANCER_LOGIN_STATE); pqxx::result checkLoginKey = Database::executePreparedStatement_SELECT_CHECK_FREELANCER_LOGIN_STATE(databaseConnection, freelancerEmail, loginKey); int checkLoginKeyExtracted = std::stoi(checkLoginKey.at(0).at(0).c_str()); if (checkLoginKeyExtracted == 1) @@ -389,8 +392,4 @@ namespace Utilities { std::string generateExpiredCookie() { return "EXPIRED; HttpOnly; Secure; Path=/; Max-Age=0"; } - - - - } \ No newline at end of file