first draft is working

This commit is contained in:
2025-11-22 19:41:46 +01:00
parent e4289ee1ac
commit b3c4395fac
12 changed files with 1767 additions and 119 deletions

File diff suppressed because it is too large Load Diff

25580
src/json.hpp

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,9 @@
#include "ShadowrunApi.hpp"
#include "ShadowrunCharacterForm.hpp"
#include "ShadowrunDb.hpp"
#include "login.hpp"
#include <format>
#include <set>
#include <vector>
using namespace std;
@@ -113,7 +111,10 @@ void initApi(crow::SimpleApp& app)
CROW_ROUTE(app, "/api/shadowrun/characters")
([&]() {
auto characters = getCharacters();
return utils::toJsonArray(characters);
auto res =
crow::response(200, utils::toJsonArray(characters));
res.set_header("Content-Type", "application/json");
return res;
});
CROW_ROUTE(app, "/api/shadowrun/characters").methods("POST"_method)
@@ -124,7 +125,9 @@ void initApi(crow::SimpleApp& app)
if(id > 0){
auto character = getChracter(id);
if (character.has_value()){
return crow::response(200, nlohmann::json(character.value()).dump());
auto res = crow::response(200, nlohmann::json(character.value()).dump());
res.set_header("Content-Type", "application/json");
return res;
}
}
return crow::response(405, "Failed to create character");
@@ -135,15 +138,53 @@ void initApi(crow::SimpleApp& app)
auto optCharacter = getChracter(id);
if (!optCharacter.has_value())
return crow::response(404, "Character not found");
return crow::response(200, nlohmann::json(optCharacter.value()).dump());
auto res = crow::response(200, nlohmann::json(optCharacter.value()).dump());
res.set_header("Content-Type", "application/json");
return res;
});
CROW_ROUTE(app, "/api/shadowrun/characters_data/<int>")
([&](int id) {
auto character_data = getChracterData(id);
if (!character_data.empty())
return crow::response(405, "No character data found");
return crow::response(200, utils::toJsonArray(character_data));
nlohmann::json j;
const auto characterData = getChracterData(id);
if(characterData.empty())
return crow::response(405, "Character not found");
for(const auto& data : characterData ){
const auto& key = magic_enum::enum_cast<Type>(data.type);
if(key.has_value()){
auto res = utils::parseJson(data.json);
if(res){
j[magic_enum::enum_name(key.value())] = res.value();
} else {
CROW_LOG_ERROR << "Failed to parse json: " << res.error();
}
} else {
CROW_LOG_ERROR << "Read invalid type from database: " << data.type;
}
}
auto res = crow::response(200, j.dump());
res.set_header("Content-Type", "application/json");
return res;
});
CROW_ROUTE(app, "/api/shadowrun/characters_data/<int>").methods("POST"_method)
([&](const crow::request& req, int id) {
nlohmann::json j = nlohmann::json::parse(req.body);
for (auto type : magic_enum::enum_values<Type>()) {
const auto& key = magic_enum::enum_name(type);
if (j.contains(key)){
storeCharacterData(id, type, j[key].dump());
}
}
auto res = crow::response(200, "Saved Character data");
return res;
//return crow::response(405, ret.error());
});
}

View File

