@@ -2,13 +2,19 @@ use clap::{crate_authors, crate_version, value_parser, Arg, ArgAction, Command};
22use dialoguer:: { console:: Term , theme:: ColorfulTheme , Input , MultiSelect , Password , Select } ;
33use dotenv:: dotenv;
44use 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+ } ;
1218
1319fn database_argument ( ) -> Arg {
1420 Arg :: new ( "db" )
@@ -220,6 +226,14 @@ fn thoth_commands() -> Command {
220226 . subcommand ( Command :: new ( "register" ) . about ( "Create a new user account" ) )
221227 . subcommand ( Command :: new ( "password" ) . about ( "Reset a password" ) ) ,
222228 )
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+ )
223237}
224238
225239fn main ( ) -> ThothResult < ( ) > {
@@ -326,7 +340,7 @@ fn main() -> ThothResult<()> {
326340 let database_url = account_matches. get_one :: < String > ( "db" ) . unwrap ( ) ;
327341 match account_matches. subcommand ( ) {
328342 Some ( ( "register" , _) ) => {
329- let pool = init_pool ( database_url) ;
343+ let pool = init_pg_pool ( database_url) ;
330344
331345 let name = Input :: new ( )
332346 . with_prompt ( "Enter given name" )
@@ -383,7 +397,7 @@ fn main() -> ThothResult<()> {
383397 register ( account_data, linked_publishers, & pool) . map ( |_| ( ) )
384398 }
385399 Some ( ( "password" , _) ) => {
386- let pool = init_pool ( database_url) ;
400+ let pool = init_pg_pool ( database_url) ;
387401 let all_emails =
388402 all_emails ( & pool) . expect ( "No user accounts present in database." ) ;
389403 let email_selection = Select :: with_theme ( & ColorfulTheme :: default ( ) )
@@ -402,6 +416,32 @@ fn main() -> ThothResult<()> {
402416 _ => unreachable ! ( ) ,
403417 }
404418 }
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+ } ,
405445 _ => unreachable ! ( ) ,
406446 }
407447}
0 commit comments