diff options
-rw-r--r-- | Vagrantfile | 2 | ||||
-rw-r--r-- | migrations/1_create_masses/up.sql | 4 | ||||
-rw-r--r-- | src/bin/client.rs | 2 | ||||
-rw-r--r-- | src/bin/server.rs | 52 | ||||
-rw-r--r-- | src/constants.rs | 1 | ||||
-rw-r--r-- | src/mass.rs | 2 | ||||
-rw-r--r-- | src/math.rs | 3 | ||||
-rw-r--r-- | tests/tests.rs | 17 |
8 files changed, 72 insertions, 11 deletions
diff --git a/Vagrantfile b/Vagrantfile index efd37f1..d4c4268 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,5 +1,5 @@ Vagrant.configure("2") do |config| - config.vm.box = "bento/debian-9.4" + config.vm.box = "bento/debian-9.6" config.vm.provision :shell, path: "postgres/bootstrap.sh" config.vm.network "forwarded_port", guest: 5432, host: 5432 config.ssh.forward_x11 = true diff --git a/migrations/1_create_masses/up.sql b/migrations/1_create_masses/up.sql index f666e09..1f10915 100644 --- a/migrations/1_create_masses/up.sql +++ b/migrations/1_create_masses/up.sql @@ -1,5 +1,5 @@ CREATE TABLE masses ( id SERIAL PRIMARY KEY, - name VARCHAR NOT NULL, - mass VARCHAR NOT NULL + name TEXT UNIQUE NOT NULL, + mass TEXT NOT NULL ) diff --git a/src/bin/client.rs b/src/bin/client.rs index a91c2dc..9f5fbfc 100644 --- a/src/bin/client.rs +++ b/src/bin/client.rs @@ -34,7 +34,7 @@ fn main() { let server; let mut name = String::new(); - let matches = App::new("space") + let matches = App::new("space client") .subcommand(SubCommand::with_name("mining")) .subcommand(SubCommand::with_name("engines")) .subcommand(SubCommand::with_name("refinery")) diff --git a/src/bin/server.rs b/src/bin/server.rs index 881cc4d..708cd3e 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -1,14 +1,19 @@ extern crate space; +use clap::{App, SubCommand}; +use diesel::pg::PgConnection; +use diesel::prelude::*; use std::collections::HashMap; use std::io::Write; use std::net::TcpListener; -use std::thread::sleep; +use std::thread::{sleep, spawn}; use std::time::{Duration, Instant}; use space::constants; -use space::mass::Mass; -use space::math::rand_name; +use space::mass::{Mass, MassEntry}; +use space::math::{get_db_url, rand_name}; +use space::schema::masses::dsl::masses as db_masses; +use space::schema::masses::dsl::name as name_column; use space::server_connection::ServerConnection; fn populate() -> HashMap<String, Mass> { @@ -21,12 +26,44 @@ fn populate() -> HashMap<String, Mass> { masses } +fn backup(masses: HashMap<String, Mass>) { + let connection = PgConnection::establish(&get_db_url()).expect("Cannot connect"); + for (name, mass) in masses { + let mass_entry = mass.to_mass_entry(name.to_string()); + diesel::insert_into(db_masses) + .values(&mass_entry) + .on_conflict(name_column) + .do_update() + .set(&mass_entry) + .execute(&connection) + .expect("Cannot backup"); + } +} + +fn restore() -> HashMap<String, Mass> { + let connection = PgConnection::establish(&get_db_url()).expect("Cannot connect"); + db_masses + .load::<MassEntry>(&connection) + .expect("Cannot query, are you sure you can restore?") + .iter() + .map(|mass_entry| mass_entry.to_mass()) + .collect() +} + fn main() { let listener = TcpListener::bind("localhost:6000").unwrap(); listener.set_nonblocking(true).unwrap(); - let mut masses = populate(); + let matches = App::new("space server") + .subcommand(SubCommand::with_name("--restore")) + .get_matches(); + + let mut masses = match matches.subcommand_name() { + Some("--restore") => restore(), + _ => populate(), + }; + let mut backup_countdown = constants::BACKUP_COUNTDOWN; let mut connections: Vec<ServerConnection> = Vec::new(); for stream in listener.incoming() { match stream { @@ -64,11 +101,18 @@ fn main() { masses.insert(key.to_string(), mass); } + if backup_countdown == 0 { + let masses_clone = masses.clone(); + spawn(move || backup(masses_clone)); + backup_countdown = constants::BACKUP_COUNTDOWN; + } + if timer.elapsed().as_millis() < constants::LOOP_DURATION_MS.into() { sleep(Duration::from_millis( constants::LOOP_DURATION_MS - timer.elapsed().as_millis() as u64, )); } + backup_countdown -= 1; } } } diff --git a/src/constants.rs b/src/constants.rs index ab045bf..ece6a76 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -29,6 +29,7 @@ pub const CRUDE_MINERALS_SIZE: usize = 10; pub const FLOAT_PRECISION: f64 = 0.001; pub const LOOP_DURATION_MS: u64 = 100; +pub const BACKUP_COUNTDOWN: usize = 10; pub const POSTGRES_USERNAME: &str = "space"; pub const POSTGRES_PASSWORD: &str = "space"; diff --git a/src/mass.rs b/src/mass.rs index aaf788f..9629e24 100644 --- a/src/mass.rs +++ b/src/mass.rs @@ -26,7 +26,7 @@ pub struct Mass { pub effects: Effects, } -#[derive(Queryable, Insertable)] +#[derive(Queryable, Insertable, Identifiable, AsChangeset, Debug)] #[table_name = "db_masses"] pub struct MassEntry { pub id: Option<i32>, diff --git a/src/math.rs b/src/math.rs index 5ba7981..26220d2 100644 --- a/src/math.rs +++ b/src/math.rs @@ -2,9 +2,10 @@ extern crate rand; use self::rand::distributions::Alphanumeric; use self::rand::Rng; +use std::iter::repeat; + use crate::constants; use crate::modules::types::ModuleType; -use std::iter::repeat; pub fn rand_name() -> String { repeat(()) diff --git a/tests/tests.rs b/tests/tests.rs index 7d7449c..4c5c96b 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -535,7 +535,8 @@ mod tests { .len(); let name = String::from("test"); - let mass = Mass::new_astroid(); + let mut mass = Mass::new_astroid(); + diesel::insert_into(db_masses) .values(&mass.to_mass_entry(name.clone())) .execute(&connection) @@ -555,6 +556,20 @@ mod tests { assert!(mass.position.x == db_mass[0].to_mass().1.position.x); + mass.process(&mut HashMap::new()); + + diesel::update(db_masses) + .set(mass.to_mass_entry(name.clone())) + .execute(&connection) + .expect("Cannot update"); + + let db_mass = db_masses + .filter(dsl::name.eq(name.clone())) + .load::<MassEntry>(&connection) + .expect("Cannot filter"); + + assert!(mass.position.x == db_mass[0].to_mass().1.position.x); + diesel::delete(db_masses.filter(dsl::name.eq(name))) .execute(&connection) .expect("Cannot delete"); |