Data provider refactor #11

Merged
micialware merged 11 commits from data-provider-refactor into master 2026-08-25 12:21:54 +03:00
6 changed files with 45 additions and 23 deletions
Showing only changes of commit 06bf9138c0 - Show all commits

No files matched your search

+1 -1
View File
@@ -95,7 +95,7 @@ pub fn fill_state(state: &mut AppState) {
let setting = load_settings(&state.connection); let setting = load_settings(&state.connection);
state.dictionary = list; state.dictionary = list;
state.decks = sets; state.decks = sets.unwrap_or_default();
state.word_groups = groups; state.word_groups = groups;
state.sync_data = setting state.sync_data = setting
} }
+19 -14
View File
@@ -2,11 +2,13 @@ use crate::core::srs::OrderMode;
use crate::data::entities::DeckSettings; use crate::data::entities::DeckSettings;
use rusqlite::Connection; use rusqlite::Connection;
use crate::notification::NotificationData;
use crate::notification::NotificationData::{DbLoadError, DbSaveError};
pub fn load_sets(connection: &Connection) -> Vec<DeckSettings> { pub fn load_sets(connection: &Connection) -> Result<Vec<DeckSettings>, NotificationData> {
let mut stmt = connection let mut stmt = connection
.prepare("SELECT id, name, forward, backward, filter FROM card_set") .prepare("SELECT id, name, forward, backward, filter FROM card_set")
.unwrap(); .expect("Failed to prepare state query");
let iter = stmt let iter = stmt
.query_map([], |row| { .query_map([], |row| {
Ok(DeckSettings { Ok(DeckSettings {
@@ -19,17 +21,17 @@ pub fn load_sets(connection: &Connection) -> Vec<DeckSettings> {
open_mode: OrderMode::Default, open_mode: OrderMode::Default,
}) })
}) })
.unwrap(); .map_err(|_| DbLoadError)?;
let mut buffer = vec![]; let mut buffer = vec![];
for word in iter { for word in iter.filter_map(|result| result.ok()) {
buffer.push(word.unwrap()); buffer.push(word);
} }
buffer Ok(buffer)
} }
pub fn add_set(set: &mut DeckSettings, connection: &Connection) { pub fn add_set(set: &mut DeckSettings, connection: &Connection) -> Result<(), NotificationData> {
let index : u32 = connection let index : u32 = connection
.query_row( .query_row(
"INSERT INTO card_set (name, forward, backward, filter) VALUES (?1, ?2, ?3, ?4) RETURNING id", "INSERT INTO card_set (name, forward, backward, filter) VALUES (?1, ?2, ?3, ?4) RETURNING id",
@@ -41,14 +43,15 @@ pub fn add_set(set: &mut DeckSettings, connection: &Connection) {
), ),
|row| row.get(0) |row| row.get(0)
) )
.unwrap(); .map_err(|_| DbSaveError)?;
set.id = index.into(); set.id = index.into();
Ok(())
} }
pub fn update_deck(set: &mut DeckSettings, connection: &Connection) { pub fn update_deck(set: &mut DeckSettings, connection: &Connection) -> Result<(), NotificationData> {
if !set.id.is_valid() { if !set.id.is_valid() {
add_set(set, connection); add_set(set, connection)?;
} else { } else {
connection connection
.execute( .execute(
@@ -61,15 +64,17 @@ pub fn update_deck(set: &mut DeckSettings, connection: &Connection) {
&set.id &set.id
), ),
) )
.unwrap(); .map_err(|_| DbSaveError)?;
} }
Ok(())
} }
pub fn delete_set(set: &DeckSettings, connection: &Connection) { pub fn delete_set(set: &DeckSettings, connection: &Connection) -> Result<(), NotificationData> {
if !set.id.is_valid() { if !set.id.is_valid() {
return; return Err(DbSaveError);
} }
connection connection
.execute("DELETE FROM card_set WHERE id = ?1", (&set.id,)) .execute("DELETE FROM card_set WHERE id = ?1", (&set.id,))
.unwrap(); .map_err(|_| DbSaveError)?;
Ok(())
} }
+2 -1
View File
@@ -77,7 +77,8 @@ pub enum RootMessage {
None, None,
UpdateData, UpdateData,
} }
#[allow(clippy::enum_variant_names)]
#[allow(clippy::large_enum_variant)]
pub enum Page { pub enum Page {
Selector(SelectorState), Selector(SelectorState),
Quiz(QuizState), Quiz(QuizState),
+8
View File
@@ -157,6 +157,12 @@ impl NotificationManager {
NotificationData::WebApiUnavailable => { NotificationData::WebApiUnavailable => {
text!("Не получается подключиться к Api") text!("Не получается подключиться к Api")
} }
NotificationData::DbSaveError => {
text!("Не получается сохранить данные")
}
NotificationData::DbLoadError => {
text!("Не получается загрузить данные")
}
} }
.width(Fill) .width(Fill)
.into() .into()
@@ -179,4 +185,6 @@ pub enum NotificationData {
OpenFileError, OpenFileError,
VoiceVoxUnavailable, VoiceVoxUnavailable,
WebApiUnavailable, WebApiUnavailable,
DbSaveError,
DbLoadError,
} }
+11 -6
View File
@@ -1,8 +1,10 @@
use crate::app::AppState;
use crate::data::entities::DeckSettings;
use crate::data_provider::card_sets::{delete_set, update_deck}; use crate::data_provider::card_sets::{delete_set, update_deck};
use crate::data_provider::card_stats::{delete_stats, load_stats_of_deck}; use crate::data_provider::card_stats::{delete_stats, load_stats_of_deck};
use crate::navigation::Page::PreviousPage; use crate::navigation::Page::PreviousPage;
use crate::navigation::{NavigatedPage, Page, RootMessage}; use crate::navigation::{NavigatedPage, Page, RootMessage};
use crate::notification::NotificationRequest;
use crate::pages::repetition_settings::RepetitionSettingsMessage::*; use crate::pages::repetition_settings::RepetitionSettingsMessage::*;
use crate::styling::*; use crate::styling::*;
use iced::widget::button::danger; use iced::widget::button::danger;
@@ -10,12 +12,10 @@ use iced::widget::text_input::Catalog;
use iced::widget::{button, column, row, scrollable, space, text, text_input}; use iced::widget::{button, column, row, scrollable, space, text, text_input};
use iced::{Element, Task}; use iced::{Element, Task};
use iced_core::Length::Fill; use iced_core::Length::Fill;
use iced_core::{Padding, Theme, color}; use iced_core::{color, Padding, Theme};
use parking_lot::Mutex; use parking_lot::Mutex;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use crate::app::AppState;
use crate::data::entities::DeckSettings;
pub struct RepetitionSettingsState { pub struct RepetitionSettingsState {
set: DeckSettings, set: DeckSettings,
@@ -61,7 +61,9 @@ impl NavigatedPage<RepetitionSettingsMessage> for RepetitionSettingsState {
Back => {} Back => {}
Save => { Save => {
let mut state = self.state.lock(); let mut state = self.state.lock();
update_deck(&mut self.set, &state.connection); if let Err(e) = update_deck(&mut self.set, &state.connection) {
return Task::done(RootMessage::PushNotification(NotificationRequest::Error(e)));
}
if self.filter_changed { if self.filter_changed {
update_deck_stats(&self.set, &state); update_deck_stats(&self.set, &state);
} }
@@ -95,7 +97,10 @@ impl NavigatedPage<RepetitionSettingsMessage> for RepetitionSettingsState {
}); });
} }
let mut state = self.state.lock(); let mut state = self.state.lock();
delete_set(&self.set, &state.connection); if let Err(e) = delete_set(&self.set, &state.connection) {
return Task::done(RootMessage::PushNotification(NotificationRequest::Error(e)));
}
state.decks.remove(self.index); state.decks.remove(self.index);
return Task::done(RootMessage::RepetitionSettings(Back)); return Task::done(RootMessage::RepetitionSettings(Back));
} }
+4 -1
View File
@@ -27,6 +27,7 @@ use iced_core::svg::Handle;
use parking_lot::Mutex; use parking_lot::Mutex;
use std::ops::Deref; use std::ops::Deref;
use std::sync::Arc; use std::sync::Arc;
use crate::notification::NotificationRequest;
#[derive(Clone)] #[derive(Clone)]
pub struct RepetitionsState { pub struct RepetitionsState {
@@ -146,7 +147,9 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
let mut deck = self.selected_deck().unwrap().clone(); let mut deck = self.selected_deck().unwrap().clone();
let mut state = self.state.lock(); let mut state = self.state.lock();
{ {
update_deck(&mut deck.general_settings, &state.connection); if let Err(e) = update_deck(&mut deck.general_settings, &state.connection){
return Task::done(RootMessage::PushNotification(NotificationRequest::Error(e)))
}
if let Some(index) = deck.index { if let Some(index) = deck.index {
state.decks[index] = deck.general_settings.clone(); state.decks[index] = deck.general_settings.clone();
} else { } else {