use crate::core::srs::OrderMode; use crate::data::entities::{CardState, DeckSettings}; use crate::data_provider::TableAccessQuerySet; use crate::notification::NotificationData::{DbLoadError, DbSaveError}; use crate::notification::{MaybeError, NotificationData}; use chrono::NaiveDate; use rusqlite::{Connection, Error, Params, Row}; pub struct DeckQuerySet; impl TableAccessQuerySet for DeckQuerySet { fn load() -> &'static str { "SELECT id, name, forward, backward, filter FROM decks" } fn save() -> &'static str { "UPDATE decks SET name = ?1, forward = ?2, backward = ?3, filter = ?4 WHERE id = ?5" } fn add() -> &'static str { "INSERT INTO states (word_id, set_id, score, last_opened, fsrs_opened, fsrs_memory, fsrs_open_day) VALUES (?1, ?2, ?3, ?4)" } fn name() -> &'static str { "decks" } fn from_sql(row: &Row) -> Result { Ok(DeckSettings { id: row.get(0)?, name: row.get(1)?, forward: row.get(2)?, backward: row.get(3)?, filter: row.get(4)?, count: None, open_mode: OrderMode::Default, }) } fn insert_params(entity: &DeckSettings) -> impl Params { ( &entity.name, &entity.forward, &entity.backward, &entity.filter, ) } fn update_params(entity: &DeckSettings) -> impl Params { (&entity.name, &entity.forward, &entity.backward, &entity.filter, entity.id) } } pub fn load_sets(connection: &Connection) -> Result, NotificationData> { let mut stmt = connection .prepare("SELECT id, name, forward, backward, filter FROM decks") .expect("Failed to prepare state query"); let iter = stmt .query_map([], |row| { Ok(DeckSettings { id: row.get(0)?, name: row.get(1)?, forward: row.get(2)?, backward: row.get(3)?, filter: row.get(4)?, count: None, open_mode: OrderMode::Default, }) }) .map_err(|_| DbLoadError)?; let mut buffer = Vec::with_capacity(16); iter.filter_map(|res| res.ok()).for_each(|i| buffer.push(i)); Ok(buffer) } pub fn add_set(set: &mut DeckSettings, connection: &Connection) -> MaybeError { let index : u32 = connection .query_row( "INSERT INTO decks (name, forward, backward, filter) VALUES (?1, ?2, ?3, ?4) RETURNING id", ( &set.name, &set.forward, &set.backward, &set.filter, ), |row| row.get(0) ) .map_err(|_| DbSaveError)?; set.id = index.into(); Ok(()) } pub fn update_deck(set: &mut DeckSettings, connection: &Connection) -> MaybeError { if !set.id.is_valid() { add_set(set, connection)?; } else { connection .execute( "UPDATE decks SET name = ?1, forward = ?2, backward = ?3, filter = ?4 WHERE id = ?5", ( &set.name, &set.forward, &set.backward, &set.filter, &set.id ), ) .map_err(|_| DbSaveError)?; } Ok(()) } pub fn delete_set(set: &DeckSettings, connection: &Connection) -> MaybeError { if !set.id.is_valid() { return Err(DbSaveError); } connection .execute("DELETE FROM decks WHERE id = ?1", (&set.id,)) .map_err(|_| DbSaveError)?; Ok(()) }