add db connections pool

This commit is contained in:
Nikita Galaiko 2023-09-14 12:23:25 +02:00 committed by GitButler
parent d7eee727cb
commit b05fe81000
7 changed files with 72 additions and 37 deletions

34
Cargo.lock generated
View File

@ -1741,6 +1741,8 @@ dependencies = [
"notify",
"num_cpus",
"posthog-rs",
"r2d2",
"r2d2_sqlite",
"rand 0.8.5",
"refinery",
"reqwest",
@ -3674,6 +3676,28 @@ 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.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99f31323d6161385f385046738df520e0e8694fa74852d35891fc0be08348ddc"
dependencies = [
"r2d2",
"rusqlite",
"uuid",
]
[[package]]
name = "rand"
version = "0.7.3"
@ -4106,6 +4130,15 @@ dependencies = [
"windows-sys 0.48.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"
@ -5707,6 +5740,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d"
dependencies = [
"getrandom 0.2.10",
"rand 0.8.5",
"serde",
]

View File

@ -27,6 +27,8 @@ md5 = "0.7.0"
notify = { version = "6.0.1" }
num_cpus = "1.16.0"
posthog-rs = "0.2.2"
r2d2 = "0.8.10"
r2d2_sqlite = "0.22.0"
rand = "0.8.5"
refinery = { version = "0.8", features = [ "rusqlite" ] }
reqwest = "0.11.14"

View File

@ -239,11 +239,13 @@ fn parse_row(row: &rusqlite::Row) -> Result<Bookmark> {
#[cfg(test)]
mod tests {
use crate::test_utils;
use super::*;
#[test]
fn list_by_project_id_all() -> Result<()> {
let db = database::Database::memory()?;
let db = database::Database::try_from(&test_utils::temp_dir().join("test.db"))?;
let database = Database::from(db);
let bookmark = Bookmark {
@ -266,7 +268,7 @@ mod tests {
#[test]
fn list_by_project_id_range() -> Result<()> {
let db = database::Database::memory()?;
let db = database::Database::try_from(&test_utils::temp_dir().join("test.db"))?;
let database = Database::from(db);
let bookmark_one = Bookmark {
@ -300,7 +302,7 @@ mod tests {
#[test]
fn update() -> Result<()> {
let db = database::Database::memory()?;
let db = database::Database::try_from(&test_utils::temp_dir().join("test.db"))?;
let database = Database::from(db);
let bookmark = Bookmark {

View File

@ -1,11 +1,11 @@
use std::{
fs, path,
sync::{Arc, Mutex},
};
use std::{fs, path, sync::Arc};
use anyhow::{Context, Result};
use rusqlite::{Connection, Transaction};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use refinery::config::Config;
use rusqlite::Transaction;
use tauri::AppHandle;
mod embedded {
@ -15,7 +15,7 @@ mod embedded {
#[derive(Clone)]
pub struct Database {
conn: Arc<Mutex<Connection>>,
pool: Arc<Pool<SqliteConnectionManager>>,
}
impl TryFrom<&path::PathBuf> for Database {
@ -40,28 +40,14 @@ impl TryFrom<&AppHandle> for Database {
}
impl Database {
#[cfg(test)]
pub fn memory() -> Result<Self> {
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| tracing::info!("Applied migration: {}", m))
})
.context("Failed to run migrations")?;
Ok(Self {
conn: Arc::new(Mutex::new(conn)),
})
}
fn open<P: AsRef<path::Path>>(path: P) -> Result<Self> {
let path = path.as_ref();
let mut conn = Connection::open(path).context("Failed to open database")?;
let manager = SqliteConnectionManager::file(path);
let pool = r2d2::Pool::new(manager)?;
let mut cfg =
Config::new(refinery::config::ConfigDbType::Sqlite).set_db_path(path.to_str().unwrap());
embedded::migrations::runner()
.run(&mut conn)
.run(&mut cfg)
.map(|report| {
report
.applied_migrations()
@ -70,12 +56,12 @@ impl Database {
})
.context("Failed to run migrations")?;
Ok(Self {
conn: Arc::new(Mutex::new(conn)),
pool: Arc::new(pool),
})
}
pub fn transaction<T>(&self, f: impl FnOnce(&Transaction) -> Result<T>) -> Result<T> {
let mut conn = self.conn.lock().unwrap();
let mut conn = self.pool.get()?;
let tx = conn.transaction().context("Failed to start transaction")?;
let result = f(&tx)?;
tx.commit().context("Failed to commit transaction")?;
@ -85,10 +71,12 @@ impl Database {
#[cfg(test)]
mod tests {
use crate::test_utils;
use super::*;
#[test]
fn test_memory() {
let db = Database::memory().unwrap();
let db = Database::try_from(&test_utils::temp_dir().join("test.db")).unwrap();
db.transaction(|tx| {
tx.execute("CREATE TABLE test (id INTEGER PRIMARY KEY)", [])
.unwrap();

View File

@ -132,11 +132,13 @@ fn insert_stmt<'conn>(
#[cfg(test)]
mod tests {
use crate::test_utils;
use super::*;
#[test]
fn insert_query() -> Result<()> {
let db = database::Database::memory()?;
let db = test_utils::test_database();
let database = Database::from(db);
let project_id = "project_id";
@ -162,7 +164,7 @@ mod tests {
#[test]
fn insert_update() -> Result<()> {
let db = database::Database::memory()?;
let db = test_utils::test_database();
let database = Database::from(db);
let project_id = "project_id";
@ -195,7 +197,7 @@ mod tests {
#[test]
fn aggregate_deltas_by_file() -> Result<()> {
let db = database::Database::memory()?;
let db = test_utils::test_database();
let database = Database::from(db);
let project_id = "project_id";

View File

@ -190,11 +190,13 @@ fn insert_stmt<'conn>(
#[cfg(test)]
mod tests {
use crate::test_utils;
use super::*;
#[test]
fn test_insert_query() -> Result<()> {
let db = database::Database::memory()?;
let db = test_utils::test_database();
let database = Database::from(db);
let project_id = "project_id";
@ -235,7 +237,7 @@ mod tests {
#[test]
fn test_update() -> Result<()> {
let db = database::Database::memory()?;
let db = test_utils::test_database();
let database = Database::from(db);
let project_id = "project_id";

View File

@ -2,7 +2,12 @@ use std::{fs, path};
use tempfile::tempdir;
use crate::git;
use crate::{database, git};
pub fn test_database() -> database::Database {
let path = temp_dir().join("test.db");
database::Database::try_from(&path).unwrap()
}
pub fn temp_dir() -> path::PathBuf {
let path = tempdir().unwrap().path().to_path_buf();