Skip to content

Commit 278f310

Browse files
committed
carray doc tweaks
1 parent f3a0579 commit 278f310

4 files changed

Lines changed: 56 additions & 38 deletions

File tree

doc/changes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ It allows :meth:`binding single dimension packed arrays <apsw.carray>`
5454
of 32/64 bit integers, or 64 bit floats. For example these can come
5555
from :mod:`array`, `numpy arrays
5656
<https://numpy.org/doc/stable/reference/generated/numpy.array.html>`__
57-
or binary data.
57+
or binary data. See the :ref:`example <example_carray>`.
5858

5959
``SQLITE_SCM_`` constants (``BRANCH``, ``TAGS``, ``DATETIME``) are available
6060
on the module if built with the :attr:`amalgamation <using_amalgamation>`.

doc/extensions.rst

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,41 @@ functionality. All extensions are disabled by default and you need to
1010
:ref:`take steps <setup_build_flags>` to have them available at compilation
1111
time, to enable them and then to use them.
1212

13-
If you get APSW from PyPI or are using SQLite from your Linux/BSD platform
14-
then they all enabled usually.
13+
If you get APSW from PyPI they are all enabled. If APSW comes from
14+
your Linux/BSD platform then it will match your platform
15+
configuration.
16+
17+
CARRAY
18+
======
19+
20+
`Runtime array of values extension <https://sqlite.org/carray.html>`__ used
21+
with :meth:`apsw.carray`.
22+
23+
Session
24+
=======
25+
26+
:doc:`session`
27+
28+
Math functions
29+
==============
30+
31+
Several `SQL functions <https://sqlite.org/lang_mathfunc.html>`__
32+
33+
Percentile (media)
34+
==================
35+
36+
Several `SQL functions <https://sqlite.org/percentile.html>`__ related
37+
to `percentiles <https://en.wikipedia.org/wiki/Percentile>`__. Python
38+
has a :mod:`statistics` module with some of the same functions, but
39+
this extension is more convenient.
1540

1641
.. _ext-fts3:
1742

1843
FTS5
1944
====
2045

2146
`FTS5 <https://www.sqlite.org/fts5.html>`__ is the full text search extension.
22-
APSW includes comprehensive :doc:`functionality <textsearch>`..
47+
APSW includes comprehensive :doc:`functionality <textsearch>`.
2348

2449
.. _ext-icu:
2550

@@ -42,3 +67,4 @@ The RTree extension provides a `spatial table
4267
<https://en.wikipedia.org/wiki/R-tree>`_ - see the `documentation
4368
<https://sqlite.org/rtree.html>`__. There are no additional APIs and
4469
the `documented SQL <https://sqlite.org/rtree.html>`__ works as is.
70+

examples/main.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,13 @@
103103
# a simple value
104104
event = "system started"
105105
# DO NOT DO THIS
106-
query = f"insert into log values(0, '{ event }')"
106+
query = f"insert into log values(0, '{event}')"
107107
print("query:", query)
108108

109109
# BECAUSE ... a bad guy could provide a value like this
110110
event = "bad guy here') ; drop table important; -- comment"
111111
# which has effects like this
112-
query = f"insert into log values(0, '{ event }')"
112+
query = f"insert into log values(0, '{event}')"
113113
print("bad guy:", query)
114114

