@@ -167,6 +167,42 @@ where
167
167
self . state . history = vec ! [ ] ;
168
168
}
169
169
170
+ fn set_focus ( & mut self , focus : Focus ) {
171
+ self . state . focus = focus;
172
+ if focus != Focus :: PopUp {
173
+ self . popup = None ;
174
+ self . last_focused_component = focus;
175
+ }
176
+ if focus == Focus :: Editor || focus == Focus :: History || focus == Focus :: Favorites {
177
+ self . last_focused_tab = focus;
178
+ }
179
+ }
180
+
181
+ fn set_popup ( & mut self , popup : Box < dyn PopUp < DB > > ) {
182
+ self . popup = Some ( popup) ;
183
+ self . set_focus ( Focus :: PopUp ) ;
184
+ }
185
+
186
+ fn last_focused_tab ( & mut self ) {
187
+ match self . last_focused_tab {
188
+ Focus :: Editor => self . set_focus ( Focus :: Editor ) ,
189
+ Focus :: History => self . set_focus ( Focus :: History ) ,
190
+ Focus :: Favorites => self . set_focus ( Focus :: Favorites ) ,
191
+ _ => { } ,
192
+ }
193
+ }
194
+
195
+ fn last_focused_component ( & mut self ) {
196
+ match self . last_focused_component {
197
+ Focus :: Menu => self . set_focus ( Focus :: Menu ) ,
198
+ Focus :: Editor => self . set_focus ( Focus :: Editor ) ,
199
+ Focus :: Data => self . set_focus ( Focus :: Data ) ,
200
+ Focus :: History => self . set_focus ( Focus :: History ) ,
201
+ Focus :: Favorites => self . set_focus ( Focus :: Favorites ) ,
202
+ Focus :: PopUp => { } ,
203
+ }
204
+ }
205
+
170
206
pub async fn run ( & mut self ) -> Result < ( ) > {
171
207
let ( action_tx, mut action_rx) = mpsc:: unbounded_channel ( ) ;
172
208
let connection_opts = self . state . connection_opts . clone ( ) ;
@@ -204,7 +240,7 @@ where
204
240
205
241
loop {
206
242
if let Some ( popup) = & mut self . popup {
207
- self . state . focus = Focus :: PopUp ;
243
+ self . set_focus ( Focus :: PopUp ) ;
208
244
}
209
245
match & mut self . state . query_task {
210
246
Some ( DbTask :: Query ( task) ) => {
@@ -221,8 +257,7 @@ where
221
257
match results. results {
222
258
Ok ( _) => {
223
259
self . state . query_task = Some ( DbTask :: TxPending ( tx, results) ) ;
224
- self . popup = Some ( Box :: new ( ConfirmTx :: < DB > :: new ( ) ) ) ;
225
- self . state . focus = Focus :: PopUp ;
260
+ self . set_popup ( Box :: new ( ConfirmTx :: < DB > :: new ( ) ) ) ;
226
261
} ,
227
262
Err ( _) => {
228
263
self . state . query_task = None ;
@@ -256,31 +291,26 @@ where
256
291
match payload {
257
292
Some ( PopUpPayload :: SetDataTable ( result, statement) ) => {
258
293
self . components . data . set_data_state ( result, statement) ;
259
- self . popup = None ;
260
- action_tx. send ( Action :: FocusEditor ) ?;
294
+ self . set_focus ( Focus :: Editor ) ;
261
295
} ,
262
296
Some ( PopUpPayload :: ConfirmQuery ( query) ) => {
263
297
action_tx. send ( Action :: Query ( vec ! [ query] , true ) ) ?;
264
- self . popup = None ;
265
- action_tx. send ( Action :: FocusEditor ) ?;
298
+ self . set_focus ( Focus :: Editor ) ;
266
299
} ,
267
300
Some ( PopUpPayload :: ConfirmExport ( confirmed) ) => {
268
301
if confirmed {
269
302
action_tx. send ( Action :: ExportData ( ExportFormat :: CSV ) ) ?;
270
- self . popup = Some ( Box :: new ( Exporting :: new ( ) ) ) ;
303
+ self . set_popup ( Box :: new ( Exporting :: new ( ) ) ) ;
271
304
} else {
272
- self . popup = None ;
273
- action_tx. send ( Action :: FocusData ) ?;
305
+ self . set_focus ( Focus :: Data ) ;
274
306
}
275
307
} ,
276
308
Some ( PopUpPayload :: Cancel ) => {
277
- self . popup = None ;
278
- self . last_focused_component ( action_tx. clone ( ) ) ?;
309
+ self . last_focused_component ( ) ;
279
310
} ,
280
311
Some ( PopUpPayload :: NamedFavorite ( name, query_lines) ) => {
281
312
self . state . favorites . add_entry ( name, query_lines) ;
282
- self . popup = None ;
283
- action_tx. send ( Action :: FocusEditor ) ?;
313
+ self . set_focus ( Focus :: Editor ) ;
284
314
} ,
285
315
None => { } ,
286
316
}
@@ -357,46 +387,28 @@ where
357
387
} ) ?;
358
388
self . last_frame_mouse_event = None ;
359
389
} ,
360
- Action :: FocusMenu => {
361
- self . state . focus = Focus :: Menu ;
362
- self . last_focused_component = Focus :: Menu ;
363
- } ,
364
- Action :: FocusEditor => {
365
- self . state . focus = Focus :: Editor ;
366
- self . last_focused_tab = Focus :: Editor ;
367
- self . last_focused_component = Focus :: Editor ;
368
- } ,
369
- Action :: FocusData => {
370
- self . state . focus = Focus :: Data ;
371
- self . last_focused_component = Focus :: Data ;
372
- } ,
373
- Action :: FocusHistory => {
374
- self . state . focus = Focus :: History ;
375
- self . last_focused_tab = Focus :: History ;
376
- self . last_focused_component = Focus :: History ;
377
- } ,
378
- Action :: FocusFavorites => {
379
- self . state . focus = Focus :: Favorites ;
380
- self . last_focused_tab = Focus :: Favorites ;
381
- self . last_focused_component = Focus :: Favorites ;
382
- } ,
390
+ Action :: FocusMenu => self . set_focus ( Focus :: Menu ) ,
391
+ Action :: FocusEditor => self . set_focus ( Focus :: Editor ) ,
392
+ Action :: FocusData => self . set_focus ( Focus :: Data ) ,
393
+ Action :: FocusHistory => self . set_focus ( Focus :: History ) ,
394
+ Action :: FocusFavorites => self . set_focus ( Focus :: Favorites ) ,
383
395
Action :: CycleFocusForwards => {
384
396
match self . state . focus {
385
- Focus :: Menu => action_tx . send ( Action :: FocusEditor ) ? ,
386
- Focus :: Editor => action_tx . send ( Action :: FocusData ) ? ,
387
- Focus :: Data => action_tx . send ( Action :: FocusHistory ) ? ,
388
- Focus :: History => action_tx . send ( Action :: FocusFavorites ) ? ,
389
- Focus :: Favorites => action_tx . send ( Action :: FocusMenu ) ? ,
397
+ Focus :: Menu => self . set_focus ( Focus :: Editor ) ,
398
+ Focus :: Editor => self . set_focus ( Focus :: Data ) ,
399
+ Focus :: Data => self . set_focus ( Focus :: History ) ,
400
+ Focus :: History => self . set_focus ( Focus :: Favorites ) ,
401
+ Focus :: Favorites => self . set_focus ( Focus :: Menu ) ,
390
402
Focus :: PopUp => { } ,
391
403
}
392
404
} ,
393
405
Action :: CycleFocusBackwards => {
394
406
match self . state . focus {
395
- Focus :: History => action_tx . send ( Action :: FocusData ) ? ,
396
- Focus :: Data => action_tx . send ( Action :: FocusEditor ) ? ,
397
- Focus :: Editor => action_tx . send ( Action :: FocusMenu ) ? ,
398
- Focus :: Menu => action_tx . send ( Action :: FocusFavorites ) ? ,
399
- Focus :: Favorites => action_tx . send ( Action :: FocusHistory ) ? ,
407
+ Focus :: History => self . set_focus ( Focus :: Data ) ,
408
+ Focus :: Data => self . set_focus ( Focus :: Editor ) ,
409
+ Focus :: Editor => self . set_focus ( Focus :: Menu ) ,
410
+ Focus :: Menu => self . set_focus ( Focus :: Favorites ) ,
411
+ Focus :: Favorites => self . set_focus ( Focus :: History ) ,
400
412
Focus :: PopUp => { } ,
401
413
}
402
414
} ,
@@ -407,78 +419,77 @@ where
407
419
self . components . menu . set_table_list ( Some ( results) ) ;
408
420
}
409
421
} ,
410
- Action :: Query ( query_lines, confirmed) => {
422
+ Action :: Query ( query_lines, confirmed) => ' query_action : {
411
423
let query_string = query_lines. clone ( ) . join ( " \n " ) ;
412
- if !query_string. is_empty ( ) {
413
- self . add_to_history ( query_lines. clone ( ) ) ;
414
- let first_query = database:: get_first_query ( query_string. clone ( ) , self . state . dialect . as_ref ( ) ) ;
415
- let execution_type = first_query. map ( |( _, statement_type) | {
416
- ( database:: get_execution_type ( statement_type. clone ( ) , * confirmed) , statement_type)
417
- } ) ;
418
- let action_tx = action_tx. clone ( ) ;
419
- if let Some ( pool) = & self . pool {
420
- let pool = pool. clone ( ) ;
421
- let dialect = self . state . dialect . clone ( ) ;
422
- match execution_type {
423
- Ok ( ( ExecutionType :: Transaction , statement_type) ) => {
424
- self . components . data . set_loading ( ) ;
425
- let tx = pool. begin ( ) . await ?;
426
- self . state . query_task = Some ( DbTask :: TxStart ( tokio:: spawn ( async move {
427
- let ( results, tx) =
428
- database:: query_with_tx :: < DB > ( tx, dialect. as_ref ( ) , query_string. clone ( ) ) . await ;
429
- match results {
430
- Ok ( Either :: Left ( rows_affected) ) => {
431
- log:: info!( "{:?} rows affected" , rows_affected) ;
432
- (
433
- QueryResultsWithMetadata {
434
- results : Ok ( Rows { headers : vec ! [ ] , rows : vec ! [ ] , rows_affected : Some ( rows_affected) } ) ,
435
- statement_type,
436
- } ,
437
- tx,
438
- )
439
- } ,
440
- Ok ( Either :: Right ( rows) ) => {
441
- log:: info!( "{:?} rows affected" , rows. rows_affected) ;
442
- ( QueryResultsWithMetadata { results : Ok ( rows) , statement_type } , tx)
443
- } ,
444
- Err ( e) => {
445
- log:: error!( "{e:?}" ) ;
446
- ( QueryResultsWithMetadata { results : Err ( e) , statement_type } , tx)
447
- } ,
448
- }
449
- } ) ) ) ;
450
- self . state . last_query_start = Some ( chrono:: Utc :: now ( ) ) ;
451
- self . state . last_query_end = None ;
452
- } ,
453
- Ok ( ( ExecutionType :: Confirm , statement_type) ) => {
454
- self . popup = Some ( Box :: new ( ConfirmQuery :: < DB > :: new ( query_string. clone ( ) , statement_type) ) ) ;
455
- self . state . focus = Focus :: PopUp ;
456
- } ,
457
- Ok ( ( ExecutionType :: Normal , statement_type) ) => {
458
- self . components . data . set_loading ( ) ;
459
- let dialect = self . state . dialect . clone ( ) ;
460
- self . state . query_task = Some ( DbTask :: Query ( tokio:: spawn ( async move {
461
- let results = database:: query ( query_string. clone ( ) , dialect. as_ref ( ) , & pool) . await ;
462
- match & results {
463
- Ok ( rows) => {
464
- log:: info!( "{:?} rows, {:?} affected" , rows. rows. len( ) , rows. rows_affected) ;
465
- } ,
466
- Err ( e) => {
467
- log:: error!( "{e:?}" ) ;
468
- } ,
469
- } ;
470
-
471
- QueryResultsWithMetadata { results, statement_type }
472
- } ) ) ) ;
473
- self . state . last_query_start = Some ( chrono:: Utc :: now ( ) ) ;
474
- self . state . last_query_end = None ;
475
- } ,
476
- Err ( e) => self . components . data . set_data_state ( Some ( Err ( e) ) , None ) ,
477
- }
478
- } else {
479
- log:: error!( "No connection pool" ) ;
480
- self . components . data . set_data_state ( Some ( Err ( DbError :: Left ( sqlx:: Error :: PoolTimedOut ) ) ) , None )
424
+ if query_string. is_empty ( ) {
425
+ break ' query_action;
426
+ }
427
+ self . add_to_history ( query_lines. clone ( ) ) ;
428
+ let first_query = database:: get_first_query ( query_string. clone ( ) , self . state . dialect . as_ref ( ) ) ;
429
+ let execution_type = first_query. map ( |( _, statement_type) | {
430
+ ( database:: get_execution_type ( statement_type. clone ( ) , * confirmed) , statement_type)
431
+ } ) ;
432
+ let action_tx = action_tx. clone ( ) ;
433
+ if let Some ( pool) = & self . pool {
434
+ let pool = pool. clone ( ) ;
435
+ let dialect = self . state . dialect . clone ( ) ;
436
+ match execution_type {
437
+ Ok ( ( ExecutionType :: Transaction , statement_type) ) => {
438
+ self . components . data . set_loading ( ) ;
439
+ let tx = pool. begin ( ) . await ?;
440
+ self . state . query_task = Some ( DbTask :: TxStart ( tokio:: spawn ( async move {
441
+ let ( results, tx) = database:: query_with_tx :: < DB > ( tx, dialect. as_ref ( ) , query_string. clone ( ) ) . await ;
442
+ match results {
443
+ Ok ( Either :: Left ( rows_affected) ) => {
444
+ log:: info!( "{:?} rows affected" , rows_affected) ;
445
+ (
446
+ QueryResultsWithMetadata {
447
+ results : Ok ( Rows { headers : vec ! [ ] , rows : vec ! [ ] , rows_affected : Some ( rows_affected) } ) ,
448
+ statement_type,
449
+ } ,
450
+ tx,
451
+ )
452
+ } ,
453
+ Ok ( Either :: Right ( rows) ) => {
454
+ log:: info!( "{:?} rows affected" , rows. rows_affected) ;
455
+ ( QueryResultsWithMetadata { results : Ok ( rows) , statement_type } , tx)
456
+ } ,
457
+ Err ( e) => {
458
+ log:: error!( "{e:?}" ) ;
459
+ ( QueryResultsWithMetadata { results : Err ( e) , statement_type } , tx)
460
+ } ,
461
+ }
462
+ } ) ) ) ;
463
+ self . state . last_query_start = Some ( chrono:: Utc :: now ( ) ) ;
464
+ self . state . last_query_end = None ;
465
+ } ,
466
+ Ok ( ( ExecutionType :: Confirm , statement_type) ) => {
467
+ self . set_popup ( Box :: new ( ConfirmQuery :: < DB > :: new ( query_string. clone ( ) , statement_type) ) ) ;
468
+ } ,
469
+ Ok ( ( ExecutionType :: Normal , statement_type) ) => {
470
+ self . components . data . set_loading ( ) ;
471
+ let dialect = self . state . dialect . clone ( ) ;
472
+ self . state . query_task = Some ( DbTask :: Query ( tokio:: spawn ( async move {
473
+ let results = database:: query ( query_string. clone ( ) , dialect. as_ref ( ) , & pool) . await ;
474
+ match & results {
475
+ Ok ( rows) => {
476
+ log:: info!( "{:?} rows, {:?} affected" , rows. rows. len( ) , rows. rows_affected) ;
477
+ } ,
478
+ Err ( e) => {
479
+ log:: error!( "{e:?}" ) ;
480
+ } ,
481
+ } ;
482
+
483
+ QueryResultsWithMetadata { results, statement_type }
484
+ } ) ) ) ;
485
+ self . state . last_query_start = Some ( chrono:: Utc :: now ( ) ) ;
486
+ self . state . last_query_end = None ;
487
+ } ,
488
+ Err ( e) => self . components . data . set_data_state ( Some ( Err ( e) ) , None ) ,
481
489
}
490
+ } else {
491
+ log:: error!( "No connection pool" ) ;
492
+ self . components . data . set_data_state ( Some ( Err ( DbError :: Left ( sqlx:: Error :: PoolTimedOut ) ) ) , None )
482
493
}
483
494
} ,
484
495
Action :: AbortQuery => {
@@ -499,11 +510,10 @@ where
499
510
}
500
511
} ,
501
512
Action :: RequestSaveFavorite ( query_lines) => {
502
- self . popup = Some ( Box :: new ( NameFavorite :: < DB > :: new (
513
+ self . set_popup ( Box :: new ( NameFavorite :: < DB > :: new (
503
514
self . state . favorites . iter ( ) . map ( |f| f. get_name ( ) . to_string ( ) ) . collect ( ) ,
504
515
query_lines. clone ( ) ,
505
516
) ) ) ;
506
- self . state . focus = Focus :: PopUp ;
507
517
} ,
508
518
Action :: DeleteFavorite ( name) => {
509
519
self . state . favorites . delete_entry ( name. clone ( ) ) ;
@@ -527,12 +537,10 @@ where
527
537
}
528
538
} ,
529
539
Action :: RequestExportData ( row_count) => {
530
- self . popup = Some ( Box :: new ( ConfirmExport :: < DB > :: new ( * row_count) ) ) ;
531
- self . state . focus = Focus :: PopUp ;
540
+ self . set_popup ( Box :: new ( ConfirmExport :: < DB > :: new ( * row_count) ) ) ;
532
541
} ,
533
542
Action :: ExportDataFinished => {
534
- self . popup = None ;
535
- action_tx. send ( Action :: FocusData ) ?;
543
+ self . set_focus ( Focus :: Data ) ;
536
544
} ,
537
545
_ => { } ,
538
546
}
@@ -613,26 +621,26 @@ where
613
621
let tab_content_target = tabs_layout[ 1 ] ;
614
622
let data_target = right_layout[ 1 ] ;
615
623
if menu_target. contains ( position) {
616
- action_tx . send ( Action :: FocusMenu ) ? ;
624
+ self . set_focus ( Focus :: Menu ) ;
617
625
} else if data_target. contains ( position) {
618
- action_tx . send ( Action :: FocusData ) ? ;
626
+ self . set_focus ( Focus :: Data ) ;
619
627
} else if tab_content_target. contains ( position) {
620
- self . last_focused_tab ( action_tx . clone ( ) ) ? ;
628
+ self . last_focused_tab ( ) ;
621
629
} else if tabs_target. contains ( position) {
622
630
match self . state . focus {
623
631
Focus :: Editor => {
624
632
if matches ! ( event. kind, MouseEventKind :: Up ( _) ) {
625
- action_tx . send ( Action :: FocusHistory ) ? ;
633
+ self . set_focus ( Focus :: History ) ;
626
634
}
627
635
} ,
628
636
Focus :: History => {
629
637
if matches ! ( event. kind, MouseEventKind :: Up ( _) ) {
630
- action_tx . send ( Action :: FocusFavorites ) ? ;
638
+ self . set_focus ( Focus :: Favorites ) ;
631
639
}
632
640
} ,
633
641
Focus :: Favorites => {
634
642
if matches ! ( event. kind, MouseEventKind :: Up ( _) ) {
635
- action_tx . send ( Action :: FocusEditor ) ? ;
643
+ self . set_focus ( Focus :: Editor ) ;
636
644
}
637
645
} ,
638
646
Focus :: PopUp => { } ,
@@ -721,26 +729,4 @@ where
721
729
frame. render_widget ( popup_cta, layout[ 0 ] ) ;
722
730
frame. render_widget ( popup_actions, center ( layout[ 1 ] , Constraint :: Fill ( 1 ) , Constraint :: Percentage ( 50 ) ) ) ;
723
731
}
724
-
725
- fn last_focused_tab ( & self , action_tx : mpsc:: UnboundedSender < Action > ) -> Result < ( ) > {
726
- match self . last_focused_tab {
727
- Focus :: Editor => action_tx. send ( Action :: FocusEditor ) ?,
728
- Focus :: History => action_tx. send ( Action :: FocusHistory ) ?,
729
- Focus :: Favorites => action_tx. send ( Action :: FocusFavorites ) ?,
730
- _ => { } ,
731
- } ;
732
- Ok ( ( ) )
733
- }
734
-
735
- fn last_focused_component ( & self , action_tx : mpsc:: UnboundedSender < Action > ) -> Result < ( ) > {
736
- match self . last_focused_component {
737
- Focus :: Menu => action_tx. send ( Action :: FocusMenu ) ?,
738
- Focus :: Editor => action_tx. send ( Action :: FocusEditor ) ?,
739
- Focus :: Data => action_tx. send ( Action :: FocusData ) ?,
740
- Focus :: History => action_tx. send ( Action :: FocusHistory ) ?,
741
- Focus :: Favorites => action_tx. send ( Action :: FocusFavorites ) ?,
742
- Focus :: PopUp => { } ,
743
- } ;
744
- Ok ( ( ) )
745
- }
746
732
}
0 commit comments