diff options
author | tom barrett <spalf0@gmail.com> | 2019-04-01 10:54:28 -0500 |
---|---|---|
committer | tom barrett <spalf0@gmail.com> | 2019-04-01 10:54:28 -0500 |
commit | 810c77ba30c65215c2d5e4b6f8a73f3b73e2b152 (patch) | |
tree | 3666053d51c598f701733231244104f536a4d24a /src | |
parent | 95b3508d2397b64c7c63bd3586e524998f194e36 (diff) |
database backup and restore
Diffstat (limited to 'src')
-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 |
5 files changed, 53 insertions, 7 deletions
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(()) |