105 lines
3.2 KiB
C++
105 lines
3.2 KiB
C++
#include "database.h"
|
|
#include <pqxx/pqxx>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
#include <string>
|
|
#include <iostream>
|
|
|
|
Database::Database(const std::string &conninfo)
|
|
{
|
|
try {
|
|
connection_ = std::make_unique<pqxx::connection>(conninfo);
|
|
if (!connection_->is_open()) {
|
|
throw std::runtime_error("Konnte DB-Verbindung nicht öffnen!");
|
|
}
|
|
} catch (const std::exception &e) {
|
|
std::cerr << "[Database] Fehler beim Verbinden: " << e.what() << std::endl;
|
|
|
|
|
|
throw;
|
|
}
|
|
}
|
|
|
|
std::vector<std::map<std::string, std::string>>
|
|
Database::query(const std::string &sql)
|
|
{
|
|
std::vector<std::map<std::string, std::string>> rows;
|
|
try {
|
|
pqxx::work txn(*connection_);
|
|
pqxx::result r = txn.exec(sql);
|
|
txn.commit();
|
|
for (auto row : r) {
|
|
std::map<std::string, std::string> oneRow;
|
|
for (auto f = 0u; f < row.size(); f++) {
|
|
std::string colName = r.column_name(f);
|
|
std::string value = row[f].c_str() ? row[f].c_str() : "";
|
|
oneRow[colName] = value;
|
|
}
|
|
rows.push_back(std::move(oneRow));
|
|
}
|
|
} catch (const std::exception &ex) {
|
|
std::cerr << "[Database] query-Fehler: " << ex.what() << "\nSQL: " << sql << std::endl;
|
|
}
|
|
return rows;
|
|
}
|
|
|
|
void Database::prepare(const std::string &stmtName, const std::string &sql)
|
|
{
|
|
try {
|
|
pqxx::work txn(*connection_);
|
|
txn.conn().prepare(stmtName, sql);
|
|
txn.commit();
|
|
} catch (const std::exception &ex) {
|
|
std::cerr << "[Database] prepare-Fehler: " << ex.what()
|
|
<< "\nSQL: " << sql << std::endl;
|
|
}
|
|
}
|
|
|
|
Database::FieldList Database::execute(const std::string &stmtName, const std::vector<std::string> ¶ms) {
|
|
std::vector<std::unordered_map<std::string, std::string>> rows;
|
|
try {
|
|
pqxx::work txn(*connection_);
|
|
pqxx::prepare::invocation inv = txn.prepared(stmtName);
|
|
for (auto &p : params) {
|
|
inv(p);
|
|
}
|
|
pqxx::result r = inv.exec();
|
|
txn.commit();
|
|
for (const auto &row : r) {
|
|
std::unordered_map<std::string, std::string> mapRow;
|
|
for (pqxx::row::size_type i = 0; i < row.size(); ++i) {
|
|
std::string colName = r.column_name(i);
|
|
mapRow[colName] = row[i].c_str() ? row[i].c_str() : "";
|
|
}
|
|
rows.push_back(std::move(mapRow));
|
|
}
|
|
}
|
|
catch (const std::exception &ex) {
|
|
std::cerr << "[Database] execute-Fehler: " << ex.what()
|
|
<< "\nStatement: " << stmtName << std::endl;
|
|
}
|
|
|
|
return rows;
|
|
}
|
|
|
|
void Database::remove(const std::string &stmtName) {
|
|
pqxx::work txn(*connection_);
|
|
txn.conn().unprepare(stmtName);
|
|
txn.commit();
|
|
}
|
|
|
|
bool Database::isValid() const {
|
|
try {
|
|
if (!connection_ || !connection_->is_open()) {
|
|
return false;
|
|
}
|
|
pqxx::work txn(*connection_);
|
|
txn.exec("SELECT 1"); // Einfacher Ping
|
|
txn.commit();
|
|
return true;
|
|
} catch (const std::exception &ex) {
|
|
std::cerr << "[Database] Verbindung ungültig: " << ex.what() << "\n";
|
|
return false;
|
|
}
|
|
}
|