Repo integration #15
No files matched your search
+14
-40
@@ -286,30 +286,17 @@ impl<T: EntityData + Clone, D: DbLayer<T>> DataRepositoryInner<T, D> {
|
|||||||
where
|
where
|
||||||
T: Send + Sync,
|
T: Send + Sync,
|
||||||
{
|
{
|
||||||
let mut cache: Vec<EntityHandle<T>> = self
|
let mut query = Query {
|
||||||
.cache
|
cache: vec![],
|
||||||
.par_iter()
|
|
||||||
.enumerate()
|
|
||||||
.filter(|(_, entity)| rule(entity))
|
|
||||||
.map(|(i, entity)| EntityHandle::new(entity.id(), i, true))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
cache.extend(
|
|
||||||
self.temporal
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.filter(|(_, entity)| rule(entity))
|
|
||||||
.map(|(i, entity)| EntityHandle::new(entity.id(), i, false))
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Query {
|
|
||||||
cache,
|
|
||||||
rule,
|
rule,
|
||||||
parallel: true,
|
parallel: true,
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
shift_stamp: self.shifts,
|
shift_stamp: self.shifts,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
query.load(self);
|
||||||
|
|
||||||
|
query
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn query(
|
pub fn query(
|
||||||
@@ -319,30 +306,17 @@ impl<T: EntityData + Clone, D: DbLayer<T>> DataRepositoryInner<T, D> {
|
|||||||
where
|
where
|
||||||
T: Send + Sync,
|
T: Send + Sync,
|
||||||
{
|
{
|
||||||
let mut cache: Vec<EntityHandle<T>> = self
|
let mut query = Query {
|
||||||
.cache
|
cache: vec![],
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.filter(|(_, entity)| rule(entity))
|
|
||||||
.map(|(i, entity)| EntityHandle::new(entity.id(), i, true))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
cache.extend(
|
|
||||||
self.temporal
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.filter(|(_, entity)| rule(entity))
|
|
||||||
.map(|(i, entity)| EntityHandle::new(entity.id(), i, false))
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Query {
|
|
||||||
cache,
|
|
||||||
rule,
|
rule,
|
||||||
parallel: false,
|
parallel: false,
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
shift_stamp: self.shifts,
|
shift_stamp: self.shifts,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
query.load(self);
|
||||||
|
|
||||||
|
query
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty_query(&self) -> Query<T, DataRepositoryInner<T, D>, D> {
|
pub fn empty_query(&self) -> Query<T, DataRepositoryInner<T, D>, D> {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::data::entities::{CardState, DeckSettings};
|
use crate::data::entities::{CardState, DeckSettings};
|
||||||
|
use crate::data::repositories::{DataRepository, DataRepositoryInner};
|
||||||
use crate::data_provider::{SqliteDbLayer, TableAccessQuerySet};
|
use crate::data_provider::{SqliteDbLayer, TableAccessQuerySet};
|
||||||
use crate::notification::NotificationData::{DbLoadError, DbSaveError};
|
use crate::notification::NotificationData::{DbLoadError, DbSaveError};
|
||||||
use crate::notification::{MaybeError, NotificationData};
|
use crate::notification::{MaybeError, NotificationData};
|
||||||
@@ -7,10 +8,11 @@ use fsrs::MemoryState;
|
|||||||
use log::info;
|
use log::info;
|
||||||
use rusqlite::{Connection, Error, Params, Row, params};
|
use rusqlite::{Connection, Error, Params, Row, params};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use crate::data::repositories::{DataRepository, DataRepositoryInner};
|
|
||||||
|
|
||||||
pub type CardStateRepository = DataRepository<CardState, SqliteDbLayer<CardState, CardStatesQuerySet>>;
|
pub type CardStateRepository =
|
||||||
pub type CardStateRepositoryInner = DataRepositoryInner<CardState, SqliteDbLayer<CardState, CardStatesQuerySet>>;
|
DataRepository<CardState, SqliteDbLayer<CardState, CardStatesQuerySet>>;
|
||||||
|
pub type CardStateRepositoryInner =
|
||||||
|
DataRepositoryInner<CardState, SqliteDbLayer<CardState, CardStatesQuerySet>>;
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CardStatesQuerySet;
|
pub struct CardStatesQuerySet;
|
||||||
impl TableAccessQuerySet<CardState> for CardStatesQuerySet {
|
impl TableAccessQuerySet<CardState> for CardStatesQuerySet {
|
||||||
@@ -19,11 +21,11 @@ impl TableAccessQuerySet<CardState> for CardStatesQuerySet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn save() -> &'static str {
|
fn save() -> &'static str {
|
||||||
"UPDATE states SET score = ?1, last_opened = ?2 WHERE id = ?3"
|
"UPDATE states SET score = ?1, last_opened = ?2, fsrs_opened = ?3, fsrs_memory = ?4, fsrs_open_day = ?5 WHERE id = ?6"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add() -> &'static str {
|
fn add() -> &'static str {
|
||||||
"INSERT INTO states (word_id, deck_id, score, last_opened, fsrs_opened, fsrs_memory, fsrs_open_day) VALUES (?1, ?2, ?3, ?4) RETURNING id"
|
"INSERT INTO states (word_id, deck_id, score, last_opened, fsrs_opened, fsrs_memory, fsrs_open_day) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name() -> &'static str {
|
fn name() -> &'static str {
|
||||||
@@ -58,7 +60,14 @@ impl TableAccessQuerySet<CardState> for CardStatesQuerySet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn update_params(entity: &CardState) -> impl Params {
|
fn update_params(entity: &CardState) -> impl Params {
|
||||||
(entity.score, entity.last_open.timestamp(), entity.id)
|
(
|
||||||
|
entity.score,
|
||||||
|
entity.last_open.timestamp(),
|
||||||
|
entity.id,
|
||||||
|
entity.fsrs_opened,
|
||||||
|
memory_to_i64(&entity.fsrs_memory),
|
||||||
|
entity.fsrs_open_day,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn load_stats_of_deck(
|
pub fn load_stats_of_deck(
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ impl TableAccessQuerySet<WordGroup> for CustomFieldsQuerySet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add() -> &'static str {
|
fn add() -> &'static str {
|
||||||
"INSERT INTO word_groups (name) VALUES (?1) RETURNING id"
|
"INSERT INTO word_groups (name) VALUES (?1)"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name() -> &'static str {
|
fn name() -> &'static str {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ impl TableAccessQuerySet<DeckSettings> for DeckQuerySet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add() -> &'static str {
|
fn add() -> &'static str {
|
||||||
"INSERT INTO decks (name, forward, backward, filter) VALUES (?1, ?2, ?3, ?4) RETURNING id"
|
"INSERT INTO decks (name, forward, backward, filter) VALUES (?1, ?2, ?3, ?4)"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name() -> &'static str {
|
fn name() -> &'static str {
|
||||||
|
|||||||
@@ -21,13 +21,16 @@ impl TableAccessQuerySet<HistoryNote> for HistoryQuerySet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add() -> &'static str {
|
fn add() -> &'static str {
|
||||||
"INSERT INTO history (deck_id, state_id, timestamp, answer, before, after, fsrs) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7) RETURNING rowid"
|
"INSERT INTO history (deck_id, state_id, timestamp, answer, before, after, fsrs) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name() -> &'static str {
|
fn name() -> &'static str {
|
||||||
"history"
|
"history"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn id_field() -> &'static str {
|
||||||
|
"rowid"
|
||||||
|
}
|
||||||
fn from_sql(row: &Row) -> Result<HistoryNote, Error> {
|
fn from_sql(row: &Row) -> Result<HistoryNote, Error> {
|
||||||
Ok(HistoryNote {
|
Ok(HistoryNote {
|
||||||
id: row.get(0)?,
|
id: row.get(0)?,
|
||||||
|
|||||||
+32
-12
@@ -1,8 +1,8 @@
|
|||||||
use crate::data::Id;
|
use crate::data::Id;
|
||||||
use crate::data::entities::{EntityData};
|
use crate::data::entities::EntityData;
|
||||||
use crate::data::repositories::{BatchedDbLayer, DbLayer};
|
use crate::data::repositories::{BatchedDbLayer, DbLayer};
|
||||||
use crate::notification::MaybeError;
|
use crate::notification::MaybeError;
|
||||||
use crate::notification::NotificationData::{DbLoadError, DbSaveError};
|
use crate::notification::NotificationData::DbSaveError;
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use rusqlite::{Connection, Error, Params, Row};
|
use rusqlite::{Connection, Error, Params, Row};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
@@ -25,6 +25,9 @@ pub trait TableAccessQuerySet<T> {
|
|||||||
fn save() -> &'static str;
|
fn save() -> &'static str;
|
||||||
fn add() -> &'static str;
|
fn add() -> &'static str;
|
||||||
fn name() -> &'static str;
|
fn name() -> &'static str;
|
||||||
|
fn id_field() -> &'static str {
|
||||||
|
"id"
|
||||||
|
}
|
||||||
fn from_sql(row: &Row) -> Result<T, Error>;
|
fn from_sql(row: &Row) -> Result<T, Error>;
|
||||||
fn insert_params(entity: &T) -> impl Params;
|
fn insert_params(entity: &T) -> impl Params;
|
||||||
fn update_params(entity: &T) -> impl Params;
|
fn update_params(entity: &T) -> impl Params;
|
||||||
@@ -38,9 +41,9 @@ where
|
|||||||
_phantom: PhantomData<(T, Q)>,
|
_phantom: PhantomData<(T, Q)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Q: TableAccessQuerySet<T>> Default for SqliteDbLayer<T, Q>{
|
impl<T, Q: TableAccessQuerySet<T>> Default for SqliteDbLayer<T, Q> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self{
|
Self {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,7 +55,10 @@ impl<T: EntityData, Q: TableAccessQuerySet<T>> DbLayer<T> for SqliteDbLayer<T, Q
|
|||||||
|
|
||||||
connection
|
connection
|
||||||
.execute(Q::save(), Q::update_params(entity))
|
.execute(Q::save(), Q::update_params(entity))
|
||||||
.map_err(|e| {error!("{}", e); DbSaveError})?;
|
.map_err(|e| {
|
||||||
|
error!("{}", e);
|
||||||
|
DbSaveError
|
||||||
|
})?;
|
||||||
debug!("Updated in {} for {:?}", Q::name(), time.elapsed());
|
debug!("Updated in {} for {:?}", Q::name(), time.elapsed());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -61,8 +67,11 @@ impl<T: EntityData, Q: TableAccessQuerySet<T>> DbLayer<T> for SqliteDbLayer<T, Q
|
|||||||
let time = Instant::now();
|
let time = Instant::now();
|
||||||
|
|
||||||
let index: u32 = connection
|
let index: u32 = connection
|
||||||
.query_row(Q::add(), Q::insert_params(entity), |row| row.get(0))
|
.query_row(format!("{} RETURNING {}", Q::add(), Q::id_field()).as_str(), Q::insert_params(entity), |row| row.get(0))
|
||||||
.map_err(|e| {error!("{}", e); DbSaveError})?;
|
.map_err(|e| {
|
||||||
|
error!("{}", e);
|
||||||
|
DbSaveError
|
||||||
|
})?;
|
||||||
|
|
||||||
entity.set_id(index.into());
|
entity.set_id(index.into());
|
||||||
debug!("Added into {} for {:?}", Q::name(), time.elapsed());
|
debug!("Added into {} for {:?}", Q::name(), time.elapsed());
|
||||||
@@ -80,7 +89,10 @@ impl<T: EntityData, Q: TableAccessQuerySet<T>> DbLayer<T> for SqliteDbLayer<T, Q
|
|||||||
format!("DELETE FROM {} WHERE id = ?1", Q::name()).as_str(),
|
format!("DELETE FROM {} WHERE id = ?1", Q::name()).as_str(),
|
||||||
(&id,),
|
(&id,),
|
||||||
)
|
)
|
||||||
.map_err(|e| {error!("{}", e); DbSaveError})?;
|
.map_err(|e| {
|
||||||
|
error!("{}", e);
|
||||||
|
DbSaveError
|
||||||
|
})?;
|
||||||
debug!("Deleted from {} for {:?}", Q::name(), time.elapsed());
|
debug!("Deleted from {} for {:?}", Q::name(), time.elapsed());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -93,7 +105,10 @@ impl<T: EntityData, Q: TableAccessQuerySet<T>> DbLayer<T> for SqliteDbLayer<T, Q
|
|||||||
.expect("Failed to prepare state query");
|
.expect("Failed to prepare state query");
|
||||||
let iter = stmt
|
let iter = stmt
|
||||||
.query_map([], |row| Ok(Q::from_sql(row)?))
|
.query_map([], |row| Ok(Q::from_sql(row)?))
|
||||||
.map_err(|e| {error!("{}", e); DbSaveError})?;
|
.map_err(|e| {
|
||||||
|
error!("{}", e);
|
||||||
|
DbSaveError
|
||||||
|
})?;
|
||||||
|
|
||||||
iter.filter_map(|res| res.ok())
|
iter.filter_map(|res| res.ok())
|
||||||
.for_each(|i| storage.push(i));
|
.for_each(|i| storage.push(i));
|
||||||
@@ -123,7 +138,10 @@ impl<T: EntityData, Q: TableAccessQuerySet<T>> BatchedDbLayer<T> for SqliteDbLay
|
|||||||
format!("DELETE FROM {} WHERE id in ({})", Q::name(), stringed).as_str(),
|
format!("DELETE FROM {} WHERE id in ({})", Q::name(), stringed).as_str(),
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
.map_err(|_| DbSaveError)?;
|
.map_err(|e| {
|
||||||
|
error!("{}", e);
|
||||||
|
DbSaveError
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
debug!(
|
debug!(
|
||||||
"Deleted {} from {} for {:?}",
|
"Deleted {} from {} for {:?}",
|
||||||
@@ -145,8 +163,10 @@ impl<T: EntityData, Q: TableAccessQuerySet<T>> BatchedDbLayer<T> for SqliteDbLay
|
|||||||
{
|
{
|
||||||
let mut stmt = tx.prepare(Q::add()).expect("Failed to prepare state query");
|
let mut stmt = tx.prepare(Q::add()).expect("Failed to prepare state query");
|
||||||
for entity in entities.iter() {
|
for entity in entities.iter() {
|
||||||
stmt.execute(Q::insert_params(entity))
|
stmt.execute(Q::insert_params(entity)).map_err(|e| {
|
||||||
.map_err(|_| DbSaveError)?;
|
error!("{}", e);
|
||||||
|
DbSaveError
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ impl TableAccessQuerySet<WordGroup> for WordGroupQuerySet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add() -> &'static str {
|
fn add() -> &'static str {
|
||||||
"INSERT INTO word_groups (name) VALUES (?1) RETURNING id"
|
"INSERT INTO word_groups (name) VALUES (?1)"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name() -> &'static str {
|
fn name() -> &'static str {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ impl TableAccessQuerySet<WordData> for WordQuerySet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add() -> &'static str {
|
fn add() -> &'static str {
|
||||||
"INSERT INTO words (key, value, tags, more, group_id) VALUES (?1, ?2, ?3, ?4, ?5) RETURNING id"
|
"INSERT INTO words (key, value, tags, more, group_id) VALUES (?1, ?2, ?3, ?4, ?5)"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name() -> &'static str {
|
fn name() -> &'static str {
|
||||||
@@ -63,7 +63,7 @@ impl TableAccessQuerySet<WordData> for WordQuerySet {
|
|||||||
pub fn add_word(word: &mut WordData, connection: &Connection) -> MaybeError {
|
pub fn add_word(word: &mut WordData, connection: &Connection) -> MaybeError {
|
||||||
let index : u32 = connection
|
let index : u32 = connection
|
||||||
.query_row(
|
.query_row(
|
||||||
"INSERT INTO words (key, value, tags, more, group_id) VALUES (?1, ?2, ?3, ?4, ?5) RETURNING id",
|
"INSERT INTO words (key, value, tags, more, group_id) VALUES (?1, ?2, ?3, ?4, ?5)",
|
||||||
(
|
(
|
||||||
&word.key,
|
&word.key,
|
||||||
&word.value,
|
&word.value,
|
||||||
@@ -193,7 +193,7 @@ pub fn load_word_groups(connection: &Connection) -> Result<Vec<WordGroup>, Notif
|
|||||||
pub fn add_group(group: &mut WordGroup, connection: &Connection) -> MaybeError {
|
pub fn add_group(group: &mut WordGroup, connection: &Connection) -> MaybeError {
|
||||||
let index: u32 = connection
|
let index: u32 = connection
|
||||||
.query_row(
|
.query_row(
|
||||||
"INSERT INTO word_groups (name) VALUES (?1) RETURNING id",
|
"INSERT INTO word_groups (name) VALUES (?1)",
|
||||||
(&group.name,),
|
(&group.name,),
|
||||||
|row| row.get(0),
|
|row| row.get(0),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -382,7 +382,7 @@ impl DictionaryState {
|
|||||||
scrollable(col).height(Fill).into()
|
scrollable(col).height(Fill).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn word_line<'a>(data: &WordLineState) -> Row<'a, DictionaryMessage> {
|
fn word_line<'a>(data: &WordLineState) -> Row<'a, DictionaryMessage> {
|
||||||
let mut line = Row::new().width(Fill).align_y(Center);
|
let mut line = Row::new().width(Fill).align_y(Center);
|
||||||
let handle = data.handle.clone();
|
let handle = data.handle.clone();
|
||||||
line = line.push(
|
line = line.push(
|
||||||
@@ -391,7 +391,7 @@ impl DictionaryState {
|
|||||||
.spacing(15)
|
.spacing(15)
|
||||||
.on_toggle(move |b| Include(handle, b)),
|
.on_toggle(move |b| Include(handle, b)),
|
||||||
);
|
);
|
||||||
//
|
|
||||||
line = line.push(
|
line = line.push(
|
||||||
text_input("Слово", &data.key)
|
text_input("Слово", &data.key)
|
||||||
.size(ACCENT_FONT_SIZE)
|
.size(ACCENT_FONT_SIZE)
|
||||||
|
|||||||
Reference in new issue
Block a user