added configurable database path

This commit is contained in:
2026-02-15 00:44:49 +01:00
parent 7a79e8e803
commit 14b8234e77
10 changed files with 88 additions and 54 deletions

View File

@@ -13,25 +13,31 @@ source=(
)
md5sums=('SKIP') # SKIP if local files
build() {
cd "$srcdir"
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
make
cmake -S "${srcdir}" \
-B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr
cmake --build build
}
package() {
install -Dm755 "$srcdir/${pkgname}" \
local src="${srcdir}"
# Binary (built by CMake into build/)
install -Dm755 "$src/build/${pkgname}" \
"$pkgdir/usr/bin/${pkgname}"
# Frontend build output
install -d "$pkgdir/usr/share/${pkgname}/frontend/build"
cp -a "$srcdir/frontend/build/." \
"$pkgdir/usr/share/${pkgname}/frontend/build"
cp -a "$src/frontend/build/." \
"$pkgdir/usr/share/${pkgname}/frontend/build/"
# Assets directory
install -d "$pkgdir/usr/share/${pkgname}/assets"
cp -a "$srcdir/assets/." \
cp -a "$src/assets/." \
"$pkgdir/usr/share/${pkgname}/assets/"
# systemd service
install -Dm644 "$srcdir/shadowrun-server.service" \
install -Dm644 "$src/shadowrun-server.service" \
"$pkgdir/usr/lib/systemd/system/shadowrun-server.service"
}

View File

@@ -1,3 +1,4 @@
{
"httpPort" : 3010
"http_port" : 3010,
"db_path": "/var/lib/shadowrun-server/shadowrun.db"
}

View File

@@ -1,3 +1,4 @@
#include "databasepool.h"
DatabasePool dbpool(std::thread::hardware_concurrency());
std::unique_ptr<DatabasePool> dbpool = nullptr;

View File

