mirror of
https://github.com/patarapolw/cjdic2.git
synced 2026-11-09 17:39:35 +00:00
main as user.db, then attach readonly db's
This commit is contained in:
1 parent
d96346bfea
commit
fa5bfb56b0
11 files changed
+526
-435
No files matched your search
+65
-9
@@ -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<()> {
|
||||
|
||||
Reference in new issue
Block a user