mirror of
https://github.com/ankitects/anki.git
synced 2025-09-22 16:02:23 -04:00
cache notetypes
This commit is contained in:
parent
1ca7fb4a80
commit
a226f70733
5 changed files with 49 additions and 34 deletions
|
@ -7,11 +7,12 @@ use crate::log::Logger;
|
||||||
use crate::timestamp::TimestampSecs;
|
use crate::timestamp::TimestampSecs;
|
||||||
use crate::types::Usn;
|
use crate::types::Usn;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
notetype::{NoteType, NoteTypeID},
|
||||||
sched::cutoff::{sched_timing_today, SchedTimingToday},
|
sched::cutoff::{sched_timing_today, SchedTimingToday},
|
||||||
storage::SqliteStorage,
|
storage::SqliteStorage,
|
||||||
undo::UndoManager,
|
undo::UndoManager,
|
||||||
};
|
};
|
||||||
use std::path::PathBuf;
|
use std::{collections::HashMap, path::PathBuf, sync::Arc};
|
||||||
|
|
||||||
pub fn open_collection<P: Into<PathBuf>>(
|
pub fn open_collection<P: Into<PathBuf>>(
|
||||||
path: P,
|
path: P,
|
||||||
|
@ -50,6 +51,7 @@ pub struct CollectionState {
|
||||||
task_state: CollectionTaskState,
|
task_state: CollectionTaskState,
|
||||||
pub(crate) undo: UndoManager,
|
pub(crate) undo: UndoManager,
|
||||||
timing_today: Option<SchedTimingToday>,
|
timing_today: Option<SchedTimingToday>,
|
||||||
|
pub(crate) notetype_cache: HashMap<NoteTypeID, Arc<NoteType>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
|
|
@ -380,7 +380,7 @@ where
|
||||||
renamed: &HashMap<String, String>,
|
renamed: &HashMap<String, String>,
|
||||||
) -> Result<HashSet<String>> {
|
) -> Result<HashSet<String>> {
|
||||||
let mut referenced_files = HashSet::new();
|
let mut referenced_files = HashSet::new();
|
||||||
let note_types = self.ctx.storage.get_all_notetype_core()?;
|
let note_types = self.ctx.get_all_notetypes()?;
|
||||||
let mut collection_modified = false;
|
let mut collection_modified = false;
|
||||||
|
|
||||||
let nids = self.ctx.search_notes("")?;
|
let nids = self.ctx.search_notes("")?;
|
||||||
|
|
|
@ -30,7 +30,10 @@ use crate::{
|
||||||
timestamp::TimestampSecs,
|
timestamp::TimestampSecs,
|
||||||
types::Usn,
|
types::Usn,
|
||||||
};
|
};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::{
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
use unicase::UniCase;
|
use unicase::UniCase;
|
||||||
|
|
||||||
define_newtype!(NoteTypeID, i64);
|
define_newtype!(NoteTypeID, i64);
|
||||||
|
@ -200,11 +203,45 @@ impl Collection {
|
||||||
.get_notetype(nt.id)?
|
.get_notetype(nt.id)?
|
||||||
.ok_or_else(|| AnkiError::invalid_input("no such notetype"))?;
|
.ok_or_else(|| AnkiError::invalid_input("no such notetype"))?;
|
||||||
col.update_notes_for_changed_fields(nt, existing_notetype.fields.len())?;
|
col.update_notes_for_changed_fields(nt, existing_notetype.fields.len())?;
|
||||||
|
// fixme: card templates
|
||||||
|
// fixme: update cache instead of clearing
|
||||||
|
col.state.notetype_cache.remove(&nt.id);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_notetype_by_name(&mut self, name: &str) -> Result<Option<NoteType>> {
|
pub fn get_notetype_by_name(&mut self, name: &str) -> Result<Option<Arc<NoteType>>> {
|
||||||
self.storage.get_notetype_by_name(name)
|
if let Some(ntid) = self.storage.get_notetype_id(name)? {
|
||||||
|
self.get_notetype(ntid)
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_notetype(&mut self, ntid: NoteTypeID) -> Result<Option<Arc<NoteType>>> {
|
||||||
|
if let Some(nt) = self.state.notetype_cache.get(&ntid) {
|
||||||
|
return Ok(Some(nt.clone()));
|
||||||
|
}
|
||||||
|
if let Some(nt) = self.storage.get_notetype(ntid)? {
|
||||||
|
let nt = Arc::new(nt);
|
||||||
|
self.state.notetype_cache.insert(ntid, nt.clone());
|
||||||
|
Ok(Some(nt))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_all_notetypes(&mut self) -> Result<HashMap<NoteTypeID, Arc<NoteType>>> {
|
||||||
|
self.storage
|
||||||
|
.get_all_notetype_names()?
|
||||||
|
.into_iter()
|
||||||
|
.map(|(ntid, _)| {
|
||||||
|
self.get_notetype(ntid)
|
||||||
|
.transpose()
|
||||||
|
.unwrap()
|
||||||
|
.map(|nt| (ntid, nt))
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,12 +297,11 @@ impl SqlWriter<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_single_field(&mut self, field_name: &str, val: &str, is_re: bool) -> Result<()> {
|
fn write_single_field(&mut self, field_name: &str, val: &str, is_re: bool) -> Result<()> {
|
||||||
let note_types = self.col.storage.get_all_notetype_core()?;
|
let note_types = self.col.get_all_notetypes()?;
|
||||||
|
|
||||||
let mut field_map = vec![];
|
let mut field_map = vec![];
|
||||||
for nt in note_types.values() {
|
for nt in note_types.values() {
|
||||||
let fields = self.col.storage.get_notetype_fields(nt.id)?;
|
for field in &nt.fields {
|
||||||
for field in &fields {
|
|
||||||
if matches_wildcard(&field.name, field_name) {
|
if matches_wildcard(&field.name, field_name) {
|
||||||
field_map.push((nt.id, field.ord));
|
field_map.push((nt.id, field.ord));
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,21 +46,7 @@ impl SqliteStorage {
|
||||||
.transpose()
|
.transpose()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_all_notetype_core(&self) -> Result<HashMap<NoteTypeID, NoteType>> {
|
fn get_notetype_fields(&self, ntid: NoteTypeID) -> Result<Vec<NoteField>> {
|
||||||
let mut nts: HashMap<NoteTypeID, NoteType> = self
|
|
||||||
.db
|
|
||||||
.prepare_cached(include_str!("get_notetype.sql"))?
|
|
||||||
.query_and_then(NO_PARAMS, row_to_notetype_core)?
|
|
||||||
.map(|ntres| ntres.map(|nt| (nt.id, nt)))
|
|
||||||
.collect::<Result<_>>()?;
|
|
||||||
for nt in nts.values_mut() {
|
|
||||||
nt.fields = self.get_notetype_fields(nt.id)?;
|
|
||||||
}
|
|
||||||
Ok(nts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// pub as currently used by searching code
|
|
||||||
pub(crate) fn get_notetype_fields(&self, ntid: NoteTypeID) -> Result<Vec<NoteField>> {
|
|
||||||
self.db
|
self.db
|
||||||
.prepare_cached(include_str!("get_fields.sql"))?
|
.prepare_cached(include_str!("get_fields.sql"))?
|
||||||
.query_and_then(&[ntid], |row| {
|
.query_and_then(&[ntid], |row| {
|
||||||
|
@ -90,7 +76,7 @@ impl SqliteStorage {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_notetype_id(&self, name: &str) -> Result<Option<NoteTypeID>> {
|
pub(crate) fn get_notetype_id(&self, name: &str) -> Result<Option<NoteTypeID>> {
|
||||||
self.db
|
self.db
|
||||||
.prepare_cached("select id from notetypes where name = ?")?
|
.prepare_cached("select id from notetypes where name = ?")?
|
||||||
.query_row(params![name], |row| row.get(0))
|
.query_row(params![name], |row| row.get(0))
|
||||||
|
@ -98,16 +84,7 @@ impl SqliteStorage {
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_notetype_by_name(&mut self, name: &str) -> Result<Option<NoteType>> {
|
pub fn get_all_notetype_names(&self) -> Result<Vec<(NoteTypeID, String)>> {
|
||||||
if let Some(id) = self.get_notetype_id(name)? {
|
|
||||||
self.get_notetype(id)
|
|
||||||
} else {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn get_all_notetype_names(&self) -> Result<Vec<(NoteTypeID, String)>> {
|
|
||||||
self.db
|
self.db
|
||||||
.prepare_cached(include_str!("get_notetype_names.sql"))?
|
.prepare_cached(include_str!("get_notetype_names.sql"))?
|
||||||
.query_and_then(NO_PARAMS, |row| Ok((row.get(0)?, row.get(1)?)))?
|
.query_and_then(NO_PARAMS, |row| Ok((row.get(0)?, row.get(1)?)))?
|
||||||
|
|
Loading…
Reference in a new issue