import data from rethinkdb

This commit is contained in:
Cadey Ratio 2020-11-03 09:47:19 -05:00
parent 66507e82b1
commit 768bd412b0
8 changed files with 134 additions and 47 deletions

View File

@ -11,7 +11,6 @@ CREATE TABLE IF NOT EXISTS switches
, member_id INTEGER NOT NULL , member_id INTEGER NOT NULL
, started_at TIMESTAMP NOT NULL , started_at TIMESTAMP NOT NULL
, ended_at TIMESTAMP , ended_at TIMESTAMP
, duration INTEGER
, FOREIGN KEY (member_id) , FOREIGN KEY (member_id)
REFERENCES members(id) REFERENCES members(id)
); );

View File

@ -7,10 +7,3 @@ VALUES
(3, 'Ashe', 'https://mi.within.website/static/img/ashe.png'), (3, 'Ashe', 'https://mi.within.website/static/img/ashe.png'),
(4, 'Sephie', 'https://mi.within.website/static/img/sephie.png'), (4, 'Sephie', 'https://mi.within.website/static/img/sephie.png'),
(5, 'Mai', 'https://mi.within.website/static/img/mai.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)

View File

@ -12,7 +12,7 @@ use rocket::{
}; };
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use rusty_ulid::generate_ulid_string; use rusty_ulid::generate_ulid_string;
use std::{convert::TryInto, io::Read}; use std::io::Read;
#[get("/members")] #[get("/members")]
#[instrument(skip(conn), err)] #[instrument(skip(conn), err)]
@ -56,12 +56,12 @@ pub fn get_switches(
.load::<(models::Switch, models::Member)>(&*conn) .load::<(models::Switch, models::Member)>(&*conn)
.map_err(Error::Database)? .map_err(Error::Database)?
.into_iter() .into_iter()
.map(|front| FrontChange { .map(|(switch, member)| FrontChange {
id: front.0.id, duration: switch.duration(),
who: front.1.cmene, id: switch.id,
started_at: front.0.started_at, who: member.cmene,
ended_at: front.0.ended_at, started_at: switch.started_at,
duration: front.0.duration, ended_at: switch.ended_at,
}) })
.collect(); .collect();
@ -84,12 +84,12 @@ pub fn get_current_front(conn: MainDatabase) -> Result<Json<FrontChange>> {
.map_err(Error::Database)?; .map_err(Error::Database)?;
match front.pop() { match front.pop() {
Some(front) => Ok(Json(FrontChange { Some((switch, member)) => Ok(Json(FrontChange {
id: front.0.id, duration: switch.duration(),
who: front.1.cmene, id: switch.id,
started_at: front.0.started_at, who: member.cmene,
ended_at: front.0.ended_at, started_at: switch.started_at,
duration: front.0.duration, ended_at: switch.ended_at,
})), })),
None => Err(Error::NotFound), None => Err(Error::NotFound),
} }
@ -139,13 +139,6 @@ pub fn make_switch(
diesel::update(switches.find(last.id)) diesel::update(switches.find(last.id))
.set(&models::UpdateSwitchTime { .set(&models::UpdateSwitchTime {
ended_at: Some(now.clone()), 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) .execute(&*conn)
.map_err(Error::Database) .map_err(Error::Database)
@ -176,11 +169,11 @@ pub fn get_switch(conn: MainDatabase, switch_id: String) -> Result<Json<FrontCha
.map_err(Error::Database)?; .map_err(Error::Database)?;
Ok(Json(FrontChange { Ok(Json(FrontChange {
duration: switch.duration(),
id: switch.id, id: switch.id,
who: member.cmene, who: member.cmene,
started_at: switch.started_at, started_at: switch.started_at,
ended_at: switch.ended_at, ended_at: switch.ended_at,
duration: switch.duration,
})) }))
} }

View File

@ -0,0 +1,79 @@
#[macro_use]
extern crate tracing;
use chrono::prelude::*;
use color_eyre::eyre::Result;
use diesel::{prelude::*, SqliteConnection};
use serde::Deserialize;
use serde_json::from_reader;
use std::{env, fs::File, io::BufReader};
#[derive(Deserialize, Debug)]
struct RethinkTime {
epoch_time: f64,
}
impl Into<NaiveDateTime> 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<RethinkTime>,
}
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 </path/to/switches.json>");
let fin = File::open(&fname)?;
let bufreader = BufReader::new(fin);
let data: Vec<mi::models::Switch> = from_reader::<BufReader<File>, Vec<RethinkRow>>(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::<Vec<mi::models::Switch>>();
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"),
}
}

22
backend/src/lib.rs Normal file
View File

@ -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);

View File

@ -1,28 +1,15 @@
#![feature(proc_macro_hygiene, decl_macro)] #![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate diesel;
#[macro_use] #[macro_use]
extern crate rocket; extern crate rocket;
#[macro_use] #[macro_use]
extern crate rocket_contrib;
#[macro_use]
extern crate tracing; extern crate tracing;
use color_eyre::eyre::Result; use color_eyre::eyre::Result;
use diesel::sqlite::SqliteConnection;
use rocket_contrib::helmet::SpaceHelmet; use rocket_contrib::helmet::SpaceHelmet;
use rocket_prometheus::PrometheusMetrics; use rocket_prometheus::PrometheusMetrics;
const APPLICATION_NAME: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); use ::mi::{api, web, MainDatabase, APPLICATION_NAME};
pub mod api;
pub mod models;
pub mod schema;
pub mod web;
#[database("main_data")]
pub struct MainDatabase(SqliteConnection);
fn main() -> Result<()> { fn main() -> Result<()> {
let _ = kankyo::init(); let _ = kankyo::init();

View File

@ -1,6 +1,7 @@
use crate::schema::*; use crate::schema::*;
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use serde::Serialize; use serde::Serialize;
use std::convert::TryInto;
#[derive(Queryable, Debug, Serialize)] #[derive(Queryable, Debug, Serialize)]
pub struct Member { pub struct Member {
@ -10,7 +11,7 @@ pub struct Member {
pub picurl: String, pub picurl: String,
} }
#[derive(Queryable, Associations)] #[derive(Queryable, Associations, Insertable)]
#[belongs_to(Member)] #[belongs_to(Member)]
#[table_name = "switches"] #[table_name = "switches"]
pub struct Switch { pub struct Switch {
@ -18,7 +19,22 @@ pub struct Switch {
pub member_id: i32, pub member_id: i32,
pub started_at: NaiveDateTime, pub started_at: NaiveDateTime,
pub ended_at: Option<NaiveDateTime>, pub ended_at: Option<NaiveDateTime>,
pub duration: Option<i32>, }
impl Switch {
pub fn duration(&self) -> Option<i32> {
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)] #[derive(Insertable)]
@ -33,5 +49,4 @@ pub struct NewSwitch {
#[table_name = "switches"] #[table_name = "switches"]
pub struct UpdateSwitchTime { pub struct UpdateSwitchTime {
pub ended_at: Option<NaiveDateTime>, pub ended_at: Option<NaiveDateTime>,
pub duration: Option<i32>,
} }

View File

@ -12,7 +12,6 @@ table! {
member_id -> Integer, member_id -> Integer,
started_at -> Timestamp, started_at -> Timestamp,
ended_at -> Nullable<Timestamp>, ended_at -> Nullable<Timestamp>,
duration -> Nullable<Integer>,
} }
} }