hold the DB open for the duration of the check

This commit is contained in:
Damien Elmes 2020-02-08 21:02:43 +10:00
parent cee8d4b789
commit 3350b4fa69
3 changed files with 17 additions and 6 deletions

View File

@ -314,7 +314,10 @@ impl Backend {
fn add_file_to_media_folder(&mut self, input: pt::AddFileToMediaFolderIn) -> Result<String> { fn add_file_to_media_folder(&mut self, input: pt::AddFileToMediaFolderIn) -> Result<String> {
let mgr = MediaManager::new(&self.media_folder, &self.media_db)?; let mgr = MediaManager::new(&self.media_folder, &self.media_db)?;
Ok(mgr.add_file(&input.desired_name, &input.data)?.into()) let mut ctx = mgr.dbctx();
Ok(mgr
.add_file(&mut ctx, &input.desired_name, &input.data)?
.into())
} }
fn sync_media(&self, input: SyncMediaIn) -> Result<()> { fn sync_media(&self, input: SyncMediaIn) -> Result<()> {

View File

@ -2,6 +2,7 @@
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use crate::err::{AnkiError, Result}; use crate::err::{AnkiError, Result};
use crate::media::database::MediaDatabaseContext;
use crate::media::files::{ use crate::media::files::{
data_for_file, filename_if_normalized, remove_files, MEDIA_SYNC_FILESIZE_LIMIT, data_for_file, filename_if_normalized, remove_files, MEDIA_SYNC_FILESIZE_LIMIT,
}; };
@ -60,6 +61,7 @@ where
let mut oversize = vec![]; let mut oversize = vec![];
let mut all_files = vec![]; let mut all_files = vec![];
let mut renamed_files = vec![]; let mut renamed_files = vec![];
let mut ctx = self.mgr.dbctx();
for dentry in self.mgr.media_folder.read_dir()? { for dentry in self.mgr.media_folder.read_dir()? {
let dentry = dentry?; let dentry = dentry?;
@ -92,7 +94,7 @@ where
} }
// rename if required // rename if required
let (norm_name, renamed) = self.normalize_and_maybe_rename(&disk_fname)?; let (norm_name, renamed) = self.normalize_and_maybe_rename(&mut ctx, &disk_fname)?;
if renamed { if renamed {
renamed_files.push(RenamedFile { renamed_files.push(RenamedFile {
current_fname: norm_name.to_string(), current_fname: norm_name.to_string(),
@ -114,6 +116,7 @@ where
/// Returns (normalized_form, needs_rename) /// Returns (normalized_form, needs_rename)
fn normalize_and_maybe_rename<'a>( fn normalize_and_maybe_rename<'a>(
&mut self, &mut self,
ctx: &mut MediaDatabaseContext,
disk_fname: &'a str, disk_fname: &'a str,
) -> Result<(Cow<'a, str>, bool)> { ) -> Result<(Cow<'a, str>, bool)> {
// already normalized? // already normalized?
@ -127,7 +130,7 @@ where
info: "file disappeared".into(), info: "file disappeared".into(),
} }
})?; })?;
let fname = self.mgr.add_file(disk_fname, &data)?; let fname = self.mgr.add_file(ctx, disk_fname, &data)?;
debug!("renamed {} to {}", disk_fname, fname); debug!("renamed {} to {}", disk_fname, fname);
assert_ne!(fname.as_ref(), disk_fname); assert_ne!(fname.as_ref(), disk_fname);

View File

@ -39,7 +39,12 @@ impl MediaManager {
/// appended to the name. /// appended to the name.
/// ///
/// Also notes the file in the media database. /// Also notes the file in the media database.
pub fn add_file<'a>(&self, desired_name: &'a str, data: &[u8]) -> Result<Cow<'a, str>> { pub fn add_file<'a>(
&self,
ctx: &mut MediaDatabaseContext,
desired_name: &'a str,
data: &[u8],
) -> Result<Cow<'a, str>> {
let pre_add_folder_mtime = mtime_as_i64(&self.media_folder)?; let pre_add_folder_mtime = mtime_as_i64(&self.media_folder)?;
// add file to folder // add file to folder
@ -50,7 +55,7 @@ impl MediaManager {
let post_add_folder_mtime = mtime_as_i64(&self.media_folder)?; let post_add_folder_mtime = mtime_as_i64(&self.media_folder)?;
// add to the media DB // add to the media DB
self.dbctx().transact(|ctx| { ctx.transact(|ctx| {
let existing_entry = ctx.get_entry(&chosen_fname)?; let existing_entry = ctx.get_entry(&chosen_fname)?;
let new_sha1 = Some(data_hash); let new_sha1 = Some(data_hash);
@ -94,7 +99,7 @@ impl MediaManager {
syncer.sync(hkey).await syncer.sync(hkey).await
} }
fn dbctx(&self) -> MediaDatabaseContext { pub fn dbctx(&self) -> MediaDatabaseContext {
MediaDatabaseContext::new(&self.db) MediaDatabaseContext::new(&self.db)
} }
} }