From 21ddab2f49720cde3691d2dcf43461849296cc7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 May 2025 14:12:00 +0000 Subject: [PATCH 1/5] Update rusqlite requirement from 0.35.0 to 0.36.0 Updates the requirements on [rusqlite](https://github.com/rusqlite/rusqlite) to permit the latest version. - [Release notes](https://github.com/rusqlite/rusqlite/releases) - [Changelog](https://github.com/rusqlite/rusqlite/blob/master/Changelog.md) - [Commits](https://github.com/rusqlite/rusqlite/compare/v0.35.0...v0.36.0) --- updated-dependencies: - dependency-name: rusqlite dependency-version: 0.36.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f1513a2..6ca3db6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,7 @@ window = ["rusqlite/window"] crossbeam-channel = { version = "0.5" } futures-channel = { version = "0.3" } futures-util = { version = "0.3" } -rusqlite = { version = "0.35.0" } +rusqlite = { version = "0.36.0" } [dev-dependencies] async-std = { version = "1.12.0" } From 31cca2dc917186a987efa80403f2eac35b5163d2 Mon Sep 17 00:00:00 2001 From: Ryan Fowler Date: Mon, 26 May 2025 13:27:21 -0700 Subject: [PATCH 2/5] Fix rusqlite Name build error --- src/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client.rs b/src/client.rs index 251a057..0886ca5 100644 --- a/src/client.rs +++ b/src/client.rs @@ -172,7 +172,7 @@ impl Client { fn create_conn(mut builder: ClientBuilder) -> Result { let path = builder.path.take().unwrap_or_else(|| ":memory:".into()); let conn = if let Some(vfs) = builder.vfs.take() { - Connection::open_with_flags_and_vfs(path, builder.flags, &vfs)? + Connection::open_with_flags_and_vfs(path, builder.flags, vfs.as_str())? } else { Connection::open_with_flags(path, builder.flags)? }; From 4224d5bf5551567ed0c269d8d9f8121f1cd99f48 Mon Sep 17 00:00:00 2001 From: Ryan Fowler Date: Fri, 6 Jun 2025 18:50:06 -0700 Subject: [PATCH 3/5] Clamp number of pool connections to 1 --- src/pool.rs | 11 +++++++++-- tests/tests.rs | 13 +++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/pool.rs b/src/pool.rs index e8c133e..36f8e43 100644 --- a/src/pool.rs +++ b/src/pool.rs @@ -78,9 +78,16 @@ impl PoolBuilder { /// Specify the number of sqlite connections to open as part of the pool. /// - /// Defaults to the number of logical CPUs of the current system. + /// Defaults to the number of logical CPUs of the current system. Values + /// less than `1` are clamped to `1`. + /// + /// ``` + /// use async_sqlite::PoolBuilder; + /// + /// let builder = PoolBuilder::new().num_conns(2); + /// ``` pub fn num_conns(mut self, num_conns: usize) -> Self { - self.num_conns = Some(num_conns); + self.num_conns = Some(num_conns.max(1)); self } diff --git a/tests/tests.rs b/tests/tests.rs index f96195f..0027220 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -84,6 +84,7 @@ async_test!(test_journal_mode); async_test!(test_concurrency); async_test!(test_pool); async_test!(test_pool_conn_for_each); +async_test!(test_pool_num_conns_zero_clamps); async fn test_journal_mode() { let tmp_dir = tempfile::tempdir().unwrap(); @@ -227,3 +228,15 @@ async fn test_pool_conn_for_each() { // cleanup pool.close().await.expect("closing client conn"); } + +async fn test_pool_num_conns_zero_clamps() { + let tmp_dir = tempfile::tempdir().unwrap(); + let pool = PoolBuilder::new() + .path(tmp_dir.path().join("clamp.db")) + .num_conns(0) + .open() + .await + .expect("pool unable to be opened"); + let results = pool.conn_for_each(|_| Ok(())).await; + assert_eq!(results.len(), 1); +} From 5eaace886ed75c3cbcf1b4e90df05a0d387a3ed8 Mon Sep 17 00:00:00 2001 From: Ryan Fowler Date: Fri, 6 Jun 2025 19:26:13 -0700 Subject: [PATCH 4/5] Close pool connections concurrently --- src/pool.rs | 17 ++++++++++++----- tests/tests.rs | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/pool.rs b/src/pool.rs index e8c133e..7bd44ce 100644 --- a/src/pool.rs +++ b/src/pool.rs @@ -78,9 +78,16 @@ impl PoolBuilder { /// Specify the number of sqlite connections to open as part of the pool. /// - /// Defaults to the number of logical CPUs of the current system. + /// Defaults to the number of logical CPUs of the current system. Values + /// less than `1` are clamped to `1`. + /// + /// ``` + /// use async_sqlite::PoolBuilder; + /// + /// let builder = PoolBuilder::new().num_conns(2); + /// ``` pub fn num_conns(mut self, num_conns: usize) -> Self { - self.num_conns = Some(num_conns); + self.num_conns = Some(num_conns.max(1)); self } @@ -197,9 +204,9 @@ impl Pool { /// After this method returns, all calls to `self::conn()` or /// `self::conn_mut()` will return an [`Error::Closed`] error. pub async fn close(&self) -> Result<(), Error> { - for client in self.state.clients.iter() { - client.close().await?; - } + let closes = self.state.clients.iter().map(|client| client.close()); + let res = join_all(closes).await; + res.into_iter().collect::, Error>>()?; Ok(()) } diff --git a/tests/tests.rs b/tests/tests.rs index f96195f..4eaf002 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -84,6 +84,8 @@ async_test!(test_journal_mode); async_test!(test_concurrency); async_test!(test_pool); async_test!(test_pool_conn_for_each); +async_test!(test_pool_close_concurrent); +async_test!(test_pool_num_conns_zero_clamps); async fn test_journal_mode() { let tmp_dir = tempfile::tempdir().unwrap(); @@ -227,3 +229,36 @@ async fn test_pool_conn_for_each() { // cleanup pool.close().await.expect("closing client conn"); } + +async fn test_pool_close_concurrent() { + let tmp_dir = tempfile::tempdir().unwrap(); + let pool = PoolBuilder::new() + .path(tmp_dir.path().join("sqlite.db")) + .num_conns(2) + .open() + .await + .expect("pool unable to be opened"); + + let c1 = pool.close(); + let c2 = pool.close(); + futures_util::future::join_all([c1, c2]) + .await + .into_iter() + .collect::, Error>>() + .expect("closing concurrently"); + + let res = pool.conn(|c| c.execute("SELECT 1", ())).await; + assert!(matches!(res, Err(Error::Closed))); +} + +async fn test_pool_num_conns_zero_clamps() { + let tmp_dir = tempfile::tempdir().unwrap(); + let pool = PoolBuilder::new() + .path(tmp_dir.path().join("clamp.db")) + .num_conns(0) + .open() + .await + .expect("pool unable to be opened"); + let results = pool.conn_for_each(|_| Ok(())).await; + assert_eq!(results.len(), 1); +} From 4d6f7ab75c36a0049149fddd65dec589c75ebf0d Mon Sep 17 00:00:00 2001 From: Ryan Fowler Date: Fri, 6 Jun 2025 19:38:28 -0700 Subject: [PATCH 5/5] Release v0.5.2 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 6ca3db6..555679c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "async-sqlite" -version = "0.5.1" +version = "0.5.2" authors = ["Ryan Fowler"] edition = "2021" license = "MIT"