@@ -28,7 +28,7 @@ struct CachedDbTables {
2828///
2929/// Presents a terminal UI for selecting:
3030/// 1. Which databases to replicate (multi-select)
31- /// 2. For each selected database: tables to exclude
31+ /// 2. For each selected database: tables to include (Enter = include all)
3232/// 3. For each selected database: tables to replicate schema-only (no data)
3333/// 4. For each selected database: time-based filters
3434/// 5. Summary and confirmation
@@ -97,7 +97,7 @@ pub async fn select_databases_and_tables(
9797 let mut current_step = WizardStep :: SelectDatabases ;
9898
9999 // Track selections per database for back navigation
100- let mut excluded_tables_by_db : std:: collections:: HashMap < String , Vec < String > > =
100+ let mut included_tables_by_db : std:: collections:: HashMap < String , Vec < String > > =
101101 std:: collections:: HashMap :: new ( ) ;
102102 let mut schema_only_by_db: std:: collections:: HashMap < String , Vec < ( String , String ) > > =
103103 std:: collections:: HashMap :: new ( ) ; // (schema, table)
@@ -140,7 +140,7 @@ pub async fn select_databases_and_tables(
140140 }
141141
142142 // Clear previous selections when re-selecting databases
143- excluded_tables_by_db . clear ( ) ;
143+ included_tables_by_db . clear ( ) ;
144144 schema_only_by_db. clear ( ) ;
145145 time_filters_by_db. clear ( ) ;
146146 table_cache. clear ( ) ;
@@ -160,11 +160,12 @@ pub async fn select_databases_and_tables(
160160 WizardStep :: SelectTablesForDb ( db_idx) => {
161161 let db_name = & db_names[ selected_db_indices[ db_idx] ] . clone ( ) ;
162162 print_header ( & format ! (
163- "Step 2 of 5: Select Tables to Exclude ({}/{})" ,
163+ "Step 2 of 5: Select Tables to Include ({}/{})" ,
164164 db_idx + 1 ,
165165 selected_db_indices. len( )
166166 ) ) ;
167167 println ! ( "Database: {}" , db_name) ;
168+ println ! ( "Press Enter without selecting to include ALL tables." ) ;
168169 println ! ( "Navigation: Space to toggle, Enter to continue, Esc to go back" ) ;
169170 println ! ( ) ;
170171
@@ -182,11 +183,11 @@ pub async fn select_databases_and_tables(
182183 continue ;
183184 }
184185
185- // Get previously excluded tables for this database (for back navigation)
186- let previous_exclusions : Vec < usize > = excluded_tables_by_db
186+ // Get previously included tables for this database (for back navigation)
187+ let previous_inclusions : Vec < usize > = included_tables_by_db
187188 . get ( db_name)
188- . map ( |excluded | {
189- excluded
189+ . map ( |included | {
190+ included
190191 . iter ( )
191192 . filter_map ( |t| {
192193 // Strip db name prefix to match display names
@@ -202,23 +203,31 @@ pub async fn select_databases_and_tables(
202203 . unwrap_or_default ( ) ;
203204
204205 let selections = MultiSelect :: new (
205- "Select tables to EXCLUDE (or press Enter to include all):" ,
206+ "Select tables to INCLUDE ( Enter = include all):" ,
206207 cached. table_display_names . clone ( ) ,
207208 )
208- . with_default ( & previous_exclusions )
209+ . with_default ( & previous_inclusions )
209210 . with_help_message ( "Space toggle, Enter confirm, Esc go back" )
210211 . prompt ( ) ;
211212
212213 match selections {
213- Ok ( selected_exclusions) => {
214- // Build exclusion list for this database
215- let db_exclusions: Vec < String > = selected_exclusions
216- . iter ( )
217- . map ( |table_name| format ! ( "{}.{}" , db_name, table_name) )
218- . collect ( ) ;
214+ Ok ( selected_inclusions) => {
215+ // If nothing selected, include all tables
216+ let db_inclusions: Vec < String > = if selected_inclusions. is_empty ( ) {
217+ cached
218+ . table_display_names
219+ . iter ( )
220+ . map ( |table_name| format ! ( "{}.{}" , db_name, table_name) )
221+ . collect ( )
222+ } else {
223+ selected_inclusions
224+ . iter ( )
225+ . map ( |table_name| format ! ( "{}.{}" , db_name, table_name) )
226+ . collect ( )
227+ } ;
219228
220229 // Store for back navigation
221- excluded_tables_by_db . insert ( db_name. clone ( ) , db_exclusions ) ;
230+ included_tables_by_db . insert ( db_name. clone ( ) , db_inclusions ) ;
222231
223232 // Move to next database or schema-only step
224233 if db_idx + 1 < selected_db_indices. len ( ) {
@@ -266,21 +275,21 @@ pub async fn select_databases_and_tables(
266275 continue ;
267276 }
268277
269- // Filter out excluded tables
270- let excluded = excluded_tables_by_db . get ( db_name) ;
278+ // Filter to only included tables
279+ let included = included_tables_by_db . get ( db_name) ;
271280 let available_tables: Vec < ( usize , String ) > = cached
272281 . table_display_names
273282 . iter ( )
274283 . enumerate ( )
275284 . filter ( |( _, name) | {
276285 let full_name = format ! ( "{}.{}" , db_name, name) ;
277- !excluded . is_some_and ( |ex| ex . contains ( & full_name) )
286+ included . is_some_and ( |inc| inc . contains ( & full_name) )
278287 } )
279288 . map ( |( idx, name) | ( idx, name. clone ( ) ) )
280289 . collect ( ) ;
281290
282291 if available_tables. is_empty ( ) {
283- println ! ( " All tables excluded from '{}'" , db_name) ;
292+ println ! ( " No tables included from '{}'" , db_name) ;
284293 if db_idx + 1 < selected_db_indices. len ( ) {
285294 current_step = WizardStep :: SelectSchemaOnlyForDb ( db_idx + 1 ) ;
286295 } else {
@@ -380,21 +389,21 @@ pub async fn select_databases_and_tables(
380389 continue ;
381390 }
382391
383- // Filter out excluded and schema-only tables
384- let excluded = excluded_tables_by_db . get ( db_name) ;
392+ // Filter to included tables, excluding schema-only ones
393+ let included = included_tables_by_db . get ( db_name) ;
385394 let schema_only = schema_only_by_db. get ( db_name) ;
386395 let available_tables: Vec < ( usize , String ) > = cached
387396 . table_display_names
388397 . iter ( )
389398 . enumerate ( )
390399 . filter ( |( idx, name) | {
391400 let full_name = format ! ( "{}.{}" , db_name, name) ;
392- let is_excluded = excluded . is_some_and ( |ex| ex . contains ( & full_name) ) ;
401+ let is_included = included . is_some_and ( |inc| inc . contains ( & full_name) ) ;
393402 let t = & cached. all_tables [ * idx] ;
394403 let is_schema_only = schema_only. is_some_and ( |so| {
395404 so. iter ( ) . any ( |( s, n) | s == & t. schema && n == & t. name )
396405 } ) ;
397- !is_excluded && !is_schema_only
406+ is_included && !is_schema_only
398407 } )
399408 . map ( |( idx, name) | ( idx, name. clone ( ) ) )
400409 . collect ( ) ;
@@ -550,9 +559,9 @@ pub async fn select_databases_and_tables(
550559 WizardStep :: Review => {
551560 print_header ( "Step 5 of 5: Review Configuration" ) ;
552561
553- // Collect all exclusions
554- let excluded_tables : Vec < String > =
555- excluded_tables_by_db . values ( ) . flatten ( ) . cloned ( ) . collect ( ) ;
562+ // Collect all inclusions
563+ let included_tables : Vec < String > =
564+ included_tables_by_db . values ( ) . flatten ( ) . cloned ( ) . collect ( ) ;
556565
557566 let selected_databases: Vec < String > = selected_db_indices
558567 . iter ( )
@@ -566,16 +575,22 @@ pub async fn select_databases_and_tables(
566575 }
567576 println ! ( ) ;
568577
569- if !excluded_tables . is_empty ( ) {
570- println ! ( "Tables to exclude: {}" , excluded_tables . len ( ) ) ;
571- for table in & excluded_tables {
572- println ! ( " ✗ {}" , table) ;
578+ println ! ( "Tables to replicate: {}" , included_tables . len ( ) ) ;
579+ if included_tables . len ( ) <= 20 {
580+ for table in & included_tables {
581+ println ! ( " ✓ {}" , table) ;
573582 }
574- println ! ( ) ;
575583 } else {
576- println ! ( "Tables to exclude: none" ) ;
577- println ! ( ) ;
584+ // Show first 10 and last 5 with ellipsis
585+ for table in included_tables. iter ( ) . take ( 10 ) {
586+ println ! ( " ✓ {}" , table) ;
587+ }
588+ println ! ( " ... ({} more tables)" , included_tables. len( ) - 15 ) ;
589+ for table in included_tables. iter ( ) . skip ( included_tables. len ( ) - 5 ) {
590+ println ! ( " ✓ {}" , table) ;
591+ }
578592 }
593+ println ! ( ) ;
579594
580595 // Show schema-only tables
581596 let schema_only_count: usize = schema_only_by_db. values ( ) . map ( |v| v. len ( ) ) . sum ( ) ;
@@ -647,16 +662,17 @@ pub async fn select_databases_and_tables(
647662 . map ( |& i| db_names[ i] . clone ( ) )
648663 . collect ( ) ;
649664
650- let excluded_tables : Vec < String > = excluded_tables_by_db . values ( ) . flatten ( ) . cloned ( ) . collect ( ) ;
665+ let included_tables : Vec < String > = included_tables_by_db . values ( ) . flatten ( ) . cloned ( ) . collect ( ) ;
651666
652667 tracing:: info!( "" ) ;
653668 tracing:: info!( "✓ Configuration confirmed" ) ;
654669 tracing:: info!( "" ) ;
655670
656- let filter = if excluded_tables. is_empty ( ) {
671+ // Use include_tables filter (3rd parameter)
672+ let filter = if included_tables. is_empty ( ) {
657673 ReplicationFilter :: new ( Some ( selected_databases) , None , None , None ) ?
658674 } else {
659- ReplicationFilter :: new ( Some ( selected_databases) , None , None , Some ( excluded_tables ) ) ?
675+ ReplicationFilter :: new ( Some ( selected_databases) , None , Some ( included_tables ) , None ) ?
660676 } ;
661677
662678 // Build TableRules from selections
0 commit comments