Skip to content

Commit

Permalink
Fix selecting the session when there could be multiple
Browse files Browse the repository at this point in the history
Signed-off-by: Joas Schilling <coding@schilljs.com>
  • Loading branch information
nickvergessen committed Feb 24, 2021
1 parent 60f51cd commit 3d730f5
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 19 deletions.
4 changes: 2 additions & 2 deletions lib/Controller/RoomController.php
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ protected function formatRoomV1(Room $room, ?Participant $currentParticipant): a
$numActiveGuests = 0;
$cleanGuests = false;
$participantList = [];
$participants = $this->participantService->getParticipantsForRoom($room, true); // FIXME NEEDS the session but can potentially kill APIv1?
$participants = $this->participantService->getSessionsAndParticipantsForRoom($room); // FIXME NEEDS the session but can potentially kill APIv1?
uasort($participants, function (Participant $participant1, Participant $participant2) {
$s1 = $participant1->getSession() ? $participant1->getSession()->getLastPing() : 0;
$s2 = $participant2->getSession() ? $participant2->getSession()->getLastPing() : 0;
Expand Down Expand Up @@ -1110,7 +1110,7 @@ public function getParticipants(bool $includeStatus = false): DataResponse {
}

$maxPingAge = $this->timeFactory->getTime() - 100;
$participants = $this->participantService->getParticipantsForRoom($this->room, true);
$participants = $this->participantService->getSessionsAndParticipantsForRoom($this->room);
$results = $headers = $statuses = [];

if ($this->userId !== null
Expand Down
2 changes: 1 addition & 1 deletion lib/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ public function getRoomsForUser(string $userId, bool $loadSession = false, bool
->where($query->expr()->isNotNull('a.id'));

if ($loadSession) {
$helper->selectSessionsTable($query);
$helper->selectSessionsTable($query); // FIXME ?
$query->leftJoin('a', 'talk_sessions', 's', $query->expr()->andX(
$query->expr()->eq('a.id', 's.attendee_id')
));
Expand Down
13 changes: 13 additions & 0 deletions lib/Model/SelectHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,17 @@ public function selectSessionsTable(IQueryBuilder $query, string $alias = 's'):
->addSelect($alias . 'last_ping')
->selectAlias($alias . 'id', 's_id');
}

public function selectSessionsTableMax(IQueryBuilder $query, string $alias = 's'): void {
if ($alias !== '') {
$alias .= '.';
}

$query->selectAlias($query->func()->max($alias . 'attendee_id'), 'attendee_id')
->selectAlias($query->func()->max($alias . 'session_id'), 'session_id')
// BIT_OR would be better, but SQLite does not support something like it.
->selectAlias($query->func()->max($alias . 'in_call'), 'in_call')
->selectAlias($query->func()->max($alias . 'last_ping'), 'last_ping')
->selectAlias($query->func()->max($alias . 'id'), 's_id');
}
}
17 changes: 11 additions & 6 deletions lib/Room.php
Original file line number Diff line number Diff line change
Expand Up @@ -427,13 +427,14 @@ public function getParticipant(?string $userId, $sessionId = null): Participant
->setMaxResults(1);

if ($sessionId !== false) {
$helper->selectSessionsTable($query);
if ($sessionId !== null) {
$helper->selectSessionsTable($query);
$query->leftJoin('a', 'talk_sessions', 's', $query->expr()->andX(
$query->expr()->eq('s.session_id', $query->createNamedParameter($sessionId)),
$query->expr()->eq('a.id', 's.attendee_id')
));
} else {
$helper->selectSessionsTable($query); // FIXME PROBLEM
$query->leftJoin('a', 'talk_sessions', 's', $query->expr()->eq('a.id', 's.attendee_id'));
}
}
Expand Down Expand Up @@ -494,7 +495,7 @@ public function getParticipantByPin(string $pin): Participant {
$helper = new SelectHelper();
$helper->selectAttendeesTable($query);
$query->from('talk_attendees', 'a')
->andWhere($query->expr()->eq('a.pin', $query->createNamedParameter($pin)))
->where($query->expr()->eq('a.pin', $query->createNamedParameter($pin)))
->andWhere($query->expr()->eq('a.room_id', $query->createNamedParameter($this->getId())))
->setMaxResults(1);
$result = $query->execute();
Expand All @@ -521,18 +522,20 @@ public function getParticipantByAttendeeId(int $attendeeId, $sessionId = null):
$helper = new SelectHelper();
$helper->selectAttendeesTable($query);
$query->from('talk_attendees', 'a')
->andWhere($query->expr()->eq('a.id', $query->createNamedParameter($attendeeId, IQueryBuilder::PARAM_INT)))
->where($query->expr()->eq('a.id', $query->createNamedParameter($attendeeId, IQueryBuilder::PARAM_INT)))
->andWhere($query->expr()->eq('a.room_id', $query->createNamedParameter($this->getId())))
->setMaxResults(1);

if ($sessionId !== false) {
$helper->selectSessionsTable($query);
if ($sessionId !== null) {
$helper->selectSessionsTable($query);
$query->leftJoin('a', 'talk_sessions', 's', $query->expr()->andX(
$query->expr()->eq('s.session_id', $query->createNamedParameter($sessionId)),
$query->expr()->eq('a.id', 's.attendee_id')
));
} else {
$helper->selectSessionsTableMax($query);
$query->groupBy('a.id');
$query->leftJoin('a', 'talk_sessions', 's', $query->expr()->eq('a.id', 's.attendee_id'));
}
}
Expand Down Expand Up @@ -564,21 +567,23 @@ public function getParticipantByActor(string $actorType, string $actorId, $sessi

$query = $this->db->getQueryBuilder();
$helper = new SelectHelper();
$helper->selectSessionsTable($query);
$helper->selectAttendeesTable($query);
$query->from('talk_attendees', 'a')
->andWhere($query->expr()->eq('a.actor_type', $query->createNamedParameter($actorType)))
->andWhere($query->expr()->eq('a.actor_id', $query->createNamedParameter($actorId)))
->andWhere($query->expr()->eq('a.room_id', $query->createNamedParameter($this->getId())))
->setMaxResults(1);

if ($sessionId !== false) {
$helper->selectSessionsTable($query);
if ($sessionId !== null) {
$helper->selectSessionsTable($query);
$query->leftJoin('a', 'talk_sessions', 's', $query->expr()->andX(
$query->expr()->eq('s.session_id', $query->createNamedParameter($sessionId)),
$query->expr()->eq('a.id', 's.attendee_id')
));
} else {
$helper->selectSessionsTableMax($query);
$query->groupBy('a.id');
$query->leftJoin('a', 'talk_sessions', 's', $query->expr()->eq('a.id', 's.attendee_id'));
}
}
Expand Down
37 changes: 27 additions & 10 deletions lib/Service/ParticipantService.php
Original file line number Diff line number Diff line change
Expand Up @@ -583,24 +583,40 @@ public function getLastCommonReadChatMessageForMultipleRooms(array $roomIds): ar

/**
* @param Room $room
* @param bool $loadSession Loads a random session if possible for the users
* @return Participant[]
*/
public function getParticipantsForRoom(Room $room, bool $loadSession = false): array {
public function getParticipantsForRoom(Room $room): array {
$query = $this->connection->getQueryBuilder();

$helper = new SelectHelper();
$helper->selectAttendeesTable($query);
$query->from('talk_attendees', 'a')
->where($query->expr()->eq('a.room_id', $query->createNamedParameter($room->getId(), IQueryBuilder::PARAM_INT)));

if ($loadSession) {
$helper->selectSessionsTable($query);
$query->leftJoin(
return $this->getParticipantsFromQuery($query, $room);
}

/**
* Get all sessions and attendees without a session for the room
*
* This will return multiple items for the same attendee if the attendee
* has multiple sessions in the room.
*
* @param Room $room
* @return Participant[]
*/
public function getSessionsAndParticipantsForRoom(Room $room): array {
$query = $this->connection->getQueryBuilder();

$helper = new SelectHelper();
$helper->selectAttendeesTable($query);
$helper->selectSessionsTable($query);
$query->from('talk_attendees', 'a')
->leftJoin(
'a', 'talk_sessions', 's',
$query->expr()->eq('s.attendee_id', 'a.id')
);
}
)
->where($query->expr()->eq('a.room_id', $query->createNamedParameter($room->getId(), IQueryBuilder::PARAM_INT)));

return $this->getParticipantsFromQuery($query, $room);
}
Expand All @@ -622,7 +638,7 @@ public function getParticipantsForAllSessions(Room $room, int $maxAge = 0): arra
$query->expr()->eq('s.attendee_id', 'a.id')
)
->where($query->expr()->eq('a.room_id', $query->createNamedParameter($room->getId(), IQueryBuilder::PARAM_INT)))
->andWhere($query->expr()->isNotNull('s.id'));
->andWhere($query->expr()->isNotNull('a.id'));

if ($maxAge > 0) {
$query->andWhere($query->expr()->gt('s.last_ping', $query->createNamedParameter($maxAge, IQueryBuilder::PARAM_INT)));
Expand Down Expand Up @@ -667,15 +683,16 @@ public function getParticipantsByNotificationLevel(Room $room, int $notification

$helper = new SelectHelper();
$helper->selectAttendeesTable($query);
$helper->selectSessionsTable($query);
$helper->selectSessionsTableMax($query);
$query->from('talk_attendees', 'a')
// Currently we only care if the user has a session at all, so we can select any: #ThisIsFine
->leftJoin(
'a', 'talk_sessions', 's',
$query->expr()->eq('s.attendee_id', 'a.id')
)
->where($query->expr()->eq('a.room_id', $query->createNamedParameter($room->getId(), IQueryBuilder::PARAM_INT)))
->andWhere($query->expr()->eq('a.notification_level', $query->createNamedParameter($notificationLevel, IQueryBuilder::PARAM_INT)));
->andWhere($query->expr()->eq('a.notification_level', $query->createNamedParameter($notificationLevel, IQueryBuilder::PARAM_INT)))
->groupBy('a.id');

return $this->getParticipantsFromQuery($query, $room);
}
Expand Down

0 comments on commit 3d730f5

Please sign in to comment.