mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-31 03:25:43 +01:00
The bug comes with the SQLx-sqlite pool bug, where several connections are
created by default, but the `new` function takes care of that, fixing that bug
by making a single instance of the database.
If constructed directly, the pool would create several connections to the
database, which in most instances is fine, but with SQLite :memory: each
connection is entirely independent.
Also follow documentation to make sure that failed `acquire` will not end up
dropping connections by setting test_before_acquire to false
However, if your workload is sensitive to dropped connections such as using an in-memory
SQLite database with a pool size of 1, you can pretty easily ensure that a cancelled
`acquire()` call will never drop connections by tweaking your [`PoolOptions`]:
* Set [`test_before_acquire(false)`][PoolOptions::test_before_acquire]
* Never set [`before_acquire`][PoolOptions::before_acquire] or
[`after_connect`][PoolOptions::after_connect].
47 lines
1.3 KiB
Rust
47 lines
1.3 KiB
Rust
use std::str::FromStr;
|
|
use std::time::Duration;
|
|
|
|
use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions};
|
|
use sqlx::{Error, Pool, Sqlite};
|
|
|
|
#[inline(always)]
|
|
pub async fn create_sqlite_pool(
|
|
path: &str,
|
|
#[cfg(feature = "sqlcipher")] password: String,
|
|
) -> Result<Pool<Sqlite>, Error> {
|
|
let db_options = SqliteConnectOptions::from_str(path)?
|
|
.busy_timeout(Duration::from_secs(10))
|
|
.read_only(false)
|
|
.pragma("busy_timeout", "5000")
|
|
.pragma("journal_mode", "wal")
|
|
.pragma("synchronous", "normal")
|
|
.pragma("temp_store", "memory")
|
|
.pragma("mmap_size", "30000000000")
|
|
.shared_cache(true)
|
|
.create_if_missing(true);
|
|
|
|
#[cfg(feature = "sqlcipher")]
|
|
let db_options = db_options.pragma("key", password);
|
|
|
|
let is_memory = path.contains(":memory:");
|
|
|
|
let options = SqlitePoolOptions::new()
|
|
.min_connections(1)
|
|
.max_connections(1);
|
|
|
|
let pool = if is_memory {
|
|
// Make sure that the connection is not closed after the first query, or any query, as long
|
|
// as the pool is not dropped
|
|
options
|
|
.idle_timeout(None)
|
|
.max_lifetime(None)
|
|
.test_before_acquire(false)
|
|
} else {
|
|
options
|
|
}
|
|
.connect_with(db_options)
|
|
.await?;
|
|
|
|
Ok(pool)
|
|
}
|