summaryrefslogtreecommitdiff
path: root/src/db.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/db.rs')
-rw-r--r--src/db.rs130
1 files changed, 62 insertions, 68 deletions
diff --git a/src/db.rs b/src/db.rs
index 86f2083..92bfecd 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -1,8 +1,6 @@
use anyhow::{Result, anyhow};
use directories::BaseDirs;
-use r2d2::{Pool, PooledConnection};
-use r2d2_sqlite::SqliteConnectionManager;
-use rusqlite::params;
+use rusqlite::{Connection, params};
use std::{
path::{Path, PathBuf},
time::UNIX_EPOCH,
@@ -22,36 +20,36 @@ const DEDUPE_DB: &str =
"DELETE FROM flacs WHERE rowid NOT IN (SELECT MAX(rowid) FROM flacs GROUP BY path)";
const GET_MODTIME: &str = "SELECT modtime FROM flacs WHERE path = ?1";
-pub fn open_db(
- path: Option<impl AsRef<Path>>,
- threads: usize,
-) -> Result<Pool<SqliteConnectionManager>> {
- if let Some(file) = path {
- let manager = SqliteConnectionManager::file(file);
- let pool = Pool::builder().max_size(threads as u32).build(manager)?;
- let conn = pool.get()?;
- conn.execute(TABLE_CREATE, ())?;
- Ok(pool)
- } else if let Some(base_dir) = BaseDirs::new() {
- let file = Path::new(base_dir.data_dir()).join("reencoder.db");
- let manager = SqliteConnectionManager::file(file);
- let pool = Pool::builder().max_size(threads as u32).build(manager)?;
- let conn = pool.get()?;
- conn.execute(TABLE_CREATE, ())?;
- Ok(pool)
- } else {
- Err(anyhow!("Failed to locate data directory"))
- }
+pub trait Database {
+ type Conn;
+ fn new(path: Option<impl AsRef<Path>>) -> Result<Self::Conn>;
+ fn insert_file(&self, filename: impl AsRef<Path>) -> Result<()>;
+ fn update_file(&self, filename: impl AsRef<Path>) -> Result<()>;
+ fn check_file(&self, filename: impl AsRef<Path>) -> Result<bool>;
+ fn init_clean_files(&self) -> Result<Vec<PathBuf>, rusqlite::Error>;
+ fn remove_file(&self, filename: impl AsRef<Path>) -> Result<()>;
+ fn get_toencode_files(&self) -> Result<Vec<PathBuf>, rusqlite::Error>;
+ fn get_toencode_number(&self) -> Result<u64, rusqlite::Error>;
+ fn get_modtime(&self, file: impl AsRef<Path>) -> Result<u64>;
+ fn vacuum(&self) -> Result<()>;
}
-pub struct Database(pub PooledConnection<SqliteConnectionManager>);
-
-impl Database {
- pub fn new(conn: PooledConnection<SqliteConnectionManager>) -> Self {
- Database(conn)
+impl Database for Connection {
+ type Conn = Connection;
+ fn new(path: Option<impl AsRef<Path>>) -> Result<Self> {
+ let conn = if let Some(file) = path {
+ Connection::open(file)?
+ } else if let Some(base_dir) = BaseDirs::new() {
+ let file = Path::new(base_dir.data_dir()).join("reencoder.db");
+ Connection::open(file)?
+ } else {
+ return Err(anyhow!("Failed to locate data directory"));
+ };
+ conn.execute(TABLE_CREATE, ())?;
+ Ok(conn)
}
- pub fn insert_file(&self, filename: impl AsRef<Path>) -> Result<()> {
+ fn insert_file(&self, filename: impl AsRef<Path>) -> Result<()> {
let toencode = !matches!(get_vendor(&filename)?.as_str(), CURRENT_VENDOR);
let modtime = filename
@@ -61,7 +59,7 @@ impl Database {
.duration_since(UNIX_EPOCH)?
.as_secs();
- self.0.execute(
+ self.execute(
ADD_NEW_ITEM,
params![filename.as_ref().to_str().unwrap(), toencode, modtime],
)?;
@@ -69,7 +67,7 @@ impl Database {
Ok(())
}
- pub fn update_file(&self, filename: impl AsRef<Path>) -> Result<()> {
+ fn update_file(&self, filename: impl AsRef<Path>) -> Result<()> {
let modtime = filename
.as_ref()
.metadata()?
@@ -77,7 +75,7 @@ impl Database {
.duration_since(UNIX_EPOCH)?
.as_secs();
- self.0.execute(
+ self.execute(
REPLACE_ITEM,
params![filename.as_ref().to_str().unwrap(), false, modtime],
)?;
@@ -85,8 +83,8 @@ impl Database {
Ok(())
}
- pub fn check_file(&self, filename: impl AsRef<Path>) -> Result<bool> {
- if self.0.query_one(
+ fn check_file(&self, filename: impl AsRef<Path>) -> Result<bool> {
+ if self.query_one(
CHECK_FILE,
params!(filename.as_ref().to_str().unwrap()),
|row| {
@@ -100,9 +98,9 @@ impl Database {
}
}
- pub fn init_clean_files(&self) -> Result<Vec<PathBuf>, rusqlite::Error> {
- self.0.execute(DEDUPE_DB, ())?;
- let mut stmt = self.0.prepare(FETCH_FILES)?;
+ fn init_clean_files(&self) -> Result<Vec<PathBuf>, rusqlite::Error> {
+ self.execute(DEDUPE_DB, ())?;
+ let mut stmt = self.prepare(FETCH_FILES)?;
let mut rows = stmt.query(())?;
let mut files = Vec::new();
while let Ok(Some(row)) = rows.next() {
@@ -112,14 +110,13 @@ impl Database {
Ok(files)
}
- pub fn remove_file(&self, filename: impl AsRef<Path>) -> Result<()> {
- self.0
- .execute(REMOVE_FILE, params!(filename.as_ref().to_str().unwrap()))?;
+ fn remove_file(&self, filename: impl AsRef<Path>) -> Result<()> {
+ self.execute(REMOVE_FILE, params!(filename.as_ref().to_str().unwrap()))?;
Ok(())
}
- pub fn get_toencode_files(&self) -> Result<Vec<PathBuf>, rusqlite::Error> {
- let mut stmt = self.0.prepare(TOENCODE_QUERY)?;
+ fn get_toencode_files(&self) -> Result<Vec<PathBuf>, rusqlite::Error> {
+ let mut stmt = self.prepare(TOENCODE_QUERY)?;
let mut rows = stmt.query(())?;
let mut files: Vec<PathBuf> = Vec::new();
while let Ok(Some(row)) = rows.next() {
@@ -129,15 +126,15 @@ impl Database {
Ok(files)
}
- pub fn get_toencode_number(&self) -> Result<u64, rusqlite::Error> {
- self.0.query_one(TOENCODE_NUMBER, (), |row| {
+ fn get_toencode_number(&self) -> Result<u64, rusqlite::Error> {
+ self.query_one(TOENCODE_NUMBER, (), |row| {
let num: u64 = row.get(0)?;
Ok(num)
})
}
- pub fn get_modtime(&self, file: impl AsRef<Path>) -> Result<u64> {
- Ok(self.0.query_one(
+ fn get_modtime(&self, file: impl AsRef<Path>) -> Result<u64> {
+ Ok(self.query_one(
GET_MODTIME,
params![file.as_ref().to_str().unwrap()],
|row| {
@@ -147,8 +144,8 @@ impl Database {
)?)
}
- pub fn vaccum(&self) -> Result<()> {
- self.0.execute("VACUUM", ())?;
+ fn vacuum(&self) -> Result<()> {
+ self.execute("VACUUM", ())?;
Ok(())
}
}
@@ -163,12 +160,11 @@ mod tests {
let dbname = String::from("temp1.db");
let filenames = ["16bit.flac", "24bit.flac", "32bit.flac"];
let mut counter = 0;
- let pool = open_db(Some(&dbname), 10).unwrap();
- let conn = Database::new(pool.get().unwrap());
+ let conn = Connection::new(Some(&dbname)).unwrap();
for file in filenames {
conn.insert_file(&file.to_string()).unwrap();
}
- let mut stmt = conn.0.prepare(TOENCODE_QUERY).unwrap();
+ let mut stmt = conn.prepare(TOENCODE_QUERY).unwrap();
let mut returned = stmt.query(()).unwrap();
while let Ok(Some(_)) = returned.next() {
@@ -182,27 +178,25 @@ mod tests {
fn check_update() {
let dbname = String::from("temp2.db");
let filenames = ["16bit.flac", "24bit.flac", "32bit.flac"];
- let pool = open_db(Some(&dbname), 10).unwrap();
- let conn = Database::new(pool.get().unwrap());
+ let conn = Connection::new(Some(&dbname)).unwrap();
for file in filenames {
conn.insert_file(Path::new(file).canonicalize().unwrap())
.unwrap();
}
- conn.0
- .execute(
- REPLACE_ITEM,
- params![
- Path::new("16bit.flac")
- .canonicalize()
- .unwrap()
- .to_str()
- .unwrap(),
- true,
- ""
- ],
- )
- .unwrap();
+ conn.execute(
+ REPLACE_ITEM,
+ params![
+ Path::new("16bit.flac")
+ .canonicalize()
+ .unwrap()
+ .to_str()
+ .unwrap(),
+ true,
+ ""
+ ],
+ )
+ .unwrap();
conn.update_file(
Path::new("16bit.flac")
@@ -213,7 +207,7 @@ mod tests {
)
.unwrap();
- let mut stmt = conn.0.prepare(TOENCODE_QUERY).unwrap();
+ let mut stmt = conn.prepare(TOENCODE_QUERY).unwrap();
let mut returned = stmt.query(()).unwrap();
let mut counter = 0;
while let Ok(Some(_)) = returned.next() {