use std::{
mem::ManuallyDrop,
ops::{Deref, DerefMut},
sync::Arc
};
use rusqlite::{Connection, params};
use crate::Error;
use super::{InnerWrConn, Shared};
pub struct WrConn {
pub(super) sh: Arc<Shared>,
pub(super) inner: ManuallyDrop<InnerWrConn>
}
impl WrConn {
#[allow(clippy::missing_const_for_fn)]
pub fn add_dirt(&mut self, weight: usize) {
self.inner.dirt = self.inner.dirt.saturating_add(weight);
}
}
impl WrConn {
pub fn incremental_vacuum(&self, n: Option<usize>) -> Result<(), Error> {
let n = if let Some(n) = n {
Some(
i64::try_from(n)
.map_err(|_| Error::bad_param("Invalid page count"))?
)
} else {
None
};
n.map_or_else(
|| {
self
.inner
.conn
.execute("PRAGMA incremental_vacuum;", params![])
},
|n| {
self
.inner
.conn
.execute("PRAGMA incremental_vacuum(?);", params![n])
}
)
.map(|_| ())
.map_err(Error::Sqlite)
}
}
impl Deref for WrConn {
type Target = Connection;
fn deref(&self) -> &Connection {
&self.inner.conn
}
}
impl DerefMut for WrConn {
fn deref_mut(&mut self) -> &mut Connection {
&mut self.inner.conn
}
}
impl Drop for WrConn {
fn drop(&mut self) {
let mut g = self.sh.inner.lock();
g.conn = Some(unsafe { ManuallyDrop::take(&mut self.inner) });
self.sh.signal.notify_one();
}
}