use dbo, not test.
All checks were successful
Deploy / Build (push) Successful in 6m54s

This commit is contained in:
luocai 2024-11-27 19:23:06 +08:00
parent 1df434efba
commit 889faa4404
13 changed files with 102 additions and 349 deletions

View File

@ -1,7 +1,6 @@
find_package(Wt REQUIRED Dbo)
add_library(Database
Database.h Database.cpp
Session.h Session.cpp
Task.h
User.h

View File

@ -1,234 +0,0 @@
#include "Database.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 <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) {
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;
int result = sqlite3_open(path.c_str(), &m_sqlite3);
if (result != SQLITE_OK) {
ret = false;
LOG(error) << "open database failed.";
}
initialize();
return ret;
}
void Database::updateVisitCount(const std::string &url, const std::string &visitorUuid, const std::string &userAgent,
int64_t time) {
sqlite3_stmt *stmt;
auto strippedUrl = url;
if (strippedUrl.size() > 1 && strippedUrl.back() == '/') {
strippedUrl.pop_back();
}
const char *query = "SELECT id, page_view_count FROM visit_analysis WHERE url = ? AND visitor_uuid = ?";
if (sqlite3_prepare_v2(m_sqlite3, query, -1, &stmt, 0) != SQLITE_OK) {
LOG(error) << "Failed to prepare statement: " << sqlite3_errmsg(m_sqlite3);
}
sqlite3_bind_text(stmt, 1, strippedUrl.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, visitorUuid.c_str(), -1, SQLITE_STATIC);
int id = -1;
int page_view_count = 0;
if (sqlite3_step(stmt) == SQLITE_ROW) {
id = sqlite3_column_int(stmt, 0);
page_view_count = sqlite3_column_int(stmt, 1);
}
sqlite3_finalize(stmt);
if (id != -1) { // 更新记录
const char *updateQuery =
"UPDATE visit_analysis SET last_user_agent = ?, last_view_time = ?, page_view_count = ? WHERE id = ?";
if (sqlite3_prepare_v2(m_sqlite3, updateQuery, -1, &stmt, 0) != SQLITE_OK) {
LOG(error) << "Failed to prepare update statement: " << sqlite3_errmsg(m_sqlite3);
}
sqlite3_bind_text(stmt, 1, userAgent.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_int64(stmt, 2, time);
sqlite3_bind_int(stmt, 3, page_view_count + 1);
sqlite3_bind_int(stmt, 4, id);
if (sqlite3_step(stmt) != SQLITE_DONE) {
LOG(error) << "Failed to update record: " << sqlite3_errmsg(m_sqlite3);
}
sqlite3_finalize(stmt);
} else { // 插入新记录
const char *insertQuery = "INSERT INTO visit_analysis (url, visitor_uuid, last_user_agent, last_view_time, "
"page_view_count) VALUES (?, ?, ?, ?, 1)";
if (sqlite3_prepare_v2(m_sqlite3, insertQuery, -1, &stmt, 0) != SQLITE_OK) {
LOG(error) << "Failed to prepare insert statement: " << sqlite3_errmsg(m_sqlite3);
}
sqlite3_bind_text(stmt, 1, strippedUrl.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, visitorUuid.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 3, userAgent.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_int64(stmt, 4, time);
if (sqlite3_step(stmt) != SQLITE_DONE) {
LOG(error) << "Failed to insert record: " << sqlite3_errmsg(m_sqlite3) << std::endl;
}
sqlite3_finalize(stmt);
}
}
void Database::clearVisitRecord() {
char *message = nullptr;
constexpr auto sql = "DELETE FROM visit_analysis";
int rc = sqlite3_exec(m_sqlite3, sql, nullptr, nullptr, &message);
if (rc != SQLITE_OK) {
LOG(error) << "SQL error: " << message;
sqlite3_free(message);
}
}
VisitAnalysis Database::siteVisitAnalysisData() {
VisitAnalysis ret;
sqlite3_stmt *stmt = nullptr;
const char *sql = "SELECT COUNT(DISTINCT visitor_uuid) as unique_visitors, SUM(page_view_count) as "
"total_page_views FROM visit_analysis";
if (sqlite3_prepare_v2(m_sqlite3, sql, -1, &stmt, nullptr) != SQLITE_OK) {
LOG(error) << "Failed to prepare statement: " << sqlite3_errmsg(m_sqlite3);
return ret;
}
if (sqlite3_step(stmt) == SQLITE_ROW) {
ret.uniqueVisitorCount = sqlite3_column_int(stmt, 0);
ret.pageViewCount = sqlite3_column_int(stmt, 1);
} else {
LOG(error) << "Failed to execute query: " << sqlite3_errmsg(m_sqlite3);
}
sqlite3_finalize(stmt);
return ret;
}
static std::vector<std::string> urlFilter = {
"/",
"/search",
"/LoginPage",
"/MessageBoard",
"/我的笔记",
"/我的博客",
};
std::list<VisitAnalysis> Database::mostViewedUrls(int size) {
const char *sql = "SELECT url, SUM(page_view_count) AS total_page_view_count "
"FROM visit_analysis "
"GROUP BY url "
"ORDER BY total_page_view_count DESC "
"LIMIT ?";
sqlite3_stmt *stmt = nullptr;
std::list<VisitAnalysis> ret;
auto rc = sqlite3_prepare_v2(m_sqlite3, sql, -1, &stmt, nullptr);
if (rc != SQLITE_OK) {
LOG(error) << "Failed to prepare statement: " << sqlite3_errmsg(m_sqlite3);
return ret;
}
sqlite3_bind_int(stmt, 1, size + urlFilter.size());
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
VisitAnalysis pv;
pv.url = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
if (std::find(urlFilter.cbegin(), urlFilter.cend(), pv.url) != urlFilter.cend()) continue;
pv.pageViewCount = sqlite3_column_int(stmt, 1);
if (ret.size() < size) {
ret.push_back(pv);
}
}
if (rc != SQLITE_DONE) {
LOG(error) << "Failed to execute statement: " << sqlite3_errmsg(m_sqlite3);
}
sqlite3_finalize(stmt);
return ret;
}
std::list<VisitAnalysis> Database::latestViewedUrls(int size) {
std::list<VisitAnalysis> ret;
sqlite3_stmt *stmt;
const char *sql = R"(
SELECT url, MAX(last_view_time) as last_view_time
FROM visit_analysis
GROUP BY url
ORDER BY last_view_time DESC
LIMIT ?
)";
if (sqlite3_prepare_v2(m_sqlite3, sql, -1, &stmt, nullptr) != SQLITE_OK) {
LOG(error) << "Failed to prepare statement: " << sqlite3_errmsg(m_sqlite3);
return ret;
}
if (sqlite3_bind_int(stmt, 1, size + urlFilter.size()) != SQLITE_OK) {
LOG(error) << "Failed to bind parameter: " << sqlite3_errmsg(m_sqlite3);
sqlite3_finalize(stmt);
return ret;
}
while (sqlite3_step(stmt) == SQLITE_ROW) {
VisitAnalysis visit;
visit.url = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
if (std::find(urlFilter.cbegin(), urlFilter.cend(), visit.url) != urlFilter.cend()) continue;
visit.lastViewTime = sqlite3_column_int64(stmt, 1);
if (ret.size() < size) {
ret.push_back(visit);
}
}
return ret;
}
VisitAnalysis Database::visitAnalysisData(const std::string &url) {
VisitAnalysis ret;
sqlite3_stmt *stmt;
std::string query =
"SELECT SUM(page_view_count), COUNT(DISTINCT visitor_uuid) FROM visit_analysis WHERE url = '" + url + "';";
if (sqlite3_prepare_v2(m_sqlite3, query.c_str(), -1, &stmt, nullptr) == SQLITE_OK) {
if (sqlite3_step(stmt) == SQLITE_ROW) {
ret.pageViewCount = sqlite3_column_int(stmt, 0);
ret.uniqueVisitorCount = sqlite3_column_int(stmt, 1);
}
sqlite3_finalize(stmt);
} else {
LOG(error) << "Failed to execute query: " << sqlite3_errmsg(m_sqlite3);
}
return ret;
}
void Database::initialize() {
char *message = nullptr;
auto sql = R"(
CREATE TABLE IF NOT EXISTS visit_analysis (
id INTEGER PRIMARY KEY AUTOINCREMENT,
url TEXT NOT NULL,
visitor_uuid TEXT NOT NULL,
last_user_agent TEXT NOT NULL,
last_view_time INTEGER NOT NULL,
page_view_count INTEGER NOT NULL
);
)";
int result = sqlite3_exec(m_sqlite3, sql, 0, 0, &message);
if (result != SQLITE_OK) {
LOG(error) << "Failed to create table: " << message << std::endl;
sqlite3_free(message);
}
}
Database::~Database() {
if (m_sqlite3 != nullptr) {
sqlite3_close(m_sqlite3);
m_sqlite3 = nullptr;
}
}

