generated from wessel/boilerplate
113 lines
3.7 KiB
C++
113 lines
3.7 KiB
C++
#include "ConfigManager.hpp"
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
|
|
namespace assignments::two {
|
|
|
|
ConfigManager::ConfigManager(rclcpp::Logger logger)
|
|
: logger_(logger), loaded_(false)
|
|
{
|
|
// Try to auto-load config from default location
|
|
std::string config_path = find_config_file();
|
|
if (!config_path.empty()) {
|
|
load_config(config_path);
|
|
}
|
|
}
|
|
|
|
bool ConfigManager::load_config(const std::string& config_file_path) {
|
|
try {
|
|
RCLCPP_INFO(logger_, "[CFG] '%s': loading configuration", config_file_path.c_str());
|
|
|
|
if (!std::filesystem::exists(config_file_path)) {
|
|
RCLCPP_ERROR(logger_, "[CFG] '%s': file does not exist", config_file_path.c_str());
|
|
return false;
|
|
}
|
|
|
|
config_ = toml::parse_file(config_file_path);
|
|
loaded_ = true;
|
|
|
|
RCLCPP_INFO(logger_, "[CFG] '%s': configuration loaded", config_file_path.c_str());
|
|
return true;
|
|
|
|
} catch (const toml::parse_error& e) {
|
|
RCLCPP_ERROR(logger_, "[CFG] '%s': failed to parse: %s", config_file_path.c_str(), e.what());
|
|
loaded_ = false;
|
|
return false;
|
|
} catch (const std::exception& e) {
|
|
RCLCPP_ERROR(logger_, "[CFG] '%s': failed to load: %s", config_file_path.c_str(), e.what());
|
|
loaded_ = false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
std::optional<DatabaseConfig> ConfigManager::get_database_config() const {
|
|
if (!loaded_ || !config_.has_value()) {
|
|
RCLCPP_ERROR(logger_, "[CFG] database configuration not loaded");
|
|
return std::nullopt;
|
|
}
|
|
|
|
try {
|
|
return parse_database_config(config_.value());
|
|
} catch (const std::exception& e) {
|
|
RCLCPP_ERROR(logger_, "[CFG] database configuration failed to parse: %s", e.what());
|
|
return std::nullopt;
|
|
}
|
|
}
|
|
|
|
bool ConfigManager::is_loaded() const {
|
|
return loaded_;
|
|
}
|
|
|
|
std::string ConfigManager::find_config_file() const {
|
|
// Look for config file in several locations
|
|
for (const auto& path : default_config_paths_) {
|
|
if (std::filesystem::exists(path)) {
|
|
RCLCPP_INFO(logger_, "[CFG] '%s': found configuration file", path.c_str());
|
|
return path;
|
|
}
|
|
}
|
|
|
|
RCLCPP_WARN(logger_, "[CFG] no configuration file found at default locations");
|
|
return "";
|
|
}
|
|
|
|
DatabaseConfig ConfigManager::parse_database_config(const toml::table& config) const {
|
|
DatabaseConfig db_config;
|
|
|
|
// Parse database section
|
|
auto database_section = config["database"];
|
|
if (!database_section) {
|
|
throw std::runtime_error("missing [database] section in configuration");
|
|
}
|
|
|
|
db_config.host = database_section["host"].value_or<std::string>("localhost");
|
|
db_config.port = database_section["port"].value_or<int>(5432);
|
|
db_config.dbname = database_section["dbname"].value_or<std::string>("grades");
|
|
db_config.user = database_section["user"].value_or<std::string>("postgres");
|
|
db_config.password = database_section["password"].value_or<std::string>("postgres");
|
|
db_config.timeout = database_section["timeout"].value_or<int>(30);
|
|
db_config.ssl = database_section["ssl"].value_or<bool>(false);
|
|
|
|
// Parse pool section if present
|
|
auto pool_section = database_section["pool"];
|
|
if (pool_section) {
|
|
db_config.min_connections = pool_section["min_connections"].value_or<int>(1);
|
|
db_config.max_connections = pool_section["max_connections"].value_or<int>(10);
|
|
} else {
|
|
db_config.min_connections = 1;
|
|
db_config.max_connections = 10;
|
|
}
|
|
|
|
RCLCPP_INFO(logger_, "[CFG] database config parsed - %s:%s@%s:%d",
|
|
db_config.user.c_str(),
|
|
db_config.dbname.c_str(),
|
|
db_config.host.c_str(),
|
|
db_config.port
|
|
);
|
|
|
|
return db_config;
|
|
}
|
|
|
|
} // namespace assignments::two
|