C++ · Collections

Collections

#include <ustore/db.hpp> 1.0.0-rc.1 · d6d40961

§ Named Collections and Transactions

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 of the same names, and a save or a compaction takes an optional progress callable:

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.

API

Functions

collection_namedReads the collection name was given at the head, or at the snapshot of receiver when it names one, through a one-off arena, since a name answers one identifier.
db.hpp:49 ↗
expected<ustore_collection_id_t> collection_named(
    receiver_t const & receiver,
    std::string_view name,
    ustore_modality_t *modality = nullptr) noexcept;
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.

Parameters

receiverinThe receiver whose snapshot the name is read at, or the head when it names none.
nameinThe collection's name.
modalityoutWhat 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_existsWhether a collection named name exists at the head, or at the snapshot of receiver.
db.hpp:95 ↗
expected<bool> collection_exists(
    receiver_t const & receiver,
    std::string_view name) noexcept;
list_collectionsLists the collections at the head, or at the snapshot of receiver, with their identifiers in arena.
db.hpp:103 ↗
expected<collections_list_t> list_collections(
    receiver_t const & receiver,
    arena_t & arena) noexcept;