Historical Access

Historical Access: the engine that answers HistoryRead and HistoryUpdate, the store interface behind it, the SQLite store that implements one, and the annotations property.

ua::history::HistoryEngine

class

Storage-agnostic Historical Access semantics (OPC 10000-11 section 6.4 / section 6.8).

The engine implements the normative read/update behaviour - half-open windowing, returnBounds with Bad_BoundNotFound placeholders, forward/reverse direction, the numValuesPerNode cap with continuation points, single-instant reads, ReadModified, Insert/Replace/Update status fan-out, Delete, modification-record creation - over an abstract HistoryStore. It performs no I/O and owns no threads, so it is unit-tested directly against an in-memory store. The NamespaceHistoryDelegate (see history_delegate.h) wraps the engine with a strand + worker thread and a HistoryStore instance.

All methods are pure functions of (store, item): they are invoked one item at a time from the delegate's worker, after the SDK service layer has already performed request-level validation.

Member types

ua::NamespaceHistoryDelegate::ReadRawItem ReadRawItem

Request item for a ReadRaw / ReadModified operation (re-exported from the delegate seam so callers can spell these types as HistoryEngine::ReadRawItem).

ua::NamespaceHistoryDelegate::ReadRawItemResult ReadRawItemResult

Per-node result of a ReadRaw / ReadModified operation.

ua::NamespaceHistoryDelegate::Cursor Cursor

Continuation cursor carried between paginated raw reads.

ua::NamespaceHistoryDelegate::ReadAtTimeItem ReadAtTimeItem

Request item for a ReadAtTime operation.

ua::NamespaceHistoryDelegate::ReadAtTimeItemResult ReadAtTimeItemResult

Per-node result of a ReadAtTime operation.

ua::NamespaceHistoryDelegate::ReadEventsItem ReadEventsItem

Request item for a ReadEvents operation.

ua::NamespaceHistoryDelegate::ReadEventsItemResult ReadEventsItemResult

Per-node result of a ReadEvents operation.

ua::NamespaceHistoryDelegate::ReadAnnotationItem ReadAnnotationItem

Request item for a ReadAnnotationData operation.

ua::NamespaceHistoryDelegate::ReadAnnotationItemResult ReadAnnotationItemResult

Per-node result of a ReadAnnotationData operation.

ua::NamespaceHistoryDelegate::UpdateDataItem UpdateDataItem

Request item for an UpdateData (Insert / Replace / Update) operation.

ua::NamespaceHistoryDelegate::UpdateDataItemResult UpdateDataItemResult

Per-node result of an UpdateData operation.

ua::NamespaceHistoryDelegate::UpdateEventsItem UpdateEventsItem

Request item for an UpdateEvents operation.

ua::NamespaceHistoryDelegate::UpdateEventsItemResult UpdateEventsItemResult

Per-node result of an UpdateEvents operation.

ua::NamespaceHistoryDelegate::UpdateStructureDataItem UpdateStructureDataItem

Request item for an UpdateStructureData (Annotation) operation.

ua::NamespaceHistoryDelegate::UpdateStructureDataItemResult UpdateStructureDataItemResult

Per-node result of an UpdateStructureData operation.

ua::NamespaceHistoryDelegate::DeleteRawItem DeleteRawItem

Request item for a DeleteRaw operation.

ua::NamespaceHistoryDelegate::DeleteAtTimeItem DeleteAtTimeItem

Request item for a DeleteAtTime operation.

ua::NamespaceHistoryDelegate::DeleteEventsItem DeleteEventsItem

Request item for a DeleteEvents operation.

ua::NamespaceHistoryDelegate::DeleteItemResult DeleteItemResult

Per-node result shared by the delete operations.

Static functions

ReadRawItemResult read_raw(HistoryStore &store, ReadRawItem &item)

Read raw or modified values for one operation (OPC 10000-11 section 6.4.3).

  • store (HistoryStore &) - the history store queried for raw / modified values.
  • item (ReadRawItem &) - the ReadRaw / ReadModified operation; carries the request window and flags, and its continuation cursor is updated in place when a page boundary is hit.

Returns: the per-node result: the values (or modification infos) and a continuation point when the numValuesPerNode cap is reached.

ReadAtTimeItemResult read_at_time(HistoryStore &store, const ReadAtTimeItem &item)

Read values at specific timestamps (OPC 10000-11 section 6.4.5).

  • store (HistoryStore &) - the history store queried for exact and surrounding raw values.
  • item (const ReadAtTimeItem &) - the ReadAtTime operation; carries the requested timestamps and the use_simple_bounds flag.

Returns: the per-node result: one DataValue per requested timestamp, in request order.

ReadEventsItemResult read_events(HistoryStore &store, ReadEventsItem &item)

Read historical Events for one operation (OPC 10000-11 section 6.4.2).

  • store (HistoryStore &) - the history store queried for stored events.
  • item (ReadEventsItem &) - the ReadEvents operation; carries the time window, the event filter select clauses, and its continuation cursor is updated in place when a page boundary is hit.

Returns: the per-node result: the projected event field lists, with a continuation point when the numValuesPerNode cap is reached.

std::string field_key(const ua::SimpleAttributeOperand &operand)

The storage field key for a select clause: its browse-path names joined with '/'.

  • operand (const ua::SimpleAttributeOperand &) - the select clause whose browse-path names form the key.

Returns: the storage field key: the operand's browse-path names joined with '/'.

UpdateDataItemResult update_data(HistoryStore &store, const UpdateDataItem &item, std::string_view userName={})

Insert / Replace / Update one operation's values (OPC 10000-11 section 6.8.2).

  • store (HistoryStore &) - the history store the values are written to.
  • item (const UpdateDataItem &) - the UpdateData operation; carries the Insert / Replace / Update mode and the values.
  • userName (std::string_view) - identity recorded in each generated modification record's ModificationInfo; empty when no user identity is available.

