C++ · Documents

Documents

#include <ustore/docs_collection.hpp>#include <ustore/docs_ref.hpp>#include <ustore/types.hpp>#include <ustore/docs_table.hpp> 1.0.0-rc.1 · d6d40961

A docs_collection_t hands out docs_ref proxies, which read and write JSON through ustore_docs_read and ustore_docs_write:

auto [people, people_status] = db.create<docs_collection_t>("people");
status_t status = people[key_from_integer(1)].assign(R"({"person": "Alice", "age": 27, "height": 1})");
status = people[key_from_integer(2)].assign(R"({"person": "Bob", "age": "27", "weight": 2})");

expected<owned_value_t> document = people[key_from_integer(1)].value();
expected<owned_value_t> person = people[collection_key_field_t {key_from_integer(1), "/person"}].value(ustore_docs_field_type_string_k);

status = people[key_from_integer(1)].patch(R"([{"op": "replace", "path": "/age", "value": 28}])");
status = people[key_from_integer(2)].merge(R"({"weight": null})");
expected<values_view_t> documents = people[{key_from_integer(1), key_from_integer(2)}].value(arena);
expected<sz::strings_view_t> paths = people[{key_from_integer(1), key_from_integer(2)}].gist(arena);

Field access through a proxy is shorthand like any other read without an arena, while gist and gather export into the arena they are given. Besides assign, a reference offers insert, update and upsert, and as switches the format every later call exchanges.

§ Tables

gather reads fields of many documents into a docs_table, converting each field into its column type on a best-effort basis. A header whose column types are known at compile time is built column by column:

auto header = make_table_header() //
                  .with<std::int32_t>("age")
                  .with<std::string_view>("age")
                  .with<std::string_view>("person");

std::array<ustore_key_t, 3> keys {key_from_integer(1), key_from_integer(2), key_from_integer(3)};
auto table = people[keys].gather(header, arena);
auto ages = table->column<0>();
for (std::size_t row = 0; row != ages.size(); ++row)
    if (ages[row].valid)
        std::printf("%d\n", ages[row].value);

A header whose column types are known only at runtime views an array of field_type_t, and its columns are typed at the point of use:

field_type_t const columns[] = {
    {"age", ustore_docs_field_type_i32_k},
    {"age", ustore_docs_field_type_string_k},
    {"person", ustore_docs_field_type_string_k},
};
auto dynamic = people[keys].gather(make_table_header(columns), arena);
auto names = dynamic->column(2).as<std::string_view>();

A table is a view: one ustore_docs_column_view_t per column lives in the arena, while its index and header view the keys and the header the gather was given. Every cell carries valid, converted and collides flags beside its value, which is meaningful only when valid.

API

Types

docs_read_collection_tMap from keys to JSON documents that only reads, cheap to construct and to copy.
docs_collection.hpp:40 ↗
class docs_read_collection_t

A handle addresses either the current state of a collection or its view inside a transaction or a snapshot, holds no state of its own, so any number of threads share it, and never outlives its database. The type of a handle shapes only how values cross it, since documents are stored as JSON whatever they arrive as.

Fields

modality_kustore_modality_tWhat the collections this kind of handle addresses hold, which a creation records and a lookup checks.
collection_key_field_tA key inside a collection, optionally narrowed down to one field of its document.
types.hpp:63 ↗
struct collection_key_field_t

Fields

collectionustore_collection_id_tCollection owning the key.
keyustore_key_tKey inside the collection.
fieldstd::string_viewPath of the document field, or an empty one for the whole value.
cellOne entry of a column, with the flags ustore_docs_gather reports for it.
docs_table.hpp:41 ↗
template <typename element_type_>
struct cell

Fields

validboolWhether the value was found and converted.
convertedboolWhether the conversion changed the semantics of the value.
collidesboolWhether an inconvertible value sits under the field.
valueelement_type_The value, meaningful only when valid.
scalar_column_viewColumn of fixed-width scalars, viewing the arena of the gather.
docs_table.hpp:58 ↗
template <typename element_type_>
class scalar_column_view
variable_length_column_viewColumn of strings, a tape of either offset width inside the arena of the gather.
docs_table.hpp:83 ↗
template <typename element_type_>
class variable_length_column_view
dynamic_column_view_tColumn whose type is known only at runtime, viewed as a typed column through as.
docs_table.hpp:118 ↗
class dynamic_column_view_t
field_type_tA column of a table header: the field to gather and the type to convert it into.
docs_table.hpp:153 ↗
struct field_type_t

