add (unused) add_card, and move sql to separate files

This commit is contained in:
Damien Elmes 2020-03-27 14:39:38 +10:00
parent 82ed288dc5
commit 6b9378fb41
6 changed files with 169 additions and 19 deletions

View File

@ -87,12 +87,22 @@ impl Default for Card {
}
impl RequestContext<'_> {
pub fn update_card(&mut self, card: &mut Card) -> Result<()> {
pub(crate) fn update_card(&mut self, card: &mut Card) -> Result<()> {
if card.id.0 == 0 {
return Err(AnkiError::invalid_input("card id not set"));
}
card.mtime = TimestampSecs::now();
card.usn = self.storage.usn()?;
self.storage.flush_card(card)
self.storage.update_card(card)
}
#[allow(dead_code)]
pub(crate) fn add_card(&mut self, card: &mut Card) -> Result<()> {
if card.id.0 != 0 {
return Err(AnkiError::invalid_input("card id already set"));
}
card.mtime = TimestampSecs::now();
card.usn = self.storage.usn()?;
self.storage.add_card(card)
}
}

View File

@ -0,0 +1,54 @@
insert into cards (
id,
nid,
did,
ord,
mod,
usn,
type,
queue,
due,
ivl,
factor,
reps,
lapses,
left,
odue,
odid,
flags,
data
)
values
(
(
case
when ?1 in (
select
id
from cards
) then (
select
max(id) + 1
from cards
)
else ?1
end
),
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?
)

View File

@ -0,0 +1,23 @@
-- the casts are required as Anki didn't prevent add-ons from
-- storing strings or floats in columns before
select
nid,
did,
ord,
cast(mod as integer),
usn,
type,
queue,
due,
cast(ivl as integer),
factor,
reps,
lapses,
left,
odue,
odid,
flags,
data
from cards
where
id = ?

View File

@ -4,6 +4,7 @@
use super::sqlite::CachedStatementKind;
use crate::card::{Card, CardID, CardQueue, CardType};
use crate::err::Result;
use crate::timestamp::TimestampMillis;
use rusqlite::params;
use rusqlite::{
types::{FromSql, FromSqlError, ValueRef},
@ -33,14 +34,9 @@ impl FromSql for CardQueue {
impl super::StorageContext<'_> {
pub fn get_card(&mut self, cid: CardID) -> Result<Option<Card>> {
// the casts are required as Anki didn't prevent add-ons from
// storing strings or floats in columns before
self.with_cached_stmt(
CachedStatementKind::GetCard,
"
select nid, did, ord, cast(mod as integer), usn, type, queue, due,
cast(ivl as integer), factor, reps, lapses, left, odue, odid,
flags, data from cards where id=?",
include_str!("get_card.sql"),
|stmt| {
stmt.query_row(params![cid], |row| {
Ok(Card {
@ -70,19 +66,44 @@ flags, data from cards where id=?",
)
}
pub(crate) fn flush_card(&mut self, card: &Card) -> Result<()> {
pub(crate) fn update_card(&mut self, card: &Card) -> Result<()> {
self.with_cached_stmt(
CachedStatementKind::FlushCard,
"
insert or replace into cards
(id, nid, did, ord, mod, usn, type, queue, due, ivl, factor,
reps, lapses, left, odue, odid, flags, data)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
",
CachedStatementKind::UpdateCard,
include_str!("update_card.sql"),
|stmt| {
stmt.execute(params![
card.nid,
card.did,
card.ord,
card.mtime,
card.usn,
card.ctype as u8,
card.queue as i8,
card.due,
card.ivl,
card.factor,
card.reps,
card.lapses,
card.left,
card.odue,
card.odid,
card.flags,
card.data,
card.id,
])?;
Ok(())
},
)
}
pub(crate) fn add_card(&mut self, card: &mut Card) -> Result<()> {
let now = TimestampMillis::now().0;
self.with_cached_stmt(
CachedStatementKind::AddCard,
include_str!("add_card.sql"),
|stmt| {
stmt.execute(params![
now,
card.nid,
card.did,
card.ord,
@ -103,6 +124,25 @@ values
])?;
Ok(())
},
)
)?;
card.id = CardID(self.db.last_insert_rowid());
Ok(())
}
}
#[cfg(test)]
mod test {
use crate::{card::Card, storage::SqliteStorage};
use std::path::Path;
#[test]
fn add_card() {
let storage = SqliteStorage::open_or_create(Path::new(":memory:")).unwrap();
let mut ctx = storage.context(false);
let mut card = Card::default();
ctx.add_card(&mut card).unwrap();
let id1 = card.id;
ctx.add_card(&mut card).unwrap();
assert_ne!(id1, card.id);
}
}

View File

@ -0,0 +1,21 @@
update cards
set
nid = ?,
did = ?,
ord = ?,
mod = ?,
usn = ?,
type = ?,
queue = ?,
due = ?,
ivl = ?,
factor = ?,
reps = ?,
lapses = ?,
left = ?,
odue = ?,
odid = ?,
flags = ?,
data = ?
where
id = ?

View File

@ -205,9 +205,11 @@ impl SqliteStorage {
}
#[derive(Clone, Copy, VariantCount)]
#[allow(clippy::enum_variant_names)]
pub(super) enum CachedStatementKind {
GetCard,
FlushCard,
UpdateCard,
AddCard,
}
pub(crate) struct StorageContext<'a> {