Returns: the per-value operation results.

DeleteItemResult delete_raw(HistoryStore &store, const DeleteRawItem &item, std::string_view userName={})

Delete raw values in the [startTime, endTime] interval (OPC 10000-11 section 6.8.5).

  • store (HistoryStore &) - the history store the values are deleted from.
  • item (const DeleteRawItem &) - the DeleteRaw operation; carries the [startTime, endTime] interval to delete.
  • userName (std::string_view) - identity stamped on the generated Delete modification records.

Returns: the operation result (always Good; an empty range is not an error).

DeleteItemResult delete_at_time(HistoryStore &store, const DeleteAtTimeItem &item, std::string_view userName={})

Delete raw values at specific timestamps (OPC 10000-11 section 6.8.5).

  • store (HistoryStore &) - the history store the values are deleted from.
  • item (const DeleteAtTimeItem &) - the DeleteAtTime operation; carries the specific timestamps to delete.
  • userName (std::string_view) - identity stamped on the generated Delete modification records.

Returns: the per-timestamp operation results (Good when a value was deleted, else Bad_NoEntryExists).

UpdateEventsItemResult update_events(HistoryStore &store, const UpdateEventsItem &item)

Insert / Replace / Update historical events (OPC 10000-11 section 6.8.4).

  • store (HistoryStore &) - the history store the events are written to.
  • item (const UpdateEventsItem &) - the UpdateEvents operation; carries the Insert / Replace / Update mode, the event filter, and the event field values.

Returns: the per-event operation results.

DeleteItemResult delete_events(HistoryStore &store, const DeleteEventsItem &item)

Delete historical events by EventId (OPC 10000-11 section 6.8.5).

  • store (HistoryStore &) - the history store the events are deleted from.
  • item (const DeleteEventsItem &) - the DeleteEvents operation; carries the EventIds to delete.

Returns: the per-EventId operation results.

ReadAnnotationItemResult read_annotations(HistoryStore &store, const ReadAnnotationItem &item)

Read history Annotations at specific timestamps (OPC 10000-11 section 6.4.6).

  • store (HistoryStore &) - the history store queried for stored Annotations.
  • item (const ReadAnnotationItem &) - the ReadAnnotationData operation; carries the requested timestamps.

Returns: the per-node result: one DataValue per requested timestamp, in request order.

UpdateStructureDataItemResult update_structure_data(HistoryStore &store, const UpdateStructureDataItem &item)

Insert / Replace / Update / Remove structured history - Annotations (OPC 10000-11 section 6.8.3).

  • store (HistoryStore &) - the history store the Annotations are written to.
  • item (const UpdateStructureDataItem &) - the UpdateStructureData operation; carries the Insert / Replace / Update / Remove mode and the Annotation entries.

Returns: the per-entry operation results.

ua::history::HistoryEngine::RawCursor

struct

Continuation state: the not-yet-returned tail of an already-ordered result plus the page size to slice on each resume.

Stored opaquely in the SDK's HistoryContinuationPoint. For a modified read remaining_infos runs parallel to remaining; for a raw read it is empty.

Public attributes

std::vector< ua::DataValue > remaining
std::vector< ua::ModificationInfo > remaining_infos
uint32_t page_size

ua::history::HistoryEngine::EventsCursor

struct

Continuation state for a paged event read: the not-yet-returned tail plus the page size.

Public attributes

std::vector< ua::HistoryEventFieldList > remaining
uint32_t page_size

ua::history::HistoryDelegate

class

Canonical reference NamespaceHistoryDelegate.

Owns a dedicated single-thread pool + strand so the (potentially blocking) store I/O never runs on the server's async threads, and drives the storage-agnostic HistoryEngine over an injected HistoryStore. The store is touched only from the worker strand, so it needs no internal synchronisation.

The store is injected (dependency injection) rather than hard-wired to SQLite so one delegate serves any backend, and so the engine can be exercised over an in-memory store in tests.

Functions

HistoryDelegate(std::unique_ptr< HistoryStore > store)

Take ownership of store, the storage backend the wrapped HistoryEngine drives.

  • store (std::unique_ptr< HistoryStore >) - the storage backend that the wrapped HistoryEngine reads from and writes to.
Capabilities capabilities() const noexcept override

Declares which history operations this delegate supports.

Returns: The supported-operation flags. The default returns all-false (no operations supported).

void read_raw_async(const ReadContext &context, std::vector< ReadRawItem > items, ReadRawCallback callback) noexcept override

Reads raw or modified value history for a batch of nodes.

  • context (const ReadContext &) - Read context, including cancellation flag and timestamp preference.
  • items (std::vector< ReadRawItem >) - Per-node read requests, taken by value so the delegate may retain them.
  • callback (ReadRawCallback) - Receives a BatchResult whose batch status reports whether the request was accepted, and each per-item Result holds the node's values or an ErrorDetail. This method never throws.
void read_at_time_async(const ReadContext &context, std::vector< ReadAtTimeItem > items, ReadAtTimeCallback callback) noexcept override

Reads values at specific timestamps for a batch of nodes.

  • context (const ReadContext &) - Read context, including cancellation flag and timestamp preference.
  • items (std::vector< ReadAtTimeItem >) - Per-node read requests, taken by value so the delegate may retain them.
  • callback (ReadAtTimeCallback) - Receives a BatchResult whose per-item Result holds the node's values or an ErrorDetail. This method never throws.
void read_events_async(const ReadContext &context, std::vector< ReadEventsItem > items, ReadEventsCallback callback) noexcept override

Reads historical events for a batch of event-source nodes.

  • context (const ReadContext &) - Read context, including cancellation flag and timestamp preference.
  • items (std::vector< ReadEventsItem >) - Per-node read requests, taken by value so the delegate may retain them.
  • callback (ReadEventsCallback) - Receives a BatchResult whose per-item Result holds the matching events or an ErrorDetail. This method never throws.
