aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/db/cards.rs99
-rw-r--r--src/db/mod.rs4
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")),
]);