115115
### bindings_sequence: Bindings (sequence)
@@ -277,7 +277,7 @@ def row_tracer(
277277

278278
def ilove7(*args: apsw.SQLiteValue) -> int:
279279
"A scalar function"
280-
print(f"ilove7 got { args } but I love 7")
280+
print(f"ilove7 got {args} but I love 7")
281281
return 7
282282

283283

@@ -489,7 +489,7 @@ def __init__(self, x, y):
489489
self.y = y
490490

491491
def __repr__(self) -> str:
492-
return f"Point({ self.x }, { self.y })"
492+
return f"Point({self.x}, {self.y})"
493493

494494
def __eq__(self, other: object) -> bool:
495495
return (
@@ -500,7 +500,7 @@ def __eq__(self, other: object) -> bool:
500500

501501
def to_sqlite_value(self) -> str:
502502
# called to convert Point into something SQLite supports
503-
return f"{ self.x };{ self.y }"
503+
return f"{self.x};{self.y}"
504504

505505
# This converter will be registered
506506
@classmethod
@@ -510,7 +510,7 @@ def convert_from_sqlite(cls, value: str) -> Point:
510510

511511
# Existing types
512512
def complex_to_sqlite_value(c: complex) -> str:
513-
return f"{ c.real }+{ c.imag }"
513+
return f"{c.real}+{c.imag}"
514514

515515

516516
def datetime_to_sqlite_value(dt: datetime.datetime) -> float:
@@ -561,7 +561,7 @@ def sqlite_to_datetime(v: float) -> datetime.datetime:
561561
print("querying data")
562562
for row in connection.execute("select * from conversion"):
563563
for i, value in enumerate(row):
564-
print(f"column {i} = { value !r}")
564+
print(f"column {i} = {value!r}")
565565

566566
# clear registrar
567567
connection.cursor_factory = apsw.Cursor
@@ -657,7 +657,9 @@ def make_set(*args):
657657
):
658658
pass
659659

660-
print(f"After {time.monotonic() - start:.3f} seconds, we hit {number=}")
660+
print(
661+
f"After {time.monotonic() - start:.3f} seconds, we hit {number=}"
662+
)
661663

662664
# We used the default "no exception" exception. Lets have an explicit exception.
663665
# with both row and time limits ...
@@ -941,7 +943,7 @@ def my_update_hook(
941943
) -> None:
942944
op: str = apsw.mapping_authorizer_function[type]
943945
print(
944-
f"Updated: { op } db { db_name }, table { table_name }, rowid { rowid }"
946+
f"Updated: {op} db {db_name}, table {table_name}, rowid {rowid}"
945947
)
946948

947949

@@ -1191,7 +1193,7 @@ def xFileControl(self, op: int, ptr: int) -> bool:
11911193
return super().xFileControl(op, ptr)
11921194
# implement our own pragma
11931195
p = apsw.VFSFcntlPragma(ptr)
1194-
print(f"pragma received { p.name } = { p.value }")
1196+
print(f"pragma received {p.name} = {p.value}")
11951197
# what do we understand?
11961198
if p.name == "my_custom_pragma":
11971199
p.result = "orange"
@@ -1323,11 +1325,9 @@ def xFileControl(self, op: int, ptr: int) -> bool:
13231325
# for per connection statistics.
13241326

13251327
current_usage, max_usage = apsw.status(apsw.SQLITE_STATUS_MEMORY_USED)
1326-
print(f"SQLite memory usage { current_usage } max { max_usage }")
1328+
print(f"SQLite memory usage {current_usage} max {max_usage}")
13271329
schema_used, _ = connection.status(apsw.SQLITE_DBSTATUS_SCHEMA_USED)
1328-
print(
1329-
f"{ schema_used } bytes used to store schema for this connection"
1330-
)
1330+
print(f"{schema_used} bytes used to store schema for this connection")
13311331

13321332
### trace_v2: Tracing
13331333
# This shows using :meth:`Connection.trace_v2`
@@ -1424,7 +1424,9 @@ def trace_hook(trace: dict) -> None:
14241424

14251425
# pragma functions are virtual tables - see how many rows this processes even
14261426
# though only one has 'pow'
1427-
connection.execute("SELECT narg FROM pragma_function_list WHERE name='pow'").get
1427+
connection.execute(
1428+
"SELECT narg FROM pragma_function_list WHERE name='pow'"
1429+
).get
14281430

14291431
# trigger that causes rollback
14301432
connection.execute("""
@@ -1499,12 +1501,12 @@ def trace_hook(trace: dict) -> None:
14991501
# See values before change
15001502
print("Before values")
15011503
print(f'{connection.pragma("schema_version")=}')
1502-
print(f'{connection.data_version()=}')
1504+
print(f"{connection.data_version()=}")
15031505

15041506
print("\nAfter values")
15051507
# add to table from previous section
15061508
con2.execute("insert into dummy values(1, 2, 3)")
1507-
print(f'{connection.data_version()=}')
1509+
print(f"{connection.data_version()=}")
15081510

15091511
# and add a table. changing an existing table definition etc also
15101512
# bump the schema version

src/apsw.c

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -292,33 +292,21 @@ static int allow_missing_dict_bindings = 0;
292292
293293
Indicates a Python object is being provided as a runtime array for the
294294
`Carray extension <https://sqlite.org/carray.html>`__. This is useful if you
295-
need a number of numbers (int or float), strings, or blobs available during a query,
295+
need many numbers (int or float), strings, or blobs available during a query,
296296
You can avoid temporary tables, formatting SQL with corresponding numbers of ``?``,
297297
and the array will be used without calling back into Python code or acquiring the GIL.
298298
299-
.. code-block:: python
300-
301-
import array
302-
303-
# packed array of 32 bit int
304-
ids = array.array("i", [1, 73, 94567, 62])
305-
306-
# get records matching those ids
307-
for row in con.execute("SELECT * FROM record WHERE record.id IN CARRAY(?)",
308-
apsw.carray(ids)):
309-
print(row)
299+
See the :ref:`example <example_carray>`.
310300
311301
:param object: For numbers, any object that implements the buffer protocol as
312302
a single contiguous binary data like :class:`bytes`, :class:`bytearray`,
313303
:class:`array.array`, numpy.array etc.
314304
315305
Otherwise it should be a tuple of strings, or a tuple of binary data
316306
objects.
317-
318307
:param start: Index of the first entry to bind
319308
:param stop: Index to stop at - ie one beyond the last entry bound. Default
320-
is all remaining members. There is a limit of 2 billion, and a minimum
321-
of 1.
309+
is all remaining members.
322310
:param flags: Default auto detect.
323311
324312
For numbers, detection is done from the buffer
@@ -345,8 +333,10 @@ static int allow_missing_dict_bindings = 0;
345333
and :code:`apsw.SQLITE_CARRAY_BLOB` respectively, but they would be detected anyway.
346334
A wrong value will fail.
347335
348-
Carray support is only present if APSW was compiled with ``SQLITE_ENABLE_CARRAY`` such as
349-
PyPi builds.
336+
.. note::
337+
338+
Carray support is only present if APSW was compiled with ``SQLITE_ENABLE_CARRAY`` such as
339+
PyPi builds. The array must have at least one member and at most 2 billion.
350340
*/
351341

352342
/** .. method:: sqlite_lib_version() -> str

0 commit comments

Comments
 (0)