View File

@ -1,49 +0,0 @@
#ifndef __DATABASE_H__
#define __DATABASE_H__
#include "HomeBox.h"
#include "Singleton.h"
#include "Task.h"
#include <string>
namespace Wt {
namespace Dbo {
class SqlConnectionPool;
}
} // namespace Wt
class VisitAnalysis {
public:
std::string url;
int pageViewCount = 0;
int uniqueVisitorCount = 0;
int lastViewTime = 0;
};
struct sqlite3;
class Session;
class Database {
friend class Amass::Singleton<Database>;
public:
~Database();
std::unique_ptr<Session> session();
bool open(const std::string &path);
void updateVisitCount(const std::string &url, const std::string &visitorUuid, const std::string &userAgent, int64_t time);
void clearVisitRecord();
VisitAnalysis visitAnalysisData(const std::string &url);
VisitAnalysis siteVisitAnalysisData();
std::list<VisitAnalysis> mostViewedUrls(int size);
std::list<VisitAnalysis> latestViewedUrls(int size);
protected:
void initialize();
private:
std::unique_ptr<Wt::Dbo::SqlConnectionPool> m_sqlConnectionPool;
sqlite3 *m_sqlite3 = nullptr;
};
#endif // __DATABASE_H__

View File

@ -1,6 +1,32 @@
#include "Session.h"
#include "BoostLog.h"
#include <Wt/Auth/Dbo/UserDatabase.h>
#include <Wt/Dbo/WtJsonSqlTraits.h>
#include <Wt/Dbo/backend/Sqlite3.h>
#include <Wt/Dbo/FixedSqlConnectionPool.h>
#include <Wt/Dbo/SqlConnectionPool.h>
namespace Database {
std::unique_ptr<Wt::Dbo::SqlConnectionPool> sqlConnectionPool;
bool initialize(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);
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();
}
return true;
}
std::unique_ptr<Session> session() {
if (!sqlConnectionPool) return {};
return std::make_unique<Session>(*sqlConnectionPool);
}
} // namespace Database
Session::Session(Wt::Dbo::SqlConnectionPool &connectionPool) {
setConnectionPool(connectionPool);

View File

@ -4,9 +4,9 @@
#include "HomeBox.h"
#include "Task.h"
#include "User.h"
#include "VisitorRecord.h"
#include <Wt/Auth/Login.h>
#include <Wt/Dbo/Session.h>
#include "VisitorRecord.h"
using UserDatabase = Wt::Auth::Dbo::UserDatabase<AuthInfo>;
@ -23,4 +23,9 @@ private:
Wt::Auth::Login m_login;
};
namespace Database {
bool initialize(const std::string &path);
std::unique_ptr<Session> session();
} // namespace Database
#endif // __SESSION_H__