void read_annotations_async(const ReadContext &context, std::vector< ReadAnnotationItem > items, ReadAnnotationCallback callback) noexcept override

Reads history annotations for a batch of nodes.

  • context (const ReadContext &) - Read context, including cancellation flag and timestamp preference.
  • items (std::vector< ReadAnnotationItem >) - Per-node read requests, taken by value so the delegate may retain them.
  • callback (ReadAnnotationCallback) - Receives a BatchResult whose per-item Result holds the annotation values or an ErrorDetail. This method never throws.
void update_data_async(const UpdateContext &context, std::vector< UpdateDataItem > items, UpdateDataCallback callback) noexcept override

Inserts or replaces historical values for a batch of nodes.

  • context (const UpdateContext &) - Update context, including the cancellation flag.
  • items (std::vector< UpdateDataItem >) - Per-node update requests, taken by value so the delegate may retain them.
  • callback (UpdateDataCallback) - Receives a BatchResult whose per-item Result holds the per-value status codes or an ErrorDetail. This method never throws.
void update_events_async(const UpdateContext &context, std::vector< UpdateEventsItem > items, UpdateEventsCallback callback) noexcept override

Inserts, replaces, or updates historical events for a batch of event-source nodes.

  • context (const UpdateContext &) - Update context, including the cancellation flag.
  • items (std::vector< UpdateEventsItem >) - Per-node update requests, taken by value so the delegate may retain them.
  • callback (UpdateEventsCallback) - Receives a BatchResult whose per-item Result holds the per-event status codes or an ErrorDetail. This method never throws.
void update_structure_data_async(const UpdateContext &context, std::vector< UpdateStructureDataItem > items, UpdateStructureDataCallback callback) noexcept override

