added new database

This commit is contained in:
Lukas Forsberg 2025-11-16 17:03:18 +01:00
parent dd56a8d57e
commit d1c95d2b8b
10 changed files with 77 additions and 43 deletions

View File

@ -1,6 +1,8 @@
cmake_minimum_required(VERSION 3.10)
project(CrowHTMX)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(TARGET_NAME lf-server-admin-panel )
set(CMAKE_CXX_STANDARD 23)
@ -31,6 +33,9 @@ foreach(file IN LISTS TEMPLATE_FILES)
configure_file("${file}" "${CMAKE_BINARY_DIR}/${rel_path}" COPYONLY)
endforeach()
add_compile_options(-Wno-deprecated-declarations)
add_compile_options(-Wno-deprecated-literal-operator)
# Use Crow from system include (installed via yay -S crow + asio)
include_directories(/usr/include src src/htmx src/shadowrun src/database src/login)

View File

@ -12,6 +12,14 @@ Database::~Database() {
sqlite3_close(m_db);
}
string Database::currentTime(){
auto now = std::chrono::system_clock::now();
std::time_t t = std::chrono::system_clock::to_time_t(now);
std::stringstream ss;
ss << std::put_time(std::gmtime(&t), "%Y-%m-%d %H:%M:%S");
return ss.str();
}
sqlite3_stmt* Database::prepareStmt(const string& sql){
sqlite3_stmt* stmt = nullptr;
if (sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) {

View File

@ -17,7 +17,7 @@ class Database {
typedef std::vector<std::variant<int64_t, std::string>> QueryData;
public:
static constexpr std::string dbFile = "app.db";
static constexpr std::string dbFile = "test.db";
Database();
~Database();
@ -30,6 +30,8 @@ public:
std::set<std::string> getStrSet(const std::string& sql);
static std::string currentTime();
template <typename T>
std::optional<T> getSqlData(sqlite3_stmt* stmt, int i)
{

View File

@ -7,7 +7,6 @@
#include <string>
class HtmxObject {
public:

View File

@ -1,6 +1,6 @@
#include "login.hpp"
#include "sodium.h"
#include "database.hpp"
#include "databasepool.h"
#include "utils.hpp"
#include <iostream>
namespace login

View File

@ -1,7 +1,5 @@
#include <crow.h>
#include <cstdlib>
#include <string>
#include <print>
#include <optional>
#include "json_settings.h"
#include "htmx_helper.h"

View File

@ -5,6 +5,7 @@
#include "ShadowrunDb.hpp"
#include "login.hpp"
#include <format>
#include <set>
#include <vector>
using namespace std;
@ -83,7 +84,7 @@ void initApi(crow::SimpleApp& app)
auto query = crow::query_string(req.url_params);
std::string name = query.get("name") ? query.get("name") : "";
auto data = getCharacterData(getKeyOfCharacter(name));
auto data = getCharacterDataMap(getKeyOfCharacter(name));
return crow::response{ShadowrunCharacterForm(data).htmx()};
}));
@ -98,8 +99,8 @@ void initApi(crow::SimpleApp& app)
<< "<label>Character Name: "
<< "<select name='name'>";
for (const auto& name : characters) {
html << "<option value='" << name << "'>" << name << "</option>";
for (const auto& character : characters) {
html << "<option value='" << character.name << "'>" << character.name << "</option>";
}
html << "</select></label>"

View File

@ -4,7 +4,7 @@
#include "htmx/HtmxObject.h"
#include <map>
#include <string>
#include <vector>
class ShadowrunCharacterForm : public HtmxObject {
public:

View File

@ -1,4 +1,8 @@
#include "ShadowrunDb.hpp"
#include <format>
#include <functional>
#include <map>
#include "database.hpp"
#include "databasepool.h"
#include "crow.h"
#include "sqlite_orm.h"
@ -19,52 +23,69 @@ int64_t getKeyOfCharacter(const string& name){
if (!character.empty()) {
return character[0].id;
} else {
return db->insert(ShadowrunCharacter{-1, name, ""});
return db->insert(ShadowrunCharacter{-1, name, Database::currentTime()});
}
}
bool storeCharacterData(int64_t characterKey, vector<pair<const string, const string>>& idValues){
auto sql = format("SELECT name FROM shadowrun_data WHERE character_id = {};", characterKey);
auto db = Database();
if (!db.open())
return false;
auto set = db.getStrSet(sql);
auto characterData = getCharacterData(characterKey);
std::map<string, ShadowrunData*> dataMap;
for(auto& data : characterData) {
dataMap[data.name] = &data;
}
auto db = dbpool.acquire();
for (auto& idValue : idValues) {
const string& name = idValue.first;
const string& value = idValue.second;
// update if already exist
if(set.contains(idValue.first)){
auto sql = format("UPDATE shadowrun_data SET value = '{}', updated_at = CURRENT_TIMESTAMP WHERE name = '{}' AND character_id = {}", idValue.second, idValue.first, characterKey);
if (!db.exec(sql)){
CROW_LOG_WARNING << "Failed to update " << idValue.first << " with " << idValue.second;
}
auto it = dataMap.find(name);
if(it != dataMap.end()){
db->update_all(
sqlite_orm::set(
assign(&ShadowrunData::value, idValue.second),
assign(&ShadowrunData::updated_at, Database::currentTime())
),
where(
c(&ShadowrunData::name) == name and
c(&ShadowrunData::character_id) == characterKey
)
);
} else {
auto sql = format("INSERT INTO shadowrun_data (character_id, name, value) "
"VALUES ({}, '{}', '{}')", characterKey, idValue.first, idValue.second);
if (!db.exec(sql)){
CROW_LOG_WARNING << "Failed to insert " << idValue.first << " with " << idValue.second;
}
ShadowrunData entry {
.id = -1,
.character_id = static_cast<int>(characterKey),
.name = name,
.value = value,
.created_at = Database::currentTime(),
.updated_at = "",
};
db->insert(entry);
}
}
return true;
}
std::set<std::string> getCharacters(){
string sql = "SELECT name FROM shadowrun_characters;";
auto db = Database();
if (!db.open())
return std::set<std::string>();
return db.getStrSet(sql);
std::vector<ShadowrunCharacter> getCharacters(){
auto db = dbpool.acquire();
return db->get_all<ShadowrunCharacter>();
}
std::map<std::string, std::string> getCharacterData(int64_t characterKey) {
std::string sql = "SELECT name, value FROM shadowrun_data WHERE character_id = ?;";
auto db = Database();
if (!db.open())
return std::map<std::string, std::string>();
std::map<string, string> getCharacterDataMap(int64_t characterKey){
auto characterData = getCharacterData(characterKey);
std::map<string, string> dataMap;
for(auto& data : characterData) {
dataMap[data.name] = data.value;
}
return dataMap;
}
return db.getStrMap(sql, {characterKey});
vector<ShadowrunData> getCharacterData(int64_t characterKey) {
auto db = dbpool.acquire();
return db->get_all<ShadowrunData>(
where(c(&ShadowrunData::character_id) == characterKey)
);
}
}

View File

@ -4,9 +4,8 @@
#include <cstdint>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <optional>
namespace shadowrun {
struct ShadowrunCharacter {
int id;
@ -25,9 +24,10 @@ namespace shadowrun {
int64_t getKeyOfCharacter(const std::string& name);
bool storeCharacterData(int64_t characterKey, std::vector<std::pair<const std::string, const std::string>>& idValues);
std::set<std::string> getCharacters();
std::vector<ShadowrunCharacter> getCharacters();
std::map<std::string, std::string> getCharacterData(int64_t characterKey);
std::vector<ShadowrunData> getCharacterData(int64_t characterKey);
std::map<std::string, std::string> getCharacterDataMap(int64_t characterKey);
}
#endif // __SHADOWRUNDB_H__