Possible to load basic data from the database
This commit is contained in:
parent
69f7f625f8
commit
397189c259
99
.vscode/settings.json
vendored
99
.vscode/settings.json
vendored
@ -1,6 +1,103 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"text_encoding": "cpp",
|
||||
"thread": "cpp"
|
||||
"thread": "cpp",
|
||||
"deque": "cpp",
|
||||
"string": "cpp",
|
||||
"vector": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"hash_map": "cpp",
|
||||
"strstream": "cpp",
|
||||
"barrier": "cpp",
|
||||
"bit": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cctype": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"compare": "cpp",
|
||||
"complex": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"coroutine": "cpp",
|
||||
"csetjmp": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cuchar": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"exception": "cpp",
|
||||
"expected": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"regex": "cpp",
|
||||
"source_location": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"flat_map": "cpp",
|
||||
"flat_set": "cpp",
|
||||
"format": "cpp",
|
||||
"fstream": "cpp",
|
||||
"future": "cpp",
|
||||
"generator": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"latch": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"print": "cpp",
|
||||
"queue": "cpp",
|
||||
"ranges": "cpp",
|
||||
"scoped_allocator": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"span": "cpp",
|
||||
"spanstream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stack": "cpp",
|
||||
"stacktrace": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stdfloat": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"syncstream": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp"
|
||||
}
|
||||
}
|
||||
@ -67,7 +67,8 @@ add_executable(${TARGET_NAME}
|
||||
src/shadowrun/ShadowrunCharacterForm.cpp
|
||||
src/shadowrun/ShadowrunApi.cpp
|
||||
src/shadowrun/ShadowrunApi.hpp
|
||||
|
||||
src/shadowrun/ShadowrunDb.cpp
|
||||
src/shadowrun/ShadowrunDb.hpp
|
||||
|
||||
)
|
||||
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
#include "crow.h"
|
||||
#include "database.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Database::Database() :
|
||||
m_db(nullptr)
|
||||
{}
|
||||
@ -9,6 +11,15 @@ Database::~Database() {
|
||||
sqlite3_close(m_db);
|
||||
}
|
||||
|
||||
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) {
|
||||
CROW_LOG_ERROR << "Failed to prepare statement: " << sqlite3_errmsg(m_db);
|
||||
return nullptr;
|
||||
}
|
||||
return stmt;
|
||||
}
|
||||
|
||||
bool Database::exec(const char* sqlQuery) {
|
||||
char* errmsg = nullptr;
|
||||
int rc = sqlite3_exec(m_db, sqlQuery, nullptr, nullptr, &errmsg);
|
||||
@ -20,13 +31,72 @@ bool Database::exec(const char* sqlQuery) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Database::exec(const std::string& sqlQuery)
|
||||
{
|
||||
exec(sqlQuery.c_str());
|
||||
bool Database::exec(const std::string& sqlQuery){
|
||||
return exec(sqlQuery.c_str());
|
||||
}
|
||||
|
||||
map<string, string> Database::getStrMap(const string& sql){
|
||||
sqlite3_stmt* stmt = prepareStmt(sql);
|
||||
map<string, string> map;
|
||||
if (stmt == nullptr)
|
||||
return map;
|
||||
|
||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
string key = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
|
||||
string value = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
|
||||
map[key] = value;
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
return map;
|
||||
}
|
||||
|
||||
set<string> Database::getStrSet(const string& sql){
|
||||
sqlite3_stmt* stmt = prepareStmt(sql);
|
||||
set<string> vec;
|
||||
if (stmt == nullptr)
|
||||
return vec;
|
||||
|
||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
string s = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
|
||||
vec.insert(s);
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
return vec;
|
||||
}
|
||||
|
||||
std::optional<int64_t> Database::getInt(const char* sql) {
|
||||
sqlite3_stmt* stmt = prepareStmt(sql);
|
||||
if (stmt == nullptr)
|
||||
return {};
|
||||
|
||||
std::optional<int64_t> id;
|
||||
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
id = sqlite3_column_int64(stmt, 0);
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
return id;
|
||||
}
|
||||
|
||||
std::optional<int64_t> Database::insert(const char* sql) {
|
||||
sqlite3_stmt* stmt = prepareStmt(sql);
|
||||
if (stmt == nullptr)
|
||||
return {};
|
||||
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||
CROW_LOG_ERROR << "Insert failed: " << sqlite3_errmsg(m_db);
|
||||
sqlite3_finalize(stmt);
|
||||
return {};
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
return sqlite3_last_insert_rowid(m_db);
|
||||
}
|
||||
|
||||
bool Database::open(){
|
||||
int rc = sqlite3_open("example.db", &m_db);
|
||||
int rc = sqlite3_open("app.db", &m_db);
|
||||
if (rc) {
|
||||
CROW_LOG_ERROR << "Can't open database: " << sqlite3_errmsg(m_db);
|
||||
return false;
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include <string>
|
||||
|
||||
#include <optional>
|
||||
#include <set>
|
||||
class Database {
|
||||
|
||||
public:
|
||||
@ -14,7 +15,18 @@ public:
|
||||
bool exec(const char* sqlQuery);
|
||||
bool exec(const std::string& sqlQuery);
|
||||
|
||||
/// returns true if the sql statment returns at least one row
|
||||
std::optional<int64_t> getInt(const char* sql);
|
||||
|
||||
std::optional<int64_t> insert(const char* sql);
|
||||
|
||||
std::set<std::string> getStrSet(const std::string& sql);
|
||||
|
||||
std::map<std::string, std::string> Database::getStrMap(const std::string& sql);
|
||||
|
||||
private:
|
||||
sqlite3_stmt* prepareStmt(const std::string& sql);
|
||||
|
||||
sqlite3* m_db;
|
||||
};
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ HtmxShAttributeList::HtmxShAttributeList(const std::string& id, const vector<str
|
||||
html += format("<h2>{}</h2>", id);
|
||||
html += "<div class='grid'>";
|
||||
for (auto& item : itemList){
|
||||
string item_id = utils::to_id_format(id + "_" + item);
|
||||
string item_id = utils::to_id_format(format("{}_{}", id, item));
|
||||
|
||||
html += format("<label>{}:<input type='text' name='{}'></label>", item, item_id);
|
||||
}
|
||||
@ -19,8 +19,15 @@ HtmxShAttributeList::HtmxShAttributeList(const std::string& id, const std::vecto
|
||||
html += format("<h2>{}</h2>", id);
|
||||
html += "<div class='grid'>";
|
||||
for (auto& item : itemValueList){
|
||||
string item_id = utils::to_id_format(id + "_" + item.first);
|
||||
string item_id = utils::to_id_format(format("{}_{}", id, item));
|
||||
html += format("<label>{}:<input type='text' name='{}' value='{}'></label>", item, item_id, item.second);
|
||||
}
|
||||
html += "</div>";
|
||||
}
|
||||
|
||||
void HtmxShAttributeList::genIds(std::vector<std::string>& vec, const std::string& id, const std::vector<std::string>& itemList)
|
||||
{
|
||||
for (auto& item : itemList){
|
||||
vec.push_back(utils::to_id_format(format("{}_{}", id, item)));
|
||||
}
|
||||
}
|
||||
@ -13,6 +13,8 @@ public:
|
||||
|
||||
// create new item list where each item as a value
|
||||
HtmxShAttributeList(const std::string& id, const std::vector<std::pair<std::string, std::string>>& itemValueList);
|
||||
|
||||
static void genIds(std::vector<std::string>& vec, const std::string& id, const std::vector<std::string>& itemList);
|
||||
};
|
||||
|
||||
#endif // HTMXSHATTRIBUTELIST_H
|
||||
@ -26,3 +26,10 @@ HtmxShCondition::HtmxShCondition(std::string id, size_t nbrOfBoxes)
|
||||
}
|
||||
html += "</div></div>";
|
||||
}
|
||||
|
||||
void HtmxShCondition::genIds(std::vector<std::string>& vec, std::string id, size_t nbrOfBoxes)
|
||||
{
|
||||
for (int i = 0; i < nbrOfBoxes; i++){
|
||||
vec.push_back(utils::to_id_format(format("{}_{}",id, i)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,12 +2,15 @@
|
||||
#define __HTMXSHCONDITION_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "HtmxObject.h"
|
||||
|
||||
class HtmxShCondition : public HtmxObject {
|
||||
|
||||
public:
|
||||
HtmxShCondition(std::string id, size_t nbrOfBoxes);
|
||||
|
||||
static void genIds(std::vector<std::string>& vec, std::string id, size_t nbrOfBoxes);
|
||||
};
|
||||
|
||||
#endif // __HTMXSHCONDITION_H__
|
||||
@ -40,4 +40,13 @@ HtmxShItemList::HtmxShItemList(const std::string& id, const std::vector<std::pai
|
||||
|
||||
html += "</div></div>";
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
void HtmxShItemList::genIds(std::vector<std::string>& vec, const std::string& id, const std::vector<std::string>& columns, size_t size)
|
||||
{
|
||||
for (size_t i = 0; i < size; i++){
|
||||
for (auto& col : columns){
|
||||
vec.push_back(utils::to_id_format(format("{}_{}_{}", id, i, col)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,8 @@ public:
|
||||
|
||||
// create new item list where each item as a value
|
||||
HtmxShItemList(const std::string& id, const std::vector<std::pair<std::string, std::string>>& itemValueList);
|
||||
|
||||
static void genIds(std::vector<std::string>& vec, const std::string& id, const std::vector<std::string>& columns, size_t size);
|
||||
};
|
||||
|
||||
#endif // HTMXSHITEMLIST_H
|
||||
@ -2,66 +2,71 @@
|
||||
|
||||
#include "ShadowrunApi.hpp"
|
||||
#include "ShadowrunCharacterForm.hpp"
|
||||
#include "database.hpp"
|
||||
#include "ShadowrunDb.hpp"
|
||||
#include <format>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
namespace shadowrun
|
||||
{
|
||||
|
||||
bool initDb() {
|
||||
auto db = Database();
|
||||
static std::unordered_map<std::string, std::string> parse_query_string(const std::string& query) {
|
||||
std::unordered_map<std::string, std::string> params;
|
||||
std::istringstream stream(query);
|
||||
std::string pair;
|
||||
|
||||
if (!db.open()){
|
||||
return false;
|
||||
while (std::getline(stream, pair, '&')) {
|
||||
auto pos = pair.find('=');
|
||||
if (pos != std::string::npos) {
|
||||
std::string key = pair.substr(0, pos);
|
||||
std::string value = pair.substr(pos + 1);
|
||||
params[key] = value; // You may want to URL-decode here
|
||||
}
|
||||
}
|
||||
|
||||
// Create a tables
|
||||
const char* create_sql_chars = "CREATE TABLE IF NOT EXISTS shadowrun_characters ("
|
||||
"id INTEGER PRIMARY KEY,"
|
||||
"name TEXT,"
|
||||
"created_at DATETIME DEFAULT CURRENT_TIMESTAMP);";
|
||||
|
||||
if (!db.exec(create_sql_chars)){
|
||||
CROW_LOG_ERROR << "Failed to create shadowrun_characters table";
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* create_sql_data = "CREATE TABLE IF NOT EXISTS shadowrun_data ("
|
||||
"id INTEGER PRIMARY KEY,"
|
||||
"character_id INTEGER NOT NULL,"
|
||||
"name TEXT NOT NULL,"
|
||||
"value TEXT,"
|
||||
"created_at DATETIME DEFAULT CURRENT_TIMESTAMP,"
|
||||
"updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,"
|
||||
"FOREIGN KEY (character_id) REFERENCES characters(id) ON DELETE CASCADE);";
|
||||
|
||||
if (!db.exec(create_sql_data)){
|
||||
CROW_LOG_ERROR << "Failed to create shadowrun_data table";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return params;
|
||||
}
|
||||
|
||||
static crow::response rsp(const std::string& msg){
|
||||
auto str = format("<div class='alert alert-success'>"
|
||||
"{} </div>", msg);
|
||||
return crow::response{str};
|
||||
}
|
||||
|
||||
void initApi(crow::SimpleApp& app)
|
||||
{
|
||||
CROW_ROUTE(app, "/api/shadowrun/submit-character").methods("POST"_method)(
|
||||
[](const crow::request& req) {
|
||||
auto params = crow::query_string(req.body);
|
||||
auto params = parse_query_string(req.body);
|
||||
|
||||
std::string name = params.get("name") ? params.get("name") : "";
|
||||
std::string metatype = params.get("metatype") ? params.get("metatype") : "";
|
||||
std::string age = params.get("age") ? params.get("age") : "";
|
||||
// ... extract more fields as needed
|
||||
auto name_data = params["Character-Info_Name"];
|
||||
if (name_data.empty()){
|
||||
CROW_LOG_WARNING << "Character without name submited, will not be saved";
|
||||
return rsp("Failed : Character without name submited, will not be saved");
|
||||
}
|
||||
|
||||
// Optionally save to a DB or do logic here
|
||||
auto key = getKeyOfCharacter(name_data);
|
||||
if (key < 0){
|
||||
CROW_LOG_ERROR << "Failed to create id of character : " << name_data;
|
||||
return rsp("Failed to create id of character");
|
||||
}
|
||||
|
||||
// Return response HTML
|
||||
std::ostringstream out;
|
||||
out << "<div class='alert alert-success'>"
|
||||
<< "Character " << name << " submitted successfully!"
|
||||
<< "</div>";
|
||||
vector<pair<const string&, const string&>> idValues;
|
||||
idValues.reserve(ShadowrunCharacterForm::m_formIds.size());
|
||||
|
||||
for (auto& id : ShadowrunCharacterForm::m_formIds) {
|
||||
auto data = params[id];
|
||||
if(!
|
||||
data.empty()){
|
||||
idValues.push_back(make_pair(id, data));
|
||||
}
|
||||
}
|
||||
|
||||
return crow::response{out.str()};
|
||||
if (!storeCharacterData(key, idValues)){
|
||||
CROW_LOG_ERROR << "Failed to store character data of " << name_data;
|
||||
return rsp("Failed to store character data");
|
||||
};
|
||||
return rsp(format("Character {} submitted successfully", name_data));
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/api/shadowrun/character-form")
|
||||
@ -69,9 +74,7 @@ void initApi(crow::SimpleApp& app)
|
||||
auto query = crow::query_string(req.url_params);
|
||||
std::string name = query.get("name") ? query.get("name") : "";
|
||||
|
||||
// TODO: Load data from file or DB using `name`
|
||||
std::string metatype = "Troll";
|
||||
int age = 28;
|
||||
auto data = getCharacterData(getKeyOfCharacter(name));
|
||||
|
||||
return crow::response{ShadowrunCharacterForm().htmx()};
|
||||
});
|
||||
@ -81,7 +84,7 @@ void initApi(crow::SimpleApp& app)
|
||||
std::ostringstream html;
|
||||
|
||||
// Simulated character database
|
||||
std::vector<std::string> characters = { "Trogdor", "Alice", "Zigzag" };
|
||||
auto characters = getCharacters();
|
||||
|
||||
html << "<form hx-get='/api/shadowrun/character-form' hx-target='#form-container' hx-params='*'>"
|
||||
<< "<label>Character Name: "
|
||||
@ -98,7 +101,7 @@ void initApi(crow::SimpleApp& app)
|
||||
return crow::response{html.str()};
|
||||
});
|
||||
|
||||
if(initDb()){
|
||||
if(!shadowrun::initDb()){
|
||||
CROW_LOG_ERROR << "Failed to Init shadowrun database";
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,6 +76,31 @@ static const vector<string> cArmorParamters = {
|
||||
"Notes",
|
||||
};
|
||||
|
||||
static const vector<string> genFormIds(){
|
||||
vector<string> vec;
|
||||
vec.reserve(200);
|
||||
|
||||
// OBS make sure to update both here and in ShadowrunCharacterForm()
|
||||
HtmxShAttributeList::genIds(vec, "Character Info", cCharacterInfo);
|
||||
HtmxShAttributeList::genIds(vec, "Attributes", cAttributes);
|
||||
HtmxShItemList::genIds(vec, "Active Skills", cSkillParameters, 6);
|
||||
HtmxShItemList::genIds(vec, "Knowledge Skills", cSkillParameters, 6);
|
||||
vec.push_back("positive_qualities");
|
||||
vec.push_back("negative_qualities");
|
||||
vec.push_back("datapack_notes");
|
||||
HtmxShCondition::genIds(vec, "Physical Condition", 18);
|
||||
HtmxShCondition::genIds(vec, "Stun Condition", 12);
|
||||
HtmxShItemList::genIds(vec, "Contacts", cContactsParameters, 6);
|
||||
HtmxShItemList::genIds(vec, "Ranged Weapons", cRangedWeaponsParameters, 7);
|
||||
HtmxShItemList::genIds(vec, "Cyberware and Bioware", cImplantParameters, 7);
|
||||
HtmxShItemList::genIds(vec, "Melee Weapons", cMeleeWeaponParameters, 7);
|
||||
HtmxShItemList::genIds(vec, "Armor", cArmorParamters , 3);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
const std::vector<std::string> ShadowrunCharacterForm::m_formIds = genFormIds();
|
||||
|
||||
ShadowrunCharacterForm::ShadowrunCharacterForm() {
|
||||
html.reserve(30000);
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ class ShadowrunCharacterForm : public HtmxObject {
|
||||
public:
|
||||
ShadowrunCharacterForm();
|
||||
|
||||
private:
|
||||
static const std::vector<std::string> m_formIds;
|
||||
};
|
||||
|
||||
#endif // SHADOWRUN_CHARACTER_FORM_HPP
|
||||
110
src/shadowrun/ShadowrunDb.cpp
Normal file
110
src/shadowrun/ShadowrunDb.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
#include <format>
|
||||
#include "database.hpp"
|
||||
#include "crow.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace shadowrun {
|
||||
|
||||
bool initDb() {
|
||||
auto db = Database();
|
||||
|
||||
if (!db.open()){
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a tables
|
||||
const char* create_sql_chars = "CREATE TABLE IF NOT EXISTS shadowrun_characters ("
|
||||
"id INTEGER PRIMARY KEY,"
|
||||
"name TEXT NOT NULL,"
|
||||
"created_at DATETIME DEFAULT CURRENT_TIMESTAMP);";
|
||||
|
||||
if (!db.exec(create_sql_chars)){
|
||||
CROW_LOG_ERROR << "Failed to create shadowrun_characters table";
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* create_sql_data = "CREATE TABLE IF NOT EXISTS shadowrun_data ("
|
||||
"id INTEGER PRIMARY KEY,"
|
||||
"character_id INTEGER NOT NULL,"
|
||||
"name TEXT NOT NULL,"
|
||||
"value TEXT,"
|
||||
"created_at DATETIME DEFAULT CURRENT_TIMESTAMP,"
|
||||
"updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,"
|
||||
"FOREIGN KEY (character_id) REFERENCES characters(id) ON DELETE CASCADE);";
|
||||
|
||||
if (!db.exec(create_sql_data)){
|
||||
CROW_LOG_ERROR << "Failed to create shadowrun_data table";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int64_t getKeyOfCharacter(const string& name){
|
||||
auto sql = format("SELECT 1 FROM shadowrun_characters WHERE name = '{}' LIMIT 1;", name);
|
||||
auto db = Database();
|
||||
|
||||
if (!db.open())
|
||||
return -1;
|
||||
|
||||
auto opt_int = db.getInt(sql.c_str());
|
||||
if (opt_int.has_value()) {
|
||||
return opt_int.value();
|
||||
} else {
|
||||
sql = format("INSERT INTO shadowrun_characters (name) VALUES ('{}');", name);
|
||||
auto key = db.insert(sql.c_str());
|
||||
|
||||
if(key.has_value()){
|
||||
return key.value();
|
||||
} else {
|
||||
CROW_LOG_ERROR << "Failed to insert character " << name;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
for (auto& idValue : idValues) {
|
||||
// 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;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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::map<std::string, std::string> getCharacterData(int64_t characterKey) {
|
||||
auto sql = format("SELECT name, value FROM shadowrun_data WHERE character_id = {};", characterKey);
|
||||
auto db = Database();
|
||||
if (!db.open())
|
||||
return std::map<std::string, std::string>();
|
||||
|
||||
return db.getStrMap(sql);
|
||||
}
|
||||
|
||||
}
|
||||
20
src/shadowrun/ShadowrunDb.hpp
Normal file
20
src/shadowrun/ShadowrunDb.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef __SHADOWRUNDB_H__
|
||||
#define __SHADOWRUNDB_H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
namespace shadowrun{
|
||||
|
||||
bool initDb();
|
||||
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::map<std::string, std::string> getCharacterData(int64_t characterKey);
|
||||
}
|
||||
|
||||
#endif // __SHADOWRUNDB_H__
|
||||
Loading…
x
Reference in New Issue
Block a user