-
Notifications
You must be signed in to change notification settings - Fork 1k
More granular table traits #4775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 14 commits
1a4ba06
03d2091
aa84d00
a55e72b
c372050
cddd5f4
8beb8b2
6e28135
da07177
645c65d
3bb6b83
23ef57d
69b64b7
e7ba78e
371b4c3
5ef61f7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -183,13 +183,15 @@ pub struct {insert_callback_id}(__sdk::CallbackId); | |
| write!( | ||
| out, | ||
| " | ||
| impl<'ctx> __sdk::EventTable for {table_handle}<'ctx> {{ | ||
| impl<'ctx> __sdk::TableLike for {table_handle}<'ctx> {{ | ||
| type Row = {row_type}; | ||
| type EventContext = super::EventContext; | ||
|
|
||
| fn count(&self) -> u64 {{ self.imp.count() }} | ||
| fn iter(&self) -> impl Iterator<Item = {row_type}> + '_ {{ self.imp.iter() }} | ||
| }} | ||
|
|
||
| impl<'ctx> __sdk::WithInsert for {table_handle}<'ctx> {{ | ||
| type InsertCallbackId = {insert_callback_id}; | ||
|
|
||
| fn on_insert( | ||
|
|
@@ -203,6 +205,8 @@ impl<'ctx> __sdk::EventTable for {table_handle}<'ctx> {{ | |
| self.imp.remove_on_insert(callback.0) | ||
| }} | ||
| }} | ||
|
|
||
| impl<'ctx> __sdk::EventTable for {table_handle}<'ctx> {{}} | ||
|
Comment on lines
+208
to
+209
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need these empty impls? Maybe now Table can just be removed entirely? |
||
| " | ||
| ); | ||
| } else { | ||
|
|
@@ -213,13 +217,15 @@ impl<'ctx> __sdk::EventTable for {table_handle}<'ctx> {{ | |
| out, | ||
| "pub struct {delete_callback_id}(__sdk::CallbackId); | ||
|
|
||
| impl<'ctx> __sdk::Table for {table_handle}<'ctx> {{ | ||
| impl<'ctx> __sdk::TableLike for {table_handle}<'ctx> {{ | ||
| type Row = {row_type}; | ||
| type EventContext = super::EventContext; | ||
|
|
||
| fn count(&self) -> u64 {{ self.imp.count() }} | ||
| fn iter(&self) -> impl Iterator<Item = {row_type}> + '_ {{ self.imp.iter() }} | ||
| }} | ||
|
|
||
| impl<'ctx> __sdk::WithInsert for {table_handle}<'ctx> {{ | ||
| type InsertCallbackId = {insert_callback_id}; | ||
|
|
||
| fn on_insert( | ||
|
|
@@ -232,7 +238,9 @@ impl<'ctx> __sdk::Table for {table_handle}<'ctx> {{ | |
| fn remove_on_insert(&self, callback: {insert_callback_id}) {{ | ||
| self.imp.remove_on_insert(callback.0) | ||
| }} | ||
| }} | ||
|
|
||
| impl<'ctx> __sdk::WithDelete for {table_handle}<'ctx> {{ | ||
| type DeleteCallbackId = {delete_callback_id}; | ||
|
|
||
| fn on_delete( | ||
|
|
@@ -246,6 +254,8 @@ impl<'ctx> __sdk::Table for {table_handle}<'ctx> {{ | |
| self.imp.remove_on_delete(callback.0) | ||
| }} | ||
| }} | ||
|
|
||
| impl<'ctx> __sdk::Table for {table_handle}<'ctx> {{}} | ||
| " | ||
| ); | ||
|
|
||
|
|
@@ -258,7 +268,7 @@ impl<'ctx> __sdk::Table for {table_handle}<'ctx> {{ | |
| " | ||
| pub struct {update_callback_id}(__sdk::CallbackId); | ||
|
|
||
| impl<'ctx> __sdk::TableWithPrimaryKey for {table_handle}<'ctx> {{ | ||
| impl<'ctx> __sdk::WithUpdate for {table_handle}<'ctx> {{ | ||
| type UpdateCallbackId = {update_callback_id}; | ||
|
|
||
| fn on_update( | ||
|
|
@@ -272,6 +282,8 @@ impl<'ctx> __sdk::TableWithPrimaryKey for {table_handle}<'ctx> {{ | |
| self.imp.remove_on_update(callback.0) | ||
| }} | ||
| }} | ||
|
|
||
| impl<'ctx> __sdk::TableWithPrimaryKey for {table_handle}<'ctx> {{}} | ||
| " | ||
| ); | ||
| } | ||
|
|
@@ -1877,7 +1889,7 @@ impl<Ctx: __sdk::DbContext< | |
| out, | ||
| "EventContext", | ||
| Some("__sdk::Event<Reducer>"), | ||
| "[`__sdk::Table::on_insert`], [`__sdk::Table::on_delete`] and [`__sdk::TableWithPrimaryKey::on_update`] callbacks", | ||
| "[`__sdk::WithInsert::on_insert`], [`__sdk::WithDelete::on_delete`] and [`__sdk::WithUpdate::on_update`] callbacks", | ||
| Some("[`__sdk::Event`]"), | ||
| ); | ||
|
|
||
|
|
||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the main change to functionality. I wanted to have access to specific traits so in bevy_stdb I can go from: Before/after fn bind_insert<TRow, TTable>(world: &World, table: &TTable)
where
TRow: Send + Sync + Clone + InModule + 'static,
RowEvent<TRow>: Send + Sync,
- TTable: Table<
+ TTable: WithInsert<
Row = TRow,
EventContext = <<TRow as InModule>::Module as SpacetimeModule>::EventContext,
>,
TTable::EventContext: AbstractEventContext<Event = RowEvent<TRow>>,
{
let sender = channel_sender::<InsertMessage<TRow>>(world);
table.on_insert(move |ctx, row| {
let _ = sender.send(InsertMessage {
event: ctx.event().clone(),
row: row.clone(),
});
});
} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| //! The [`Table`] and [`TableWithPrimaryKey`] traits, | ||
| //! The [`TableLike`], [`Table`], [`TableWithPrimaryKey`], and [`EventTable`] traits, | ||
| //! together with the [`WithInsert`], [`WithDelete`], and [`WithUpdate`] capability traits, | ||
| //! which allow certain simple queries of the client cache, | ||
| //! and expose row callbacks which run when subscribed rows are inserted, deleted or updated. | ||
| //! | ||
|
|
@@ -7,12 +8,10 @@ | |
| //! which mediate access to tables in the client cache. | ||
| //! Obtain a table handle by calling a method on `ctx.db`, where `ctx` is a `DbConnection` or `EventContext`. | ||
|
|
||
| /// Trait implemented by table handles, which mediate access to tables in the client cache. | ||
| /// Common functionality shared by table-like handles. | ||
| /// | ||
| /// Obtain a table handle by calling a method on `ctx.db`, where `ctx` is a `DbConnection` or `EventContext`. | ||
| /// | ||
| /// For persistent (non-event) tables only. See [`EventTable`] for transient event tables. | ||
| pub trait Table { | ||
| pub trait TableLike { | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe this could have a better name? Its meant to be the common things all tables have. |
||
| /// The type of rows stored in this table. | ||
| type Row: 'static; | ||
|
|
||
|
|
@@ -24,20 +23,32 @@ pub trait Table { | |
|
|
||
| /// An iterator over all the subscribed rows in the client cache. | ||
| fn iter(&self) -> impl Iterator<Item = Self::Row> + '_; | ||
| } | ||
|
|
||
| /// Capability trait for table-like handles which support insert callbacks. | ||
| pub trait WithInsert: TableLike { | ||
| type InsertCallbackId; | ||
| /// Register a callback to run whenever a subscribed row is inserted into the client cache. | ||
|
|
||
| /// Register a callback to run whenever a row is observed as inserted by this table handle. | ||
| /// | ||
| /// For persistent tables, this means a subscribed row is inserted into the client cache. | ||
| /// For event tables, this means an event row is delivered. | ||
| /// | ||
| /// The returned [`Self::InsertCallbackId`] can be passed to [`Self::remove_on_insert`] | ||
| /// to cancel the callback. | ||
| fn on_insert( | ||
| &self, | ||
| callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, | ||
| ) -> Self::InsertCallbackId; | ||
|
|
||
| /// Cancel a callback previously registered by [`Self::on_insert`], causing it not to run in the future. | ||
| fn remove_on_insert(&self, callback: Self::InsertCallbackId); | ||
| } | ||
|
|
||
| /// Capability trait for table-like handles which support delete callbacks. | ||
| pub trait WithDelete: TableLike { | ||
| type DeleteCallbackId; | ||
|
|
||
| /// Register a callback to run whenever a subscribed row is deleted from the client cache. | ||
| /// | ||
| /// The returned [`Self::DeleteCallbackId`] can be passed to [`Self::remove_on_delete`] | ||
|
|
@@ -46,22 +57,15 @@ pub trait Table { | |
| &self, | ||
| callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, | ||
| ) -> Self::DeleteCallbackId; | ||
|
|
||
| /// Cancel a callback previously registered by [`Self::on_delete`], causing it not to run in the future. | ||
| fn remove_on_delete(&self, callback: Self::DeleteCallbackId); | ||
| } | ||
|
|
||
| /// Subtrait of [`Table`] implemented only by tables with a column designated as a primary key, | ||
| /// which allows the SDK to identify updates. | ||
| /// | ||
| /// SpacetimeDB does not have a special notion of updates as a primitive operation. | ||
| /// Instead, an update is a delete followed by an insert | ||
| /// of rows with the same primary key within the same transaction. | ||
| /// This means that the module's calls to `ctx.db.some_table().unique_column().update(...)` | ||
| /// may not result in an update event on the client if `unique_column` is not the primary key, | ||
| /// and that clients may observe update events resulting from deletes and inserts by the module | ||
| /// without going through such an `update` method. | ||
| pub trait TableWithPrimaryKey: Table { | ||
| /// Capability trait for table-like handles which support update callbacks. | ||
| pub trait WithUpdate: TableLike { | ||
| type UpdateCallbackId; | ||
|
|
||
| /// Register a callback to run whenever a subscribed row is updated within a transaction, | ||
| /// with an old version deleted and a new version inserted with the same primary key. | ||
| /// | ||
|
|
@@ -74,38 +78,34 @@ pub trait TableWithPrimaryKey: Table { | |
| &self, | ||
| callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, | ||
| ) -> Self::UpdateCallbackId; | ||
|
|
||
| /// Cancel a callback previously registered by [`Self::on_update`], causing it not to run in the future. | ||
| fn remove_on_update(&self, callback: Self::UpdateCallbackId); | ||
| } | ||
|
|
||
| /// Trait implemented by persistent table handles, which mediate access to tables in the client cache. | ||
| /// | ||
| /// Obtain a table handle by calling a method on `ctx.db`, where `ctx` is a `DbConnection` or `EventContext`. | ||
| /// | ||
| /// For persistent (non-event) tables only. See [`EventTable`] for transient event tables. | ||
| pub trait Table: TableLike + WithInsert + WithDelete {} | ||
|
|
||
| /// Subtrait of [`Table`] implemented only by tables with a column designated as a primary key, | ||
| /// which allows the SDK to identify updates. | ||
| /// | ||
| /// SpacetimeDB does not have a special notion of updates as a primitive operation. | ||
| /// Instead, an update is a delete followed by an insert | ||
| /// of rows with the same primary key within the same transaction. | ||
| /// This means that the module's calls to `ctx.db.some_table().unique_column().update(...)` | ||
| /// may not result in an update event on the client if `unique_column` is not the primary key, | ||
| /// and that clients may observe update events resulting from deletes and inserts by the module | ||
| /// without going through such an `update` method. | ||
| pub trait TableWithPrimaryKey: Table + WithUpdate {} | ||
|
|
||
| /// Trait for event tables, whose rows are transient and never persisted in the client cache. | ||
| /// | ||
| /// Event table rows are delivered as inserts but are not stored; | ||
| /// only `on_insert` callbacks fire, and `count`/`iter` always reflect an empty table. | ||
| /// | ||
| /// Obtain a table handle by calling a method on `ctx.db`, where `ctx` is a `DbConnection` or `EventContext`. | ||
| pub trait EventTable { | ||
| /// The type of rows in this table. | ||
| type Row: 'static; | ||
|
|
||
| /// The `EventContext` type generated for the module which defines this table. | ||
| type EventContext; | ||
|
|
||
| /// The number of subscribed rows in the client cache (always 0 for event tables). | ||
| fn count(&self) -> u64; | ||
|
|
||
| /// An iterator over all the subscribed rows in the client cache (always empty for event tables). | ||
| fn iter(&self) -> impl Iterator<Item = Self::Row> + '_; | ||
|
|
||
| type InsertCallbackId; | ||
| /// Register a callback to run whenever a row is inserted. | ||
| /// | ||
| /// The returned [`Self::InsertCallbackId`] can be passed to [`Self::remove_on_insert`] | ||
| /// to cancel the callback. | ||
| fn on_insert( | ||
| &self, | ||
| callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, | ||
| ) -> Self::InsertCallbackId; | ||
| /// Cancel a callback previously registered by [`Self::on_insert`], causing it not to run in the future. | ||
| fn remove_on_insert(&self, callback: Self::InsertCallbackId); | ||
| } | ||
| pub trait EventTable: TableLike + WithInsert {} | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trait changes mean we need updated codegen too (breaking).