View File

@ -1,5 +1,4 @@
#include "Application.h"
#include "Database/Database.h"
#include "Database/Session.h"
#include "DateTime.h"
#include "HttpSession.h"
@ -62,7 +61,7 @@ Application::Application(const std::string &path)
m_router->insert("/api/v1/tasklist", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
using namespace boost::beast;
auto database = Amass::Singleton<Database>::instance()->session();
auto database = Database::session();
Tasks tasks = database->find<Task>();
std::ostringstream oss;
Wt::Dbo::jsonSerialize(tasks, oss);
@ -87,7 +86,7 @@ Application::Application(const std::string &path)
if (root.contains("content")) {
content = root.at("content").as_string();
}
auto database = Amass::Singleton<Database>::instance()->session();
auto database = Database::session();;
auto task = std::make_unique<Task>();
task->createTime = system_clock::time_point(seconds(root.at("createTime").as_int64()));
task->content = content;
@ -111,7 +110,7 @@ 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) {
using namespace boost::beast;
LOG(info) << "delete task: " << matches.at("id");
auto database = Amass::Singleton<Database>::instance()->session();
auto database = Database::session();;
Wt::Dbo::ptr<Task> joe = database->find<Task>().where("id = ?").bind(std::stoi(matches.at("id")));
int status = -1;
if (joe) {
@ -140,7 +139,7 @@ Application::Application(const std::string &path)
session.reply(
ServiceLogic::make_200<boost::beast::http::string_body>(request, "notify successed.\n", "text/html"));
});
// clang-format on
m_router->insert("/api/v1/visit_analysis", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
using namespace boost::beast;
auto rootJson = boost::json::parse(request.body());
@ -149,28 +148,27 @@ Application::Application(const std::string &path)
if (root.contains("url")) {
url = root["url"].as_string();
}
auto database = Amass::Singleton<Database>::instance();
auto database = Database::session();
if (std::filesystem::exists("amass_blog" + url) && url.find("/我的博客/page") != 0) {
std::string visitorUuid;
Wt::Dbo::Transaction transaction(*database);
auto record = std::make_unique<VisitorRecord>();
record->time = std::chrono::system_clock::now();
record->url = url;
if (root.contains("visitor_uuid")) {
visitorUuid = root["visitor_uuid"].as_string();
record->visitorUuid = root["visitor_uuid"].as_string();
}
std::string userAgent;
if (root.contains("user_agent")) {
userAgent = root["user_agent"].as_string();
record->userAgent = root["user_agent"].as_string();
}
auto now = std::chrono::system_clock::now();
std::time_t now_time = std::chrono::system_clock::to_time_t(now);
database->updateVisitCount(url, visitorUuid, userAgent, now_time);
database->add(std::move(record));
}
auto data = database->visitAnalysisData(std::string(url));
auto total = database->siteVisitAnalysisData();
boost::json::object reply;
reply["page_view_count"] = data.pageViewCount;
reply["unique_visitor_count"] = data.uniqueVisitorCount;
reply["site_page_view_count"] = total.pageViewCount;
reply["site_unique_visitor_count"] = total.uniqueVisitorCount;
reply["page_view_count"] = database->query<int>("SELECT COUNT(*) FROM visitor_record WHERE url = ?").bind(std::string(url));
reply["unique_visitor_count"] = database->query<int>("SELECT COUNT(DISTINCT visitor_uuid) FROM visitor_record WHERE url = ?").bind(std::string(url));
reply["site_page_view_count"] = database->query<int>("SELECT COUNT(*) FROM visitor_record");
reply["site_unique_visitor_count"] = database->query<int>("SELECT COUNT(DISTINCT visitor_uuid) FROM visitor_record");
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
@ -196,13 +194,13 @@ Application::Application(const std::string &path)
}
}
}
auto data = Amass::Singleton<Database>::instance()->mostViewedUrls(size);
auto database = Database::session();
Wt::Dbo::collection<std::tuple<std::string, int>> query = database->query<std::tuple<std::string, int>>("SELECT url, COUNT(*) as count FROM visitor_record GROUP BY url ORDER BY count DESC LIMIT ?").bind(size);
boost::json::array reply;
for (auto &d : data) {
for (auto &[url, count] : query) {
boost::json::object object;
object["url"] = d.url;
object["count"] = d.pageViewCount;
object["url"] = url;
object["count"] = count;
reply.push_back(std::move(object));
}
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
@ -216,6 +214,7 @@ Application::Application(const std::string &path)
m_router->insert("/api/v1/latest_viewed_urls", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) {
using namespace boost::beast;
using namespace std::chrono;
int size = 5;
std::error_code error;
if (!request.body().empty()) {
@ -229,13 +228,14 @@ Application::Application(const std::string &path)
}
}
}
auto data = Amass::Singleton<Database>::instance()->latestViewedUrls(size);
auto database = Database::session();
using Reslut = std::tuple<std::string, system_clock::time_point>;
Wt::Dbo::collection<Reslut> query = database->query<Reslut>("SELECT url, MAX(time) FROM visitor_record GROUP BY url ORDER BY MAX(time) DESC LIMIT ?").bind(size);
boost::json::array reply;
for (auto &d : data) {
for (auto &[url, time] : query) {
boost::json::object object;
object["url"] = d.url;
object["time"] = d.lastViewTime;
object["url"] = url;
object["time"] = duration_cast<seconds>(time.time_since_epoch()).count();
reply.push_back(std::move(object));
}
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
@ -246,7 +246,7 @@ Application::Application(const std::string &path)
s.prepare_payload();
session.reply(std::move(s));
});
// clang-format on
m_ioContext = Amass::Singleton<IoContext>::instance<Amass::Construct>(getThreads());
m_timer = std::make_shared<boost::asio::system_timer>(*m_ioContext->ioContext());
@ -303,7 +303,7 @@ void Application::alarmTask() {
LOG(error) << error.message();
return;
}
auto session = Amass::Singleton<Database>::instance()->session();
auto session = Database::session();
Tasks tasks = session->find<Task>();
bool founded = false;
std::string content;

