diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/db/cards.rs | 99 | ||||
-rw-r--r-- | src/db/mod.rs | 4 |
2 files changed, 69 insertions, 34 deletions
diff --git a/src/db/cards.rs b/src/db/cards.rs index 709e4eb..7778354 100644 --- a/src/db/cards.rs +++ b/src/db/cards.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use rusqlite::{params, Connection}; +use rusqlite::{named_params, Connection}; use crate::model::DbEntry; use crate::util::time; @@ -10,7 +10,8 @@ use crate::{ }; pub fn all(conn: &Connection) -> Result<Vec<DbEntry>> { - let mut stmt = conn.prepare("SELECT question, responses, deleted FROM cards")?; + let query = r#"SELECT question, responses, deleted FROM cards"#; + let mut stmt = conn.prepare(query)?; let res: Result<Vec<DbEntry>, rusqlite::Error> = stmt .query_map([], |row| { @@ -27,6 +28,11 @@ pub fn all(conn: &Connection) -> Result<Vec<DbEntry>> { } pub fn insert(conn: &mut Connection, questions: &Vec<Question>) -> Result<()> { + let query = r#" + INSERT INTO cards (question, responses, state, created, ready) + VALUES (:question, :responses, :state, :created, :ready) + "#; + let now = time::seconds_since_unix_epoch()?; let state = serde_json::to_string(&space_repetition::init())?; @@ -38,11 +44,14 @@ pub fn insert(conn: &mut Connection, questions: &Vec<Question>) -> Result<()> { { let responses = serialization::words_to_line(responses); tx.execute( - " - INSERT INTO cards (question, responses, state, created, ready) - VALUES (?, ?, ?, ?, ?) - ", - params![question, responses, state, now, now], + query, + named_params![ + ":question": question, + ":responses": responses, + ":state": state, + ":created": now, + ":ready": now + ], )?; } tx.commit()?; @@ -50,6 +59,14 @@ pub fn insert(conn: &mut Connection, questions: &Vec<Question>) -> Result<()> { } pub fn delete(conn: &mut Connection, questions: &Vec<Question>) -> Result<()> { + let query = r#" + UPDATE cards + SET deleted = :deleted + WHERE + question = :question + AND responses = :responses + "#; + let now = time::seconds_since_unix_epoch()?; let tx = conn.transaction()?; @@ -60,8 +77,12 @@ pub fn delete(conn: &mut Connection, questions: &Vec<Question>) -> Result<()> { { let responses = serialization::words_to_line(responses); tx.execute( - "UPDATE cards SET deleted = ? WHERE question = ? AND responses = ?", - params![now, question, responses], + query, + named_params![ + ":deleted": now, + ":question": question, + ":responses": responses + ], )?; } tx.commit()?; @@ -69,6 +90,14 @@ pub fn delete(conn: &mut Connection, questions: &Vec<Question>) -> Result<()> { } pub fn undelete(conn: &mut Connection, questions: &Vec<Question>) -> Result<()> { + let query = r#" + UPDATE cards + SET deleted = NULL + WHERE + question = :questions + AND responses = :responses + "#; + let tx = conn.transaction()?; for Question { question, @@ -77,8 +106,11 @@ pub fn undelete(conn: &mut Connection, questions: &Vec<Question>) -> Result<()> { let responses = serialization::words_to_line(responses); tx.execute( - "UPDATE cards SET deleted = NULL WHERE question = ? AND responses = ?", - params![question, responses], + query, + named_params![ + ":question": question, + ":responses": responses + ], )?; } tx.commit()?; @@ -86,21 +118,18 @@ pub fn undelete(conn: &mut Connection, questions: &Vec<Question>) -> Result<()> } pub fn pick_random_ready(conn: &Connection) -> Option<Card> { - let now = time::seconds_since_unix_epoch().ok()?; - - let mut stmt = conn - .prepare( - " + let query = r#" SELECT question, responses, state, ready FROM cards - WHERE deleted IS NULL AND ready <= ? + WHERE deleted IS NULL AND ready <= :ready ORDER BY RANDOM() LIMIT 1 - ", - ) - .ok()?; + "#; - let mut rows = stmt.query([now]).ok()?; + let now = time::seconds_since_unix_epoch().ok()?; + + let mut stmt = conn.prepare(query).ok()?; + let mut rows = stmt.query(named_params![":ready": now]).ok()?; let row = rows.next().ok()??; let state_str: String = row.get(2).ok()?; let responses_str: String = row.get(1).ok()?; @@ -113,18 +142,15 @@ pub fn pick_random_ready(conn: &Connection) -> Option<Card> { } pub fn next_ready(conn: &Connection) -> Option<u64> { - let mut stmt = conn - .prepare( - " + let query = r#" SELECT ready FROM cards WHERE deleted IS NULL ORDER BY ready LIMIT 1 - ", - ) - .ok()?; + "#; + let mut stmt = conn.prepare(query).ok()?; let mut rows = stmt.query([]).ok()?; let row = rows.next().ok()??; row.get(0).ok()? @@ -142,17 +168,24 @@ pub fn count_available(conn: &Connection) -> Option<i32> { } pub fn update(conn: &Connection, question: &str, state: &space_repetition::State) -> Result<()> { + let query = r#" + UPDATE cards + SET state = :state, updated = :updated, ready = :ready + WHERE question = :question + "#; + let now = time::seconds_since_unix_epoch()?; let ready = now + state.get_interval_seconds(); let state_str = serde_json::to_string(state)?; conn.execute( - " - UPDATE cards - SET state = ?, updated = ?, ready = ? - WHERE question = ? - ", - params![state_str, now, ready, question], + query, + named_params![ + ":state": state_str, + ":updated": now, + ":ready": ready, + ":question": question + ], )?; Ok(()) diff --git a/src/db/mod.rs b/src/db/mod.rs index 67d9a93..210f5e9 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -15,7 +15,9 @@ pub fn init(database: &str) -> Result<Connection> { fn apply_migrations(conn: &mut Connection) -> Result<()> { let migrations = Migrations::new(vec![ M::up(include_str!("migrations/01-init.sql")), - M::up(include_str!("migrations/02-primary-key-question-responses.sql")), + M::up(include_str!( + "migrations/02-primary-key-question-responses.sql" + )), M::up(include_str!("migrations/03-drop-deck-read.sql")), M::up(include_str!("migrations/04-strict-tables.sql")), ]); |