From ecb4162ae451ca59e9499060799b1c023c594e46 Mon Sep 17 00:00:00 2001 From: nekobit Date: Sun, 2 Oct 2022 23:20:02 +0000 Subject: [PATCH] Database config, function arguments FossilOrigin-Name: cb4cda127244dddb0df8b4979dcbffe93c40b17b7d5ee80e7bf2523f96a03805 --- CMakeLists.txt | 1 + config.sample.yaml | 6 ++-- src/config/config_db.cpp | 53 ++++++++++++++++++++++++++++++++++ src/config/config_db.h | 38 ++++++++++++++++++++++++ src/config/config_loader.h | 2 ++ src/database/database.h | 6 ++++ src/database/sqlite/sqlite.cpp | 4 ++- src/database/sqlite/sqlite.h | 4 ++- src/http/httpserver.cpp | 7 +++-- src/http/httpserver.h | 4 ++- src/http/microhttpd_server.cpp | 4 +-- src/http/microhttpd_server.h | 2 +- src/http/request.h | 3 +- src/main.cpp | 28 ++++++++++++++++-- src/route_args.h | 26 +++++++++++++++++ 15 files changed, 173 insertions(+), 15 deletions(-) create mode 100644 src/config/config_db.cpp create mode 100644 src/config/config_db.h create mode 100644 src/route_args.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 12c256d..67b18fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ set(sources src/main.cpp src/http/request.cpp src/http/response.cpp src/config/config_http.cpp + src/config/config_db.cpp src/config/config_loader.cpp src/config/config_helpers.cpp src/logger.cpp) diff --git a/config.sample.yaml b/config.sample.yaml index 5a43043..4fa5407 100644 --- a/config.sample.yaml +++ b/config.sample.yaml @@ -9,6 +9,8 @@ http: database: + db_type: "sqlite" + db_name: "wormhole" + sqlite: - db_name: "wormhole" - # db_file: "/mnt/little_boy/wormhole.sqlite" + db_file: "/mnt/little_boy/wormhole.sqlite" diff --git a/src/config/config_db.cpp b/src/config/config_db.cpp new file mode 100644 index 0000000..7200398 --- /dev/null +++ b/src/config/config_db.cpp @@ -0,0 +1,53 @@ +/* + * Wormhole - Federated social network + * Copyright (C) 2022 Nekobit + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "config/config_db.h" +#include "config/config_helpers.h" + +// Decl +namespace +{ + bool load_database_sqlite(Config::Database&, YAML::Node&); +} + +// Calls other (local) database functions if the database block exists +void Config::load_database(Config::Database& cfg, YAML::Node& node) +{ + if (!Config::enter_block(node, "database")) + return; + + cfg.name = node["db_name"].as(); + + if (!load_database_sqlite(cfg, node)) + return; +} + +namespace +{ + bool load_database_sqlite(Config::Database& cfg, YAML::Node& node) + { + // If database block doesn't exist, give up anyway + if (node["db_type"].as() != "sqlite" && + !Config::enter_block(node, "sqlite")) + return false; + + cfg.type = DB::Database::Type::SQLite; + cfg.file = node["db_file"].as(); + return true; + } +} diff --git a/src/config/config_db.h b/src/config/config_db.h new file mode 100644 index 0000000..89819a8 --- /dev/null +++ b/src/config/config_db.h @@ -0,0 +1,38 @@ +/* + * Wormhole - Federated social network + * Copyright (C) 2022 Nekobit + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "database/database.h" +#include +#include +#include + +namespace Config +{ + struct Database + { + std::string name; + /** SQLite only */ + std::string file; + DB::Database::Type type; + }; + + void load_database(Config::Database& cfg, YAML::Node& node); +} + diff --git a/src/config/config_loader.h b/src/config/config_loader.h index 54b0579..bd50ef6 100644 --- a/src/config/config_loader.h +++ b/src/config/config_loader.h @@ -21,6 +21,7 @@ #include #include #include +#include "config/config_db.h" #include "config_http.h" namespace Config @@ -39,6 +40,7 @@ namespace Config struct CommonConfig { Config::HTTP http; + Config::Database database; } config; }; diff --git a/src/database/database.h b/src/database/database.h index fc4ee30..8649a96 100644 --- a/src/database/database.h +++ b/src/database/database.h @@ -26,6 +26,12 @@ namespace DB public: explicit Database(); virtual ~Database() = default; + + enum class Type + { + SQLite, + PostgreSQL + }; private: }; } diff --git a/src/database/sqlite/sqlite.cpp b/src/database/sqlite/sqlite.cpp index 08bf733..3453b9d 100644 --- a/src/database/sqlite/sqlite.cpp +++ b/src/database/sqlite/sqlite.cpp @@ -16,12 +16,14 @@ * along with this program. If not, see . */ +#include #include "sqlite.h" using namespace DB; -SQLite::SQLite() +SQLite::SQLite(std::filesystem::path path) : DB::Database(), + path{std::move(path)}, db(nullptr, SQLiteDeleter()) { diff --git a/src/database/sqlite/sqlite.h b/src/database/sqlite/sqlite.h index 708a0b6..8e3a00e 100644 --- a/src/database/sqlite/sqlite.h +++ b/src/database/sqlite/sqlite.h @@ -18,6 +18,7 @@ #pragma once +#include #include #include #include "../database.h" @@ -27,9 +28,10 @@ namespace DB class SQLite : public DB::Database { public: - explicit SQLite(); + explicit SQLite(std::filesystem::path path); virtual ~SQLite() = default; private: + std::filesystem::path path; struct SQLiteDeleter { void operator()(sqlite3* db) { sqlite3_close(db); } }; std::unique_ptr db; }; diff --git a/src/http/httpserver.cpp b/src/http/httpserver.cpp index 14af19e..a788fd9 100644 --- a/src/http/httpserver.cpp +++ b/src/http/httpserver.cpp @@ -23,9 +23,10 @@ using namespace HTTP; -Server::Server(uint16_t port) +Server::Server(uint16_t port, std::any callback_args) : port{port}, - req_map() + req_map(), + cb_args(callback_args) {} void Server::start() @@ -53,7 +54,7 @@ std::optional Server::handle_request(HTTP::Request &reques auto args = reqs.first.match_get_args(request); if (args) { - return reqs.second(*args); + return reqs.second(cb_args, *args); } } return std::nullopt; diff --git a/src/http/httpserver.h b/src/http/httpserver.h index 5a88820..ea6d083 100644 --- a/src/http/httpserver.h +++ b/src/http/httpserver.h @@ -18,6 +18,7 @@ #pragma once +#include #include #include #include @@ -30,7 +31,7 @@ namespace HTTP class Server { public: - explicit Server(uint16_t port); + explicit Server(uint16_t port, std::any callback_args); virtual ~Server() = default; /** @@ -72,6 +73,7 @@ namespace HTTP std::vector req_map; private: + std::any cb_args; /** Port number, should be set once */ uint16_t port; diff --git a/src/http/microhttpd_server.cpp b/src/http/microhttpd_server.cpp index 1a6a32a..83ba7fd 100644 --- a/src/http/microhttpd_server.cpp +++ b/src/http/microhttpd_server.cpp @@ -58,8 +58,8 @@ namespace } } -MicroHttpdServer::MicroHttpdServer(std::uint16_t port) - : Server(port), +MicroHttpdServer::MicroHttpdServer(std::uint16_t port, std::any callback_args) + : Server(port, callback_args), serv(nullptr) { diff --git a/src/http/microhttpd_server.h b/src/http/microhttpd_server.h index b663756..0263d0a 100644 --- a/src/http/microhttpd_server.h +++ b/src/http/microhttpd_server.h @@ -27,7 +27,7 @@ namespace HTTP class MicroHttpdServer : public Server { public: - explicit MicroHttpdServer(std::uint16_t port = 4000); + explicit MicroHttpdServer(std::uint16_t port, std::any callback_args); virtual ~MicroHttpdServer() = default; virtual void start() override final; diff --git a/src/http/request.h b/src/http/request.h index 94a81c9..15da616 100644 --- a/src/http/request.h +++ b/src/http/request.h @@ -18,6 +18,7 @@ #pragma once +#include #include #include #include @@ -35,7 +36,7 @@ namespace HTTP */ using RequestArgs_t = std::vector; using RequestCallback_t = std::function< - std::optional( const RequestArgs_t& )>; + std::optional( std::any& args, const RequestArgs_t& )>; using RequestCallbackPair_t = std::pair; /** diff --git a/src/main.cpp b/src/main.cpp index a8c60fa..b0f668d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,9 +20,12 @@ #include #include #include "config/config_loader.h" +#include "database/database.h" +#include "database/sqlite/sqlite.h" #include "http/httpserver.h" #include "http/microhttpd_server.h" #include "logger.h" +#include "route_args.h" int start_wormhole() { @@ -30,6 +33,8 @@ int start_wormhole() Logger::instance() << "Loading config..."; + std::shared_ptr database = nullptr; + try { Config::instance().load_config(CONFIG_DIR "/config.yaml"); @@ -38,18 +43,35 @@ int start_wormhole() { return EXIT_FAILURE; } + + // Select Database + switch (Config::instance().config.database.type) + { + case DB::Database::Type::SQLite: + database = std::make_shared(Config::instance().config.database.file); + break; + case DB::Database::Type::PostgreSQL: + Logger::instance() << "Not implemented!"; + return EXIT_FAILURE; + default: + Logger::instance() << "Unsupported Database!"; + return EXIT_FAILURE; + } + + // Passed as std::any to each route function + RouteArgs args{database.get()}; // Start HTTPD Server std::shared_ptr server = - std::make_shared(Config::instance().config.http.port); + std::make_shared(Config::instance().config.http.port, std::make_any(args)); // TODO Move to another file server->map_routes({ - { {HTTP::Request::Type::GET, "/test"}, [](const HTTP::RequestArgs_t& arg){ + { {HTTP::Request::Type::GET, "/test"}, [](std::any& args, const HTTP::RequestArgs_t& arg){ return HTTP::Response{"Hello, browser!"}; } }, - { {HTTP::Request::Type::GET, "/welcome/:"}, [](const HTTP::RequestArgs_t& arg){ + { {HTTP::Request::Type::GET, "/welcome/:"}, [](std::any& args, const HTTP::RequestArgs_t& arg){ return HTTP::Response{std::string("Hello, ") + arg.at(0) + std::string("!")}; } }, }); diff --git a/src/route_args.h b/src/route_args.h new file mode 100644 index 0000000..e0aa71f --- /dev/null +++ b/src/route_args.h @@ -0,0 +1,26 @@ +/* + * Wormhole - Federated social network + * Copyright (C) 2022 Nekobit + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "database/database.h" + +struct RouteArgs +{ + DB::Database* db; +};