View File

@ -1,6 +1,6 @@
#include "Application.h"
#include "BoostLog.h"
#include "Database/Database.h"
#include "Database/Session.h"
#include "IoContext.h"
#include "Listener.h"
#include "Live2dBackend.h"
@ -11,7 +11,6 @@
#include "WeChatContext/CorporationContext.h"
#include "WeChatContext/WeChatContext.h"
#include "WebApplication.h"
#include <Wt/Dbo/SqlConnectionPool.h>
#include <boost/program_options.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/ptree.hpp>
@ -60,15 +59,12 @@ int main(int argc, char const *argv[]) {
}
auto application = Singleton<Application>::instance<Construct>("settings.ini");
auto database = Singleton<Database>::instance<Construct>();
if (!std::filesystem::exists(application->getDocumentRoot())) {
LOG(fatal) << "document root: " << application->getDocumentRoot() << " is not exists...";
std::exit(102);
}
BOOST_ASSERT_MSG(!application->getServer().empty(), "server.empty() == true");
database->open(std::format("{}/database.sqlite", application->getDocumentRoot()));
Database::initialize(std::format("{}/database.sqlite", application->getDocumentRoot()));
auto address = boost::asio::ip::make_address(application->getServer());
auto listener =
std::make_shared<Listener>(application->ioContext(), boost::asio::ip::tcp::endpoint{address, application->getPort()});

