From 0c6889dcff9a71e1372f7333862ae7be97e9ac34 Mon Sep 17 00:00:00 2001 From: Mars Ultor Date: Sat, 25 Oct 2025 18:45:36 -0500 Subject: [PATCH] database stuff done --- src/daemon-utils/database-utils.cpp | 116 ++++++++++++++++++++++++++++ src/daemon-utils/database-utils.hpp | 31 ++++++++ src/daemon-utils/socket-manager.cpp | 4 - src/daemon-utils/socket-manager.hpp | 4 +- 4 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 src/daemon-utils/database-utils.cpp create mode 100644 src/daemon-utils/database-utils.hpp diff --git a/src/daemon-utils/database-utils.cpp b/src/daemon-utils/database-utils.cpp new file mode 100644 index 0000000..fb63ac9 --- /dev/null +++ b/src/daemon-utils/database-utils.cpp @@ -0,0 +1,116 @@ +#include "database-utils.hpp" +#include + +namespace database_utils { + +TrackerDb::TrackerDb(std::shared_ptr connection) + : conn_(std::move(connection)) {} + +void TrackerDb::initialize_schema() { + conn_->Query(R"( + CREATE TABLE IF NOT EXISTS trackers ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + tracker_id VARCHAR UNIQUE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ); + )"); + + conn_->Query(R"( + CREATE TABLE IF NOT EXISTS access_logs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + tracker_fk INTEGER REFERENCES trackers(id) ON DELETE CASCADE, + accessed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + ip_address VARCHAR + ); + )"); +} + +bool TrackerDb::tracker_exists(const std::string& tracker_id) { + auto stmt = conn_->Prepare("SELECT COUNT(*) FROM trackers WHERE tracker_id = $1;"); + auto res = stmt->Execute(tracker_id); + if (res->HasError()) throw std::runtime_error(res->GetError()); + int64_t count = res->GetValue(0, 0); + return count > 0; +} + +void TrackerDb::add_tracker(const std::string& tracker_id) { + if (tracker_exists(tracker_id)) return; + auto stmt = conn_->Prepare("INSERT INTO trackers (tracker_id) VALUES ($1);"); + auto res = stmt->Execute(tracker_id); + if (res->HasError()) throw std::runtime_error(res->GetError()); +} + +void TrackerDb::log_access(const std::string& tracker_id, const std::string& ip_address) { + if (!tracker_exists(tracker_id)) add_tracker(tracker_id); + + auto stmt = conn_->Prepare(R"( + INSERT INTO access_logs (tracker_fk, ip_address) + SELECT id, $2 FROM trackers WHERE tracker_id = $1; + )"); + auto res = stmt->Execute(tracker_id, ip_address); + if (res->HasError()) throw std::runtime_error(res->GetError()); +} + +std::vector> TrackerDb::get_all_accesses() { + auto res = conn_->Query(R"( + SELECT t.tracker_id, l.accessed_at, l.ip_address + FROM access_logs l + JOIN trackers t ON t.id = l.tracker_fk + ORDER BY l.accessed_at DESC; + )"); + if (res->HasError()) throw std::runtime_error(res->GetError()); + + std::vector> out; + out.reserve(res->RowCount()); + for (std::size_t i = 0; i < res->RowCount(); ++i) { + out.emplace_back( + res->GetValue(0, i), + res->GetValue(1, i), + res->GetValue(2, i) + ); + } + return out; +} + +std::vector> TrackerDb::get_accesses_for(const std::string& tracker_id) { + auto stmt = conn_->Prepare(R"( + SELECT accessed_at, ip_address + FROM access_logs l + JOIN trackers t ON t.id = l.tracker_fk + WHERE t.tracker_id = $1 + ORDER BY accessed_at DESC; + )"); + auto res = stmt->Execute(tracker_id); + if (res->HasError()) throw std::runtime_error(res->GetError()); + + std::vector> out; + out.reserve(res->RowCount()); + for (std::size_t i = 0; i < res->RowCount(); ++i) { + out.emplace_back( + res->GetValue(0, i), + res->GetValue(1, i) + ); + } + return out; +} + +std::size_t TrackerDb::get_access_count(const std::string& tracker_id) { + auto stmt = conn_->Prepare(R"( + SELECT COUNT(*) + FROM access_logs l + JOIN trackers t ON t.id = l.tracker_fk + WHERE t.tracker_id = $1; + )"); + auto res = stmt->Execute(tracker_id); + if (res->HasError()) throw std::runtime_error(res->GetError()); + return static_cast(res->GetValue(0, 0)); +} + +void TrackerDb::remove_tracker(const std::string& tracker_id) { + auto stmt = conn_->Prepare("DELETE FROM trackers WHERE tracker_id = $1;"); + auto res = stmt->Execute(tracker_id); + if (res->HasError()) throw std::runtime_error(res->GetError()); +} + +} // namespace database_utils + diff --git a/src/daemon-utils/database-utils.hpp b/src/daemon-utils/database-utils.hpp new file mode 100644 index 0000000..aa1c30e --- /dev/null +++ b/src/daemon-utils/database-utils.hpp @@ -0,0 +1,31 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace database_utils { + +class TrackerDb { +public: + explicit TrackerDb(std::shared_ptr connection); + ~TrackerDb() = default; + + void initialize_schema(); + + bool tracker_exists(const std::string& tracker_id); + void add_tracker(const std::string& tracker_id); + void log_access(const std::string& tracker_id, const std::string& ip_address); + + std::vector> get_all_accesses(); + std::vector> get_accesses_for(const std::string& tracker_id); + std::size_t get_access_count(const std::string& tracker_id); + void remove_tracker(const std::string& tracker_id); + +private: + std::shared_ptr conn_; +}; + +} // namespace database_utils + diff --git a/src/daemon-utils/socket-manager.cpp b/src/daemon-utils/socket-manager.cpp index 68f9fd6..1337d9f 100644 --- a/src/daemon-utils/socket-manager.cpp +++ b/src/daemon-utils/socket-manager.cpp @@ -83,8 +83,4 @@ void start_http_server(std::uint16_t port, std::shared_ptr c } } -namespace database_utils { - void initialize_db(std::shared_ptr connection){ -} -} diff --git a/src/daemon-utils/socket-manager.hpp b/src/daemon-utils/socket-manager.hpp index 28b449a..ce583d3 100644 --- a/src/daemon-utils/socket-manager.hpp +++ b/src/daemon-utils/socket-manager.hpp @@ -10,6 +10,4 @@ namespace socket_manager { void start_http_server(std::uint16_t port, std::shared_ptr connection ); } -namespace database_utils { - void initialize_db(std::shared_ptr connection); -} +