@@ -6,12 +6,8 @@
#include "ShadowrunDb.hpp"
#include "loginDb.hpp"
namespace Database {
static constexpr std::string dbFile = "shadowrun.db";
}
inline auto make_database() {
auto storage = sqlite_orm::make_storage(Database::dbFile,
inline auto make_database(const std::string& path) {
auto storage = sqlite_orm::make_storage(path,
sqlite_orm::make_table("users",
sqlite_orm::make_column("id", &login::User::id, sqlite_orm::primary_key()),
sqlite_orm::make_column("username", &login::User::username, sqlite_orm::unique() ),

View File

@@ -7,19 +7,35 @@
class DatabasePool {
public:
DatabasePool(size_t size) {
// allow multithreaded access to database
// Construct pool with path + size
DatabasePool(const std::string& path)
: db_path(path)
{
// Enable multithreaded SQLite
assert(sqlite3_config(SQLITE_CONFIG_MULTITHREAD) == SQLITE_OK);
assert(sqlite3_initialize() == SQLITE_OK);
}
for (size_t i = 0; i < size; ++i){
auto db = std::make_shared<decltype(make_database())>(make_database());
db->sync_schema();
pool.push(db);
bool init(size_t size){
try{
// Pre-create the pool
for (size_t i = 0; i < size; ++i) {
auto db = std::make_shared<decltype(make_database(db_path))>(make_database(db_path));
db->sync_schema();
pool.push(db);
}
// init the database
auto db = acquire();
release(db);
return true;
}
catch (...) {
return false;
}
}
std::shared_ptr<decltype(make_database())> acquire() {
// Acquire a database connection from the pool
std::shared_ptr<decltype(make_database(std::string{}))> acquire() {
std::unique_lock<std::mutex> lock(mutex);
cv.wait(lock, [&]{ return !pool.empty(); });
auto db = pool.front();
@@ -27,7 +43,8 @@ public:
return db;
}
void release(std::shared_ptr<decltype(make_database())> db) {
// Return a connection to the pool
void release(std::shared_ptr<decltype(make_database(std::string{}))> db) {
std::unique_lock<std::mutex> lock(mutex);
pool.push(db);
lock.unlock();
@@ -35,9 +52,10 @@ public:
}
private:
std::queue<std::shared_ptr<decltype(make_database())>> pool;
std::queue<std::shared_ptr<decltype(make_database(std::string{}))>> pool;
std::mutex mutex;
std::condition_variable cv;
const std::string db_path;
};
extern DatabasePool dbpool;
extern std::unique_ptr<DatabasePool> dbpool;

View File

@@ -10,7 +10,8 @@ using namespace::AppSettings;
Settings AppSettings::deafult(){
return Settings {
.httpPort = 3010
.http_port = 3010,
.db_path = "/var/lib/shadowrun-server/shadowrun.db"
};
}

View File

@@ -2,17 +2,19 @@
#define JSON_SETTINGS_H
#include "json.hpp"
#include <string>
namespace AppSettings {
static constexpr char settingsFile[] = "assets/settings.json";
struct Settings {
int httpPort;
int http_port;
std::string db_path;
};
Settings load();
Settings deafult();
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Settings, httpPort);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Settings, http_port, db_path);
}
#endif // JSON_SETTINGS_H

View File

@@ -59,7 +59,7 @@ int createUser(const std::string& username, const std::string& password){
return -1;
int64_t id = -1;
auto db = dbpool.acquire();
auto db = dbpool->acquire();
for (auto &u : db->get_all<login::User>()) {
if (u.username == username){
@@ -73,16 +73,16 @@ int createUser(const std::string& username, const std::string& password){
createPasswordHash(usr, password);
id = db->insert(usr);
}
dbpool.release(db);
dbpool->release(db);
return id;
}
std::optional<User> getUser(const std::string& username){
auto db = dbpool.acquire();
auto db = dbpool->acquire();
auto user = db->get_all<login::User>(
where(c(&login::User::username) == username)
);
dbpool.release(db);
dbpool->release(db);
if(user.size() > 0){
return user[0];

View File

@@ -4,23 +4,26 @@
#include "utils.hpp"
#include "login.hpp"
#include "ShadowrunApi.hpp"
#include "databasepool.h"
using namespace std;
int main() {
crow::SimpleApp app;
// Root route
CROW_ROUTE(app, "/")([&]() {
auto data = utils::read_file(utils::build_dir / "index.html");
return crow::response(200, "text/html", data);
});
auto settings = AppSettings::load();
auto opt_isPortOpen = utils::isLocalPortOpen(settings.httpPort);
// create global database
dbpool = std::make_unique<DatabasePool>(settings.db_path);
if (!dbpool->init(std::thread::hardware_concurrency())){
CROW_LOG_ERROR << "Failed to create database at : " << settings.db_path;
return 1;
}
auto opt_isPortOpen = utils::isLocalPortOpen(settings.http_port);
if (opt_isPortOpen.has_value()){
if (opt_isPortOpen.value()){
CROW_LOG_ERROR << "Local port : " << settings.httpPort << " is already open";
CROW_LOG_ERROR << "Local port : " << settings.http_port << " is already open";
return 1;
}
}
@@ -29,6 +32,12 @@ int main() {
return 1;
}
// Root route
CROW_ROUTE(app, "/")([&]() {
auto data = utils::read_file(utils::build_dir / "index.html");
return crow::response(200, "text/html", data);
});
shadowrun::initApi(app);
login::initLogin(app);
@@ -53,5 +62,5 @@ int main() {
});
app.loglevel(crow::LogLevel::INFO);
app.bindaddr("0.0.0.0").port(settings.httpPort).multithreaded().run();
app.bindaddr("0.0.0.0").port(settings.http_port).multithreaded().run();
}

View File

@@ -14,7 +14,7 @@ int64_t createCharacter(const string& name){
return -1;
int64_t id;
auto db = dbpool.acquire();
auto db = dbpool->acquire();
auto character = db->get_optional<ShadowrunCharacter>(
where(c(&ShadowrunCharacter::name) == name)
@@ -26,38 +26,38 @@ int64_t createCharacter(const string& name){
auto c = newShadowrunCharacter(name);
id = db->insert(c);
}
dbpool.release(db);
dbpool->release(db);
return id;
}
std::vector<ShadowrunCharacter> getCharacters(){
auto db = dbpool.acquire();
auto db = dbpool->acquire();
auto characters = db->get_all<ShadowrunCharacter>();
dbpool.release(db);
dbpool->release(db);
return characters;
}
optional<ShadowrunCharacter> getChracter(int id)
{
auto db = dbpool.acquire();
auto db = dbpool->acquire();
optional<ShadowrunCharacter> character = db->get_optional<ShadowrunCharacter>(id);
dbpool.release(db);
dbpool->release(db);
return character;
}
vector<ShadowrunCharacterData> getChracterData(int character_id)
{
auto db = dbpool.acquire();
auto db = dbpool->acquire();
auto characterData = db->get_all<ShadowrunCharacterData>(
where(c(&ShadowrunCharacterData::character_id) == character_id)
);
dbpool.release(db);
dbpool->release(db);
return characterData;
}
int storeCharacterData(int characterId, const Type type, const string& json){
int id;
auto db = dbpool.acquire();
auto db = dbpool->acquire();
auto characterData = db->get_all<ShadowrunCharacterData>(
where(
(c(&ShadowrunCharacterData::character_id) == characterId) and
@@ -78,13 +78,13 @@ int storeCharacterData(int characterId, const Type type, const string& json){
db->update(character);
id = character.id;
}
dbpool.release(db);
dbpool->release(db);
return id;
}
int storeCharacterData(const ShadowrunCharacterData& data){
int id;
auto db = dbpool.acquire();
auto db = dbpool->acquire();
auto characterData = db->get_optional<ShadowrunCharacterData>(data.id);
if(!characterData.has_value()){
@@ -94,7 +94,7 @@ int storeCharacterData(const ShadowrunCharacterData& data){
db->update(data);
id = data.id;
}
dbpool.release(db);
dbpool->release(db);
return id;
}