# [asyncio-foundationdb](https://github.com/amirouche/asyncio-foundationdb/)
[](https://builds.sr.ht/~amirouche/asyncio-foundationdb/commits/main/.build.yml?)
asyncio drivers for foundationdb tested with CPython 3.7-3.10 and PyPy 3.7, and PyPy 3.8
[](https://unsplash.com/photos/lRoX0shwjUQ)
## Table of Content
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->
- [Getting started](#getting-started)
- [ChangeLog](#changelog)
- [v0.10.x](#v010x)
- [`import found`](#import-found)
- [`from found import bstore`](#from-found-import-bstore)
- [`from found import nstore`](#from-found-import-nstore)
- [`from found import eavstore`](#from-found-import-eavstore)
- [`from found import pstore`](#from-found-import-pstore)
<!-- markdown-toc end -->
## Getting started
```
pip install asyncio-foundationdb
```
```python
import found
async def get(tx, key):
out = await found.get(tx, key)
async def set(tx, key, value):
return found.set(tx, key, value)
db = await found.open()
out = await found.transactional(db, get, b'hello')
assert out is None
await found.transactional(db, set, b'hello', b'world')
out = await found.transactional(db, get, b'hello')
assert out == b'world'
```
## ChangeLog
### v0.10.x
- Almost full rewrite
- Remove hooks for the time being
- Port Generic Tuple Store aka. `nstore`
- Add blob store aka. `bstore`
- Add Entity-Attribute-Value store aka. `eavstore`
- Add inverted index store aka. `pstore`
## `import found`
### `found.BaseFoundException`
All `found` exceptions inherit that class.
### `found.FoundException`
Exception raised when there is an error foundationdb client driver, or
foundationdb server side.
### async `found.open(cluster_file=None)`
Open database.
Coroutine that will open a connection with the cluster specified in
the file `cluster_file`. If `cluster_file` is not provided the default
is `/etc/foundationdb/fdb.cluster`. Returns a database object.
### async `found.transactional(db, func, *args, snapshot=False, **kwargs)`
Operate a transaction for `func`.
Coroutine that will operate a transaction against `db` for `func`. If
`snapshot=True` then the transaction is read-only. `func` will receive
an appropriate transaction object as first argument, then `args`, then
`kwargs`. Because of errors `transactional` might run `func` several
times, hence `func` should be idempotent.
### async `found.get(tx, key)`
Get the value associated with `key`.
Coroutine that will fetch the value associated with `key` inside the
database associated with `tx`. `key` must be `bytes`. In case of
success, returns `bytes`. Otherwise, if there is no value associated
with `key`, returns the object `None`.
### `found.set(tx, key, value)`
Set `key` to `value`.
In the database associated with `tx`, associate `key` with
`value`. Both `key` and `value` must be `bytes`.
### `found.pack(tuple)`
Serialize python objects `tuple` into bytes.
### `found.pack_with_versionstamp(tuple)`
Serialize python objects `tuple` into bytes. `tuple` may contain
`found.Versionstamp` objects.
### `found.unpack(bytes)`
Deserialize bytes into python objects.
### `found.Versionstamp(...)`
FIXME.
### `found.clear(tx, key, other=None)`
Remove key or keys.
In the database associated with `tx`, clear the specified `key` or
range of keys.
`key` and `other` if provided must be `bytes`.
If `other=None`, then clear the association that might exists with
`key`. Otherwise, if `other` is provided, `found.clear` will remove
any association between `key` and `other` but not the association with
`other` if any (that is `other` is excluded from the range).
### async `found.query(tx, key, other, *, limit=0, mode=STREAMING_MODE_ITERATOR)`
Fetch key-value pairs.
In the database associated with `tx`, generate at most `limit`
key-value pairs inside the specified range, with the specified order.
If `key < other` then `found.query` generates key-value pairs in
lexicographic order. Otherwise, if `key > other` then `found.query`
generates key-value pairs in reverse lexicographic order, that is
starting at `other` until `key`.
If `limit=0`, then `found.query` generates all key-value pairs in the
specified bounds. Otherwise if `limit > 0` then, it generates at most
`limit` pairs.
The keyword `mode` can be one the following constant:
- `found.STREAMING_MODE_WANT_ALL`
- `found.STREAMING_MODE_ITERATOR`
- `found.STREAMING_MODE_EXACT`
- `found.STREAMING_MODE_SMALL`
- `found.STREAMING_MODE_MEDIUM`
- `found.STREAMING_MODE_LARGE`
- `found.STREAMING_MODE_SERIAL`
### `found.next_prefix(key)`
Returns the immediatly next byte sequence that is not prefix of `key`.
### `found.lt(key, offset=0)`
### `found.lte(key, offset=0)`
### `found.gt(key, offset=0)`
### `found.gte(key, offset=0)`
### async `found.read_version(tx)`
### `found.set_read_version(tx, version)`
### `found.add(tx, key, param)`
### `found.bit_and(tx, key, param)`
### `found.bit_or(tx, key, param)`
### `found.bit_xor(tx, key, param)`
### `found.max(tx, key, param)`
### `found.byte_max(tx, key, param)`
### `found.min(tx, key, param)`
### `found.byte_min(tx, key, param)`
### `found.set_versionstamped_key(tx, key, param)`
### `found.set_versionstamped_value(tx, key, param)`
## `from found import bstore`
### `bstore.BStoreException`
Exception specific to `bstore`.
### `bstore.make(name, prefix)`
Handle over a `bstore` called `name` with `prefix`.
### async `bstore.get_or_create(tx, bstore, blob)`
### `bstore.get(tx, bstore, uid)`
## `from found import nstore`
### `nstore.NStoreException`
Exception specific to `nstore`.
### `nstore.make(name, prefix, n)`
Create a handle over a `nstore` called `name` with `prefix` and `n`
columns.
The argument `name` should be a string, it is really meant to ease
debugging. `prefix` should be a tuple that can be packed with
`found.pack`. Last but not least, `n` is the number of columns in the
returned tuple store (or, if you prefer, the number of tuple items).
It is preferable to store the returned value.
### `nstore.add(tx, nstore, *items, *, value=b'')`
In the database associated with `tx`, as part of `nstore`, add
`items` associated with `value`.
### `nstore.remove(tx, nstore, *items)`
In the database associated with `tx`, as part of `nstore`, remove
`items` and the associated value.
### async `nstore.get(tx, nstore, *items)`
In the database associated with `tx`, as part of `nstore`, get the
value associated with `items`. If there is no such items in `nstore`,
returns `None`.
### `nstore.var(name)`
Create a variable called `name` for use with `nstore.query`.
### async `nstore.query(tx, nstore, pattern, *patterns)`
In the database associated with `tx`, as part of `nstore`, generate
mappings that match `pattern` and `patterns`. Both `pattern` and
`patterns` may contain `nstore.var` that will be replaced with
matching values in the generic tuple store.
## `from found import eavstore`
### `eavstore.make(name, prefix)`
Create a handle over an eavstore called `name` with `prefix`.
The argument `name` should be a string, it is really meant to ease
debugging. `prefix` should be a tuple that can be packed with
`found.pack`.
### `eavstore.create(tx, eavstore, dict)`
Store a dictionary.
In the database associated with `tx`, as part of `eavstore`, save
`dict` and returns its unique identifier.
### async `eavstore.get(tx, eavstore, uid)`
Fetch a dictionary.
In the database associated with `tx`, as part of `eavstore`, retrieve
the dictionary associated with `uid`. If there is no such dictionary,
returns an empty dictionary.
### `eavstore.remove(tx, eavstore, uid)`
Clear a dictionary.
In the database associated with `tx`, as part of `eavstore`, remove
the dictionary associated with `uid`.
### `eavstore.update(tx, eavstore, uid, dict)`
Update a dictionary.
In the database associated with `tx`, as part of `eavstore`, replace
the dictionary associated with `uid` with `dict`.
### async `eavstore.query(tx, eavstore, key, value)`
Lookup dictionaries according to sppecification.
In the database associated with `tx`, as part of `eavstore`, generates
unique identifier for dictionaries that have `key` equal to `value`.
## `from found import pstore`
### `pstore.PStoreException`
Exception specific to `pstore`.
### `pstore.make(name, prefix, pool)`
A handle over a `pstore` called `name` with `prefix`, that will use
`pool`.
### async `pstore.index(tx, store, docuid, counter)`
Associates `docuid` with `counter`.
Coroutine that associates the identifier `docuid` with the dict-like
`counter` inside the database associated with `tx` at `store` for
later retriaval with `pstore.search`.
`counter` must be a dict-like mapping string to integers bigger than
zero.
### async `pstore.search(tx, store, keywords, limit)`
Return a sorted list of at most `limit` documents matching `keywords`.