Fields

fieldstd::string_viewField inside every document.
typeustore_docs_field_type_tType the field converts into.
table_index_view_tThe first column of a table, naming the document of every row.
docs_table.hpp:163 ↗
struct table_index_view_t

Fields

collections_beginstrided_iterator<ustore_collection_id_t const>
keys_beginstrided_iterator<ustore_key_t const>
countstd::size_t
table_header_view_tThe header row of a table, naming the field and type of every column.
docs_table.hpp:173 ↗
struct table_header_view_t

Fields

fields_beginstrided_iterator<std::string_view const>
types_beginstrided_iterator<ustore_docs_field_type_t const>
countstd::size_t
table_headerHeader of a table whose column types are known at compile time, built column by column through with.
docs_table.hpp:184 ↗
template <typename... column_types_>
struct table_header

Fields

columnsstd::array<field_type_t, sizeof...(column_types_)>Field and type of every column, in order.
docs_tableResults of ustore_docs_gather, with documents as rows and fields as columns.
docs_table.hpp:228 ↗
template <typename... column_types_>
class docs_table

A view that copies cheaply: its columns live in the arena of the gather, while its index and header view the keys and fields the gather was asked for.

Classdocs_collection_tTransactional map from keys to JSON documents, cheap to construct, which reads and writes the head or the view of a transaction.4
docs_collection.hpp:149 ↗
class docs_collection_t
deferred_tThe twin a deferred receiver hands out, whose verbs answer deferred calls.
docs_collection.hpp:167 ↗
using deferred_t = deferred_docs_collection_t;
clear_valuesEmpties every document, keeping the keys.
docs_collection.hpp:170 ↗
status_t clear_values() noexcept;
clearRemoves every document, keeping the collection.
docs_collection.hpp:173 ↗
status_t clear() noexcept;
dropRemoves the collection with all its documents.
docs_collection.hpp:176 ↗
status_t drop() noexcept;
Classdocs_read_refProxy reading documents, or fields inside them, at a batch of locations, through a snapshot, a transaction or the head, which never writes them.6
docs_ref.hpp:35 ↗
template <typename locations_type_>
class docs_read_ref

A read given an arena answers views into it, valid until the next call given that arena. The same read without one is shorthand: it makes a one-off arena and answers a result owning it, or a scalar copied out of it, which is slower than reusing an arena and keeps no state anywhere. Copying is cheap and nothing throws.

docs_read_ref
docs_ref.hpp:54 ↗
docs_read_ref(
    receiver_t receiver,
    locations_type_ && locations,
    ustore_docs_field_type_t type = ustore_docs_field_type_json_k) noexcept;
valueReads the documents or fields into arena, in the format of the proxy.
docs_ref.hpp:64 ↗
expected<value_t> value(
    arena_t & arena,
    ustore_watch_t watch = ustore_watch_keys_k) noexcept;
expected<one_off_answer_of<value_t>> value(
    ustore_watch_t watch = ustore_watch_keys_k) noexcept;

Reads the documents or fields into a one-off arena, which the answer owns, in the format of the proxy.

expected<one_off_answer_of<value_t>> value(
    ustore_docs_field_type_t type,
    ustore_watch_t watch = ustore_watch_keys_k) noexcept;

Reads the documents or fields into a one-off arena, which the answer owns, in the format type.

lengthReads the lengths of the documents or fields into arena.
docs_ref.hpp:81 ↗
expected<length_t> length(
    arena_t & arena,
    ustore_watch_t watch = ustore_watch_keys_k) noexcept;
expected<one_off_answer_of<length_t>> length(
    ustore_watch_t watch = ustore_watch_keys_k) noexcept;

Reads the lengths of the documents or fields into a one-off arena.

presentChecks which locations hold a value, which may be empty, into arena.
docs_ref.hpp:91 ↗
expected<present_t> present(
    arena_t & arena,
    ustore_watch_t watch = ustore_watch_keys_k) noexcept;
expected<one_off_answer_of<present_t>> present(
    ustore_watch_t watch = ustore_watch_keys_k) noexcept;

Checks which locations hold a value, which may be empty, into a one-off arena.

gistLists the unique paths to the leaves of the documents into arena.
docs_ref.hpp:104 ↗
expected<sz::strings_view_t> gist(
    arena_t & arena,
    ustore_watch_t watch = ustore_watch_keys_k) noexcept;
