mirror of
https://github.com/ankitects/anki.git
synced 2025-12-10 21:36:55 -05:00
move note code into notes.rs, add ability to rollback when unchanged
This commit is contained in:
parent
ae06b9e446
commit
47c142a74c
6 changed files with 36 additions and 26 deletions
|
|
@ -1,3 +1,6 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use crate::err::Result;
|
||||
use crate::i18n::I18n;
|
||||
use crate::log::Logger;
|
||||
|
|
@ -35,6 +38,7 @@ pub(crate) struct RequestContext<'a> {
|
|||
pub storage: StorageContext<'a>,
|
||||
pub i18n: &'a I18n,
|
||||
pub log: &'a Logger,
|
||||
pub should_commit: bool,
|
||||
}
|
||||
|
||||
impl Collection {
|
||||
|
|
@ -52,6 +56,7 @@ impl Collection {
|
|||
storage: self.storage.context(self.server),
|
||||
i18n: &self.i18n,
|
||||
log: &self.log,
|
||||
should_commit: true,
|
||||
};
|
||||
func(&mut ctx)
|
||||
}
|
||||
|
|
@ -67,13 +72,15 @@ impl Collection {
|
|||
|
||||
let mut res = func(ctx);
|
||||
|
||||
if res.is_ok() {
|
||||
if let Err(e) = ctx.storage.commit_rust_op(op) {
|
||||
if res.is_ok() && ctx.should_commit {
|
||||
if let Err(e) = ctx.storage.mark_modified() {
|
||||
res = Err(e);
|
||||
} else if let Err(e) = ctx.storage.commit_rust_op(op) {
|
||||
res = Err(e);
|
||||
}
|
||||
}
|
||||
|
||||
if res.is_err() {
|
||||
if res.is_err() || !ctx.should_commit {
|
||||
ctx.storage.rollback_rust_trx()?;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ pub mod i18n;
|
|||
pub mod latex;
|
||||
pub mod log;
|
||||
pub mod media;
|
||||
pub mod notes;
|
||||
pub mod sched;
|
||||
pub mod storage;
|
||||
pub mod template;
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ use crate::err::{AnkiError, DBErrorKind, Result};
|
|||
use crate::i18n::{tr_args, tr_strs, FString};
|
||||
use crate::latex::extract_latex_expanding_clozes;
|
||||
use crate::log::debug;
|
||||
use crate::media::col::{for_every_note, get_note_types, mark_collection_modified, set_note, Note};
|
||||
use crate::media::database::MediaDatabaseContext;
|
||||
use crate::media::files::{
|
||||
data_for_file, filename_if_normalized, trash_folder, MEDIA_SYNC_FILESIZE_LIMIT,
|
||||
};
|
||||
use crate::notes::{for_every_note, get_note_types, set_note, Note};
|
||||
use crate::text::{normalize_to_nfc, MediaRef};
|
||||
use crate::{media::MediaManager, text::extract_media_refs};
|
||||
use coarsetime::Instant;
|
||||
|
|
@ -42,26 +42,26 @@ struct MediaFolderCheck {
|
|||
oversize: Vec<String>,
|
||||
}
|
||||
|
||||
pub struct MediaChecker<'a, P>
|
||||
pub struct MediaChecker<'a, 'b, P>
|
||||
where
|
||||
P: FnMut(usize) -> bool,
|
||||
{
|
||||
ctx: &'a RequestContext<'a>,
|
||||
ctx: &'a mut RequestContext<'b>,
|
||||
mgr: &'a MediaManager,
|
||||
progress_cb: P,
|
||||
checked: usize,
|
||||
progress_updated: Instant,
|
||||
}
|
||||
|
||||
impl<P> MediaChecker<'_, P>
|
||||
impl<P> MediaChecker<'_, '_, P>
|
||||
where
|
||||
P: FnMut(usize) -> bool,
|
||||
{
|
||||
pub(crate) fn new<'a>(
|
||||
ctx: &'a RequestContext<'a>,
|
||||
pub(crate) fn new<'a, 'b>(
|
||||
ctx: &'a mut RequestContext<'b>,
|
||||
mgr: &'a MediaManager,
|
||||
progress_cb: P,
|
||||
) -> MediaChecker<'a, P> {
|
||||
) -> MediaChecker<'a, 'b, P> {
|
||||
MediaChecker {
|
||||
ctx,
|
||||
mgr,
|
||||
|
|
@ -404,8 +404,8 @@ where
|
|||
Ok(())
|
||||
})?;
|
||||
|
||||
if collection_modified {
|
||||
mark_collection_modified(&self.ctx.storage.db)?;
|
||||
if !collection_modified {
|
||||
self.ctx.should_commit = false;
|
||||
}
|
||||
|
||||
Ok(referenced_files)
|
||||
|
|
@ -546,7 +546,7 @@ mod test {
|
|||
let progress = |_n| true;
|
||||
|
||||
let (output, report) = col.transact(None, |ctx| {
|
||||
let mut checker = MediaChecker::new(&ctx, &mgr, progress);
|
||||
let mut checker = MediaChecker::new(ctx, &mgr, progress);
|
||||
let output = checker.check()?;
|
||||
let summary = checker.summarize_output(&mut output.clone());
|
||||
Ok((output, summary))
|
||||
|
|
@ -616,7 +616,7 @@ Unused: unused.jpg
|
|||
let progress = |_n| true;
|
||||
|
||||
col.transact(None, |ctx| {
|
||||
let mut checker = MediaChecker::new(&ctx, &mgr, progress);
|
||||
let mut checker = MediaChecker::new(ctx, &mgr, progress);
|
||||
checker.restore_trash()
|
||||
})?;
|
||||
|
||||
|
|
@ -630,7 +630,7 @@ Unused: unused.jpg
|
|||
// if we repeat the process, restoring should do the same thing if the contents are equal
|
||||
fs::write(trash_folder.join("test.jpg"), "test")?;
|
||||
col.transact(None, |ctx| {
|
||||
let mut checker = MediaChecker::new(&ctx, &mgr, progress);
|
||||
let mut checker = MediaChecker::new(ctx, &mgr, progress);
|
||||
checker.restore_trash()
|
||||
})?;
|
||||
assert_eq!(files_in_dir(&trash_folder), Vec::<String>::new());
|
||||
|
|
@ -642,7 +642,7 @@ Unused: unused.jpg
|
|||
// but rename if required
|
||||
fs::write(trash_folder.join("test.jpg"), "test2")?;
|
||||
col.transact(None, |ctx| {
|
||||
let mut checker = MediaChecker::new(&ctx, &mgr, progress);
|
||||
let mut checker = MediaChecker::new(ctx, &mgr, progress);
|
||||
checker.restore_trash()
|
||||
})?;
|
||||
assert_eq!(files_in_dir(&trash_folder), Vec::<String>::new());
|
||||
|
|
@ -666,7 +666,7 @@ Unused: unused.jpg
|
|||
let progress = |_n| true;
|
||||
|
||||
let mut output = col.transact(None, |ctx| {
|
||||
let mut checker = MediaChecker::new(&ctx, &mgr, progress);
|
||||
let mut checker = MediaChecker::new(ctx, &mgr, progress);
|
||||
checker.check()
|
||||
})?;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ use std::path::{Path, PathBuf};
|
|||
|
||||
pub mod changetracker;
|
||||
pub mod check;
|
||||
pub mod col;
|
||||
pub mod database;
|
||||
pub mod files;
|
||||
pub mod sync;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
/// Basic note reading/updating functionality for the media DB check.
|
||||
/// At the moment, this is just basic note reading/updating functionality for
|
||||
/// the media DB check.
|
||||
use crate::err::{AnkiError, DBErrorKind, Result};
|
||||
use crate::text::strip_html_preserving_image_filenames;
|
||||
use crate::time::{i64_unix_millis, i64_unix_secs};
|
||||
use crate::time::i64_unix_secs;
|
||||
use crate::types::{ObjID, Timestamp, Usn};
|
||||
use rusqlite::{params, Connection, Row, NO_PARAMS};
|
||||
use serde_aux::field_attributes::deserialize_number_from_string;
|
||||
|
|
@ -140,8 +141,3 @@ pub(super) fn set_note(db: &Connection, note: &mut Note, note_type: &NoteType) -
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn mark_collection_modified(db: &Connection) -> Result<()> {
|
||||
db.execute("update col set mod=?", params![i64_unix_millis()])?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
use crate::collection::CollectionOp;
|
||||
use crate::err::Result;
|
||||
use crate::err::{AnkiError, DBErrorKind};
|
||||
use crate::time::i64_unix_secs;
|
||||
use crate::time::{i64_unix_millis, i64_unix_secs};
|
||||
use crate::types::Usn;
|
||||
use rusqlite::{params, Connection, NO_PARAMS};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
|
@ -173,6 +173,13 @@ impl StorageContext<'_> {
|
|||
|
||||
//////////////////////////////////////////
|
||||
|
||||
pub(crate) fn mark_modified(&self) -> Result<()> {
|
||||
self.db
|
||||
.prepare_cached("update col set mod=?")?
|
||||
.execute(params![i64_unix_millis()])?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn usn(&mut self) -> Result<Usn> {
|
||||
if self.server {
|
||||
|
|
|
|||
Loading…
Reference in a new issue