Files
cdk/crates/cdk-sqlite/src/common.rs
C 43ab1fdde1 Do not create the wallet struct directly; instead, call new. (#707)
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].
2025-04-06 07:13:14 +01:00

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)
}