database stuff done
This commit is contained in:
116
src/daemon-utils/database-utils.cpp
Normal file
116
src/daemon-utils/database-utils.cpp
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
#include "database-utils.hpp"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace database_utils {
|
||||||
|
|
||||||
|
TrackerDb::TrackerDb(std::shared_ptr<duckdb::Connection> 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<int64_t>(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<std::tuple<std::string, std::string, std::string>> 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<std::tuple<std::string, std::string, std::string>> out;
|
||||||
|
out.reserve(res->RowCount());
|
||||||
|
for (std::size_t i = 0; i < res->RowCount(); ++i) {
|
||||||
|
out.emplace_back(
|
||||||
|
res->GetValue<std::string>(0, i),
|
||||||
|
res->GetValue<std::string>(1, i),
|
||||||
|
res->GetValue<std::string>(2, i)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::tuple<std::string, std::string>> 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<std::tuple<std::string, std::string>> out;
|
||||||
|
out.reserve(res->RowCount());
|
||||||
|
for (std::size_t i = 0; i < res->RowCount(); ++i) {
|
||||||
|
out.emplace_back(
|
||||||
|
res->GetValue<std::string>(0, i),
|
||||||
|
res->GetValue<std::string>(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<std::size_t>(res->GetValue<int64_t>(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
|
||||||
|
|
||||||
31
src/daemon-utils/database-utils.hpp
Normal file
31
src/daemon-utils/database-utils.hpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <duckdb.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace database_utils {
|
||||||
|
|
||||||
|
class TrackerDb {
|
||||||
|
public:
|
||||||
|
explicit TrackerDb(std::shared_ptr<duckdb::Connection> 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<std::tuple<std::string, std::string, std::string>> get_all_accesses();
|
||||||
|
std::vector<std::tuple<std::string, std::string>> 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<duckdb::Connection> conn_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace database_utils
|
||||||
|
|
||||||
@@ -83,8 +83,4 @@ void start_http_server(std::uint16_t port, std::shared_ptr<duckdb::Connection> c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace database_utils {
|
|
||||||
void initialize_db(std::shared_ptr<duckdb::Connection> connection){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,6 +10,4 @@ namespace socket_manager {
|
|||||||
void start_http_server(std::uint16_t port, std::shared_ptr<duckdb::Connection> connection );
|
void start_http_server(std::uint16_t port, std::shared_ptr<duckdb::Connection> connection );
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace database_utils {
|
|
||||||
void initialize_db(std::shared_ptr<duckdb::Connection> connection);
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user