Flush db file's dir
This commit is contained in:
parent
62f8e5fdcd
commit
4324792f54
1 changed files with 23 additions and 16 deletions
|
|
@ -2,7 +2,7 @@ use core::time::Duration;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Arc,
|
sync::{Arc, Weak},
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Result};
|
||||||
|
|
@ -48,6 +48,7 @@ impl std::fmt::Debug for PoolWithTimestamp {
|
||||||
pub struct Database {
|
pub struct Database {
|
||||||
config: DatabaseConfig,
|
config: DatabaseConfig,
|
||||||
connection_pools: Arc<Mutex<HashMap<VaultId, PoolWithTimestamp>>>,
|
connection_pools: Arc<Mutex<HashMap<VaultId, PoolWithTimestamp>>>,
|
||||||
|
opening_pools: Arc<Mutex<HashMap<VaultId, Weak<Mutex<()>>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Transaction<'a> = sqlx::Transaction<'a, Sqlite>;
|
pub type Transaction<'a> = sqlx::Transaction<'a, Sqlite>;
|
||||||
|
|
@ -66,25 +67,13 @@ impl Database {
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
info!("Applying pending database migrations");
|
// SQLite flushes its own files, not ancestors created by this process
|
||||||
|
Self::flush_directory_ancestors(&vault_directory).await?;
|
||||||
// Filenames encode only a digest, so their vault names cannot be
|
|
||||||
// recovered here. Check migrations now and open pools lazily by name.
|
|
||||||
let mut entries = tokio::fs::read_dir(&vault_directory).await?;
|
|
||||||
while let Some(entry) = entries.next_entry().await? {
|
|
||||||
if entry.file_type().await?.is_file()
|
|
||||||
&& entry.path().extension().is_some_and(|ext| ext == "sqlite")
|
|
||||||
{
|
|
||||||
Self::open_database(config, &entry.path())
|
|
||||||
.await?
|
|
||||||
.close()
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let database = Self {
|
let database = Self {
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
connection_pools: Arc::default(),
|
connection_pools: Arc::default(),
|
||||||
|
opening_pools: Arc::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start background task to cleanup idle connection pools
|
// Start background task to cleanup idle connection pools
|
||||||
|
|
@ -127,9 +116,27 @@ impl Database {
|
||||||
|
|
||||||
Self::run_migrations(&pool).await?;
|
Self::run_migrations(&pool).await?;
|
||||||
|
|
||||||
|
if let Some(directory) = file_name.parent() {
|
||||||
|
#[cfg(unix)]
|
||||||
|
Self::flush_directory_ancestors(directory).await?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(pool)
|
Ok(pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn flush_directory_ancestors(directory: &Path) -> Result<()> {
|
||||||
|
let directory = tokio::fs::canonicalize(directory).await?;
|
||||||
|
for ancestor in directory.ancestors() {
|
||||||
|
tokio::fs::File::open(ancestor)
|
||||||
|
.await?
|
||||||
|
.sync_all()
|
||||||
|
.await
|
||||||
|
.with_context(|| format!("Cannot flush directory {}", ancestor.display()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn run_migrations(pool: &Pool<Sqlite>) -> Result<()> {
|
async fn run_migrations(pool: &Pool<Sqlite>) -> Result<()> {
|
||||||
sqlx::migrate!("src/app_state/database/migrations")
|
sqlx::migrate!("src/app_state/database/migrations")
|
||||||
.run(pool)
|
.run(pool)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue