use crate::helpers::into_result; use crate::notification::NotificationData; use crate::notification::NotificationData::IncorrectAnkiFile; use log::info; use rusqlite::Connection; use serde_json::Value; use std::collections::BTreeMap; #[derive(Clone)] pub struct ImportData(pub(crate) Vec); #[derive(Clone, Debug)] pub struct ImportGroup { pub id: u64, pub name: String, pub fields: Vec, pub length: u64, pub mapping: BTreeMap, pub imported: bool, } #[derive(Clone)] pub struct ImportNote { pub tags: String, pub fields: Vec, } pub fn load_groups(connection: &Connection) -> Result { let json_models: String = connection .query_one("select models from col", (), |row| row.get(0)) .map_err(|_| IncorrectAnkiFile)?; let raw: Value = serde_json::from_str(json_models.as_str()).map_err(|_| IncorrectAnkiFile)?; let sets = raw.as_object(); if let Some(sets) = sets { let mut total_data = ImportData(vec![]); let mut count_stmt = connection .prepare("select mid, count(id) from notes group by mid") .map_err(|_| IncorrectAnkiFile)?; let counts = count_stmt .query_map([], |row| Ok((row.get(0)?, row.get(1)?))) .map_err(|_| IncorrectAnkiFile)? .filter_map(|x| x.ok()) .collect::>(); for (_, collection) in sets { let fields_property = collection.get("flds"); if let Some(fields_property) = fields_property { let fields = into_result(fields_property.as_array(), IncorrectAnkiFile)? .iter() .filter_map(|x| x.get("name")) .map(|x| x.as_str().unwrap().to_string()) .collect(); let id = collection.get("id"); if id.is_none() || id.unwrap().as_u64().is_none() { return Err(IncorrectAnkiFile); } let id = id.unwrap().as_u64().unwrap(); let name = collection.get("name"); if name.is_none() || name.unwrap().as_str().is_none() { return Err(IncorrectAnkiFile); } let name = name.unwrap().as_str().unwrap().to_string(); let mut group = ImportGroup { id, name, fields, mapping: Default::default(), length: 0, imported: false, }; if let Some((_, count)) = counts.iter().find(|(id, _)| *id == group.id as i64) { group.length = *count as u64 } info!("{:?}", group); total_data.0.push(group); } } return Ok(total_data); } Err(IncorrectAnkiFile) } pub fn get_words_of_group( connection: &Connection, group_id: u64, ) -> Result, NotificationData> { let mut count_stmt = connection .prepare("select tags, flds from notes where mid == ?1;") .map_err(|_| IncorrectAnkiFile)?; Ok(count_stmt .query_map((group_id as i64,), |row| { Ok(ImportNote { tags: row.get(0)?, fields: row .get::(1)? .split('') .map(|x| x.to_string()) .collect(), }) }) .map_err(|_| IncorrectAnkiFile)? .filter_map(|x| x.ok()) .collect::>()) }