@@ -2,13 +2,19 @@ use clap::{crate_authors, crate_version, value_parser, Arg, ArgAction, Command};
2
2
use dialoguer:: { console:: Term , theme:: ColorfulTheme , Input , MultiSelect , Password , Select } ;
3
3
use dotenv:: dotenv;
4
4
use std:: env;
5
- use thoth:: api:: account:: model:: { AccountData , LinkedPublisher } ;
6
- use thoth:: api:: account:: service:: { all_emails, all_publishers, register, update_password} ;
7
- use thoth:: api:: db:: { init_pool, revert_migrations, run_migrations} ;
8
- use thoth:: api_server;
9
- use thoth:: app_server;
10
- use thoth:: export_server;
11
- use thoth_errors:: ThothResult ;
5
+ use thoth:: {
6
+ api:: {
7
+ account:: {
8
+ model:: { AccountData , LinkedPublisher } ,
9
+ service:: { all_emails, all_publishers, register, update_password} ,
10
+ } ,
11
+ db:: { init_pool as init_pg_pool, revert_migrations, run_migrations} ,
12
+ redis:: { del, init_pool as init_redis_pool, scan_match} ,
13
+ } ,
14
+ api_server, app_server,
15
+ errors:: { ThothError , ThothResult } ,
16
+ export_server, ALL_SPECIFICATIONS ,
17
+ } ;
12
18
13
19
fn database_argument ( ) -> Arg {
14
20
Arg :: new ( "db" )
@@ -220,6 +226,14 @@ fn thoth_commands() -> Command {
220
226
. subcommand ( Command :: new ( "register" ) . about ( "Create a new user account" ) )
221
227
. subcommand ( Command :: new ( "password" ) . about ( "Reset a password" ) ) ,
222
228
)
229
+ . subcommand (
230
+ Command :: new ( "cache" )
231
+ . about ( "Manage cached records" )
232
+ . arg ( redis_argument ( ) )
233
+ . subcommand_required ( true )
234
+ . arg_required_else_help ( true )
235
+ . subcommand ( Command :: new ( "delete" ) . about ( "Delete cached records" ) ) ,
236
+ )
223
237
}
224
238
225
239
fn main ( ) -> ThothResult < ( ) > {
@@ -326,7 +340,7 @@ fn main() -> ThothResult<()> {
326
340
let database_url = account_matches. get_one :: < String > ( "db" ) . unwrap ( ) ;
327
341
match account_matches. subcommand ( ) {
328
342
Some ( ( "register" , _) ) => {
329
- let pool = init_pool ( database_url) ;
343
+ let pool = init_pg_pool ( database_url) ;
330
344
331
345
let name = Input :: new ( )
332
346
. with_prompt ( "Enter given name" )
@@ -383,7 +397,7 @@ fn main() -> ThothResult<()> {
383
397
register ( account_data, linked_publishers, & pool) . map ( |_| ( ) )
384
398
}
385
399
Some ( ( "password" , _) ) => {
386
- let pool = init_pool ( database_url) ;
400
+ let pool = init_pg_pool ( database_url) ;
387
401
let all_emails =
388
402
all_emails ( & pool) . expect ( "No user accounts present in database." ) ;
389
403
let email_selection = Select :: with_theme ( & ColorfulTheme :: default ( ) )
@@ -402,6 +416,32 @@ fn main() -> ThothResult<()> {
402
416
_ => unreachable ! ( ) ,
403
417
}
404
418
}
419
+ Some ( ( "cache" , cache_matches) ) => match cache_matches. subcommand ( ) {
420
+ Some ( ( "delete" , _) ) => {
421
+ let redis_url = cache_matches. get_one :: < String > ( "redis" ) . unwrap ( ) ;
422
+ let pool = init_redis_pool ( redis_url) ;
423
+ let chosen: Vec < usize > = MultiSelect :: new ( )
424
+ . items ( & ALL_SPECIFICATIONS )
425
+ . with_prompt ( "Select cached specifications to delete" )
426
+ . interact_on ( & Term :: stdout ( ) ) ?;
427
+ // run a separate tokio runtime to avoid interfering with actix's threads
428
+ let runtime = tokio:: runtime:: Builder :: new_multi_thread ( )
429
+ . worker_threads ( 1 )
430
+ . enable_all ( )
431
+ . build ( ) ?;
432
+ runtime. block_on ( async {
433
+ for index in chosen {
434
+ let specification = ALL_SPECIFICATIONS . get ( index) . unwrap ( ) ;
435
+ let keys = scan_match ( & pool, & format ! ( "{}*" , specification) ) . await ?;
436
+ for key in keys {
437
+ del ( & pool, & key) . await ?;
438
+ }
439
+ }
440
+ Ok :: < ( ) , ThothError > ( ( ) )
441
+ } )
442
+ }
443
+ _ => unreachable ! ( ) ,
444
+ } ,
405
445
_ => unreachable ! ( ) ,
406
446
}
407
447
}
0 commit comments