mirror of
https://github.com/ankitects/anki.git
synced 2026-01-15 23:09:00 -05:00
98 lines
2.9 KiB
Rust
98 lines
2.9 KiB
Rust
// Copyright: Ankitects Pty Ltd and contributors
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
use std::convert::TryFrom;
|
|
|
|
use num_enum::TryFromPrimitive;
|
|
use rusqlite::params;
|
|
|
|
use super::SqliteStorage;
|
|
use crate::{
|
|
card::CardId,
|
|
decks::DeckId,
|
|
error::{AnkiError, Result},
|
|
notes::NoteId,
|
|
sync::Graves,
|
|
types::Usn,
|
|
};
|
|
|
|
#[derive(TryFromPrimitive)]
|
|
#[repr(u8)]
|
|
enum GraveKind {
|
|
Card,
|
|
Note,
|
|
Deck,
|
|
}
|
|
|
|
impl SqliteStorage {
|
|
pub(crate) fn clear_all_graves(&self) -> Result<()> {
|
|
self.db.execute("delete from graves", [])?;
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) fn add_card_grave(&self, cid: CardId, usn: Usn) -> Result<()> {
|
|
self.add_grave(cid.0, GraveKind::Card, usn)
|
|
}
|
|
|
|
pub(crate) fn add_note_grave(&self, nid: NoteId, usn: Usn) -> Result<()> {
|
|
self.add_grave(nid.0, GraveKind::Note, usn)
|
|
}
|
|
|
|
pub(crate) fn add_deck_grave(&self, did: DeckId, usn: Usn) -> Result<()> {
|
|
self.add_grave(did.0, GraveKind::Deck, usn)
|
|
}
|
|
|
|
pub(crate) fn remove_card_grave(&self, cid: CardId) -> Result<()> {
|
|
self.remove_grave(cid.0, GraveKind::Card)
|
|
}
|
|
|
|
pub(crate) fn remove_note_grave(&self, nid: NoteId) -> Result<()> {
|
|
self.remove_grave(nid.0, GraveKind::Note)
|
|
}
|
|
|
|
pub(crate) fn remove_deck_grave(&self, did: DeckId) -> Result<()> {
|
|
self.remove_grave(did.0, GraveKind::Deck)
|
|
}
|
|
|
|
pub(crate) fn pending_graves(&self, pending_usn: Usn) -> Result<Graves> {
|
|
let mut stmt = self.db.prepare(&format!(
|
|
"select oid, type from graves where {}",
|
|
pending_usn.pending_object_clause()
|
|
))?;
|
|
let mut rows = stmt.query([pending_usn])?;
|
|
let mut graves = Graves::default();
|
|
while let Some(row) = rows.next()? {
|
|
let oid: i64 = row.get(0)?;
|
|
let kind = GraveKind::try_from(row.get::<_, u8>(1)?)
|
|
.map_err(|_| AnkiError::invalid_input("invalid grave kind"))?;
|
|
match kind {
|
|
GraveKind::Card => graves.cards.push(CardId(oid)),
|
|
GraveKind::Note => graves.notes.push(NoteId(oid)),
|
|
GraveKind::Deck => graves.decks.push(DeckId(oid)),
|
|
}
|
|
}
|
|
Ok(graves)
|
|
}
|
|
|
|
pub(crate) fn update_pending_grave_usns(&self, new_usn: Usn) -> Result<()> {
|
|
self.db
|
|
.prepare("update graves set usn=? where usn=-1")?
|
|
.execute([new_usn])?;
|
|
Ok(())
|
|
}
|
|
|
|
fn add_grave(&self, oid: i64, kind: GraveKind, usn: Usn) -> Result<()> {
|
|
self.db
|
|
.prepare_cached(include_str!("add.sql"))?
|
|
.execute(params![usn, oid, kind as u8])?;
|
|
Ok(())
|
|
}
|
|
|
|
/// Only useful when undoing
|
|
fn remove_grave(&self, oid: i64, kind: GraveKind) -> Result<()> {
|
|
self.db
|
|
.prepare_cached(include_str!("remove.sql"))?
|
|
.execute(params![oid, kind as u8])?;
|
|
Ok(())
|
|
}
|
|
}
|