# Collections

> UStore for C++

### Named Collections and Transactions

```cpp
expected<docs_collection_t> people = db.find_or_create<docs_collection_t>("people");

expected<transaction_t> transaction = db.transaction();
blobs_collection_t inside = *transaction->find("blobs");
status = inside[key_from_integer(42)].assign("written inside a transaction");
expected<commit_stamp_t> committed = transaction->commit();

expected<snapshot_t> snapshot = db.snapshot();
auto pinned = (*snapshot->find("blobs"))[key_from_integer(42)].value();
```

Each collection type names the modality it holds as `modality_k`, so `create` records it and refuses a name starting with `_`, which system collections keep, `find` refuses a collection holding another with `status_code_t::invalid_argument_k`, and `find_or_create` creates only when no collection carries the name.
A handle taken from a transaction reads and writes through it, and a transaction commits only when `commit` is called, answering the commit's position in commit order.
A snapshot hands out the read-only twin of every collection, such as `docs_read_collection_t` for `find<docs_collection_t>`, so nothing writes through it, and `save(path)` writes it out as a new database.

### Describing, Clearing and Compacting

`describe`, `clear` and `compact` wrap [the C calls](/docs/ustore/c/) of the same names, and a save or a compaction takes an optional progress callable:

```cpp
expected<ustore_database_description_t> description = db.describe();
if (description)
    std::printf("%s holds %llu keys\n", ustore_engine_name(description->engine),
                (unsigned long long)description->keys);
status = db.clear(ustore_drop_pairs_k);

ustore_size_t const budget = 1ull << 30;
auto within_budget = [&](ustore_size_t finished, ustore_size_t total) noexcept {
    std::fprintf(stderr, "saved %llu of %llu bytes\n", (unsigned long long)finished, (unsigned long long)total);
    return finished <= budget ? ustore_continue_k : ustore_cancel_k;
};
status = snapshot->save("/var/backups/ustore", within_budget);
status = db.compact();
```

`clear` empties every collection as its `ustore_drop_mode_t` names, so `ustore_drop_collection_k` drops every named collection, which the `ram` and RocksDB engines refuse while a snapshot is open.
A progress callable answers `ustore_continue_k` or `ustore_cancel_k` and is `noexcept`, so one that may throw does not compile, and the call borrows it until it is final, so a temporary does not compile either.

`#include <ustore/db.hpp>`

## collection_named

Reads the collection `name` was given at the head, or at the snapshot of [`receiver`](https://www.unum.cloud/docs/ustore/cpp/quickstart.md#receiver) when it names one, through a one-off arena, since a name answers one identifier.

```cpp
expected<ustore_collection_id_t> collection_named(
    receiver_t const & receiver,
    std::string_view name,
    ustore_modality_t *modality = nullptr) noexcept;
```

```cpp
expected<ustore_collection_id_t> collection_named(
    receiver_t const & receiver,
    std::string_view name,
    ustore_modality_t modality) noexcept;
```

Reads the collection `name` was given, as the overload above, refusing one that holds another modality than `modality`.

Names resolve in two phases, so this is the only place a name reaches the database, and every other call addresses its collection by the identifier this returns.

- `receiver` (in): The receiver whose snapshot the name is read at, or the head when it names none.
- `name` (in): The collection's name.
- `modality` (out): What the collection holds, written when given.

Statuses: - `status_code_t::not_found_k` No collection carries `name`.
- `status_code_t::invalid_argument_k` The collection holds another modality than `modality`.

## collection_exists

Whether a collection named `name` exists at the head, or at the snapshot of [`receiver`](https://www.unum.cloud/docs/ustore/cpp/quickstart.md#receiver).

```cpp
expected<bool> collection_exists(
    receiver_t const & receiver,
    std::string_view name) noexcept;
```

## list_collections

Lists the collections at the head, or at the snapshot of [`receiver`](https://www.unum.cloud/docs/ustore/cpp/quickstart.md#receiver), with their identifiers in `arena`.

```cpp
expected<collections_list_t> list_collections(
    receiver_t const & receiver,
    arena_t & arena) noexcept;
```