@@ -1,13 +1,7 @@
#include "ShadowrunDb.hpp"
#include <format>
#include <functional>
#include <map>
#include <optional>
#include "database.hpp"
#include "databasepool.h"
#include "crow.h"
#include "utils.hpp"
#include "sqlite_orm.h"
using namespace std;
using namespace sqlite_orm;
@@ -28,53 +22,11 @@ int64_t createCharacter(const string& name){
if (!character.empty()) {
return character[0].id;
} else {
auto c = createShadowrunCharacter(name);
auto c = newShadowrunCharacter(name);
return db->insert(c);
}
}
/*
bool storeCharacterData(int64_t characterKey, vector<pair<const string, const string>>& idValues){
auto characterData = getCharacterData(characterKey);
std::map<string, ShadowrunCharacterData*> 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
auto it = dataMap.find(name);
if(it != dataMap.end()){
db->update_all(
sqlite_orm::set(
assign(&ShadowrunData::value, idValue.second),
assign(&ShadowrunData::updated_at, utils::currentTime())
),
where(
c(&ShadowrunData::name) == name and
c(&ShadowrunData::character_id) == characterKey
)
);
} else {
ShadowrunData entry {
.id = -1,
.character_id = static_cast<int>(characterKey),
.name = name,
.value = value,
.created_at = utils::currentTime(),
.updated_at = "",
};
db->insert(entry);
}
}
return true;
}
*/
std::vector<ShadowrunCharacter> getCharacters(){
auto db = dbpool.acquire();
return db->get_all<ShadowrunCharacter>();
@@ -105,8 +57,31 @@ vector<ShadowrunCharacterData> getChracterData(int character_id)
return characterData;
}
int storeCharacterData(const ShadowrunCharacterData& data)
{
int storeCharacterData(int characterId, const Type type, const string& json){
auto db = dbpool.acquire();
auto characterData = db->get_all<ShadowrunCharacterData>(
where(
(c(&ShadowrunCharacterData::character_id) == characterId) and
(c(&ShadowrunCharacterData::type) == static_cast<int>(type)))
);
if(characterData.empty()){
ShadowrunCharacterData character = newShadowrunCharacterData(characterId, type, json);
return db->insert(character);
}
else {
if (characterData.size() > 1){
CROW_LOG_ERROR << "Character ID: " << characterId << "has mote than 1 type: " << magic_enum::enum_name(type);
}
auto& character = characterData[0];
character.json = json;
character.updated_at = utils::currentTime();
db->update(character);
return character.id;
}
}
int storeCharacterData(const ShadowrunCharacterData& data){
auto db = dbpool.acquire();
auto characterData = db->get_optional<ShadowrunCharacterData>(data.id);
@@ -119,13 +94,4 @@ int storeCharacterData(const ShadowrunCharacterData& data)
}
}
/*
vector<ShadowrunData> getCharacterData(int64_t characterKey) {
auto db = dbpool.acquire();
return db->get_all<ShadowrunData>(
where(c(&ShadowrunData::character_id) == characterKey)
);
}
*/
}

View File

@@ -7,8 +7,17 @@
#include <optional>
#include "json.hpp"
#include "utils.hpp"
#include "sqlite_orm.h"
#include "magic_enum.hpp"
namespace shadowrun {
enum class Type {
Unknown = 0,
Info = 1,
Attributes = 2,
Skills = 3,
};
struct ShadowrunCharacter {
int id;
std::string name;
@@ -17,26 +26,40 @@ namespace shadowrun {
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ShadowrunCharacter, id, name, created_at)
inline ShadowrunCharacter createShadowrunCharacter(const std::string& name){
inline ShadowrunCharacter newShadowrunCharacter(const std::string& name){
return ShadowrunCharacter {-1, name, utils::currentTime()};
}
struct ShadowrunCharacterData {
int id;
int character_id;
std::string type;
int type;
std::string json;
std::string created_at;
std::string updated_at;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ShadowrunCharacterData, id, character_id, type, json, created_at, updated_at);
inline ShadowrunCharacterData newShadowrunCharacterData(int character_id, Type type, const std::string json){
std::string time = utils::currentTime();
return ShadowrunCharacterData {
.id = -1,
.character_id = character_id,
.type = static_cast<int>(type),
.json = json,
.created_at = time,
.updated_at = time,
};
}
int64_t createCharacter(const std::string& name);
bool storeCharacterData(int64_t characterKey, std::vector<std::pair<const std::string, const std::string>>& idValues);
std::vector<ShadowrunCharacter> getCharacters();
std::optional<ShadowrunCharacter> getChracter(int id);
std::vector<ShadowrunCharacterData> getChracterData(int character_id);
int storeCharacterData(const ShadowrunCharacterData& data);
int storeCharacterData(int characterId, const Type type, const std::string& json);
}
#endif // __SHADOWRUNDB_H__

View File

@@ -143,4 +143,12 @@ string currentTime(){
return ss.str();
}
std::expected<nlohmann::json, std::string> parseJson(const std::string& input) {
try {
return nlohmann::json::parse(input);
}
catch (const nlohmann::json::exception& e) {
return std::unexpected(e.what());
}
}
}

View File

@@ -6,8 +6,8 @@
#include <cstdint>
#include <filesystem>
#include <map>
#include <expected>
#include "json.hpp"
namespace utils {
std::map<std::string, std::string> parseBody(const std::string& body);
@@ -33,6 +33,20 @@ namespace utils {
}
return arr.dump();
}
std::expected<nlohmann::json, std::string> parseJson(const std::string& input);
template <typename T>
std::expected<T, std::string> fromJson(const std::string& input) {
try {
return nlohmann::json::parse(input).get<T>();
}
catch (const nlohmann::json::exception& e) {
return std::unexpected(e.what());
}
}
}
#endif