Inserts, replaces, updates, or removes structured history (e.g.

  • context (const UpdateContext &) - Update context, including the cancellation flag.
  • items (std::vector< UpdateStructureDataItem >) - Per-node update requests, taken by value so the delegate may retain them.
  • callback (UpdateStructureDataCallback) - Receives a BatchResult whose per-item Result holds the per-entry status codes or an ErrorDetail. This method never throws.
void delete_raw_async(const UpdateContext &context, std::vector< DeleteRawItem > items, DeleteRawCallback callback) noexcept override

Deletes raw or modified value history over a time range for a batch of nodes.

  • context (const UpdateContext &) - Update context, including the cancellation flag.
  • items (std::vector< DeleteRawItem >) - Per-node delete requests, taken by value so the delegate may retain them.
  • callback (DeleteRawCallback) - Receives a BatchResult whose per-item Result holds the outcome or an ErrorDetail. This method never throws.
void delete_at_time_async(const UpdateContext &context, std::vector< DeleteAtTimeItem > items, DeleteAtTimeCallback callback) noexcept override

Deletes values at specific timestamps for a batch of nodes.

  • context (const UpdateContext &) - Update context, including the cancellation flag.
  • items (std::vector< DeleteAtTimeItem >) - Per-node delete requests, taken by value so the delegate may retain them.
  • callback (DeleteAtTimeCallback) - Receives a BatchResult whose per-item Result holds the outcome or an ErrorDetail. This method never throws.
void delete_events_async(const UpdateContext &context, std::vector< DeleteEventsItem > items, DeleteEventsCallback callback) noexcept override

Deletes historical events for a batch of event-source nodes.

  • context (const UpdateContext &) - Update context, including the cancellation flag.
  • items (std::vector< DeleteEventsItem >) - Per-node delete requests, taken by value so the delegate may retain them.
  • callback (DeleteEventsCallback) - Receives a BatchResult whose per-item Result holds the outcome or an ErrorDetail. This method never throws.

ua::history::HistoryNamespace

class

Forwarding wrapper around an SDK-provided Namespace that attaches a history delegate without changing the underlying address-space behaviour.

Functions

HistoryNamespace(ua::shared_ptr< ua::Namespace > inner, ua::shared_ptr< ua::NamespaceHistoryDelegate > delegate)

Wrap inner, attaching delegate as the namespace's history delegate.

  • inner (ua::shared_ptr< ua::Namespace >) - the SDK-provided namespace whose non-history behaviour is forwarded unchanged.
  • delegate (ua::shared_ptr< ua::NamespaceHistoryDelegate >) - the history delegate attached to the wrapped namespace.
ua::String uri() const override

Returns the namespace URI that uniquely identifies this namespace.

Returns: The namespace URI, the string form used to register and look this namespace up in the server's namespace array.

void set_index(uint16_t index) override

Assigns the namespace index this namespace occupies in the server's namespace array.

  • index (uint16_t) - Zero-based candidate namespace-array slot.
void shutdown_async(std::function< void(ua::VoidResult)> callback) noexcept override

Forwards the shutdown to the wrapped namespace: this wrapper arms nothing of its own.

void find_node(const ua::NodeId &nodeId, FindNodeCompleteCallback callback) override

Resolves a node owned by this namespace to an accessor.

  • nodeId (const ua::NodeId &) - Identifier of the node to resolve. Its namespace index is assumed to belong to this namespace.
  • callback (FindNodeCompleteCallback) - Receives a NodeAccessorResult - on success an accessor for the node; on failure a bad StatusCode carrying any ErrorDetail (e.g. BadNodeIdUnknown). Never throws.
void create_node(const ua::NodeId &nodeId, ua::NodeClass nodeClass, ua::InitialAttributes initialAttributes, CreateNodeCompleteCallback callback) override

Creates a node of the given class in this namespace, with its initial attributes.

  • nodeId (const ua::NodeId &) - Identifier for the new node; must not already exist in this namespace.
  • nodeClass (ua::NodeClass) - OPC UA node class to instantiate.
  • initialAttributes (ua::InitialAttributes) - Standard attributes (id + wire-form value) to apply atomically as the node is created; may be empty for a bare node. A Variable's live value is not a creation attribute (use a value source / write_value); a VariableType's static default Value may be supplied here.
  • callback (CreateNodeCompleteCallback) - Receives a NodeAccessorResult - on success an accessor for the created node; on failure a bad StatusCode carrying any ErrorDetail (BadNotSupported from the base default). Never throws.
void delete_node(const ua::NodeId &nodeId, bool deleteForwardHierarchicalRefs, DeleteNodeCompleteCallback callback) override

Deletes a node and its intra-namespace references from this namespace.

  • nodeId (const ua::NodeId &) - Identifier of the node to delete.
  • deleteForwardHierarchicalRefs (bool) - When true, also delete nodes reachable by forward hierarchical references from this node (recursive subtree delete).
  • callback (DeleteNodeCompleteCallback) - Receives a DeleteNodeResult - on success the ExternalReference entries needing cross-namespace cleanup; on failure a bad StatusCode carrying any ErrorDetail. Never throws.
void create_monitoring(std::span< const ua::MonitoringCreateItem > items, CreateMonitoringCallback callback) override

Forwards monitored-item creation to the wrapped namespace.

void delete_monitoring(std::span< const ua::MonitoringHandle > handles, DeleteMonitoringCallback callback) override

Forwards monitored-item removal to the wrapped namespace.

  • handles (std::span< const ua::MonitoringHandle >) - the monitored-item handles to remove from the wrapped namespace.
  • callback (DeleteMonitoringCallback) - invoked with the per-handle removal results.
void modify_monitoring(std::span< const ua::MonitoringModifyItem > items, ModifyMonitoringCallback callback) override

Forwards monitored-item modification to the wrapped namespace.

ua::shared_ptr< ua::NamespaceHistoryDelegate > history_delegate() noexcept override

Returns the delegate that provides historical-access for nodes in this namespace.

Returns: The history delegate, or nullptr if this namespace has no history support.

ua::SemanticChangeSource * semantic_change_source() noexcept override

Optional capability for SemanticsChanged delivery (CTT Data Access Analog 008).

Returns: The namespace's SemanticChangeSource used to signal SemanticsChanged data-changes, or nullptr when the namespace does not track semantic changes.

std::optional< ua::PermissionType > effective_permissions(const ua::AccessIdentity &identity, std::optional< ua::NodeAccessor > node) const override

Forwards the wrapped namespace's access-control answer unchanged.

  • identity (const ua::AccessIdentity &) - the identity whose permissions are being resolved.
  • node (std::optional< ua::NodeAccessor >) - the node the permissions are wanted for, or nullopt for the namespace itself.

Returns: the wrapped namespace's answer, unchanged.

void effective_permissions_async(ua::shared_ptr< const ua::AccessIdentity > identity, std::optional< std::vector< ua::NodeId > > nodes, ua::EffectivePermissionsCallback callback) override

Forwards asynchronous effective-permission resolution to the wrapped namespace.

void validate_role_permissions_update_async(ua::NodeId nodeId, std::optional< std::vector< ua::RolePermissionType > > proposedRolePermissions, std::function< void(ua::VoidResult)> callback) noexcept override

Forwards prospective RolePermissions operability validation to the wrapped namespace.

std::optional< std::vector< ua::RolePermissionType > > default_role_permissions() const override

Forwards the wrapped namespace's Part-18 default.

Returns: the wrapped namespace's default RolePermissions, or nullopt when it declares none.

std::optional< ua::AccessRestrictionType > default_access_restrictions() const override

Forwards the wrapped namespace's channel default.

Returns: the wrapped namespace's default AccessRestrictions, or nullopt when it declares none.

void on_identity_released(const ua::AccessIdentityKey &key) noexcept override

Forwards the identity-lifetime notification to the wrapped namespace.

  • key (const ua::AccessIdentityKey &) - the identity that has been released.
std::optional< ua::NodeId > metadata_object() const override

Forwards the metadata Object already served by the wrapped namespace.

Returns: the wrapped namespace's NamespaceMetadata Object, or nullopt when it serves none.

ua::history::SqliteConnection

class

RAII wrapper around a sqlite3* connection handle.

Opens or creates a SQLite database at the given path.

Functions

SqliteConnection(const std::string &dbPath)

Open (or create) the SQLite database at dbPath.

  • dbPath (const std::string &) - filesystem path of the SQLite database to open or create.
SqliteConnection(SqliteConnection &&) noexcept=default

Move-constructible; ownership of the underlying sqlite3* handle transfers.

SqliteConnection & operator=(SqliteConnection &&) noexcept=default

Move-assignable; ownership of the underlying sqlite3* handle transfers.

Returns: reference to this connection.

ua::VoidResult execute(const char *sql)

Execute a SQL statement that returns no results (CREATE TABLE, etc.).

  • sql (const char *) - the SQL statement to run (expected to produce no result rows).

Returns: a VoidResult that carries an error if the statement fails.

sqlite3 * handle() noexcept

Access the raw handle for statement preparation.

Returns: the underlying sqlite3* connection handle.

ua::history::SqliteStatement

class

RAII wrapper around a sqlite3_stmt* prepared statement.

Functions

SqliteStatement(SqliteConnection &connection, const char *sql)

Prepare sql against connection.

  • connection (SqliteConnection &) - the open connection the statement is prepared against.
  • sql (const char *) - the SQL text to compile into a prepared statement.
SqliteStatement(SqliteStatement &&) noexcept=default

Move-constructible; ownership of the prepared sqlite3_stmt* transfers.

SqliteStatement & operator=(SqliteStatement &&) noexcept=default

Move-assignable; ownership of the prepared sqlite3_stmt* transfers.

Returns: reference to this statement.

void bind_text(int index, std::string_view value)

Bind a text value to parameter index.

  • index (int) - the 1-based parameter position to bind.
  • value (std::string_view) - the text value to bind.
void bind_int64(int index, int64_t value)

Bind a 64-bit integer to parameter index.

  • index (int) - the 1-based parameter position to bind.
  • value (int64_t) - the 64-bit integer value to bind.
void bind_double(int index, double value)

Bind a floating-point value to parameter index.

  • index (int) - the 1-based parameter position to bind.
  • value (double) - the floating-point value to bind.
void bind_blob(int index, std::span< const uint8_t > data)

Bind a binary blob to parameter index.

void bind_null(int index)

Bind SQL NULL to parameter index.

  • index (int) - the 1-based parameter position to set to SQL NULL.
bool step()

Returns true if a row is available (SQLITE_ROW), false on SQLITE_DONE.

Returns: true if a row is available (SQLITE_ROW), false on SQLITE_DONE.

void reset()

Reset the statement and clear bindings for reuse.

int64_t column_int64(int index) const

Read column index of the current row as a 64-bit integer.

  • index (int) - the 0-based column position to read.

Returns: the column value as a 64-bit integer.

double column_double(int index) const

Read column index of the current row as a floating-point value.

  • index (int) - the 0-based column position to read.

Returns: the column value as a floating-point number.

std::string_view column_text(int index) const

Read column index of the current row as text (valid until the next step/reset).

  • index (int) - the 0-based column position to read.

Returns: the column text, valid until the next step/reset.

std::span< const uint8_t > column_blob(int index) const

Read column index of the current row as a binary blob (valid until the next step/reset).

  • index (int) - the 0-based column position to read.

Returns: the column blob, valid until the next step/reset.

int column_bytes(int index) const

Byte length of column index in the current row.

  • index (int) - the 0-based column position to measure.

Returns: the byte length of the column value.

bool column_is_null(int index) const

Whether column index of the current row is SQL NULL.

  • index (int) - the 0-based column position to test.

Returns: true if the column value is SQL NULL.

ua::history::StatementResetGuard

class

Ensures a SqliteStatement is reset on scope exit.

Functions

Capture stmt, resetting it on scope exit.

  • stmt (SqliteStatement &) - the statement to reset when this guard goes out of scope.
~StatementResetGuard()

ua::history::SqliteHistoryStore

class

SQLite-backed HistoryStore - the real persistence layer for the reference Historical Access implementation.

Raw values live in history_values keyed by (node_id, source_time); the full DataValue (value + status + timestamps) is stored as a UA-Binary BLOB via the SDK codec. Modification records live in history_modifications. Annotations are stored decomposed into their own fields rather than as an encoded Variant, so no structure-resolving codec is required (this is a store-implementation choice; the seam only requires that an annotation DataValue round-trips, see history_store.h). All access is single-threaded (driven from the delegate's worker strand), so no internal synchronisation is needed.

Per the HistoryStore failure contract, every method returns a ua::Result and never throws: SQLite/codec errors raised internally as ua::UaException are caught at the seam boundary and converted to an error Result carrying an ErrorDetail.

Range/bound queries map the engine's exclusive bounds to inclusive integer-tick bounds (+/-1 tick) so a single prepared BETWEEN statement serves every inclusivity combination.

Functions

SqliteHistoryStore(const std::string &dbPath, ua::shared_ptr< const ua::UaBinaryDataValueCodec > codec)

Open (or create) the SQLite-backed store at dbPath, using codec to serialise and deserialise stored DataValues.

  • dbPath (const std::string &) - filesystem path of the SQLite database to open or create.
  • codec (ua::shared_ptr< const ua::UaBinaryDataValueCodec >) - codec used to serialise and deserialise stored DataValues.
ua::Result< std::vector< ua::DataValue > > read_values(const ua::NodeId &node, std::optional< ua::DateTime > lower, bool lower_inclusive, std::optional< ua::DateTime > upper, bool upper_inclusive, uint32_t limit) override

Raw values whose SourceTimestamp lies in the (lower, upper) interval with the given inclusivity, ordered ascending by SourceTimestamp (ties broken by insertion order).

  • node (const ua::NodeId &) - The Variable node whose raw history is queried.
  • lower (std::optional< ua::DateTime >) - Lower time bound, or std::nullopt for unbounded below.
  • lower_inclusive (bool) - Whether a value exactly at lower is included.
  • upper (std::optional< ua::DateTime >) - Upper time bound, or std::nullopt for unbounded above.
  • upper_inclusive (bool) - Whether a value exactly at upper is included.
  • limit (uint32_t) - Maximum number of values to return; 0 means no limit.

Returns: The matching raw values ascending by SourceTimestamp, or an error Result on storage failure.

ua::Result< std::optional< ua::DataValue > > read_nearest_value(const ua::NodeId &node, ua::DateTime reference, Direction direction, bool inclusive) override

The nearest raw value at/around reference in the given direction.

  • node (const ua::NodeId &) - The Variable node whose raw history is queried.
  • reference (ua::DateTime) - Reference timestamp the search is relative to.
  • direction (Direction) - Whether to search towards earlier (Before) or later (After) timestamps.
  • inclusive (bool) - Whether a value exactly at reference qualifies.

Returns: The nearest matching value, a good empty optional if none exists, or an error Result on storage failure.

ua::Result< std::optional< ua::DataValue > > read_value_at(const ua::NodeId &node, ua::DateTime timestamp) override

The raw value whose SourceTimestamp exactly equals timestamp, if any (collision detection for Insert/Replace/Update and exact-match for AtTime / DeleteAtTime).

  • node (const ua::NodeId &) - The Variable node whose raw history is queried.
  • timestamp (ua::DateTime) - The exact SourceTimestamp to match.

Returns: The value at timestamp, a good empty optional if none exists, or an error Result on storage failure.

ua::VoidResult insert_value(const ua::NodeId &node, const ua::DataValue &value) override

Insert or overwrite the value at its SourceTimestamp.

  • node (const ua::NodeId &) - The Variable node whose raw history is written.
  • value (const ua::DataValue &) - The value to insert or overwrite, keyed by its SourceTimestamp.

Returns: A good VoidResult on success, or an error carrying the storage failure.

ua::VoidResult delete_value_at(const ua::NodeId &node, ua::DateTime timestamp) override

Remove the value whose SourceTimestamp exactly equals timestamp.

  • node (const ua::NodeId &) - The Variable node whose raw history is modified.
  • timestamp (ua::DateTime) - The exact SourceTimestamp of the value to remove.

Returns: A good VoidResult on success, or an error carrying the storage failure.

ua::Result< std::size_t > delete_values(const ua::NodeId &node, ua::DateTime start, ua::DateTime end) override

Remove all values whose SourceTimestamp lies in the [start, end] closed interval.

  • node (const ua::NodeId &) - The Variable node whose raw history is modified.
  • start (ua::DateTime) - Inclusive start of the SourceTimestamp interval to delete.
  • end (ua::DateTime) - Inclusive end of the SourceTimestamp interval to delete.

Returns: The number of values removed, or an error Result on storage failure.

ua::VoidResult insert_modification(const ua::NodeId &node, const ua::DataValue &value, const ua::ModificationInfo &info) override

Record a modification (Insert/Replace/Update/Delete) of the value at its SourceTimestamp.

  • node (const ua::NodeId &) - The Variable node whose modification history is written.
  • value (const ua::DataValue &) - The value the modification applies to, keyed by its SourceTimestamp.
  • info (const ua::ModificationInfo &) - The modification record (update type, time, user) to store.

Returns: A good VoidResult on success, or an error carrying the storage failure.

ua::Result< std::vector< ModifiedValue > > read_modifications(const ua::NodeId &node, std::optional< ua::DateTime > lower, bool lower_inclusive, std::optional< ua::DateTime > upper, bool upper_inclusive, uint32_t limit) override

Modification records whose SourceTimestamp lies in (lower, upper) with the given inclusivity, ordered ascending by SourceTimestamp (ties broken by modification order).

  • node (const ua::NodeId &) - The Variable node whose modification history is queried.
  • lower (std::optional< ua::DateTime >) - Lower time bound, or std::nullopt for unbounded below.
  • lower_inclusive (bool) - Whether a record exactly at lower is included.
  • upper (std::optional< ua::DateTime >) - Upper time bound, or std::nullopt for unbounded above.
  • upper_inclusive (bool) - Whether a record exactly at upper is included.
  • limit (uint32_t) - Maximum number of records to return; 0 means no limit.

Returns: The matching modification records ascending by SourceTimestamp, or an error Result on storage failure.

ua::Result< bool > has_modification_at(const ua::NodeId &node, ua::DateTime timestamp) override

Whether a modification record exists at exactly timestamp (drives the Raw-read ExtraData bit).

  • node (const ua::NodeId &) - The Variable node whose modification history is queried.
  • timestamp (ua::DateTime) - The exact SourceTimestamp to test.

Returns: True if a modification record exists at timestamp, or an error Result on storage failure.

ua::VoidResult insert_event(const ua::NodeId &node, const StoredEvent &event) override

Store a historical Event.

  • node (const ua::NodeId &) - The notifier node the event is stored under.
  • event (const StoredEvent &) - The historical event to store.

Returns: A good VoidResult on success, or an error carrying the storage failure.

ua::Result< std::vector< StoredEvent > > read_events(const ua::NodeId &node, std::optional< ua::DateTime > lower, bool lower_inclusive, std::optional< ua::DateTime > upper, bool upper_inclusive, uint32_t limit) override

Events whose Time lies in (lower, upper) with the given inclusivity, ordered ascending by Time (ties broken by insertion order).

  • node (const ua::NodeId &) - The notifier node whose event history is queried.
  • lower (std::optional< ua::DateTime >) - Lower time bound, or std::nullopt for unbounded below.
  • lower_inclusive (bool) - Whether an event exactly at lower is included.
  • upper (std::optional< ua::DateTime >) - Upper time bound, or std::nullopt for unbounded above.
  • upper_inclusive (bool) - Whether an event exactly at upper is included.
  • limit (uint32_t) - Maximum number of events to return; 0 means no limit.

Returns: The matching events ascending by Time, or an error Result on storage failure.

ua::Result< std::optional< StoredEvent > > read_event(const ua::NodeId &node, const ua::ByteString &eventId) override

The stored Event with the given EventId, if any (for Replace/Update).

  • node (const ua::NodeId &) - The notifier node whose event history is queried.
  • eventId (const ua::ByteString &) - The EventId identifying the stored event.

Returns: The event with eventId, a good empty optional if none exists, or an error Result on storage failure.

ua::Result< bool > delete_event(const ua::NodeId &node, const ua::ByteString &eventId) override

Delete the Event with the given EventId.

  • node (const ua::NodeId &) - The notifier node whose event history is modified.
  • eventId (const ua::ByteString &) - The EventId identifying the event to delete.

Returns: True if an event was removed, false if none matched, or an error Result on storage failure.

ua::VoidResult insert_annotation(const ua::NodeId &node, const ua::DataValue &annotation) override

Insert or overwrite the annotation at its SourceTimestamp.

  • node (const ua::NodeId &) - The Variable node the annotation is stored under.
  • annotation (const ua::DataValue &) - The annotation as a DataValue whose Value is an Annotation, keyed by its SourceTimestamp.

Returns: A good VoidResult on success, or an error carrying the storage failure.

ua::Result< std::optional< ua::DataValue > > read_annotation_at(const ua::NodeId &node, ua::DateTime timestamp) override

The annotation at exactly timestamp, if any (as a DataValue whose Value is an Annotation).

  • node (const ua::NodeId &) - The Variable node whose annotations are queried.
  • timestamp (ua::DateTime) - The exact SourceTimestamp to match.

Returns: The annotation at timestamp, a good empty optional if none exists, or an error Result on storage failure.

ua::VoidResult delete_annotation_at(const ua::NodeId &node, ua::DateTime timestamp) override

Remove the annotation at exactly timestamp.

  • node (const ua::NodeId &) - The Variable node whose annotations are modified.
  • timestamp (ua::DateTime) - The exact SourceTimestamp of the annotation to remove.

Returns: A good VoidResult on success, or an error carrying the storage failure.

ua::history::ModifiedValue

struct

A raw historical value together with the modification record that produced it.

Returned by read_modifications for ReadModified.

Public attributes

ua::DataValue value

The historical value as stored.

ua::ModificationInfo info

The modification record (update type, time, user) that produced it.

ua::history::StoredEvent

struct

A stored historical Event.

fields maps an opaque field key to that field's value. The key is a token the engine assigns (see HistoryEngine::field_key); a store MUST persist and return keys byte-for-byte and MUST NOT parse or interpret them. This lets a backend keep event fields in a generic key/value table without understanding OPC UA browse paths, and lets the engine change the key format without breaking any store.

time (the event's Time field) and event_id (its EventId field) are derived views the store windows and identifies on: they are the canonical copy the store indexes by, and the engine also keeps them inside fields so a read can project the Time/EventId select clauses. A store reads time/event_id for ordering and lookup and round-trips fields opaquely.

Public attributes

ua::DateTime time

The event's Time field; the store windows and orders on this.

ua::ByteString event_id

The event's EventId field; the store identifies the event by this.

std::map< std::string, ua::Variant > fields

All event fields, keyed by the engine's opaque field key.

ua::history::HistoryStore

class

Storage backend seam for the Historical Access reference implementation.

The Part-11 semantics (windowing, bounds, continuation, status fan-out, interpolation, modification-record construction) live in HistoryEngine, which is storage-agnostic and drives a HistoryStore. A customer plugs in their own backend (a historian, an RDBMS, a time-series DB) by implementing this seam; SqliteHistoryStore is the bundled reference implementation, and works against an in-memory SQLite database as well as a file.

Failure contract. Every method returns a ua::Result<T> / ua::VoidResult and never throws: a storage failure is reported as an error Result carrying a StatusCode and an ErrorDetail, which the engine forwards into the per-item history result. A successful read that simply finds nothing is a good Result holding an empty std::optional / empty vector - it is not an error. (This is why a lookup returns Result<optional<...>> rather than optional<...>.)

All methods are invoked from the delegate's single worker strand, so implementations do not need to be internally synchronised.

Functions

~HistoryStore()=default
ua::Result< std::vector< ua::DataValue > > read_values(const ua::NodeId &node, std::optional< ua::DateTime > lower, bool lower_inclusive, std::optional< ua::DateTime > upper, bool upper_inclusive, uint32_t limit)=0

Raw values whose SourceTimestamp lies in the (lower, upper) interval with the given inclusivity, ordered ascending by SourceTimestamp (ties broken by insertion order).

  • node (const ua::NodeId &) - The Variable node whose raw history is queried.
  • lower (std::optional< ua::DateTime >) - Lower time bound, or std::nullopt for unbounded below.
  • lower_inclusive (bool) - Whether a value exactly at lower is included.
  • upper (std::optional< ua::DateTime >) - Upper time bound, or std::nullopt for unbounded above.
  • upper_inclusive (bool) - Whether a value exactly at upper is included.
  • limit (uint32_t) - Maximum number of values to return; 0 means no limit.

Returns: The matching raw values ascending by SourceTimestamp, or an error Result on storage failure.

ua::Result< std::optional< ua::DataValue > > read_nearest_value(const ua::NodeId &node, ua::DateTime reference, Direction direction, bool inclusive)=0

The nearest raw value at/around reference in the given direction.

  • node (const ua::NodeId &) - The Variable node whose raw history is queried.
  • reference (ua::DateTime) - Reference timestamp the search is relative to.
  • direction (Direction) - Whether to search towards earlier (Before) or later (After) timestamps.
  • inclusive (bool) - Whether a value exactly at reference qualifies.

Returns: The nearest matching value, a good empty optional if none exists, or an error Result on storage failure.

ua::Result< std::optional< ua::DataValue > > read_value_at(const ua::NodeId &node, ua::DateTime timestamp)=0

The raw value whose SourceTimestamp exactly equals timestamp, if any (collision detection for Insert/Replace/Update and exact-match for AtTime / DeleteAtTime).

  • node (const ua::NodeId &) - The Variable node whose raw history is queried.
  • timestamp (ua::DateTime) - The exact SourceTimestamp to match.

Returns: The value at timestamp, a good empty optional if none exists, or an error Result on storage failure.

ua::VoidResult insert_value(const ua::NodeId &node, const ua::DataValue &value)=0

Insert or overwrite the value at its SourceTimestamp.

  • node (const ua::NodeId &) - The Variable node whose raw history is written.
  • value (const ua::DataValue &) - The value to insert or overwrite, keyed by its SourceTimestamp.

Returns: A good VoidResult on success, or an error carrying the storage failure.

ua::VoidResult delete_value_at(const ua::NodeId &node, ua::DateTime timestamp)=0

Remove the value whose SourceTimestamp exactly equals timestamp.

  • node (const ua::NodeId &) - The Variable node whose raw history is modified.
  • timestamp (ua::DateTime) - The exact SourceTimestamp of the value to remove.

Returns: A good VoidResult on success, or an error carrying the storage failure.

ua::Result< std::size_t > delete_values(const ua::NodeId &node, ua::DateTime start, ua::DateTime end)=0

Remove all values whose SourceTimestamp lies in the [start, end] closed interval.

  • node (const ua::NodeId &) - The Variable node whose raw history is modified.
  • start (ua::DateTime) - Inclusive start of the SourceTimestamp interval to delete.
  • end (ua::DateTime) - Inclusive end of the SourceTimestamp interval to delete.

Returns: The number of values removed, or an error Result on storage failure.

ua::VoidResult insert_modification(const ua::NodeId &node, const ua::DataValue &value, const ua::ModificationInfo &info)=0

Record a modification (Insert/Replace/Update/Delete) of the value at its SourceTimestamp.

  • node (const ua::NodeId &) - The Variable node whose modification history is written.
  • value (const ua::DataValue &) - The value the modification applies to, keyed by its SourceTimestamp.
  • info (const ua::ModificationInfo &) - The modification record (update type, time, user) to store.

Returns: A good VoidResult on success, or an error carrying the storage failure.

ua::Result< std::vector< ModifiedValue > > read_modifications(const ua::NodeId &node, std::optional< ua::DateTime > lower, bool lower_inclusive, std::optional< ua::DateTime > upper, bool upper_inclusive, uint32_t limit)=0

Modification records whose SourceTimestamp lies in (lower, upper) with the given inclusivity, ordered ascending by SourceTimestamp (ties broken by modification order).

  • node (const ua::NodeId &) - The Variable node whose modification history is queried.
  • lower (std::optional< ua::DateTime >) - Lower time bound, or std::nullopt for unbounded below.
  • lower_inclusive (bool) - Whether a record exactly at lower is included.
  • upper (std::optional< ua::DateTime >) - Upper time bound, or std::nullopt for unbounded above.
  • upper_inclusive (bool) - Whether a record exactly at upper is included.
  • limit (uint32_t) - Maximum number of records to return; 0 means no limit.

Returns: The matching modification records ascending by SourceTimestamp, or an error Result on storage failure.

ua::Result< bool > has_modification_at(const ua::NodeId &node, ua::DateTime timestamp)=0

Whether a modification record exists at exactly timestamp (drives the Raw-read ExtraData bit).

  • node (const ua::NodeId &) - The Variable node whose modification history is queried.
  • timestamp (ua::DateTime) - The exact SourceTimestamp to test.

Returns: True if a modification record exists at timestamp, or an error Result on storage failure.

ua::VoidResult insert_event(const ua::NodeId &node, const StoredEvent &event)=0

Store a historical Event.

  • node (const ua::NodeId &) - The notifier node the event is stored under.
  • event (const StoredEvent &) - The historical event to store.

Returns: A good VoidResult on success, or an error carrying the storage failure.

ua::Result< std::vector< StoredEvent > > read_events(const ua::NodeId &node, std::optional< ua::DateTime > lower, bool lower_inclusive, std::optional< ua::DateTime > upper, bool upper_inclusive, uint32_t limit)=0

Events whose Time lies in (lower, upper) with the given inclusivity, ordered ascending by Time (ties broken by insertion order).

  • node (const ua::NodeId &) - The notifier node whose event history is queried.
  • lower (std::optional< ua::DateTime >) - Lower time bound, or std::nullopt for unbounded below.
  • lower_inclusive (bool) - Whether an event exactly at lower is included.
  • upper (std::optional< ua::DateTime >) - Upper time bound, or std::nullopt for unbounded above.
  • upper_inclusive (bool) - Whether an event exactly at upper is included.
  • limit (uint32_t) - Maximum number of events to return; 0 means no limit.

Returns: The matching events ascending by Time, or an error Result on storage failure.

ua::Result< std::optional< StoredEvent > > read_event(const ua::NodeId &node, const ua::ByteString &eventId)=0

The stored Event with the given EventId, if any (for Replace/Update).

  • node (const ua::NodeId &) - The notifier node whose event history is queried.
  • eventId (const ua::ByteString &) - The EventId identifying the stored event.

Returns: The event with eventId, a good empty optional if none exists, or an error Result on storage failure.

ua::Result< bool > delete_event(const ua::NodeId &node, const ua::ByteString &eventId)=0

Delete the Event with the given EventId.

  • node (const ua::NodeId &) - The notifier node whose event history is modified.
  • eventId (const ua::ByteString &) - The EventId identifying the event to delete.

Returns: True if an event was removed, false if none matched, or an error Result on storage failure.

ua::VoidResult insert_annotation(const ua::NodeId &node, const ua::DataValue &annotation)=0

Insert or overwrite the annotation at its SourceTimestamp.

  • node (const ua::NodeId &) - The Variable node the annotation is stored under.
  • annotation (const ua::DataValue &) - The annotation as a DataValue whose Value is an Annotation, keyed by its SourceTimestamp.

Returns: A good VoidResult on success, or an error carrying the storage failure.

ua::Result< std::optional< ua::DataValue > > read_annotation_at(const ua::NodeId &node, ua::DateTime timestamp)=0

The annotation at exactly timestamp, if any (as a DataValue whose Value is an Annotation).

  • node (const ua::NodeId &) - The Variable node whose annotations are queried.
  • timestamp (ua::DateTime) - The exact SourceTimestamp to match.

Returns: The annotation at timestamp, a good empty optional if none exists, or an error Result on storage failure.

ua::VoidResult delete_annotation_at(const ua::NodeId &node, ua::DateTime timestamp)=0

Remove the annotation at exactly timestamp.

  • node (const ua::NodeId &) - The Variable node whose annotations are modified.
  • timestamp (ua::DateTime) - The exact SourceTimestamp of the annotation to remove.

Returns: A good VoidResult on success, or an error carrying the storage failure.

Enumerations

ua::history::Direction

enum

Direction of a nearest-value lookup relative to a reference timestamp.

  • Before - towards earlier timestamps
  • After - towards later timestamps

Was this page helpful?