@@ -821,7 +821,7 @@ impl RelationalDB {
821821
822822 let is_ephemeral_tables = |table_id : & TableId | -> bool {
823823 tx_data
824- . ephermal_tables ( )
824+ . ephemeral_tables ( )
825825 . map ( |etables| etables. contains ( table_id) )
826826 . unwrap_or ( false )
827827 } ;
@@ -2542,46 +2542,68 @@ mod tests {
25422542 Ok ( ( ) )
25432543 }
25442544
2545- #[ test]
2546- fn test_views ( ) -> ResultTest < ( ) > {
2547- let stdb = TestDB :: durable ( ) ?;
2545+ fn setup_view ( stdb : & TestDB ) -> ResultTest < ( ViewId , TableId , ModuleDef , ViewDef ) > {
25482546 let module_def = view_module_def ( ) ;
25492547 let view_def = module_def. view ( "my_view" ) . unwrap ( ) ;
25502548
2551- let row_type = view_def. product_type_ref ;
2552- let typespace = module_def. typespace ( ) ;
2549+ let mut tx = begin_mut_tx ( stdb) ;
2550+ let ( view_id, table_id) = stdb. create_view ( & mut tx, & module_def, view_def) ?;
2551+ stdb. commit_tx ( tx) ?;
2552+
2553+ Ok ( ( view_id, table_id, module_def. clone ( ) , view_def. clone ( ) ) )
2554+ }
25532555
2556+ fn insert_view_row (
2557+ stdb : & TestDB ,
2558+ view_id : ViewId ,
2559+ table_id : TableId ,
2560+ typespace : & Typespace ,
2561+ row_type : AlgebraicTypeRef ,
2562+ sender : Identity ,
2563+ v : u8 ,
2564+ ) -> ResultTest < ( ) > {
25542565 let to_bstan = |pv : & ProductValue | {
25552566 Bytes :: from ( to_vec ( & AlgebraicValue :: Array ( [ pv. clone ( ) ] . into ( ) ) ) . expect ( "bstan serialization failed" ) )
25562567 } ;
2557- let row_pv = |v : u8 | ProductValue :: from_iter ( vec ! [ AlgebraicValue :: U8 ( v) ] ) ;
25582568
2559- let project_views = |stdb : & TestDB , table_id : TableId , sender : Identity | {
2560- let tx = begin_tx ( stdb) ;
2561- stdb. iter_by_col_eq ( & tx, table_id, 0 , & sender. into ( ) )
2562- . unwrap ( )
2563- . map ( |row| ProductValue {
2564- elements : row. to_product_value ( ) . elements . iter ( ) . skip ( 1 ) . cloned ( ) . collect ( ) ,
2565- } )
2566- . collect :: < Vec < _ > > ( )
2567- } ;
2569+ let row_pv = |v : u8 | ProductValue :: from_iter ( vec ! [ AlgebraicValue :: U8 ( v) ] ) ;
25682570
2569- // Create the view
2570- let mut tx = begin_mut_tx ( & stdb ) ;
2571- let ( view_id , table_id ) = stdb. create_view ( & mut tx, & module_def , view_def ) ?;
2571+ let mut tx = begin_mut_tx ( stdb ) ;
2572+ tx . subscribe_view ( view_id , ArgId :: SENTINEL , sender ) ? ;
2573+ stdb. materialize_view ( & mut tx, table_id , sender , row_type , to_bstan ( & row_pv ( v ) ) , typespace ) ?;
25722574 stdb. commit_tx ( tx) ?;
25732575
2574- let apply_view_update = |sender : Identity , val : u8 | -> ResultTest < ( ) > {
2575- let mut tx = begin_mut_tx ( & stdb) ;
2576- tx. subscribe_view ( view_id, ArgId :: SENTINEL , sender) ?;
2577- stdb. materialize_view ( & mut tx, table_id, sender, row_type, to_bstan ( & row_pv ( val) ) , typespace) ?;
2578- stdb. commit_tx ( tx) ?;
2579- Ok ( ( ) )
2580- } ;
2576+ Ok ( ( ) )
2577+ }
2578+
2579+ fn project_views ( stdb : & TestDB , table_id : TableId , sender : Identity ) -> Vec < ProductValue > {
2580+ let tx = begin_tx ( stdb) ;
2581+
2582+ stdb. iter_by_col_eq ( & tx, table_id, 0 , & sender. into ( ) )
2583+ . unwrap ( )
2584+ . map ( |row| {
2585+ let pv = row. to_product_value ( ) ;
2586+ ProductValue {
2587+ elements : pv. elements . iter ( ) . skip ( 1 ) . cloned ( ) . collect ( ) ,
2588+ }
2589+ } )
2590+ . collect ( )
2591+ }
2592+
2593+ #[ test]
2594+ fn test_views ( ) -> ResultTest < ( ) > {
2595+ let stdb = TestDB :: durable ( ) ?;
2596+
2597+ let ( view_id, table_id, module_def, view_def) = setup_view ( & stdb) ?;
2598+ let row_type = view_def. product_type_ref ;
2599+ let typespace = module_def. typespace ( ) ;
2600+
2601+ let row_pv = |v : u8 | ProductValue :: from_iter ( vec ! [ AlgebraicValue :: U8 ( v) ] ) ;
25812602
25822603 // Sender 1
25832604 let sender1 = Identity :: ONE ;
2584- apply_view_update ( sender1, 42 ) ?;
2605+ insert_view_row ( & stdb, view_id, table_id, typespace, row_type, sender1, 42 ) ?;
2606+
25852607 let mut tx = begin_mut_tx ( & stdb) ;
25862608 tx. unsubscribe_view ( view_id, ArgId :: SENTINEL , sender1) ?;
25872609 stdb. commit_tx ( tx) ?;
@@ -2595,7 +2617,7 @@ mod tests {
25952617 // Sender 2
25962618 let sender2 = Identity :: ZERO ;
25972619 let before_sender2 = Instant :: now ( ) ;
2598- apply_view_update ( sender2, 84 ) ?;
2620+ insert_view_row ( & stdb , view_id , table_id , typespace , row_type , sender2, 84 ) ?;
25992621
26002622 assert_eq ! (
26012623 project_views( & stdb, table_id, sender2) [ 0 ] ,
@@ -2622,11 +2644,43 @@ mod tests {
26222644 let tx = begin_mut_tx ( & stdb) ;
26232645 let st_view_row = tx. lookup_st_view_subs ( view_id) ?;
26242646 assert_eq ! ( st_view_row. len( ) , 1 , "Sender 1 should be removed from st_view_subs" ) ;
2625- assert_eq ! (
2626- st_view_row[ 0 ] . identity. 0 , sender2,
2627- "Sender 1 should be removed from st_view_subs"
2647+ assert_eq ! ( st_view_row[ 0 ] . identity. 0 , sender2) ;
2648+
2649+ Ok ( ( ) )
2650+ }
2651+
2652+ #[ test]
2653+ fn test_view_tables_are_ephemeral ( ) -> ResultTest < ( ) > {
2654+ let stdb = TestDB :: durable ( ) ?;
2655+
2656+ let ( view_id, table_id, module_def, view_def) = setup_view ( & stdb) ?;
2657+ let row_type = view_def. product_type_ref ;
2658+ let typespace = module_def. typespace ( ) ;
2659+
2660+ // Write some rows (reusing the same helper)
2661+ insert_view_row ( & stdb, view_id, table_id, typespace, row_type, Identity :: ONE , 10 ) ?;
2662+ insert_view_row ( & stdb, view_id, table_id, typespace, row_type, Identity :: ZERO , 20 ) ?;
2663+
2664+ assert ! (
2665+ !project_views( & stdb, table_id, Identity :: ZERO ) . is_empty( ) ,
2666+ "View table should NOT be empty after insert"
26282667 ) ;
26292668
2669+ // Reopen the database — view tables must not persist
2670+ let stdb = stdb. reopen ( ) ?;
2671+
2672+ // Validate that the view's backing table has been removed
2673+ assert ! (
2674+ project_views( & stdb, table_id, Identity :: ZERO ) . is_empty( ) ,
2675+ "View table should be empty after reopening the database"
2676+ ) ;
2677+
2678+ let tx = begin_mut_tx ( & stdb) ;
2679+ let subs_rows = tx. lookup_st_view_subs ( view_id) ?;
2680+ assert ! (
2681+ subs_rows. is_empty( ) ,
2682+ "st_view_subs should be empty after reopening the database"
2683+ ) ;
26302684 Ok ( ( ) )
26312685 }
26322686
0 commit comments