Files
Jason Larabie 346e2b2514 Add C++ query builder (#4664)
# Description of Changes
- Added a query builder for C++ module bindings
  - Added query-builder table/filter/join types
- Added semijoin support with compile-time checks for lookup-table and
indexed-field usage
  - Added support for returning query-builder queries from C++ views
- Hooked query-builder metadata into the C++ table/view macros and V10
module-def path
- Added test coverage for the new C++ query-builder behavior
  - Compile tests for pass/fail cases
  - SQL tests for generated query output
  - Added a C++ test module for view primary key coverage
- **Update:** Switched the core to pass the columns and index-columns
metadata with the table source for better client-side codegen to have
some shared code between server + client.
# API and ABI breaking changes
- No intended API or ABI breaking changes
- Adds a new public query-builder API to the C++ bindings
- C++ views can now return query-builder query types in addition to
materialized row results

# Expected complexity level and risk

3 - Mostly contained to C++ bindings, but it touches macros, view
registration/serialization, and module-def generation, so there are a
few places where the pieces need to stay in sync.

# Testing

I've done end to end testing of I think every type as well as built some
tests to confirm the SQL output.

- [x] Run the C++ query-builder SQL tests
[crates/bindings-cpp/tests/query-builder-compile/run_query_builder_compile_tests.sh]
- [x] Smoke test a generated C++ module using query-builder views

---------

Signed-off-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: Ryan <r.ekhoff@clockworklabs.io>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-12 13:02:36 +00:00

88 lines
2.5 KiB
C++

#ifndef SPACETIMEDB_VIEW_CONTEXT_H
#define SPACETIMEDB_VIEW_CONTEXT_H
#include <spacetimedb/bsatn/types.h> // For Identity
#include <spacetimedb/bsatn/timestamp.h> // For Timestamp
#include <spacetimedb/query_builder.h>
#include <spacetimedb/readonly_database_context.h> // For ReadOnlyDatabaseContext
#include <array>
namespace SpacetimeDB {
/**
* @brief Context for views with caller identity
*
* ViewContext provides read-only database access along with the identity
* of the caller who invoked the view. Use this when the view needs to
* filter or customize results based on who is calling it.
*
* Key differences from ReducerContext:
* - db is ReadOnlyDatabaseContext (no mutations allowed)
* - No connection_id (views are stateless, don't track connections)
* - No rng() method (views should be deterministic)
*
* Example usage:
* @code
* SPACETIMEDB_VIEW(std::vector<Item>, get_my_items, Public, ViewContext ctx) {
* std::vector<Item> my_items;
* // Filter by caller's identity using indexed field
* for (const auto& item : ctx.db[item_owner].filter(ctx.sender())) {
* my_items.push_back(item);
* }
* return Ok(my_items);
* }
* @endcode
*/
struct ViewContext {
private:
// Caller's identity - who invoked this view
Identity sender_;
public:
// Read-only database access - no mutations allowed
ReadOnlyDatabaseContext db;
QueryBuilder from;
// Constructors
ViewContext() = default;
explicit ViewContext(Identity s)
: sender_(s) {}
Identity sender() const { return sender_; }
};
/**
* @brief Context for anonymous views without caller identity
*
* AnonymousViewContext provides read-only database access without
* exposing the caller's identity. Use this for views that return
* the same data regardless of who calls them.
*
* This is more efficient than ViewContext as it doesn't require
* identity information to be passed from the host.
*
* Key differences from ViewContext:
* - No sender field (caller identity not available)
* - Otherwise identical functionality
*
* Example usage:
* @code
* SPACETIMEDB_VIEW(std::optional<uint64_t>, count_users, Public, AnonymousViewContext ctx) {
* return Ok(std::optional<uint64_t>(ctx.db[user].count()));
* }
* @endcode
*/
struct AnonymousViewContext {
// Read-only database access - no mutations allowed
ReadOnlyDatabaseContext db;
QueryBuilder from;
// Constructors
AnonymousViewContext() = default;
};
} // namespace SpacetimeDB
#endif // SPACETIMEDB_VIEW_CONTEXT_H