Database config, function arguments
FossilOrigin-Name: cb4cda127244dddb0df8b4979dcbffe93c40b17b7d5ee80e7bf2523f96a03805
This commit is contained in:
parent
de3d9a16e0
commit
ecb4162ae4
15 changed files with 173 additions and 15 deletions
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
53
src/config/config_db.cpp
Normal file
53
src/config/config_db.cpp
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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<std::string>();
|
||||
|
||||
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<std::string>() != "sqlite" &&
|
||||
!Config::enter_block(node, "sqlite"))
|
||||
return false;
|
||||
|
||||
cfg.type = DB::Database::Type::SQLite;
|
||||
cfg.file = node["db_file"].as<std::string>();
|
||||
return true;
|
||||
}
|
||||
}
|
38
src/config/config_db.h
Normal file
38
src/config/config_db.h
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "database/database.h"
|
||||
#include <string>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
#include <cstdint>
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
#include <filesystem>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
#include <optional>
|
||||
#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;
|
||||
};
|
||||
|
||||
|
|
|
@ -26,6 +26,12 @@ namespace DB
|
|||
public:
|
||||
explicit Database();
|
||||
virtual ~Database() = default;
|
||||
|
||||
enum class Type
|
||||
{
|
||||
SQLite,
|
||||
PostgreSQL
|
||||
};
|
||||
private:
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,12 +16,14 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <utility>
|
||||
#include "sqlite.h"
|
||||
|
||||
using namespace DB;
|
||||
|
||||
SQLite::SQLite()
|
||||
SQLite::SQLite(std::filesystem::path path)
|
||||
: DB::Database(),
|
||||
path{std::move(path)},
|
||||
db(nullptr, SQLiteDeleter())
|
||||
{
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <sqlite3.h>
|
||||
#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<sqlite3, SQLiteDeleter> db;
|
||||
};
|
||||
|
|
|
@ -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<HTTP::Response const> 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;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <any>
|
||||
#include <initializer_list>
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
|
@ -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<RequestCallbackPair_t> req_map;
|
||||
|
||||
private:
|
||||
std::any cb_args;
|
||||
/** Port number, should be set once */
|
||||
uint16_t port;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <any>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
@ -35,7 +36,7 @@ namespace HTTP
|
|||
*/
|
||||
using RequestArgs_t = std::vector<std::string>;
|
||||
using RequestCallback_t = std::function<
|
||||
std::optional<HTTP::Response const>( const RequestArgs_t& )>;
|
||||
std::optional<HTTP::Response const>( std::any& args, const RequestArgs_t& )>;
|
||||
using RequestCallbackPair_t = std::pair<Request, RequestCallback_t>;
|
||||
|
||||
/**
|
||||
|
|
28
src/main.cpp
28
src/main.cpp
|
@ -20,9 +20,12 @@
|
|||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#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<DB::Database> 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<DB::SQLite>(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<HTTP::Server> server =
|
||||
std::make_shared<HTTP::MicroHttpdServer>(Config::instance().config.http.port);
|
||||
std::make_shared<HTTP::MicroHttpdServer>(Config::instance().config.http.port, std::make_any<RouteArgs>(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{"<html><body>Hello, browser!</body></html>"};
|
||||
} },
|
||||
|
||||
{ {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("<html><body>Hello, ") + arg.at(0) + std::string("!</body></html>")};
|
||||
} },
|
||||
});
|
||||
|
|
26
src/route_args.h
Normal file
26
src/route_args.h
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "database/database.h"
|
||||
|
||||
struct RouteArgs
|
||||
{
|
||||
DB::Database* db;
|
||||
};
|
Loading…
Reference in a new issue