@@ -9,7 +9,7 @@ use serenity::{
99
1010use kaisantantoudaijin:: {
1111 context:: { ChannelContext , ContextBuilder } ,
12- database:: RedisHandle ,
12+ database:: { AnyDatabaseHandle , DynamoDbHandle , RedisHandle } ,
1313 model:: message:: Message ,
1414} ;
1515
@@ -19,10 +19,40 @@ fn strip_affix<'a>(content: &'a str, affix: &str) -> Option<&'a str> {
1919 . or_else ( || content. strip_suffix ( affix) )
2020}
2121
22+ #[ derive( Debug , Clone ) ]
23+ enum DatabaseClient {
24+ Redis {
25+ prefix : String ,
26+ pool : deadpool_redis:: Pool ,
27+ } ,
28+ DynamoDb {
29+ table_name : String ,
30+ client : aws_sdk_dynamodb:: Client ,
31+ } ,
32+ }
33+
34+ impl DatabaseClient {
35+ pub async fn obtain_handle (
36+ & self ,
37+ guild_id : serenity:: model:: id:: GuildId ,
38+ ) -> Result < AnyDatabaseHandle > {
39+ match self {
40+ DatabaseClient :: Redis { prefix, pool } => {
41+ let conn = pool. get ( ) . await ?;
42+ let db = RedisHandle :: new ( prefix. clone ( ) , guild_id, conn) ;
43+ Ok ( db. into ( ) )
44+ }
45+ DatabaseClient :: DynamoDb { table_name, client } => {
46+ let db = DynamoDbHandle :: new ( client. clone ( ) , guild_id, table_name. clone ( ) ) ;
47+ Ok ( db. into ( ) )
48+ }
49+ }
50+ }
51+ }
52+
2253struct Handler {
2354 command_prefix : String ,
24- redis_prefix : String ,
25- redis : deadpool_redis:: Pool ,
55+ database_client : DatabaseClient ,
2656}
2757
2858#[ async_trait:: async_trait]
@@ -54,16 +84,15 @@ impl EventHandler for Handler {
5484 return ;
5585 } ;
5686
57- let redis_conn = match self . redis . get ( ) . await {
87+ let db = match self . database_client . obtain_handle ( guild_id ) . await {
5888 Ok ( x) => x,
5989 Err ( e) => {
60- tracing:: error!( "error in getting redis connection: {:#}" , e) ;
90+ tracing:: error!( "error in getting DB connection: {:#}" , e) ;
6191 let _ = msg. channel_id . say ( & ctx. http , "エラーが発生しました" ) . await ;
6292 return ;
6393 }
6494 } ;
6595
66- let db = RedisHandle :: new ( self . redis_prefix . clone ( ) , guild_id, redis_conn) ;
6796 let ctx = ContextBuilder :: with_serenity ( & ctx)
6897 . db ( db)
6998 . guild_id ( guild_id)
@@ -88,6 +117,7 @@ impl EventHandler for Handler {
88117
89118#[ derive( Parser ) ]
90119#[ command( group( clap:: ArgGroup :: new( "tokens" ) . required( true ) . multiple( false ) . args( [ "token" , "token_file" ] ) ) ) ]
120+ #[ command( group( clap:: ArgGroup :: new( "database_config" ) . required( true ) . multiple( false ) . args( [ "redis_uri" , "dynamodb_table_name" ] ) ) ) ]
91121struct Args {
92122 #[ arg( long, default_value = "!kaisan" , env = "KAISANDAIJIN_COMMAND_PREFIX" ) ]
93123 command_prefix : String ,
@@ -96,14 +126,16 @@ struct Args {
96126 #[ arg( long, env = "KAISANDAIJIN_DISCORD_TOKEN_FILE" ) ]
97127 token_file : Option < PathBuf > ,
98128 #[ arg( short, long, env = "KAISANDAIJIN_REDIS_URI" ) ]
99- redis_uri : String ,
129+ redis_uri : Option < String > ,
100130 #[ arg(
101131 short = 'p' ,
102132 long,
103133 default_value = "kaisandaijin" ,
104134 env = "KAISANDAIJIN_REDIS_PREFIX"
105135 ) ]
106136 redis_prefix : String ,
137+ #[ arg( short, long, env = "KAISANDAIJIN_DYNAMODB_TABLE_NAME" ) ]
138+ dynamodb_table_name : Option < String > ,
107139 /// Specify log level filter, configured in conjunction with KAISANDAIJIN_LOG environment variable
108140 #[ arg( short, long) ]
109141 log_level : Option < tracing_subscriber:: filter:: LevelFilter > ,
@@ -113,9 +145,6 @@ struct Args {
113145async fn main ( ) -> Result < ( ) > {
114146 let args = Args :: parse ( ) ;
115147
116- let redis = deadpool_redis:: Config :: from_url ( args. redis_uri )
117- . create_pool ( Some ( deadpool_redis:: Runtime :: Tokio1 ) ) ?;
118-
119148 let token = if let Some ( token) = args. token {
120149 token
121150 } else {
@@ -135,6 +164,22 @@ async fn main() -> Result<()> {
135164 . with_writer ( std:: io:: stderr)
136165 . init ( ) ;
137166
167+ let database_client = match ( & args. redis_uri , & args. dynamodb_table_name ) {
168+ ( Some ( redis_uri) , None ) => DatabaseClient :: Redis {
169+ prefix : args. redis_prefix . clone ( ) ,
170+ pool : deadpool_redis:: Config :: from_url ( redis_uri)
171+ . create_pool ( Some ( deadpool_redis:: Runtime :: Tokio1 ) ) ?,
172+ } ,
173+ ( None , Some ( table_name) ) => DatabaseClient :: DynamoDb {
174+ table_name : table_name. clone ( ) ,
175+ client : {
176+ let config = aws_config:: load_from_env ( ) . await ;
177+ aws_sdk_dynamodb:: Client :: new ( & config)
178+ } ,
179+ } ,
180+ _ => anyhow:: bail!( "either Redis URI or DynamoDB table name must be specified" ) ,
181+ } ;
182+
138183 let intents = [
139184 GatewayIntents :: GUILDS ,
140185 GatewayIntents :: GUILD_MESSAGES ,
@@ -146,8 +191,7 @@ async fn main() -> Result<()> {
146191 let mut client = Client :: builder ( token, intents)
147192 . event_handler ( Handler {
148193 command_prefix : args. command_prefix ,
149- redis_prefix : args. redis_prefix ,
150- redis,
194+ database_client,
151195 } )
152196 . await
153197 . context ( "Failed to create client" ) ?;
0 commit comments