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 );
|
||||
}
|
||||
|
||||
namespace database_utils {
|
||||
void initialize_db(std::shared_ptr<duckdb::Connection> connection);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user