use native struct for NoteType
This commit is contained in:
parent
d6646a6db5
commit
8cfb1fad44
@ -319,7 +319,10 @@ impl Backend {
|
||||
OValue::SetAllDecks(pb::Empty {})
|
||||
}
|
||||
Value::AllStockNotetypes(_) => OValue::AllStockNotetypes(pb::AllStockNotetypesOut {
|
||||
notetypes: all_stock_notetypes(&self.i18n),
|
||||
notetypes: all_stock_notetypes(&self.i18n)
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
@ -401,12 +401,16 @@ where
|
||||
&self.mgr.media_folder,
|
||||
)? {
|
||||
// note was modified, needs saving
|
||||
set_note(&self.ctx.storage.db, note, nt.sort_field_idx())?;
|
||||
set_note(
|
||||
&self.ctx.storage.db,
|
||||
note,
|
||||
nt.config.sort_field_idx as usize,
|
||||
)?;
|
||||
collection_modified = true;
|
||||
}
|
||||
|
||||
// extract latex
|
||||
extract_latex_refs(note, &mut referenced_files, nt.latex_uses_svg());
|
||||
extract_latex_refs(note, &mut referenced_files, nt.config.latex_svg);
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
|
@ -6,7 +6,7 @@ mod stock;
|
||||
|
||||
pub use crate::backend_proto::{
|
||||
card_requirement::CardRequirementKind, CardRequirement, CardTemplate, CardTemplateConfig,
|
||||
NoteField, NoteFieldConfig, NoteType, NoteTypeConfig, NoteTypeKind,
|
||||
NoteField, NoteFieldConfig, NoteType as NoteTypeProto, NoteTypeConfig, NoteTypeKind,
|
||||
};
|
||||
pub use schema11::{CardTemplateSchema11, NoteFieldSchema11, NoteTypeSchema11};
|
||||
pub use stock::all_stock_notetypes;
|
||||
@ -15,6 +15,8 @@ use crate::{
|
||||
define_newtype,
|
||||
template::{without_legacy_template_directives, FieldRequirements, ParsedTemplate},
|
||||
text::ensure_string_in_nfc,
|
||||
timestamp::TimestampSecs,
|
||||
types::Usn,
|
||||
};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use unicase::UniCase;
|
||||
@ -42,29 +44,35 @@ pub(crate) const DEFAULT_LATEX_HEADER: &str = r#"\documentclass[12pt]{article}
|
||||
|
||||
pub(crate) const DEFAULT_LATEX_FOOTER: &str = r#"\end{document}"#;
|
||||
|
||||
impl NoteType {
|
||||
pub fn new() -> Self {
|
||||
let mut nt = Self::default();
|
||||
pub struct NoteType {
|
||||
pub id: NoteTypeID,
|
||||
pub name: String,
|
||||
pub mtime_secs: TimestampSecs,
|
||||
pub usn: Usn,
|
||||
pub fields: Vec<NoteField>,
|
||||
pub templates: Vec<CardTemplate>,
|
||||
pub config: NoteTypeConfig,
|
||||
}
|
||||
|
||||
impl Default for NoteType {
|
||||
fn default() -> Self {
|
||||
let mut conf = NoteTypeConfig::default();
|
||||
conf.css = DEFAULT_CSS.into();
|
||||
conf.latex_pre = DEFAULT_LATEX_HEADER.into();
|
||||
conf.latex_post = DEFAULT_LATEX_FOOTER.into();
|
||||
nt.config = Some(conf);
|
||||
nt
|
||||
}
|
||||
|
||||
pub fn id(&self) -> NoteTypeID {
|
||||
NoteTypeID(self.id)
|
||||
}
|
||||
|
||||
pub fn sort_field_idx(&self) -> usize {
|
||||
self.config.as_ref().unwrap().sort_field_idx as usize
|
||||
}
|
||||
|
||||
pub fn latex_uses_svg(&self) -> bool {
|
||||
self.config.as_ref().unwrap().latex_svg
|
||||
NoteType {
|
||||
id: NoteTypeID(0),
|
||||
name: "".into(),
|
||||
mtime_secs: TimestampSecs(0),
|
||||
usn: Usn(0),
|
||||
fields: vec![],
|
||||
templates: vec![],
|
||||
config: conf,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NoteType {
|
||||
pub(crate) fn ensure_names_unique(&mut self) {
|
||||
let mut names = HashSet::new();
|
||||
for t in &mut self.templates {
|
||||
@ -134,7 +142,7 @@ impl NoteType {
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
self.config.as_mut().unwrap().reqs = reqs;
|
||||
self.config.reqs = reqs;
|
||||
}
|
||||
|
||||
pub(crate) fn normalize_names(&mut self) {
|
||||
@ -180,3 +188,17 @@ impl NoteType {
|
||||
self.update_requirements();
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NoteType> for NoteTypeProto {
|
||||
fn from(nt: NoteType) -> Self {
|
||||
NoteTypeProto {
|
||||
id: nt.id.0,
|
||||
name: nt.name,
|
||||
mtime_secs: nt.mtime_secs.0 as u32,
|
||||
usn: nt.usn.0,
|
||||
config: Some(nt.config),
|
||||
fields: nt.fields,
|
||||
templates: nt.templates,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,11 +88,11 @@ impl NoteTypeSchema11 {
|
||||
impl From<NoteTypeSchema11> for NoteType {
|
||||
fn from(nt: NoteTypeSchema11) -> Self {
|
||||
NoteType {
|
||||
id: nt.id.0,
|
||||
id: nt.id,
|
||||
name: nt.name,
|
||||
mtime_secs: nt.mtime.0 as u32,
|
||||
usn: nt.usn.0,
|
||||
config: Some(NoteTypeConfig {
|
||||
mtime_secs: nt.mtime,
|
||||
usn: nt.usn,
|
||||
config: NoteTypeConfig {
|
||||
kind: nt.kind as i32,
|
||||
sort_field_idx: nt.sortf as u32,
|
||||
css: nt.css,
|
||||
@ -102,7 +102,7 @@ impl From<NoteTypeSchema11> for NoteType {
|
||||
latex_svg: nt.latexsvg,
|
||||
reqs: nt.req.0.into_iter().map(Into::into).collect(),
|
||||
other: other_to_bytes(&nt.other),
|
||||
}),
|
||||
},
|
||||
fields: nt.flds.into_iter().map(Into::into).collect(),
|
||||
templates: nt.tmpls.into_iter().map(Into::into).collect(),
|
||||
}
|
||||
@ -134,17 +134,17 @@ fn bytes_to_other(bytes: &[u8]) -> HashMap<String, Value> {
|
||||
|
||||
impl From<NoteType> for NoteTypeSchema11 {
|
||||
fn from(p: NoteType) -> Self {
|
||||
let c = p.config.unwrap();
|
||||
let c = p.config;
|
||||
NoteTypeSchema11 {
|
||||
id: NoteTypeID(p.id),
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
kind: if c.kind == 1 {
|
||||
NoteTypeKind::Cloze
|
||||
} else {
|
||||
NoteTypeKind::Standard
|
||||
},
|
||||
mtime: TimestampSecs(p.mtime_secs as i64),
|
||||
usn: Usn(p.usn),
|
||||
mtime: p.mtime_secs,
|
||||
usn: p.usn,
|
||||
sortf: c.sort_field_idx as u16,
|
||||
did: if c.target_deck_id == 0 {
|
||||
None
|
||||
|
@ -16,7 +16,7 @@ impl SqliteStorage {
|
||||
if idx == StockNoteType::Basic as usize {
|
||||
self.set_config_value(
|
||||
ConfigKey::CurrentNoteTypeID.into(),
|
||||
&nt.id(),
|
||||
&nt.id,
|
||||
self.usn(false)?,
|
||||
TimestampSecs::now(),
|
||||
)?;
|
||||
@ -43,7 +43,7 @@ fn fieldref<S: AsRef<str>>(name: S) -> String {
|
||||
}
|
||||
|
||||
pub(crate) fn basic(i18n: &I18n) -> NoteType {
|
||||
let mut nt = NoteType::new();
|
||||
let mut nt = NoteType::default();
|
||||
nt.name = i18n.tr(TR::NotetypesBasicName).into();
|
||||
let front = i18n.tr(TR::NotetypesFrontField);
|
||||
let back = i18n.tr(TR::NotetypesBackField);
|
||||
@ -108,15 +108,14 @@ pub(crate) fn basic_optional_reverse(i18n: &I18n) -> NoteType {
|
||||
}
|
||||
|
||||
pub(crate) fn cloze(i18n: &I18n) -> NoteType {
|
||||
let mut nt = NoteType::new();
|
||||
let mut nt = NoteType::default();
|
||||
nt.name = i18n.tr(TR::NotetypesClozeName).into();
|
||||
let text = i18n.tr(TR::NotetypesTextField);
|
||||
nt.add_field(text.as_ref());
|
||||
let fmt = format!("{{{{cloze:{}}}}}", text);
|
||||
nt.add_template(nt.name.clone(), fmt.clone(), fmt);
|
||||
let mut config = nt.config.as_mut().unwrap();
|
||||
config.kind = NoteTypeKind::Cloze as i32;
|
||||
config.css += "
|
||||
nt.config.kind = NoteTypeKind::Cloze as i32;
|
||||
nt.config.css += "
|
||||
.cloze {
|
||||
font-weight: bold;
|
||||
color: blue;
|
||||
|
@ -301,10 +301,10 @@ impl SqlWriter<'_> {
|
||||
|
||||
let mut field_map = vec![];
|
||||
for nt in note_types.values() {
|
||||
let fields = self.col.storage.get_notetype_fields(nt.id())?;
|
||||
let fields = self.col.storage.get_notetype_fields(nt.id)?;
|
||||
for field in &fields {
|
||||
if matches_wildcard(&field.name, field_name) {
|
||||
field_map.push((nt.id(), field.ord));
|
||||
field_map.push((nt.id, field.ord));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,11 +3,9 @@
|
||||
|
||||
use super::SqliteStorage;
|
||||
use crate::{
|
||||
backend_proto::{
|
||||
CardTemplate, CardTemplateConfig, NoteField, NoteFieldConfig, NoteType, NoteTypeConfig,
|
||||
},
|
||||
backend_proto::{CardTemplate, CardTemplateConfig, NoteField, NoteFieldConfig, NoteTypeConfig},
|
||||
err::{AnkiError, DBErrorKind, Result},
|
||||
notetype::{NoteTypeID, NoteTypeSchema11},
|
||||
notetype::{NoteType, NoteTypeID, NoteTypeSchema11},
|
||||
timestamp::TimestampMillis,
|
||||
};
|
||||
use prost::Message;
|
||||
@ -22,7 +20,7 @@ fn row_to_notetype_core(row: &Row) -> Result<NoteType> {
|
||||
name: row.get(1)?,
|
||||
mtime_secs: row.get(2)?,
|
||||
usn: row.get(3)?,
|
||||
config: Some(config),
|
||||
config,
|
||||
fields: vec![],
|
||||
templates: vec![],
|
||||
})
|
||||
@ -41,7 +39,7 @@ impl SqliteStorage {
|
||||
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)))
|
||||
.map(|ntres| ntres.map(|nt| (nt.id, nt)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
@ -86,7 +84,8 @@ impl SqliteStorage {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_all_notetype_meta(&self) -> Result<Vec<(NoteTypeID, String)>> {
|
||||
#[allow(dead_code)]
|
||||
fn get_all_notetype_names(&self) -> Result<Vec<(NoteTypeID, String)>> {
|
||||
self.db
|
||||
.prepare_cached(include_str!("get_notetype_names.sql"))?
|
||||
.query_and_then(NO_PARAMS, |row| Ok((row.get(0)?, row.get(1)?)))?
|
||||
@ -97,7 +96,7 @@ impl SqliteStorage {
|
||||
&self,
|
||||
) -> Result<HashMap<NoteTypeID, NoteTypeSchema11>> {
|
||||
let mut nts = HashMap::new();
|
||||
for (ntid, _name) in self.get_all_notetype_meta()? {
|
||||
for (ntid, _name) in self.get_all_notetype_core()? {
|
||||
let full = self.get_full_notetype(ntid)?.unwrap();
|
||||
nts.insert(ntid, full.into());
|
||||
}
|
||||
@ -149,24 +148,24 @@ impl SqliteStorage {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_notetype_meta(&self, nt: &NoteType) -> Result<()> {
|
||||
assert!(nt.id != 0);
|
||||
fn update_notetype_config(&self, nt: &NoteType) -> Result<()> {
|
||||
assert!(nt.id.0 != 0);
|
||||
let mut stmt = self
|
||||
.db
|
||||
.prepare_cached(include_str!("update_notetype_meta.sql"))?;
|
||||
.prepare_cached(include_str!("update_notetype_core.sql"))?;
|
||||
let mut config_bytes = vec![];
|
||||
nt.config.as_ref().unwrap().encode(&mut config_bytes)?;
|
||||
nt.config.encode(&mut config_bytes)?;
|
||||
stmt.execute(params![nt.id, nt.name, nt.mtime_secs, nt.usn, config_bytes])?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn add_new_notetype(&self, nt: &mut NoteType) -> Result<()> {
|
||||
assert!(nt.id == 0);
|
||||
assert!(nt.id.0 == 0);
|
||||
|
||||
let mut stmt = self.db.prepare_cached(include_str!("add_notetype.sql"))?;
|
||||
let mut config_bytes = vec![];
|
||||
nt.config.as_ref().unwrap().encode(&mut config_bytes)?;
|
||||
nt.config.encode(&mut config_bytes)?;
|
||||
stmt.execute(params![
|
||||
TimestampMillis::now(),
|
||||
nt.name,
|
||||
@ -174,10 +173,10 @@ impl SqliteStorage {
|
||||
nt.usn,
|
||||
config_bytes
|
||||
])?;
|
||||
nt.id = self.db.last_insert_rowid();
|
||||
nt.id.0 = self.db.last_insert_rowid();
|
||||
|
||||
self.update_notetype_fields(nt.id(), &nt.fields)?;
|
||||
self.update_notetype_templates(nt.id(), &nt.templates)?;
|
||||
self.update_notetype_fields(nt.id, &nt.fields)?;
|
||||
self.update_notetype_templates(nt.id, &nt.templates)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -199,7 +198,7 @@ impl SqliteStorage {
|
||||
}
|
||||
nt.name.push('_');
|
||||
}
|
||||
self.update_notetype_meta(&nt)?;
|
||||
self.update_notetype_config(&nt)?;
|
||||
self.update_notetype_fields(ntid, &nt.fields)?;
|
||||
self.update_notetype_templates(ntid, &nt.templates)?;
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ fn unicase_compare(s1: &str, s2: &str) -> Ordering {
|
||||
}
|
||||
|
||||
// fixme: rollback savepoint when tags not changed
|
||||
// fixme: switch away from proto for top level struct
|
||||
|
||||
// currently public for dbproxy
|
||||
#[derive(Debug)]
|
||||
|
Loading…
Reference in New Issue
Block a user