feat: add event database entities
This commit is contained in:
parent
1bc9ae01d8
commit
d7c5c85460
6 changed files with 107 additions and 2 deletions
88
src/db/event.rs
Normal file
88
src/db/event.rs
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
use std::{fmt::Display, str::FromStr};
|
||||
|
||||
use chrono::Utc;
|
||||
use r2d2_sqlite::rusqlite::{
|
||||
self,
|
||||
types::{FromSql, FromSqlError},
|
||||
Row, ToSql,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum EventType {
|
||||
Watering,
|
||||
}
|
||||
|
||||
impl ToString for EventType {
|
||||
fn to_string(&self) -> String {
|
||||
String::from(match self {
|
||||
Self::Watering => "watering",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ParseEventTypeErr;
|
||||
|
||||
impl Display for ParseEventTypeErr {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "invalid name")
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for ParseEventTypeErr {}
|
||||
|
||||
impl FromStr for EventType {
|
||||
type Err = ParseEventTypeErr;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"watering" => Ok(Self::Watering),
|
||||
_ => Err(ParseEventTypeErr),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSql for EventType {
|
||||
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
|
||||
Ok(self.to_string().into())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromSql for EventType {
|
||||
fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
|
||||
value
|
||||
.as_str()?
|
||||
.parse()
|
||||
.map_err(|e| FromSqlError::Other(Box::new(e)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Event {
|
||||
id: i32,
|
||||
plant_id: i32,
|
||||
event_type: EventType,
|
||||
time: chrono::DateTime<Utc>,
|
||||
description: String,
|
||||
}
|
||||
|
||||
impl Event {
|
||||
pub fn from_row(row: Row<'_>) -> rusqlite::Result<Self> {
|
||||
Ok(Self {
|
||||
id: row.get("id")?,
|
||||
plant_id: row.get("plant_id")?,
|
||||
event_type: row.get("event_type")?,
|
||||
time: row.get("time")?,
|
||||
description: row.get("description")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct NewEvent {
|
||||
plant_id: i32,
|
||||
event_type: EventType,
|
||||
time: chrono::DateTime<Utc>,
|
||||
description: String,
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
mod comment;
|
||||
mod event;
|
||||
mod plant;
|
||||
|
||||
use r2d2_sqlite::{rusqlite, SqliteConnectionManager};
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ use r2d2_sqlite::SqliteConnectionManager;
|
|||
use tera::Tera;
|
||||
use tower_http::compression::CompressionLayer;
|
||||
|
||||
const MIGRATIONS: [&str; 3] = [
|
||||
const MIGRATIONS: [&str; 4] = [
|
||||
include_str!("migrations/000_initial.sql"),
|
||||
include_str!("migrations/001_plants.sql"),
|
||||
include_str!("migrations/002_comments.sql"),
|
||||
include_str!("migrations/003_events.sql"),
|
||||
];
|
||||
const STATIC_FILES: [(&str, &'static str); 1] = [(
|
||||
"htmx_2.0.4.min.js",
|
||||
|
|
|
|||
9
src/migrations/003_events.sql
Normal file
9
src/migrations/003_events.sql
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
create table events (
|
||||
id integer primary key,
|
||||
plant_id integer not null
|
||||
references plants (id)
|
||||
on delete cascade,
|
||||
event_type text not null,
|
||||
time text not null,
|
||||
description text not null
|
||||
);
|
||||
Loading…
Add table
Add a link
Reference in a new issue