fix: only get() connection in UpEndConnection when necessary

makes the interface actually respond during rescans, helps improve throughput in general
feat/type-attributes
Tomáš Mládek 2022-09-05 21:51:44 +02:00
parent 4018cae840
commit 91596b284d
1 changed files with 38 additions and 22 deletions

View File

@ -24,7 +24,7 @@ use crate::util::LoggerSink;
use anyhow::{anyhow, Result};
use chrono::NaiveDateTime;
use diesel::prelude::*;
use diesel::r2d2::{self, ConnectionManager, PooledConnection};
use diesel::r2d2::{self, ConnectionManager};
use diesel::result::{DatabaseErrorKind, Error};
use diesel::sqlite::SqliteConnection;
use hierarchies::initialize_hier;
@ -76,7 +76,7 @@ pub struct OpenResult {
}
pub struct UpEndDatabase {
pool: DbPool,
pool: Arc<DbPool>,
lock: Arc<RwLock<()>>,
pub vault_path: Arc<PathBuf>,
pub db_path: Arc<PathBuf>,
@ -119,7 +119,7 @@ impl UpEndDatabase {
trace!("Pool created.");
let db = UpEndDatabase {
pool,
pool: Arc::new(pool),
lock: Arc::new(RwLock::new(())),
vault_path: Arc::new(dirpath.as_ref().canonicalize()?),
db_path: Arc::new(upend_path),
@ -165,7 +165,7 @@ impl UpEndDatabase {
pub fn connection(&self) -> Result<UpEndConnection> {
Ok(UpEndConnection {
conn: self.pool.get()?,
pool: self.pool.clone(),
lock: self.lock.clone(),
vault_path: self.vault_path.clone(),
})
@ -173,14 +173,16 @@ impl UpEndDatabase {
}
pub struct UpEndConnection {
conn: PooledConnection<ConnectionManager<SqliteConnection>>,
pool: Arc<DbPool>,
lock: Arc<RwLock<()>>,
vault_path: Arc<PathBuf>,
}
impl UpEndConnection {
pub fn execute<S: AsRef<str>>(&self, query: S) -> Result<usize, diesel::result::Error> {
self.conn.execute(query.as_ref())
pub fn execute<S: AsRef<str>>(&self, query: S) -> Result<usize> {
let _lock = self.lock.write().unwrap();
let conn = self.pool.get()?;
Ok(conn.execute(query.as_ref())?)
}
pub fn transaction<T, E, F>(&self, f: F) -> Result<T, E>
@ -205,10 +207,11 @@ impl UpEndConnection {
debug!("Querying META:{key}");
let _lock = self.lock.read().unwrap();
let conn = self.pool.get()?;
dsl::meta
.filter(dsl::key.eq(key))
.load::<models::MetaValue>(&self.conn)?
.load::<models::MetaValue>(&conn)?
.first()
.ok_or(anyhow!(r#"No META "{key}" value found."#))
.map(|mv| mv.value.clone())
@ -224,16 +227,17 @@ impl UpEndConnection {
);
let _lock = self.lock.write().unwrap();
let conn = self.pool.get()?;
diesel::insert_into(files::table)
.values(&file)
.execute(&self.conn)?;
.execute(&conn)?;
Ok(files::dsl::files
.filter(files::dsl::valid.eq(true))
.filter(files::dsl::hash.eq(file.hash))
.count()
.first::<i64>(&self.conn)?
.first::<i64>(&conn)?
.try_into()
.unwrap())
}
@ -242,11 +246,12 @@ impl UpEndConnection {
use crate::database::inner::schema::files::dsl::*;
let _lock = self.lock.read().unwrap();
let conn = self.pool.get()?;
let matches = files
.filter(valid.eq(true))
.filter(hash.eq(&obj_hash.0))
.load::<models::File>(&self.conn)?;
.load::<models::File>(&conn)?;
let matches = matches
.into_iter()
@ -267,7 +272,8 @@ impl UpEndConnection {
pub fn retrieve_all_files(&self) -> Result<Vec<models::File>> {
use crate::database::inner::schema::files::dsl::*;
let _lock = self.lock.read().unwrap();
let matches = files.load::<models::File>(&self.conn)?;
let conn = self.pool.get()?;
let matches = files.load::<models::File>(&conn)?;
Ok(matches)
}
@ -277,10 +283,11 @@ impl UpEndConnection {
debug!("Setting file ID {}'s mtime = {:?}", file_id, m_time);
let _lock = self.lock.write().unwrap();
let conn = self.pool.get()?;
Ok(diesel::update(files.filter(id.eq(file_id)))
.set(mtime.eq(m_time))
.execute(&self.conn)?)
.execute(&conn)?)
}
pub fn file_set_valid(&self, file_id: i32, is_valid: bool) -> Result<usize> {
@ -289,10 +296,11 @@ impl UpEndConnection {
debug!("Setting file ID {} to valid = {}", file_id, is_valid);
let _lock = self.lock.write().unwrap();
let conn = self.pool.get()?;
Ok(diesel::update(files.filter(id.eq(file_id)))
.set(valid.eq(is_valid))
.execute(&self.conn)?)
.execute(&conn)?)
}
pub fn normalize_path(&self, path: &Path) -> Result<PathBuf> {
@ -306,10 +314,11 @@ impl UpEndConnection {
use crate::database::inner::schema::data::dsl::*;
let _lock = self.lock.read().unwrap();
let conn = self.pool.get()?;
let entry = data
.filter(identity.eq(Address::Hash(hash.clone()).encode()?))
.load::<models::Entry>(&self.conn)?;
.load::<models::Entry>(&conn)?;
match entry.len() {
0 => Ok(None),
@ -326,11 +335,12 @@ impl UpEndConnection {
use crate::database::inner::schema::data::dsl::*;
let _lock = self.lock.read().unwrap();
let conn = self.pool.get()?;
let primary = data
.filter(entity.eq(object_address.encode()?))
.or_filter(value_str.eq(EntryValue::Address(object_address.clone()).to_string()?))
.load::<models::Entry>(&self.conn)?;
.load::<models::Entry>(&conn)?;
let entries = primary
.iter()
@ -348,7 +358,7 @@ impl UpEndConnection {
.collect::<Result<Vec<Vec<u8>>>>()?,
),
)
.load::<models::Entry>(&self.conn)?;
.load::<models::Entry>(&conn)?;
let secondary_entries = secondary
.iter()
@ -364,21 +374,23 @@ impl UpEndConnection {
debug!("Deleting {}!", object_address);
let _lock = self.lock.write().unwrap();
let conn = self.pool.get()?;
let matches = data
.filter(identity.eq(object_address.encode()?))
.or_filter(entity.eq(object_address.encode()?))
.or_filter(value_str.eq(EntryValue::Address(object_address).to_string()?));
Ok(diesel::delete(matches).execute(&self.conn)?)
Ok(diesel::delete(matches).execute(&conn)?)
}
pub fn query(&self, query: Query) -> Result<Vec<Entry>> {
trace!("Querying: {:?}", query);
let _lock = self.lock.read().unwrap();
let conn = self.pool.get()?;
let entries = execute(&self.conn, query)?;
let entries = execute(&conn, query)?;
let entries = entries
.iter()
.map(Entry::try_from)
@ -405,9 +417,11 @@ impl UpEndConnection {
fn insert_model_entry(&self, entry: models::Entry) -> Result<usize> {
let _lock = self.lock.write().unwrap();
let conn = self.pool.get()?;
let result = diesel::insert_into(data::table)
.values(&entry)
.execute(&self.conn);
.execute(&conn);
match result {
Ok(num) => Ok(num),
@ -423,11 +437,12 @@ impl UpEndConnection {
use crate::database::inner::schema::data::dsl::*;
let _lock = self.lock.read().unwrap();
let conn = self.pool.get()?;
let result = data
.select(entity)
.distinct()
.load::<Vec<u8>>(&self.conn)?
.load::<Vec<u8>>(&conn)?
.into_iter()
.filter_map(|buf| Address::decode(&buf).ok())
.collect();
@ -440,12 +455,13 @@ impl UpEndConnection {
use crate::database::inner::schema::data::dsl::*;
let _lock = self.lock.read().unwrap();
let conn = self.pool.get()?;
let result = data
.select(attribute)
.distinct()
.order_by(attribute)
.load::<String>(&self.conn)?;
.load::<String>(&conn)?;
Ok(result)
}