minor refactoring in config
implement pagination
This commit is contained in:
@ -195,6 +195,30 @@ namespace Database {
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes the SELECT_FREELANCERS_WITHCOMMISSIONSSTATE statement
|
||||
* Takes an open pqxx::connection
|
||||
*/
|
||||
pqxx::result executeStatement_SELECT_FREELANCERS_COUNT(pqxx::connection &connection) {
|
||||
pqxx::work work(connection);
|
||||
pqxx::result result = work.exec(SQL_Statement_SELECT_FREELANCERS_COUNT);
|
||||
work.commit();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes the SELECT_FREELANCERS_WITHCOMMISSIONSSTATE_LIMITED_AND_OFFSET statement
|
||||
* Takes an open pqxx::connection the limit and the offset
|
||||
*/
|
||||
pqxx::result executePreparedStatement_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE_LIMITED_AND_OFFSET(pqxx::connection &connection, int limit, int offset) {
|
||||
if (offset < 0)
|
||||
offset = 0;
|
||||
pqxx::work work(connection);
|
||||
pqxx::result result = work.exec_prepared(PREPARED_STATEMENT_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE_LIMITED_AND_OFFSET, limit, offset);
|
||||
work.commit();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes the PURGE_EXPIRED_FREELANCER_RESET_KEYS statement
|
||||
* Takes an open pqxx::connection
|
||||
|
@ -144,6 +144,12 @@ namespace DatabaseStatementConstCollection {
|
||||
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;";
|
||||
|
||||
/*
|
||||
* Name and Statement for prepared statement to delete specific reset key of a freelancer
|
||||
*/
|
||||
const static std::string PREPARED_STATEMENT_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE_LIMITED_AND_OFFSET = "selectFreelancersWithCommissionstateLimitedAndOffset";
|
||||
const static std::string SQL_STATEMENT_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE_LIMITED_AND_OFFSET = "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 limit $1 offset $2;";
|
||||
|
||||
/*
|
||||
* IDs of prepared statements
|
||||
*/
|
||||
@ -169,6 +175,7 @@ namespace DatabaseStatementConstCollection {
|
||||
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;
|
||||
const static int ID_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE_LIMITED_AND_OFFSET = 22;
|
||||
|
||||
/*
|
||||
* Easy access to prepared statements via prepared statement name
|
||||
@ -195,7 +202,8 @@ namespace DatabaseStatementConstCollection {
|
||||
{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}
|
||||
{PREPARED_STATEMENT_DELETE_FREELANCER_RESET_KEY, SQL_STATEMENT_DELETE_FREELANCER_RESET_KEY},
|
||||
{PREPARED_STATEMENT_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE_LIMITED_AND_OFFSET, SQL_STATEMENT_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE_LIMITED_AND_OFFSET}
|
||||
};
|
||||
/*
|
||||
* Easy access to prepared statement name via int
|
||||
@ -222,7 +230,8 @@ namespace DatabaseStatementConstCollection {
|
||||
{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}
|
||||
{ID_DELETE_FREELANCER_RESET_KEY, PREPARED_STATEMENT_DELETE_FREELANCER_RESET_KEY},
|
||||
{ID_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE_LIMITED_AND_OFFSET, PREPARED_STATEMENT_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE_LIMITED_AND_OFFSET}
|
||||
};
|
||||
|
||||
/*
|
||||
@ -235,5 +244,11 @@ namespace DatabaseStatementConstCollection {
|
||||
* 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;";
|
||||
|
||||
/*
|
||||
* Selects freelancer count
|
||||
*/
|
||||
const static std::string SQL_Statement_SELECT_FREELANCERS_COUNT = "select count(*) from freelancers;";
|
||||
|
||||
}
|
||||
#endif
|
@ -15,6 +15,7 @@
|
||||
# regularTaskExecution={false}
|
||||
# regularTaskExecutionIntervalSeconds={900} 15min
|
||||
# regularTaskExecutionModules={} # options separated by "|": reeeprint|counter
|
||||
# itemsPerPage{0} #0 == no pagination
|
||||
|
||||
|
||||
|
||||
@ -41,6 +42,8 @@ regularTaskExecution=true;
|
||||
|
||||
regularTaskExecutionIntervalSeconds=2;
|
||||
|
||||
regularTaskExecutionModules=reeeprint|counter;
|
||||
regularTaskExecutionModules=;
|
||||
|
||||
itemsPerPage=5;
|
||||
|
||||
#configend#
|
||||
|
24
src/main.cpp
24
src/main.cpp
@ -1,6 +1,7 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <map>
|
||||
|
||||
#include <pqxx/pqxx>
|
||||
|
||||
@ -36,9 +37,28 @@ int main(int argc, char *argv[]) {
|
||||
* Freelancer Profile listing for customers
|
||||
*/
|
||||
CROW_ROUTE(app, "/").methods("POST"_method, "GET"_method)
|
||||
([configuration]() {
|
||||
([configuration](const crow::request& request) {
|
||||
int selectedPage = 1;
|
||||
if (!request.url_params.keys().empty()) {
|
||||
string selectedPageString = request.url_params.get("page");
|
||||
if (!selectedPageString.empty())
|
||||
selectedPage = stoi(selectedPageString);
|
||||
}
|
||||
auto page = crow::mustache::load(TEMPLATE_CUSTOMER_INDEX_FREELANCER_LISTING);
|
||||
crow::mustache::context ctx(Utilities::getFreelancerListing(configuration));
|
||||
crow::mustache::context ctx(Utilities::getFreelancerListing(configuration, selectedPage));
|
||||
if (configuration.itemsPerPage > 0) {
|
||||
ctx[MUSTACHE_PAGINATION] = true;
|
||||
vector<int> pages = Utilities::getFreelancerIndexPagination(configuration);
|
||||
ctx[MUSTACHE_PAGINATION_NUMBERS] = pages;
|
||||
if (selectedPage <= 1)
|
||||
ctx[MUSTACHE_PAGINATION_PREVIOUS] = 1;
|
||||
else
|
||||
ctx[MUSTACHE_PAGINATION_PREVIOUS] = selectedPage - 1;
|
||||
if (selectedPage >= pages.size())
|
||||
ctx[MUSTACHE_PAGINATION_NEXT] = pages.size();
|
||||
else
|
||||
ctx[MUSTACHE_PAGINATION_NEXT] = selectedPage + 1;
|
||||
}
|
||||
return page.render(ctx);
|
||||
});
|
||||
|
||||
|
@ -52,5 +52,11 @@ namespace TemplateConstCollection {
|
||||
|
||||
//Mustache Cookie variable names
|
||||
const static std::string MUSTACHE_COOKIE_LOGGED_IN = "COOKIE_LOGGED_IN";
|
||||
|
||||
//Mustache variable names
|
||||
const static std::string MUSTACHE_PAGINATION = "PAGINATION";
|
||||
const static std::string MUSTACHE_PAGINATION_NUMBERS = "PAGINATION_NUMBERS";
|
||||
const static std::string MUSTACHE_PAGINATION_PREVIOUS = "PAGINATION_PREVIOUS";
|
||||
const static std::string MUSTACHE_PAGINATION_NEXT = "PAGINATION_NEXT";
|
||||
}
|
||||
#endif
|
@ -11,6 +11,7 @@
|
||||
#include <stdexcept>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <math.h>
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include <pqxx/pqxx>
|
||||
@ -78,6 +79,7 @@ namespace Utilities {
|
||||
{MODULE_NAME_REEE_PRINT, false},
|
||||
{MODULE_NAME_COUNTER_PRINT, false}
|
||||
};
|
||||
int itemsPerPage = 20;
|
||||
|
||||
/*
|
||||
* validates existence of mandatory variables in config
|
||||
@ -142,57 +144,64 @@ namespace Utilities {
|
||||
|
||||
if (lineVector.size() == 2) {
|
||||
std::cout << lineVector.at(0) << " - " << lineVector.at(1) << std::endl;
|
||||
std::string lineString = trimFromDelimiter(lineVector.at(1), ';');
|
||||
if (lineString.empty())
|
||||
continue;
|
||||
if (lineVector.at(0) == "emailAddress") {
|
||||
emailAddress = trimFromDelimiter(lineVector.at(1), ';');
|
||||
emailAddress = lineString;
|
||||
continue;
|
||||
}
|
||||
if (lineVector.at(0) == "emailPassword") {
|
||||
emailPassword = trimFromDelimiter(lineVector.at(1), ';');
|
||||
emailPassword = lineString;
|
||||
continue;
|
||||
}
|
||||
if (lineVector.at(0) == "emailServerAddress") {
|
||||
emailServerAddress = trimFromDelimiter(lineVector.at(1), ';');
|
||||
emailServerAddress = lineString;
|
||||
continue;
|
||||
}
|
||||
if (lineVector.at(0) == "emailServerPort") {
|
||||
emailServerPort = std::stoi(trimFromDelimiter(lineVector.at(1), ';'));
|
||||
emailServerPort = std::stoi(lineString);
|
||||
continue;
|
||||
}
|
||||
if (lineVector.at(0) == "emailAddressDisplay") {
|
||||
emailAddressDisplay = trimFromDelimiter(lineVector.at(1), ';');
|
||||
emailAddressDisplay = lineString;
|
||||
continue;
|
||||
}
|
||||
if (lineVector.at(0) == "databaseConnectionString") {
|
||||
databaseConnectionString = trimFromDelimiter(lineVector.at(1), ';');
|
||||
databaseConnectionString = lineString;
|
||||
continue;
|
||||
}
|
||||
if (lineVector.at(0) == "sslCrtPath") {
|
||||
sslCrtPath = trimFromDelimiter(lineVector.at(1), ';');
|
||||
sslCrtPath = lineString;
|
||||
continue;
|
||||
}
|
||||
if (lineVector.at(0) == "sslKeyPath") {
|
||||
sslKeyPath = trimFromDelimiter(lineVector.at(1), ';');
|
||||
sslKeyPath = lineString;
|
||||
continue;
|
||||
}
|
||||
if (lineVector.at(0) == "domain") {
|
||||
domain = trimFromDelimiter(lineVector.at(1), ';');
|
||||
domain = lineString;
|
||||
continue;
|
||||
}
|
||||
if (lineVector.at(0) == "regularTaskExecution") {
|
||||
regularTaskExecution = (trimFromDelimiter(lineVector.at(1), ';') == "true");
|
||||
regularTaskExecution = (lineString == "true");
|
||||
continue;
|
||||
}
|
||||
if (lineVector.at(0) == "regularTaskExecutionIntervalSeconds") {
|
||||
regularTaskExecutionIntervalSeconds = std::stoi(trimFromDelimiter(lineVector.at(1), ';'));
|
||||
regularTaskExecutionIntervalSeconds = std::stoi(lineString);
|
||||
continue;
|
||||
}
|
||||
if (lineVector.at(0) == "regularTaskExecutionModules") {
|
||||
std::vector<std::string> modules = Utilities::splitStringIntoVector(trimFromDelimiter(lineVector.at(1), ';'), '|');
|
||||
std::vector<std::string> modules = Utilities::splitStringIntoVector(lineString, '|');
|
||||
for (const std::string& module : modules) {
|
||||
regularTaskExecutionModules.at(module) = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (lineVector.at(0) == "itemsPerPage") {
|
||||
itemsPerPage = std::stoi(lineString);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -356,12 +365,36 @@ namespace Utilities {
|
||||
* takes configuration
|
||||
* returns crow::json::wvalue with the Freelancer profile listing
|
||||
*/
|
||||
crow::json::wvalue getFreelancerListing(const Utilities::config& configuration) {
|
||||
crow::json::wvalue getFreelancerListing(const Utilities::config& configuration, int page) {
|
||||
pqxx::connection databaseConnection(configuration.databaseConnectionString);
|
||||
pqxx::result result = Database::executeStatement_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE(databaseConnection);
|
||||
pqxx::result result;
|
||||
if (configuration.itemsPerPage == 0)
|
||||
result = Database::executeStatement_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE(databaseConnection);
|
||||
else {
|
||||
Database::prepareStatement(databaseConnection, ID_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE_LIMITED_AND_OFFSET);
|
||||
result = Database::executePreparedStatement_SELECT_FREELANCERS_WITHCOMMISSIONSSTATE_LIMITED_AND_OFFSET(databaseConnection, configuration.itemsPerPage, configuration.itemsPerPage * (page - 1));
|
||||
}
|
||||
|
||||
return Database::convertResultToJSON(result, "freelancerProfiles");
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets a vector<int> with the appropriate pagination for the configuration.itemsPerPage
|
||||
* takes configuration
|
||||
* returns vector<int>
|
||||
*/
|
||||
std::vector<int> getFreelancerIndexPagination(const Utilities::config& configuration) {
|
||||
pqxx::connection databaseConnection(configuration.databaseConnectionString);
|
||||
pqxx::result freelancerCountResult = Database::executeStatement_SELECT_FREELANCERS_COUNT(databaseConnection);
|
||||
double freelancerCount = std::stoi(freelancerCountResult.at(0).at(0).c_str());
|
||||
int pageCount = ceil(freelancerCount / configuration.itemsPerPage);
|
||||
std::vector<int> pagination;
|
||||
for (int i = 1; i <= pageCount; ++i) {
|
||||
pagination.push_back(i);
|
||||
}
|
||||
return pagination;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if freelancer is logged in
|
||||
* Takes config, the loginkey and freelancerid taken from the secure cookie
|
||||
|
@ -23,6 +23,7 @@
|
||||
</tr>
|
||||
{{/freelancerProfiles}}
|
||||
</table>
|
||||
{{> templateIncludes/pagination.html.html}}
|
||||
{{> templateIncludes/freelancerLoginSignupProfileLogoutInterface.html.html}}
|
||||
</body>
|
||||
</html>
|
||||
|
11
templates/templateIncludes/pagination.html.html
Normal file
11
templates/templateIncludes/pagination.html.html
Normal file
@ -0,0 +1,11 @@
|
||||
{{#PAGINATION}}
|
||||
<div>
|
||||
<a href="/?page={{PAGINATION_PREVIOUS}}">«</a> -
|
||||
<a href="/?page={{PAGINATION_NEXT}}">»</a> |
|
||||
<br>
|
||||
{{#PAGINATION_NUMBERS}}
|
||||
<a href="/?page={{.}}">{{.}}</a>
|
||||
{{/PAGINATION_NUMBERS}}
|
||||
</div>
|
||||
<br>
|
||||
{{/PAGINATION}}
|
Reference in New Issue
Block a user