View File

@ -9,6 +9,7 @@ add_executable(UnitTest main.cpp
)
target_compile_definitions(UnitTest
PRIVATE BOOST_TEST_NO_MAIN
PUBLIC LOG_FILTER_LEVEL=1
)

View File

@ -1,22 +1,13 @@
#include "Database/Database.h"
#include "BoostLog.h"
#include "Database/Session.h"
#include <Wt/Dbo/SqlConnectionPool.h>
#include <boost/test/unit_test.hpp>
#include <filesystem>
static constexpr auto path = "build/database.sqlite";
using namespace std::chrono;
BOOST_AUTO_TEST_CASE(DatabaseTest) {
if (std::filesystem::exists(path)) {
std::filesystem::remove(path);
}
Database database;
database.open(path);
// BOOST_TEST(database.open(path));
auto session = database.session();
auto session = Database::session();
Wt::Dbo ::Transaction transaction(*session);
@ -70,12 +61,23 @@ BOOST_AUTO_TEST_CASE(DatabaseTest) {
auto d = session->add(std::move(item));
}
auto now = std::chrono::system_clock::now();
std::time_t now_time = std::chrono::system_clock::to_time_t(now);
database.updateVisitCount("/note", "uuid_123", "chrome", now_time);
database.updateVisitCount("/note/1", "uuid_1232", "chrome", now_time);
database.updateVisitCount("/note", "uuid_123", "chrome", now_time);
database.updateVisitCount("/note", "uuid_1234", "chrome", now_time);
}
BOOST_AUTO_TEST_CASE(VisitorRecordTest) {
// database.updateVisitCount("/note", "uuid_123", "chrome", now_time);
// database.updateVisitCount("/note/1", "uuid_1232", "chrome", now_time);
// database.updateVisitCount("/note", "uuid_123", "chrome", now_time);
// database.updateVisitCount("/note", "uuid_1234", "chrome", now_time);
auto session = Database::session();
{
Wt::Dbo ::Transaction transaction(*session);
auto now = std::chrono::system_clock::now();
auto record = std::make_unique<VisitorRecord>();
record->time = now;
record->url = "/note";
record->userAgent = "chrome";
record->visitorUuid = "uuid_123";
auto d = session->add(std::move(record));
}
}

