try to load members from database first and cache them in-memory

This commit is contained in:
Sorunome 2020-07-14 11:30:13 +02:00
parent 259cede94e
commit 4394196ba1
No known key found for this signature in database
GPG key ID: B19471D07FC9BE9C
4 changed files with 24 additions and 14 deletions

View file

@ -528,6 +528,15 @@ class Database extends _$Database {
return sdk.Event.fromDb(res.first, room).asUser; return sdk.Event.fromDb(res.first, room).asUser;
} }
Future<List<sdk.User>> getUsers(int clientId, sdk.Room room) async {
final res = await dbGetUsers(clientId, room.id).get();
final ret = <sdk.User>[];
for (final r in res) {
ret.add(sdk.Event.fromDb(r, room).asUser);
}
return ret;
}
Future<List<sdk.Event>> getEventList(int clientId, sdk.Room room) async { Future<List<sdk.Event>> getEventList(int clientId, sdk.Room room) async {
final res = await dbGetEventList(clientId, room.id).get(); final res = await dbGetEventList(clientId, room.id).get();
final eventList = <sdk.Event>[]; final eventList = <sdk.Event>[];

View file

@ -6196,21 +6196,11 @@ abstract class _$Database extends GeneratedDatabase {
}).map(_rowToDbRoomState); }).map(_rowToDbRoomState);
} }
Selectable<DbRoomState> dbGetUsers( Selectable<DbRoomState> dbGetUsers(int client_id, String room_id) {
int client_id, List<String> mxids, String room_id) {
var $arrayStartIndex = 2;
final expandedmxids = $expandVar($arrayStartIndex, mxids.length);
$arrayStartIndex += mxids.length;
return customSelect( return customSelect(
'SELECT * FROM room_states WHERE client_id = :client_id AND type = \'m.room.member\' AND state_key IN ($expandedmxids) AND room_id = :room_id', 'SELECT * FROM room_states WHERE client_id = :client_id AND type = \'m.room.member\' AND room_id = :room_id',
variables: [ variables: [Variable.withInt(client_id), Variable.withString(room_id)],
Variable.withInt(client_id), readsFrom: {roomStates}).map(_rowToDbRoomState);
for (var $ in mxids) Variable.withString($),
Variable.withString(room_id)
],
readsFrom: {
roomStates
}).map(_rowToDbRoomState);
} }
DbEvent _rowToDbEvent(QueryRow row) { DbEvent _rowToDbEvent(QueryRow row) {

View file

@ -216,6 +216,7 @@ storeRoomState: INSERT OR REPLACE INTO room_states (client_id, event_id, room_id
getAllRoomAccountData: SELECT * FROM room_account_data WHERE client_id = :client_id; getAllRoomAccountData: SELECT * FROM room_account_data WHERE client_id = :client_id;
storeRoomAccountData: INSERT OR REPLACE INTO room_account_data (client_id, type, room_id, content) VALUES (:client_id, :type, :room_id, :content); storeRoomAccountData: INSERT OR REPLACE INTO room_account_data (client_id, type, room_id, content) VALUES (:client_id, :type, :room_id, :content);
dbGetUser: SELECT * FROM room_states WHERE client_id = :client_id AND type = 'm.room.member' AND state_key = :state_key AND room_id = :room_id; dbGetUser: SELECT * FROM room_states WHERE client_id = :client_id AND type = 'm.room.member' AND state_key = :state_key AND room_id = :room_id;
dbGetUsers: SELECT * FROM room_states WHERE client_id = :client_id AND type = 'm.room.member' AND room_id = :room_id;
dbGetEventList: SELECT * FROM events WHERE client_id = :client_id AND room_id = :room_id GROUP BY event_id ORDER BY sort_order DESC; dbGetEventList: SELECT * FROM events WHERE client_id = :client_id AND room_id = :room_id GROUP BY event_id ORDER BY sort_order DESC;
getStates: SELECT * FROM room_states WHERE client_id = :client_id AND room_id = :room_id; getStates: SELECT * FROM room_states WHERE client_id = :client_id AND room_id = :room_id;
resetNotificationCount: UPDATE rooms SET notification_count = 0, highlight_count = 0 WHERE client_id = :client_id AND room_id = :room_id; resetNotificationCount: UPDATE rooms SET notification_count = 0, highlight_count = 0 WHERE client_id = :client_id AND room_id = :room_id;

View file

@ -1004,10 +1004,20 @@ class Room {
/// Request the full list of participants from the server. The local list /// Request the full list of participants from the server. The local list
/// from the store is not complete if the client uses lazy loading. /// from the store is not complete if the client uses lazy loading.
Future<List<User>> requestParticipants() async { Future<List<User>> requestParticipants() async {
if (!participantListComplete && partial && client.database != null) {
// we aren't fully loaded, maybe the users are in the database
final users = await client.database.getUsers(client.id, this);
for (final user in users) {
setState(user);
}
}
if (participantListComplete) return getParticipants(); if (participantListComplete) return getParticipants();
final matrixEvents = await client.api.requestMembers(id); final matrixEvents = await client.api.requestMembers(id);
final users = final users =
matrixEvents.map((e) => Event.fromMatrixEvent(e, this).asUser).toList(); matrixEvents.map((e) => Event.fromMatrixEvent(e, this).asUser).toList();
for (final user in users) {
setState(user); // at *least* cache this in-memory
}
users.removeWhere( users.removeWhere(
(u) => [Membership.leave, Membership.ban].contains(u.membership)); (u) => [Membership.leave, Membership.ban].contains(u.membership));
return users; return users;