added configurable database path
This commit is contained in:
22
PKGBUILD
22
PKGBUILD
@@ -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"
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
{
|
||||
"httpPort" : 3010
|
||||
"http_port" : 3010,
|
||||
"db_path": "/var/lib/shadowrun-server/shadowrun.db"
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "databasepool.h"
|
||||
|
||||
DatabasePool dbpool(std::thread::hardware_concurrency());
|
||||
std::unique_ptr<DatabasePool> dbpool = nullptr;
|
||||
|
||||
|
||||
@@ -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() ),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
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())>(make_database());
|
||||
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;
|
||||
@@ -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"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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];
|
||||
|
||||
27
src/main.cpp
27
src/main.cpp
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user