apsw-sqlite3mc 3.53.1.0__tar.gz → 3.53.3.1__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.
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/PKG-INFO +3 -2
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/README.rst +1 -1
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/__init__.pyi +41 -10
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/sqlite_extra.json +1 -9
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/tests/__main__.py +53 -22
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/tests/aiotest.py +11 -3
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/tests/extratest.py +3 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/tests/ftstests.py +8 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/tests/mctests.py +6 -1
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw_sqlite3mc.egg-info/PKG-INFO +3 -2
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/checksums +6 -1
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/setup.py +10 -5
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/sqlite3/sqlite3.c +1641 -467
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/apsw.c +76 -21
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/apsw.docstrings +16 -2
- apsw_sqlite3mc-3.53.3.1/src/apswversion.h +1 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/connection.c +50 -11
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/constants.c +4 -2
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/cursor.c +7 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/sqlite_debug.h +20 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/tools/vend.py +1 -13
- apsw_sqlite3mc-3.53.1.0/src/apswversion.h +0 -1
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/LICENSE +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/MANIFEST.in +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/__main__.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/aio.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/bestpractice.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/ext.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/fts5.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/fts5aux.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/fts5query.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/fts_test_strings +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/mcall.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/py.typed +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/shell.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/speedtest.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/sqlite_extra.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/sqlite_extra_binaries/README.md +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/tests/async_meta.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/tests/carray.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/tests/fork_checker.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/tests/jsonb.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/tests/sessiontests.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/tests/shelltest.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/trace.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw/unicode.py +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw_sqlite3mc.egg-info/SOURCES.txt +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw_sqlite3mc.egg-info/dependency_links.txt +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw_sqlite3mc.egg-info/entry_points.txt +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/apsw_sqlite3mc.egg-info/top_level.txt +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/pyproject.toml +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/setup.apsw +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/setup.cfg +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/_unicodedb.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/argparse.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/async.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/backup.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/blob.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/carray.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/exceptions.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/faultinject.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/faultinject.h +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/fileio_win32.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/fts.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/jsonb.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/pyutil.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/session.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/statementcache.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/stringconstants.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/testextension.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/traceback.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/unicode.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/util.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/vfs.c +0 -0
- {apsw_sqlite3mc-3.53.1.0 → apsw_sqlite3mc-3.53.3.1}/src/vtable.c +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: apsw_sqlite3mc
|
|
3
|
-
Version: 3.53.1
|
|
3
|
+
Version: 3.53.3.1
|
|
4
4
|
Summary: SQLite3 Multiple Ciphers combined with Another Python SQLite Wrapper
|
|
5
5
|
Home-page: https://github.com/utelle/apsw-sqlite3mc
|
|
6
6
|
Author: Ulrich Telle
|
|
@@ -24,6 +24,7 @@ Classifier: Framework :: Trio
|
|
|
24
24
|
Classifier: Framework :: AsyncIO
|
|
25
25
|
Classifier: Framework :: AnyIO
|
|
26
26
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
27
|
+
Classifier: Typing :: Typed
|
|
27
28
|
Requires-Python: >=3.10
|
|
28
29
|
Description-Content-Type: text/x-rst
|
|
29
30
|
License-File: LICENSE
|
|
@@ -89,7 +90,7 @@ Setting the key on a new database is the only change needed to your code.
|
|
|
89
90
|
|
|
90
91
|
>>> import apsw
|
|
91
92
|
>>> print(apsw.mc_version)
|
|
92
|
-
SQLite3 Multiple Ciphers 2.3.
|
|
93
|
+
SQLite3 Multiple Ciphers 2.3.6
|
|
93
94
|
>>> con = apsw.Connection("database.sqlite3")
|
|
94
95
|
>>> con.pragma("key", "my secret passphrase")
|
|
95
96
|
ok
|
|
@@ -59,7 +59,7 @@ Setting the key on a new database is the only change needed to your code.
|
|
|
59
59
|
|
|
60
60
|
>>> import apsw
|
|
61
61
|
>>> print(apsw.mc_version)
|
|
62
|
-
SQLite3 Multiple Ciphers 2.3.
|
|
62
|
+
SQLite3 Multiple Ciphers 2.3.6
|
|
63
63
|
>>> con = apsw.Connection("database.sqlite3")
|
|
64
64
|
>>> con.pragma("key", "my secret passphrase")
|
|
65
65
|
ok
|
|
@@ -1748,7 +1748,9 @@ class Connection:
|
|
|
1748
1748
|
"""If *keep* is *None* then all registered virtual tables are dropped.
|
|
1749
1749
|
|
|
1750
1750
|
Otherwise *keep* is a sequence of strings, naming the virtual tables that
|
|
1751
|
-
are kept, dropping all others.
|
|
1751
|
+
are kept, dropping all others.
|
|
1752
|
+
|
|
1753
|
+
Calls: `sqlite3_drop_modules <https://sqlite.org/c3ref/drop_modules.html>`__"""
|
|
1752
1754
|
...
|
|
1753
1755
|
|
|
1754
1756
|
def enable_load_extension(self, enable: bool) -> None:
|
|
@@ -1926,7 +1928,9 @@ class Connection:
|
|
|
1926
1928
|
...
|
|
1927
1929
|
|
|
1928
1930
|
def get_autocommit(self) -> bool:
|
|
1929
|
-
"""Returns if the Connection is in auto commit mode (ie not in a
|
|
1931
|
+
"""Returns if the Connection is in auto commit mode (ie not in a
|
|
1932
|
+
transaction). It is recommended to use :meth:`txn_state` instead
|
|
1933
|
+
which is more reliable.
|
|
1930
1934
|
|
|
1931
1935
|
Calls: `sqlite3_get_autocommit <https://sqlite.org/c3ref/get_autocommit.html>`__"""
|
|
1932
1936
|
...
|
|
@@ -1993,6 +1997,9 @@ class Connection:
|
|
|
1993
1997
|
|
|
1994
1998
|
def last_insert_rowid(self) -> int:
|
|
1995
1999
|
"""Returns the integer key of the most recent insert in the database.
|
|
2000
|
+
It is recommended to use SQL `RETURNING <https://sqlite.org/lang_returning.html>`__
|
|
2001
|
+
instead because that ensures you get the rowid directly from the
|
|
2002
|
+
SQL that made the change.
|
|
1996
2003
|
|
|
1997
2004
|
Calls: `sqlite3_last_insert_rowid <https://sqlite.org/c3ref/last_insert_rowid.html>`__"""
|
|
1998
2005
|
...
|
|
@@ -2805,6 +2812,13 @@ class Cursor:
|
|
|
2805
2812
|
- [(3, 4), (4, 5)]
|
|
2806
2813
|
* - select 3,4; select 5
|
|
2807
2814
|
- [(3, 4), 5]
|
|
2815
|
+
* - select null
|
|
2816
|
+
- None
|
|
2817
|
+
* - select 'yes' where 1=2
|
|
2818
|
+
- None
|
|
2819
|
+
|
|
2820
|
+
It is not possible to tell the difference between :code:`None`
|
|
2821
|
+
returned, versus no matching rows.
|
|
2808
2822
|
|
|
2809
2823
|
Row tracers are not called when using this method."""
|
|
2810
2824
|
|
|
@@ -4530,6 +4544,8 @@ SQLITE_CHANGESETAPPLY_INVERT: int = 2
|
|
|
4530
4544
|
"""For `Flags for sqlite3changeset_apply_v2 <https://sqlite.org/session/c_changesetapply_fknoaction.html>'__"""
|
|
4531
4545
|
SQLITE_CHANGESETAPPLY_NOSAVEPOINT: int = 1
|
|
4532
4546
|
"""For `Flags for sqlite3changeset_apply_v2 <https://sqlite.org/session/c_changesetapply_fknoaction.html>'__"""
|
|
4547
|
+
SQLITE_CHANGESETAPPLY_NOUPDATELOOP: int = 16
|
|
4548
|
+
"""For `Flags for sqlite3changeset_apply_v2 <https://sqlite.org/session/c_changesetapply_fknoaction.html>'__"""
|
|
4533
4549
|
SQLITE_CHANGESETSTART_INVERT: int = 2
|
|
4534
4550
|
"""For `Flags for sqlite3changeset_start_v2 <https://sqlite.org/session/c_changesetstart_invert.html>'__"""
|
|
4535
4551
|
SQLITE_CHANGESET_ABORT: int = 2
|
|
@@ -5563,7 +5579,8 @@ mapping_session_changeset_apply_v2_flags: dict[str | int, int | str]
|
|
|
5563
5579
|
Doc at https://sqlite.org/session/c_changesetapply_fknoaction.html
|
|
5564
5580
|
|
|
5565
5581
|
SQLITE_CHANGESETAPPLY_FKNOACTION SQLITE_CHANGESETAPPLY_IGNORENOOP
|
|
5566
|
-
SQLITE_CHANGESETAPPLY_INVERT SQLITE_CHANGESETAPPLY_NOSAVEPOINT
|
|
5582
|
+
SQLITE_CHANGESETAPPLY_INVERT SQLITE_CHANGESETAPPLY_NOSAVEPOINT
|
|
5583
|
+
SQLITE_CHANGESETAPPLY_NOUPDATELOOP"""
|
|
5567
5584
|
|
|
5568
5585
|
mapping_session_changeset_start_v2_flags: dict[str | int, int | str]
|
|
5569
5586
|
"""Flags for sqlite3changeset_start_v2 mapping names to int and int to names.
|
|
@@ -6344,7 +6361,7 @@ class AsyncConnection:
|
|
|
6344
6361
|
the first statement"""
|
|
6345
6362
|
...
|
|
6346
6363
|
|
|
6347
|
-
def changes(self) -> int:
|
|
6364
|
+
async def changes(self) -> int:
|
|
6348
6365
|
"""Returns the number of database rows that were changed (or inserted
|
|
6349
6366
|
or deleted) by the most recently completed INSERT, UPDATE, or DELETE
|
|
6350
6367
|
statement.
|
|
@@ -6667,7 +6684,9 @@ class AsyncConnection:
|
|
|
6667
6684
|
"""If *keep* is *None* then all registered virtual tables are dropped.
|
|
6668
6685
|
|
|
6669
6686
|
Otherwise *keep* is a sequence of strings, naming the virtual tables that
|
|
6670
|
-
are kept, dropping all others.
|
|
6687
|
+
are kept, dropping all others.
|
|
6688
|
+
|
|
6689
|
+
Calls: `sqlite3_drop_modules <https://sqlite.org/c3ref/drop_modules.html>`__"""
|
|
6671
6690
|
...
|
|
6672
6691
|
|
|
6673
6692
|
async def enable_load_extension(self, enable: bool) -> None:
|
|
@@ -6809,8 +6828,10 @@ class AsyncConnection:
|
|
|
6809
6828
|
* `FTS5 documentation <https://www.sqlite.org/fts5.html#custom_tokenizers>`__"""
|
|
6810
6829
|
...
|
|
6811
6830
|
|
|
6812
|
-
def get_autocommit(self) -> bool:
|
|
6813
|
-
"""Returns if the Connection is in auto commit mode (ie not in a
|
|
6831
|
+
async def get_autocommit(self) -> bool:
|
|
6832
|
+
"""Returns if the Connection is in auto commit mode (ie not in a
|
|
6833
|
+
transaction). It is recommended to use :meth:`txn_state` instead
|
|
6834
|
+
which is more reliable.
|
|
6814
6835
|
|
|
6815
6836
|
Calls: `sqlite3_get_autocommit <https://sqlite.org/c3ref/get_autocommit.html>`__"""
|
|
6816
6837
|
...
|
|
@@ -6825,7 +6846,7 @@ class AsyncConnection:
|
|
|
6825
6846
|
<Connection.row_trace>`"""
|
|
6826
6847
|
...
|
|
6827
6848
|
|
|
6828
|
-
in_transaction: bool
|
|
6849
|
+
in_transaction: Awaitable[bool]
|
|
6829
6850
|
"""It is recommended to use :meth:`txn_state` instead which is more reliable.
|
|
6830
6851
|
|
|
6831
6852
|
Calls: `sqlite3_get_autocommit <https://sqlite.org/c3ref/get_autocommit.html>`__"""
|
|
@@ -6849,8 +6870,11 @@ class AsyncConnection:
|
|
|
6849
6870
|
|
|
6850
6871
|
Calls: `sqlite3_is_interrupted <https://sqlite.org/c3ref/interrupt.html>`__"""
|
|
6851
6872
|
|
|
6852
|
-
def last_insert_rowid(self) -> int:
|
|
6873
|
+
async def last_insert_rowid(self) -> int:
|
|
6853
6874
|
"""Returns the integer key of the most recent insert in the database.
|
|
6875
|
+
It is recommended to use SQL `RETURNING <https://sqlite.org/lang_returning.html>`__
|
|
6876
|
+
instead because that ensures you get the rowid directly from the
|
|
6877
|
+
SQL that made the change.
|
|
6854
6878
|
|
|
6855
6879
|
Calls: `sqlite3_last_insert_rowid <https://sqlite.org/c3ref/last_insert_rowid.html>`__"""
|
|
6856
6880
|
...
|
|
@@ -7278,7 +7302,7 @@ class AsyncConnection:
|
|
|
7278
7302
|
Calls: `sqlite3_table_column_metadata <https://sqlite.org/c3ref/table_column_metadata.html>`__"""
|
|
7279
7303
|
...
|
|
7280
7304
|
|
|
7281
|
-
def total_changes(self) -> int:
|
|
7305
|
+
async def total_changes(self) -> int:
|
|
7282
7306
|
"""Returns the total number of database rows that have be modified,
|
|
7283
7307
|
inserted, or deleted since the database connection was opened.
|
|
7284
7308
|
|
|
@@ -7627,6 +7651,13 @@ class AsyncCursor:
|
|
|
7627
7651
|
- [(3, 4), (4, 5)]
|
|
7628
7652
|
* - select 3,4; select 5
|
|
7629
7653
|
- [(3, 4), 5]
|
|
7654
|
+
* - select null
|
|
7655
|
+
- None
|
|
7656
|
+
* - select 'yes' where 1=2
|
|
7657
|
+
- None
|
|
7658
|
+
|
|
7659
|
+
It is not possible to tell the difference between :code:`None`
|
|
7660
|
+
returned, versus no matching rows.
|
|
7630
7661
|
|
|
7631
7662
|
Row tracers are not called when using this method."""
|
|
7632
7663
|
|
|
@@ -27,10 +27,6 @@
|
|
|
27
27
|
"description": "A VFS shim that writes a checksum on each page of an SQLite database file",
|
|
28
28
|
"type": "extension"
|
|
29
29
|
},
|
|
30
|
-
"closure": {
|
|
31
|
-
"description": "A virtual table that finds the transitive closure of a parent/child relationship in a real table",
|
|
32
|
-
"type": "extension"
|
|
33
|
-
},
|
|
34
30
|
"completion": {
|
|
35
31
|
"description": "A virtual table that returns suggested completions for a partial SQL input",
|
|
36
32
|
"type": "extension"
|
|
@@ -60,7 +56,7 @@
|
|
|
60
56
|
"type": "extension"
|
|
61
57
|
},
|
|
62
58
|
"ieee754": {
|
|
63
|
-
"description": "functions for the exact display
|
|
59
|
+
"description": "functions for the exact display and input of IEEE754 Binary64 floating-point numbers",
|
|
64
60
|
"type": "extension"
|
|
65
61
|
},
|
|
66
62
|
"memstat": {
|
|
@@ -147,10 +143,6 @@
|
|
|
147
143
|
"description": "Database Remote-Copy Tool",
|
|
148
144
|
"type": "executable"
|
|
149
145
|
},
|
|
150
|
-
"sqlite3_scrub": {
|
|
151
|
-
"description": "Makes a backup zeroing out all deleted content",
|
|
152
|
-
"type": "executable"
|
|
153
|
-
},
|
|
154
146
|
"sqlite3_shell": {
|
|
155
147
|
"description": "Command line shell",
|
|
156
148
|
"type": "executable"
|
|
@@ -183,7 +183,7 @@ class BadIsTrue(int):
|
|
|
183
183
|
class ThreadRunner(threading.Thread):
|
|
184
184
|
def __init__(self, callable, *args, **kwargs):
|
|
185
185
|
threading.Thread.__init__(self)
|
|
186
|
-
self.daemon
|
|
186
|
+
self.daemon = True
|
|
187
187
|
self.callable = callable
|
|
188
188
|
self.args = args
|
|
189
189
|
self.kwargs = kwargs
|
|
@@ -234,7 +234,11 @@ def bgdel():
|
|
|
234
234
|
bgdelq = queue.Queue()
|
|
235
235
|
bgdelthread = threading.Thread(target=bgdel)
|
|
236
236
|
bgdelthread.daemon = True
|
|
237
|
-
|
|
237
|
+
try:
|
|
238
|
+
bgdelthread.start()
|
|
239
|
+
except RuntimeError:
|
|
240
|
+
# wasm build can't do this
|
|
241
|
+
pass
|
|
238
242
|
|
|
239
243
|
|
|
240
244
|
def deletefile(name):
|
|
@@ -397,7 +401,11 @@ class APSW(unittest.TestCase):
|
|
|
397
401
|
val = exc
|
|
398
402
|
|
|
399
403
|
t = threading.Thread(target=thread, daemon=True)
|
|
400
|
-
|
|
404
|
+
try:
|
|
405
|
+
t.start()
|
|
406
|
+
except RuntimeError:
|
|
407
|
+
# wasm can't start thread
|
|
408
|
+
return
|
|
401
409
|
t.join(1)
|
|
402
410
|
if val != 3:
|
|
403
411
|
raise val
|
|
@@ -3187,7 +3195,7 @@ class APSW(unittest.TestCase):
|
|
|
3187
3195
|
|
|
3188
3196
|
# for coverage
|
|
3189
3197
|
self.db.cache_flush()
|
|
3190
|
-
getattr(self.db, "
|
|
3198
|
+
getattr(self.db, "release" + "_" + "memory")() # avoids old name testing false positive
|
|
3191
3199
|
|
|
3192
3200
|
c.execute("commit")
|
|
3193
3201
|
self.assertEqual(300, self.db.total_changes())
|
|
@@ -3702,7 +3710,10 @@ class APSW(unittest.TestCase):
|
|
|
3702
3710
|
vals["stop"] = True
|
|
3703
3711
|
|
|
3704
3712
|
t = ThreadRunner(wt)
|
|
3705
|
-
|
|
3713
|
+
try:
|
|
3714
|
+
t.start()
|
|
3715
|
+
except RuntimeError:
|
|
3716
|
+
return
|
|
3706
3717
|
# ensure thread t has started
|
|
3707
3718
|
time.sleep(0.1)
|
|
3708
3719
|
b4 = time.time()
|
|
@@ -5065,7 +5076,10 @@ class APSW(unittest.TestCase):
|
|
|
5065
5076
|
db2 = apsw.Connection(self.db.filename)
|
|
5066
5077
|
db2.set_busy_timeout(30000)
|
|
5067
5078
|
t = ThreadRunner(db2.cursor().execute, "select * from foo")
|
|
5068
|
-
|
|
5079
|
+
try:
|
|
5080
|
+
t.start()
|
|
5081
|
+
except RuntimeError:
|
|
5082
|
+
return
|
|
5069
5083
|
time.sleep(1)
|
|
5070
5084
|
self.db.cursor().execute("commit")
|
|
5071
5085
|
t.go()
|
|
@@ -5181,7 +5195,10 @@ class APSW(unittest.TestCase):
|
|
|
5181
5195
|
end = time.time() + runtime
|
|
5182
5196
|
threads = [threading.Thread(target=dostuff, args=(end,)) for _ in range(20)]
|
|
5183
5197
|
for t in threads:
|
|
5184
|
-
|
|
5198
|
+
try:
|
|
5199
|
+
t.start()
|
|
5200
|
+
except RuntimeError:
|
|
5201
|
+
return
|
|
5185
5202
|
|
|
5186
5203
|
for t in threads:
|
|
5187
5204
|
t.join()
|
|
@@ -6022,20 +6039,25 @@ class APSW(unittest.TestCase):
|
|
|
6022
6039
|
f"file {filename} function {name} calls PyGILState_Ensure but does not have MakeExistingException"
|
|
6023
6040
|
)
|
|
6024
6041
|
# not further checked
|
|
6025
|
-
if
|
|
6026
|
-
"
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6042
|
+
if (
|
|
6043
|
+
name.split("_")[0]
|
|
6044
|
+
in (
|
|
6045
|
+
"ZeroBlobBind",
|
|
6046
|
+
"APSWVFS",
|
|
6047
|
+
"APSWVFSFile",
|
|
6048
|
+
"APSWBuffer",
|
|
6049
|
+
"FunctionCBInfo",
|
|
6050
|
+
"APSWFTS5Tokenizer",
|
|
6051
|
+
"cursor",
|
|
6052
|
+
"APSWChangesetIterator",
|
|
6053
|
+
"JSONB",
|
|
6054
|
+
"AwaitableWrapper",
|
|
6055
|
+
"BoxedCall",
|
|
6056
|
+
"APSWChangeset",
|
|
6057
|
+
)
|
|
6058
|
+
or name in {"apsw_no_change_repr", "convert_column_to_pyobject"}
|
|
6059
|
+
or name.split("_")[:2] == ["apsw", "module"]
|
|
6060
|
+
):
|
|
6039
6061
|
return
|
|
6040
6062
|
|
|
6041
6063
|
checks = {
|
|
@@ -7313,6 +7335,12 @@ class APSW(unittest.TestCase):
|
|
|
7313
7335
|
"Verify VFS functionality"
|
|
7314
7336
|
global testtimeout
|
|
7315
7337
|
|
|
7338
|
+
if sys.platform == "emscripten":
|
|
7339
|
+
# there is some weird issued inside this environment +
|
|
7340
|
+
# sqlite where writes aren't getting flushed before a read
|
|
7341
|
+
# which means the obfuscated database doesn't work.
|
|
7342
|
+
return
|
|
7343
|
+
|
|
7316
7344
|
testdb = vfstestdb
|
|
7317
7345
|
|
|
7318
7346
|
# some coverage related stuff
|
|
@@ -8831,7 +8859,10 @@ class APSW(unittest.TestCase):
|
|
|
8831
8859
|
|
|
8832
8860
|
runtime = float(os.getenv("APSW_HEAVY_DURATION")) if os.getenv("APSW_HEAVY_DURATION") else 30
|
|
8833
8861
|
t = ThreadRunner(wt)
|
|
8834
|
-
|
|
8862
|
+
try:
|
|
8863
|
+
t.start()
|
|
8864
|
+
except RuntimeError:
|
|
8865
|
+
return
|
|
8835
8866
|
b4 = time.time()
|
|
8836
8867
|
# try to get concurrency error
|
|
8837
8868
|
try:
|
|
@@ -69,7 +69,10 @@ class Async(unittest.TestCase):
|
|
|
69
69
|
res.append(apsw.async_run_coro)
|
|
70
70
|
|
|
71
71
|
t = threading.Thread(target=check)
|
|
72
|
-
|
|
72
|
+
try:
|
|
73
|
+
t.start()
|
|
74
|
+
except RuntimeError:
|
|
75
|
+
return
|
|
73
76
|
t.join()
|
|
74
77
|
|
|
75
78
|
self.assertEqual(res, [None])
|
|
@@ -1331,7 +1334,12 @@ class Async(unittest.TestCase):
|
|
|
1331
1334
|
|
|
1332
1335
|
for fn in self.get_all_atests():
|
|
1333
1336
|
with self.subTest(fw="asyncio", fn=fn):
|
|
1334
|
-
|
|
1337
|
+
try:
|
|
1338
|
+
asyncio.run(self.asyncTearDown(fn("asyncio")), debug=False)
|
|
1339
|
+
except RuntimeError as exc:
|
|
1340
|
+
if "can't start new thread" in str(exc):
|
|
1341
|
+
return
|
|
1342
|
+
raise
|
|
1335
1343
|
|
|
1336
1344
|
def testTrio(self):
|
|
1337
1345
|
import importlib.metadata
|
|
@@ -1408,7 +1416,7 @@ class Async(unittest.TestCase):
|
|
|
1408
1416
|
def testNoIO(self):
|
|
1409
1417
|
"no async running"
|
|
1410
1418
|
self.assertRaisesRegex(
|
|
1411
|
-
RuntimeError, "Unable to determine current Async environment", apsw.Connection.as_async, ""
|
|
1419
|
+
RuntimeError, "(Unable to determine current Async environment|can't start new thread)", apsw.Connection.as_async, ""
|
|
1412
1420
|
)
|
|
1413
1421
|
|
|
1414
1422
|
|
|
@@ -512,6 +512,10 @@ class FTS(unittest.TestCase):
|
|
|
512
512
|
|
|
513
513
|
def testCLI(self):
|
|
514
514
|
"Test command line interface"
|
|
515
|
+
|
|
516
|
+
if sys.platform == "emscripten":
|
|
517
|
+
return
|
|
518
|
+
|
|
515
519
|
if coverage_run:
|
|
516
520
|
cov_params = ["-m", "coverage", "run", "--source", "apsw", "-p"]
|
|
517
521
|
env = os.environ.copy()
|
|
@@ -2243,6 +2247,10 @@ class Unicode(unittest.TestCase):
|
|
|
2243
2247
|
|
|
2244
2248
|
def testCLI(self):
|
|
2245
2249
|
"Exercise command line interface"
|
|
2250
|
+
|
|
2251
|
+
if sys.platform == "emscripten":
|
|
2252
|
+
return
|
|
2253
|
+
|
|
2246
2254
|
text = ""
|
|
2247
2255
|
for codepoints in self.cat_examples.values():
|
|
2248
2256
|
# surrogates not allowed
|
|
@@ -122,7 +122,12 @@ class MultipleCiphers(unittest.TestCase):
|
|
|
122
122
|
time.sleep(0.5)
|
|
123
123
|
self.db.execute("end")
|
|
124
124
|
|
|
125
|
-
threading.Thread(target=busy)
|
|
125
|
+
t = threading.Thread(target=busy)
|
|
126
|
+
try:
|
|
127
|
+
t.start()
|
|
128
|
+
except RuntimeError:
|
|
129
|
+
# wasm can't start thread
|
|
130
|
+
return
|
|
126
131
|
|
|
127
132
|
self.assertRaises(apsw.BusyError, apply_encryption, con2, key="hello world")
|
|
128
133
|
con2.set_busy_timeout(1000)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: apsw-sqlite3mc
|
|
3
|
-
Version: 3.53.1
|
|
3
|
+
Version: 3.53.3.1
|
|
4
4
|
Summary: SQLite3 Multiple Ciphers combined with Another Python SQLite Wrapper
|
|
5
5
|
Home-page: https://github.com/utelle/apsw-sqlite3mc
|
|
6
6
|
Author: Ulrich Telle
|
|
@@ -24,6 +24,7 @@ Classifier: Framework :: Trio
|
|
|
24
24
|
Classifier: Framework :: AsyncIO
|
|
25
25
|
Classifier: Framework :: AnyIO
|
|
26
26
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
27
|
+
Classifier: Typing :: Typed
|
|
27
28
|
Requires-Python: >=3.10
|
|
28
29
|
Description-Content-Type: text/x-rst
|
|
29
30
|
License-File: LICENSE
|
|
@@ -89,7 +90,7 @@ Setting the key on a new database is the only change needed to your code.
|
|
|
89
90
|
|
|
90
91
|
>>> import apsw
|
|
91
92
|
>>> print(apsw.mc_version)
|
|
92
|
-
SQLite3 Multiple Ciphers 2.3.
|
|
93
|
+
SQLite3 Multiple Ciphers 2.3.6
|
|
93
94
|
>>> con = apsw.Connection("database.sqlite3")
|
|
94
95
|
>>> con.pragma("key", "my secret passphrase")
|
|
95
96
|
ok
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
# way.
|
|
10
10
|
|
|
11
11
|
# These are used too compile sqlite extra
|
|
12
|
+
https://sqlite.org/vec1/zip/vec1-20260526165101-762865e44d.zip 152789 977b062b7f1a15756fb428676d3425a57e3c84dc254cb104cb7ff31f642ede1c a332720cdebb74739b01c53187c6487b9c143c5cca45d863ef80c36e2683a0ba
|
|
12
13
|
https://sqlite.org/vec1/zip/vec1-20260505104119-eb38e10fef.zip 149803 b37509b229a393a387f3f4f352529dcf10cc3ebdbb2c75fa062763d4fdd0953b ceb3aa3699c378872e88b06b237e94eec9e545ffc1abe7388f521a107ec50699
|
|
13
14
|
https://sqlite.org/vec1/zip/vec1-20260409204746-4b73767df0.zip 119674 952af14601531b527a497df81d038a2693c1a39dba2d76ed798c3e5ba3dd7c22 55e2d7e05da20b7eb4abbe77688bdff4662a6f4f248f6710e7d2b605d3c90107
|
|
14
15
|
https://sqlite.org/vec1/zip/vec1-20260330201854-5b7c141049.zip 107146 099acc5f1eee719cae16d4843e904bba432cda9ce43d1cefb756f6566462d9f5 1c3e4264a416d68209ea37139c7e0ad42fcee4f66c021c8f495cce9882bc71e3
|
|
@@ -17,9 +18,13 @@ https://sqlite.org/vec1/zip/vec1-20260306155250-d070184523.zip 75980 6a58eebbe1e
|
|
|
17
18
|
https://sqlite.org/sqlar/zip/sqlar-src-20180107193712-4824e73896.zip 1980460 63bc4b3459fd00498f161d87d8b4516a581278da900001af183486458396806c c7b6a21b58e7499b7c3e36f26b7fafe44ddbd85097b37d905d72ccf5ff3e7cb8
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
https://
|
|
21
|
+
https://github.com/madler/zlib/releases/download/v1.3.2/zlib132.zip 1616754 e8bf55f3017aa181690990cb58a994e77885da140609fc8f94abe9b65d2cae28 6b35b981f73425dc5f142cbee457f078d42240c022c804982849b962f1d1e2c6
|
|
21
22
|
|
|
22
23
|
# SQLite releases
|
|
24
|
+
https://sqlite.org/2026/sqlite-autoconf-3530300.tar.gz 3282443 c917d7db16648ec95f714974ace5e5dcf46b7dc70e26600a0a102a3141125db0 98f2b3f3c11be6a03ea32346937b032c2472ebbd7a716bed36ca2f5693e7ce8b
|
|
25
|
+
https://sqlite.org/2026/sqlite-src-3530300.zip 14537772 bb80bf8a3bffc19241ce8aba5a4bc74e9c3980013cb0b5f0f0976a99516942af 2daecfa16e3b19e058dc2e2cb717b80ade361e0315aa5376c3619f66aa81e181
|
|
26
|
+
https://sqlite.org/2026/sqlite-autoconf-3530200.tar.gz 3279926 588ad51949419a56ebe81fe56193d510c559eb94c9a57748387860b5d3069316 025328da165109f48abccc6e7478508060804412bed2bd81d47e98ba1b72983b
|
|
27
|
+
https://sqlite.org/2026/sqlite-src-3530200.zip 14527073 cafff764c03f6d720968f746e2f47a986bbf12bf4c18904f1eb131c0b0b592d3 490ec7af32a6bfa5f3e05dc279c04286cfe3f328def4a8b7344e3fa20be18a4c
|
|
23
28
|
https://sqlite.org/2026/sqlite-autoconf-3530100.tar.gz 3275272 83e6b2020a034e9a7ad4a72feea59e1ad52f162e09cbd26735a3ffb98359fc4f 36ca143645cf76997d07b66e9244c636b8ccdec64a1d50558259c4e415e6558b
|
|
24
29
|
https://sqlite.org/2026/sqlite-src-3530100.zip 14515734 1b2b5755d9064c4d5d1b0bf5307b48b089963e291c40cc7351318aa1b61c460e 27cfc9264b2188fd17f811a8c03424eb65391c2ef9874cbfc860ea25f4322363
|
|
25
30
|
https://sqlite.org/2026/sqlite-autoconf-3530000.tar.gz 3274709 851e9b38192fe2ceaa65e0baa665e7fa06230c3d9bd1a6a9662d02380d73365a 60c4b08c6729761e488d185e0d52411da10b14c72b53ada6936dc5eea225cefe
|
|
@@ -306,7 +306,7 @@ class fetch(Command):
|
|
|
306
306
|
for desc, url, replace in (
|
|
307
307
|
(
|
|
308
308
|
"experimental vec1 extension source",
|
|
309
|
-
"https://sqlite.org/vec1/zip/vec1-
|
|
309
|
+
"https://sqlite.org/vec1/zip/vec1-20260526165101-762865e44d.zip",
|
|
310
310
|
"sqlite3/vec1",
|
|
311
311
|
),
|
|
312
312
|
(
|
|
@@ -316,7 +316,7 @@ class fetch(Command):
|
|
|
316
316
|
),
|
|
317
317
|
(
|
|
318
318
|
"zlib source",
|
|
319
|
-
"https://
|
|
319
|
+
"https://github.com/madler/zlib/releases/download/v1.3.2/zlib132.zip",
|
|
320
320
|
"sqlite3/zlib",
|
|
321
321
|
),
|
|
322
322
|
):
|
|
@@ -359,7 +359,9 @@ class fetch(Command):
|
|
|
359
359
|
val = sysconfig.get_config_var(v)
|
|
360
360
|
if val:
|
|
361
361
|
env[v] = val
|
|
362
|
-
|
|
362
|
+
# configure failing to run is ignored - this happens with
|
|
363
|
+
# linux host doing emscripten etc
|
|
364
|
+
subprocess.call(["./configure"], cwd="sqlite3", env=env)
|
|
363
365
|
|
|
364
366
|
|
|
365
367
|
# We allow enable/omit to be specified to build and then pass them to build_ext
|
|
@@ -406,7 +408,7 @@ class apsw_build(bparent):
|
|
|
406
408
|
|
|
407
409
|
def run(self):
|
|
408
410
|
# this has to be done first ...
|
|
409
|
-
if all(pathlib.Path(f).exists() for f in ("sqlite3/tool/dbtotxt.c", "sqlite3/ext/misc/
|
|
411
|
+
if all(pathlib.Path(f).exists() for f in ("sqlite3/tool/dbtotxt.c", "sqlite3/ext/misc/unionvtab.c")):
|
|
410
412
|
# Call into vend which we can't import so do something similar
|
|
411
413
|
vend = types.ModuleType("vend")
|
|
412
414
|
sys.modules["vend"] = vend
|
|
@@ -893,12 +895,14 @@ def download(url: str, checksum: bool = True, missing_checksum_ok: bool = False)
|
|
|
893
895
|
cache_name = cache_dir / file_name
|
|
894
896
|
if cache_name.exists():
|
|
895
897
|
try:
|
|
896
|
-
if abs(time.time() - cache_name.stat().st_mtime) < 7 *24 * 60 * 60:
|
|
898
|
+
if abs(time.time() - cache_name.stat().st_mtime) < 7 * 24 * 60 * 60:
|
|
897
899
|
page = (cache_dir / file_name).read_bytes()
|
|
898
900
|
write(" Cached", url)
|
|
899
901
|
if checksum:
|
|
900
902
|
verifyurl(url, page, missing_checksum_ok)
|
|
901
903
|
return io.BytesIO(page)
|
|
904
|
+
# remove stale file
|
|
905
|
+
cache_name.unlink()
|
|
902
906
|
except Exception:
|
|
903
907
|
# many things could go wrong in the above including being
|
|
904
908
|
# unable to stat, unable to read etc, so we fallback to a
|
|
@@ -1019,6 +1023,7 @@ if __name__ == "__main__":
|
|
|
1019
1023
|
"Framework :: AsyncIO",
|
|
1020
1024
|
"Framework :: AnyIO",
|
|
1021
1025
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
1026
|
+
"Typing :: Typed",
|
|
1022
1027
|
],
|
|
1023
1028
|
keywords=["database", "sqlite", "encryption"],
|
|
1024
1029
|
license="OSI Approved",
|