gatherGathers every column of header from every document into arena, as a table typed at runtime.
docs_ref.hpp:131 ↗
expected<docs_table_t> gather(
    table_header_view_t const & header,
    arena_t & arena,
    ustore_watch_t watch = ustore_watch_keys_k) noexcept;
template <typename... column_types_>
expected<docs_table<column_types_...>> gather(
    table_header<column_types_...> const & header,
    arena_t & arena,
    ustore_watch_t watch = ustore_watch_keys_k) noexcept;

Gathers every column of header from every document into arena, as a table typed at compile time.

Classdocs_refProxy reading and writing documents, or fields inside them, at a batch of locations, at the head or through a transaction.8
docs_ref.hpp:243 ↗
template <typename locations_type_>
class docs_ref

A proxy assigns one value to one or many locations, or many values to as many locations.

assignUpserts values pair-wise into the locations, in the format of the proxy.
docs_ref.hpp:257 ↗
template <typename values_argument_type_>
status_t assign(
    values_argument_type_ && values,
    ustore_durability_t durability = ustore_durability_buffered_k) noexcept;
template <typename values_argument_type_>
status_t assign(
    values_argument_type_ && values,
    ustore_docs_field_type_t type,
    ustore_durability_t durability = ustore_durability_buffered_k) noexcept;

Upserts values pair-wise into the locations, in the format type.

removeRemoves the documents whole, refusing locations that name a field, which a patch or a merge removes.
docs_ref.hpp:276 ↗
status_t remove(
    ustore_durability_t durability = ustore_durability_buffered_k) noexcept;

Statuses

  • status_code_t::invalid_argument_k A location names a field.
clear_valuesKeeps the keys, but empties the associated values.
docs_ref.hpp:301 ↗
status_t clear_values(
    ustore_durability_t durability = ustore_durability_buffered_k) noexcept;
patchPatches the documents with RFC 6902 JSON Patches.
docs_ref.hpp:307 ↗
template <typename values_argument_type_>
status_t patch(
    values_argument_type_ && values,
    ustore_durability_t durability = ustore_durability_buffered_k) noexcept;
mergePatches the documents with RFC 7386 JSON Merge Patches.
docs_ref.hpp:315 ↗
template <typename values_argument_type_>
status_t merge(
    values_argument_type_ && values,
    ustore_durability_t durability = ustore_durability_buffered_k) noexcept;
insertInserts values, failing where a document already exists.
docs_ref.hpp:323 ↗
template <typename values_argument_type_>
status_t insert(
    values_argument_type_ && values,
    ustore_durability_t durability = ustore_durability_buffered_k) noexcept;
upsertInserts values, replacing existing documents.
docs_ref.hpp:331 ↗
template <typename values_argument_type_>
status_t upsert(
    values_argument_type_ && values,
    ustore_durability_t durability = ustore_durability_buffered_k) noexcept;
updateReplaces existing documents or fields with values.
docs_ref.hpp:339 ↗
template <typename values_argument_type_>
status_t update(
    values_argument_type_ && values,
    ustore_durability_t durability = ustore_durability_buffered_k) noexcept;

Functions

docs_field_typeThe document field type that stores element_type_.
types.hpp:319 ↗
template <typename element_type_>
ustore_docs_field_type_t docs_field_type() noexcept;
is_variable_lengthWhether a gathered column of type holds strings, which offsets address, rather than scalars.
docs_table.hpp:30 ↗
bool is_variable_length(ustore_docs_field_type_t type) noexcept;
make_table_headerStarts a header whose column types are known at compile time.
docs_table.hpp:207 ↗
table_header make_table_header() noexcept;
table_header_view_t make_table_header(
    std::span<field_type_t const> columns) noexcept;

Views columns, whose types are known only at runtime, as a table header.

TypesMember types6
docs_read_ref::locations_store_tlocation_store<locations_type_>
docs_read_ref::locations_plain_ttypename locations_store_t::plain_t
docs_read_ref::keys_extractor_tplaces_arg_extractor<locations_plain_t>
docs_read_ref::value_tstd::conditional_t<is_one_k, value_view_t, values_view_t>
docs_read_ref::present_tstd::conditional_t<is_one_k, bool, bits_view_t>
docs_read_ref::length_tstd::conditional_t<is_one_k, ustore_length_t, lengths_view_t>