@@ -21,50 +21,47 @@ use crate::views::{EncodableMe, EncodablePrivateUser, EncodableVersion, OwnedCra
2121
2222/// Handles the `GET /me` route.
2323pub async fn me ( app : AppState , req : Parts ) -> AppResult < Json < EncodableMe > > {
24+ use diesel_async:: RunQueryDsl ;
25+
2426 let mut conn = app. db_read_prefer_primary ( ) . await ?;
2527 let user_id = AuthCheck :: only_cookie ( )
2628 . check ( & req, & mut conn)
2729 . await ?
2830 . user_id ( ) ;
29- spawn_blocking ( move || {
30- use diesel:: RunQueryDsl ;
31-
32- let conn: & mut AsyncConnectionWrapper < _ > = & mut conn. into ( ) ;
31+ let ( user, verified, email, verification_sent) : ( User , Option < bool > , Option < String > , bool ) =
32+ users:: table
33+ . find ( user_id)
34+ . left_join ( emails:: table)
35+ . select ( (
36+ User :: as_select ( ) ,
37+ emails:: verified. nullable ( ) ,
38+ emails:: email. nullable ( ) ,
39+ emails:: token_generated_at. nullable ( ) . is_not_null ( ) ,
40+ ) )
41+ . first ( & mut conn)
42+ . await ?;
43+
44+ let owned_crates = CrateOwner :: by_owner_kind ( OwnerKind :: User )
45+ . inner_join ( crates:: table)
46+ . filter ( crate_owners:: owner_id. eq ( user_id) )
47+ . select ( ( crates:: id, crates:: name, crate_owners:: email_notifications) )
48+ . order ( crates:: name. asc ( ) )
49+ . load ( & mut conn)
50+ . await ?
51+ . into_iter ( )
52+ . map ( |( id, name, email_notifications) | OwnedCrate {
53+ id,
54+ name,
55+ email_notifications,
56+ } )
57+ . collect ( ) ;
3358
34- let ( user, verified, email, verification_sent) : ( User , Option < bool > , Option < String > , bool ) =
35- users:: table
36- . find ( user_id)
37- . left_join ( emails:: table)
38- . select ( (
39- User :: as_select ( ) ,
40- emails:: verified. nullable ( ) ,
41- emails:: email. nullable ( ) ,
42- emails:: token_generated_at. nullable ( ) . is_not_null ( ) ,
43- ) )
44- . first ( conn) ?;
45-
46- let owned_crates = CrateOwner :: by_owner_kind ( OwnerKind :: User )
47- . inner_join ( crates:: table)
48- . filter ( crate_owners:: owner_id. eq ( user_id) )
49- . select ( ( crates:: id, crates:: name, crate_owners:: email_notifications) )
50- . order ( crates:: name. asc ( ) )
51- . load ( conn) ?
52- . into_iter ( )
53- . map ( |( id, name, email_notifications) | OwnedCrate {
54- id,
55- name,
56- email_notifications,
57- } )
58- . collect ( ) ;
59-
60- let verified = verified. unwrap_or ( false ) ;
61- let verification_sent = verified || verification_sent;
62- Ok ( Json ( EncodableMe {
63- user : EncodablePrivateUser :: from ( user, email, verified, verification_sent) ,
64- owned_crates,
65- } ) )
66- } )
67- . await
59+ let verified = verified. unwrap_or ( false ) ;
60+ let verification_sent = verified || verification_sent;
61+ Ok ( Json ( EncodableMe {
62+ user : EncodablePrivateUser :: from ( user, email, verified, verification_sent) ,
63+ owned_crates,
64+ } ) )
6865}
6966
7067/// Handles the `GET /me/updates` route.
@@ -110,29 +107,28 @@ pub async fn updates(app: AppState, req: Parts) -> AppResult<Json<Value>> {
110107
111108/// Handles the `PUT /confirm/:email_token` route
112109pub async fn confirm_user_email ( state : AppState , Path ( token) : Path < String > ) -> AppResult < Response > {
113- let conn = state. db_write ( ) . await ?;
114- spawn_blocking ( move || {
115- use diesel:: RunQueryDsl ;
116-
117- let conn: & mut AsyncConnectionWrapper < _ > = & mut conn. into ( ) ;
110+ use diesel:: update;
111+ use diesel_async:: RunQueryDsl ;
118112
119- use diesel :: update ;
113+ let mut conn = state . db_write ( ) . await ? ;
120114
121- let updated_rows = update ( emails:: table. filter ( emails:: token. eq ( & token) ) )
122- . set ( emails:: verified. eq ( true ) )
123- . execute ( conn) ?;
115+ let updated_rows = update ( emails:: table. filter ( emails:: token. eq ( & token) ) )
116+ . set ( emails:: verified. eq ( true ) )
117+ . execute ( & mut conn)
118+ . await ?;
124119
125- if updated_rows == 0 {
126- return Err ( bad_request ( "Email belonging to token not found." ) ) ;
127- }
120+ if updated_rows == 0 {
121+ return Err ( bad_request ( "Email belonging to token not found." ) ) ;
122+ }
128123
129- ok_true ( )
130- } )
131- . await
124+ ok_true ( )
132125}
133126
134127/// Handles `PUT /me/email_notifications` route
135128pub async fn update_email_notifications ( app : AppState , req : BytesRequest ) -> AppResult < Response > {
129+ use diesel:: pg:: upsert:: excluded;
130+ use diesel_async:: RunQueryDsl ;
131+
136132 let ( parts, body) = req. 0 . into_parts ( ) ;
137133
138134 #[ derive( Deserialize ) ]
@@ -152,51 +148,45 @@ pub async fn update_email_notifications(app: AppState, req: BytesRequest) -> App
152148 . check ( & parts, & mut conn)
153149 . await ?
154150 . user_id ( ) ;
155- spawn_blocking ( move || {
156- use diesel:: RunQueryDsl ;
157151
158- let conn: & mut AsyncConnectionWrapper < _ > = & mut conn. into ( ) ;
159-
160- use diesel:: pg:: upsert:: excluded;
161-
162- // Build inserts from existing crates belonging to the current user
163- let to_insert = CrateOwner :: by_owner_kind ( OwnerKind :: User )
164- . filter ( crate_owners:: owner_id. eq ( user_id) )
165- . select ( (
166- crate_owners:: crate_id,
167- crate_owners:: owner_id,
168- crate_owners:: owner_kind,
169- crate_owners:: email_notifications,
170- ) )
171- . load ( conn) ?
172- . into_iter ( )
173- // Remove records whose `email_notifications` will not change from their current value
174- . map (
175- |( c_id, o_id, o_kind, e_notifications) : ( i32 , i32 , i32 , bool ) | {
176- let current_e_notifications = * updates. get ( & c_id) . unwrap_or ( & e_notifications) ;
177- (
178- crate_owners:: crate_id. eq ( c_id) ,
179- crate_owners:: owner_id. eq ( o_id) ,
180- crate_owners:: owner_kind. eq ( o_kind) ,
181- crate_owners:: email_notifications. eq ( current_e_notifications) ,
182- )
183- } ,
184- )
185- . collect :: < Vec < _ > > ( ) ;
186-
187- // Upsert crate owners; this should only actually execute updates
188- diesel:: insert_into ( crate_owners:: table)
189- . values ( & to_insert)
190- . on_conflict ( (
191- crate_owners:: crate_id,
192- crate_owners:: owner_id,
193- crate_owners:: owner_kind,
194- ) )
195- . do_update ( )
196- . set ( crate_owners:: email_notifications. eq ( excluded ( crate_owners:: email_notifications) ) )
197- . execute ( conn) ?;
198-
199- ok_true ( )
200- } )
201- . await
152+ // Build inserts from existing crates belonging to the current user
153+ let to_insert = CrateOwner :: by_owner_kind ( OwnerKind :: User )
154+ . filter ( crate_owners:: owner_id. eq ( user_id) )
155+ . select ( (
156+ crate_owners:: crate_id,
157+ crate_owners:: owner_id,
158+ crate_owners:: owner_kind,
159+ crate_owners:: email_notifications,
160+ ) )
161+ . load ( & mut conn)
162+ . await ?
163+ . into_iter ( )
164+ // Remove records whose `email_notifications` will not change from their current value
165+ . map (
166+ |( c_id, o_id, o_kind, e_notifications) : ( i32 , i32 , i32 , bool ) | {
167+ let current_e_notifications = * updates. get ( & c_id) . unwrap_or ( & e_notifications) ;
168+ (
169+ crate_owners:: crate_id. eq ( c_id) ,
170+ crate_owners:: owner_id. eq ( o_id) ,
171+ crate_owners:: owner_kind. eq ( o_kind) ,
172+ crate_owners:: email_notifications. eq ( current_e_notifications) ,
173+ )
174+ } ,
175+ )
176+ . collect :: < Vec < _ > > ( ) ;
177+
178+ // Upsert crate owners; this should only actually execute updates
179+ diesel:: insert_into ( crate_owners:: table)
180+ . values ( & to_insert)
181+ . on_conflict ( (
182+ crate_owners:: crate_id,
183+ crate_owners:: owner_id,
184+ crate_owners:: owner_kind,
185+ ) )
186+ . do_update ( )
187+ . set ( crate_owners:: email_notifications. eq ( excluded ( crate_owners:: email_notifications) ) )
188+ . execute ( & mut conn)
189+ . await ?;
190+
191+ ok_true ( )
202192}
0 commit comments