diff options
author | Julius Härtl <jus@bitgrid.net> | 2022-11-07 20:26:06 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-07 20:26:06 +0300 |
commit | 95837d0626cb7f610ee996a2b057acff9639e1e6 (patch) | |
tree | c717dbeff2593eeb9e7f208d67ca6a6baab6aacb | |
parent | 19f466fd4d9db0698494827fe90f3c6b854617e4 (diff) | |
parent | 8698e2ce3fdc1d4fbba06558ab8b2a89e54918b8 (diff) |
Merge pull request #4194 from nextcloud/3on108/master
Permanently delete deck cards marked as deleted after 5 min in a cron job
-rw-r--r-- | docs/API.md | 4 | ||||
-rw-r--r-- | lib/Cron/DeleteCron.php | 12 | ||||
-rw-r--r-- | lib/Db/CardMapper.php | 11 | ||||
-rw-r--r-- | tests/unit/Cron/DeleteCronTest.php | 27 |
4 files changed, 49 insertions, 5 deletions
diff --git a/docs/API.md b/docs/API.md index 9f96b516..654f78b8 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1,7 +1,7 @@ The REST API provides access for authenticated users to their data inside the Deck app. To get a better understanding of Decks data models and their relations, please have a look at the [data structure](structure.md) documentation. -# Prequisited +# Prerequisites - All requests require a `OCS-APIRequest` HTTP header to be set to `true` and a `Content-Type` of `application/json`. - The API is located at https://nextcloud.local/index.php/apps/deck/api/v1.0 @@ -9,7 +9,7 @@ The REST API provides access for authenticated users to their data inside the De ## Naming -- Board is the the project like grouping of tasks that can be shared to different users and groups +- Board is the project like grouping of tasks that can be shared to different users and groups - Stack is the grouping of cards which is rendered in vertical columns in the UI diff --git a/lib/Cron/DeleteCron.php b/lib/Cron/DeleteCron.php index 41d027b5..f766931d 100644 --- a/lib/Cron/DeleteCron.php +++ b/lib/Cron/DeleteCron.php @@ -28,6 +28,7 @@ use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\TimedJob; use OCA\Deck\Db\AttachmentMapper; use OCA\Deck\Db\BoardMapper; +use OCA\Deck\Db\CardMapper; use OCA\Deck\InvalidAttachmentType; use OCA\Deck\Service\AttachmentService; use OCP\BackgroundJob\IJob; @@ -36,14 +37,17 @@ class DeleteCron extends TimedJob { /** @var BoardMapper */ private $boardMapper; + /** @var CardMapper */ + private $cardMapper; /** @var AttachmentService */ private $attachmentService; /** @var AttachmentMapper */ private $attachmentMapper; - public function __construct(ITimeFactory $time, BoardMapper $boardMapper, AttachmentService $attachmentService, AttachmentMapper $attachmentMapper) { + public function __construct(ITimeFactory $time, BoardMapper $boardMapper, CardMapper $cardMapper, AttachmentService $attachmentService, AttachmentMapper $attachmentMapper) { parent::__construct($time); $this->boardMapper = $boardMapper; + $this->cardMapper = $cardMapper; $this->attachmentService = $attachmentService; $this->attachmentMapper = $attachmentMapper; @@ -61,6 +65,12 @@ class DeleteCron extends TimedJob { $this->boardMapper->delete($board); } + $timeLimit = time() - (60 * 5); // 5 min buffer + $cards = $this->cardMapper->findToDelete($timeLimit, 500); + foreach ($cards as $card) { + $this->cardMapper->delete($card); + } + $attachments = $this->attachmentMapper->findToDelete(); foreach ($attachments as $attachment) { try { diff --git a/lib/Db/CardMapper.php b/lib/Db/CardMapper.php index e23f8046..e245c032 100644 --- a/lib/Db/CardMapper.php +++ b/lib/Db/CardMapper.php @@ -177,6 +177,17 @@ class CardMapper extends QBMapper implements IPermissionMapper { return $qb; } + public function findToDelete($timeLimit, $limit = null) { + $qb = $this->db->getQueryBuilder(); + $qb->select('id', 'title', 'owner', 'archived', 'deleted_at', 'last_modified') + ->from('deck_cards') + ->where($qb->expr()->gt('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT))) + ->andWhere($qb->expr()->lt('deleted_at', $qb->createNamedParameter($timeLimit, IQueryBuilder::PARAM_INT))) + ->orderBy('deleted_at') + ->setMaxResults($limit); + return $this->findEntities($qb); + } + public function findDeleted($boardId, $limit = null, $offset = null) { $qb = $this->queryCardsByBoard($boardId); $qb->andWhere($qb->expr()->neq('c.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT))) diff --git a/tests/unit/Cron/DeleteCronTest.php b/tests/unit/Cron/DeleteCronTest.php index 94e390e5..88d73b8a 100644 --- a/tests/unit/Cron/DeleteCronTest.php +++ b/tests/unit/Cron/DeleteCronTest.php @@ -27,6 +27,8 @@ use OCA\Deck\Db\Attachment; use OCA\Deck\Db\AttachmentMapper; use OCA\Deck\Db\Board; use OCA\Deck\Db\BoardMapper; +use OCA\Deck\Db\Card; +use OCA\Deck\Db\CardMapper; use OCA\Deck\InvalidAttachmentType; use OCA\Deck\Service\AttachmentService; use OCA\Deck\Service\IAttachmentService; @@ -40,7 +42,9 @@ class DeleteCronTest extends TestCase { private $timeFactory; /** @var BoardMapper|MockObject */ protected $boardMapper; - /** @var AttachmentService|MockObject */ + /** @var CardMapper|\PHPUnit\Framework\MockObject\MockObject */ + protected $cardMapper; + /** @var AttachmentService|\PHPUnit\Framework\MockObject\MockObject */ private $attachmentService; /** @var AttachmentMapper|MockObject */ private $attachmentMapper; @@ -51,9 +55,10 @@ class DeleteCronTest extends TestCase { parent::setUp(); $this->timeFactory = $this->createMock(ITimeFactory::class); $this->boardMapper = $this->createMock(BoardMapper::class); + $this->cardMapper = $this->createMock(CardMapper::class); $this->attachmentService = $this->createMock(AttachmentService::class); $this->attachmentMapper = $this->createMock(AttachmentMapper::class); - $this->deleteCron = new DeleteCron($this->timeFactory, $this->boardMapper, $this->attachmentService, $this->attachmentMapper); + $this->deleteCron = new DeleteCron($this->timeFactory, $this->boardMapper, $this->cardMapper, $this->attachmentService, $this->attachmentMapper); } protected function getBoard($id) { @@ -62,6 +67,12 @@ class DeleteCronTest extends TestCase { return $board; } + protected function getCard($id) { + $card = new Card(); + $card->setId($id); + return $card; + } + public function testDeleteCron() { $boards = [ $this->getBoard(1), @@ -81,6 +92,14 @@ class DeleteCronTest extends TestCase { [$boards[3]] ); + $cards = [ $this->getCard(10) ]; + $this->cardMapper->expects($this->once()) + ->method('findToDelete') + ->willReturn($cards); + $this->cardMapper->expects($this->once()) + ->method('delete') + ->with($cards[0]); + $attachment = new Attachment(); $attachment->setType('deck_file'); $this->attachmentMapper->expects($this->once()) @@ -107,6 +126,10 @@ class DeleteCronTest extends TestCase { ->method('findToDelete') ->willReturn($boards); + $this->cardMapper->expects($this->once()) + ->method('findToDelete') + ->willReturn([]); + $attachment = new Attachment(); $attachment->setType('deck_file_invalid'); $this->attachmentMapper->expects($this->once()) |