@@ -199,6 +199,9 @@ 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 for the future.
204+ pub is_guest : bool ,
202205}
203206
204207pub struct MasNewUserPassword {
@@ -563,52 +566,65 @@ impl<'conn> MasWriter<'conn> {
563566 #[ allow( clippy:: missing_panics_doc) ] // not a real panic
564567 #[ tracing:: instrument( skip_all, level = Level :: DEBUG ) ]
565568 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- }
569+ self . writer_pool
570+ . spawn_with_connection ( move |conn| {
571+ Box :: pin ( async move {
572+ // `UNNEST` is a fast way to do bulk inserts, as it lets us send multiple rows in one statement
573+ // without having to change the statement SQL thus altering the query plan.
574+ // 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>.
575+ // In the future we could consider using sqlx's support for `PgCopyIn` / the `COPY FROM STDIN` statement,
576+ // which is allegedly the best for insert performance, but is less simple to encode.
577+ let mut user_ids: Vec < Uuid > = Vec :: with_capacity ( users. len ( ) ) ;
578+ let mut usernames: Vec < String > = Vec :: with_capacity ( users. len ( ) ) ;
579+ let mut created_ats: Vec < DateTime < Utc > > = Vec :: with_capacity ( users. len ( ) ) ;
580+ let mut locked_ats: Vec < Option < DateTime < Utc > > > =
581+ Vec :: with_capacity ( users. len ( ) ) ;
582+ let mut can_request_admins: Vec < bool > = Vec :: with_capacity ( users. len ( ) ) ;
583+ let mut is_guests: Vec < bool > = Vec :: with_capacity ( users. len ( ) ) ;
584+ for MasNewUser {
585+ user_id,
586+ username,
587+ created_at,
588+ locked_at,
589+ can_request_admin,
590+ is_guest,
591+ } in users
592+ {
593+ user_ids. push ( user_id) ;
594+ usernames. push ( username) ;
595+ created_ats. push ( created_at) ;
596+ locked_ats. push ( locked_at) ;
597+ can_request_admins. push ( can_request_admin) ;
598+ is_guests. push ( is_guest) ;
599+ }
595600
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" ) ?;
601+ sqlx:: query!(
602+ r#"
603+ INSERT INTO syn2mas__users (
604+ user_id, username,
605+ created_at, locked_at,
606+ can_request_admin, is_guest)
607+ SELECT * FROM UNNEST(
608+ $1::UUID[], $2::TEXT[],
609+ $3::TIMESTAMP WITH TIME ZONE[], $4::TIMESTAMP WITH TIME ZONE[],
610+ $5::BOOL[], $6::BOOL[])
611+ "# ,
612+ & user_ids[ ..] ,
613+ & usernames[ ..] ,
614+ & created_ats[ ..] ,
615+ // We need to override the typing for arrays of optionals (sqlx limitation)
616+ & locked_ats[ ..] as & [ Option <DateTime <Utc >>] ,
617+ & can_request_admins[ ..] ,
618+ & is_guests[ ..] ,
619+ )
620+ . execute ( & mut * conn)
621+ . await
622+ . into_database ( "writing users to MAS" ) ?;
609623
610- Ok ( ( ) )
611- } ) ) . boxed ( )
624+ Ok ( ( ) )
625+ } )
626+ } )
627+ . boxed ( )
612628 }
613629
614630 /// Write a batch of user passwords to the database.
@@ -1197,6 +1213,7 @@ mod test {
11971213 created_at: DateTime :: default ( ) ,
11981214 locked_at: None ,
11991215 can_request_admin: false ,
1216+ is_guest: false ,
12001217 } ] )
12011218 . await
12021219 . expect ( "failed to write user" ) ;
@@ -1221,6 +1238,7 @@ mod test {
12211238 created_at: DateTime :: default ( ) ,
12221239 locked_at: None ,
12231240 can_request_admin: false ,
1241+ is_guest: false ,
12241242 } ] )
12251243 . await
12261244 . expect ( "failed to write user" ) ;
@@ -1252,6 +1270,7 @@ mod test {
12521270 created_at: DateTime :: default ( ) ,
12531271 locked_at: None ,
12541272 can_request_admin: false ,
1273+ is_guest: false ,
12551274 } ] )
12561275 . await
12571276 . expect ( "failed to write user" ) ;
@@ -1285,6 +1304,7 @@ mod test {
12851304 created_at: DateTime :: default ( ) ,
12861305 locked_at: None ,
12871306 can_request_admin: false ,
1307+ is_guest: false ,
12881308 } ] )
12891309 . await
12901310 . expect ( "failed to write user" ) ;
@@ -1319,6 +1339,7 @@ mod test {
13191339 created_at: DateTime :: default ( ) ,
13201340 locked_at: None ,
13211341 can_request_admin: false ,
1342+ is_guest: false ,
13221343 } ] )
13231344 . await
13241345 . expect ( "failed to write user" ) ;
@@ -1352,6 +1373,7 @@ mod test {
13521373 created_at: DateTime :: default ( ) ,
13531374 locked_at: None ,
13541375 can_request_admin: false ,
1376+ is_guest: false ,
13551377 } ] )
13561378 . await
13571379 . expect ( "failed to write user" ) ;
@@ -1389,6 +1411,7 @@ mod test {
13891411 created_at: DateTime :: default ( ) ,
13901412 locked_at: None ,
13911413 can_request_admin: false ,
1414+ is_guest: false ,
13921415 } ] )
13931416 . await
13941417 . expect ( "failed to write user" ) ;
@@ -1437,6 +1460,7 @@ mod test {
14371460 created_at: DateTime :: default ( ) ,
14381461 locked_at: None ,
14391462 can_request_admin: false ,
1463+ is_guest: false ,
14401464 } ] )
14411465 . await
14421466 . expect ( "failed to write user" ) ;
0 commit comments