use single connection to database

This commit is contained in:
Nikita Galaiko 2023-05-23 10:21:58 +02:00
parent b17f704efb
commit 2fb8fe3389
3 changed files with 29 additions and 69 deletions

32
src-tauri/Cargo.lock generated
View File

@ -1480,8 +1480,6 @@ dependencies = [
"md5",
"notify",
"portable-pty",
"r2d2",
"r2d2_sqlite",
"refinery",
"reqwest",
"rusqlite",
@ -3255,27 +3253,6 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "r2d2"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93"
dependencies = [
"log",
"parking_lot",
"scheduled-thread-pool",
]
[[package]]
name = "r2d2_sqlite"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4f5d0337e99cd5cacd91ffc326c6cc9d8078def459df560c4f9bf9ba4a51034"
dependencies = [
"r2d2",
"rusqlite",
]
[[package]]
name = "rand"
version = "0.7.3"
@ -3687,15 +3664,6 @@ dependencies = [
"windows-sys 0.42.0",
]
[[package]]
name = "scheduled-thread-pool"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19"
dependencies = [
"parking_lot",
]
[[package]]
name = "scoped-tls"
version = "1.0.1"

View File

@ -53,9 +53,7 @@ sentry-debug-images = "0.31.0"
zip = "0.6.5"
rusqlite = { version = "0.28.0", features = [ "bundled", "blob" ] }
refinery = { version = "0.8", features = [ "rusqlite" ] }
r2d2_sqlite = { version = "0.21.0", features = ["bundled"] }
sha1 = "0.10.5"
r2d2 = "0.8.10"
[features]
# by default Tauri runs in production mode

View File

@ -1,8 +1,11 @@
use std::path;
use std::{
path,
sync::{Arc, Mutex},
};
use anyhow::{Context, Result};
use rusqlite::Transaction;
use rusqlite::{Connection, Transaction};
mod embedded {
use refinery::embed_migrations;
@ -11,55 +14,46 @@ mod embedded {
#[derive(Clone)]
pub struct Database {
pub pool: r2d2::Pool<r2d2_sqlite::SqliteConnectionManager>,
conn: Arc<Mutex<Connection>>,
}
impl Database {
#[cfg(test)]
pub fn memory() -> Result<Self> {
let manager = r2d2_sqlite::SqliteConnectionManager::memory().with_init(|conn| {
conn.execute_batch("PRAGMA journal_mode=WAL;")
.map_err(|e| rusqlite::Error::ToSqlConversionFailure(e.into()))?;
embedded::migrations::runner()
.run(conn)
.map(|report| {
report
.applied_migrations()
.iter()
.for_each(|m| log::info!("Applied migration: {}", m))
})
.map_err(|e| rusqlite::Error::ToSqlConversionFailure(e.into()))
});
let mut conn = Connection::open_in_memory().context("Failed to open in memory database")?;
embedded::migrations::runner()
.run(&mut conn)
.map(|report| {
report
.applied_migrations()
.iter()
.for_each(|m| log::info!("Applied migration: {}", m))
})
.context("Failed to run migrations")?;
Ok(Self {
pool: r2d2::Pool::new(manager).context("Failed to create pool")?,
conn: Arc::new(Mutex::new(conn)),
})
}
pub fn open<P: AsRef<path::Path>>(path: P) -> Result<Self> {
let path = path.as_ref();
let manager = r2d2_sqlite::SqliteConnectionManager::file(path).with_init(|conn| {
conn.execute_batch("PRAGMA journal_mode=WAL;")
.map_err(|e| rusqlite::Error::ToSqlConversionFailure(e.into()))?;
embedded::migrations::runner()
.run(conn)
.map(|report| {
report
.applied_migrations()
.iter()
.for_each(|m| log::info!("Applied migration: {}", m))
})
.map_err(|e| rusqlite::Error::ToSqlConversionFailure(e.into()))
});
let mut conn = Connection::open(path).context("Failed to open database")?;
embedded::migrations::runner()
.run(&mut conn)
.map(|report| {
report
.applied_migrations()
.iter()
.for_each(|m| log::info!("Applied migration: {}", m))
})
.context("Failed to run migrations")?;
Ok(Self {
pool: r2d2::Pool::new(manager).context("Failed to create pool")?,
conn: Arc::new(Mutex::new(conn)),
})
}
pub fn transaction<T>(&self, f: impl FnOnce(&Transaction) -> Result<T>) -> Result<T> {
let mut conn = self
.pool
.get()
.context("Failed to get connection from pool")?;
let mut conn = self.conn.lock().unwrap();
let tx = conn.transaction().context("Failed to start transaction")?;
let result = f(&tx)?;
tx.commit().context("Failed to commit transaction")?;