main as user.db, then attach readonly db's

This commit is contained in:
polv committed 2026-02-23 14:56:42 +07:00
1 parent d96346bfea
commit fa5bfb56b0
11 files changed
+526 -435

No files matched your search

+65 -9
View File
@@ -1,30 +1,86 @@
use std::{
path::Path,
sync::{Arc, Mutex},
env::current_dir,
path::{Path, PathBuf},
sync::{
Arc, Mutex,
atomic::{AtomicBool, Ordering},
},
};
use rusqlite::{Connection, Result};
use anyhow::Result;
use rusqlite::Connection;
use crate::models::Entry;
mod yomitan;
pub use yomitan::{YomitanRow, YomitanZipImportResult};
pub use yomitan::YomitanRow;
mod yomitan_writer;
pub use yomitan_writer::{YomitanWriter, YomitanZipImportResult};
#[derive(Clone)]
pub struct Database {
pub(crate) struct Database {
pub(crate) conn: Arc<Mutex<Connection>>,
pub(crate) dir: PathBuf,
yomitan_attached: Arc<AtomicBool>,
}
impl Database {
pub fn new<P: AsRef<Path>>(path: P) -> Result<Self> {
let conn = Connection::open(path)?;
pub fn new(db_dir: impl AsRef<Path>) -> Result<Self> {
let dir = db_dir.as_ref().to_path_buf();
let conn = Connection::open(dir.join("user.db"))?;
conn.execute_batch(
r"
PRAGMA jornal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA foreign_keys = ON;
",
)?;
Ok(Self {
conn: Arc::new(Mutex::new(conn)),
dir,
yomitan_attached: Arc::new(AtomicBool::new(false)),
})
}
pub fn yomitan(&self) -> yomitan::YomitanDatabase {
yomitan::YomitanDatabase::new(self.clone())
pub fn yomitan(&self) -> Result<yomitan::YomitanDatabase> {
self.ensure_yomitan_attached()?;
Ok(yomitan::YomitanDatabase::new(self.clone()))
}
fn ensure_yomitan_attached(&self) -> Result<()> {
if self.yomitan_attached.load(Ordering::Acquire) {
return Ok(());
}
let conn = self.conn.lock().unwrap();
if !self.yomitan_attached.load(Ordering::Relaxed) {
let dir = self.dir.clone();
let path = if self.dir.is_absolute() {
dir
} else {
current_dir()?.join(dir)
};
let mut path = path
.join("yomitan.db")
.to_string_lossy()
.replace(r"\", r"/");
#[cfg(windows)]
{
if !path.starts_with("/") {
path = format!("/{}", path);
}
}
let uri = format!("file:{}?mode=ro&immutable=1", path);
conn.execute("ATTACH DATABASE ?1 AS yomitan", [uri])?;
self.yomitan_attached.store(true, Ordering::Release);
}
Ok(())
}
pub fn init(&self) -> Result<()> {