Database config, function arguments

FossilOrigin-Name: cb4cda127244dddb0df8b4979dcbffe93c40b17b7d5ee80e7bf2523f96a03805
This commit is contained in:
nekobit 2022-10-02 23:20:02 +00:00
parent de3d9a16e0
commit ecb4162ae4
15 changed files with 173 additions and 15 deletions

View file

@ -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)

View file

@ -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
View 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
View 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);
}

View file

@ -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;
};

View file

@ -26,6 +26,12 @@ namespace DB
public:
explicit Database();
virtual ~Database() = default;
enum class Type
{
SQLite,
PostgreSQL
};
private:
};
}

View file

@ -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())
{

View file

@ -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;
};

View file

@ -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;

View file

@ -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;

View file

@ -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)
{

View file

@ -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;

View file

@ -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>;
/**

View file

@ -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
View 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;
};