mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 22:42:25 -04:00
add (currently disabled) check for missing/empty decks on card add
This commit is contained in:
parent
d3b27c302c
commit
36531ea96d
4 changed files with 58 additions and 10 deletions
|
@ -7,6 +7,7 @@ use crate::log::Logger;
|
|||
use crate::timestamp::TimestampSecs;
|
||||
use crate::types::Usn;
|
||||
use crate::{
|
||||
decks::{Deck, DeckID},
|
||||
notetype::{NoteType, NoteTypeID},
|
||||
sched::cutoff::{sched_timing_today, SchedTimingToday},
|
||||
storage::SqliteStorage,
|
||||
|
@ -52,6 +53,7 @@ pub struct CollectionState {
|
|||
pub(crate) undo: UndoManager,
|
||||
timing_today: Option<SchedTimingToday>,
|
||||
pub(crate) notetype_cache: HashMap<NoteTypeID, Arc<NoteType>>,
|
||||
pub(crate) deck_cache: HashMap<DeckID, Arc<Deck>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use crate::define_newtype;
|
||||
use crate::{collection::Collection, define_newtype, err::Result};
|
||||
|
||||
mod schema11;
|
||||
pub use schema11::Deck;
|
||||
use std::sync::Arc;
|
||||
|
||||
define_newtype!(DeckID, i64);
|
||||
|
||||
|
@ -25,3 +26,24 @@ pub(crate) fn get_deck(decks: &[Deck], id: DeckID) -> Option<&Deck> {
|
|||
|
||||
None
|
||||
}
|
||||
|
||||
impl Deck {
|
||||
pub(crate) fn is_filtered(&self) -> bool {
|
||||
matches!(self, Deck::Filtered(_))
|
||||
}
|
||||
}
|
||||
|
||||
impl Collection {
|
||||
pub(crate) fn get_deck(&mut self, did: DeckID) -> Result<Option<Arc<Deck>>> {
|
||||
if let Some(deck) = self.state.deck_cache.get(&did) {
|
||||
return Ok(Some(deck.clone()));
|
||||
}
|
||||
if let Some(deck) = self.storage.get_deck(did)? {
|
||||
let deck = Arc::new(deck);
|
||||
self.state.deck_cache.insert(did, deck.clone());
|
||||
Ok(Some(deck))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -216,7 +216,7 @@ impl Collection {
|
|||
note: &Note,
|
||||
) -> Result<()> {
|
||||
let existing = self.storage.existing_cards_for_note(note.id)?;
|
||||
self.generate_cards_for_note(ctx, note, &existing, None)
|
||||
self.generate_cards_for_note(ctx, note, &existing, Some(ctx.notetype.target_deck_id()))
|
||||
}
|
||||
|
||||
fn generate_cards_for_note(
|
||||
|
@ -230,7 +230,7 @@ impl Collection {
|
|||
if cards.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
self.add_generated_cards(ctx, note.id, &cards, target_deck_id)
|
||||
self.add_generated_cards(note.id, &cards, target_deck_id)
|
||||
}
|
||||
|
||||
pub(crate) fn generate_cards_for_notetype(&mut self, ctx: &CardGenContext) -> Result<()> {
|
||||
|
@ -253,19 +253,13 @@ impl Collection {
|
|||
|
||||
pub(crate) fn add_generated_cards(
|
||||
&mut self,
|
||||
ctx: &CardGenContext,
|
||||
nid: NoteID,
|
||||
cards: &[CardToGenerate],
|
||||
target_deck_id: Option<DeckID>,
|
||||
) -> Result<()> {
|
||||
let mut next_pos = None;
|
||||
for c in cards {
|
||||
// fixme: deal with case where invalid deck pointed to
|
||||
// fixme: deprecated note type deck id
|
||||
let did = c
|
||||
.did
|
||||
.or(target_deck_id)
|
||||
.unwrap_or_else(|| ctx.notetype.target_deck_id());
|
||||
let did = self.deck_id_for_adding(c.did.or(target_deck_id))?;
|
||||
let due = c.due.unwrap_or_else(|| {
|
||||
if next_pos.is_none() {
|
||||
next_pos = Some(self.get_and_update_next_card_position().unwrap_or(0));
|
||||
|
@ -278,4 +272,28 @@ impl Collection {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// If deck ID does not exist or points to a filtered deck, fall back on default.
|
||||
fn deck_id_for_adding(&mut self, did: Option<DeckID>) -> Result<DeckID> {
|
||||
if let Some(did) = did.and_then(|did| self.deck_id_if_normal(did)) {
|
||||
Ok(did)
|
||||
} else {
|
||||
self.default_deck_id()
|
||||
}
|
||||
}
|
||||
|
||||
fn default_deck_id(&mut self) -> Result<DeckID> {
|
||||
// currently hard-coded, we could create this as needed in the future
|
||||
Ok(DeckID(1))
|
||||
}
|
||||
|
||||
/// If deck exists and and is a normal deck, return it.
|
||||
fn deck_id_if_normal(&mut self, did: DeckID) -> Option<DeckID> {
|
||||
// fixme: currently disabled until deck writes are immediate
|
||||
return Some(did);
|
||||
|
||||
self.get_deck(did)
|
||||
.ok()
|
||||
.and_then(|opt| opt.and_then(|d| if !d.is_filtered() { Some(d.id()) } else { None }))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,4 +22,10 @@ impl SqliteStorage {
|
|||
self.db.execute("update col set decks = ?", &[json])?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn get_deck(&self, did: DeckID) -> Result<Option<Deck>> {
|
||||
// fixme: this is just temporary until we create an extra table
|
||||
let mut decks = self.get_all_decks()?;
|
||||
Ok(decks.remove(&did))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue