@@ -9,9 +9,9 @@ use super::{
99 SharedMutexGuard , SharedWriteGuard ,
1010} ;
1111use crate :: system_tables:: {
12- system_tables, ConnectionIdViaU128 , StConnectionCredentialsFields , StConnectionCredentialsRow , StViewColumnFields ,
13- StViewFields , StViewParamFields , StViewParamRow , ST_CONNECTION_CREDENTIALS_ID , ST_VIEW_COLUMN_ID , ST_VIEW_ID ,
14- ST_VIEW_PARAM_ID ,
12+ system_tables, ConnectionIdViaU128 , IdentityViaU256 , StConnectionCredentialsFields , StConnectionCredentialsRow ,
13+ StViewClientFields , StViewClientRow , StViewColumnFields , StViewFields , StViewParamFields , StViewParamRow ,
14+ ST_CONNECTION_CREDENTIALS_ID , ST_VIEW_CLIENT_ID , ST_VIEW_COLUMN_ID , ST_VIEW_ID , ST_VIEW_PARAM_ID ,
1515} ;
1616use crate :: traits:: { InsertFlags , RowTypeForTable , TxData , UpdateFlags } ;
1717use crate :: {
@@ -1767,6 +1767,89 @@ impl<'a, I: Iterator<Item = RowRef<'a>>> Iterator for FilterDeleted<'a, I> {
17671767}
17681768
17691769impl MutTxId {
1770+ /// Delete view data and metadata for a client connection
1771+ pub fn delete_view_data_for_client ( & mut self , sender : Identity , connection_id : ConnectionId ) -> Result < ( ) > {
1772+ for row in self . delete_st_view_client_rows ( sender, connection_id) ? {
1773+ if !self . is_identity_subscribed_to_view_args ( row. view_id , row. arg_id , sender) ? {
1774+ self . delete_view_rows_for_identity ( row. view_id , row. arg_id , sender) ?;
1775+ }
1776+ }
1777+ Ok ( ( ) )
1778+ }
1779+
1780+ /// Delete and return the rows in `st_view_client` for a client connection
1781+ fn delete_st_view_client_rows (
1782+ & mut self ,
1783+ sender : Identity ,
1784+ connection_id : ConnectionId ,
1785+ ) -> Result < Vec < StViewClientRow > > {
1786+ let sender = IdentityViaU256 ( sender) ;
1787+ let conn_id = ConnectionIdViaU128 ( connection_id) ;
1788+ let cols = col_list ! [ StViewClientFields :: Identity , StViewClientFields :: ConnectionId ] ;
1789+ let value = AlgebraicValue :: product ( [ sender. into ( ) , conn_id. into ( ) ] ) ;
1790+ self . iter_by_col_eq ( ST_VIEW_CLIENT_ID , cols, & value) ?
1791+ . map ( |row_ref| StViewClientRow :: try_from ( row_ref) . map ( |row| ( row, row_ref. pointer ( ) ) ) )
1792+ . collect :: < Result < Vec < _ > > > ( ) ?
1793+ . into_iter ( )
1794+ . map ( |( row, ptr) | self . delete ( ST_VIEW_CLIENT_ID , ptr) . map ( |_| row) )
1795+ . collect ( )
1796+ }
1797+
1798+ /// Is anyone is subscribed to the view arguments identified by `arg_id`
1799+ fn is_identity_subscribed_to_view_args ( & self , view_id : ViewId , arg_id : u64 , sender : Identity ) -> Result < bool > {
1800+ Ok ( self
1801+ . iter_by_col_eq (
1802+ ST_VIEW_CLIENT_ID ,
1803+ col_list ! [
1804+ StViewClientFields :: ViewId ,
1805+ StViewClientFields :: ArgId ,
1806+ StViewClientFields :: Identity
1807+ ] ,
1808+ & AlgebraicValue :: product ( [ view_id. into ( ) , arg_id. into ( ) , sender. into ( ) ] ) ,
1809+ ) ?
1810+ . next ( )
1811+ . is_some ( ) )
1812+ }
1813+
1814+ /// Lookup a row in `st_view` by its primary key
1815+ fn st_view_row ( & self , view_id : ViewId ) -> Result < Option < StViewRow > > {
1816+ self . iter_by_col_eq ( ST_VIEW_ID , col_list ! [ StViewFields :: ViewId ] , & view_id. into ( ) ) ?
1817+ . next ( )
1818+ . map ( StViewRow :: try_from)
1819+ . transpose ( )
1820+ }
1821+
1822+ /// Get the [`TableId`] for this view's backing table by probing `st_view`.
1823+ /// Note, all views with at least one subscriber are materialized.
1824+ fn get_table_id_for_view ( & self , view_id : ViewId ) -> Result < Option < ( TableId , bool ) > > {
1825+ Ok ( self
1826+ . st_view_row ( view_id) ?
1827+ . and_then ( |row| row. table_id . map ( |id| ( id, row. is_anonymous ) ) ) )
1828+ }
1829+
1830+ /// Delete the rows of a view subscribed to by `sender`
1831+ fn delete_view_rows_for_identity ( & mut self , view_id : ViewId , arg_id : u64 , sender : Identity ) -> Result < ( ) > {
1832+ if let Some ( ( table_id, is_anonymous) ) = self . get_table_id_for_view ( view_id) ? {
1833+ let value = if is_anonymous {
1834+ let none_sender = AlgebraicValue :: OptionNone ( ) ;
1835+ AlgebraicValue :: product ( [ none_sender, arg_id. into ( ) ] )
1836+ } else {
1837+ let sender = IdentityViaU256 ( sender) ;
1838+ let some_sender = AlgebraicValue :: OptionSome ( sender. into ( ) ) ;
1839+ AlgebraicValue :: product ( [ some_sender, arg_id. into ( ) ] )
1840+ } ;
1841+ for row_pointer in self
1842+ . iter_by_col_eq ( table_id, col_list ! [ 0 , 1 ] , & value) ?
1843+ . map ( |row_ref| row_ref. pointer ( ) )
1844+ . collect :: < Vec < _ > > ( )
1845+ . into_iter ( )
1846+ {
1847+ self . delete ( table_id, row_pointer) ?;
1848+ }
1849+ }
1850+ Ok ( ( ) )
1851+ }
1852+
17701853 pub fn insert_st_client (
17711854 & mut self ,
17721855 identity : Identity ,
0 commit comments