This commit is contained in:
parent
85b93fbbe3
commit
059d6d3879
@ -1,14 +1,23 @@
|
|||||||
|
find_package(Wt REQUIRED Dbo)
|
||||||
|
|
||||||
add_library(Database
|
add_library(Database
|
||||||
Database.h Database.cpp
|
Database.h Database.cpp
|
||||||
Task.h Task.cpp
|
Session.h Session.cpp
|
||||||
HomeBox.h HomeBox.cpp
|
Task.h
|
||||||
|
User.h
|
||||||
|
HomeBox.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
get_filename_component(PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
|
||||||
|
|
||||||
target_include_directories(Database
|
target_include_directories(Database
|
||||||
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
|
INTERFACE ${PARENT_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(Database
|
target_link_libraries(Database
|
||||||
PUBLIC sqlite3
|
PUBLIC sqlite3
|
||||||
PUBLIC Universal
|
PUBLIC Universal
|
||||||
|
PUBLIC Wt::Wt
|
||||||
|
PUBLIC Wt::Dbo
|
||||||
|
PRIVATE Wt::DboSqlite3
|
||||||
)
|
)
|
@ -1,9 +1,29 @@
|
|||||||
#include "Database.h"
|
#include "Database.h"
|
||||||
#include "BoostLog.h"
|
#include "BoostLog.h"
|
||||||
|
#include "Session.h"
|
||||||
|
#include <Wt/Dbo/FixedSqlConnectionPool.h>
|
||||||
|
#include <Wt/Dbo/SqlConnectionPool.h>
|
||||||
|
#include <Wt/Dbo/backend/Sqlite3.h>
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
std::unique_ptr<Session> Database::session() {
|
||||||
|
if (!m_sqlConnectionPool) return {};
|
||||||
|
return std::make_unique<Session>(*m_sqlConnectionPool);
|
||||||
|
}
|
||||||
|
|
||||||
bool Database::open(const std::string &path) {
|
bool Database::open(const std::string &path) {
|
||||||
|
try {
|
||||||
|
auto connection = std::make_unique<Wt::Dbo::backend::Sqlite3>(path);
|
||||||
|
connection->setProperty("show-queries", "true");
|
||||||
|
connection->setDateTimeStorage(Wt::Dbo::SqlDateTimeType::DateTime,
|
||||||
|
Wt::Dbo::backend::DateTimeStorage::PseudoISO8601AsText);
|
||||||
|
m_sqlConnectionPool = std::make_unique<Wt::Dbo::FixedSqlConnectionPool>(std::move(connection), 10);
|
||||||
|
session()->createTables();
|
||||||
|
} catch (const Wt::Dbo::Exception &e) {
|
||||||
|
LOG(error) << e.code() << ": " << e.what();
|
||||||
|
}
|
||||||
|
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
int result = sqlite3_open(path.c_str(), &m_sqlite3);
|
int result = sqlite3_open(path.c_str(), &m_sqlite3);
|
||||||
if (result != SQLITE_OK) {
|
if (result != SQLITE_OK) {
|
||||||
@ -14,97 +34,6 @@ bool Database::open(const std::string &path) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int selectTaskCallback(void *data, int argc, char **argv, char **columnName) {
|
|
||||||
auto tasks = reinterpret_cast<Tasks *>(data);
|
|
||||||
Task task;
|
|
||||||
for (int i = 0; i < argc; i++) {
|
|
||||||
if (argv[i] == nullptr) continue;
|
|
||||||
if (strcmp(columnName[i], "id") == 0) {
|
|
||||||
task.id = std::atol(argv[i]);
|
|
||||||
} else if (strcmp(columnName[i], "create_time") == 0) {
|
|
||||||
task.createTime = std::atol(argv[i]);
|
|
||||||
} else if (strcmp(columnName[i], "content") == 0) {
|
|
||||||
task.content = argv[i];
|
|
||||||
} else if (strcmp(columnName[i], "comment") == 0) {
|
|
||||||
task.comment = argv[i];
|
|
||||||
} else if (strcmp(columnName[i], "finished") == 0) {
|
|
||||||
task.finished = std::atol(argv[i]);
|
|
||||||
} else if (strcmp(columnName[i], "parent_id") == 0) {
|
|
||||||
task.parentId = std::atol(argv[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tasks->push_back(task);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tasks Database::tasks() {
|
|
||||||
Tasks ret;
|
|
||||||
char *error = nullptr;
|
|
||||||
if (sqlite3_exec(m_sqlite3, "select * from tasks", selectTaskCallback, &ret, &error) != SQLITE_OK) {
|
|
||||||
LOG(error) << "sqlite3_exec() failed: " << error << std::endl;
|
|
||||||
sqlite3_free(error);
|
|
||||||
}
|
|
||||||
std::unordered_map<int, Task *> tasks;
|
|
||||||
for (auto iterator = ret.begin(); iterator != ret.end();) {
|
|
||||||
if (iterator->parentId >= 0) {
|
|
||||||
if (tasks.count(iterator->parentId) > 0) {
|
|
||||||
auto parentTask = tasks.at(iterator->parentId);
|
|
||||||
parentTask->children.push_back(*iterator);
|
|
||||||
tasks.insert({iterator->id, &parentTask->children.back()});
|
|
||||||
} else {
|
|
||||||
LOG(warning) << "task`s parent id " << iterator->parentId << " not existed.";
|
|
||||||
}
|
|
||||||
iterator = ret.erase(iterator);
|
|
||||||
} else {
|
|
||||||
tasks.insert({iterator->id, &(*iterator)});
|
|
||||||
++iterator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Database::addTask(uint64_t createTime, const std::string &content, const std::string &comment, int parentId,
|
|
||||||
bool finished) {
|
|
||||||
bool ret = true;
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "INSERT INTO tasks (create_time,content,comment,parent_id,finished) VALUES (" << createTime << ",\""
|
|
||||||
<< content << "\",\"" << comment << "\"," << parentId << "," << finished << ");";
|
|
||||||
auto sql = oss.str();
|
|
||||||
char *error = nullptr;
|
|
||||||
int result = sqlite3_exec(m_sqlite3, sql.c_str(), NULL, NULL, &error);
|
|
||||||
if (result != SQLITE_OK) {
|
|
||||||
LOG(error) << "add task failed: " << error << ", sql: " << sql;
|
|
||||||
sqlite3_free(error);
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Database::removeTask(int id) {
|
|
||||||
bool ret = true;
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "DELETE FROM tasks WHERE id = " << id << ";";
|
|
||||||
auto sql = oss.str();
|
|
||||||
char *error = nullptr;
|
|
||||||
int result = sqlite3_exec(m_sqlite3, sql.c_str(), NULL, NULL, &error);
|
|
||||||
if (result != SQLITE_OK) {
|
|
||||||
LOG(error) << "add task failed: " << error << ", sql: " << sql;
|
|
||||||
sqlite3_free(error);
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Database::setTaskFinished(int id, bool finished, uint64_t finishedTime) {
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "UPDATE tasks SET finished = " << finished << ", finished_time = " << finishedTime << " WHERE id = " << id;
|
|
||||||
auto sql = oss.str();
|
|
||||||
int result = sqlite3_exec(m_sqlite3, sql.c_str(), NULL, NULL, NULL);
|
|
||||||
if (result != SQLITE_OK) {
|
|
||||||
LOG(error) << "add task failed: " << sqlite3_errmsg(m_sqlite3) << ", sql: " << sql;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Database::updateVisitCount(const std::string &url, const std::string &visitorUuid, const std::string &userAgent,
|
void Database::updateVisitCount(const std::string &url, const std::string &visitorUuid, const std::string &userAgent,
|
||||||
int64_t time) {
|
int64_t time) {
|
||||||
@ -278,72 +207,9 @@ VisitAnalysis Database::visitAnalysisData(const std::string &url) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::addHomeBoxItem(const std::string &name, const std::string &location, int cost) {
|
|
||||||
bool ret = true;
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "INSERT INTO homebox (name,location,cost) VALUES (\"" << name << "\",\"" << location << "\"," << cost
|
|
||||||
<< ");";
|
|
||||||
auto sql = oss.str();
|
|
||||||
char *error = nullptr;
|
|
||||||
int result = sqlite3_exec(m_sqlite3, sql.c_str(), NULL, NULL, &error);
|
|
||||||
if (result != SQLITE_OK) {
|
|
||||||
LOG(error) << "add task failed: " << error << ", sql: " << sql;
|
|
||||||
sqlite3_free(error);
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int selectHomeBoxItemCallback(void *data, int argc, char **argv, char **columnName) {
|
|
||||||
auto items = reinterpret_cast<HomeBox::Items *>(data);
|
|
||||||
HomeBox::Item item;
|
|
||||||
for (int i = 0; i < argc; i++) {
|
|
||||||
if (argv[i] == nullptr) continue;
|
|
||||||
if (strcmp(columnName[i], "id") == 0) {
|
|
||||||
item.id = std::atol(argv[i]);
|
|
||||||
} else if (strcmp(columnName[i], "name") == 0) {
|
|
||||||
item.name = argv[i];
|
|
||||||
} else if (strcmp(columnName[i], "location") == 0) {
|
|
||||||
item.location = argv[i];
|
|
||||||
} else if (strcmp(columnName[i], "cost") == 0) {
|
|
||||||
item.cost = std::atol(argv[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
items->push_back(item);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
HomeBox::Items Database::homeBoxItems() {
|
|
||||||
HomeBox::Items ret;
|
|
||||||
char *error = nullptr;
|
|
||||||
if (sqlite3_exec(m_sqlite3, "select * from homebox", selectHomeBoxItemCallback, &ret, &error) != SQLITE_OK) {
|
|
||||||
LOG(error) << "sqlite3_exec() failed: " << error << std::endl;
|
|
||||||
sqlite3_free(error);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Database::initialize() {
|
void Database::initialize() {
|
||||||
const char *sql =
|
|
||||||
"CREATE TABLE IF NOT EXISTS tasks (id INTEGER PRIMARY KEY AUTOINCREMENT, create_time INTEGER NOT NULL, "
|
|
||||||
"parent_id INTEGER, content VARCHAR(512) NOT NULL, comment VARCHAR(512) NOT NULL, finished BOLL, finished_time "
|
|
||||||
"INTEGER);";
|
|
||||||
int result = sqlite3_exec(m_sqlite3, sql, NULL, NULL, NULL);
|
|
||||||
if (result != SQLITE_OK) {
|
|
||||||
LOG(error) << "Failed to create table: " << sqlite3_errmsg(m_sqlite3);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *homeBoxSql = "CREATE TABLE IF NOT EXISTS homebox (id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
|
||||||
"name VARCHAR(512) NOT NULL, location VARCHAR(512) NOT NULL, cost INTEGER);";
|
|
||||||
result = sqlite3_exec(m_sqlite3, homeBoxSql, NULL, NULL, NULL);
|
|
||||||
if (result != SQLITE_OK) {
|
|
||||||
LOG(error) << "Failed to create table: " << sqlite3_errmsg(m_sqlite3);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *message = nullptr;
|
char *message = nullptr;
|
||||||
sql = R"(
|
auto sql = R"(
|
||||||
CREATE TABLE IF NOT EXISTS visit_analysis (
|
CREATE TABLE IF NOT EXISTS visit_analysis (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
url TEXT NOT NULL,
|
url TEXT NOT NULL,
|
||||||
@ -353,7 +219,7 @@ void Database::initialize() {
|
|||||||
page_view_count INTEGER NOT NULL
|
page_view_count INTEGER NOT NULL
|
||||||
);
|
);
|
||||||
)";
|
)";
|
||||||
result = sqlite3_exec(m_sqlite3, sql, 0, 0, &message);
|
int result = sqlite3_exec(m_sqlite3, sql, 0, 0, &message);
|
||||||
if (result != SQLITE_OK) {
|
if (result != SQLITE_OK) {
|
||||||
LOG(error) << "Failed to create table: " << message << std::endl;
|
LOG(error) << "Failed to create table: " << message << std::endl;
|
||||||
sqlite3_free(message);
|
sqlite3_free(message);
|
||||||
|
@ -6,6 +6,12 @@
|
|||||||
#include "Task.h"
|
#include "Task.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
namespace Wt {
|
||||||
|
namespace Dbo {
|
||||||
|
class SqlConnectionPool;
|
||||||
|
}
|
||||||
|
} // namespace Wt
|
||||||
|
|
||||||
class VisitAnalysis {
|
class VisitAnalysis {
|
||||||
public:
|
public:
|
||||||
std::string url;
|
std::string url;
|
||||||
@ -15,34 +21,28 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct sqlite3;
|
struct sqlite3;
|
||||||
|
class Session;
|
||||||
|
|
||||||
class Database {
|
class Database {
|
||||||
friend class Amass::Singleton<Database>;
|
friend class Amass::Singleton<Database>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~Database();
|
~Database();
|
||||||
|
std::unique_ptr<Session> session();
|
||||||
bool open(const std::string &path);
|
bool open(const std::string &path);
|
||||||
Tasks tasks();
|
|
||||||
bool addTask(uint64_t createTime, const std::string &content, const std::string &comment = "", int parentId = -1,
|
|
||||||
bool finished = false);
|
|
||||||
bool removeTask(int id);
|
|
||||||
void setTaskFinished(int id, bool finished, uint64_t finishedTime);
|
|
||||||
|
|
||||||
void updateVisitCount(const std::string &url, const std::string &visitorUuid, const std::string &userAgent,
|
void updateVisitCount(const std::string &url, const std::string &visitorUuid, const std::string &userAgent, int64_t time);
|
||||||
int64_t time);
|
|
||||||
void clearVisitRecord();
|
void clearVisitRecord();
|
||||||
VisitAnalysis visitAnalysisData(const std::string &url);
|
VisitAnalysis visitAnalysisData(const std::string &url);
|
||||||
VisitAnalysis siteVisitAnalysisData();
|
VisitAnalysis siteVisitAnalysisData();
|
||||||
std::list<VisitAnalysis> mostViewedUrls(int size);
|
std::list<VisitAnalysis> mostViewedUrls(int size);
|
||||||
std::list<VisitAnalysis> latestViewedUrls(int size);
|
std::list<VisitAnalysis> latestViewedUrls(int size);
|
||||||
|
|
||||||
HomeBox::Items homeBoxItems();
|
|
||||||
bool addHomeBoxItem(const std::string &name, const std::string &location, int cost);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::unique_ptr<Wt::Dbo::SqlConnectionPool> m_sqlConnectionPool;
|
||||||
sqlite3 *m_sqlite3 = nullptr;
|
sqlite3 *m_sqlite3 = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
#include "HomeBox.h"
|
|
@ -1,20 +1,23 @@
|
|||||||
#ifndef __HOMEBOX_H__
|
#ifndef __HOMEBOX_H__
|
||||||
#define __HOMEBOX_H__
|
#define __HOMEBOX_H__
|
||||||
|
|
||||||
#include <list>
|
#include <Wt/Dbo/Dbo.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class HomeBox {
|
namespace HomeBox {
|
||||||
public:
|
|
||||||
class Item {
|
class Item {
|
||||||
public:
|
public:
|
||||||
int id = -1;
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string location;
|
std::string location;
|
||||||
int cost;
|
int cost;
|
||||||
};
|
|
||||||
|
|
||||||
using Items = std::list<Item>;
|
template <class Action>
|
||||||
|
void persist(Action &a) {
|
||||||
|
Wt::Dbo::field(a, name, "name");
|
||||||
|
Wt::Dbo::field(a, location, "location");
|
||||||
|
Wt::Dbo::field(a, cost, "cost");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
} // namespace HomeBox
|
||||||
|
|
||||||
#endif // __HOMEBOX_H__
|
#endif // __HOMEBOX_H__
|
@ -1,30 +1,17 @@
|
|||||||
#include "Session.h"
|
#include "Session.h"
|
||||||
#include "BoostLog.h"
|
|
||||||
#include <Wt/Auth/Dbo/AuthInfo.h>
|
|
||||||
#include <Wt/Auth/Dbo/UserDatabase.h>
|
#include <Wt/Auth/Dbo/UserDatabase.h>
|
||||||
#include <Wt/Auth/FacebookService.h>
|
|
||||||
#include <Wt/Auth/GoogleService.h>
|
|
||||||
#include <Wt/Auth/HashFunction.h>
|
|
||||||
#include <Wt/Auth/PasswordService.h>
|
|
||||||
#include <Wt/Auth/PasswordStrengthValidator.h>
|
|
||||||
#include <Wt/Auth/PasswordVerifier.h>
|
|
||||||
#include <Wt/Dbo/backend/Sqlite3.h>
|
|
||||||
|
|
||||||
Session::Session(Wt::Dbo::SqlConnectionPool &connectionPool) : m_connectionPool(connectionPool) {
|
Session::Session(Wt::Dbo::SqlConnectionPool &connectionPool) {
|
||||||
setConnectionPool(m_connectionPool);
|
setConnectionPool(connectionPool);
|
||||||
|
|
||||||
|
mapClass<Task>("task");
|
||||||
|
mapClass<HomeBox::Item>("homebox_item");
|
||||||
|
|
||||||
mapClass<User>("user");
|
mapClass<User>("user");
|
||||||
mapClass<AuthInfo>("auth_info");
|
mapClass<AuthInfo>("auth_info");
|
||||||
mapClass<AuthInfo::AuthIdentityType>("auth_identity");
|
mapClass<AuthInfo::AuthIdentityType>("auth_identity");
|
||||||
mapClass<AuthInfo::AuthTokenType>("auth_token");
|
mapClass<AuthInfo::AuthTokenType>("auth_token");
|
||||||
|
|
||||||
try {
|
|
||||||
createTables();
|
|
||||||
LOG(info) << "Created database.";
|
|
||||||
} catch (Wt::Dbo::Exception &e) {
|
|
||||||
LOG(error) << e.what() << ", using existing database";
|
|
||||||
}
|
|
||||||
|
|
||||||
m_users = std::make_unique<UserDatabase>(*this);
|
m_users = std::make_unique<UserDatabase>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,3 +33,7 @@ Wt::Auth::AbstractUserDatabase &Session::users() {
|
|||||||
Wt::Auth::Login &Session::login() {
|
Wt::Auth::Login &Session::login() {
|
||||||
return m_login;
|
return m_login;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DBO_INSTANTIATE_TEMPLATES(User)
|
||||||
|
DBO_INSTANTIATE_TEMPLATES(Task)
|
||||||
|
DBO_INSTANTIATE_TEMPLATES(HomeBox::Item)
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef __SESSION_H__
|
#ifndef __SESSION_H__
|
||||||
#define __SESSION_H__
|
#define __SESSION_H__
|
||||||
|
|
||||||
|
#include "HomeBox.h"
|
||||||
|
#include "Task.h"
|
||||||
#include "User.h"
|
#include "User.h"
|
||||||
#include <Wt/Auth/Login.h>
|
#include <Wt/Auth/Login.h>
|
||||||
#include <Wt/Dbo/Session.h>
|
#include <Wt/Dbo/Session.h>
|
||||||
@ -16,7 +18,6 @@ public:
|
|||||||
Wt::Auth::Login &login();
|
Wt::Auth::Login &login();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Wt::Dbo::SqlConnectionPool &m_connectionPool;
|
|
||||||
std::unique_ptr<UserDatabase> m_users;
|
std::unique_ptr<UserDatabase> m_users;
|
||||||
Wt::Auth::Login m_login;
|
Wt::Auth::Login m_login;
|
||||||
};
|
};
|
@ -1,34 +0,0 @@
|
|||||||
#include "Task.h"
|
|
||||||
#include <boost/json/array.hpp>
|
|
||||||
#include <boost/json/object.hpp>
|
|
||||||
#include <boost/json/serialize.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace json {
|
|
||||||
|
|
||||||
static boost::json::object serialize(const Task &task) {
|
|
||||||
boost::json::object ret;
|
|
||||||
ret["id"] = task.id;
|
|
||||||
ret["parentId"] = task.parentId;
|
|
||||||
ret["finished"] = task.finished;
|
|
||||||
ret["createTime"] = task.createTime;
|
|
||||||
ret["content"] = task.content;
|
|
||||||
ret["comment"] = task.comment;
|
|
||||||
|
|
||||||
boost::json::array children;
|
|
||||||
for (auto &child : task.children) {
|
|
||||||
children.push_back(serialize(child));
|
|
||||||
}
|
|
||||||
ret["children"] = std::move(children);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string serialize(const Tasks &tasks) {
|
|
||||||
boost::json::array ret;
|
|
||||||
for (auto &task : tasks) {
|
|
||||||
ret.push_back(serialize(task));
|
|
||||||
}
|
|
||||||
return boost::json::serialize(ret);
|
|
||||||
}
|
|
||||||
} // namespace json
|
|
||||||
} // namespace boost
|
|
@ -1,31 +1,33 @@
|
|||||||
#ifndef __TASK_H__
|
#ifndef __TASK_H__
|
||||||
#define __TASK_H__
|
#define __TASK_H__
|
||||||
|
|
||||||
#include <list>
|
#include <Wt/Dbo/Dbo.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class Task;
|
class Task;
|
||||||
using Tasks = std::list<Task>;
|
using Tasks = Wt::Dbo::collection<Wt::Dbo::ptr<Task>>;
|
||||||
|
|
||||||
class Task {
|
class Task {
|
||||||
public:
|
public:
|
||||||
int id = -1;
|
|
||||||
int parentId = -1;
|
|
||||||
bool finished = false;
|
bool finished = false;
|
||||||
int32_t createTime = 0;
|
int32_t createTime = 0;
|
||||||
std::string content;
|
std::string content;
|
||||||
std::string comment;
|
std::string comment;
|
||||||
|
|
||||||
|
Wt::Dbo::ptr<Task> parent;
|
||||||
Tasks children;
|
Tasks children;
|
||||||
|
|
||||||
template <class Action>
|
template <class Action>
|
||||||
void persist(Action &a) {
|
void persist(Action &a) {
|
||||||
|
Wt::Dbo::field(a, content, "content");
|
||||||
|
Wt::Dbo::field(a, comment, "comment");
|
||||||
|
Wt::Dbo::field(a, finished, "finished");
|
||||||
|
Wt::Dbo::field(a, createTime, "create_time");
|
||||||
|
|
||||||
|
Wt::Dbo::belongsTo(a, parent, "parent");
|
||||||
|
Wt::Dbo::hasMany(a, children, Wt::Dbo::ManyToOne, "parent");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace json {
|
|
||||||
std::string serialize(const Tasks &tasks);
|
|
||||||
}
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // __TASK_H__
|
#endif // __TASK_H__
|
@ -1,5 +1,6 @@
|
|||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "Database.h"
|
#include "Database/Database.h"
|
||||||
|
#include "Database/Session.h"
|
||||||
#include "DateTime.h"
|
#include "DateTime.h"
|
||||||
#include "HttpSession.h"
|
#include "HttpSession.h"
|
||||||
#include "IoContext.h"
|
#include "IoContext.h"
|
||||||
@ -8,6 +9,7 @@
|
|||||||
#include "ServiceManager.h"
|
#include "ServiceManager.h"
|
||||||
#include "SystemUsage.h"
|
#include "SystemUsage.h"
|
||||||
#include "WeChatContext/CorporationContext.h"
|
#include "WeChatContext/CorporationContext.h"
|
||||||
|
#include <Wt/Dbo/Json.h>
|
||||||
#include <boost/json/object.hpp>
|
#include <boost/json/object.hpp>
|
||||||
#include <boost/json/serialize.hpp>
|
#include <boost/json/serialize.hpp>
|
||||||
#include <boost/stacktrace.hpp>
|
#include <boost/stacktrace.hpp>
|
||||||
@ -60,22 +62,23 @@ Application::Application(const std::string &path)
|
|||||||
|
|
||||||
m_router->insert("/api/v1/tasklist", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
|
m_router->insert("/api/v1/tasklist", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
|
||||||
using namespace boost::beast;
|
using namespace boost::beast;
|
||||||
auto database = Amass::Singleton<Database>::instance();
|
auto database = Amass::Singleton<Database>::instance()->session();
|
||||||
auto tasks = database->tasks();
|
Tasks tasks = database->find<Task>();
|
||||||
|
std::ostringstream oss;
|
||||||
|
Wt::Dbo::jsonSerialize(tasks, oss);
|
||||||
|
|
||||||
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
|
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
|
||||||
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
|
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
|
||||||
s.set(http::field::content_type, "application/json;charset=UTF-8");
|
s.set(http::field::content_type, "application/json;charset=UTF-8");
|
||||||
s.keep_alive(request.keep_alive());
|
s.keep_alive(request.keep_alive());
|
||||||
s.body() = boost::json::serialize(tasks);
|
s.body() = oss.str();
|
||||||
s.prepare_payload();
|
s.prepare_payload();
|
||||||
session.reply(std::move(s));
|
session.reply(std::move(s));
|
||||||
});
|
});
|
||||||
|
|
||||||
m_router->insert("/api/v1/task/add", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
|
m_router->insert("/api/v1/task/add", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) mutable {
|
||||||
using namespace boost::beast;
|
using namespace boost::beast;
|
||||||
LOG(info) << "add task: " << request.body();
|
LOG(info) << "add task: " << request.body();
|
||||||
auto database = Amass::Singleton<Database>::instance();
|
|
||||||
auto rootJson = boost::json::parse(request.body());
|
auto rootJson = boost::json::parse(request.body());
|
||||||
auto &root = rootJson.as_object();
|
auto &root = rootJson.as_object();
|
||||||
|
|
||||||
@ -83,10 +86,18 @@ Application::Application(const std::string &path)
|
|||||||
if (root.contains("content")) {
|
if (root.contains("content")) {
|
||||||
content = root.at("content").as_string();
|
content = root.at("content").as_string();
|
||||||
}
|
}
|
||||||
bool ret = database->addTask(root.at("createTime").as_int64(), content,
|
auto database = Amass::Singleton<Database>::instance()->session();
|
||||||
std::string(root.at("comment").as_string()), root.at("parentId").as_int64());
|
auto task = std::make_unique<Task>();
|
||||||
|
task->createTime = root.at("createTime").as_int64();
|
||||||
|
task->content = content;
|
||||||
|
task->comment = std::string(root.at("comment").as_string());
|
||||||
|
auto t = database->add(std::move(task));
|
||||||
|
Wt::Dbo::ptr<Task> parent = database->find<Task>("where id=?").bind(root.at("parentId").as_int64());
|
||||||
|
if (parent) {
|
||||||
|
parent.modify()->children.insert(t);
|
||||||
|
}
|
||||||
boost::json::object reply;
|
boost::json::object reply;
|
||||||
reply["status"] = ret ? 0 : -1;
|
reply["status"] = 0;
|
||||||
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
|
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
|
||||||
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
|
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
|
||||||
s.set(http::field::content_type, "application/json;charset=UTF-8");
|
s.set(http::field::content_type, "application/json;charset=UTF-8");
|
||||||
@ -99,11 +110,15 @@ Application::Application(const std::string &path)
|
|||||||
m_router->insert("/api/v1/task/delete/{id}", [this](HttpSession &session, const Request &request,const boost::urls::matches &matches) {
|
m_router->insert("/api/v1/task/delete/{id}", [this](HttpSession &session, const Request &request,const boost::urls::matches &matches) {
|
||||||
using namespace boost::beast;
|
using namespace boost::beast;
|
||||||
LOG(info) << "delete task: " << matches.at("id");
|
LOG(info) << "delete task: " << matches.at("id");
|
||||||
auto database = Amass::Singleton<Database>::instance();
|
auto database = Amass::Singleton<Database>::instance()->session();
|
||||||
auto status = database->removeTask(std::stoi(matches.at("id")));
|
Wt::Dbo::ptr<Task> joe = database->find<Task>().where("id = ?").bind(std::stoi(matches.at("id")));
|
||||||
|
int status = -1;
|
||||||
|
if (joe) {
|
||||||
|
joe.remove();
|
||||||
|
status = 0;
|
||||||
|
}
|
||||||
boost::json::object reply;
|
boost::json::object reply;
|
||||||
reply["status"] = status ? 0 : -1;
|
reply["status"] = status;
|
||||||
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
|
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
|
||||||
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
|
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
|
||||||
s.set(http::field::content_type, "application/json;charset=UTF-8");
|
s.set(http::field::content_type, "application/json;charset=UTF-8");
|
||||||
@ -125,8 +140,7 @@ Application::Application(const std::string &path)
|
|||||||
ServiceLogic::make_200<boost::beast::http::string_body>(request, "notify successed.\n", "text/html"));
|
ServiceLogic::make_200<boost::beast::http::string_body>(request, "notify successed.\n", "text/html"));
|
||||||
});
|
});
|
||||||
// clang-format on
|
// clang-format on
|
||||||
m_router->insert("/api/v1/visit_analysis", [this](HttpSession &session, const Request &request,
|
m_router->insert("/api/v1/visit_analysis", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
|
||||||
const boost::urls::matches &matches) {
|
|
||||||
using namespace boost::beast;
|
using namespace boost::beast;
|
||||||
auto rootJson = boost::json::parse(request.body());
|
auto rootJson = boost::json::parse(request.body());
|
||||||
auto &root = rootJson.as_object();
|
auto &root = rootJson.as_object();
|
||||||
@ -166,8 +180,7 @@ Application::Application(const std::string &path)
|
|||||||
session.reply(std::move(s));
|
session.reply(std::move(s));
|
||||||
});
|
});
|
||||||
|
|
||||||
m_router->insert("/api/v1/most_viewed_urls", [this](HttpSession &session, const Request &request,
|
m_router->insert("/api/v1/most_viewed_urls", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
|
||||||
const boost::urls::matches &matches) {
|
|
||||||
using namespace boost::beast;
|
using namespace boost::beast;
|
||||||
int size = 5;
|
int size = 5;
|
||||||
std::error_code error;
|
std::error_code error;
|
||||||
@ -200,8 +213,7 @@ Application::Application(const std::string &path)
|
|||||||
session.reply(std::move(s));
|
session.reply(std::move(s));
|
||||||
});
|
});
|
||||||
|
|
||||||
m_router->insert("/api/v1/latest_viewed_urls", [this](HttpSession &session, const Request &request,
|
m_router->insert("/api/v1/latest_viewed_urls", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
|
||||||
const boost::urls::matches &matches) {
|
|
||||||
using namespace boost::beast;
|
using namespace boost::beast;
|
||||||
int size = 5;
|
int size = 5;
|
||||||
std::error_code error;
|
std::error_code error;
|
||||||
@ -290,21 +302,21 @@ void Application::alarmTask() {
|
|||||||
LOG(error) << error.message();
|
LOG(error) << error.message();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto database = Amass::Singleton<Database>::instance();
|
auto session = Amass::Singleton<Database>::instance()->session();
|
||||||
auto tasks = database->tasks();
|
Tasks tasks = session->find<Task>();
|
||||||
bool founded = false;
|
bool founded = false;
|
||||||
std::string content;
|
std::string content;
|
||||||
for (auto &task : tasks) {
|
for (auto &task : tasks) {
|
||||||
if (founded) break;
|
if (founded) break;
|
||||||
for (auto &child : task.children) {
|
for (auto child : task->children) {
|
||||||
if (!child.finished) {
|
if (!child->finished) {
|
||||||
content = child.content;
|
content = child->content;
|
||||||
founded = true;
|
founded = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!founded && !task.finished) {
|
if (!founded && !task->finished) {
|
||||||
content = task.content;
|
content = task->content;
|
||||||
founded = true;
|
founded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "BoostLog.h"
|
#include "BoostLog.h"
|
||||||
#include "Database.h"
|
#include "Database/Database.h"
|
||||||
#include "IoContext.h"
|
#include "IoContext.h"
|
||||||
#include "Listener.h"
|
#include "Listener.h"
|
||||||
#include "Live2dBackend.h"
|
#include "Live2dBackend.h"
|
||||||
@ -11,6 +11,7 @@
|
|||||||
#include "WeChatContext/CorporationContext.h"
|
#include "WeChatContext/CorporationContext.h"
|
||||||
#include "WeChatContext/WeChatContext.h"
|
#include "WeChatContext/WeChatContext.h"
|
||||||
#include "WebApplication.h"
|
#include "WebApplication.h"
|
||||||
|
#include <Wt/Dbo/SqlConnectionPool.h>
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include <boost/property_tree/ini_parser.hpp>
|
#include <boost/property_tree/ini_parser.hpp>
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "Database.h"
|
#include "Database/Database.h"
|
||||||
#include "BoostLog.h"
|
#include "BoostLog.h"
|
||||||
|
#include "Database/Session.h"
|
||||||
|
#include <Wt/Dbo/SqlConnectionPool.h>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
@ -11,19 +13,66 @@ BOOST_AUTO_TEST_CASE(DatabaseTest) {
|
|||||||
std::filesystem::remove(path);
|
std::filesystem::remove(path);
|
||||||
}
|
}
|
||||||
Database database;
|
Database database;
|
||||||
BOOST_TEST(database.open(path));
|
database.open(path);
|
||||||
|
// BOOST_TEST(database.open(path));
|
||||||
|
|
||||||
database.addTask(1234, "Hello");
|
auto session = database.session();
|
||||||
|
|
||||||
database.addTask(1234, "这是一个测试", "", true);
|
Wt::Dbo ::Transaction transaction(*session);
|
||||||
|
|
||||||
database.addHomeBoxItem("手机", "抽屉", 1499);
|
auto task = std::make_unique<Task>();
|
||||||
auto items = database.homeBoxItems();
|
task->comment = "my_comment";
|
||||||
BOOST_CHECK_EQUAL(items.size(), 1);
|
task->content = "my_content";
|
||||||
|
|
||||||
|
auto p = session->add(std::move(task));
|
||||||
|
|
||||||
|
{
|
||||||
|
task = std::make_unique<Task>();
|
||||||
|
task->comment = "my_comment1";
|
||||||
|
task->content = "my_content1";
|
||||||
|
auto c = session->add(std::move(task));
|
||||||
|
p.modify()->children.insert(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
task = std::make_unique<Task>();
|
||||||
|
task->comment = "my_comment2";
|
||||||
|
task->content = "my_content2";
|
||||||
|
auto c = session->add(std::move(task));
|
||||||
|
p.modify()->children.insert(c);
|
||||||
|
|
||||||
|
{
|
||||||
|
task = std::make_unique<Task>();
|
||||||
|
task->comment = "my_comment3";
|
||||||
|
task->content = "my_content3";
|
||||||
|
auto d = session->add(std::move(task));
|
||||||
|
c.modify()->children.insert(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
task = std::make_unique<Task>();
|
||||||
|
task->comment = "my_comment4";
|
||||||
|
task->content = "my_content4";
|
||||||
|
auto d = session->add(std::move(task));
|
||||||
|
c.modify()->children.insert(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Wt::Dbo::ptr<Task> tt = session->find<Task>("where id = 3");
|
||||||
|
LOG(info) << tt->parent->content;
|
||||||
|
LOG(info) << tt->children.size();
|
||||||
|
|
||||||
|
{
|
||||||
|
auto item = std::make_unique<HomeBox::Item>();
|
||||||
|
item->cost = 1499;
|
||||||
|
item->location = "抽屉";
|
||||||
|
item->name = "手机";
|
||||||
|
|
||||||
|
auto d = session->add(std::move(item));
|
||||||
|
}
|
||||||
|
|
||||||
auto now = std::chrono::system_clock::now();
|
auto now = std::chrono::system_clock::now();
|
||||||
std::time_t now_time = std::chrono::system_clock::to_time_t(now);
|
std::time_t now_time = std::chrono::system_clock::to_time_t(now);
|
||||||
database.setTaskFinished(1, true, now_time);
|
|
||||||
|
|
||||||
database.updateVisitCount("/note", "uuid_123", "chrome", now_time);
|
database.updateVisitCount("/note", "uuid_123", "chrome", now_time);
|
||||||
database.updateVisitCount("/note/1", "uuid_1232", "chrome", now_time);
|
database.updateVisitCount("/note/1", "uuid_1232", "chrome", now_time);
|
||||||
|
@ -3,11 +3,9 @@ find_package(Wt REQUIRED Wt)
|
|||||||
add_library(WebApplication
|
add_library(WebApplication
|
||||||
WebApplication.h WebApplication.cpp
|
WebApplication.h WebApplication.cpp
|
||||||
LoginWidget.h LoginWidget.cpp
|
LoginWidget.h LoginWidget.cpp
|
||||||
User.h User.cpp
|
|
||||||
Hello.h Hello.cpp
|
Hello.h Hello.cpp
|
||||||
Restful.h Restful.cpp
|
Restful.h Restful.cpp
|
||||||
Dialog.h Dialog.cpp
|
Dialog.h Dialog.cpp
|
||||||
Session.h Session.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(WebApplication
|
target_include_directories(WebApplication
|
||||||
@ -16,8 +14,6 @@ target_include_directories(WebApplication
|
|||||||
|
|
||||||
target_link_libraries(WebApplication
|
target_link_libraries(WebApplication
|
||||||
PUBLIC Universal
|
PUBLIC Universal
|
||||||
PRIVATE Wt::Wt
|
|
||||||
PRIVATE Wt::Dbo
|
|
||||||
PRIVATE Wt::HTTP
|
PRIVATE Wt::HTTP
|
||||||
PRIVATE Wt::DboSqlite3
|
PRIVATE Database
|
||||||
)
|
)
|
@ -1,8 +1,9 @@
|
|||||||
#include "Hello.h"
|
#include "Hello.h"
|
||||||
#include "BoostLog.h"
|
#include "BoostLog.h"
|
||||||
|
#include "Database/Database.h"
|
||||||
|
#include "Database/Session.h"
|
||||||
#include "Dialog.h"
|
#include "Dialog.h"
|
||||||
#include "LoginWidget.h"
|
#include "LoginWidget.h"
|
||||||
#include "Session.h"
|
|
||||||
#include "WebApplication.h"
|
#include "WebApplication.h"
|
||||||
#include <Wt/Auth/Identity.h>
|
#include <Wt/Auth/Identity.h>
|
||||||
#include <Wt/WBootstrap2Theme.h>
|
#include <Wt/WBootstrap2Theme.h>
|
||||||
@ -12,14 +13,13 @@
|
|||||||
#include <Wt/WPushButton.h>
|
#include <Wt/WPushButton.h>
|
||||||
#include <Wt/WText.h>
|
#include <Wt/WText.h>
|
||||||
|
|
||||||
Hello::Hello(const Wt::WEnvironment &env, Wt::Dbo::SqlConnectionPool &connectionPool, bool embedded)
|
Hello::Hello(const Wt::WEnvironment &env, bool embedded) : Wt::WApplication(env) {
|
||||||
: Wt::WApplication(env) {
|
|
||||||
messageResourceBundle().use(appRoot() + "wt");
|
messageResourceBundle().use(appRoot() + "wt");
|
||||||
messageResourceBundle().use(appRoot() + "auth_strings");
|
messageResourceBundle().use(appRoot() + "auth_strings");
|
||||||
messageResourceBundle().use(appRoot() + "auth_css_theme");
|
messageResourceBundle().use(appRoot() + "auth_css_theme");
|
||||||
useStyleSheet("/resources/app.css");
|
useStyleSheet("/resources/app.css");
|
||||||
LOG(info) << "app root: " << appRoot();
|
LOG(info) << "app root: " << appRoot();
|
||||||
m_session = std::make_unique<Session>(connectionPool);
|
m_session = Amass::Singleton<Database>::instance()->session();
|
||||||
m_session->login().changed().connect(this, &Hello::authEvent);
|
m_session->login().changed().connect(this, &Hello::authEvent);
|
||||||
setTitle("Hello world");
|
setTitle("Hello world");
|
||||||
if (!embedded) {
|
if (!embedded) {
|
||||||
@ -35,7 +35,6 @@ Hello::Hello(const Wt::WEnvironment &env, Wt::Dbo::SqlConnectionPool &connection
|
|||||||
} else {
|
} else {
|
||||||
LOG(error) << "Missing: parameter: 'div'";
|
LOG(error) << "Missing: parameter: 'div'";
|
||||||
}
|
}
|
||||||
internalPathChanged().connect(this, &Hello::handlePathChange);
|
|
||||||
auto externalPath = env.getParameter("path");
|
auto externalPath = env.getParameter("path");
|
||||||
if (externalPath != nullptr) {
|
if (externalPath != nullptr) {
|
||||||
m_externalPath = *externalPath;
|
m_externalPath = *externalPath;
|
||||||
@ -55,6 +54,7 @@ Hello::Hello(const Wt::WEnvironment &env, Wt::Dbo::SqlConnectionPool &connection
|
|||||||
root()->addWidget(std::make_unique<Wt::WText>("<p><emph>Note: you can also run this application "
|
root()->addWidget(std::make_unique<Wt::WText>("<p><emph>Note: you can also run this application "
|
||||||
"from within <a href=\"hello.html\">a web page</a>.</emph></p>"));
|
"from within <a href=\"hello.html\">a web page</a>.</emph></p>"));
|
||||||
}
|
}
|
||||||
|
LOG(info) << "internal path: " << internalPath();
|
||||||
|
|
||||||
m_root->addWidget(std::make_unique<Wt::WText>("Your name, please ? "));
|
m_root->addWidget(std::make_unique<Wt::WText>("Your name, please ? "));
|
||||||
m_nameEdit = m_root->addWidget(std::make_unique<Wt::WLineEdit>());
|
m_nameEdit = m_root->addWidget(std::make_unique<Wt::WLineEdit>());
|
||||||
@ -73,10 +73,8 @@ Hello::Hello(const Wt::WEnvironment &env, Wt::Dbo::SqlConnectionPool &connection
|
|||||||
auto app = Amass::Singleton<WebApplication>::instance();
|
auto app = Amass::Singleton<WebApplication>::instance();
|
||||||
|
|
||||||
m_root->addWidget(std::make_unique<Dialog>());
|
m_root->addWidget(std::make_unique<Dialog>());
|
||||||
|
internalPathChanged().connect(this, &Hello::handlePathChange);
|
||||||
if (!m_externalPath.empty()) {
|
handlePathChange(m_externalPath.empty() ? internalPath() : m_externalPath);
|
||||||
handlePathChange(m_externalPath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Hello::~Hello() {
|
Hello::~Hello() {
|
||||||
|
@ -7,7 +7,7 @@ class Session;
|
|||||||
|
|
||||||
class Hello : public Wt::WApplication {
|
class Hello : public Wt::WApplication {
|
||||||
public:
|
public:
|
||||||
Hello(const Wt::WEnvironment &env, Wt::Dbo::SqlConnectionPool &connectionPool, bool embedded);
|
Hello(const Wt::WEnvironment &env, bool embedded);
|
||||||
~Hello();
|
~Hello();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "Restful.h"
|
#include "Restful.h"
|
||||||
#include "Session.h"
|
#include "Database/Database.h"
|
||||||
|
#include "Database/Session.h"
|
||||||
#include <Wt/Dbo/Impl.h>
|
#include <Wt/Dbo/Impl.h>
|
||||||
#include <Wt/Dbo/Json.h>
|
#include <Wt/Dbo/Json.h>
|
||||||
#include <Wt/Dbo/backend/Sqlite3.h>
|
#include <Wt/Dbo/backend/Sqlite3.h>
|
||||||
@ -10,7 +11,7 @@ DBO_INSTANTIATE_TEMPLATES(MyMessage)
|
|||||||
DbStruct *m_dbStruct;
|
DbStruct *m_dbStruct;
|
||||||
|
|
||||||
void AuthenticationResource::handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) {
|
void AuthenticationResource::handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) {
|
||||||
Session session(m_connectionPool);
|
auto session = Amass::Singleton<Database>::instance()->session();
|
||||||
response.setMimeType("application/json");
|
response.setMimeType("application/json");
|
||||||
response.addHeader("Server", "Wt");
|
response.addHeader("Server", "Wt");
|
||||||
|
|
||||||
@ -48,8 +49,7 @@ int DbStruct::rand() {
|
|||||||
return distribution(rng);
|
return distribution(rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationResource::AuthenticationResource(Wt::Dbo::SqlConnectionPool &connectionPool)
|
AuthenticationResource::AuthenticationResource() {
|
||||||
: m_connectionPool(connectionPool) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DbStruct::DbStruct(const std::string &db) : rng(clock()), distribution(1, 10000) {
|
DbStruct::DbStruct(const std::string &db) : rng(clock()), distribution(1, 10000) {
|
||||||
|
@ -46,11 +46,8 @@ struct DbStruct {
|
|||||||
|
|
||||||
class AuthenticationResource : public Wt::WResource {
|
class AuthenticationResource : public Wt::WResource {
|
||||||
public:
|
public:
|
||||||
AuthenticationResource(Wt::Dbo::SqlConnectionPool &connectionPool);
|
AuthenticationResource();
|
||||||
void handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) final;
|
void handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) final;
|
||||||
|
|
||||||
private:
|
|
||||||
Wt::Dbo::SqlConnectionPool &m_connectionPool;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlaintextResource : public Wt::WResource {
|
class PlaintextResource : public Wt::WResource {
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
#include "User.h"
|
|
||||||
#include <Wt/Dbo/Impl.h>
|
|
||||||
#include <Wt/Auth/Dbo/AuthInfo.h>
|
|
||||||
|
|
||||||
DBO_INSTANTIATE_TEMPLATES(User)
|
|
@ -1,8 +1,8 @@
|
|||||||
#include "WebApplication.h"
|
#include "WebApplication.h"
|
||||||
#include "BoostLog.h"
|
#include "BoostLog.h"
|
||||||
|
#include "Database/Session.h"
|
||||||
#include "Hello.h"
|
#include "Hello.h"
|
||||||
#include "Restful.h"
|
#include "Restful.h"
|
||||||
#include "Session.h"
|
|
||||||
#include <Wt/Auth/AuthService.h>
|
#include <Wt/Auth/AuthService.h>
|
||||||
#include <Wt/Auth/HashFunction.h>
|
#include <Wt/Auth/HashFunction.h>
|
||||||
#include <Wt/Auth/PasswordService.h>
|
#include <Wt/Auth/PasswordService.h>
|
||||||
@ -23,13 +23,12 @@ WebApplication::WebApplication(uint16_t port, const std::string &documentRoot) {
|
|||||||
initializeAuthenticationService();
|
initializeAuthenticationService();
|
||||||
|
|
||||||
m_server = std::make_unique<Wt::WServer>(std::format("{}/resources", documentRoot), args);
|
m_server = std::make_unique<Wt::WServer>(std::format("{}/resources", documentRoot), args);
|
||||||
m_sqlConnectionPool = createConnectionPool(std::format("{}/database.sqlite", documentRoot));
|
|
||||||
|
|
||||||
m_server->addEntryPoint(Wt::EntryPointType::Application,
|
m_server->addEntryPoint(Wt::EntryPointType::Application,
|
||||||
std::bind(&WebApplication::createApplication, this, std::placeholders::_1, false));
|
std::bind(&WebApplication::createApplication, this, std::placeholders::_1, false));
|
||||||
m_server->addEntryPoint(Wt::EntryPointType::WidgetSet,
|
m_server->addEntryPoint(Wt::EntryPointType::WidgetSet,
|
||||||
std::bind(&WebApplication::createApplication, this, std::placeholders::_1, true), "/wt/app.js");
|
std::bind(&WebApplication::createApplication, this, std::placeholders::_1, true), "/wt/app.js");
|
||||||
m_server->addResource(std::make_shared<AuthenticationResource>(*m_sqlConnectionPool), "/auth");
|
m_server->addResource(std::make_shared<AuthenticationResource>(), "/auth");
|
||||||
m_server->addResource(std::make_shared<PlaintextResource>(), "/plaintext");
|
m_server->addResource(std::make_shared<PlaintextResource>(), "/plaintext");
|
||||||
m_server->addResource(std::make_shared<DbResource>(std::format("{}/database.sqlite", documentRoot)), "/db");
|
m_server->addResource(std::make_shared<DbResource>(std::format("{}/database.sqlite", documentRoot)), "/db");
|
||||||
|
|
||||||
@ -39,15 +38,8 @@ WebApplication::WebApplication(uint16_t port, const std::string &documentRoot) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Wt::Dbo::SqlConnectionPool> WebApplication::createConnectionPool(const std::string &sqlite3) {
|
|
||||||
auto connection = std::make_unique<Wt::Dbo::backend::Sqlite3>(sqlite3);
|
|
||||||
connection->setProperty("show-queries", "true");
|
|
||||||
connection->setDateTimeStorage(Wt::Dbo::SqlDateTimeType::DateTime, Wt::Dbo::backend::DateTimeStorage::PseudoISO8601AsText);
|
|
||||||
return std::make_unique<Wt::Dbo::FixedSqlConnectionPool>(std::move(connection), 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Wt::WApplication> WebApplication::createApplication(const Wt::WEnvironment &env, bool embedded) {
|
std::unique_ptr<Wt::WApplication> WebApplication::createApplication(const Wt::WEnvironment &env, bool embedded) {
|
||||||
return std::make_unique<Hello>(env, *m_sqlConnectionPool, embedded);
|
return std::make_unique<Hello>(env, embedded);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebApplication::~WebApplication() {
|
WebApplication::~WebApplication() {
|
||||||
|
@ -9,10 +9,6 @@ class WServer;
|
|||||||
class WApplication;
|
class WApplication;
|
||||||
class WEnvironment;
|
class WEnvironment;
|
||||||
|
|
||||||
namespace Dbo {
|
|
||||||
class SqlConnectionPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Auth {
|
namespace Auth {
|
||||||
class AuthService;
|
class AuthService;
|
||||||
class PasswordService;
|
class PasswordService;
|
||||||
@ -32,12 +28,10 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
WebApplication(uint16_t port, const std::string &documentRoot);
|
WebApplication(uint16_t port, const std::string &documentRoot);
|
||||||
static std::unique_ptr<Wt::Dbo::SqlConnectionPool> createConnectionPool(const std::string &sqlite3);
|
|
||||||
std::unique_ptr<Wt::WApplication> createApplication(const Wt::WEnvironment &env, bool embedded);
|
std::unique_ptr<Wt::WApplication> createApplication(const Wt::WEnvironment &env, bool embedded);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Wt::WServer> m_server;
|
std::unique_ptr<Wt::WServer> m_server;
|
||||||
std::unique_ptr<Wt::Dbo::SqlConnectionPool> m_sqlConnectionPool;
|
|
||||||
|
|
||||||
std::unique_ptr<Wt::Auth::AuthService> m_authService;
|
std::unique_ptr<Wt::Auth::AuthService> m_authService;
|
||||||
std::unique_ptr<Wt::Auth::PasswordService> m_passwordService;
|
std::unique_ptr<Wt::Auth::PasswordService> m_passwordService;
|
||||||
|
Loading…
Reference in New Issue
Block a user