33//! This module is internal, and may incompatibly change without warning.
44
55use crate :: callbacks:: CallbackId ;
6- use crate :: db_connection:: { PendingMutation , SharedCell } ;
6+ use crate :: db_connection:: { debug_log , PendingMutation , SharedCell } ;
77use crate :: spacetime_module:: { InModule , SpacetimeModule , TableUpdate , WithBsatn } ;
88use anymap:: { any:: Any , Map } ;
99use bytes:: Bytes ;
1010use core:: any:: type_name;
1111use core:: hash:: Hash ;
1212use futures_channel:: mpsc;
1313use spacetimedb_data_structures:: map:: { hash_map:: Entry , HashCollectionExt , HashMap } ;
14+ use std:: fmt:: Debug ;
15+ use std:: fs:: File ;
16+ use std:: io:: Write ;
1417use std:: marker:: PhantomData ;
1518use std:: sync:: Arc ;
1619
@@ -35,6 +38,9 @@ pub struct TableCache<Row> {
3538 /// Entries are added to this map during [`crate::DbConnectionBuilder::build`],
3639 /// via a `register_table` function autogenerated for each table.
3740 pub ( crate ) unique_indices : HashMap < & ' static str , Box < dyn UniqueIndexDyn < Row = Row > > > ,
41+
42+ /// Clone of the [`crate::db_connection::DbContextImpl::extra_logging`].
43+ extra_logging : Option < SharedCell < File > > ,
3844}
3945
4046/// Stores an entry of the typed row value together with its ref count in the table cache.
@@ -59,11 +65,12 @@ pub(crate) struct RowEntry<Row> {
5965}
6066
6167// Can't derive this because the `Row` generic messes us up.
62- impl < Row > Default for TableCache < Row > {
63- fn default ( ) -> Self {
68+ impl < Row > TableCache < Row > {
69+ fn new ( extra_logging : Option < SharedCell < File > > ) -> Self {
6470 Self {
6571 entries : Default :: default ( ) ,
6672 unique_indices : Default :: default ( ) ,
73+ extra_logging,
6774 }
6875 }
6976}
@@ -185,7 +192,13 @@ impl<'r, Row> TableAppliedDiff<'r, Row> {
185192 }
186193}
187194
188- impl < Row : Clone + Send + Sync + ' static > TableCache < Row > {
195+ impl < Row > TableCache < Row > {
196+ fn debug_log ( & self , body : impl FnOnce ( & mut File ) -> std:: result:: Result < ( ) , std:: io:: Error > ) {
197+ debug_log ( & self . extra_logging , body) ;
198+ }
199+ }
200+
201+ impl < Row : Clone + Debug + Send + Sync + ' static > TableCache < Row > {
189202 fn handle_delete < ' r > (
190203 & mut self ,
191204 inserts : & mut RowEventMap < ' _ , Row > ,
@@ -195,8 +208,16 @@ impl<Row: Clone + Send + Sync + 'static> TableCache<Row> {
195208 // Extract the entry and decrement the `ref_count`.
196209 // Only create a delete event if `ref_count = 0`.
197210 let Entry :: Occupied ( mut entry) = self . entries . entry ( delete. bsatn . clone ( ) ) else {
211+ self . debug_log ( |file| {
212+ writeln ! ( file, "`handle_delete` for table with row type {}: a delete update should correspond to an existing row in the table cache, but the row {delete:?} was not present" , std:: any:: type_name:: <Row >( ) ) ?;
213+ writeln ! ( file, "table contents:" ) ?;
214+ for ( bsatn, RowEntry { row, ref_count } ) in self . entries . iter ( ) {
215+ writeln ! ( file, "\t {bsatn:?}\n \t \t {row:?}\n \t \t ref_count {ref_count}" ) ?;
216+ }
217+ Ok ( ( ) )
218+ } ) ;
198219 // We're guaranteed to never hit this as long as we apply inserts before deletes.
199- unreachable ! ( "a delete update should correspond to an existing row in the table cache" ) ;
220+ unreachable ! ( "a delete update should correspond to an existing row in the table cache, but the row {delete:?} was not present " ) ;
200221 } ;
201222 let ref_count = & mut entry. get_mut ( ) . ref_count ;
202223 * ref_count -= 1 ;
@@ -320,19 +341,21 @@ pub struct ClientCache<M: SpacetimeModule + ?Sized> {
320341 /// The strings are table names, since we may have multiple tables with the same row type.
321342 tables : Map < dyn Any + Send + Sync > ,
322343
344+ /// Clone of the [`crate::db_connection::DbContextImpl::extra_logging`].
345+ extra_logging : Option < SharedCell < File > > ,
346+
323347 _module : PhantomData < M > ,
324348}
325349
326- impl < M : SpacetimeModule > Default for ClientCache < M > {
327- fn default ( ) -> Self {
350+ impl < M : SpacetimeModule > ClientCache < M > {
351+ pub ( crate ) fn new ( extra_logging : Option < SharedCell < File > > ) -> Self {
328352 Self {
329353 tables : Map :: new ( ) ,
354+ extra_logging,
330355 _module : PhantomData ,
331356 }
332357 }
333- }
334358
335- impl < M : SpacetimeModule > ClientCache < M > {
336359 /// Get a handle on the [`TableCache`] which stores rows of type `Row` for the table `table_name`.
337360 pub ( crate ) fn get_table < Row : InModule < Module = M > + Send + Sync + ' static > (
338361 & self ,
@@ -353,12 +376,12 @@ impl<M: SpacetimeModule> ClientCache<M> {
353376 . entry :: < HashMap < & ' static str , TableCache < Row > > > ( )
354377 . or_insert_with ( Default :: default)
355378 . entry ( table_name)
356- . or_default ( )
379+ . or_insert_with ( || TableCache :: new ( self . extra_logging . clone ( ) ) )
357380 }
358381
359382 /// Apply all the mutations in `diff`
360383 /// to the [`TableCache`] which stores rows of type `Row` for the table `table_name`.
361- pub fn apply_diff_to_table < ' r , Row : InModule < Module = M > + Clone + Send + Sync + ' static > (
384+ pub fn apply_diff_to_table < ' r , Row : InModule < Module = M > + Clone + Debug + Send + Sync + ' static > (
362385 & mut self ,
363386 table_name : & ' static str ,
364387 diff : & ' r TableUpdate < Row > ,
@@ -530,7 +553,7 @@ pub struct UniqueConstraintHandle<Row: InModule, Col> {
530553}
531554
532555impl <
533- Row : Clone + InModule + Send + Sync + ' static ,
556+ Row : Clone + Debug + InModule + Send + Sync + ' static ,
534557 Col : std:: any:: Any + Eq + std:: hash:: Hash + Clone + Send + Sync + std:: fmt:: Debug + ' static ,
535558 > UniqueConstraintHandle < Row , Col >
536559{
0 commit comments