@@ -1437,6 +1437,63 @@ func (d *Database) GetRoomsByMembership(ctx context.Context, userID spec.UserID,
14371437 return roomIDs , nil
14381438}
14391439
1440+ // GetBulkStateACLs is a lighter weight form of GetBulkStateContent, which only returns ACL state events.
1441+ func (d * Database ) GetBulkStateACLs (ctx context.Context , roomIDs []string ) ([]tables.StrippedEvent , error ) {
1442+ tuples := []gomatrixserverlib.StateKeyTuple {{EventType : "m.room.server_acl" , StateKey : "" }}
1443+
1444+ var eventNIDs []types.EventNID
1445+ eventNIDToVer := make (map [types.EventNID ]gomatrixserverlib.RoomVersion )
1446+ // TODO: This feels like this is going to be really slow...
1447+ for _ , roomID := range roomIDs {
1448+ roomInfo , err2 := d .roomInfo (ctx , nil , roomID )
1449+ if err2 != nil {
1450+ return nil , fmt .Errorf ("GetBulkStateACLs: failed to load room info for room %s : %w" , roomID , err2 )
1451+ }
1452+ // for unknown rooms or rooms which we don't have the current state, skip them.
1453+ if roomInfo == nil || roomInfo .IsStub () {
1454+ continue
1455+ }
1456+ // No querier needed, as we don't actually do state resolution
1457+ stateRes := state .NewStateResolution (d , roomInfo , nil )
1458+ entries , err2 := stateRes .LoadStateAtSnapshotForStringTuples (ctx , roomInfo .StateSnapshotNID (), tuples )
1459+ if err2 != nil {
1460+ return nil , fmt .Errorf ("GetBulkStateACLs: failed to load state for room %s : %w" , roomID , err2 )
1461+ }
1462+ for _ , entry := range entries {
1463+ eventNIDs = append (eventNIDs , entry .EventNID )
1464+ eventNIDToVer [entry .EventNID ] = roomInfo .RoomVersion
1465+ }
1466+ }
1467+ eventIDs , err := d .EventsTable .BulkSelectEventID (ctx , nil , eventNIDs )
1468+ if err != nil {
1469+ eventIDs = map [types.EventNID ]string {}
1470+ }
1471+ events , err := d .EventJSONTable .BulkSelectEventJSON (ctx , nil , eventNIDs )
1472+ if err != nil {
1473+ return nil , fmt .Errorf ("GetBulkStateACLs: failed to load event JSON for event nids: %w" , err )
1474+ }
1475+ result := make ([]tables.StrippedEvent , len (events ))
1476+ for i := range events {
1477+ roomVer := eventNIDToVer [events [i ].EventNID ]
1478+ verImpl , err := gomatrixserverlib .GetRoomVersion (roomVer )
1479+ if err != nil {
1480+ return nil , err
1481+ }
1482+ ev , err := verImpl .NewEventFromTrustedJSONWithEventID (eventIDs [events [i ].EventNID ], events [i ].EventJSON , false )
1483+ if err != nil {
1484+ return nil , fmt .Errorf ("GetBulkStateACLs: failed to load event JSON for event NID %v : %w" , events [i ].EventNID , err )
1485+ }
1486+ result [i ] = tables.StrippedEvent {
1487+ EventType : ev .Type (),
1488+ RoomID : ev .RoomID ().String (),
1489+ StateKey : * ev .StateKey (),
1490+ ContentValue : tables .ExtractContentValue (& types.HeaderedEvent {PDU : ev }),
1491+ }
1492+ }
1493+
1494+ return result , nil
1495+ }
1496+
14401497// GetBulkStateContent returns all state events which match a given room ID and a given state key tuple. Both must be satisfied for a match.
14411498// If a tuple has the StateKey of '*' and allowWildcards=true then all state events with the EventType should be returned.
14421499func (d * Database ) GetBulkStateContent (ctx context.Context , roomIDs []string , tuples []gomatrixserverlib.StateKeyTuple , allowWildcards bool ) ([]tables.StrippedEvent , error ) {
@@ -1487,6 +1544,9 @@ func (d *Database) GetBulkStateContent(ctx context.Context, roomIDs []string, tu
14871544 if roomInfo == nil || roomInfo .IsStub () {
14881545 continue
14891546 }
1547+ // TODO: This is inefficient as we're loading the _entire_ state, but only care about a subset of it.
1548+ // This is why GetBulkStateACLs exists. LoadStateAtSnapshotForStringTuples only loads the state we care about,
1549+ // but is unfortunately not able to load wildcard state keys.
14901550 entries , err2 := d .loadStateAtSnapshot (ctx , roomInfo .StateSnapshotNID ())
14911551 if err2 != nil {
14921552 return nil , fmt .Errorf ("GetBulkStateContent: failed to load state for room %s : %w" , roomID , err2 )
0 commit comments