- [Source](https://github.com/rogerbinns/apsw/releases/download/3.47.0.0/apsw-3.47.0.0.zip)
- [Install](https://rogerbinns.github.io/apsw/install.html)
- [Changelogs](https://rogerbinns.github.io/apsw/changes.html)
- [Documentation](https://rogerbinns.github.io/apsw/)
Support for Python 3.8 removed ([APSW issue 539](https://github.com/rogerbinns/apsw/issues/539)).
The readonly database statistics virtual table ([dbstat](https://www.sqlite.org/dbstat.html)) is enabled by default for PyPI builds, and when --enable-all-extensions is passed to manual [builds](https://rogerbinns.github.io/apsw/install.html#build).
Added [recursive triggers](https://rogerbinns.github.io/apsw/bestpractice.html#apsw.bestpractice.connection_recursive_triggers) and [optimize](https://rogerbinns.github.io/apsw/bestpractice.html#apsw.bestpractice.connection_optimize) to [apsw.bestpractice](https://rogerbinns.github.io/apsw/bestpractice.html#module-apsw.bestpractice).
Multiple callbacks can be present for [Connection.trace_v2()](https://rogerbinns.github.io/apsw/connection.html#apsw.Connection.trace_v2) with APSW ensuring they are all called ([APSW issue 502](https://github.com/rogerbinns/apsw/issues/502))
[Connection.trace_v2()](https://rogerbinns.github.io/apsw/connection.html#apsw.Connection.trace_v2) callback information now has trigger, id, and total_changes fields.
Added [Connection.data_version](https://rogerbinns.github.io/apsw/connection.html#apsw.Connection.data_version) for getting a change counter. [pragma data_version](https://sqlite.org/pragma.html#pragma_data_version) doesn’t update when changes are made on the same connection, only others.
Added [apsw.ext.ShowResourceUsage()](https://rogerbinns.github.io/apsw/ext.html#apsw.ext.ShowResourceUsage) for getting resource and SQLite usage in a context block, and also use it for the shell [timer](https://rogerbinns.github.io/apsw/shell.html#shell-cmd-timer) command.
Added [apsw.ext.Trace()](https://rogerbinns.github.io/apsw/ext.html#apsw.ext.Trace) for tracing SQL execution, row and change counting, and timing per statement for use in a context block.
Added [FTS5 support](https://rogerbinns.github.io/apsw/textsearch.html) including registering and calling tokenizers, and auxiliary functions. The [apsw.fts5](https://rogerbinns.github.io/apsw/textsearch.html#module-apsw.fts5) module provides many additional classes and methods for working with FTS5, including tokenizers for HTML, JSON, regular expressions, support tokenizers for synonyms, stop words, transformers, and a [Table](https://rogerbinns.github.io/apsw/textsearch.html#apsw.fts5.Table) class that wraps access to a FTS5 table (including [creating one](https://rogerbinns.github.io/apsw/textsearch.html#apsw.fts5.Table.create)) with [search()](https://rogerbinns.github.io/apsw/textsearch.html#apsw.fts5.Table.search), [more_like()](https://rogerbinns.github.io/apsw/textsearch.html#apsw.fts5.Table.more_like), and [query_suggest()](https://rogerbinns.github.io/apsw/textsearch.html#apsw.fts5.Table.query_suggest). [apsw.fts5query](https://rogerbinns.github.io/apsw/textsearch.html#module-apsw.fts5query) can parse, modify, and reconstruct queries. The shell gets a [ftsq](https://rogerbinns.github.io/apsw/shell.html#shell-cmd-ftsq) command for issuing queries.
Added [apsw.unicode](https://rogerbinns.github.io/apsw/textsearch.html#module-apsw.unicode) which implements Unicode algorithms for determining codepoint groups making up a user perceived character, word and sentence splitting, and where line breaks can be made. These are used to make provided FTS5 tokenizers and auxiliary functions fully Unicode aware. There are many additional methods such as getting categories, stripping diacritics, case folding, width when output to a terminal, text wrapping, and more.
[apsw.ext.format_query_table()](https://rogerbinns.github.io/apsw/ext.html#apsw.ext.format_query_table) uses [apsw.unicode](https://rogerbinns.github.io/apsw/textsearch.html#module-apsw.unicode) to get widths and line breaks more accurate. As a side effect it loses the word_wrap parameter (breaking change).