bettola/common/src/db/database_manager.cpp

98 lines
3.5 KiB
C++

#include "database_manager.h"
#include <memory>
#include "vfs.h"
DatabaseManager::DatabaseManager(const std::string& db_path) :
_db(db_path) {
_player_repository = std::make_unique<PlayerRepository>(_db);
_machine_repository = std::make_unique<MachineRepository>(_db);
_service_repository = std::make_unique<ServiceRepository>(_db);
_vfs_repository = std::make_unique<VFSRepository>(_db);
_db << "CREATE TABLE IF NOT EXISTS players("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"username TEXT NOT NULL UNIQUE,"
"password TEXT NOT NULL,"
"hostname TEXT NOT NULL,"
"home_machine_id INTEGER"
");";
_db << "CREATE TABLE IF NOT EXISTS machines ("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"owner_id INTEGER,"
"hostname TEXT NOT NULL,"
"ip_address TEXT NOT NULL UNIQUE"
");";
_db << "CREATE TABLE IF NOT EXISTS vfs_nodes ("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"machine_id INTEGER NOT NULL,"
"parent_id INTEGER,"
"name TEXT NOT NULL,"
"type INTEGER NOT NULL,"
"content TEXT,"
"owner_id INTEGER NOT NULL,"
"group_id INTEGER NOT NULL,"
"permissions INTEGER NOT NULL"
");";
_db << "CREATE TABLE IF NOT EXISTS services ("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"machine_id INTEGER NOT NULL,"
"port INTEGER NOT NULL,"
"name TEXT NOT NULL"
");";
}
DatabaseManager::~DatabaseManager(void) {
/* db is auto closed when _db goes out of scope. */
}
bool DatabaseManager::create_player(const std::string& username, const std::string& password,
const std::string& hostname, vfs_node* vfs_template) {
long long player_id = 0;
long long machine_id = 0;
try {
_db << "BEGIN;";
player_id = _player_repository->create(username, password, hostname);
/* Create the home machine. */
/* TODO: Implement real IP allication. */
std::string ip_address = "192.168.1." + std::to_string(player_id);
machine_id = _machine_repository->create(player_id, hostname, ip_address);
_player_repository->set_home_machine_id(player_id, machine_id);
/* Create the root dir for the new machine's VFS. */
long long root_id = _vfs_repository->create_node(machine_id, nullptr, "/", DIR_NODE,
"", player_id, player_id, 0755);
/* Create default subdirs. */
_vfs_repository->create_node(machine_id, &root_id, "home", DIR_NODE,
"", player_id, player_id, 0755);
_vfs_repository->create_node(machine_id, &root_id, "etc", DIR_NODE,
"", player_id, player_id, 0755);
/* Create /bin and get it's ID */
long long bin_id = _vfs_repository->create_node(machine_id, &root_id, "bin", DIR_NODE,
"", player_id, player_id, 0755);
/* Copy scripts from template into new machine's /bin */
vfs_node* template_bin = vfs_template->children["bin"];
for(auto const& [name, node] : template_bin->children) {
_vfs_repository->create_node(machine_id, &bin_id, name, node->type, node->content,
player_id, player_id, 0755);
}
/* Add default SSH service. */
_service_repository->create(machine_id, 22, "SSH");
_db << "COMMIT";
} catch(const std::exception& e) {
_db << "ROLLBACK;"; /* Ensure atomicity. */
return false;
}
return true;
}