From 768bd412b0eaeda8c3d44af06c84474edede9b2f Mon Sep 17 00:00:00 2001 From: Christine Dodrill Date: Tue, 3 Nov 2020 09:47:19 -0500 Subject: [PATCH] import data from rethinkdb --- .../2020-09-13-154110_switches/up.sql | 1 - .../2020-09-13-155542_system/up.sql | 7 -- backend/src/api.rs | 35 ++++---- backend/src/bin/import_rethink_switches.rs | 79 +++++++++++++++++++ backend/src/lib.rs | 22 ++++++ backend/src/main.rs | 15 +--- backend/src/models.rs | 21 ++++- backend/src/schema.rs | 1 - 8 files changed, 134 insertions(+), 47 deletions(-) create mode 100644 backend/src/bin/import_rethink_switches.rs create mode 100644 backend/src/lib.rs diff --git a/backend/migrations/2020-09-13-154110_switches/up.sql b/backend/migrations/2020-09-13-154110_switches/up.sql index 238332c..080afc8 100644 --- a/backend/migrations/2020-09-13-154110_switches/up.sql +++ b/backend/migrations/2020-09-13-154110_switches/up.sql @@ -11,7 +11,6 @@ CREATE TABLE IF NOT EXISTS switches , member_id INTEGER NOT NULL , started_at TIMESTAMP NOT NULL , ended_at TIMESTAMP - , duration INTEGER , FOREIGN KEY (member_id) REFERENCES members(id) ); diff --git a/backend/migrations/2020-09-13-155542_system/up.sql b/backend/migrations/2020-09-13-155542_system/up.sql index 377b6e3..2176194 100644 --- a/backend/migrations/2020-09-13-155542_system/up.sql +++ b/backend/migrations/2020-09-13-155542_system/up.sql @@ -7,10 +7,3 @@ VALUES (3, 'Ashe', 'https://mi.within.website/static/img/ashe.png'), (4, 'Sephie', 'https://mi.within.website/static/img/sephie.png'), (5, 'Mai', 'https://mi.within.website/static/img/mai.png'); - --- testing values -INSERT INTO - switches(id, member_id, started_at, ended_at, duration) -VALUES - ( 'ropjar', 0, '2013-10-07 08:23:19.120', datetime('now'), 200), - ( 'flopnax', 5, datetime('now'), NULL, 0) diff --git a/backend/src/api.rs b/backend/src/api.rs index 5d10602..dff7634 100644 --- a/backend/src/api.rs +++ b/backend/src/api.rs @@ -12,7 +12,7 @@ use rocket::{ }; use rocket_contrib::json::Json; use rusty_ulid::generate_ulid_string; -use std::{convert::TryInto, io::Read}; +use std::io::Read; #[get("/members")] #[instrument(skip(conn), err)] @@ -56,12 +56,12 @@ pub fn get_switches( .load::<(models::Switch, models::Member)>(&*conn) .map_err(Error::Database)? .into_iter() - .map(|front| FrontChange { - id: front.0.id, - who: front.1.cmene, - started_at: front.0.started_at, - ended_at: front.0.ended_at, - duration: front.0.duration, + .map(|(switch, member)| FrontChange { + duration: switch.duration(), + id: switch.id, + who: member.cmene, + started_at: switch.started_at, + ended_at: switch.ended_at, }) .collect(); @@ -84,12 +84,12 @@ pub fn get_current_front(conn: MainDatabase) -> Result> { .map_err(Error::Database)?; match front.pop() { - Some(front) => Ok(Json(FrontChange { - id: front.0.id, - who: front.1.cmene, - started_at: front.0.started_at, - ended_at: front.0.ended_at, - duration: front.0.duration, + Some((switch, member)) => Ok(Json(FrontChange { + duration: switch.duration(), + id: switch.id, + who: member.cmene, + started_at: switch.started_at, + ended_at: switch.ended_at, })), None => Err(Error::NotFound), } @@ -139,13 +139,6 @@ pub fn make_switch( diesel::update(switches.find(last.id)) .set(&models::UpdateSwitchTime { ended_at: Some(now.clone()), - duration: Some( - now.clone() - .signed_duration_since(last.started_at) - .num_seconds() - .try_into() - .expect("don't expect a switch to last 30+ years"), - ), }) .execute(&*conn) .map_err(Error::Database) @@ -176,11 +169,11 @@ pub fn get_switch(conn: MainDatabase, switch_id: String) -> Result for RethinkTime { + fn into(self) -> NaiveDateTime { + NaiveDateTime::from_timestamp(self.epoch_time.round() as i64, 0) + } +} + +#[derive(Deserialize, Debug)] +struct RethinkRow { + id: String, + who: String, + started_at: RethinkTime, + ended_at: Option, +} + +fn main() -> Result<()> { + let _ = kankyo::init(); + color_eyre::install()?; + tracing_subscriber::fmt::init(); + + info!("{} rethink dump importer starting up", mi::APPLICATION_NAME); + + let conn = establish_connection(); + + let fname = env::args() + .skip(1) + .next() + .expect("usage: import_rethink_switches "); + + let fin = File::open(&fname)?; + let bufreader = BufReader::new(fin); + let data: Vec = from_reader::, Vec>(bufreader)? + .into_iter() + .map(|rr| mi::models::Switch { + id: rr.id, + member_id: member_to_id(rr.who), + started_at: rr.started_at.into(), + ended_at: rr.ended_at.map(|time| time.into()), + }) + .collect::>(); + diesel::insert_into(mi::schema::switches::table) + .values(&data) + .execute(&conn)?; + + Ok(()) +} + +pub fn establish_connection() -> SqliteConnection { + let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); + SqliteConnection::establish(&database_url) + .expect(&format!("Error connecting to {}", database_url)) +} + +pub fn member_to_id(name: String) -> i32 { + match name.as_str() { + "Cadey" => 0, + "Nicole" => 1, + "Jessie" => 2, + "Ashe" => 3, + "Sephie" => 4, + "Mai" => 5, + + _ => panic!("name not matched"), + } +} diff --git a/backend/src/lib.rs b/backend/src/lib.rs new file mode 100644 index 0000000..ccf66cc --- /dev/null +++ b/backend/src/lib.rs @@ -0,0 +1,22 @@ +#![feature(proc_macro_hygiene, decl_macro)] + +#[macro_use] +extern crate diesel; +#[macro_use] +extern crate rocket; +#[macro_use] +extern crate rocket_contrib; +#[macro_use] +extern crate tracing; + +use diesel::sqlite::SqliteConnection; + +pub const APPLICATION_NAME: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); + +pub mod api; +pub mod models; +pub mod schema; +pub mod web; + +#[database("main_data")] +pub struct MainDatabase(SqliteConnection); diff --git a/backend/src/main.rs b/backend/src/main.rs index 6c0fd30..b0d25d3 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1,28 +1,15 @@ #![feature(proc_macro_hygiene, decl_macro)] -#[macro_use] -extern crate diesel; #[macro_use] extern crate rocket; #[macro_use] -extern crate rocket_contrib; -#[macro_use] extern crate tracing; use color_eyre::eyre::Result; -use diesel::sqlite::SqliteConnection; use rocket_contrib::helmet::SpaceHelmet; use rocket_prometheus::PrometheusMetrics; -const APPLICATION_NAME: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); - -pub mod api; -pub mod models; -pub mod schema; -pub mod web; - -#[database("main_data")] -pub struct MainDatabase(SqliteConnection); +use ::mi::{api, web, MainDatabase, APPLICATION_NAME}; fn main() -> Result<()> { let _ = kankyo::init(); diff --git a/backend/src/models.rs b/backend/src/models.rs index a7ab382..7773ff5 100644 --- a/backend/src/models.rs +++ b/backend/src/models.rs @@ -1,6 +1,7 @@ use crate::schema::*; use chrono::NaiveDateTime; use serde::Serialize; +use std::convert::TryInto; #[derive(Queryable, Debug, Serialize)] pub struct Member { @@ -10,7 +11,7 @@ pub struct Member { pub picurl: String, } -#[derive(Queryable, Associations)] +#[derive(Queryable, Associations, Insertable)] #[belongs_to(Member)] #[table_name = "switches"] pub struct Switch { @@ -18,7 +19,22 @@ pub struct Switch { pub member_id: i32, pub started_at: NaiveDateTime, pub ended_at: Option, - pub duration: Option, +} + +impl Switch { + pub fn duration(&self) -> Option { + match self.ended_at { + None => None, + Some(end_time) => Some( + end_time + .clone() + .signed_duration_since(self.started_at) + .num_seconds() + .try_into() + .expect("don't expect a switch to last 30+ years"), + ), + } + } } #[derive(Insertable)] @@ -33,5 +49,4 @@ pub struct NewSwitch { #[table_name = "switches"] pub struct UpdateSwitchTime { pub ended_at: Option, - pub duration: Option, } diff --git a/backend/src/schema.rs b/backend/src/schema.rs index 6e51b09..5314ec6 100644 --- a/backend/src/schema.rs +++ b/backend/src/schema.rs @@ -12,7 +12,6 @@ table! { member_id -> Integer, started_at -> Timestamp, ended_at -> Nullable, - duration -> Nullable, } }