use crate::data::entities::WordData; use crate::data::repositories::{DataRepository, DataRepositoryInner}; use crate::data::Id; use crate::data_provider::{SqliteDbLayer, TableAccessQuerySet}; use litemap::LiteMap; use rusqlite::{Error, Params, Row}; pub type WordRepository = DataRepository; pub type WordRepositoryInner = DataRepositoryInner; pub type WordDataLayer = SqliteDbLayer; #[derive(Clone)] pub struct WordQuerySet; impl TableAccessQuerySet for WordQuerySet { fn load() -> &'static str { "SELECT id, key, value, tags, more, group_id FROM words" } fn save() -> &'static str { "UPDATE words SET key = ?1, value = ?2, tags = ?3, more = ?4 WHERE id = ?5" } fn add() -> &'static str { "INSERT INTO words (key, value, tags, more, group_id) VALUES (?1, ?2, ?3, ?4, ?5)" } fn name() -> &'static str { "words" } fn from_sql(row: &Row) -> Result { let additional: String = row.get(4)?; Ok(WordData { id: row.get(0)?, key: row.get(1)?, value: row.get(2)?, tags: row.get(3)?, additional: additional_from_string(additional), group_id: row.get(5)?, }) } fn insert_params(entity: &WordData) -> impl Params { ( &entity.key, &entity.value, &entity.tags, additional_to_string(&entity.additional), entity.group_id, ) } fn update_params(entity: &WordData) -> impl Params { ( &entity.key, &entity.value, &entity.tags, additional_to_string(&entity.additional), entity.id, ) } } fn additional_to_string(map: &LiteMap) -> String { let mut parts = Vec::with_capacity(map.len() * 2); for (id, value) in map { parts.push(id.to_string()); parts.push(value.clone()); } parts.join("") } fn additional_from_string_temp(data: String) -> LiteMap { let pre_map : LiteMap = serde_json::from_str(data.as_str()).unwrap(); LiteMap::from(pre_map.iter().map(|(k, v)| (match k.as_str() { "reading" => Id(1), "description" => Id(2), "context" => Id(3), &_ => Id(0) }, v.to_string())).collect()) } fn additional_from_string(data: String) -> LiteMap { if data.is_empty() { return LiteMap::new() } let parts = data.split('').collect::>(); let chunks = parts.chunks(2).collect::>(); let mut map = LiteMap::with_capacity(parts.len()); for part in &chunks { let id : Id = part[0].parse().unwrap(); let value: String = part[1].to_string(); map.insert(id, value); } map }