Make db creation better

This commit is contained in:
2026-06-15 17:06:02 +03:00
parent eb5a51513d
commit 4e57f3fd6b
12 changed files with 162 additions and 155 deletions
+1
View File
@@ -3,4 +3,5 @@ pub(crate) mod card_sets;
pub(crate) mod card_stats;
pub(crate) mod voice;
pub(crate) mod settings;
pub(crate) mod sqlite;
-1
View File
@@ -1,4 +1,3 @@
use rusqlite::fallible_iterator::FallibleIterator;
use rusqlite::Connection;
pub fn get_setting(key: String, connection: &Connection) -> Option<String> {
+51
View File
@@ -0,0 +1,51 @@
use crate::dictionary::app_data_dir;
use rusqlite::Connection;
pub fn create_db() {
let path = app_data_dir();
let db_file = path.join("data.db");
if !db_file.exists() {
std::fs::File::create(&db_file).unwrap();
let connection = Connection::open(&db_file).unwrap();
connection.execute("PRAGMA foreign_keys = ON;", []).unwrap();
create_tables(&connection);
}
}
fn create_tables(conn: &Connection) {
make_card_set(conn).unwrap();
make_settings(conn).unwrap();
make_word_group(conn).unwrap();
make_words(conn).unwrap();
make_card_stats(conn).unwrap();
}
fn make_settings(conn: &Connection) -> Result<(), rusqlite::Error> {
let query = include_str!("../../sql/settings.sql");
conn.execute(query, ())?;
Ok(())
}
fn make_card_set(conn: &Connection) -> Result<(), rusqlite::Error> {
let query = include_str!("../../sql/card_set.sql");
conn.execute(query, ())?;
Ok(())
}
fn make_word_group(conn: &Connection) -> Result<(), rusqlite::Error> {
let query = include_str!("../../sql/word_group.sql");
conn.execute(query, ())?;
conn.execute("insert into word_group (name) values (\"Слова\");", ())?;
Ok(())
}
fn make_words(conn: &Connection) -> Result<(), rusqlite::Error> {
let query = include_str!("../../sql/words.sql");
conn.execute(query, ())?;
Ok(())
}
fn make_card_stats(conn: &Connection) -> Result<(), rusqlite::Error> {
let query = include_str!("../../sql/card_stats.sql");
conn.execute(query, ())?;
Ok(())
}
-88
View File
@@ -1,95 +1,7 @@
use crate::dictionary::app_data_dir;
use crate::lang::{WordData, WordGroup};
use rusqlite::Connection;
use std::collections::HashMap;
pub fn create_db() {
let path = app_data_dir();
let db_file = path.join("data.db");
if !db_file.exists() {
std::fs::File::create(&db_file).unwrap();
let connection = Connection::open(&db_file).unwrap();
connection.execute("PRAGMA foreign_keys = ON;", []).unwrap();
create_tables(&connection);
}
}
fn create_tables(conn: &Connection) {
conn.execute(
"create table settings
(
id text primary key,
value text
);",
(),
)
.unwrap_or_else(|e| 0);
conn.execute(
"create table card_set
(
id INTEGER
primary key autoincrement,
name TEXT not null,
forward TEXT not null,
backward TEXT not null,
filter TEXT not null
);",
(),
)
.unwrap_or_else(|e| 0);
conn.execute(
"create table word_group
(
id INTEGER
primary key autoincrement,
name TEXT not null
);",
(),
)
.unwrap_or_else(|e| 0);
conn.execute(
"create table words
(
id INTEGER
primary key autoincrement,
key TEXT not null,
value TEXT not null,
tags TEXT not null,
more TEXT,
group_id integer default 1 not null
constraint words_word_group_id_fk
references word_group
on update cascade on delete cascade
);",
(),
)
.unwrap_or_else(|e| 0);
conn.execute(
"create table card_stats
(
id INTEGER
primary key autoincrement,
word_id INTEGER not null
references words
on delete cascade,
set_id TEXT not null
references card_set
on delete cascade,
score INTEGER default 1 not null,
last_opened integer not null
);",
(),
)
.unwrap_or_else(|e| 0);
conn.execute(
"insert into word_group (name)
values (\"Слова\");",
(),
)
.unwrap_or_else(|e| 0);
}
pub fn add_word(word: &mut WordData, connection: &Connection) {
let index = connection
-3
View File
@@ -15,7 +15,6 @@ use iced::widget::space::horizontal;
use iced::widget::*;
use iced::{Border, Color, Length, Shadow, Task};
use rand::random_range;
use rayon::iter::IndexedParallelIterator;
use std::collections::{HashMap, HashSet};
use std::fs;
use std::ops::Add;
@@ -35,7 +34,6 @@ pub struct DictionaryState {
selected_group_index: usize,
reverse_list: bool,
auto_save_queue: HashMap<usize, DateTime<Utc>>,
total_tags_list: Vec<String>,
}
#[derive(Debug, Clone)]
@@ -117,7 +115,6 @@ impl DictionaryState {
no_typing: true,
reverse_list: true,
auto_save_queue: HashMap::new(),
total_tags_list: vec![],
};
result.update_tags();
+62 -62
View File
@@ -277,10 +277,10 @@ impl CardStatistics {
}
WordOpenMode::Ok => self.score = (self.calculated_score() + 2.0).round() as i32,
WordOpenMode::Hard => {
self.score = (self.calculated_score() - 1.0).round() as i32;
self.score = (self.calculated_score() * 0.75).round() as i32;
}
WordOpenMode::None => {
self.score = (self.calculated_score() * 0.5) as i32;
self.score = (self.calculated_score() * 0.4) as i32;
}
}
@@ -359,9 +359,9 @@ impl CardSet {
state: state_for,
order_module: match settings.open_mode {
SetOrderMode::Default => OrderModule::SemiRandomSRS(SemiRandomSRSModule::new()),
SetOrderMode::TrainWorstFirst => {
OrderModule::WorstWordsSRS(WorstWordsSRSModule::new())
}
// SetOrderMode::TrainWorstFirst => {
// OrderModule::WorstWordsSRS(WorstWordsSRSModule::new())
// }
SetOrderMode::FullRandom => OrderModule::RandomSRS(RandomSRSModule::new()),
},
}
@@ -370,7 +370,7 @@ impl CardSet {
pub fn next(&mut self) -> (WordData, CardStatistics) {
let index = match self.order_module.clone() {
OrderModule::SemiRandomSRS(mut module) => {
if module.initializated == false {
if module.initialized == false {
module.init(self)
}
let index = module.next(self);
@@ -378,21 +378,21 @@ impl CardSet {
index
}
OrderModule::RandomSRS(mut module) => {
if module.initializated == false {
if module.initialized == false {
module.init(self)
}
let index = module.next(self);
self.order_module = OrderModule::RandomSRS(module);
index
}
OrderModule::WorstWordsSRS(mut module) => {
if module.initializated == false {
module.init(self)
}
let index = module.next(self);
self.order_module = OrderModule::WorstWordsSRS(module);
index
}
// OrderModule::WorstWordsSRS(mut module) => {
// if module.initializated == false {
// module.init(self)
// }
// let index = module.next(self);
// self.order_module = OrderModule::WorstWordsSRS(module);
// index
// }
};
self.current_word_index = Some(index);
@@ -417,10 +417,10 @@ impl CardSet {
module.open(status, index, word.clone());
self.order_module = OrderModule::RandomSRS(module);
}
OrderModule::WorstWordsSRS(mut module) => {
module.open(status, index, word.clone());
self.order_module = OrderModule::WorstWordsSRS(module);
}
// OrderModule::WorstWordsSRS(mut module) => {
// module.open(status, index, word.clone());
// self.order_module = OrderModule::WorstWordsSRS(module);
// }
}
update_stat_score(word, &self.state.lock().unwrap().connection)
}
@@ -431,9 +431,9 @@ impl CardSet {
}
#[derive(Clone, PartialEq, Copy, Eq)]
pub(crate) enum SetOrderMode {
pub enum SetOrderMode {
Default,
TrainWorstFirst,
// TrainWorstFirst,
FullRandom,
}
@@ -441,7 +441,7 @@ pub(crate) enum SetOrderMode {
enum OrderModule {
SemiRandomSRS(SemiRandomSRSModule),
RandomSRS(RandomSRSModule),
WorstWordsSRS(WorstWordsSRSModule),
// WorstWordsSRS(WorstWordsSRSModule),
}
trait SRSModule {
@@ -452,35 +452,35 @@ trait SRSModule {
#[derive(Clone)]
struct RandomSRSModule {
backet: Vec<usize>,
initializated: bool,
basket: Vec<usize>,
initialized: bool,
}
impl RandomSRSModule {
fn new() -> RandomSRSModule {
Self{
backet: vec![],
initializated: false,
basket: vec![],
initialized: false,
}
}
}
impl SRSModule for RandomSRSModule {
fn next(&mut self, set: &mut CardSet) -> usize {
if self.backet.is_empty() {
self.backet = (0..set.words.len()).collect::<Vec<usize>>();
self.backet.shuffle(&mut rand::rng())
if self.basket.is_empty() {
self.basket = (0..set.words.len()).collect::<Vec<usize>>();
self.basket.shuffle(&mut rand::rng())
}
self.backet.pop().unwrap()
self.basket.pop().unwrap()
}
fn open(&mut self, _: WordOpenMode, _: usize, _: CardStatistics) {}
fn init(&mut self, set: &mut CardSet) {
self.initializated = true;
self.backet = (0..set.words.len()).collect::<Vec<usize>>();
self.backet.shuffle(&mut rand::rng())
self.initialized = true;
self.basket = (0..set.words.len()).collect::<Vec<usize>>();
self.basket.shuffle(&mut rand::rng())
}
}
@@ -489,7 +489,7 @@ struct SemiRandomSRSModule {
history: Vec<usize>,
last_weights: WeightedIndex<f32>,
generator: ThreadRng,
initializated: bool,
initialized: bool,
}
impl SemiRandomSRSModule {
@@ -498,7 +498,7 @@ impl SemiRandomSRSModule {
history: vec![],
last_weights: WeightedIndex::new([1.0]).unwrap(),
generator: rng(),
initializated: false,
initialized: false,
}
}
}
@@ -519,7 +519,7 @@ impl SRSModule for SemiRandomSRSModule {
index
}
fn open(&mut self, status: WordOpenMode, index: usize, word: CardStatistics) {
fn open(&mut self, _: WordOpenMode, index: usize, word: CardStatistics) {
let new_weight = (100.0 / word.calculated_score()).powf(2.0);
self.last_weights
.update_weights(&[(index, &new_weight)])
@@ -527,7 +527,7 @@ impl SRSModule for SemiRandomSRSModule {
}
fn init(&mut self, set: &mut CardSet) {
self.initializated = true;
self.initialized = true;
let weights = set
.set
.iter()
@@ -546,29 +546,29 @@ impl SemiRandomSRSModule {
}
}
#[derive(Clone)]
struct WorstWordsSRSModule {
initializated: bool,
}
// #[derive(Clone)]
// struct WorstWordsSRSModule {
// initializated: bool,
// }
impl SRSModule for WorstWordsSRSModule {
fn next(&mut self, set: &mut CardSet) -> usize {
todo!()
}
fn open(&mut self, status: WordOpenMode, index: usize, updated_word: CardStatistics) {
todo!()
}
fn init(&mut self, set: &mut CardSet) {
todo!()
}
}
impl WorstWordsSRSModule {
fn new() -> WorstWordsSRSModule {
WorstWordsSRSModule {
initializated: false,
}
}
}
// impl SRSModule for WorstWordsSRSModule {
// fn next(&mut self, _: &mut CardSet) -> usize {
// todo!()
// }
//
// fn open(&mut self, _: WordOpenMode, _: usize, _: CardStatistics) {
// todo!()
// }
//
// fn init(&mut self, _: &mut CardSet) {
// todo!()
// }
// }
//
// impl WorstWordsSRSModule {
// fn new() -> WorstWordsSRSModule {
// WorstWordsSRSModule {
// initializated: false,
// }
// }
// }
+2 -1
View File
@@ -14,7 +14,7 @@ mod writing;
use crate::data_provider::card_sets::load_sets;
use crate::data_provider::settings::get_setting;
use crate::data_provider::words::{create_db, load_word_groups, load_words};
use crate::data_provider::words::{ load_word_groups, load_words};
use crate::dictionary::{app_data_dir, DictionaryMessage, DictionaryState};
use crate::dictionary_test::{DictionaryQuizMessage, DictionaryQuizState};
use crate::lang::{WordData, WordGroup};
@@ -37,6 +37,7 @@ use iced::{keyboard, Element, Subscription};
use iced::{Font, Task};
use rusqlite::Connection;
use std::sync::{Arc, Mutex};
use crate::data_provider::sqlite::create_db;
const DEFAULT_SPACING: f32 = 10.0;