use crate::lang::{CardStatistics, DeckSettings}; use rusqlite::{Connection, params}; use std::time::Instant; pub fn load_stats_of_deck(set: &DeckSettings, connection: &Connection) -> Vec { let mut stmt = connection .prepare("SELECT id, word_id, score, last_opened FROM card_stats WHERE set_id = ?1") .unwrap(); let iter = stmt .query_map((set.id,), |row| { Ok(CardStatistics { id: row.get(0)?, word_id: row.get(1)?, set_id: set.id, score: row.get(2)?, last_open: row.get(3)?, }) }) .unwrap(); let mut buffer = vec![]; for word in iter { buffer.push(word.unwrap()); } buffer } pub fn add_stat_list(stats: &mut [CardStatistics], connection: &mut Connection) { let time = Instant::now(); let tx = connection.transaction().unwrap(); let count = stats.len(); { let mut stmt = tx .prepare( "INSERT INTO card_stats (word_id, set_id, score, last_opened) VALUES (?1, ?2, ?3, ?4)", ) .unwrap(); for stat in stats.iter() { stmt.execute(params![ stat.word_id, stat.set_id, stat.score, stat.last_open.timestamp() ]) .unwrap(); } } let last_index: u32 = tx.last_insert_rowid() as u32; tx.commit().unwrap(); let start_index = last_index - (count as u32) + 1; for (index, id) in (start_index..=last_index).enumerate() { stats[index].id = id.into(); } println!("Added {} cards for {:?}", stats.len(), time.elapsed()); } pub fn update_stat_score(stat: &CardStatistics, connection: &Connection) { let time = Instant::now(); connection .execute( "UPDATE card_stats SET score = ?1, last_opened = ?2 WHERE id = ?3", (&stat.score, &stat.last_open.timestamp(), &stat.id), ) .unwrap(); println!("Updated stat: {}", time.elapsed().as_millis()); } pub fn delete_stat(stat: &CardStatistics, connection: &Connection) { if !stat.id.is_valid() { return; } connection .execute("DELETE FROM card_stats WHERE id = ?1", (&stat.id,)) .unwrap(); }