@@ -50,7 +50,7 @@ use spacetimedb_sats::{AlgebraicType, AlgebraicValue, ProductType, ProductValue}
5050use spacetimedb_schema:: def:: { ModuleDef , TableDef , ViewDef } ;
5151use spacetimedb_schema:: reducer_name:: ReducerName ;
5252use spacetimedb_schema:: schema:: {
53- ColumnSchema , IndexSchema , RowLevelSecuritySchema , Schema , SequenceSchema , TableSchema ,
53+ ColumnSchema , IndexSchema , RowLevelSecuritySchema , Schema , SequenceSchema , TableSchema , VIEW_ARG_HASH_COL ,
5454} ;
5555use spacetimedb_schema:: table_name:: TableName ;
5656use spacetimedb_snapshot:: { DynSnapshotRepo , ReconstructedSnapshot , SnapshotError , SnapshotRepository } ;
@@ -1559,10 +1559,10 @@ impl RelationalDB {
15591559 Ok ( None )
15601560 }
15611561
1562- /// Write `rows` into a ( sender) view's backing table.
1562+ /// Write `rows` into a sender-scoped view's backing table.
15631563 ///
15641564 /// # Process
1565- /// 1. Delete all rows for `sender` from the view's backing table
1565+ /// 1. Delete all rows for `sender`'s implicit argument hash from the view's backing table
15661566 /// 2. Insert the new rows into the backing table
15671567 ///
15681568 /// # Arguments
@@ -1578,39 +1578,24 @@ impl RelationalDB {
15781578 sender : Identity ,
15791579 rows : Vec < ProductValue > ,
15801580 ) -> Result < ( ) , DBError > {
1581- // Delete rows for `sender` from the backing table
1582- let rows_to_delete = self
1583- . iter_by_col_eq_mut ( tx, table_id, ColId ( 0 ) , & sender. into ( ) ) ?
1584- . map ( |res| res. pointer ( ) )
1585- . collect :: < Vec < _ > > ( ) ;
1586- self . delete ( tx, table_id, rows_to_delete) ;
1587-
1588- self . write_view_rows ( tx, table_id, rows, Some ( sender) ) ?;
1589-
1590- Ok ( ( ) )
1581+ let arg_hash = MutTxId :: view_arg_hash ( sender) ;
1582+ self . materialize_view_arg_hash ( tx, table_id, arg_hash, rows)
15911583 }
15921584
1593- /// Write `rows` into an anonymous view's backing table.
1594- ///
1595- /// # Process
1596- /// 1. Clear the view's backing table
1597- /// 2. Insert the new rows into the backing table
1598- ///
1599- /// # Arguments
1600- /// * `tx` - Mutable transaction context
1601- /// * `table_id` - The id of the view's backing table
1602- /// * `rows` - Product values to insert
1603- #[ allow( clippy:: too_many_arguments) ]
1604- pub fn materialize_anonymous_view (
1585+ fn materialize_view_arg_hash (
16051586 & self ,
16061587 tx : & mut MutTxId ,
16071588 table_id : TableId ,
1589+ arg_hash : AlgebraicValue ,
16081590 rows : Vec < ProductValue > ,
16091591 ) -> Result < ( ) , DBError > {
1610- // Clear entire backing table
1611- self . clear_table ( tx, table_id) ?;
1592+ let rows_to_delete = self
1593+ . iter_by_col_eq_mut ( tx, table_id, VIEW_ARG_HASH_COL , & arg_hash) ?
1594+ . map ( |res| res. pointer ( ) )
1595+ . collect :: < Vec < _ > > ( ) ;
1596+ self . delete ( tx, table_id, rows_to_delete) ;
16121597
1613- self . write_view_rows ( tx, table_id, rows, None ) ?;
1598+ self . write_view_rows ( tx, table_id, rows, & arg_hash ) ?;
16141599
16151600 Ok ( ( ) )
16161601 }
@@ -1626,10 +1611,11 @@ impl RelationalDB {
16261611 view_call : ViewCallInfo ,
16271612 rows : Vec < ProductValue > ,
16281613 ) -> Result < ( ) , DBError > {
1629- match view_call. sender {
1630- Some ( sender) => self . materialize_view ( tx, table_id, sender, rows) ?,
1631- None => self . materialize_anonymous_view ( tx, table_id, rows) ?,
1632- }
1614+ let arg_hash = match view_call. sender {
1615+ Some ( sender) => MutTxId :: view_arg_hash ( sender) ,
1616+ None => MutTxId :: anonymous_view_arg_hash ( ) ,
1617+ } ;
1618+ self . materialize_view_arg_hash ( tx, table_id, arg_hash, rows) ?;
16331619 tx. replace_view_read_set ( view_call) ;
16341620
16351621 Ok ( ( ) )
@@ -1640,34 +1626,18 @@ impl RelationalDB {
16401626 tx : & mut MutTxId ,
16411627 table_id : TableId ,
16421628 rows : Vec < ProductValue > ,
1643- sender : Option < Identity > ,
1629+ arg_hash : & AlgebraicValue ,
16441630 ) -> Result < ( ) , DBError > {
1645- match sender {
1646- Some ( sender) => {
1647- for product in rows {
1648- let value = ProductValue :: from_iter ( std:: iter:: once ( sender. into ( ) ) . chain ( product. elements ) ) ;
1649- self . insert (
1650- tx,
1651- table_id,
1652- & value
1653- . to_bsatn_vec ( )
1654- . map_err ( |_| ViewError :: SerializeRow )
1655- . map_err ( DatastoreError :: from) ?,
1656- ) ?;
1657- }
1658- }
1659- None => {
1660- for product in rows {
1661- self . insert (
1662- tx,
1663- table_id,
1664- & product
1665- . to_bsatn_vec ( )
1666- . map_err ( |_| ViewError :: SerializeRow )
1667- . map_err ( DatastoreError :: from) ?,
1668- ) ?;
1669- }
1670- }
1631+ for product in rows {
1632+ let value = ProductValue :: from_iter ( std:: iter:: once ( arg_hash. clone ( ) ) . chain ( product. elements ) ) ;
1633+ self . insert (
1634+ tx,
1635+ table_id,
1636+ & value
1637+ . to_bsatn_vec ( )
1638+ . map_err ( |_| ViewError :: SerializeRow )
1639+ . map_err ( DatastoreError :: from) ?,
1640+ ) ?;
16711641 }
16721642
16731643 Ok ( ( ) )
@@ -2256,8 +2226,8 @@ pub mod tests_utils {
22562226 row : ProductValue ,
22572227 ) -> Result < RowRef < ' a > , DBError > {
22582228 let meta_cols = match sender {
2259- Some ( identity) => vec ! [ identity . into ( ) ] ,
2260- None => vec ! [ ] ,
2229+ Some ( identity) => vec ! [ MutTxId :: view_arg_hash ( identity ) ] ,
2230+ None => vec ! [ MutTxId :: anonymous_view_arg_hash ( ) ] ,
22612231 } ;
22622232 let cols = meta_cols. into_iter ( ) . chain ( row. elements ) ;
22632233 let row = ProductValue :: from_iter ( cols) ;
@@ -2512,8 +2482,9 @@ mod tests {
25122482
25132483 fn project_views ( stdb : & TestDB , table_id : TableId , sender : Identity ) -> Vec < ProductValue > {
25142484 let tx = begin_tx ( stdb) ;
2485+ let arg_hash = MutTxId :: view_arg_hash ( sender) ;
25152486
2516- stdb. iter_by_col_eq ( & tx, table_id, 0 , & sender . into ( ) )
2487+ stdb. iter_by_col_eq ( & tx, table_id, VIEW_ARG_HASH_COL , & arg_hash )
25172488 . unwrap ( )
25182489 . map ( |row| {
25192490 let pv = row. to_product_value ( ) ;
@@ -2526,10 +2497,16 @@ mod tests {
25262497
25272498 fn project_anonymous_views ( stdb : & TestDB , table_id : TableId ) -> Vec < ProductValue > {
25282499 let tx = begin_tx ( stdb) ;
2500+ let arg_hash = MutTxId :: anonymous_view_arg_hash ( ) ;
25292501
2530- stdb. iter ( & tx, table_id)
2502+ stdb. iter_by_col_eq ( & tx, table_id, VIEW_ARG_HASH_COL , & arg_hash )
25312503 . unwrap ( )
2532- . map ( |row| row. to_product_value ( ) )
2504+ . map ( |row| {
2505+ let pv = row. to_product_value ( ) ;
2506+ ProductValue {
2507+ elements : pv. elements . iter ( ) . skip ( 1 ) . cloned ( ) . collect ( ) ,
2508+ }
2509+ } )
25332510 . collect ( )
25342511 }
25352512
@@ -2737,7 +2714,12 @@ mod tests {
27372714 let mut tx = begin_mut_tx ( & stdb) ;
27382715 tx. subscribe_view ( view_id, ArgId :: SENTINEL , stale_sender) ?;
27392716 tx. subscribe_view ( view_id, ArgId :: SENTINEL , live_sender) ?;
2740- stdb. materialize_anonymous_view ( & mut tx, table_id, vec ! [ product![ 42u8 ] ] ) ?;
2717+ stdb. materialize_view_call (
2718+ & mut tx,
2719+ table_id,
2720+ ViewCallInfo { view_id, sender : None } ,
2721+ vec ! [ product![ 42u8 ] ] ,
2722+ ) ?;
27412723 stdb. commit_tx ( tx) ?;
27422724
27432725 let mut tx = begin_mut_tx ( & stdb) ;
@@ -2786,7 +2768,12 @@ mod tests {
27862768
27872769 let mut tx = begin_mut_tx ( & stdb) ;
27882770 tx. subscribe_view ( view_id, ArgId :: SENTINEL , sender) ?;
2789- stdb. materialize_anonymous_view ( & mut tx, table_id, vec ! [ product![ 42u8 ] ] ) ?;
2771+ stdb. materialize_view_call (
2772+ & mut tx,
2773+ table_id,
2774+ ViewCallInfo { view_id, sender : None } ,
2775+ vec ! [ product![ 42u8 ] ] ,
2776+ ) ?;
27902777 stdb. commit_tx ( tx) ?;
27912778
27922779 let mut tx = begin_mut_tx ( & stdb) ;
0 commit comments