From 1c168ec297e7671b445ee354121957f12fb6dfc8 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 26 Mar 2025 18:30:40 +0200 Subject: [PATCH 01/51] 0.0.42 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd4bd57..5afdd5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.41" +version = "0.0.42" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index fd5cdc8..9fd73b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.41" +version = "0.0.42" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index ee603c7..fe647f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.41" +version = "0.0.42" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 0e08696b7ed97fddd59dc1bf143c149ca9b2f371 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 26 Mar 2025 18:44:04 +0200 Subject: [PATCH 02/51] Fix release workflow --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 0f80778..59722b1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -122,5 +122,5 @@ jobs: MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} with: command: upload - args: --skip-existing * + args: --skip-existing dist/* From 6688295e5ad3108b7ac0e99079bf00533c2d72f8 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 26 Mar 2025 18:44:34 +0200 Subject: [PATCH 03/51] 0.0.43 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5afdd5c..4854faf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.42" +version = "0.0.43" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 9fd73b5..bea4bcd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.42" +version = "0.0.43" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index fe647f2..4e5f178 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.42" +version = "0.0.43" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From ea16d88d0db5b99f0c077833888a011de807d5c8 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 26 Mar 2025 20:40:43 +0200 Subject: [PATCH 04/51] Switch to Builder for automatic protocol detection The Builder API detects the right sync protocol automatically. --- src/lib.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9a3e030..fcaa0a6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -130,15 +130,15 @@ fn _connect_core( match sync_url { Some(sync_url) => { let sync_interval = sync_interval.map(|i| std::time::Duration::from_secs_f64(i)); - let fut = libsql::Database::open_with_remote_sync_internal( - database, - sync_url, - auth_token, - Some(ver), - true, - encryption_config, - sync_interval, - ); + let mut builder = + libsql::Builder::new_remote_replica(database, sync_url, auth_token.to_string()); + if let Some(encryption_config) = encryption_config { + builder = builder.encryption_config(encryption_config); + } + if let Some(sync_interval) = sync_interval { + builder = builder.sync_interval(sync_interval); + } + let fut = builder.build(); tokio::pin!(fut); let result = rt.block_on(check_signals(py, fut)); result.map_err(to_py_err)? From 686d877d431a09c9265da9181ec2c54fdf851409 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 26 Mar 2025 20:46:59 +0200 Subject: [PATCH 05/51] 0.0.44 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4854faf..422751f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.43" +version = "0.0.44" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index bea4bcd..6898504 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.43" +version = "0.0.44" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 4e5f178..1e60b4e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.43" +version = "0.0.44" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 145e5178910e960c7c740c322b561b11d15906b2 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 1 Apr 2025 10:29:56 +0300 Subject: [PATCH 06/51] Update libsql dependency Fixes #87 --- Cargo.lock | 26 +++++++++++++------------- Cargo.toml | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 422751f..436bfc7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -806,9 +806,9 @@ dependencies = [ [[package]] name = "libsql" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f99d7048440c5f443f7e121b27159d4d3c66d0a75e20754fd6cbb00f3cc8c18" +checksum = "09b9df6f5cc08ca4bb2467793926470210d3d8a916ea28260d6cd892bba6d8b4" dependencies = [ "anyhow", "async-stream", @@ -846,9 +846,9 @@ dependencies = [ [[package]] name = "libsql-ffi" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0e12afae859e7dc096ebc7a7cee806efa948e5b78ff9d0b4573ca7815480ab0" +checksum = "4a1dcc2bf91e8511ece5bc2bac502b78bcbcecef80635dacb30020a40419e5d6" dependencies = [ "bindgen", "cc", @@ -857,9 +857,9 @@ dependencies = [ [[package]] name = "libsql-hrana" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71f16d7adbad5bee861c955011c155893937bd4c8711c91d949060363f24e0f6" +checksum = "f14cd7d167c01bac254a4296b86a6ac090fd364c39af6c64071efdf07f206db7" dependencies = [ "base64 0.21.7", "bytes", @@ -881,9 +881,9 @@ dependencies = [ [[package]] name = "libsql-rusqlite" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c4bd62bf66a14e46643bd44adbb843c791e7c3f835a1424ffa629df8a7a9f4" +checksum = "881b3e3f05c8d3f22be9ccfa4f6a56ad25165a5458615aba8b7586558c694965" dependencies = [ "bitflags 2.6.0", "fallible-iterator 0.2.0", @@ -913,9 +913,9 @@ dependencies = [ [[package]] name = "libsql-sys" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "659587f9ebebdb2ff1112e8af7f30fc212f8d5457a3a9a549eda48544e942a7f" +checksum = "edae249cc733bb10e134d3c1522b408631f6a8741855caf7179927fd296f5715" dependencies = [ "bytes", "libsql-ffi", @@ -927,9 +927,9 @@ dependencies = [ [[package]] name = "libsql_replication" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0666c23acca99c2ebc317071f87814ad006243fa6e15c02a83e40ff8e6948832" +checksum = "b0c30add5755085fffd616190ff67703a391ae8324001738d7e6f00d6ea1b180" dependencies = [ "aes", "async-stream", diff --git a/Cargo.toml b/Cargo.toml index 6898504..b22e6ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -libsql = { version = "0.9.1", features = ["encryption"] } +libsql = { version = "0.9.2", features = ["encryption"] } tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] } tracing-subscriber = "0.3" From 45cc574a54beced9e6885c49b05f02dc8743e308 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 1 Apr 2025 10:30:28 +0300 Subject: [PATCH 07/51] 0.0.45 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 436bfc7..6b5f8bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.44" +version = "0.0.45" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index b22e6ab..e7847d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.44" +version = "0.0.45" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 1e60b4e..b7e898d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.44" +version = "0.0.45" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 9e0c1b63230de4b883e29af5460ebf0992167731 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 11 Apr 2025 20:57:17 +0300 Subject: [PATCH 08/51] Update libsql dependency --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b5f8bd..68a05bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -806,9 +806,9 @@ dependencies = [ [[package]] name = "libsql" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b9df6f5cc08ca4bb2467793926470210d3d8a916ea28260d6cd892bba6d8b4" +checksum = "8c4170192e0b9a763e5989010cff4eef19cec0ccad4cd02a07fb175536913b34" dependencies = [ "anyhow", "async-stream", @@ -846,9 +846,9 @@ dependencies = [ [[package]] name = "libsql-ffi" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1dcc2bf91e8511ece5bc2bac502b78bcbcecef80635dacb30020a40419e5d6" +checksum = "98ec8f30f1bc5e8d5bd7ec3f185c7a9b138442d9322a6ae93ba76ab9d9981c85" dependencies = [ "bindgen", "cc", @@ -857,9 +857,9 @@ dependencies = [ [[package]] name = "libsql-hrana" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f14cd7d167c01bac254a4296b86a6ac090fd364c39af6c64071efdf07f206db7" +checksum = "8546265c2df24a95bb65b8e641f3baf8b0c0d103cd42f1ce6724ff248af26f52" dependencies = [ "base64 0.21.7", "bytes", @@ -881,9 +881,9 @@ dependencies = [ [[package]] name = "libsql-rusqlite" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881b3e3f05c8d3f22be9ccfa4f6a56ad25165a5458615aba8b7586558c694965" +checksum = "bd58d0d486f6a6f3b7c83f9e43f50f10e908985a9b33846e5912b0d72027fabd" dependencies = [ "bitflags 2.6.0", "fallible-iterator 0.2.0", @@ -913,9 +913,9 @@ dependencies = [ [[package]] name = "libsql-sys" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edae249cc733bb10e134d3c1522b408631f6a8741855caf7179927fd296f5715" +checksum = "65b071c118871b0b1321955fc409a97e3b6b6757e6e9783f75f294b61231eaf2" dependencies = [ "bytes", "libsql-ffi", @@ -927,9 +927,9 @@ dependencies = [ [[package]] name = "libsql_replication" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c30add5755085fffd616190ff67703a391ae8324001738d7e6f00d6ea1b180" +checksum = "7714505f37db747fab3925fbfaab4c8941d483d844a48d32c23a31713f824aa4" dependencies = [ "aes", "async-stream", diff --git a/Cargo.toml b/Cargo.toml index e7847d3..4433942 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -libsql = { version = "0.9.2", features = ["encryption"] } +libsql = { version = "0.9.3", features = ["encryption"] } tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] } tracing-subscriber = "0.3" From d21558ba59c9ca7a161419aae5cabd3e30f9ceea Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 11 Apr 2025 21:10:14 +0300 Subject: [PATCH 09/51] 0.0.46 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68a05bf..d8870bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.45" +version = "0.0.46" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 4433942..436e5dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.45" +version = "0.0.46" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index b7e898d..6742613 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.45" +version = "0.0.46" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 7cec322e22e28453feec2e24998fa1b2adf07cbe Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 15 Apr 2025 10:08:17 +0300 Subject: [PATCH 10/51] Update libsql dependency --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8870bd..ec70fc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -806,9 +806,9 @@ dependencies = [ [[package]] name = "libsql" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c4170192e0b9a763e5989010cff4eef19cec0ccad4cd02a07fb175536913b34" +checksum = "480e95d8e7859b837ff72e92ae59f513095e8f16565b659030fbd1c7b3771685" dependencies = [ "anyhow", "async-stream", @@ -846,9 +846,9 @@ dependencies = [ [[package]] name = "libsql-ffi" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ec8f30f1bc5e8d5bd7ec3f185c7a9b138442d9322a6ae93ba76ab9d9981c85" +checksum = "751364e30fb9c9eaad7d6e990dcfe7aa12c9b016779444c126633d3fd6d4d160" dependencies = [ "bindgen", "cc", @@ -857,9 +857,9 @@ dependencies = [ [[package]] name = "libsql-hrana" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8546265c2df24a95bb65b8e641f3baf8b0c0d103cd42f1ce6724ff248af26f52" +checksum = "ea2fbe44885bfd021e58c95afdb57eb83821729032fd3c4b81ac7094178d4481" dependencies = [ "base64 0.21.7", "bytes", @@ -881,9 +881,9 @@ dependencies = [ [[package]] name = "libsql-rusqlite" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd58d0d486f6a6f3b7c83f9e43f50f10e908985a9b33846e5912b0d72027fabd" +checksum = "bf0408ddfc0632ce2863ae6d839f893691f5a323bd2ffb2472def4c8e2c8d489" dependencies = [ "bitflags 2.6.0", "fallible-iterator 0.2.0", @@ -913,9 +913,9 @@ dependencies = [ [[package]] name = "libsql-sys" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65b071c118871b0b1321955fc409a97e3b6b6757e6e9783f75f294b61231eaf2" +checksum = "095eb8c54664683acce885caf448ca89ea03189caecd897579930e968aee41c5" dependencies = [ "bytes", "libsql-ffi", @@ -927,9 +927,9 @@ dependencies = [ [[package]] name = "libsql_replication" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714505f37db747fab3925fbfaab4c8941d483d844a48d32c23a31713f824aa4" +checksum = "6e324539ae77465c406f214ae51cf7e0067819d6778f01947e2cd9c2222f41fd" dependencies = [ "aes", "async-stream", diff --git a/Cargo.toml b/Cargo.toml index 436e5dc..83be11b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -libsql = { version = "0.9.3", features = ["encryption"] } +libsql = { version = "0.9.4", features = ["encryption"] } tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] } tracing-subscriber = "0.3" From f4a34e737a928410c69326cc241597f4d63d89d7 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 15 Apr 2025 10:08:46 +0300 Subject: [PATCH 11/51] 0.0.47 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ec70fc9..e674c97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.46" +version = "0.0.47" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 83be11b..f20a274 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.46" +version = "0.0.47" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 6742613..3b1ed7d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.46" +version = "0.0.47" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From d1f16ea1b0c32863486aa61b3b1c8044527a2d67 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 23 Apr 2025 18:35:43 +0300 Subject: [PATCH 12/51] Fix quickstart link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 68b5eb1..7e0424d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- + Turso + Python

Turso + Python (experimental)

From 52e52137e4166068b888194191e08ea1fd6389f6 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 23 Apr 2025 18:45:44 +0300 Subject: [PATCH 13/51] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 7e0424d..5eedaef 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,5 @@ Learn more about what you can do with Turso: - [Embedded Replicas](https://docs.turso.tech/features/embedded-replicas) - [Platform API](https://docs.turso.tech/features/platform-api) -- [Data Edge](https://docs.turso.tech/features/data-edge) - [Branching](https://docs.turso.tech/features/branching) - [Point-in-Time Recovery](https://docs.turso.tech/features/point-in-time-recovery) -- [Scale to Zero](https://docs.turso.tech/features/scale-to-zero) From e9f9f59b4272aa37a7b638bc62155192f1ead1db Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Thu, 1 May 2025 16:13:36 +0300 Subject: [PATCH 14/51] Fix Cursor.close() to drop statement and rows --- src/lib.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fcaa0a6..ceee9b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -330,8 +330,24 @@ pub struct Cursor { // SAFETY: The libsql crate guarantees that `Connection` is thread-safe. unsafe impl Send for Cursor {} +impl Drop for Cursor { + fn drop(&mut self) { + self.stmt.replace(None); + self.rows.replace(None); + } +} + #[pymethods] impl Cursor { + fn close(self_: PyRef<'_, Self>) -> PyResult<()> { + rt().block_on(async { + let cursor: &Cursor = &self_; + cursor.stmt.replace(None); + cursor.rows.replace(None); + }); + Ok(()) + } + fn execute<'a>( self_: PyRef<'a, Self>, sql: String, @@ -474,11 +490,6 @@ impl Cursor { fn rowcount(self_: PyRef<'_, Self>) -> PyResult { Ok(*self_.rowcount.borrow()) } - - fn close(_self: PyRef<'_, Self>) -> PyResult<()> { - // TODO - Ok(()) - } } async fn begin_transaction(conn: &libsql_core::Connection) -> PyResult<()> { From 138ae16461e569a95747273ba78e11e566c0923c Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Thu, 1 May 2025 16:15:03 +0300 Subject: [PATCH 15/51] 0.0.48 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e674c97..fce5627 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.47" +version = "0.0.48" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index f20a274..cd554ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.47" +version = "0.0.48" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 3b1ed7d..8bfe860 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.47" +version = "0.0.48" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From c612d05fc5b025f3565f0a7c50e010586c6c7da2 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Thu, 1 May 2025 16:39:03 +0300 Subject: [PATCH 16/51] Implement Connection.close(), improve Cursor.close() Fixes #90 --- src/lib.rs | 96 +++++++++++++++++++++++++++++++++++---------- tests/test_suite.py | 17 ++++++++ 2 files changed, 92 insertions(+), 21 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ceee9b5..4b72dc3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -160,10 +160,10 @@ fn _connect_core( let conn = db.connect().map_err(to_py_err)?; Ok(Connection { db, - conn: Arc::new(ConnectionGuard { + conn: RefCell::new(Some(Arc::new(ConnectionGuard { conn: Some(conn), handle: rt.clone(), - }), + }))), isolation_level, autocommit, }) @@ -199,7 +199,7 @@ impl Drop for ConnectionGuard { #[pyclass] pub struct Connection { db: libsql_core::Database, - conn: Arc, + conn: RefCell>>, isolation_level: Option, autocommit: i32, } @@ -209,10 +209,15 @@ unsafe impl Send for Connection {} #[pymethods] impl Connection { + fn close(self_: PyRef<'_, Self>, py: Python<'_>) -> PyResult<()> { + self_.conn.replace(None); + Ok(()) + } + fn cursor(&self) -> PyResult { Ok(Cursor { arraysize: 1, - conn: self.conn.clone(), + conn: RefCell::new(Some(self.conn.borrow().as_ref().unwrap().clone())), stmt: RefCell::new(None), rows: RefCell::new(None), rowcount: RefCell::new(0), @@ -235,18 +240,34 @@ impl Connection { fn commit(self_: PyRef<'_, Self>) -> PyResult<()> { // TODO: Switch to libSQL transaction API - if !self_.conn.is_autocommit() { - rt().block_on(async { self_.conn.execute("COMMIT", ()).await }) - .map_err(to_py_err)?; + if !self_.conn.borrow().as_ref().unwrap().is_autocommit() { + rt().block_on(async { + self_ + .conn + .borrow() + .as_ref() + .unwrap() + .execute("COMMIT", ()) + .await + }) + .map_err(to_py_err)?; } Ok(()) } fn rollback(self_: PyRef<'_, Self>) -> PyResult<()> { // TODO: Switch to libSQL transaction API - if !self_.conn.is_autocommit() { - rt().block_on(async { self_.conn.execute("ROLLBACK", ()).await }) - .map_err(to_py_err)?; + if !self_.conn.borrow().as_ref().unwrap().is_autocommit() { + rt().block_on(async { + self_ + .conn + .borrow() + .as_ref() + .unwrap() + .execute("ROLLBACK", ()) + .await + }) + .map_err(to_py_err)?; } Ok(()) } @@ -276,7 +297,15 @@ impl Connection { fn executescript(self_: PyRef<'_, Self>, script: String) -> PyResult<()> { let _ = rt() - .block_on(async { self_.conn.execute_batch(&script).await }) + .block_on(async { + self_ + .conn + .borrow() + .as_ref() + .unwrap() + .execute_batch(&script) + .await + }) .map_err(to_py_err); Ok(()) } @@ -290,9 +319,11 @@ impl Connection { fn in_transaction(self_: PyRef<'_, Self>) -> PyResult { #[cfg(Py_3_12)] { - return Ok(!self_.conn.is_autocommit() || self_.autocommit == 0); + return Ok( + !self_.conn.borrow().as_ref().unwrap().is_autocommit() || self_.autocommit == 0 + ); } - Ok(!self_.conn.is_autocommit()) + Ok(!self_.conn.borrow().as_ref().unwrap().is_autocommit()) } #[getter] @@ -318,7 +349,7 @@ impl Connection { pub struct Cursor { #[pyo3(get, set)] arraysize: usize, - conn: Arc, + conn: RefCell>>, stmt: RefCell>, rows: RefCell>, rowcount: RefCell, @@ -332,6 +363,8 @@ unsafe impl Send for Cursor {} impl Drop for Cursor { fn drop(&mut self) { + let _enter = rt().enter(); + self.conn.replace(None); self.stmt.replace(None); self.rows.replace(None); } @@ -342,6 +375,7 @@ impl Cursor { fn close(self_: PyRef<'_, Self>) -> PyResult<()> { rt().block_on(async { let cursor: &Cursor = &self_; + cursor.conn.replace(None); cursor.stmt.replace(None); cursor.rows.replace(None); }); @@ -373,8 +407,16 @@ impl Cursor { self_: PyRef<'a, Self>, script: String, ) -> PyResult> { - rt().block_on(async { self_.conn.execute_batch(&script).await }) - .map_err(to_py_err)?; + rt().block_on(async { + self_ + .conn + .borrow() + .as_ref() + .unwrap() + .execute_batch(&script) + .await + }) + .map_err(to_py_err)?; Ok(self_) } @@ -481,7 +523,9 @@ impl Cursor { fn lastrowid(self_: PyRef<'_, Self>) -> PyResult> { let stmt = self_.stmt.borrow(); match stmt.as_ref() { - Some(_) => Ok(Some(self_.conn.last_insert_rowid())), + Some(_) => Ok(Some( + self_.conn.borrow().as_ref().unwrap().last_insert_rowid(), + )), None => Ok(None), } } @@ -498,10 +542,13 @@ async fn begin_transaction(conn: &libsql_core::Connection) -> PyResult<()> { } async fn execute(cursor: &Cursor, sql: String, parameters: Option<&PyTuple>) -> PyResult<()> { + if cursor.conn.borrow().as_ref().is_none() { + return Err(PyValueError::new_err("Connection already closed")); + } let stmt_is_dml = stmt_is_dml(&sql); let autocommit = determine_autocommit(cursor); - if !autocommit && stmt_is_dml && cursor.conn.is_autocommit() { - begin_transaction(&cursor.conn).await?; + if !autocommit && stmt_is_dml && cursor.conn.borrow().as_ref().unwrap().is_autocommit() { + begin_transaction(&cursor.conn.borrow().as_ref().unwrap()).await?; } let params = match parameters { Some(parameters) => { @@ -526,11 +573,18 @@ async fn execute(cursor: &Cursor, sql: String, parameters: Option<&PyTuple>) -> } None => libsql_core::params::Params::None, }; - let mut stmt = cursor.conn.prepare(&sql).await.map_err(to_py_err)?; + let mut stmt = cursor + .conn + .borrow() + .as_ref() + .unwrap() + .prepare(&sql) + .await + .map_err(to_py_err)?; let rows = stmt.query(params).await.map_err(to_py_err)?; if stmt_is_dml { let mut rowcount = cursor.rowcount.borrow_mut(); - *rowcount += cursor.conn.changes() as i64; + *rowcount += cursor.conn.borrow().as_ref().unwrap().changes() as i64; } else { cursor.rowcount.replace(-1); } diff --git a/tests/test_suite.py b/tests/test_suite.py index eda5203..4a83781 100644 --- a/tests/test_suite.py +++ b/tests/test_suite.py @@ -6,6 +6,11 @@ import pytest +@pytest.mark.parametrize("provider", ["libsql", "sqlite"]) +def test_connection_close(provider): + conn = connect(provider, ":memory:") + conn.close() + @pytest.mark.parametrize("provider", ["libsql", "sqlite"]) def test_execute(provider): conn = connect(provider, ":memory:") @@ -24,6 +29,18 @@ def test_cursor_execute(provider): res = cur.execute("SELECT * FROM users") assert (1, "alice@example.com") == res.fetchone() +@pytest.mark.parametrize("provider", ["libsql", "sqlite"]) +def test_cursor_close(provider): + conn = connect(provider, ":memory:") + cur = conn.cursor() + cur.execute("CREATE TABLE users (id INTEGER, email TEXT)") + cur.execute("INSERT INTO users VALUES (1, 'alice@example.com')") + cur.execute("INSERT INTO users VALUES (2, 'bob@example.com')") + res = cur.execute("SELECT * FROM users") + assert [(1, "alice@example.com"), (2, "bob@example.com")] == res.fetchall() + cur.close() + with pytest.raises(Exception): + cur.execute("SELECT * FROM users") @pytest.mark.parametrize("provider", ["libsql", "sqlite"]) def test_executemany(provider): From 6f7903cb11f4cd5eac8719eb95cf48c4823f3922 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Thu, 1 May 2025 16:46:21 +0300 Subject: [PATCH 17/51] 0.0.49 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fce5627..8abf3f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.48" +version = "0.0.49" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index cd554ca..3131adf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.48" +version = "0.0.49" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 8bfe860..9a15308 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.48" +version = "0.0.49" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From cbf98bd219a3c83cb411ecb651e2f080131b929e Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sat, 10 May 2025 08:16:22 +0300 Subject: [PATCH 18/51] Update libsql dependency --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8abf3f3..820cdf4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -806,9 +806,9 @@ dependencies = [ [[package]] name = "libsql" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480e95d8e7859b837ff72e92ae59f513095e8f16565b659030fbd1c7b3771685" +checksum = "096b80492b42179396a551078a24dbc8d50c135e80098e10cf46e1ce82b86e09" dependencies = [ "anyhow", "async-stream", @@ -846,9 +846,9 @@ dependencies = [ [[package]] name = "libsql-ffi" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "751364e30fb9c9eaad7d6e990dcfe7aa12c9b016779444c126633d3fd6d4d160" +checksum = "dfaffc5d1d4e990961c48989b04252c22dd6628c1e0c66a4724d3918932cc96e" dependencies = [ "bindgen", "cc", @@ -857,9 +857,9 @@ dependencies = [ [[package]] name = "libsql-hrana" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2fbe44885bfd021e58c95afdb57eb83821729032fd3c4b81ac7094178d4481" +checksum = "af3522399868e2302c47ae31902017e2eccbf51c50e6d7ad78eb7e96a640dd43" dependencies = [ "base64 0.21.7", "bytes", @@ -881,9 +881,9 @@ dependencies = [ [[package]] name = "libsql-rusqlite" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf0408ddfc0632ce2863ae6d839f893691f5a323bd2ffb2472def4c8e2c8d489" +checksum = "4487c5a1ee674aae0f300cb5507af03ddb9989159ff32928f3379db19cfee4a7" dependencies = [ "bitflags 2.6.0", "fallible-iterator 0.2.0", @@ -913,9 +913,9 @@ dependencies = [ [[package]] name = "libsql-sys" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "095eb8c54664683acce885caf448ca89ea03189caecd897579930e968aee41c5" +checksum = "506f309248a5ddca722b5337b9f6e0e1dbe35d829b8016f0bd409d8792d3b04d" dependencies = [ "bytes", "libsql-ffi", @@ -927,9 +927,9 @@ dependencies = [ [[package]] name = "libsql_replication" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e324539ae77465c406f214ae51cf7e0067819d6778f01947e2cd9c2222f41fd" +checksum = "bc11901506831b1f0574a69c5f22a0e466feedeb6fcc26868a424992f8d8e44b" dependencies = [ "aes", "async-stream", diff --git a/Cargo.toml b/Cargo.toml index 3131adf..56eafb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -libsql = { version = "0.9.4", features = ["encryption"] } +libsql = { version = "0.9.6", features = ["encryption"] } tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] } tracing-subscriber = "0.3" From ca3983aa9d1c8e907e999d41fa015eb42a673d3e Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sat, 10 May 2025 08:16:54 +0300 Subject: [PATCH 19/51] 0.0.50 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 820cdf4..2f556eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.49" +version = "0.0.50" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 56eafb5..c84336f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.49" +version = "0.0.50" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 9a15308..18f2609 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.49" +version = "0.0.50" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 017bd836d8c5b06a10c2ead6c97d7da2384f0579 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 14 May 2025 17:29:40 +0300 Subject: [PATCH 20/51] Update libsql dependency --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f556eb..72e71bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -806,9 +806,9 @@ dependencies = [ [[package]] name = "libsql" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "096b80492b42179396a551078a24dbc8d50c135e80098e10cf46e1ce82b86e09" +checksum = "401f255994be7b7f210216f0144be30fb853c58ba71d0e135164131a1a6095ae" dependencies = [ "anyhow", "async-stream", @@ -846,9 +846,9 @@ dependencies = [ [[package]] name = "libsql-ffi" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfaffc5d1d4e990961c48989b04252c22dd6628c1e0c66a4724d3918932cc96e" +checksum = "a2ecd5f930e89afb74b6c5c56a0c7893b06cf495ffcde8d806c43be2e3529d00" dependencies = [ "bindgen", "cc", @@ -857,9 +857,9 @@ dependencies = [ [[package]] name = "libsql-hrana" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af3522399868e2302c47ae31902017e2eccbf51c50e6d7ad78eb7e96a640dd43" +checksum = "d69b605be4f58a8f6017dcf4c10931454c14e43309871a19e005b2ba00e56ff7" dependencies = [ "base64 0.21.7", "bytes", @@ -881,9 +881,9 @@ dependencies = [ [[package]] name = "libsql-rusqlite" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4487c5a1ee674aae0f300cb5507af03ddb9989159ff32928f3379db19cfee4a7" +checksum = "ff98aad65b47b61a5d58bb25456c8935ff38faff50913f7b5fcd2d2de8355724" dependencies = [ "bitflags 2.6.0", "fallible-iterator 0.2.0", @@ -913,9 +913,9 @@ dependencies = [ [[package]] name = "libsql-sys" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "506f309248a5ddca722b5337b9f6e0e1dbe35d829b8016f0bd409d8792d3b04d" +checksum = "e18e7dc8b328afe903f730f184555f4a607560e170e1392b4e5b9f58addd0c4a" dependencies = [ "bytes", "libsql-ffi", @@ -927,9 +927,9 @@ dependencies = [ [[package]] name = "libsql_replication" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc11901506831b1f0574a69c5f22a0e466feedeb6fcc26868a424992f8d8e44b" +checksum = "fba0d482d5bf0d0b67287b03d06e6186759cf62016645b076f626dddc6a4b1a5" dependencies = [ "aes", "async-stream", diff --git a/Cargo.toml b/Cargo.toml index c84336f..058945c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -libsql = { version = "0.9.6", features = ["encryption"] } +libsql = { version = "0.9.7", features = ["encryption"] } tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] } tracing-subscriber = "0.3" From 08b59bee62e9e218a80d3b51a74978ad28794c89 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 14 May 2025 17:30:23 +0300 Subject: [PATCH 21/51] 0.0.51 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 72e71bb..666eb7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.50" +version = "0.0.51" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 058945c..b6f2bc0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.50" +version = "0.0.51" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 18f2609..a5e60a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.50" +version = "0.0.51" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From a02a592ba421957cbfa31d213aa28b5ca5fba109 Mon Sep 17 00:00:00 2001 From: "Levy A." Date: Thu, 15 May 2025 12:09:45 -0300 Subject: [PATCH 22/51] fix: only call query on statements that return rows --- src/lib.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4b72dc3..d3abc53 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -581,15 +581,18 @@ async fn execute(cursor: &Cursor, sql: String, parameters: Option<&PyTuple>) -> .prepare(&sql) .await .map_err(to_py_err)?; - let rows = stmt.query(params).await.map_err(to_py_err)?; - if stmt_is_dml { - let mut rowcount = cursor.rowcount.borrow_mut(); - *rowcount += cursor.conn.borrow().as_ref().unwrap().changes() as i64; + + if stmt.columns().iter().len() > 0 { + let rows = stmt.query(params).await.map_err(to_py_err)?; + cursor.rows.replace(Some(rows)); } else { - cursor.rowcount.replace(-1); + stmt.execute(params).await.map_err(to_py_err)?; } + + let mut rowcount = cursor.rowcount.borrow_mut(); + *rowcount += cursor.conn.borrow().as_ref().unwrap().changes() as i64; + cursor.stmt.replace(Some(stmt)); - cursor.rows.replace(Some(rows)); Ok(()) } From d5d46a756f164b49a19497860fed5b39640a27e8 Mon Sep 17 00:00:00 2001 From: "Levy A." Date: Fri, 16 May 2025 12:09:32 -0300 Subject: [PATCH 23/51] fix: replace old rows with None --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index d3abc53..4a54380 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -587,6 +587,7 @@ async fn execute(cursor: &Cursor, sql: String, parameters: Option<&PyTuple>) -> cursor.rows.replace(Some(rows)); } else { stmt.execute(params).await.map_err(to_py_err)?; + cursor.rows.replace(None); } let mut rowcount = cursor.rowcount.borrow_mut(); From d98154fc49f3c9c2c4cbf9cdb248cfe6f671b7a9 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 20 May 2025 12:25:41 +0300 Subject: [PATCH 24/51] Update libsql dependency --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 666eb7b..764c7df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -806,9 +806,9 @@ dependencies = [ [[package]] name = "libsql" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "401f255994be7b7f210216f0144be30fb853c58ba71d0e135164131a1a6095ae" +checksum = "ac8482f800f3f515e1d96af82bbb47d57d1edbc585642316eebc045f72a1930e" dependencies = [ "anyhow", "async-stream", @@ -846,9 +846,9 @@ dependencies = [ [[package]] name = "libsql-ffi" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ecd5f930e89afb74b6c5c56a0c7893b06cf495ffcde8d806c43be2e3529d00" +checksum = "1f78ac450ec98334db75ffda145c9f17377f6aa0c5a2529d233844b7b7841a48" dependencies = [ "bindgen", "cc", @@ -857,9 +857,9 @@ dependencies = [ [[package]] name = "libsql-hrana" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d69b605be4f58a8f6017dcf4c10931454c14e43309871a19e005b2ba00e56ff7" +checksum = "7df6ae47bfedf165fb22d1aad3ca983b0aa27782fea48f98b5142f36c02b459d" dependencies = [ "base64 0.21.7", "bytes", @@ -881,9 +881,9 @@ dependencies = [ [[package]] name = "libsql-rusqlite" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff98aad65b47b61a5d58bb25456c8935ff38faff50913f7b5fcd2d2de8355724" +checksum = "9a462d9e10715139636d7f17351ba28c4b5fbc439110282ef3aa53770c3a8ba5" dependencies = [ "bitflags 2.6.0", "fallible-iterator 0.2.0", @@ -913,9 +913,9 @@ dependencies = [ [[package]] name = "libsql-sys" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e18e7dc8b328afe903f730f184555f4a607560e170e1392b4e5b9f58addd0c4a" +checksum = "76ca92a20f9b274aecfa2861e0a447d43f2b4c48dc6c8b63b6702d22c51e15eb" dependencies = [ "bytes", "libsql-ffi", @@ -927,9 +927,9 @@ dependencies = [ [[package]] name = "libsql_replication" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fba0d482d5bf0d0b67287b03d06e6186759cf62016645b076f626dddc6a4b1a5" +checksum = "0e7f478774f05f272943a6d6b22c401c14178070c9919a8c678205b69bb70d16" dependencies = [ "aes", "async-stream", diff --git a/Cargo.toml b/Cargo.toml index b6f2bc0..aba59c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -libsql = { version = "0.9.7", features = ["encryption"] } +libsql = { version = "0.9.8", features = ["encryption"] } tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] } tracing-subscriber = "0.3" From 91c60bdee8eb4ac9ea3fad1d2818a1532355abd6 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 20 May 2025 12:25:54 +0300 Subject: [PATCH 25/51] 0.0.52 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 764c7df..2d25709 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.51" +version = "0.0.52" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index aba59c0..1f50390 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.51" +version = "0.0.52" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index a5e60a2..fe3d765 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.51" +version = "0.0.52" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 3bbf4b7f27aee17338dc5306825ac0aef8661747 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 26 May 2025 10:44:28 +0300 Subject: [PATCH 26/51] 0.0.53 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d25709..89598b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.52" +version = "0.0.53" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 1f50390..6490277 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.52" +version = "0.0.53" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index fe3d765..1583322 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.52" +version = "0.0.53" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 0b8c719e6940e771b3285895f13c58e1cf144263 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 30 May 2025 10:39:49 +0300 Subject: [PATCH 27/51] Update libsql dependency --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 89598b9..5372293 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -806,9 +806,9 @@ dependencies = [ [[package]] name = "libsql" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac8482f800f3f515e1d96af82bbb47d57d1edbc585642316eebc045f72a1930e" +checksum = "c1baac8ae0f37e50de0ea41806dcf0f35a7870a38f04aee8c90287428f22f1f1" dependencies = [ "anyhow", "async-stream", @@ -846,9 +846,9 @@ dependencies = [ [[package]] name = "libsql-ffi" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f78ac450ec98334db75ffda145c9f17377f6aa0c5a2529d233844b7b7841a48" +checksum = "90c8e9df679e22cc315585325e984703430681c672408f8b86f28212e6070ddb" dependencies = [ "bindgen", "cc", @@ -857,9 +857,9 @@ dependencies = [ [[package]] name = "libsql-hrana" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df6ae47bfedf165fb22d1aad3ca983b0aa27782fea48f98b5142f36c02b459d" +checksum = "e142c5a0b87aef1d2c212e9ec4cd22d326c9ccb5a010245ae9de5f1e5762a50d" dependencies = [ "base64 0.21.7", "bytes", @@ -881,9 +881,9 @@ dependencies = [ [[package]] name = "libsql-rusqlite" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a462d9e10715139636d7f17351ba28c4b5fbc439110282ef3aa53770c3a8ba5" +checksum = "93b2f2ceab161af8af7286a1f49bee6c16e009c87d073a8ae47743c532517c71" dependencies = [ "bitflags 2.6.0", "fallible-iterator 0.2.0", @@ -913,9 +913,9 @@ dependencies = [ [[package]] name = "libsql-sys" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76ca92a20f9b274aecfa2861e0a447d43f2b4c48dc6c8b63b6702d22c51e15eb" +checksum = "a46be96f6001d2f9877dd4044f919a9c682bc65313ea84d5af83719202df4468" dependencies = [ "bytes", "libsql-ffi", @@ -927,9 +927,9 @@ dependencies = [ [[package]] name = "libsql_replication" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7f478774f05f272943a6d6b22c401c14178070c9919a8c678205b69bb70d16" +checksum = "f991e5600846f3ede3d41a1d1e0c52a492eb96628f8095f16896ba9a29096211" dependencies = [ "aes", "async-stream", diff --git a/Cargo.toml b/Cargo.toml index 6490277..1235505 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -libsql = { version = "0.9.8", features = ["encryption"] } +libsql = { version = "0.9.9", features = ["encryption"] } tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] } tracing-subscriber = "0.3" From 69a8d045ebadb674b07cfbf709d89baefa881e56 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 30 May 2025 10:41:34 +0300 Subject: [PATCH 28/51] 0.0.54 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5372293..2637b28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.53" +version = "0.0.54" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 1235505..3627b6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.53" +version = "0.0.54" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 1583322..055029a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.53" +version = "0.0.54" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From e174ca8fcd4b1937b70d2b5a40933d998034fdd2 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 9 Jun 2025 10:13:56 +0300 Subject: [PATCH 29/51] Update libsql dependency --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2637b28..dfa883c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -806,9 +806,9 @@ dependencies = [ [[package]] name = "libsql" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1baac8ae0f37e50de0ea41806dcf0f35a7870a38f04aee8c90287428f22f1f1" +checksum = "2c9f529b1afe0465e1f864fa34cdcad08fb463a1bf86b40267493db83508ee9d" dependencies = [ "anyhow", "async-stream", @@ -846,9 +846,9 @@ dependencies = [ [[package]] name = "libsql-ffi" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90c8e9df679e22cc315585325e984703430681c672408f8b86f28212e6070ddb" +checksum = "739717a55160a200ef8a9122a17d559148ddd3f0c526b52b3908f9a80aca5284" dependencies = [ "bindgen", "cc", @@ -857,9 +857,9 @@ dependencies = [ [[package]] name = "libsql-hrana" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e142c5a0b87aef1d2c212e9ec4cd22d326c9ccb5a010245ae9de5f1e5762a50d" +checksum = "44633324952c32e3ab7da5e5cf36af9d7afe53e74f811e622ef23207b357ff18" dependencies = [ "base64 0.21.7", "bytes", @@ -881,9 +881,9 @@ dependencies = [ [[package]] name = "libsql-rusqlite" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93b2f2ceab161af8af7286a1f49bee6c16e009c87d073a8ae47743c532517c71" +checksum = "1d042d19c09bb858a4ca93c6ae346a8267215301e265097c2858a1c91f6384bd" dependencies = [ "bitflags 2.6.0", "fallible-iterator 0.2.0", @@ -913,9 +913,9 @@ dependencies = [ [[package]] name = "libsql-sys" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a46be96f6001d2f9877dd4044f919a9c682bc65313ea84d5af83719202df4468" +checksum = "3760d2141b2ac78a24c303c53ee0720301bbbe5158db3fc016c26f3eeeb44712" dependencies = [ "bytes", "libsql-ffi", @@ -927,9 +927,9 @@ dependencies = [ [[package]] name = "libsql_replication" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f991e5600846f3ede3d41a1d1e0c52a492eb96628f8095f16896ba9a29096211" +checksum = "039dccb52999803f36bc850be4e2ebc6987d1fe622994df1678b87c849c9dca1" dependencies = [ "aes", "async-stream", diff --git a/Cargo.toml b/Cargo.toml index 3627b6d..09f589f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -libsql = { version = "0.9.9", features = ["encryption"] } +libsql = { version = "0.9.10", features = ["encryption"] } tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] } tracing-subscriber = "0.3" From c37c4122429cb648134e7c9fb0ffc8ebedb6c98c Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 9 Jun 2025 10:17:05 +0300 Subject: [PATCH 30/51] 0.0.55 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dfa883c..282ab9b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.54" +version = "0.0.55" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 09f589f..fbd3500 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.54" +version = "0.0.55" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 055029a..d57ef20 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql-experimental" -version = "0.0.54" +version = "0.0.55" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From bcc013b3779f19d7930f10a13c50e6f37db18d56 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 10 Jun 2025 16:44:47 +0300 Subject: [PATCH 31/51] Python SDK is no longer experimental --- Cargo.toml | 2 +- README.md | 10 ++++------ example.py | 4 ++-- examples/batch/README.md | 2 +- examples/batch/main.py | 2 +- examples/encryption/README.md | 2 +- examples/encryption/main.py | 2 +- examples/execute_script.py | 2 +- examples/local/README.md | 2 +- examples/local/main.py | 2 +- examples/memory/README.md | 2 +- examples/memory/main.py | 2 +- examples/remote/README.md | 2 +- examples/remote/main.py | 2 +- examples/remote_connect.py | 2 +- examples/sqlalchemy/dialect.py | 4 ++-- examples/sync/README.md | 2 +- examples/sync/main.py | 2 +- examples/sync_write.py | 2 +- examples/transaction/README.md | 2 +- examples/transaction/main.py | 2 +- examples/vector.py | 2 +- examples/vector/README.md | 2 +- examples/vector/main.py | 2 +- perf-libsql.py | 4 ++-- pyproject.toml | 2 +- src/lib.rs | 16 ++++++++-------- tests/test_suite.py | 10 +++++----- 28 files changed, 45 insertions(+), 47 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fbd3500..403b35c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.0.55" edition = "2021" [lib] -name = "libsql_experimental" +name = "libsql_python" crate-type = ["cdylib"] [dependencies] diff --git a/README.md b/README.md index 5eedaef..c1e2ffe 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,10 @@

- Turso + Python -

Turso + Python (experimental)

+ Turso + Python +

Turso + Python

-This package is experimental, which means it is not consider to be production grade. Furthermore, the package currently only supports Linux and macOS. -

SQLite for Production. Powered by libSQL.

@@ -21,8 +19,8 @@

- - PyPI + + PyPI discord activity diff --git a/example.py b/example.py index b69aabf..af49bce 100644 --- a/example.py +++ b/example.py @@ -1,6 +1,6 @@ -import libsql_experimental +import libsql -con = libsql_experimental.connect("hello.db", sync_url="http://localhost:8080", +con = libsql.connect("hello.db", sync_url="http://localhost:8080", auth_token="") con.sync() diff --git a/examples/batch/README.md b/examples/batch/README.md index 1f499bd..092bba6 100644 --- a/examples/batch/README.md +++ b/examples/batch/README.md @@ -5,7 +5,7 @@ This example demonstrates how to use libSQL to execute a batch of SQL statements ## Install Dependencies ```bash -pip install libsql-experimental +pip install libsql ``` ## Running diff --git a/examples/batch/main.py b/examples/batch/main.py index eb81b31..11a6047 100644 --- a/examples/batch/main.py +++ b/examples/batch/main.py @@ -1,4 +1,4 @@ -import libsql_experimental as libsql +import libsql conn = libsql.connect("local.db") cur = conn.cursor() diff --git a/examples/encryption/README.md b/examples/encryption/README.md index 0cd65af..9b1acc1 100644 --- a/examples/encryption/README.md +++ b/examples/encryption/README.md @@ -5,7 +5,7 @@ This example demonstrates how to create and use an encrypted SQLite database wit ## Install Dependencies ```bash -pip install libsql-experimental +pip install libsql ``` ## Running diff --git a/examples/encryption/main.py b/examples/encryption/main.py index 5016f16..ce10b56 100644 --- a/examples/encryption/main.py +++ b/examples/encryption/main.py @@ -1,4 +1,4 @@ -import libsql_experimental as libsql +import libsql # You should set the ENCRYPTION_KEY in a environment variable # For demo purposes, we're using a fixed key diff --git a/examples/execute_script.py b/examples/execute_script.py index 3ac3be2..ab22f45 100644 --- a/examples/execute_script.py +++ b/examples/execute_script.py @@ -3,7 +3,7 @@ """ import os -import libsql_experimental as libsql +import libsql def execute_script(conn, file_path: os.PathLike): with open(file_path, 'r') as file: diff --git a/examples/local/README.md b/examples/local/README.md index 0a8aefe..22ef15d 100644 --- a/examples/local/README.md +++ b/examples/local/README.md @@ -5,7 +5,7 @@ This example demonstrates how to use libSQL with a local SQLite file. ## Install Dependencies ```bash -pip install libsql-experimental +pip install libsql ``` ## Running diff --git a/examples/local/main.py b/examples/local/main.py index 2b685bf..5efa6fb 100644 --- a/examples/local/main.py +++ b/examples/local/main.py @@ -1,4 +1,4 @@ -import libsql_experimental as libsql +import libsql conn = libsql.connect("local.db") cur = conn.cursor() diff --git a/examples/memory/README.md b/examples/memory/README.md index cca5ee0..e5e072f 100644 --- a/examples/memory/README.md +++ b/examples/memory/README.md @@ -5,7 +5,7 @@ This example demonstrates how to use libSQL with an in-memory SQLite database. ## Install Dependencies ```bash -pip install libsql-experimental +pip install libsql ``` ## Running diff --git a/examples/memory/main.py b/examples/memory/main.py index 1e66b46..8084f6c 100644 --- a/examples/memory/main.py +++ b/examples/memory/main.py @@ -1,4 +1,4 @@ -import libsql_experimental as libsql +import libsql conn = libsql.connect(":memory:") cur = conn.cursor() diff --git a/examples/remote/README.md b/examples/remote/README.md index 61919f4..99996a7 100644 --- a/examples/remote/README.md +++ b/examples/remote/README.md @@ -5,7 +5,7 @@ This example demonstrates how to use libSQL with a remote database. ## Install Dependencies ```bash -pip install libsql-experimental +pip install libsql ``` ## Running diff --git a/examples/remote/main.py b/examples/remote/main.py index 8c68671..f884518 100644 --- a/examples/remote/main.py +++ b/examples/remote/main.py @@ -1,4 +1,4 @@ -import libsql_experimental as libsql +import libsql import os url = os.getenv("TURSO_DATABASE_URL") diff --git a/examples/remote_connect.py b/examples/remote_connect.py index 056fd8e..801d545 100644 --- a/examples/remote_connect.py +++ b/examples/remote_connect.py @@ -5,7 +5,7 @@ """ import os -import libsql_experimental as libsql +import libsql print(F"connecting to {os.getenv('LIBSQL_URL')}") conn = libsql.connect(database=os.getenv('LIBSQL_URL'), diff --git a/examples/sqlalchemy/dialect.py b/examples/sqlalchemy/dialect.py index 1bd396d..0e45cf9 100644 --- a/examples/sqlalchemy/dialect.py +++ b/examples/sqlalchemy/dialect.py @@ -53,12 +53,12 @@ class SQLiteDialect_libsql(SQLiteDialect_pysqlite): @classmethod def import_dbapi(cls): - import libsql_experimental as libsql + import libsql return libsql def on_connect(self): - import libsql_experimental as libsql + import libsql sqlite3_connect = super().on_connect() diff --git a/examples/sync/README.md b/examples/sync/README.md index 36c97dc..dcd5a7c 100644 --- a/examples/sync/README.md +++ b/examples/sync/README.md @@ -5,7 +5,7 @@ This example demonstrates how to use libSQL with a synced database (local file s ## Install Dependencies ```bash -pip install libsql-experimental +pip install libsql ``` ## Running diff --git a/examples/sync/main.py b/examples/sync/main.py index 0b1a524..b937016 100644 --- a/examples/sync/main.py +++ b/examples/sync/main.py @@ -1,4 +1,4 @@ -import libsql_experimental as libsql +import libsql import os url = os.getenv("TURSO_DATABASE_URL") diff --git a/examples/sync_write.py b/examples/sync_write.py index 853aa83..9fd93b1 100644 --- a/examples/sync_write.py +++ b/examples/sync_write.py @@ -5,7 +5,7 @@ """ import os -import libsql_experimental as libsql +import libsql print(F"syncing with {os.getenv('LIBSQL_URL')}") conn = libsql.connect("hello.db", sync_url=os.getenv("LIBSQL_URL"), diff --git a/examples/transaction/README.md b/examples/transaction/README.md index 54bb441..965a6d5 100644 --- a/examples/transaction/README.md +++ b/examples/transaction/README.md @@ -5,7 +5,7 @@ This example demonstrates how to create and use an encrypted SQLite database wit ## Install Dependencies ```bash -pip install libsql-experimental +pip install libsql ``` ## Running diff --git a/examples/transaction/main.py b/examples/transaction/main.py index 4148cbc..c0f1810 100644 --- a/examples/transaction/main.py +++ b/examples/transaction/main.py @@ -1,4 +1,4 @@ -import libsql_experimental as libsql +import libsql conn = libsql.connect("local.db") cur = conn.cursor() diff --git a/examples/vector.py b/examples/vector.py index 12a1ccf..1a99e02 100644 --- a/examples/vector.py +++ b/examples/vector.py @@ -1,4 +1,4 @@ -import libsql_experimental as libsql +import libsql conn = libsql.connect("vector.db") diff --git a/examples/vector/README.md b/examples/vector/README.md index db8a345..5e9ecff 100644 --- a/examples/vector/README.md +++ b/examples/vector/README.md @@ -5,7 +5,7 @@ This example demonstrates how to use libSQL vector search with a local database. ## Install Dependencies ```bash -pip install libsql-experimental +pip install libsql ``` ## Running diff --git a/examples/vector/main.py b/examples/vector/main.py index b365b5f..2cd3d4f 100644 --- a/examples/vector/main.py +++ b/examples/vector/main.py @@ -1,4 +1,4 @@ -import libsql_experimental as libsql +import libsql conn = libsql.connect("local.db") diff --git a/perf-libsql.py b/perf-libsql.py index bbe06fe..744a233 100755 --- a/perf-libsql.py +++ b/perf-libsql.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 -import libsql_experimental +import libsql import pyperf import time -con = libsql_experimental.connect(":memory:") +con = libsql.connect(":memory:") cur = con.cursor() def func(): diff --git a/pyproject.toml b/pyproject.toml index d57ef20..5b4dd17 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["maturin>=1.1,<2.0"] build-backend = "maturin" [project] -name = "libsql-experimental" +name = "libsql" version = "0.0.55" requires-python = ">=3.7" classifiers = [ diff --git a/src/lib.rs b/src/lib.rs index 4a54380..4bad476 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,7 @@ fn rt() -> Handle { fn to_py_err(error: libsql_core::errors::Error) -> PyErr { let msg = match error { - libsql::Error::SqliteFailure(_, err) => err, + libsql_core::Error::SqliteFailure(_, err) => err, _ => error.to_string(), }; PyValueError::new_err(msg) @@ -117,21 +117,21 @@ fn _connect_core( let rt = rt(); let encryption_config = match encryption_key { Some(key) => { - let cipher = libsql::Cipher::default(); - let encryption_config = libsql::EncryptionConfig::new(cipher, key.into()); + let cipher = libsql_core::Cipher::default(); + let encryption_config = libsql_core::EncryptionConfig::new(cipher, key.into()); Some(encryption_config) } None => None, }; let db = if is_remote_path(&database) { - let result = libsql::Database::open_remote_internal(database.clone(), auth_token, ver); + let result = libsql_core::Database::open_remote_internal(database.clone(), auth_token, ver); result.map_err(to_py_err)? } else { match sync_url { Some(sync_url) => { let sync_interval = sync_interval.map(|i| std::time::Duration::from_secs_f64(i)); let mut builder = - libsql::Builder::new_remote_replica(database, sync_url, auth_token.to_string()); + libsql_core::Builder::new_remote_replica(database, sync_url, auth_token.to_string()); if let Some(encryption_config) = encryption_config { builder = builder.encryption_config(encryption_config); } @@ -144,7 +144,7 @@ fn _connect_core( result.map_err(to_py_err)? } None => { - let mut builder = libsql::Builder::new_local(database); + let mut builder = libsql_core::Builder::new_local(database); if let Some(config) = encryption_config { builder = builder.encryption_config(config); } @@ -640,10 +640,10 @@ fn convert_row(py: Python, row: libsql_core::Row, column_count: i32) -> PyResult Ok(PyTuple::new(py, elements)) } -create_exception!(libsql_experimental, Error, pyo3::exceptions::PyException); +create_exception!(libsql, Error, pyo3::exceptions::PyException); #[pymodule] -fn libsql_experimental(py: Python, m: &PyModule) -> PyResult<()> { +fn libsql(py: Python, m: &PyModule) -> PyResult<()> { let _ = tracing_subscriber::fmt::try_init(); m.add("LEGACY_TRANSACTION_CONTROL", LEGACY_TRANSACTION_CONTROL)?; m.add("paramstyle", "qmark")?; diff --git a/tests/test_suite.py b/tests/test_suite.py index 4a83781..c0c4703 100644 --- a/tests/test_suite.py +++ b/tests/test_suite.py @@ -2,7 +2,7 @@ import sqlite3 import sys -import libsql_experimental +import libsql import pytest @@ -326,18 +326,18 @@ def connect(provider, database, isolation_level="DEFERRED", autocommit=-1): raise Exception("libsql-remote server is not running") if res.getcode() != 200: raise Exception("libsql-remote server is not running") - return libsql_experimental.connect( + return libsql.connect( database, sync_url="http://localhost:8080", auth_token="" ) if provider == "libsql": if sys.version_info < (3, 12): - return libsql_experimental.connect( + return libsql.connect( database, isolation_level=isolation_level ) else: if autocommit == -1: - autocommit = libsql_experimental.LEGACY_TRANSACTION_CONTROL - return libsql_experimental.connect( + autocommit = libsql.LEGACY_TRANSACTION_CONTROL + return libsql.connect( database, isolation_level=isolation_level, autocommit=autocommit ) if provider == "sqlite": From 0fab13cf55a014acb4afeaa769619babad846ff7 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 10 Jun 2025 16:45:20 +0300 Subject: [PATCH 32/51] 0.1.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 282ab9b..5dbae2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "libsql-python" -version = "0.0.55" +version = "0.1.0" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 403b35c..ae40d9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsql-python" -version = "0.0.55" +version = "0.1.0" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 5b4dd17..1cf968c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql" -version = "0.0.55" +version = "0.1.0" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 5bad02da54f5bf14956386731dc795aaf6d5ae37 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 10 Jun 2025 17:46:01 +0300 Subject: [PATCH 33/51] Fix module init function name --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 4bad476..b9d403e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -643,7 +643,7 @@ fn convert_row(py: Python, row: libsql_core::Row, column_count: i32) -> PyResult create_exception!(libsql, Error, pyo3::exceptions::PyException); #[pymodule] -fn libsql(py: Python, m: &PyModule) -> PyResult<()> { +fn libsql_python(py: Python, m: &PyModule) -> PyResult<()> { let _ = tracing_subscriber::fmt::try_init(); m.add("LEGACY_TRANSACTION_CONTROL", LEGACY_TRANSACTION_CONTROL)?; m.add("paramstyle", "qmark")?; From 50d23b6635d9ec19af91cf235b49fdadd8d62de5 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 10 Jun 2025 18:01:00 +0300 Subject: [PATCH 34/51] Fix Python package name --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 3 +-- pyproject.toml | 1 + src/lib.rs | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5dbae2b..f1321d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -867,18 +867,6 @@ dependencies = [ "serde", ] -[[package]] -name = "libsql-python" -version = "0.1.0" -dependencies = [ - "libsql", - "pyo3", - "pyo3-build-config", - "tokio", - "tracing-subscriber", - "version_check", -] - [[package]] name = "libsql-rusqlite" version = "0.9.10" @@ -1237,6 +1225,18 @@ dependencies = [ "syn 2.0.72", ] +[[package]] +name = "pylibsql" +version = "0.1.0" +dependencies = [ + "libsql", + "pyo3", + "pyo3-build-config", + "tokio", + "tracing-subscriber", + "version_check", +] + [[package]] name = "pyo3" version = "0.19.2" diff --git a/Cargo.toml b/Cargo.toml index ae40d9c..958009c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,9 @@ [package] -name = "libsql-python" +name = "pylibsql" version = "0.1.0" edition = "2021" [lib] -name = "libsql_python" crate-type = ["cdylib"] [dependencies] diff --git a/pyproject.toml b/pyproject.toml index 1cf968c..6ee2a96 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,3 +15,4 @@ classifiers = [ [tool.maturin] features = ["pyo3/extension-module"] +module-name = "libsql" diff --git a/src/lib.rs b/src/lib.rs index b9d403e..4bad476 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -643,7 +643,7 @@ fn convert_row(py: Python, row: libsql_core::Row, column_count: i32) -> PyResult create_exception!(libsql, Error, pyo3::exceptions::PyException); #[pymodule] -fn libsql_python(py: Python, m: &PyModule) -> PyResult<()> { +fn libsql(py: Python, m: &PyModule) -> PyResult<()> { let _ = tracing_subscriber::fmt::try_init(); m.add("LEGACY_TRANSACTION_CONTROL", LEGACY_TRANSACTION_CONTROL)?; m.add("paramstyle", "qmark")?; From f621374a32426e77d340950af61a0beafa7cbe60 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 10 Jun 2025 18:01:29 +0300 Subject: [PATCH 35/51] 0.1.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f1321d3..a657362 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1227,7 +1227,7 @@ dependencies = [ [[package]] name = "pylibsql" -version = "0.1.0" +version = "0.1.1" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 958009c..90be59e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pylibsql" -version = "0.1.0" +version = "0.1.1" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 6ee2a96..5045fd1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql" -version = "0.1.0" +version = "0.1.1" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 7d36f960c1b2eca26db1873cb0e92ceda826d427 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 17 Jun 2025 09:34:51 +0300 Subject: [PATCH 36/51] Add timeout option to connect() ...including default busy timeout of 5 seconds like with Python SQLite module. --- src/lib.rs | 19 +++++++++++++++---- tests/test_suite.py | 29 +++++++++++++++++------------ 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4bad476..ed7d444 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ use pyo3::prelude::*; use pyo3::types::{PyList, PyTuple}; use std::cell::{OnceCell, RefCell}; use std::sync::{Arc, OnceLock}; +use std::time::Duration; use tokio::runtime::{Handle, Runtime}; const LEGACY_TRANSACTION_CONTROL: i32 = -1; @@ -37,10 +38,11 @@ fn is_remote_path(path: &str) -> bool { #[pyfunction] #[cfg(not(Py_3_12))] -#[pyo3(signature = (database, isolation_level="DEFERRED".to_string(), check_same_thread=true, uri=false, sync_url=None, sync_interval=None, auth_token="", encryption_key=None))] +#[pyo3(signature = (database, timeout=5.0, isolation_level="DEFERRED".to_string(), check_same_thread=true, uri=false, sync_url=None, sync_interval=None, auth_token="", encryption_key=None))] fn connect( py: Python<'_>, database: String, + timeout: f64, isolation_level: Option, check_same_thread: bool, uri: bool, @@ -52,6 +54,7 @@ fn connect( let conn = _connect_core( py, database, + timeout, isolation_level, check_same_thread, uri, @@ -65,10 +68,11 @@ fn connect( #[pyfunction] #[cfg(Py_3_12)] -#[pyo3(signature = (database, isolation_level="DEFERRED".to_string(), check_same_thread=true, uri=false, sync_url=None, sync_interval=None, auth_token="", encryption_key=None, autocommit = LEGACY_TRANSACTION_CONTROL))] +#[pyo3(signature = (database, timeout=5.0, isolation_level="DEFERRED".to_string(), check_same_thread=true, uri=false, sync_url=None, sync_interval=None, auth_token="", encryption_key=None, autocommit = LEGACY_TRANSACTION_CONTROL))] fn connect( py: Python<'_>, database: String, + timeout: f64, isolation_level: Option, check_same_thread: bool, uri: bool, @@ -81,6 +85,7 @@ fn connect( let mut conn = _connect_core( py, database, + timeout, isolation_level.clone(), check_same_thread, uri, @@ -104,6 +109,7 @@ fn connect( fn _connect_core( py: Python<'_>, database: String, + timeout: f64, isolation_level: Option, check_same_thread: bool, uri: bool, @@ -130,8 +136,11 @@ fn _connect_core( match sync_url { Some(sync_url) => { let sync_interval = sync_interval.map(|i| std::time::Duration::from_secs_f64(i)); - let mut builder = - libsql_core::Builder::new_remote_replica(database, sync_url, auth_token.to_string()); + let mut builder = libsql_core::Builder::new_remote_replica( + database, + sync_url, + auth_token.to_string(), + ); if let Some(encryption_config) = encryption_config { builder = builder.encryption_config(encryption_config); } @@ -158,6 +167,8 @@ fn _connect_core( let autocommit = isolation_level.is_none() as i32; let conn = db.connect().map_err(to_py_err)?; + let timeout = Duration::from_secs_f64(timeout); + conn.busy_timeout(timeout).map_err(to_py_err)?; Ok(Connection { db, conn: RefCell::new(Some(Arc::new(ConnectionGuard { diff --git a/tests/test_suite.py b/tests/test_suite.py index c0c4703..428f314 100644 --- a/tests/test_suite.py +++ b/tests/test_suite.py @@ -4,7 +4,12 @@ import sys import libsql import pytest +import tempfile +@pytest.mark.parametrize("provider", ["libsql", "sqlite"]) +def test_connection_timeout(provider): + conn = connect(provider, ":memory:", timeout=1.0) + conn.close() @pytest.mark.parametrize("provider", ["libsql", "sqlite"]) def test_connection_close(provider): @@ -163,7 +168,7 @@ def test_commit_and_rollback(provider): @pytest.mark.parametrize("provider", ["libsql", "sqlite"]) def test_autocommit(provider): - conn = connect(provider, ":memory:", None) + conn = connect(provider, ":memory:", timeout=4, isolation_level=None) assert conn.isolation_level == None assert conn.in_transaction == False cur = conn.cursor() @@ -182,7 +187,7 @@ def test_autocommit(provider): @pytest.mark.skipif(sys.version_info < (3, 12), reason="requires python3.12 or higher") def test_connection_autocommit(provider): # Test LEGACY_TRANSACTION_CONTROL (-1) - conn = connect(provider, ":memory:", None, autocommit=-1) + conn = connect(provider, ":memory:", timeout=5, isolation_level=None, autocommit=-1) assert conn.isolation_level is None assert conn.autocommit == -1 cur = conn.cursor() @@ -193,7 +198,7 @@ def test_connection_autocommit(provider): res = cur.execute("SELECT * FROM users") assert (1, "alice@example.com") == res.fetchone() - conn = connect(provider, ":memory:", isolation_level="DEFERRED", autocommit=-1) + conn = connect(provider, ":memory:", timeout=5, isolation_level="DEFERRED", autocommit=-1) assert conn.isolation_level == "DEFERRED" assert conn.autocommit == -1 cur = conn.cursor() @@ -205,7 +210,7 @@ def test_connection_autocommit(provider): assert (1, "alice@example.com") == res.fetchone() # Test autocommit Enabled (True) - conn = connect(provider, ":memory:", None, autocommit=True) + conn = connect(provider, ":memory:", timeout=5, isolation_level=None, autocommit=True) assert conn.isolation_level == None assert conn.autocommit == True cur = conn.cursor() @@ -216,7 +221,7 @@ def test_connection_autocommit(provider): res = cur.execute("SELECT * FROM users") assert (1, "bob@example.com") == res.fetchone() - conn = connect(provider, ":memory:", isolation_level="DEFERRED", autocommit=True) + conn = connect(provider, ":memory:", timeout=5, isolation_level="DEFERRED", autocommit=True) assert conn.isolation_level == "DEFERRED" assert conn.autocommit == True cur = conn.cursor() @@ -228,7 +233,7 @@ def test_connection_autocommit(provider): assert (1, "bob@example.com") == res.fetchone() # Test autocommit Disabled (False) - conn = connect(provider, ":memory:", isolation_level="DEFERRED", autocommit=False) + conn = connect(provider, ":memory:", timeout=5, isolation_level="DEFERRED", autocommit=False) assert conn.isolation_level == "DEFERRED" assert conn.autocommit == False cur = conn.cursor() @@ -243,7 +248,7 @@ def test_connection_autocommit(provider): # Test invalid autocommit value (should raise an error) with pytest.raises(ValueError): - connect(provider, ":memory:", None, autocommit=999) + connect(provider, ":memory:", timeout=5, isolation_level=None, autocommit=999) @pytest.mark.parametrize("provider", ["libsql", "sqlite"]) @@ -316,7 +321,7 @@ def test_int64(provider): assert [(1, 1099511627776)] == res.fetchall() -def connect(provider, database, isolation_level="DEFERRED", autocommit=-1): +def connect(provider, database, timeout=5, isolation_level="DEFERRED", autocommit=-1): if provider == "libsql-remote": from urllib import request @@ -332,21 +337,21 @@ def connect(provider, database, isolation_level="DEFERRED", autocommit=-1): if provider == "libsql": if sys.version_info < (3, 12): return libsql.connect( - database, isolation_level=isolation_level + database, timeout=timeout, isolation_level=isolation_level ) else: if autocommit == -1: autocommit = libsql.LEGACY_TRANSACTION_CONTROL return libsql.connect( - database, isolation_level=isolation_level, autocommit=autocommit + database, timeout=timeout, isolation_level=isolation_level, autocommit=autocommit ) if provider == "sqlite": if sys.version_info < (3, 12): - return sqlite3.connect(database, isolation_level=isolation_level) + return sqlite3.connect(database, timeout=timeout, isolation_level=isolation_level) else: if autocommit == -1: autocommit = sqlite3.LEGACY_TRANSACTION_CONTROL return sqlite3.connect( - database, isolation_level=isolation_level, autocommit=autocommit + database, timeout=timeout, isolation_level=isolation_level, autocommit=autocommit ) raise Exception(f"Provider `{provider}` is not supported") From 5188c17104eb270167bc9c6cb8d32abce0ded639 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 17 Jun 2025 09:46:08 +0300 Subject: [PATCH 37/51] 0.1.2 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a657362..07ebcec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1227,7 +1227,7 @@ dependencies = [ [[package]] name = "pylibsql" -version = "0.1.1" +version = "0.1.2" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 90be59e..45c2ac9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pylibsql" -version = "0.1.1" +version = "0.1.2" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 5045fd1..57acd3d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql" -version = "0.1.1" +version = "0.1.2" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 68dd923e25559ce023150286a977bf567214523d Mon Sep 17 00:00:00 2001 From: AdrianAcala Date: Sun, 22 Jun 2025 19:19:56 -0700 Subject: [PATCH 38/51] Add context manager support for database connections Implements __enter__ and __exit__ methods to enable using Connection objects as context managers. On clean exit, transactions are automatically committed. On exception, transactions are automatically rolled back. This provides sqlite3-compatible behavior and safer transaction handling. Closes #95 --- docs/api.md | 10 ++ src/lib.rs | 57 +++++++---- tests/test_suite.py | 229 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 269 insertions(+), 27 deletions(-) diff --git a/docs/api.md b/docs/api.md index f63d4f0..08d0b15 100644 --- a/docs/api.md +++ b/docs/api.md @@ -32,6 +32,16 @@ Rolls back the current transaction and starts a new one. Closes the database connection. +### `with` statement + +Connection objects can be used as context managers to ensure that transactions are properly committed or rolled back. When entering the context, the connection object is returned. When exiting: +- Without exception: automatically commits the transaction +- With exception: automatically rolls back the transaction + +This behavior is compatible with Python's `sqlite3` module. Context managers work correctly in both transactional and autocommit modes. + +When mixing manual transaction control with context managers, the context manager's commit/rollback will apply to any active transaction at the time of exit. Manual calls to `commit()` or `rollback()` within the context are allowed and will start a new transaction as usual. + ### execute(sql, parameters=()) Create a new cursor object and executes the SQL statement. diff --git a/src/lib.rs b/src/lib.rs index ed7d444..08db248 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,7 @@ use pyo3::create_exception; use pyo3::exceptions::PyValueError; use pyo3::prelude::*; use pyo3::types::{PyList, PyTuple}; -use std::cell::{OnceCell, RefCell}; +use std::cell::RefCell; use std::sync::{Arc, OnceLock}; use std::time::Duration; use tokio::runtime::{Handle, Runtime}; @@ -38,14 +38,14 @@ fn is_remote_path(path: &str) -> bool { #[pyfunction] #[cfg(not(Py_3_12))] -#[pyo3(signature = (database, timeout=5.0, isolation_level="DEFERRED".to_string(), check_same_thread=true, uri=false, sync_url=None, sync_interval=None, auth_token="", encryption_key=None))] +#[pyo3(signature = (database, timeout=5.0, isolation_level="DEFERRED".to_string(), _check_same_thread=true, _uri=false, sync_url=None, sync_interval=None, auth_token="", encryption_key=None))] fn connect( py: Python<'_>, database: String, timeout: f64, isolation_level: Option, - check_same_thread: bool, - uri: bool, + _check_same_thread: bool, + _uri: bool, sync_url: Option, sync_interval: Option, auth_token: &str, @@ -56,8 +56,8 @@ fn connect( database, timeout, isolation_level, - check_same_thread, - uri, + _check_same_thread, + _uri, sync_url, sync_interval, auth_token, @@ -68,14 +68,14 @@ fn connect( #[pyfunction] #[cfg(Py_3_12)] -#[pyo3(signature = (database, timeout=5.0, isolation_level="DEFERRED".to_string(), check_same_thread=true, uri=false, sync_url=None, sync_interval=None, auth_token="", encryption_key=None, autocommit = LEGACY_TRANSACTION_CONTROL))] +#[pyo3(signature = (database, timeout=5.0, isolation_level="DEFERRED".to_string(), _check_same_thread=true, _uri=false, sync_url=None, sync_interval=None, auth_token="", encryption_key=None, autocommit = LEGACY_TRANSACTION_CONTROL))] fn connect( py: Python<'_>, database: String, timeout: f64, isolation_level: Option, - check_same_thread: bool, - uri: bool, + _check_same_thread: bool, + _uri: bool, sync_url: Option, sync_interval: Option, auth_token: &str, @@ -87,8 +87,8 @@ fn connect( database, timeout, isolation_level.clone(), - check_same_thread, - uri, + _check_same_thread, + _uri, sync_url, sync_interval, auth_token, @@ -111,8 +111,8 @@ fn _connect_core( database: String, timeout: f64, isolation_level: Option, - check_same_thread: bool, - uri: bool, + _check_same_thread: bool, + _uri: bool, sync_url: Option, sync_interval: Option, auth_token: &str, @@ -220,7 +220,7 @@ unsafe impl Send for Connection {} #[pymethods] impl Connection { - fn close(self_: PyRef<'_, Self>, py: Python<'_>) -> PyResult<()> { + fn close(self_: PyRef<'_, Self>, _py: Python<'_>) -> PyResult<()> { self_.conn.replace(None); Ok(()) } @@ -330,11 +330,14 @@ impl Connection { fn in_transaction(self_: PyRef<'_, Self>) -> PyResult { #[cfg(Py_3_12)] { - return Ok( + Ok( !self_.conn.borrow().as_ref().unwrap().is_autocommit() || self_.autocommit == 0 - ); + ) + } + #[cfg(not(Py_3_12))] + { + Ok(!self_.conn.borrow().as_ref().unwrap().is_autocommit()) } - Ok(!self_.conn.borrow().as_ref().unwrap().is_autocommit()) } #[getter] @@ -354,6 +357,26 @@ impl Connection { self_.autocommit = autocommit; Ok(()) } + + fn __enter__(slf: PyRef<'_, Self>) -> PyResult> { + Ok(slf) + } + + fn __exit__( + self_: PyRef<'_, Self>, + exc_type: Option<&PyAny>, + _exc_val: Option<&PyAny>, + _exc_tb: Option<&PyAny>, + ) -> PyResult { + if exc_type.is_none() { + // Commit on clean exit + Connection::commit(self_)?; + } else { + // Rollback on error + Connection::rollback(self_)?; + } + Ok(false) // Always propagate exceptions + } } #[pyclass] diff --git a/tests/test_suite.py b/tests/test_suite.py index 428f314..041226f 100644 --- a/tests/test_suite.py +++ b/tests/test_suite.py @@ -6,16 +6,19 @@ import pytest import tempfile + @pytest.mark.parametrize("provider", ["libsql", "sqlite"]) def test_connection_timeout(provider): conn = connect(provider, ":memory:", timeout=1.0) conn.close() + @pytest.mark.parametrize("provider", ["libsql", "sqlite"]) def test_connection_close(provider): conn = connect(provider, ":memory:") conn.close() + @pytest.mark.parametrize("provider", ["libsql", "sqlite"]) def test_execute(provider): conn = connect(provider, ":memory:") @@ -34,6 +37,7 @@ def test_cursor_execute(provider): res = cur.execute("SELECT * FROM users") assert (1, "alice@example.com") == res.fetchone() + @pytest.mark.parametrize("provider", ["libsql", "sqlite"]) def test_cursor_close(provider): conn = connect(provider, ":memory:") @@ -47,6 +51,7 @@ def test_cursor_close(provider): with pytest.raises(Exception): cur.execute("SELECT * FROM users") + @pytest.mark.parametrize("provider", ["libsql", "sqlite"]) def test_executemany(provider): conn = connect(provider, ":memory:") @@ -198,7 +203,9 @@ def test_connection_autocommit(provider): res = cur.execute("SELECT * FROM users") assert (1, "alice@example.com") == res.fetchone() - conn = connect(provider, ":memory:", timeout=5, isolation_level="DEFERRED", autocommit=-1) + conn = connect( + provider, ":memory:", timeout=5, isolation_level="DEFERRED", autocommit=-1 + ) assert conn.isolation_level == "DEFERRED" assert conn.autocommit == -1 cur = conn.cursor() @@ -210,7 +217,9 @@ def test_connection_autocommit(provider): assert (1, "alice@example.com") == res.fetchone() # Test autocommit Enabled (True) - conn = connect(provider, ":memory:", timeout=5, isolation_level=None, autocommit=True) + conn = connect( + provider, ":memory:", timeout=5, isolation_level=None, autocommit=True + ) assert conn.isolation_level == None assert conn.autocommit == True cur = conn.cursor() @@ -221,7 +230,9 @@ def test_connection_autocommit(provider): res = cur.execute("SELECT * FROM users") assert (1, "bob@example.com") == res.fetchone() - conn = connect(provider, ":memory:", timeout=5, isolation_level="DEFERRED", autocommit=True) + conn = connect( + provider, ":memory:", timeout=5, isolation_level="DEFERRED", autocommit=True + ) assert conn.isolation_level == "DEFERRED" assert conn.autocommit == True cur = conn.cursor() @@ -233,7 +244,9 @@ def test_connection_autocommit(provider): assert (1, "bob@example.com") == res.fetchone() # Test autocommit Disabled (False) - conn = connect(provider, ":memory:", timeout=5, isolation_level="DEFERRED", autocommit=False) + conn = connect( + provider, ":memory:", timeout=5, isolation_level="DEFERRED", autocommit=False + ) assert conn.isolation_level == "DEFERRED" assert conn.autocommit == False cur = conn.cursor() @@ -260,6 +273,7 @@ def test_params(provider): res = cur.execute("SELECT * FROM users") assert (1, "alice@example.com") == res.fetchone() + @pytest.mark.parametrize("provider", ["libsql", "sqlite"]) def test_none_param(provider): conn = connect(provider, ":memory:") @@ -272,6 +286,7 @@ def test_none_param(provider): assert results[0] == (1, None) assert results[1] == (2, "alice@example.com") + @pytest.mark.parametrize("provider", ["libsql", "sqlite"]) def test_fetchmany(provider): conn = connect(provider, ":memory:") @@ -321,6 +336,194 @@ def test_int64(provider): assert [(1, 1099511627776)] == res.fetchall() +@pytest.mark.parametrize("provider", ["libsql", "sqlite"]) +def test_context_manager_commit(provider): + """Test that context manager commits on clean exit""" + conn = connect(provider, ":memory:") + with conn as c: + c.execute("CREATE TABLE t(x)") + c.execute("INSERT INTO t VALUES (1)") + # Changes should be committed + cur = conn.cursor() + cur.execute("SELECT COUNT(*) FROM t") + assert cur.fetchone()[0] == 1 + + +@pytest.mark.parametrize("provider", ["libsql", "sqlite"]) +def test_context_manager_rollback(provider): + """Test that context manager rolls back on exception""" + conn = connect(provider, ":memory:") + try: + with conn as c: + c.execute("CREATE TABLE t(x)") + c.execute("INSERT INTO t VALUES (1)") + raise ValueError("Test exception") + except ValueError: + pass + # Changes should be rolled back + cur = conn.cursor() + try: + cur.execute("SELECT COUNT(*) FROM t") + # If we get here, the table exists (rollback didn't work) + assert False, "Table should not exist after rollback" + except Exception: + # Table doesn't exist, which is what we expect after rollback + pass + + +@pytest.mark.parametrize("provider", ["libsql", "sqlite"]) +def test_context_manager_autocommit(provider): + """Test that context manager works correctly with autocommit mode""" + conn = connect(provider, ":memory:", isolation_level=None) # autocommit mode + with conn as c: + c.execute("CREATE TABLE t(x)") + c.execute("INSERT INTO t VALUES (1)") + # In autocommit mode, changes are committed immediately + cur = conn.cursor() + cur.execute("SELECT COUNT(*) FROM t") + assert cur.fetchone()[0] == 1 + + +@pytest.mark.parametrize("provider", ["libsql", "sqlite"]) +def test_context_manager_nested(provider): + """Test nested context managers""" + conn = connect(provider, ":memory:") + with conn as c1: + c1.execute("CREATE TABLE t(x)") + c1.execute("INSERT INTO t VALUES (1)") + with conn as c2: + c2.execute("INSERT INTO t VALUES (2)") + # Inner context commits + cur = conn.cursor() + cur.execute("SELECT COUNT(*) FROM t") + assert cur.fetchone()[0] == 2 + # Outer context also commits + cur = conn.cursor() + cur.execute("SELECT COUNT(*) FROM t") + assert cur.fetchone()[0] == 2 + + +@pytest.mark.parametrize("provider", ["libsql", "sqlite"]) +def test_context_manager_connection_reuse(provider): + """Test that connection remains usable after context manager exit""" + conn = connect(provider, ":memory:") + + # First use with context manager + with conn as c: + c.execute("CREATE TABLE t(x)") + c.execute("INSERT INTO t VALUES (1)") + + # Connection should still be valid + cur = conn.cursor() + cur.execute("INSERT INTO t VALUES (2)") + conn.commit() + + # Verify both inserts worked + cur.execute("SELECT COUNT(*) FROM t") + assert cur.fetchone()[0] == 2 + + # Use context manager again + with conn as c: + c.execute("INSERT INTO t VALUES (3)") + + # Final verification + cur.execute("SELECT COUNT(*) FROM t") + assert cur.fetchone()[0] == 3 + + conn.close() + + +@pytest.mark.parametrize("provider", ["libsql", "sqlite"]) +def test_context_manager_nested_exception(provider): + """Test exception handling in nested context managers""" + conn = connect(provider, ":memory:") + + # Create table outside context + conn.execute("CREATE TABLE t(x)") + conn.commit() + + # Test that nested context managers share the same transaction + # An exception in an inner context will roll back the entire transaction + try: + with conn as c1: + c1.execute("INSERT INTO t VALUES (1)") + try: + with conn as c2: + c2.execute("INSERT INTO t VALUES (2)") + raise ValueError("Inner exception") + except ValueError: + pass + # The inner rollback affects the entire transaction + # So value 1 is also rolled back + c1.execute("INSERT INTO t VALUES (3)") + except: + pass + + # Only value 3 should be committed (1 and 2 were rolled back together) + cur = conn.cursor() + cur.execute("SELECT x FROM t ORDER BY x") + results = cur.fetchall() + assert results == [(3,)] + + # Test outer exception after nested context commits + conn.execute("DROP TABLE t") + conn.execute("CREATE TABLE t(x)") + conn.commit() + + try: + with conn as c1: + c1.execute("INSERT INTO t VALUES (10)") + with conn as c2: + c2.execute("INSERT INTO t VALUES (20)") + # Inner context will commit both values + # This will cause outer rollback but values are already committed + raise RuntimeError("Outer exception") + except RuntimeError: + pass + + # Values 10 and 20 should be committed by inner context + cur.execute("SELECT COUNT(*) FROM t") + assert cur.fetchone()[0] == 2 + + +@pytest.mark.parametrize("provider", ["libsql", "sqlite"]) +def test_context_manager_manual_transaction_control(provider): + """Test mixing manual transaction control with context managers""" + conn = connect(provider, ":memory:") + + with conn as c: + c.execute("CREATE TABLE t(x)") + c.execute("INSERT INTO t VALUES (1)") + + # Manual commit within context + c.commit() + + # Start new transaction + c.execute("INSERT INTO t VALUES (2)") + # This will be committed by context manager + + # Both values should be present + cur = conn.cursor() + cur.execute("SELECT COUNT(*) FROM t") + assert cur.fetchone()[0] == 2 + + # Test manual rollback within context + with conn as c: + c.execute("INSERT INTO t VALUES (3)") + + # Manual rollback + c.rollback() + + # New transaction + c.execute("INSERT INTO t VALUES (4)") + # This will be committed by context manager + + # Should have values 1, 2, and 4 (not 3) + cur.execute("SELECT x FROM t ORDER BY x") + results = cur.fetchall() + assert results == [(1,), (2,), (4,)] + + def connect(provider, database, timeout=5, isolation_level="DEFERRED", autocommit=-1): if provider == "libsql-remote": from urllib import request @@ -331,9 +534,7 @@ def connect(provider, database, timeout=5, isolation_level="DEFERRED", autocommi raise Exception("libsql-remote server is not running") if res.getcode() != 200: raise Exception("libsql-remote server is not running") - return libsql.connect( - database, sync_url="http://localhost:8080", auth_token="" - ) + return libsql.connect(database, sync_url="http://localhost:8080", auth_token="") if provider == "libsql": if sys.version_info < (3, 12): return libsql.connect( @@ -343,15 +544,23 @@ def connect(provider, database, timeout=5, isolation_level="DEFERRED", autocommi if autocommit == -1: autocommit = libsql.LEGACY_TRANSACTION_CONTROL return libsql.connect( - database, timeout=timeout, isolation_level=isolation_level, autocommit=autocommit + database, + timeout=timeout, + isolation_level=isolation_level, + autocommit=autocommit, ) if provider == "sqlite": if sys.version_info < (3, 12): - return sqlite3.connect(database, timeout=timeout, isolation_level=isolation_level) + return sqlite3.connect( + database, timeout=timeout, isolation_level=isolation_level + ) else: if autocommit == -1: autocommit = sqlite3.LEGACY_TRANSACTION_CONTROL return sqlite3.connect( - database, timeout=timeout, isolation_level=isolation_level, autocommit=autocommit + database, + timeout=timeout, + isolation_level=isolation_level, + autocommit=autocommit, ) raise Exception(f"Provider `{provider}` is not supported") From b8a0d497421c51b64c0ba19e963385b1747f945c Mon Sep 17 00:00:00 2001 From: Jayson Reis Date: Fri, 4 Jul 2025 19:07:07 +0200 Subject: [PATCH 39/51] feat: Allow parameters to be tuple or lists This is mostly to improve the dev experience to avoid forcing a specific type allowing some duck typing --- src/lib.rs | 69 ++++++++++++++++++++++++++++++++++++++++----- tests/test_suite.py | 3 ++ 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ed7d444..4b358d3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,13 +3,23 @@ use pyo3::create_exception; use pyo3::exceptions::PyValueError; use pyo3::prelude::*; use pyo3::types::{PyList, PyTuple}; -use std::cell::{OnceCell, RefCell}; +use std::cell::RefCell; use std::sync::{Arc, OnceLock}; use std::time::Duration; use tokio::runtime::{Handle, Runtime}; const LEGACY_TRANSACTION_CONTROL: i32 = -1; +enum ListOrTuple<'py> { + List(&'py PyList), + Tuple(&'py PyTuple), +} + +struct ListOrTupleIterator<'py> { + index: usize, + inner: &'py ListOrTuple<'py> +} + fn rt() -> Handle { static RT: OnceLock = OnceLock::new(); @@ -286,7 +296,7 @@ impl Connection { fn execute( self_: PyRef<'_, Self>, sql: String, - parameters: Option<&PyTuple>, + parameters: Option, ) -> PyResult { let cursor = Connection::cursor(&self_)?; rt().block_on(async { execute(&cursor, sql, parameters).await })?; @@ -300,7 +310,7 @@ impl Connection { ) -> PyResult { let cursor = Connection::cursor(&self_)?; for parameters in parameters.unwrap().iter() { - let parameters = parameters.extract::<&PyTuple>()?; + let parameters = parameters.extract::()?; rt().block_on(async { execute(&cursor, sql.clone(), Some(parameters)).await })?; } Ok(cursor) @@ -396,7 +406,7 @@ impl Cursor { fn execute<'a>( self_: PyRef<'a, Self>, sql: String, - parameters: Option<&PyTuple>, + parameters: Option, ) -> PyResult> { rt().block_on(async { execute(&self_, sql, parameters).await })?; Ok(self_) @@ -408,7 +418,7 @@ impl Cursor { parameters: Option<&PyList>, ) -> PyResult> { for parameters in parameters.unwrap().iter() { - let parameters = parameters.extract::<&PyTuple>()?; + let parameters = parameters.extract::()?; rt().block_on(async { execute(&self_, sql.clone(), Some(parameters)).await })?; } Ok(self_) @@ -552,7 +562,11 @@ async fn begin_transaction(conn: &libsql_core::Connection) -> PyResult<()> { Ok(()) } -async fn execute(cursor: &Cursor, sql: String, parameters: Option<&PyTuple>) -> PyResult<()> { +async fn execute<'py>( + cursor: &Cursor, + sql: String, + parameters: Option>, +) -> PyResult<()> { if cursor.conn.borrow().as_ref().is_none() { return Err(PyValueError::new_err("Connection already closed")); } @@ -576,7 +590,10 @@ async fn execute(cursor: &Cursor, sql: String, parameters: Option<&PyTuple>) -> } else if let Ok(value) = param.extract::<&[u8]>() { libsql_core::Value::Blob(value.to_vec()) } else { - return Err(PyValueError::new_err("Unsupported parameter type")); + return Err(PyValueError::new_err(format!( + "Unsupported parameter type {}", + param.to_string() + ))); }; params.push(param); } @@ -653,6 +670,44 @@ fn convert_row(py: Python, row: libsql_core::Row, column_count: i32) -> PyResult create_exception!(libsql, Error, pyo3::exceptions::PyException); +impl<'py> FromPyObject<'py> for ListOrTuple<'py> { + fn extract(ob: &'py PyAny) -> PyResult { + if let Ok(list) = ob.downcast::() { + Ok(ListOrTuple::List(list)) + } else if let Ok(tuple) = ob.downcast::() { + Ok(ListOrTuple::Tuple(tuple)) + } else { + Err(PyValueError::new_err( + "Expected a list or tuple for parameters", + )) + } + } +} + +impl<'py> ListOrTuple<'py> { + pub fn iter(&self) -> ListOrTupleIterator { + ListOrTupleIterator{ + index: 0, + inner: self, + } + } +} + +impl<'py> Iterator for ListOrTupleIterator<'py> { + type Item = &'py PyAny; + + fn next(&mut self) -> Option { + let rv = match self.inner { + ListOrTuple::List(list) => list.get_item(self.index), + ListOrTuple::Tuple(tuple) => tuple.get_item(self.index), + }; + + rv.ok().map(|item| { + self.index += 1; + item + }) + } +} #[pymodule] fn libsql(py: Python, m: &PyModule) -> PyResult<()> { let _ = tracing_subscriber::fmt::try_init(); diff --git a/tests/test_suite.py b/tests/test_suite.py index 428f314..dc3b499 100644 --- a/tests/test_suite.py +++ b/tests/test_suite.py @@ -23,6 +23,9 @@ def test_execute(provider): conn.execute("INSERT INTO users VALUES (1, 'alice@example.com')") res = conn.execute("SELECT * FROM users") assert (1, "alice@example.com") == res.fetchone() + # allow lists for parameters as well + res = conn.execute("SELECT * FROM users WHERE id = ?", [1]) + assert (1, "alice@example.com") == res.fetchone() @pytest.mark.parametrize("provider", ["libsql", "sqlite"]) From 813a677cabde70805508871da783c677397eb082 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 15 Jul 2025 14:28:04 +0300 Subject: [PATCH 40/51] Update libsql dependency Update to development version for pre-release. --- Cargo.lock | 43 +++++++++++++++++++++++-------------------- Cargo.toml | 2 +- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07ebcec..081f4ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -326,6 +326,15 @@ dependencies = [ "libloading", ] +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -806,9 +815,8 @@ dependencies = [ [[package]] name = "libsql" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9f529b1afe0465e1f864fa34cdcad08fb463a1bf86b40267493db83508ee9d" +version = "0.9.15" +source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" dependencies = [ "anyhow", "async-stream", @@ -846,20 +854,19 @@ dependencies = [ [[package]] name = "libsql-ffi" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739717a55160a200ef8a9122a17d559148ddd3f0c526b52b3908f9a80aca5284" +version = "0.9.15" +source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" dependencies = [ "bindgen", "cc", + "cmake", "glob", ] [[package]] name = "libsql-hrana" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44633324952c32e3ab7da5e5cf36af9d7afe53e74f811e622ef23207b357ff18" +version = "0.9.15" +source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" dependencies = [ "base64 0.21.7", "bytes", @@ -869,9 +876,8 @@ dependencies = [ [[package]] name = "libsql-rusqlite" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d042d19c09bb858a4ca93c6ae346a8267215301e265097c2858a1c91f6384bd" +version = "0.9.15" +source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" dependencies = [ "bitflags 2.6.0", "fallible-iterator 0.2.0", @@ -884,8 +890,7 @@ dependencies = [ [[package]] name = "libsql-sqlite3-parser" version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15a90128c708356af8f7d767c9ac2946692c9112b4f74f07b99a01a60680e413" +source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" dependencies = [ "bitflags 2.6.0", "cc", @@ -901,9 +906,8 @@ dependencies = [ [[package]] name = "libsql-sys" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3760d2141b2ac78a24c303c53ee0720301bbbe5158db3fc016c26f3eeeb44712" +version = "0.9.15" +source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" dependencies = [ "bytes", "libsql-ffi", @@ -915,9 +919,8 @@ dependencies = [ [[package]] name = "libsql_replication" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "039dccb52999803f36bc850be4e2ebc6987d1fe622994df1678b87c849c9dca1" +version = "0.9.15" +source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" dependencies = [ "aes", "async-stream", diff --git a/Cargo.toml b/Cargo.toml index 45c2ac9..1182e10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -libsql = { version = "0.9.10", features = ["encryption"] } +libsql = { git = "https://github.com/tursodatabase/libsql/", rev = "57043b60f3db38236187a8905bee62b35bf18afb", features = ["encryption"] } tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] } tracing-subscriber = "0.3" From f915a222d8b504e2c72183793a0979321c31bff5 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 15 Jul 2025 14:30:52 +0300 Subject: [PATCH 41/51] 0.1.3-pre.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 081f4ec..ac2ee00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1230,7 +1230,7 @@ dependencies = [ [[package]] name = "pylibsql" -version = "0.1.2" +version = "0.1.3-pre.1" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 1182e10..8c591da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pylibsql" -version = "0.1.2" +version = "0.1.3-pre.1" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 57acd3d..4568a21 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql" -version = "0.1.2" +version = "0.1.3-pre.1" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 02fc088659778ff7187ba2e8b7468fcade35c1c4 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 16 Jul 2025 09:50:57 +0300 Subject: [PATCH 42/51] Update libsql dependency --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8c591da..2dcb502 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -libsql = { git = "https://github.com/tursodatabase/libsql/", rev = "57043b60f3db38236187a8905bee62b35bf18afb", features = ["encryption"] } +libsql = { version = "0.9.16", features = ["encryption"] } tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] } tracing-subscriber = "0.3" From d76ef4d0aacbf2219782f66b6f225f56a72474bf Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 16 Jul 2025 09:51:42 +0300 Subject: [PATCH 43/51] 0.1.3 --- Cargo.lock | 35 +++++++++++++++++++++-------------- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac2ee00..5076bec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,8 +815,9 @@ dependencies = [ [[package]] name = "libsql" -version = "0.9.15" -source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" +version = "0.9.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d95129072238e1a97837259b5112e870430991ef0305dfba8fae46c47dc3a6e" dependencies = [ "anyhow", "async-stream", @@ -854,8 +855,9 @@ dependencies = [ [[package]] name = "libsql-ffi" -version = "0.9.15" -source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" +version = "0.9.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c92aaed04d77f0e8c90d2d3a71aee00ba9d561268615cc57128d9c9e76e9464" dependencies = [ "bindgen", "cc", @@ -865,8 +867,9 @@ dependencies = [ [[package]] name = "libsql-hrana" -version = "0.9.15" -source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" +version = "0.9.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759e0846db84f03e25e3001d9060c23824cbd961eae44603d7dc58b9a8581b82" dependencies = [ "base64 0.21.7", "bytes", @@ -876,8 +879,9 @@ dependencies = [ [[package]] name = "libsql-rusqlite" -version = "0.9.15" -source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" +version = "0.9.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6fa85992b107fb372b12bdb9612577447dbe2edb4548ee6eb6338396f34273f" dependencies = [ "bitflags 2.6.0", "fallible-iterator 0.2.0", @@ -890,7 +894,8 @@ dependencies = [ [[package]] name = "libsql-sqlite3-parser" version = "0.13.0" -source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15a90128c708356af8f7d767c9ac2946692c9112b4f74f07b99a01a60680e413" dependencies = [ "bitflags 2.6.0", "cc", @@ -906,8 +911,9 @@ dependencies = [ [[package]] name = "libsql-sys" -version = "0.9.15" -source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" +version = "0.9.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49defac306e9d29bfa1c908eae1c3a5b3942b6f897f50f02d14bf12be63c281d" dependencies = [ "bytes", "libsql-ffi", @@ -919,8 +925,9 @@ dependencies = [ [[package]] name = "libsql_replication" -version = "0.9.15" -source = "git+https://github.com/tursodatabase/libsql/?rev=57043b60f3db38236187a8905bee62b35bf18afb#57043b60f3db38236187a8905bee62b35bf18afb" +version = "0.9.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aa18ccced4312c8ed9fc02f0d90a7fc42edf5223517c3745cd2f804770c04e4" dependencies = [ "aes", "async-stream", @@ -1230,7 +1237,7 @@ dependencies = [ [[package]] name = "pylibsql" -version = "0.1.3-pre.1" +version = "0.1.3" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 2dcb502..659d17b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pylibsql" -version = "0.1.3-pre.1" +version = "0.1.3" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 4568a21..6f33975 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql" -version = "0.1.3-pre.1" +version = "0.1.3" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From bb3b9e4ef7d45a3ffd88b952934ee9d454838603 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 16 Jul 2025 10:10:18 +0300 Subject: [PATCH 44/51] 0.1.4 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5076bec..aa135a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1237,7 +1237,7 @@ dependencies = [ [[package]] name = "pylibsql" -version = "0.1.3" +version = "0.1.4" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 659d17b..7e593e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pylibsql" -version = "0.1.3" +version = "0.1.4" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index 6f33975..ce28d2f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql" -version = "0.1.3" +version = "0.1.4" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 656f6b15294f5a7b4790cd33dad7d433ca28a390 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 22 Jul 2025 10:19:19 +0300 Subject: [PATCH 45/51] Update libsql dependency --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa135a2..4aef84f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,9 +815,9 @@ dependencies = [ [[package]] name = "libsql" -version = "0.9.16" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d95129072238e1a97837259b5112e870430991ef0305dfba8fae46c47dc3a6e" +checksum = "acd99c54790a50cffb62b1bf3e82c747fafad296c2fd21acce3154e4d9112241" dependencies = [ "anyhow", "async-stream", @@ -855,9 +855,9 @@ dependencies = [ [[package]] name = "libsql-ffi" -version = "0.9.16" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c92aaed04d77f0e8c90d2d3a71aee00ba9d561268615cc57128d9c9e76e9464" +checksum = "f72c71234e1ad056592c977f5353b9ee87a2f9923cc7ac80bce52b7e30dbe702" dependencies = [ "bindgen", "cc", @@ -867,9 +867,9 @@ dependencies = [ [[package]] name = "libsql-hrana" -version = "0.9.16" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759e0846db84f03e25e3001d9060c23824cbd961eae44603d7dc58b9a8581b82" +checksum = "25ce12bd586bde040a4bd33b291df6bf26dc56379629e1cb5d50e08a1bd31d56" dependencies = [ "base64 0.21.7", "bytes", @@ -879,9 +879,9 @@ dependencies = [ [[package]] name = "libsql-rusqlite" -version = "0.9.16" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6fa85992b107fb372b12bdb9612577447dbe2edb4548ee6eb6338396f34273f" +checksum = "dc5d27776273a28e4eb1a63e9abb924f7e0d8a3f26b5b713724826f3e0c8bf6f" dependencies = [ "bitflags 2.6.0", "fallible-iterator 0.2.0", @@ -911,9 +911,9 @@ dependencies = [ [[package]] name = "libsql-sys" -version = "0.9.16" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49defac306e9d29bfa1c908eae1c3a5b3942b6f897f50f02d14bf12be63c281d" +checksum = "11f4b1c9314de9c3f4d768e3b03d5e2d0b95747423dcb55c69494c49a3630728" dependencies = [ "bytes", "libsql-ffi", @@ -925,9 +925,9 @@ dependencies = [ [[package]] name = "libsql_replication" -version = "0.9.16" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aa18ccced4312c8ed9fc02f0d90a7fc42edf5223517c3745cd2f804770c04e4" +checksum = "fc5717bf0fd5ef39a40094bb606332e03a37d19b65d96399506453a8ee132167" dependencies = [ "aes", "async-stream", diff --git a/Cargo.toml b/Cargo.toml index 7e593e4..d9bef2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -libsql = { version = "0.9.16", features = ["encryption"] } +libsql = { version = "0.9.18", features = ["encryption"] } tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] } tracing-subscriber = "0.3" From 6186ff5098a7bf966ea8b62d2fc937c9c4cb79f2 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 22 Jul 2025 10:19:40 +0300 Subject: [PATCH 46/51] 0.1.5 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4aef84f..008e773 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1237,7 +1237,7 @@ dependencies = [ [[package]] name = "pylibsql" -version = "0.1.4" +version = "0.1.5" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index d9bef2e..7fc3887 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pylibsql" -version = "0.1.4" +version = "0.1.5" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index ce28d2f..a4c0b0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql" -version = "0.1.4" +version = "0.1.5" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 4c8ef5e997a5c686a32c5b2e830a05b738b67235 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 23 Jul 2025 16:25:06 +0300 Subject: [PATCH 47/51] Update libsql dependency --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 008e773..ec9cb0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,9 +815,9 @@ dependencies = [ [[package]] name = "libsql" -version = "0.9.18" +version = "0.9.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd99c54790a50cffb62b1bf3e82c747fafad296c2fd21acce3154e4d9112241" +checksum = "c92f460194a673c29e82520a061a82f83892faca9ce6881db93d591cd38cb3dc" dependencies = [ "anyhow", "async-stream", @@ -855,9 +855,9 @@ dependencies = [ [[package]] name = "libsql-ffi" -version = "0.9.18" +version = "0.9.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f72c71234e1ad056592c977f5353b9ee87a2f9923cc7ac80bce52b7e30dbe702" +checksum = "64691b229b9d5c0754115f59a0e5c0d1bcc102bfe402b96f2bbf9d5150a4ab3c" dependencies = [ "bindgen", "cc", @@ -867,9 +867,9 @@ dependencies = [ [[package]] name = "libsql-hrana" -version = "0.9.18" +version = "0.9.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ce12bd586bde040a4bd33b291df6bf26dc56379629e1cb5d50e08a1bd31d56" +checksum = "c18b78daf4af8603c048f584faada18c8970f4f3af16df0c3319a92c90d0d696" dependencies = [ "base64 0.21.7", "bytes", @@ -879,9 +879,9 @@ dependencies = [ [[package]] name = "libsql-rusqlite" -version = "0.9.18" +version = "0.9.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc5d27776273a28e4eb1a63e9abb924f7e0d8a3f26b5b713724826f3e0c8bf6f" +checksum = "c502ebc6fd1a7ba1b686c47226016fb8e913080c4021491bda33ca33c6fa1ab4" dependencies = [ "bitflags 2.6.0", "fallible-iterator 0.2.0", @@ -911,9 +911,9 @@ dependencies = [ [[package]] name = "libsql-sys" -version = "0.9.18" +version = "0.9.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11f4b1c9314de9c3f4d768e3b03d5e2d0b95747423dcb55c69494c49a3630728" +checksum = "9e7b9ab82fa6122efe2b2fe066043d6330aa4a7aa656b4ec0df9768ffd1ea6a0" dependencies = [ "bytes", "libsql-ffi", @@ -925,9 +925,9 @@ dependencies = [ [[package]] name = "libsql_replication" -version = "0.9.18" +version = "0.9.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc5717bf0fd5ef39a40094bb606332e03a37d19b65d96399506453a8ee132167" +checksum = "aa911faee7c1e039a44aeced5e61b5106fb714782e26d89216c87c83eb1ce410" dependencies = [ "aes", "async-stream", diff --git a/Cargo.toml b/Cargo.toml index 7fc3887..f51f6f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -libsql = { version = "0.9.18", features = ["encryption"] } +libsql = { version = "0.9.19", features = ["encryption"] } tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] } tracing-subscriber = "0.3" From 1251fa5db19fa8fb180d735b1d991769f1c18e25 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 23 Jul 2025 16:25:22 +0300 Subject: [PATCH 48/51] 0.1.6 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ec9cb0e..245550c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1237,7 +1237,7 @@ dependencies = [ [[package]] name = "pylibsql" -version = "0.1.5" +version = "0.1.6" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index f51f6f3..b157652 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pylibsql" -version = "0.1.5" +version = "0.1.6" edition = "2021" [lib] diff --git a/pyproject.toml b/pyproject.toml index a4c0b0e..0f01d73 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql" -version = "0.1.5" +version = "0.1.6" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 477d6bfeb19bc4e09151c79092069e79140c6ce2 Mon Sep 17 00:00:00 2001 From: Kilian Hu Date: Mon, 28 Jul 2025 12:10:03 +0200 Subject: [PATCH 49/51] Bump dependency versions and rust edition - Dependency Updates - pyo3: 0.19.0 -> 0.25.1 - pyo3-build-config: 0.19.0 -> 0.25.1 - tokio: 1.29.1 -> 1.47.0 - tracing-subscriber: 0.3.18 -> 0.3.19 - Rust Edition 2021 -> 2024 - Migrated from GIL Refs to Bound API - Replaced all GIL reference types with Bound smart pointers: - &PyAny -> Bound<'_, PyAny> - &PyList -> Bound<'_, PyList> - &PyTuple -> Bound<'_, PyTuple> - &PyModule -> &Bound<'_, PyModule> - Updated Type Definitions - Modified ListOrTuple enum to use Bound types and added #[derive(Clone)] - Updated ListOrTupleIterator to return Bound<'py, PyAny> items - API Method Updates - Constructor methods: PyTuple::new_bound -> PyTuple::new, PyList::new_bound -> PyList::new - Type access: py.get_type_bound -> py.get_type - Added error handling for fallible constructors with ? operator - Trait Implementation Changes - FromPyObject: Migrated from extract to extract_bound method - Conversion methods: Replaced into_py() and to_object() with into_pyobject().unwrap().into() - Thread Safety - Added unsafe impl Sync for both Connection and Cursor structs (required for PyO3 0.23+) - Function Signatures - Added explicit #[pyo3(signature = ...)] attributes for functions with trailing Option parameters: - execute and executemany: #[pyo3(signature = (sql, parameters=None))] - fetchmany: #[pyo3(signature = (size=None))] - __exit__: #[pyo3(signature = (exc_type=None, _exc_val=None, _exc_tb=None))] - Module Initialization - Updated pymodule function signature to accept &Bound<'_, PyModule> instead of &PyModule --- Cargo.lock | 161 ++++++++++++++++++++++++++++++++--------------------- Cargo.toml | 10 ++-- src/lib.rs | 88 ++++++++++++++++------------- 3 files changed, 153 insertions(+), 106 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 245550c..e270f34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,7 +95,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -106,7 +106,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -215,7 +215,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.72", + "syn", "which", ] @@ -398,7 +398,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -481,7 +481,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -591,6 +591,12 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -603,7 +609,7 @@ version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -663,7 +669,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.5.7", "tokio", "tower-service", "tracing", @@ -746,9 +752,9 @@ dependencies = [ [[package]] name = "indoc" -version = "1.0.9" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" +checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" [[package]] name = "inout" @@ -760,6 +766,17 @@ dependencies = [ "generic-array", ] +[[package]] +name = "io-uring" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "libc", +] + [[package]] name = "itertools" version = "0.12.1" @@ -799,9 +816,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libloading" @@ -1022,7 +1039,7 @@ dependencies = [ "hermit-abi", "libc", "wasi", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1172,7 +1189,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -1187,6 +1204,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1200,7 +1223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.72", + "syn", ] [[package]] @@ -1232,7 +1255,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -1249,15 +1272,15 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.19.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38" +checksum = "8970a78afe0628a3e3430376fc5fd76b6b45c4d43360ffd6cdd40bdde72b682a" dependencies = [ - "cfg-if", "indoc", "libc", "memoffset", - "parking_lot", + "once_cell", + "portable-atomic", "pyo3-build-config", "pyo3-ffi", "pyo3-macros", @@ -1266,9 +1289,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.19.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5" +checksum = "458eb0c55e7ece017adeba38f2248ff3ac615e53660d7c71a238d7d2a01c7598" dependencies = [ "once_cell", "target-lexicon", @@ -1276,9 +1299,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.19.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9" +checksum = "7114fe5457c61b276ab77c5055f206295b812608083644a5c5b2640c3102565c" dependencies = [ "libc", "pyo3-build-config", @@ -1286,25 +1309,27 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.19.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1" +checksum = "a8725c0a622b374d6cb051d11a0983786448f7785336139c3c94f5aa6bef7e50" dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "pyo3-macros-backend" -version = "0.19.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536" +checksum = "4109984c22491085343c05b0dbc54ddc405c3cf7b4374fc533f5c3313a572ccc" dependencies = [ + "heck", "proc-macro2", + "pyo3-build-config", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -1396,7 +1421,7 @@ dependencies = [ "libc", "spin", "untrusted", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1421,7 +1446,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1496,7 +1521,7 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1545,7 +1570,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -1611,7 +1636,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", ] [[package]] @@ -1626,17 +1661,6 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.72" @@ -1656,9 +1680,9 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "target-lexicon" -version = "0.12.15" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4873307b7c257eddcb50c9bedf158eb669578359fb28428bef438fec8e6ba7c2" +checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" [[package]] name = "thiserror" @@ -1677,7 +1701,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -1692,20 +1716,22 @@ dependencies = [ [[package]] name = "tokio" -version = "1.39.1" +version = "1.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a" +checksum = "43864ed400b6043a4757a25c7a64a8efde741aed79a056a2fb348a406701bb35" dependencies = [ "backtrace", "bytes", + "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "slab", + "socket2 0.6.0", "tokio-macros", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1720,13 +1746,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -1883,7 +1909,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -1909,9 +1935,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "nu-ansi-term", "sharded-slab", @@ -1950,9 +1976,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unindent" -version = "0.1.11" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c" +checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" [[package]] name = "untrusted" @@ -2019,7 +2045,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.72", + "syn", "wasm-bindgen-shared", ] @@ -2041,7 +2067,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2122,6 +2148,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -2204,7 +2239,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b157652..910a748 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,18 +1,18 @@ [package] name = "pylibsql" version = "0.1.6" -edition = "2021" +edition = "2024" [lib] crate-type = ["cdylib"] [dependencies] -pyo3 = "0.19.0" +pyo3 = "0.25.1" libsql = { version = "0.9.19", features = ["encryption"] } -tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] } -tracing-subscriber = "0.3" +tokio = { version = "1.47.0", features = [ "rt-multi-thread" ] } +tracing-subscriber = "0.3.19" [build-dependencies] version_check = "0.9.5" # used where logic has to be version/distribution specific, e.g. pypy -pyo3-build-config = { version = "0.19.0" } +pyo3-build-config = { version = "0.25.1" } diff --git a/src/lib.rs b/src/lib.rs index a64d535..8cd8863 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,7 @@ use ::libsql as libsql_core; use pyo3::create_exception; use pyo3::exceptions::PyValueError; use pyo3::prelude::*; -use pyo3::types::{PyList, PyTuple}; +use pyo3::types::{PyList, PyModule, PyTuple}; use std::cell::RefCell; use std::sync::{Arc, OnceLock}; use std::time::Duration; @@ -10,14 +10,15 @@ use tokio::runtime::{Handle, Runtime}; const LEGACY_TRANSACTION_CONTROL: i32 = -1; +#[derive(Clone)] enum ListOrTuple<'py> { - List(&'py PyList), - Tuple(&'py PyTuple), + List(Bound<'py, PyList>), + Tuple(Bound<'py, PyTuple>), } struct ListOrTupleIterator<'py> { index: usize, - inner: &'py ListOrTuple<'py> + inner: ListOrTuple<'py>, } fn rt() -> Handle { @@ -227,6 +228,7 @@ pub struct Connection { // SAFETY: The libsql crate guarantees that `Connection` is thread-safe. unsafe impl Send for Connection {} +unsafe impl Sync for Connection {} #[pymethods] impl Connection { @@ -293,20 +295,22 @@ impl Connection { Ok(()) } + #[pyo3(signature = (sql, parameters=None))] fn execute( self_: PyRef<'_, Self>, sql: String, - parameters: Option, + parameters: Option>, ) -> PyResult { let cursor = Connection::cursor(&self_)?; rt().block_on(async { execute(&cursor, sql, parameters).await })?; Ok(cursor) } + #[pyo3(signature = (sql, parameters=None))] fn executemany( self_: PyRef<'_, Self>, sql: String, - parameters: Option<&PyList>, + parameters: Option<&Bound<'_, PyList>>, ) -> PyResult { let cursor = Connection::cursor(&self_)?; for parameters in parameters.unwrap().iter() { @@ -340,9 +344,7 @@ impl Connection { fn in_transaction(self_: PyRef<'_, Self>) -> PyResult { #[cfg(Py_3_12)] { - Ok( - !self_.conn.borrow().as_ref().unwrap().is_autocommit() || self_.autocommit == 0 - ) + Ok(!self_.conn.borrow().as_ref().unwrap().is_autocommit() || self_.autocommit == 0) } #[cfg(not(Py_3_12))] { @@ -372,11 +374,12 @@ impl Connection { Ok(slf) } + #[pyo3(signature = (exc_type=None, _exc_val=None, _exc_tb=None))] fn __exit__( self_: PyRef<'_, Self>, - exc_type: Option<&PyAny>, - _exc_val: Option<&PyAny>, - _exc_tb: Option<&PyAny>, + exc_type: Option<&Bound<'_, PyAny>>, + _exc_val: Option<&Bound<'_, PyAny>>, + _exc_tb: Option<&Bound<'_, PyAny>>, ) -> PyResult { if exc_type.is_none() { // Commit on clean exit @@ -404,6 +407,7 @@ pub struct Cursor { // SAFETY: The libsql crate guarantees that `Connection` is thread-safe. unsafe impl Send for Cursor {} +unsafe impl Sync for Cursor {} impl Drop for Cursor { fn drop(&mut self) { @@ -426,19 +430,21 @@ impl Cursor { Ok(()) } + #[pyo3(signature = (sql, parameters=None))] fn execute<'a>( self_: PyRef<'a, Self>, sql: String, - parameters: Option, + parameters: Option>, ) -> PyResult> { rt().block_on(async { execute(&self_, sql, parameters).await })?; Ok(self_) } + #[pyo3(signature = (sql, parameters=None))] fn executemany<'a>( self_: PyRef<'a, Self>, sql: String, - parameters: Option<&PyList>, + parameters: Option<&Bound<'_, PyList>>, ) -> PyResult> { for parameters in parameters.unwrap().iter() { let parameters = parameters.extract::()?; @@ -465,7 +471,7 @@ impl Cursor { } #[getter] - fn description(self_: PyRef<'_, Self>) -> PyResult> { + fn description(self_: PyRef<'_, Self>) -> PyResult>> { let stmt = self_.stmt.borrow(); let mut elements: Vec> = vec![]; match stmt.as_ref() { @@ -481,17 +487,18 @@ impl Cursor { self_.py().None(), self_.py().None(), ) - .to_object(self_.py()); - elements.push(element); + .into_pyobject(self_.py()) + .unwrap(); + elements.push(element.into()); } - let elements = PyTuple::new(self_.py(), elements); + let elements = PyTuple::new(self_.py(), elements)?; Ok(Some(elements)) } None => Ok(None), } } - fn fetchone(self_: PyRef<'_, Self>) -> PyResult> { + fn fetchone(self_: PyRef<'_, Self>) -> PyResult>> { let mut rows = self_.rows.borrow_mut(); match rows.as_mut() { Some(rows) => { @@ -508,7 +515,8 @@ impl Cursor { } } - fn fetchmany(self_: PyRef<'_, Self>, size: Option) -> PyResult> { + #[pyo3(signature = (size=None))] + fn fetchmany(self_: PyRef<'_, Self>, size: Option) -> PyResult>> { let mut rows = self_.rows.borrow_mut(); match rows.as_mut() { Some(rows) => { @@ -534,13 +542,13 @@ impl Cursor { } } } - Ok(Some(PyList::new(self_.py(), elements))) + Ok(Some(PyList::new(self_.py(), elements)?)) } None => Ok(None), } } - fn fetchall(self_: PyRef<'_, Self>) -> PyResult> { + fn fetchall(self_: PyRef<'_, Self>) -> PyResult>> { let mut rows = self_.rows.borrow_mut(); match rows.as_mut() { Some(rows) => { @@ -557,7 +565,7 @@ impl Cursor { None => break, } } - Ok(Some(PyList::new(self_.py(), elements))) + Ok(Some(PyList::new(self_.py(), elements)?)) } None => Ok(None), } @@ -669,36 +677,40 @@ fn stmt_is_dml(sql: &str) -> bool { sql.starts_with("INSERT") || sql.starts_with("UPDATE") || sql.starts_with("DELETE") } -fn convert_row(py: Python, row: libsql_core::Row, column_count: i32) -> PyResult<&PyTuple> { +fn convert_row( + py: Python, + row: libsql_core::Row, + column_count: i32, +) -> PyResult> { let mut elements: Vec> = vec![]; for col_idx in 0..column_count { let libsql_value = row.get_value(col_idx).map_err(to_py_err)?; let value = match libsql_value { libsql_core::Value::Integer(v) => { let value = v as i64; - value.into_py(py) + value.into_pyobject(py).unwrap().into() } - libsql_core::Value::Real(v) => v.into_py(py), - libsql_core::Value::Text(v) => v.into_py(py), + libsql_core::Value::Real(v) => v.into_pyobject(py).unwrap().into(), + libsql_core::Value::Text(v) => v.into_pyobject(py).unwrap().into(), libsql_core::Value::Blob(v) => { let value = v.as_slice(); - value.into_py(py) + value.into_pyobject(py).unwrap().into() } libsql_core::Value::Null => py.None(), }; elements.push(value); } - Ok(PyTuple::new(py, elements)) + Ok(PyTuple::new(py, elements)?) } create_exception!(libsql, Error, pyo3::exceptions::PyException); impl<'py> FromPyObject<'py> for ListOrTuple<'py> { - fn extract(ob: &'py PyAny) -> PyResult { + fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult { if let Ok(list) = ob.downcast::() { - Ok(ListOrTuple::List(list)) + Ok(ListOrTuple::List(list.clone())) } else if let Ok(tuple) = ob.downcast::() { - Ok(ListOrTuple::Tuple(tuple)) + Ok(ListOrTuple::Tuple(tuple.clone())) } else { Err(PyValueError::new_err( "Expected a list or tuple for parameters", @@ -708,19 +720,19 @@ impl<'py> FromPyObject<'py> for ListOrTuple<'py> { } impl<'py> ListOrTuple<'py> { - pub fn iter(&self) -> ListOrTupleIterator { - ListOrTupleIterator{ + pub fn iter(&self) -> ListOrTupleIterator<'py> { + ListOrTupleIterator { index: 0, - inner: self, + inner: self.clone(), } } } impl<'py> Iterator for ListOrTupleIterator<'py> { - type Item = &'py PyAny; + type Item = Bound<'py, PyAny>; fn next(&mut self) -> Option { - let rv = match self.inner { + let rv = match &self.inner { ListOrTuple::List(list) => list.get_item(self.index), ListOrTuple::Tuple(tuple) => tuple.get_item(self.index), }; @@ -732,7 +744,7 @@ impl<'py> Iterator for ListOrTupleIterator<'py> { } } #[pymodule] -fn libsql(py: Python, m: &PyModule) -> PyResult<()> { +fn libsql(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> { let _ = tracing_subscriber::fmt::try_init(); m.add("LEGACY_TRANSACTION_CONTROL", LEGACY_TRANSACTION_CONTROL)?; m.add("paramstyle", "qmark")?; From eed81abda57b1761140786a5efa0b9c8f5c821ca Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 28 Jul 2025 20:23:53 +0300 Subject: [PATCH 50/51] 0.1.7 --- Cargo.lock | 2 +- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e270f34..b5b1fee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1260,7 +1260,7 @@ dependencies = [ [[package]] name = "pylibsql" -version = "0.1.6" +version = "0.1.7" dependencies = [ "libsql", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 910a748..73f1b13 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pylibsql" -version = "0.1.6" +version = "0.1.7" edition = "2024" [lib] diff --git a/pyproject.toml b/pyproject.toml index 0f01d73..5d95e0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "libsql" -version = "0.1.6" +version = "0.1.7" requires-python = ">=3.7" classifiers = [ "Programming Language :: Rust", From 14c59886b5849dc24ef8131ab2f2e3cae11416a4 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 29 Jul 2025 13:14:04 +0300 Subject: [PATCH 51/51] github: Publish Windows package --- .github/workflows/CI.yml | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 59722b1..efad52c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -86,6 +86,31 @@ jobs: name: wheels-macos-arm64 path: dist + windows-x86_64: + runs-on: windows-latest + strategy: + matrix: + target: [x86_64] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Build wheels + uses: PyO3/maturin-action@v1 + env: + CXX: clang++ + CC: clang + with: + target: ${{ matrix.target }} + args: --release --out dist --find-interpreter + sccache: 'true' + - name: Upload wheels + uses: actions/upload-artifact@v4 + with: + name: wheels-windows-x86_64 + path: dist + sdist: runs-on: ubuntu-latest steps: @@ -105,7 +130,7 @@ jobs: name: Release runs-on: ubuntu-latest if: "startsWith(github.ref, 'refs/tags/')" - needs: [linux, macos-arm64, macos-x86_64, sdist] + needs: [linux, macos-arm64, macos-x86_64, windows-x86_64, sdist] steps: - uses: actions/download-artifact@v4 with: