Skip to main content

Database support for use of SQLite (possibly other databases later).

Project description

ElectrumSV Database

Licence: MIT License
Maintainers: Roger Taylor, AustEcon
Project Lead: Roger Taylor
Homepage: https://electrumsv.io/

Overview

This is the database support library for ElectrumSV. This functionality has been extracted into an independent package so that it can be used by other projects.

Usage


Reads
-----

It is envisioned that most reads will be done with the aid of the
`replace_db_context_with_connection` decorator. The calling logic will have a reference to a
database context, and the decorator will inject a database connection as the first argument to
the wrapped function. These can happen inline in the calling context.

If a read query is one that will take more than a nominal amount of time, the developer should
use worker threads to farm out the query. There is a good argument that we should add that to
this library in order to deal with the typing complications.

Writes
------

SQLite has a [well known limitation](https://www.sqlite.org/faq.html#q5) in that only one
connection can be making changes, or writes, at a time. What this package does is use one
writer thread to apply write queries sequentially through it's connection. This is all managed
as part of the `DatabaseContext` class, which creates the `SqliteWriteDispatcher` and
`SqliteExecutor` for you.

Creating a database context::

```
from electrumsv_database import DatabaseContext
database_context = DatabaseContext(database_path)
```

Block executing a writer callback as a transaction::

```
def write(a: int, s: str, db: Optional[sqlite3.Connection]=None) -> str:
    assert db is not None and isinstance(db, sqlite3.Connection)
    db.execute("INSERT INTO SomeTable(a, s) VALUES (?, ?)", (a, s))
    return "whatever return value"

s = database_context.run_in_thread(write, 5, "test")
assert s == "whatever return value"
```

Post a writer callback to be executed as a transaction::

```
def write(a: int, s: str, db: Optional[sqlite3.Connection]=None) -> str:
    assert db is not None and isinstance(db, sqlite3.Connection)
    db.execute("INSERT INTO SomeTable(a, s) VALUES (?, ?)", (a, s))
    return "whatever return value"

future = database_context.post_to_thread(write, 5, "test")
# Perform whatever other logic.
s = future.result()
assert s == "whatever return value"
```

Asynchronously block executing a writer callback as a transaction::

```
def write(a: int, s: str, db: Optional[sqlite3.Connection]=None) -> str:
    assert db is not None and isinstance(db, sqlite3.Connection)
    db.execute("INSERT INTO SomeTable(a, s) VALUES (?, ?)", (a, s))
    return "whatever return value"

s = await database_context.run_in_thread_async(write, 5, "test")
assert s == "whatever return value"
```


Typing

Python has flawed problematic typing. It is very easy to have code that is wrong and not being checked, but be unaware of it. This package makes various choices to try and ensure that all of it's operations are typed.

Write functions

Queries that do write operations are executed using callbacks, and this means that we want to check the types of the arguments in the application logic. We use ParamSpec for this, but it has a limitation in that the typing of its args and kwargs attributes are atomic.

P1 = ParamSpec("P1")
T1 = TypeVar("T1")

    async def run_in_thread_async(self, func: Callable[P1, T1], *args: P1.args, \
            **kwargs: P1.kwargs) -> T1:
        ...

It is not possible to remove or add arguments to take into account perhaps extra ones added in the writer thread - like a reference to the database connection which the write callback should use to execute it's query. For this reason we use the following pattern, the write callback adds an optional db keyword argument to the end of it's argument list, the write dispatcher provides that adding it as an extra argument over the one the application provided.

The following pattern should be used::

def set_payment_channel_closed(channel_id: int, channel_state: ChannelState,
        db: Optional[sqlite3.Connection]=None) -> None:
    assert db is not None and isinstance(db, sqlite3.Connection)
    ...

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

electrumsv-database-1.4.tar.gz (9.2 kB view details)

Uploaded Source

Built Distribution

electrumsv_database-1.4-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file electrumsv-database-1.4.tar.gz.

File metadata

  • Download URL: electrumsv-database-1.4.tar.gz
  • Upload date:
  • Size: 9.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.62.3 importlib-metadata/4.11.1 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.10.0

File hashes

Hashes for electrumsv-database-1.4.tar.gz
Algorithm Hash digest
SHA256 fc954dbef32d2b93c4b6ce09405703a84d5b99f37bb3d714829c12cf5df4ab29
MD5 e5f8339fc5efa62bf9e516bf6fa30428
BLAKE2b-256 26240578d2e214c2ad432d1d888c5ed02220e7a5a8d6548309e085372d989755

See more details on using hashes here.

File details

Details for the file electrumsv_database-1.4-py3-none-any.whl.

File metadata

  • Download URL: electrumsv_database-1.4-py3-none-any.whl
  • Upload date:
  • Size: 9.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.62.3 importlib-metadata/4.11.1 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.10.0

File hashes

Hashes for electrumsv_database-1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 dd4a32df0045b596784f7c76dcb2938c494c3adeacbc9dd25d02d0e8b8b7636b
MD5 ed82c2f86cf5e2e9648a435107fc84b0
BLAKE2b-256 af116e60771b77ece22f9dd917134f2aea17d7f89d55199fe291a3c294858411

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page