зеркало из https://github.com/nextcloud/text.git
fix: Delete inactive sessions in one query
Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Родитель
6f12481acc
Коммит
85ef18d3fa
|
@ -99,30 +99,29 @@ class SessionMapper extends QBMapper {
|
|||
return $this->findEntities($qb);
|
||||
}
|
||||
|
||||
public function deleteInactiveWithoutSteps(?int $documentId = null) {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('session_id')
|
||||
->from('text_steps');
|
||||
public function deleteInactiveWithoutSteps(?int $documentId = null): int {
|
||||
$selectSubQuery = $this->db->getQueryBuilder();
|
||||
$selectSubQuery->select('s.id')
|
||||
->from('text_sessions', 's')
|
||||
->leftJoin('s', 'text_steps', 'st', $selectSubQuery->expr()->eq('st.session_id', 's.id'))
|
||||
->where($selectSubQuery->expr()->lt('last_contact', $selectSubQuery->createParameter('lastContact')))
|
||||
->andWhere($selectSubQuery->expr()->isNull('st.id'));
|
||||
if ($documentId !== null) {
|
||||
$qb->where($qb->expr()->eq('document_id', $qb->createNamedParameter($documentId)));
|
||||
$selectSubQuery->andWhere($selectSubQuery->expr()->eq('s.document_id', $selectSubQuery->createParameter('documentId')));
|
||||
}
|
||||
$result = $qb
|
||||
->groupBy('session_id')
|
||||
->executeQuery();
|
||||
$activeSessions = $result->fetchAll(\PDO::FETCH_COLUMN);
|
||||
$result->closeCursor();
|
||||
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->delete($this->getTableName());
|
||||
$qb->where($qb->expr()->lt('last_contact', $qb->createNamedParameter(time() - SessionService::SESSION_VALID_TIME)));
|
||||
if ($documentId !== null) {
|
||||
$qb->andWhere($qb->expr()->eq('document_id', $qb->createNamedParameter($documentId)));
|
||||
}
|
||||
$qb->andWhere($qb->expr()->notIn('id', $qb->createNamedParameter($activeSessions, IQueryBuilder::PARAM_INT_ARRAY)));
|
||||
$qb->delete($this->getTableName())
|
||||
->where($qb->expr()->in('id', $qb->createFunction($selectSubQuery->getSQL())));
|
||||
$qb->setParameters([
|
||||
'lastContact' => time() - SessionService::SESSION_VALID_TIME,
|
||||
'documentId' => $documentId,
|
||||
]);
|
||||
|
||||
return $qb->executeStatement();
|
||||
}
|
||||
|
||||
public function deleteByDocumentId($documentId) {
|
||||
public function deleteByDocumentId($documentId): int {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->delete($this->getTableName())
|
||||
->where($qb->expr()->eq('document_id', $qb->createNamedParameter($documentId)));
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\Text\Db;
|
||||
|
||||
/**
|
||||
* @group DB
|
||||
*/
|
||||
class SessionMapperTest extends \Test\TestCase {
|
||||
|
||||
private SessionMapper $sessionMapper;
|
||||
private StepMapper $stepMapper;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->sessionMapper = \OCP\Server::get(SessionMapper::class);
|
||||
$this->stepMapper = \OCP\Server::get(StepMapper::class);
|
||||
|
||||
}
|
||||
|
||||
public function testDeleteInactiveWithoutSteps() {
|
||||
$this->sessionMapper->deleteByDocumentId(1);
|
||||
$this->sessionMapper->deleteByDocumentId(2);
|
||||
$this->sessionMapper->insert(Session::fromParams([
|
||||
'userId' => 'admin',
|
||||
'documentId' => 1,
|
||||
'lastContact' => 1337,
|
||||
'token' => uniqid(),
|
||||
'color' => '00ff00',
|
||||
]));
|
||||
$this->sessionMapper->insert(Session::fromParams([
|
||||
'userId' => 'admin',
|
||||
'documentId' => 2,
|
||||
'lastContact' => 1337,
|
||||
'token' => uniqid(),
|
||||
'color' => '00ff00',
|
||||
]));
|
||||
$this->sessionMapper->deleteInactiveWithoutSteps(1);
|
||||
self::assertCount(0, $this->sessionMapper->findAll(1));
|
||||
self::assertCount(1, $this->sessionMapper->findAll(2));
|
||||
$this->sessionMapper->deleteInactiveWithoutSteps();
|
||||
self::assertCount(0, $this->sessionMapper->findAll(2));
|
||||
}
|
||||
|
||||
public function testDeleteInactiveWithoutStepsKeep() {
|
||||
$this->stepMapper->deleteAll(1);
|
||||
$this->sessionMapper->deleteByDocumentId(1);
|
||||
$this->sessionMapper->deleteByDocumentId(2);
|
||||
|
||||
$s1 = $this->sessionMapper->insert(Session::fromParams([
|
||||
'userId' => 'admin',
|
||||
'documentId' => 1,
|
||||
'lastContact' => 1337,
|
||||
'token' => uniqid(),
|
||||
'color' => '00ff00',
|
||||
]));
|
||||
$s2 = $this->sessionMapper->insert(Session::fromParams([
|
||||
'userId' => 'admin',
|
||||
'documentId' => 2,
|
||||
'lastContact' => 1337,
|
||||
'token' => uniqid(),
|
||||
'color' => '00ff00',
|
||||
]));
|
||||
$this->stepMapper->insert(Step::fromParams([
|
||||
'sessionId' => $s1->getId(),
|
||||
'documentId' => 1,
|
||||
'data' => 'YJSDATA',
|
||||
'version' => 1,
|
||||
]));
|
||||
self::assertCount(1, $this->sessionMapper->findAll(1));
|
||||
|
||||
$this->sessionMapper->deleteInactiveWithoutSteps(1);
|
||||
self::assertCount(1, $this->sessionMapper->findAll(1));
|
||||
self::assertCount(1, $this->sessionMapper->findAll(2));
|
||||
|
||||
$this->sessionMapper->deleteInactiveWithoutSteps();
|
||||
self::assertCount(1, $this->sessionMapper->findAll(1));
|
||||
self::assertCount(0, $this->sessionMapper->findAll(2));
|
||||
}
|
||||
|
||||
public function testDeleteInactiveWithoutStepsMultiple() {
|
||||
$this->sessionMapper->deleteByDocumentId(1);
|
||||
|
||||
$count = 1010;
|
||||
for ($i = 0;$i < $count;$i++) {
|
||||
$this->sessionMapper->insert(Session::fromParams([
|
||||
'userId' => 'admin',
|
||||
'documentId' => 1,
|
||||
'lastContact' => 1337,
|
||||
'token' => uniqid(),
|
||||
'color' => '00ff00',
|
||||
]));
|
||||
}
|
||||
|
||||
self::assertCount($count, $this->sessionMapper->findAll(1));
|
||||
|
||||
$deleted = $this->sessionMapper->deleteInactiveWithoutSteps();
|
||||
self::assertEquals($count, $deleted);
|
||||
|
||||
self::assertCount(0, $this->sessionMapper->findAll(1));
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче