11use std:: sync:: Arc ;
22
3- use async_graphql:: { Context , Error , Object , Result } ;
3+ use async_graphql:: { Context , Object , Result } ;
44use sqlx:: PgPool ;
55
66use crate :: models:: status_update_streak:: { StatusUpdateStreak as Streak , StreakInput } ;
@@ -14,29 +14,15 @@ impl StreakMutations {
1414 async fn increment_streak ( & self , ctx : & Context < ' _ > , input : StreakInput ) -> Result < Streak > {
1515 let pool = ctx. data :: < Arc < PgPool > > ( ) . expect ( "Pool must be in context." ) ;
1616
17- // Ensure at least one identifier is provided
18- if input. member_id . is_none ( ) && input. discord_id . is_none ( ) {
19- return Err ( Error :: new (
20- "Either `member_id` or `discord_id` must be provided." ,
21- ) ) ;
22- }
23-
24- let mut sql = String :: from ( "UPDATE Streaks SET current_streak = current_streak + 1, max_streak = GREATEST(max_streak, current_streak + 1) WHERE " ) ;
25- if let Some ( _) = input. member_id {
26- sql. push_str ( "member_id = $1" ) ;
27- } else if let Some ( _) = input. discord_id {
28- sql. push_str ( "discord_id = $1" ) ;
29- }
30-
31- sql. push_str ( " RETURNING *" ) ;
32-
33- let query = if let Some ( member_id) = input. member_id {
34- sqlx:: query_as :: < _ , Streak > ( & sql) . bind ( member_id)
35- } else if let Some ( discord_id) = input. discord_id {
36- sqlx:: query_as :: < _ , Streak > ( & sql) . bind ( discord_id)
37- } else {
38- return Err ( Error :: new ( "Invalid input." ) ) ;
39- } ;
17+ let query = sqlx:: query_as :: < _ , Streak > (
18+ "
19+ INSERT INTO StatusUpdateStreak VALUES ($1, 1, 1)
20+ ON CONFLICT (member_id) DO UPDATE SET
21+ current_streak = StatusUpdateStreak.current_streak + 1,
22+ max_streak = GREATEST(StatusUpdateStreak.max_streak, StatusUpdateStreak.current_streak + 1)
23+ RETURNING *" ,
24+ )
25+ . bind ( input. member_id ) ;
4026
4127 let updated_streak = query. fetch_one ( pool. as_ref ( ) ) . await ?;
4228
@@ -46,30 +32,17 @@ impl StreakMutations {
4632 async fn reset_streak ( & self , ctx : & Context < ' _ > , input : StreakInput ) -> Result < Streak > {
4733 let pool = ctx. data :: < Arc < PgPool > > ( ) . expect ( "Pool must be in context." ) ;
4834
49- // Ensure at least one identifier is provided
50- if input. member_id . is_none ( ) && input. discord_id . is_none ( ) {
51- return Err ( Error :: new (
52- "Either `member_id` or `discord_id` must be provided." ,
53- ) ) ;
54- }
55-
56- let mut sql = String :: from ( "UPDATE Streaks SET current_streak = 0 WHERE " ) ;
57-
58- if let Some ( _) = input. member_id {
59- sql. push_str ( "member_id = $1" ) ;
60- } else if let Some ( _) = input. discord_id {
61- sql. push_str ( "discord_id = $1" ) ;
62- }
63-
64- sql. push_str ( " RETURNING *" ) ;
65-
66- let query = if let Some ( member_id) = input. member_id {
67- sqlx:: query_as :: < _ , Streak > ( & sql) . bind ( member_id)
68- } else if let Some ( discord_id) = input. discord_id {
69- sqlx:: query_as :: < _ , Streak > ( & sql) . bind ( discord_id)
70- } else {
71- return Err ( Error :: new ( "Invalid input." ) ) ;
72- } ;
35+ let query = sqlx:: query_as :: < _ , Streak > (
36+ "
37+ INSERT INTO StatusUpdateStreak VALUES ($1, 0, 0)
38+ ON CONFLICT (member_id) DO UPDATE
39+ SET current_streak = CASE
40+ WHEN StatusUpdateStreak.current_streak > 0 THEN 0
41+ ELSE StatusUpdateStreak.current_streak - 1
42+ END
43+ RETURNING *" ,
44+ )
45+ . bind ( input. member_id ) ;
7346
7447 let updated_streak = query. fetch_one ( pool. as_ref ( ) ) . await ?;
7548 Ok ( updated_streak)
0 commit comments