use crate::db::db::Db;
use anyhow::Result;
use chrono::{Duration, NaiveDate, NaiveDateTime};
use rusqlite::params;
#[derive(Debug, Clone)]
pub struct Break {
pub id: Option<i64>,
pub date: NaiveDate,
pub start: NaiveDateTime,
pub end: NaiveDateTime,
pub duration: Duration,
pub reason: Option<String>,
pub created_at: Option<NaiveDateTime>,
}
pub struct Breaks {
db: Db,
}
impl Breaks {
pub fn new() -> Result<Self> {
let db = Db::new()?;
Ok(Self { db })
}
pub fn insert(&self, break_record: &Break) -> Result<i64> {
let conn = &self.db.conn;
let _result = conn.execute(
"INSERT INTO breaks (date, start_time, end_time, duration, reason, created_at)
VALUES (?1, ?2, ?3, ?4, ?5, datetime('now'))",
params![
break_record.date,
break_record.start,
break_record.end,
break_record.duration.num_minutes(),
break_record.reason,
],
)?;
Ok(conn.last_insert_rowid())
}
pub fn get_daily_breaks(&self, date: NaiveDate) -> Result<Vec<Break>> {
let conn = &self.db.conn;
let mut stmt = conn.prepare(
"SELECT id, date, start_time, end_time, duration, reason, created_at
FROM breaks
WHERE date = ?1
ORDER BY start_time"
)?;
let break_iter = stmt.query_map(params![date], |row| {
Ok(Break {
id: Some(row.get(0)?),
date: row.get(1)?,
start: row.get(2)?,
end: row.get(3)?,
duration: Duration::minutes(row.get::<_, i64>(4)?),
reason: row.get(5)?,
created_at: row.get(6)?,
})
})?;
let mut breaks = Vec::new();
for break_result in break_iter {
breaks.push(break_result?);
}
Ok(breaks)
}
pub fn delete(&self, id: i64) -> Result<()> {
let conn = &self.db.conn;
let affected_rows = conn.execute("DELETE FROM breaks WHERE id = ?1", params![id])?;
if affected_rows == 0 {
return Err(anyhow::anyhow!("Break record with ID {} not found", id));
}
Ok(())
}
pub fn get_by_id(&self, id: i64) -> Result<Option<Break>> {
let conn = &self.db.conn;
let mut stmt = conn.prepare(
"SELECT id, date, start_time, end_time, duration, reason, created_at
FROM breaks
WHERE id = ?1"
)?;
let mut break_iter = stmt.query_map(params![id], |row| {
Ok(Break {
id: Some(row.get(0)?),
date: row.get(1)?,
start: row.get(2)?,
end: row.get(3)?,
duration: Duration::minutes(row.get::<_, i64>(4)?),
reason: row.get(5)?,
created_at: row.get(6)?,
})
})?;
match break_iter.next() {
Some(break_result) => Ok(Some(break_result?)),
None => Ok(None),
}
}
}