@@ -199,6 +199,10 @@ pub struct MasNewUser {
199199 pub created_at : DateTime < Utc > ,
200200 pub locked_at : Option < DateTime < Utc > > ,
201201 pub can_request_admin : bool ,
202+ /// Whether the user was a Synapse guest.
203+ /// Although MAS doesn't support guest access, it's still useful to track
204+ /// for the future.
205+ pub is_guest : bool ,
202206}
203207
204208pub struct MasNewUserPassword {
@@ -563,52 +567,66 @@ impl<'conn> MasWriter<'conn> {
563567 #[ allow( clippy:: missing_panics_doc) ] // not a real panic
564568 #[ tracing:: instrument( skip_all, level = Level :: DEBUG ) ]
565569 pub fn write_users ( & mut self , users : Vec < MasNewUser > ) -> BoxFuture < ' _ , Result < ( ) , Error > > {
566- self . writer_pool . spawn_with_connection ( move |conn| Box :: pin ( async move {
567- // `UNNEST` is a fast way to do bulk inserts, as it lets us send multiple rows in one statement
568- // without having to change the statement SQL thus altering the query plan.
569- // See <https://github.com/launchbadge/sqlx/blob/main/FAQ.md#how-can-i-bind-an-array-to-a-values-clause-how-can-i-do-bulk-inserts>.
570- // In the future we could consider using sqlx's support for `PgCopyIn` / the `COPY FROM STDIN` statement,
571- // which is allegedly the best for insert performance, but is less simple to encode.
572- if users. is_empty ( ) {
573- return Ok ( ( ) ) ;
574- }
575-
576- let mut user_ids: Vec < Uuid > = Vec :: with_capacity ( users. len ( ) ) ;
577- let mut usernames: Vec < String > = Vec :: with_capacity ( users. len ( ) ) ;
578- let mut created_ats: Vec < DateTime < Utc > > = Vec :: with_capacity ( users. len ( ) ) ;
579- let mut locked_ats: Vec < Option < DateTime < Utc > > > = Vec :: with_capacity ( users. len ( ) ) ;
580- let mut can_request_admins: Vec < bool > = Vec :: with_capacity ( users. len ( ) ) ;
581- for MasNewUser {
582- user_id,
583- username,
584- created_at,
585- locked_at,
586- can_request_admin,
587- } in users
588- {
589- user_ids. push ( user_id) ;
590- usernames. push ( username) ;
591- created_ats. push ( created_at) ;
592- locked_ats. push ( locked_at) ;
593- can_request_admins. push ( can_request_admin) ;
594- }
570+ self . writer_pool
571+ . spawn_with_connection ( move |conn| {
572+ Box :: pin ( async move {
573+ // `UNNEST` is a fast way to do bulk inserts, as it lets us send multiple rows
574+ // in one statement without having to change the statement
575+ // SQL thus altering the query plan. See <https://github.com/launchbadge/sqlx/blob/main/FAQ.md#how-can-i-bind-an-array-to-a-values-clause-how-can-i-do-bulk-inserts>.
576+ // In the future we could consider using sqlx's support for `PgCopyIn` / the
577+ // `COPY FROM STDIN` statement, which is allegedly the best
578+ // for insert performance, but is less simple to encode.
579+ let mut user_ids: Vec < Uuid > = Vec :: with_capacity ( users. len ( ) ) ;
580+ let mut usernames: Vec < String > = Vec :: with_capacity ( users. len ( ) ) ;
581+ let mut created_ats: Vec < DateTime < Utc > > = Vec :: with_capacity ( users. len ( ) ) ;
582+ let mut locked_ats: Vec < Option < DateTime < Utc > > > =
583+ Vec :: with_capacity ( users. len ( ) ) ;
584+ let mut can_request_admins: Vec < bool > = Vec :: with_capacity ( users. len ( ) ) ;
585+ let mut is_guests: Vec < bool > = Vec :: with_capacity ( users. len ( ) ) ;
586+ for MasNewUser {
587+ user_id,
588+ username,
589+ created_at,
590+ locked_at,
591+ can_request_admin,
592+ is_guest,
593+ } in users
594+ {
595+ user_ids. push ( user_id) ;
596+ usernames. push ( username) ;
597+ created_ats. push ( created_at) ;
598+ locked_ats. push ( locked_at) ;
599+ can_request_admins. push ( can_request_admin) ;
600+ is_guests. push ( is_guest) ;
601+ }
595602
596- sqlx:: query!(
597- r#"
598- INSERT INTO syn2mas__users
599- (user_id, username, created_at, locked_at, can_request_admin)
600- SELECT * FROM UNNEST($1::UUID[], $2::TEXT[], $3::TIMESTAMP WITH TIME ZONE[], $4::TIMESTAMP WITH TIME ZONE[], $5::BOOL[])
601- "# ,
602- & user_ids[ ..] ,
603- & usernames[ ..] ,
604- & created_ats[ ..] ,
605- // We need to override the typing for arrays of optionals (sqlx limitation)
606- & locked_ats[ ..] as & [ Option <DateTime <Utc >>] ,
607- & can_request_admins[ ..] ,
608- ) . execute ( & mut * conn) . await . into_database ( "writing users to MAS" ) ?;
603+ sqlx:: query!(
604+ r#"
605+ INSERT INTO syn2mas__users (
606+ user_id, username,
607+ created_at, locked_at,
608+ can_request_admin, is_guest)
609+ SELECT * FROM UNNEST(
610+ $1::UUID[], $2::TEXT[],
611+ $3::TIMESTAMP WITH TIME ZONE[], $4::TIMESTAMP WITH TIME ZONE[],
612+ $5::BOOL[], $6::BOOL[])
613+ "# ,
614+ & user_ids[ ..] ,
615+ & usernames[ ..] ,
616+ & created_ats[ ..] ,
617+ // We need to override the typing for arrays of optionals (sqlx limitation)
618+ & locked_ats[ ..] as & [ Option <DateTime <Utc >>] ,
619+ & can_request_admins[ ..] ,
620+ & is_guests[ ..] ,
621+ )
622+ . execute ( & mut * conn)
623+ . await
624+ . into_database ( "writing users to MAS" ) ?;
609625
610- Ok ( ( ) )
611- } ) ) . boxed ( )
626+ Ok ( ( ) )
627+ } )
628+ } )
629+ . boxed ( )
612630 }
613631
614632 /// Write a batch of user passwords to the database.
@@ -1197,6 +1215,7 @@ mod test {
11971215 created_at: DateTime :: default ( ) ,
11981216 locked_at: None ,
11991217 can_request_admin: false ,
1218+ is_guest: false ,
12001219 } ] )
12011220 . await
12021221 . expect ( "failed to write user" ) ;
@@ -1221,6 +1240,7 @@ mod test {
12211240 created_at: DateTime :: default ( ) ,
12221241 locked_at: None ,
12231242 can_request_admin: false ,
1243+ is_guest: false ,
12241244 } ] )
12251245 . await
12261246 . expect ( "failed to write user" ) ;
@@ -1252,6 +1272,7 @@ mod test {
12521272 created_at: DateTime :: default ( ) ,
12531273 locked_at: None ,
12541274 can_request_admin: false ,
1275+ is_guest: false ,
12551276 } ] )
12561277 . await
12571278 . expect ( "failed to write user" ) ;
@@ -1285,6 +1306,7 @@ mod test {
12851306 created_at: DateTime :: default ( ) ,
12861307 locked_at: None ,
12871308 can_request_admin: false ,
1309+ is_guest: false ,
12881310 } ] )
12891311 . await
12901312 . expect ( "failed to write user" ) ;
@@ -1319,6 +1341,7 @@ mod test {
13191341 created_at: DateTime :: default ( ) ,
13201342 locked_at: None ,
13211343 can_request_admin: false ,
1344+ is_guest: false ,
13221345 } ] )
13231346 . await
13241347 . expect ( "failed to write user" ) ;
@@ -1352,6 +1375,7 @@ mod test {
13521375 created_at: DateTime :: default ( ) ,
13531376 locked_at: None ,
13541377 can_request_admin: false ,
1378+ is_guest: false ,
13551379 } ] )
13561380 . await
13571381 . expect ( "failed to write user" ) ;
@@ -1389,6 +1413,7 @@ mod test {
13891413 created_at: DateTime :: default ( ) ,
13901414 locked_at: None ,
13911415 can_request_admin: false ,
1416+ is_guest: false ,
13921417 } ] )
13931418 . await
13941419 . expect ( "failed to write user" ) ;
@@ -1438,6 +1463,7 @@ mod test {
14381463 created_at: DateTime :: default ( ) ,
14391464 locked_at: None ,
14401465 can_request_admin: false ,
1466+ is_guest: false ,
14411467 } ] )
14421468 . await
14431469 . expect ( "failed to write user" ) ;
0 commit comments