#ifndef SPACETIMEDB_READONLY_DATABASE_CONTEXT_H #define SPACETIMEDB_READONLY_DATABASE_CONTEXT_H #include "readonly_table_accessor.h" #include "readonly_field_accessors.h" #include "database.h" #include namespace SpacetimeDB { /** * @brief Read-only database context for views * * ReadOnlyDatabaseContext provides a read-only interface to the database * for use in views. It prevents all mutation operations at compile-time. * * Key differences from DatabaseContext: * - No insert/update/delete operations * - No direct table iteration (prevents inefficient full table scans) * - Table data accessible ONLY through indexed field accessors * - Enforces efficient query patterns using indexes * * This is a completely separate type from DatabaseContext (no inheritance) * to match Rust's LocalReadOnly vs Local pattern. * * Example usage: * @code * SPACETIMEDB_VIEW(std::vector, get_adults, Public, ViewContext ctx) { * // Can only access via indexed fields * std::vector adults; * for (const auto& user : ctx.db[user_age].filter(range_from(18u))) { * adults.push_back(user); * } * return Ok(adults); * } * @endcode */ class ReadOnlyDatabaseContext { public: // Generic table accessor method (type-only, requires explicit table name later) template ReadOnlyTableAccessor table() const { return ReadOnlyTableAccessor{}; } // Name-based accessor that returns a configured table accessor template ReadOnlyTableAccessor table(const char* name) const { return ReadOnlyTableAccessor(std::string(name)); } // String overload template ReadOnlyTableAccessor table(const std::string& name) const { return table(name.c_str()); } // Tag-based accessor using operator[] (SpacetimeDB standard) template ReadOnlyTableAccessor operator[](const Tag&) const { static_assert(!Tag::__is_event_internal, "Event tables are not accessible from views."); return ReadOnlyTableAccessor(std::string(Tag::__table_name_internal)); } // Field tag accessors - read-only versions // These return read-only field accessors that only support querying, not mutation template ReadOnlyPrimaryKeyAccessor operator[]( const FieldTag& field_tag) const { static_assert(!IsEventTable, "Event tables are not accessible from views."); return ReadOnlyPrimaryKeyAccessor( field_tag.table_name, field_tag.field_name, field_tag.member_ptr); } template ReadOnlyUniqueAccessor operator[]( const FieldTag& field_tag) const { static_assert(!IsEventTable, "Event tables are not accessible from views."); return ReadOnlyUniqueAccessor( field_tag.table_name, field_tag.field_name, field_tag.member_ptr); } template ReadOnlyIndexedAccessor operator[]( const FieldTag& field_tag) const { static_assert(!IsEventTable, "Event tables are not accessible from views."); return ReadOnlyIndexedAccessor( field_tag.table_name, field_tag.field_name, field_tag.member_ptr); } template ReadOnlyRegularAccessor operator[]( const FieldTag& field_tag) const { static_assert(!IsEventTable, "Event tables are not accessible from views."); return ReadOnlyRegularAccessor( field_tag.table_name, field_tag.field_name, field_tag.member_ptr); } }; } // namespace SpacetimeDB #endif // SPACETIMEDB_READONLY_DATABASE_CONTEXT_H