113 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "database_manager.h"
 | 
						|
#include "vfs.h"
 | 
						|
 | 
						|
DatabaseManager::DatabaseManager(const std::string& db_path) : _db(db_path) {
 | 
						|
  /* db is opened in the construtor's init list. */
 | 
						|
}
 | 
						|
 | 
						|
DatabaseManager::~DatabaseManager(void) {
 | 
						|
  /* db is auto closed when _db goes out of scope. */
 | 
						|
}
 | 
						|
 | 
						|
void DatabaseManager::init(void) {
 | 
						|
  _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"
 | 
						|
          ");";
 | 
						|
}
 | 
						|
 | 
						|
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;";
 | 
						|
 | 
						|
    /* Create the player. */
 | 
						|
    _db << "INSERT INTO players (username, password, hostname) VALUES (?, ?, ?);"
 | 
						|
        << username
 | 
						|
        << password
 | 
						|
        << hostname;
 | 
						|
    player_id = _db.last_insert_rowid();
 | 
						|
 | 
						|
    /* Create the home machine. */
 | 
						|
    /* TODO: Implement real IP allication. */
 | 
						|
    std::string ip_address = "192.168.1." + std::to_string(player_id);
 | 
						|
    _db << "INSERT INTO machines (owner_id, hostname, ip_address) VALUES (?, ?, ?);"
 | 
						|
        << player_id << hostname << ip_address;
 | 
						|
    machine_id = _db.last_insert_rowid();
 | 
						|
 | 
						|
    /* Link player to their new machine. */
 | 
						|
    _db << "UPDATE players SET home_machine_id = ? WHERE id = ?;"
 | 
						|
        << machine_id << player_id;
 | 
						|
 | 
						|
    /* Create the root dir for the new machine's VFS. */
 | 
						|
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES(?, NULL, ?, 1);"
 | 
						|
        << machine_id << "/";
 | 
						|
    long long root_id = _db.last_insert_rowid();
 | 
						|
 | 
						|
    /* Create default subdirs. */
 | 
						|
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES (?, ?, ?, 1);"
 | 
						|
        << machine_id << root_id << "home";
 | 
						|
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES (?, ?, ?, 1);"
 | 
						|
        << machine_id << root_id << "etc";
 | 
						|
 | 
						|
    /* Create /bing and get it's ID */
 | 
						|
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES(?, ?, ?, 1);"
 | 
						|
        << machine_id << root_id << "bin";
 | 
						|
    long long bin_id = _db.last_insert_rowid();
 | 
						|
 | 
						|
    /* 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) {
 | 
						|
      _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type, content) "
 | 
						|
             "VALUES (?, ?, ?, ?, ?);"
 | 
						|
          << machine_id << bin_id << name << FILE_NODE <<node->content;
 | 
						|
    }
 | 
						|
 | 
						|
    _db << "COMMIT";
 | 
						|
  } catch(const std::exception& e) {
 | 
						|
    _db << "ROLLBACK;"; /* Ensure atomicity. */
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
bool DatabaseManager::auth_player(const std::string& username, const std::string& password) {
 | 
						|
  bool authed = false;
 | 
						|
  _db << "SELECT id FROM players WHERE username = ? AND password = ?;"
 | 
						|
      << username
 | 
						|
      << password
 | 
						|
      >> [&](long long id) { authed = true; };
 | 
						|
 | 
						|
  return authed;
 | 
						|
}
 | 
						|
 | 
						|
long long DatabaseManager::get_player_home_machine_id(const std::string& username) {
 | 
						|
  long long machine_id = -1; /* Return -1 if not found. */
 | 
						|
  _db << "SELECT home_machine_id FROM players WHERE username = ?;"
 | 
						|
      << username
 | 
						|
      >> machine_id;
 | 
						|
  return machine_id;
 | 
						|
}
 |