Cleanup db stuff

This commit is contained in:
Tobias Reisinger 2021-12-21 12:17:01 +01:00
parent 53ead537ff
commit f3f3d36eed
4 changed files with 950 additions and 66 deletions

View file

@ -13,6 +13,7 @@ use schema::schedules::dsl::*;
pub mod errors;
pub mod models;
pub mod schema;
mod model_utils;
embed_migrations!("migrations");

75
src/db/model_utils.rs Normal file
View file

@ -0,0 +1,75 @@
use chrono::{NaiveTime, Timelike};
use diesel::backend::Backend;
use diesel::deserialize::FromSql;
use diesel::serialize::{IsNull, Output, ToSql};
use diesel::sql_types::Binary;
use diesel::sqlite::Sqlite;
use diesel::{deserialize, serialize};
use serde::{Deserialize, Serialize};
use std::io::Write;
use crate::db::models::Periods;
#[derive(Debug, Serialize, Deserialize, AsExpression, FromSqlRow, PartialEq, Clone)]
#[sql_type = "Binary"]
pub struct Period {
#[serde(with = "period_format")]
pub start: NaiveTime,
#[serde(with = "period_format")]
pub end: NaiveTime,
}
mod period_format {
use chrono::NaiveTime;
use serde::{self, Deserialize, Deserializer, Serializer};
const FORMAT: &'static str = "%H:%M";
pub fn serialize<S>(time: &NaiveTime, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = format!("{}", time.format(FORMAT));
serializer.serialize_str(&s)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<NaiveTime, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
NaiveTime::parse_from_str(&s, FORMAT).map_err(serde::de::Error::custom)
}
}
impl ToSql<Binary, Sqlite> for Periods {
fn to_sql<W: Write>(&self, out: &mut Output<W, Sqlite>) -> serialize::Result {
for period in self.0.iter() {
out.write_all(&[
period.start.hour() as u8,
period.start.minute() as u8,
period.end.hour() as u8,
period.end.minute() as u8,
])?;
}
Ok(IsNull::No)
}
}
impl FromSql<Binary, Sqlite> for Periods {
fn from_sql(bytes: Option<&<Sqlite as Backend>::RawValue>) -> deserialize::Result<Self> {
let blob = bytes.unwrap().read_blob();
let mut vec = Vec::new();
for i in (3..blob.len()).step_by(4) {
let start_val_h: u32 = blob[i - 3] as u32;
let start_val_m: u32 = blob[i - 2] as u32;
let end_val_h: u32 = blob[i - 1] as u32;
let end_val_m: u32 = blob[i - 0] as u32;
vec.push(Period {
start: NaiveTime::from_hms(start_val_h, start_val_m, 0),
end: NaiveTime::from_hms(end_val_h, end_val_m, 0),
});
}
Ok(Periods(vec))
}
}

View file

@ -1,12 +1,6 @@
use chrono::{NaiveTime, Timelike};
use diesel::backend::Backend;
use diesel::deserialize::FromSql;
use diesel::serialize::{IsNull, Output, ToSql};
use diesel::sql_types::Binary;
use diesel::sqlite::Sqlite;
use diesel::{deserialize, serialize};
use serde::{Deserialize, Serialize};
use std::io::Write;
use crate::db::model_utils::Period;
use super::schema::schedules;
use crate::types::EmgauwaUid;
@ -29,71 +23,25 @@ pub struct NewSchedule<'a> {
pub periods: &'a Periods,
}
#[derive(Debug, Serialize, Deserialize, AsExpression, FromSqlRow, PartialEq, Clone)]
#[sql_type = "Binary"]
pub struct Period {
#[serde(with = "period_format")]
pub start: NaiveTime,
#[serde(with = "period_format")]
pub end: NaiveTime,
}
#[derive(Debug, Serialize, Deserialize, AsExpression, FromSqlRow, PartialEq, Clone)]
#[sql_type = "Binary"]
pub struct Periods(pub(crate) Vec<Period>);
mod period_format {
use chrono::NaiveTime;
use serde::{self, Deserialize, Deserializer, Serializer};
const FORMAT: &'static str = "%H:%M";
pub fn serialize<S>(time: &NaiveTime, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = format!("{}", time.format(FORMAT));
serializer.serialize_str(&s)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<NaiveTime, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
NaiveTime::parse_from_str(&s, FORMAT).map_err(serde::de::Error::custom)
}
#[derive(Serialize, Queryable)]
pub struct Tag {
pub id: i32,
pub tag: String,
}
impl ToSql<Binary, Sqlite> for Periods {
fn to_sql<W: Write>(&self, out: &mut Output<W, Sqlite>) -> serialize::Result {
for period in self.0.iter() {
out.write_all(&[
period.start.hour() as u8,
period.start.minute() as u8,
period.end.hour() as u8,
period.end.minute() as u8,
])?;
}
Ok(IsNull::No)
}
#[derive(Insertable)]
#[table_name = "tags"]
pub struct NewTag<'a> {
pub tag: &'a str,
}
impl FromSql<Binary, Sqlite> for Periods {
fn from_sql(bytes: Option<&<Sqlite as Backend>::RawValue>) -> deserialize::Result<Self> {
let blob = bytes.unwrap().read_blob();
let mut vec = Vec::new();
for i in (3..blob.len()).step_by(4) {
let start_val_h: u32 = blob[i - 3] as u32;
let start_val_m: u32 = blob[i - 2] as u32;
let end_val_h: u32 = blob[i - 1] as u32;
let end_val_m: u32 = blob[i - 0] as u32;
vec.push(Period {
start: NaiveTime::from_hms(start_val_h, start_val_m, 0),
end: NaiveTime::from_hms(end_val_h, end_val_m, 0),
});
}
Ok(Periods(vec))
}
#[derive(Insertable)]
#[table_name = "junction_tag_schedule"]
pub struct NewJunctionTagSchedule<'a> {
pub tag_id: i32,
pub schedule_id: i32,
}