SQLite DB
Implementations to make access to SQLite databases a little more convenient.
SQLiteAppl
: Abstract class with which DB applications can be implemented.
SQLiteProperties:
: Class to manage properties stored in a database.
Examplarical implementations based on SQLiteAppl:
searx.cache.ExpireCacheSQLite :
: Cache that manages key/value pairs in a SQLite DB, in which the key/value
pairs are deleted after an “expire” time. This type of cache is used, for
example, for the engines, see searx.enginelib.EngineCache.
searx.favicons.cache.FaviconCacheSQLite :
: Favicon cache that manages the favicon BLOBs in a SQLite DB.
class searx.sqlitedb.DBSession(app: SQLiteAppl)[source] : A thead-local DB session
classmethod get\_connect(*app: [SQLiteAppl](#searx.sqlitedb.SQLiteAppl)*) → [Connection](https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection)[[source]](https://docs.searxng.org/_modules/searx/sqlitedb.html#DBSession.get_connect)
: Returns a thread local DB connection. The connection is only
established once per thread.
class searx.sqlitedb.SQLiteAppl(db_url: str)[source]
: Abstract base class for implementing convenient DB access in SQLite
applications. In the constructor, a SQLiteProperties instance is
already aggregated under self.properties.
DB\_SCHEMA: [int](https://docs.python.org/3/builtins/functions.html#int) = 1
: As soon as changes are made to the DB schema, the version number must be
increased. Changes to the version number require the DB to be recreated (or
migrated / if an migration path exists and is implemented).
SQLITE\_THREADING\_MODE: [str](https://docs.python.org/3/builtins/stdtypes.html#str) = 'serialized'
: Threading mode of the SQLite library. Depends on the options used at
compile time and is different for different distributions and architectures.
Possible values are 0:`single-thread`, 1:`multi-thread`,
3:`serialized` (see [`sqlite3.threadsafety`](https://docs.python.org/3/library/sqlite3.html#sqlite3.threadsafety)). Pre- Python 3.11
this value was hard coded to 1.
Depending on this value, optimizations are made, e.g. in “serialized” mode
it is not necessary to create a separate DB connector for each thread.
SQLITE\_JOURNAL\_MODE: [str](https://docs.python.org/3/builtins/stdtypes.html#str) = 'WAL'
: `SQLiteAppl` applications are optimized for [WAL](https://sqlite.org/wal.html) mode, its not recommend
to change the journal mode (see `SQLiteAppl.tear_down`).
SQLITE\_CONNECT\_ARGS: [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[str](https://docs.python.org/3/builtins/stdtypes.html#str), [str](https://docs.python.org/3/builtins/stdtypes.html#str) | [float](https://docs.python.org/3/builtins/functions.html#float) | [int](https://docs.python.org/3/builtins/functions.html#int) | [bool](https://docs.python.org/3/builtins/functions.html#bool) | [None](https://docs.python.org/3/builtins/constants.html#None)] = {'cached\_statements': 0, 'check\_same\_thread': False, 'timeout': 3.0}
: Connection arguments ([`sqlite3.connect`](https://docs.python.org/3/library/sqlite3.html#sqlite3.connect))
`check_same_thread`: *bool*
: Is disabled by default when [`SQLITE_THREADING_MODE`](#searx.sqlitedb.SQLiteAppl.SQLITE_THREADING_MODE) is
serialized. The check is more of a hindrance when [threadsafety](https://docs.python.org/3/library/sqlite3.html#sqlite3.threadsafety) is
serialized because it would prevent a DB connector from being used in
multiple threads.
Is enabled when [threadsafety](https://docs.python.org/3/library/sqlite3.html#sqlite3.threadsafety) is `single-thread` or `multi-thread`
(when threads cannot share a connection [PEP-0249](https://peps.python.org/pep-0249/#threadsafety)).
`cached_statements`:
: Is set to `0` by default. Note: Python 3.12+ fetch result are not
consistent in multi-threading application and causing an API misuse error.
The multithreading use in SQLiteAppl is intended and supported if
threadsafety is set to 3 (aka “serialized”). CPython supports “serialized”
from version 3.12 on, but unfortunately only with errors:
- <https://github.com/python/cpython/issues/118172>
- <https://github.com/python/cpython/issues/123873>
The workaround for SQLite3 multithreading cache inconsistency is to set
option `cached_statements` to `0` by default.
`isolation_level`: *unset*
: If the connection attribute [isolation\_level](https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.isolation_level) is **not** `None`, new
transactions are implicitly opened before `execute()` and
`executemany()` executes SQL- INSERT, UPDATE, DELETE, or REPLACE
statements [[1]](https://docs.python.org/3/library/sqlite3.html#sqlite3-transaction-control-isolation-level).
By default, the value is not set, which means the default from Python is
used: Python’s default is `“”`, which is an alias for `“DEFERRED”`.
`autocommit`: *unset*
: Starting with Python 3.12 the DB connection has a `autocommit` attribute
and the recommended way of controlling transaction behaviour is through
this attribute [[2]](https://docs.python.org/3/library/sqlite3.html#transaction-control-via-the-autocommit-attribute).
By default, the value is not set, which means the default from Python is
used: Python’s default is the constant [LEGACY\_TRANSACTION\_CONTROL](https://docs.python.org/3/library/sqlite3.html#sqlite3.LEGACY_TRANSACTION_CONTROL):
Pre-Python 3.12 (non-PEP 249-compliant) transaction control, see
`isolation_level` above for more details.
connect() → [Connection](https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection)[[source]](https://docs.searxng.org/_modules/searx/sqlitedb.html#SQLiteAppl.connect)
: Creates a new DB connection ([`SQLITE_CONNECT_ARGS`](#searx.sqlitedb.SQLiteAppl.SQLITE_CONNECT_ARGS)). If not
already done, the DB schema is set up. The caller must take care of
closing the resource. Alternatively, [`SQLiteAppl.DB`](#searx.sqlitedb.SQLiteAppl.DB) can also
be used (the resource behind self.DB is automatically closed when the
process or thread is terminated).
register\_functions(*conn: [Connection](https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection)*)[[source]](https://docs.searxng.org/_modules/searx/sqlitedb.html#SQLiteAppl.register_functions)
: Create [user-defined](https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.create_function) SQL functions.
`REGEXP(<pattern>, <field>)`0 | 1
: [re.search](https://docs.python.org/3/library/re.html#re.search) returns (int) 1 for a match and 0 for none match of
`<pattern>` in `<field>`.
```
SELECT '12' AS field WHERE REGEXP('^[0-9][0-9]$', field)
-- 12
SELECT REGEXP('[0-9][0-9]', 'X12Y')
-- 1
SELECT REGEXP('[0-9][0-9]', 'X1Y')
-- 0
```
property DB: [Connection](https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection)
: Provides a DB connection. The connection is a *singleton* and
therefore well suited for read access. If
[`SQLITE_THREADING_MODE`](#searx.sqlitedb.SQLiteAppl.SQLITE_THREADING_MODE) is `serialized` only one DB connection
is created for all threads.
#### Note
For dedicated [transaction control](https://docs.python.org/3/library/sqlite3.html#sqlite3-controlling-transactions), it is recommended to create a
new connection ([`SQLiteAppl.connect`](#searx.sqlitedb.SQLiteAppl.connect)).
init(*conn: [Connection](https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection)*) → [bool](https://docs.python.org/3/builtins/functions.html#bool)[[source]](https://docs.searxng.org/_modules/searx/sqlitedb.html#SQLiteAppl.init)
: Initializes the DB schema and properties, is only executed once even
if called several times.
If the initialization has not yet taken place, it is carried out and a
True is returned to the caller at the end. If the initialization has
already been carried out in the past, False is returned.
class searx.sqlitedb.SQLiteProperties(db_url: str)[source] : Simple class to manage properties of a DB application in the DB. The object has its own DB connection and transaction area.
```
CREATE TABLE IF NOT EXISTS properties (
name TEXT,
value TEXT,
m_time INTEGER DEFAULT (strftime('%s', 'now')),
PRIMARY KEY (name))
```
SQLITE\_JOURNAL\_MODE: [str](https://docs.python.org/3/builtins/stdtypes.html#str) = 'WAL'
: `SQLiteAppl` applications are optimized for [WAL](https://sqlite.org/wal.html) mode, its not recommend
to change the journal mode (see `SQLiteAppl.tear_down`).
DDL\_PROPERTIES: [str](https://docs.python.org/3/builtins/stdtypes.html#str) = “CREATE TABLE IF NOT EXISTS properties (\n name TEXT,\n value TEXT,\n m\_time INTEGER DEFAULT (strftime('%s', 'now')), -- last modified (unix epoch) time in sec.\n PRIMARY KEY (name))”
: Table to store properties of the DB application
SQLITE\_CONNECT\_ARGS: [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[str](https://docs.python.org/3/builtins/stdtypes.html#str), [str](https://docs.python.org/3/builtins/stdtypes.html#str) | [int](https://docs.python.org/3/builtins/functions.html#int) | [bool](https://docs.python.org/3/builtins/functions.html#bool) | [None](https://docs.python.org/3/builtins/constants.html#None)] = {'cached\_statements': 0, 'check\_same\_thread': False, 'timeout': 3.0}
: Connection arguments ([`sqlite3.connect`](https://docs.python.org/3/library/sqlite3.html#sqlite3.connect))
`check_same_thread`: *bool*
: Is disabled by default when `SQLITE_THREADING_MODE` is
serialized. The check is more of a hindrance when [threadsafety](https://docs.python.org/3/library/sqlite3.html#sqlite3.threadsafety) is
serialized because it would prevent a DB connector from being used in
multiple threads.
Is enabled when [threadsafety](https://docs.python.org/3/library/sqlite3.html#sqlite3.threadsafety) is `single-thread` or `multi-thread`
(when threads cannot share a connection [PEP-0249](https://peps.python.org/pep-0249/#threadsafety)).
`cached_statements`:
: Is set to `0` by default. Note: Python 3.12+ fetch result are not
consistent in multi-threading application and causing an API misuse error.
The multithreading use in SQLiteAppl is intended and supported if
threadsafety is set to 3 (aka “serialized”). CPython supports “serialized”
from version 3.12 on, but unfortunately only with errors:
- <https://github.com/python/cpython/issues/118172>
- <https://github.com/python/cpython/issues/123873>
The workaround for SQLite3 multithreading cache inconsistency is to set
option `cached_statements` to `0` by default.
`isolation_level`: *unset*
: If the connection attribute [isolation\_level](https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.isolation_level) is **not** `None`, new
transactions are implicitly opened before `execute()` and
`executemany()` executes SQL- INSERT, UPDATE, DELETE, or REPLACE
statements [[1]](https://docs.python.org/3/library/sqlite3.html#sqlite3-transaction-control-isolation-level).
By default, the value is not set, which means the default from Python is
used: Python’s default is `“”`, which is an alias for `“DEFERRED”`.
`autocommit`: *unset*
: Starting with Python 3.12 the DB connection has a `autocommit` attribute
and the recommended way of controlling transaction behaviour is through
this attribute [[2]](https://docs.python.org/3/library/sqlite3.html#transaction-control-via-the-autocommit-attribute).
By default, the value is not set, which means the default from Python is
used: Python’s default is the constant [LEGACY\_TRANSACTION\_CONTROL](https://docs.python.org/3/library/sqlite3.html#sqlite3.LEGACY_TRANSACTION_CONTROL):
Pre-Python 3.12 (non-PEP 249-compliant) transaction control, see
`isolation_level` above for more details.
init(*conn: [Connection](https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection)*) → [bool](https://docs.python.org/3/builtins/functions.html#bool)[[source]](https://docs.searxng.org/_modules/searx/sqlitedb.html#SQLiteProperties.init)
: Initializes DB schema of the properties in the DB.
set(*name: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*, *value: [str](https://docs.python.org/3/builtins/stdtypes.html#str) | [int](https://docs.python.org/3/builtins/functions.html#int)*)[[source]](https://docs.searxng.org/_modules/searx/sqlitedb.html#SQLiteProperties.set)
: Set `value` of property `name` in DB. If property already
exists, update the `m_time` (and the value).
delete(*name: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*) → [int](https://docs.python.org/3/builtins/functions.html#int)[[source]](https://docs.searxng.org/_modules/searx/sqlitedb.html#SQLiteProperties.delete)
: Delete of property `name` from DB.
row(*name: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*, *default: [Any](https://docs.python.org/3/library/typing.html#typing.Any) = None*)[[source]](https://docs.searxng.org/_modules/searx/sqlitedb.html#SQLiteProperties.row)
: Returns the DB row of property `name` or `default` if property
not exists in DB.
m\_time(*name: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*, *default: [int](https://docs.python.org/3/builtins/functions.html#int) = 0*) → [int](https://docs.python.org/3/builtins/functions.html#int)[[source]](https://docs.searxng.org/_modules/searx/sqlitedb.html#SQLiteProperties.m_time)
: Last modification time of this property.
Copyright © SearXNG team
Made with Furo
