import data from rethinkdb
This commit is contained in:
parent
66507e82b1
commit
768bd412b0
|
@ -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)
|
||||||
);
|
);
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -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,
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"),
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
|
@ -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();
|
||||||
|
|
|
@ -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>,
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue