aiolibsql 0.2.2__tar.gz → 0.2.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. aiolibsql-0.2.7/.github/workflows/wheels.yml +86 -0
  2. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/Cargo.lock +1 -1
  3. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/Cargo.toml +1 -1
  4. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/PKG-INFO +1 -1
  5. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/cli_test.py +13 -1
  6. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/pyproject.toml +1 -1
  7. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/src/lib.rs +50 -19
  8. aiolibsql-0.2.2/.github/workflows/CI.yml +0 -151
  9. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/.github/workflows/pr-tests.yml +0 -0
  10. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/.gitignore +0 -0
  11. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/CONTRIBUTING.md +0 -0
  12. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/LICENSE.md +0 -0
  13. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/README.md +0 -0
  14. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/aiolibsql_sqlalchemy.py +0 -0
  15. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/build.rs +0 -0
  16. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/docs/api.md +0 -0
  17. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/example.py +0 -0
  18. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/batch/.gitignore +0 -0
  19. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/batch/README.md +0 -0
  20. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/batch/main.py +0 -0
  21. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/encryption/.gitignore +0 -0
  22. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/encryption/README.md +0 -0
  23. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/encryption/main.py +0 -0
  24. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/execute_script.py +0 -0
  25. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/local/.gitignore +0 -0
  26. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/local/README.md +0 -0
  27. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/local/main.py +0 -0
  28. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/memory/README.md +0 -0
  29. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/memory/main.py +0 -0
  30. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/remote/README.md +0 -0
  31. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/remote/main.py +0 -0
  32. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/remote_connect.py +0 -0
  33. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/sqlalchemy/dialect.py +0 -0
  34. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/sqlalchemy/example.py +0 -0
  35. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/statements.sql +0 -0
  36. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/sync/.gitignore +0 -0
  37. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/sync/README.md +0 -0
  38. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/sync/main.py +0 -0
  39. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/sync_write.py +0 -0
  40. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/transaction/.gitignore +0 -0
  41. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/transaction/README.md +0 -0
  42. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/transaction/main.py +0 -0
  43. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/vector/.gitignore +0 -0
  44. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/vector/README.md +0 -0
  45. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/vector/main.py +0 -0
  46. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/examples/vector.py +0 -0
  47. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/perf-libsql.py +0 -0
  48. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/perf-sqlite3.py +0 -0
  49. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/shell.nix +0 -0
  50. {aiolibsql-0.2.2 → aiolibsql-0.2.7}/tests/test_suite.py +0 -0
@@ -0,0 +1,86 @@
1
+ name: Build Wheels
2
+
3
+ on:
4
+ push:
5
+ tags: ['v*']
6
+ workflow_dispatch: # Manual trigger from GitHub UI
7
+
8
+ jobs:
9
+ build:
10
+ name: Build ${{ matrix.target }} (${{ matrix.os }})
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ include:
15
+ # Linux x86_64
16
+ - os: ubuntu-latest
17
+ target: x86_64-unknown-linux-gnu
18
+ manylinux: auto
19
+ # Linux aarch64 (ARM)
20
+ - os: ubuntu-latest
21
+ target: aarch64-unknown-linux-gnu
22
+ use_qemu: true
23
+ manylinux: manylinux_2_28
24
+ # Windows x64
25
+ - os: windows-latest
26
+ target: x86_64-pc-windows-msvc
27
+ manylinux: auto
28
+ # macOS x86_64 (Intel) — cross-compile on macos-14
29
+ - os: macos-14
30
+ target: x86_64-apple-darwin
31
+ manylinux: auto
32
+ # macOS aarch64 (Apple Silicon)
33
+ - os: macos-latest
34
+ target: aarch64-apple-darwin
35
+ manylinux: auto
36
+
37
+ runs-on: ${{ matrix.os }}
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+
41
+ - name: Set up QEMU (for aarch64)
42
+ if: matrix.use_qemu
43
+ uses: docker/setup-qemu-action@v3
44
+ with:
45
+ platforms: arm64
46
+
47
+ - uses: actions/setup-python@v5
48
+ with:
49
+ python-version: |
50
+ 3.10
51
+ 3.11
52
+ 3.12
53
+ 3.13
54
+
55
+ - name: Build wheels
56
+ uses: PyO3/maturin-action@v1
57
+ with:
58
+ target: ${{ matrix.target }}
59
+ args: --release --out dist --interpreter 3.10 3.11 3.12 3.13
60
+ manylinux: ${{ matrix.manylinux }}
61
+
62
+ - name: Upload wheels
63
+ uses: actions/upload-artifact@v4
64
+ with:
65
+ name: wheels-${{ matrix.target }}
66
+ path: dist/*.whl
67
+
68
+ # Combine all wheels into one download
69
+ collect:
70
+ name: Collect all wheels
71
+ needs: build
72
+ runs-on: ubuntu-latest
73
+ steps:
74
+ - uses: actions/download-artifact@v4
75
+ with:
76
+ path: dist
77
+ pattern: wheels-*
78
+ merge-multiple: true
79
+
80
+ - name: List wheels
81
+ run: ls -lh dist/
82
+
83
+ - uses: actions/upload-artifact@v4
84
+ with:
85
+ name: all-wheels
86
+ path: dist/*.whl
@@ -1224,7 +1224,7 @@ dependencies = [
1224
1224
 
1225
1225
  [[package]]
1226
1226
  name = "pylibsql"
1227
- version = "0.2.2"
1227
+ version = "0.2.7"
1228
1228
  dependencies = [
1229
1229
  "libsql",
1230
1230
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "pylibsql"
3
- version = "0.2.2"
3
+ version = "0.2.7"
4
4
  edition = "2024"
5
5
  readme = "README.md"
6
6
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiolibsql
3
- Version: 0.2.2
3
+ Version: 0.2.7
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Framework :: AsyncIO
@@ -332,8 +332,15 @@ async def main():
332
332
 
333
333
  print("\n── ConnectionPool API ──")
334
334
 
335
+ import tempfile, os
336
+ pool_db = os.path.join(tempfile.gettempdir(), "aiolibsql_test_pool.db")
337
+ # Clean up any leftover test DB
338
+ for suffix in ("", "-wal", "-shm"):
339
+ try: os.remove(pool_db + suffix)
340
+ except FileNotFoundError: pass
341
+
335
342
  try:
336
- pool = await aiolibsql.create_pool(":memory:", size=5)
343
+ pool = await aiolibsql.create_pool(pool_db, size=5)
337
344
  report("create_pool()", True, "pool initialized with size=5")
338
345
  except Exception as e:
339
346
  report("create_pool()", False, str(e))
@@ -390,6 +397,11 @@ async def main():
390
397
  except Exception as e:
391
398
  report("pool.close()", False, str(e))
392
399
 
400
+ # Clean up temp pool DB
401
+ for suffix in ("", "-wal", "-shm"):
402
+ try: os.remove(pool_db + suffix)
403
+ except FileNotFoundError: pass
404
+
393
405
  print("\n── Module Constants ──")
394
406
 
395
407
  try:
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "aiolibsql"
7
- version = "0.2.2"
7
+ version = "0.2.7"
8
8
  description = "A fully asynchronous Python wrapper for libSQL, built with Rust and PyO3"
9
9
  requires-python = ">=3.8"
10
10
  license = {text = "MIT"}
@@ -11,7 +11,7 @@ use pyo3_async_runtimes::tokio::future_into_py;
11
11
 
12
12
 
13
13
  const LEGACY_TRANSACTION_CONTROL: i32 = -1;
14
- const VERSION: &str = "0.2.2";
14
+ const VERSION: &str = "0.2.7";
15
15
 
16
16
  enum ListOrTuple {
17
17
  List(Py<PyList>),
@@ -694,28 +694,59 @@ pub struct PoolCursor {
694
694
 
695
695
  #[pymethods]
696
696
  impl PoolCursor {
697
- fn fetchone<'py>(&self, py: Python<'py>) -> PyResult<PyObject> {
698
- let pos = self.pos.fetch_add(1, Ordering::SeqCst);
699
- let guard = self.rows.blocking_lock();
700
- if pos < guard.len() {
701
- if let Some(row) = &guard[pos] {
702
- return Ok(row.clone_ref(py));
697
+ fn fetchone<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
698
+ let rows = self.rows.clone();
699
+ let pos = self.pos.clone();
700
+ future_into_py(py, async move {
701
+ let p = pos.fetch_add(1, Ordering::SeqCst);
702
+ let guard = rows.lock().await;
703
+ if p < guard.len() {
704
+ if let Some(row) = &guard[p] {
705
+ return Python::with_gil(|py| Ok(row.clone_ref(py)));
706
+ }
703
707
  }
704
- }
705
- Ok(py.None())
708
+ Ok(Python::with_gil(|py| py.None()))
709
+ })
706
710
  }
707
711
 
708
- fn fetchall<'py>(&self, py: Python<'py>) -> PyResult<PyObject> {
709
- let pos = self.pos.load(Ordering::SeqCst);
710
- let guard = self.rows.blocking_lock();
711
- let mut result = vec![];
712
- for i in pos..guard.len() {
713
- if let Some(row) = &guard[i] {
714
- result.push(row.clone_ref(py));
712
+ fn fetchall<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
713
+ let rows = self.rows.clone();
714
+ let pos = self.pos.clone();
715
+ future_into_py(py, async move {
716
+ let p = pos.load(Ordering::SeqCst);
717
+ let guard = rows.lock().await;
718
+ let mut result = vec![];
719
+ for i in p..guard.len() {
720
+ if let Some(row) = &guard[i] {
721
+ Python::with_gil(|py| result.push(row.clone_ref(py)));
722
+ }
715
723
  }
716
- }
717
- self.pos.store(guard.len(), Ordering::SeqCst);
718
- Ok(PyList::new(py, result)?.unbind().into_any())
724
+ pos.store(guard.len(), Ordering::SeqCst);
725
+ Python::with_gil(|py| {
726
+ Ok(PyList::new(py, result)?.unbind().into_any())
727
+ })
728
+ })
729
+ }
730
+ #[pyo3(signature = (size=None))]
731
+ fn fetchmany<'py>(&self, py: Python<'py>, size: Option<usize>) -> PyResult<Bound<'py, PyAny>> {
732
+ let rows = self.rows.clone();
733
+ let pos = self.pos.clone();
734
+ let size = size.unwrap_or(1);
735
+ future_into_py(py, async move {
736
+ let p = pos.load(Ordering::SeqCst);
737
+ let guard = rows.lock().await;
738
+ let mut result = vec![];
739
+ let end = std::cmp::min(p + size, guard.len());
740
+ for i in p..end {
741
+ if let Some(row) = &guard[i] {
742
+ Python::with_gil(|py| result.push(row.clone_ref(py)));
743
+ }
744
+ }
745
+ pos.store(end, Ordering::SeqCst);
746
+ Python::with_gil(|py| {
747
+ Ok(PyList::new(py, result)?.unbind().into_any())
748
+ })
749
+ })
719
750
  }
720
751
 
721
752
  #[getter]
@@ -1,151 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
- tags:
8
- - v*
9
- pull_request:
10
- workflow_dispatch:
11
-
12
- permissions:
13
- contents: read
14
-
15
- jobs:
16
- linux:
17
- runs-on: ubuntu-latest
18
- strategy:
19
- matrix:
20
- target: [x86_64]
21
- steps:
22
- - uses: actions/checkout@v3
23
- - uses: actions/setup-python@v4
24
- with:
25
- python-version: '3.10'
26
- - name: Build wheels
27
- uses: PyO3/maturin-action@v1
28
- with:
29
- target: ${{ matrix.target }}
30
- args: --release --out dist --find-interpreter
31
- sccache: 'true'
32
- manylinux: auto
33
- - name: Upload wheels
34
- uses: actions/upload-artifact@v4
35
- with:
36
- name: wheels-linux-${{ matrix.target }}
37
- path: dist
38
-
39
- macos-x86_64:
40
- runs-on: macos-13
41
- strategy:
42
- matrix:
43
- target: [x86_64]
44
- steps:
45
- - uses: actions/checkout@v3
46
- - uses: actions/setup-python@v4
47
- with:
48
- python-version: '3.10'
49
- - name: Build wheels
50
- uses: PyO3/maturin-action@v1
51
- env:
52
- CXX: clang++
53
- CC: clang
54
- with:
55
- target: ${{ matrix.target }}
56
- args: --release --out dist --find-interpreter
57
- sccache: 'true'
58
- - name: Upload wheels
59
- uses: actions/upload-artifact@v4
60
- with:
61
- name: wheels-macos-x86_64
62
- path: dist
63
-
64
- macos-arm64:
65
- runs-on: macos-13-xlarge
66
- strategy:
67
- matrix:
68
- target: [aarch64]
69
- steps:
70
- - uses: actions/checkout@v3
71
- - uses: actions/setup-python@v4
72
- env:
73
- CXX: clang++
74
- CC: clang
75
- with:
76
- python-version: '3.10'
77
- - name: Build wheels
78
- uses: PyO3/maturin-action@v1
79
- with:
80
- target: ${{ matrix.target }}
81
- args: --release --out dist --find-interpreter
82
- sccache: 'true'
83
- - name: Upload wheels
84
- uses: actions/upload-artifact@v4
85
- with:
86
- name: wheels-macos-arm64
87
- path: dist
88
-
89
- windows-x86_64:
90
- runs-on: windows-latest
91
- strategy:
92
- matrix:
93
- target: [x86_64]
94
- steps:
95
- - uses: actions/checkout@v3
96
- - uses: actions/setup-python@v4
97
- with:
98
- python-version: '3.10'
99
- - name: Build wheels
100
- uses: PyO3/maturin-action@v1
101
- env:
102
- CXX: clang++
103
- CC: clang
104
- with:
105
- target: ${{ matrix.target }}
106
- args: --release --out dist --find-interpreter
107
- sccache: 'true'
108
- - name: Upload wheels
109
- uses: actions/upload-artifact@v4
110
- with:
111
- name: wheels-windows-x86_64
112
- path: dist
113
-
114
- sdist:
115
- runs-on: ubuntu-latest
116
- steps:
117
- - uses: actions/checkout@v3
118
- - name: Build sdist
119
- uses: PyO3/maturin-action@v1
120
- with:
121
- command: sdist
122
- args: --out dist
123
- - name: Upload sdist
124
- uses: actions/upload-artifact@v4
125
- with:
126
- name: sdist
127
- path: dist
128
-
129
- release:
130
- name: Release
131
- runs-on: ubuntu-latest
132
- if: "startsWith(github.ref, 'refs/tags/')"
133
- needs: [linux, macos-arm64, macos-x86_64, windows-x86_64, sdist]
134
- steps:
135
- - uses: actions/download-artifact@v4
136
- with:
137
- pattern: wheels-*
138
- path: dist
139
- merge-multiple: true
140
- - uses: actions/download-artifact@v4
141
- with:
142
- name: sdist
143
- path: dist
144
- - name: Publish to PyPI
145
- uses: PyO3/maturin-action@v1
146
- env:
147
- MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
148
- with:
149
- command: upload
150
- args: --skip-existing dist/*
151
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes