Warning

This document is for an in-development version of Galaxy. You can alternatively view this page in the latest release if it exists or view the top of the latest release's documentation.

Source code for galaxy.util.sqlite

import pathlib
import sqlite3
import time

READ_ONLY_QUERY_TIMEOUT = 10.0
# Number of SQLite virtual machine instructions between deadline checks
_PROGRESS_HANDLER_INTERVAL = 1000

_READ_ONLY_ACTIONS = frozenset(
    (
        sqlite3.SQLITE_SELECT,
        sqlite3.SQLITE_READ,
        sqlite3.SQLITE_FUNCTION,
        sqlite3.SQLITE_RECURSIVE,
    )
)


def _authorize_read_only(action, arg1, arg2, db_name, trigger_or_view):
    if action in _READ_ONLY_ACTIONS:
        return sqlite3.SQLITE_OK
    return sqlite3.SQLITE_DENY


[docs] def connect(path): connection = sqlite3.connect(path) connection.row_factory = sqlite3.Row return connection
[docs] def connect_read_only(path, timeout=READ_ONLY_QUERY_TIMEOUT): """Open ``path`` for running untrusted SELECT queries. The file is opened read-only and immutable, so SQLite takes no locks and creates no -wal/-shm files next to it. An authorizer refuses to prepare any statement that does more than read tables and call functions, which rules out ATTACH, PRAGMA, VACUUM INTO, transactions and writes. Statements still running ``timeout`` seconds after the connection is opened are interrupted with ``sqlite3.OperationalError("interrupted")``. """ uri = f"{pathlib.Path(path).absolute().as_uri()}?mode=ro&immutable=1" connection = sqlite3.connect(uri, uri=True) connection.row_factory = sqlite3.Row connection.set_authorizer(_authorize_read_only) deadline = time.monotonic() + timeout connection.set_progress_handler(lambda: time.monotonic() > deadline, _PROGRESS_HANDLER_INTERVAL) return connection