View File

@ -1,2 +1,16 @@
#define BOOST_TEST_MODULE OlderTest
#include "boost/test/included/unit_test.hpp"
#include <filesystem>
#include "Database/Session.h"
constexpr auto databasePath = "build/database.sqlite";
int main(int argc, char *argv[]) {
if (std::filesystem::exists(databasePath)) {
std::filesystem::remove(databasePath);
}
Database::initialize(databasePath);
extern ::boost::unit_test::test_suite *init_unit_test_suite(int argc, char *argv[]);
boost::unit_test::init_unit_test_func init_func = &init_unit_test_suite;
return ::boost::unit_test::unit_test_main(init_func, argc, argv);
}

View File

@ -1,6 +1,5 @@
#include "Hello.h"
#include "BoostLog.h"
#include "Database/Database.h"
#include "Database/Session.h"
#include "Dialog.h"
#include "LoginWidget.h"
@ -19,7 +18,7 @@ Hello::Hello(const Wt::WEnvironment &env, bool embedded) : Wt::WApplication(env)
messageResourceBundle().use(appRoot() + "auth_css_theme");
useStyleSheet("/resources/app.css");
LOG(info) << "app root: " << appRoot();
m_session = Amass::Singleton<Database>::instance()->session();
m_session = Database::session();
m_session->login().changed().connect(this, &Hello::authEvent);
setTitle("Hello world");
if (!embedded) {

View File

@ -1,5 +1,4 @@
#include "Restful.h"
#include "Database/Database.h"
#include "Database/Session.h"
#include <Wt/Dbo/Impl.h>
#include <Wt/Dbo/Json.h>
@ -11,7 +10,7 @@ DBO_INSTANTIATE_TEMPLATES(MyMessage)
DbStruct *m_dbStruct;
void AuthenticationResource::handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) {
auto session = Amass::Singleton<Database>::instance()->session();
auto session = Database::session();
response.setMimeType("application/json");
response.addHeader("Server", "Wt");

View File

@ -144,8 +144,3 @@ function main() {
}
main $@
# curl -k --insecure https://127.0.0.1/lua
# openresty -p Server
# sudo openresty -p Server -s reload
# export LD_LIBRARY_PATH=/opt/Libraries/boost_1_85_0/lib:$LD_LIBRARY_PATH