diff options
author | Sean Molenaar <sean@seanmolenaar.eu> | 2021-01-19 12:30:48 +0100 |
---|---|---|
committer | Sean Molenaar <SMillerDev@users.noreply.github.com> | 2021-01-30 18:27:06 +0100 |
commit | 023c61b88f3bfdc3829606a17fa3bf9deac600fc (patch) | |
tree | e17552831645e05366089ef1f3373a03415c8b6d /lib | |
parent | 191860fc7210b51032f3026491ed745508209936 (diff) |
Mappers: Implement item purging
Signed-off-by: Sean Molenaar <sean@seanmolenaar.eu>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Command/Updater/AfterUpdate.php | 19 | ||||
-rw-r--r-- | lib/Db/ItemMapperV2.php | 57 | ||||
-rw-r--r-- | lib/Service/ItemServiceV2.php | 21 |
3 files changed, 76 insertions, 21 deletions
diff --git a/lib/Command/Updater/AfterUpdate.php b/lib/Command/Updater/AfterUpdate.php index bedc8c9ff..f9e5671f0 100644 --- a/lib/Command/Updater/AfterUpdate.php +++ b/lib/Command/Updater/AfterUpdate.php @@ -15,6 +15,7 @@ use OCA\News\Service\ItemServiceV2; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class AfterUpdate extends Command @@ -42,14 +43,26 @@ class AfterUpdate extends Command { $this->setName('news:updater:after-update') ->setDescription('removes old read articles which are not starred') - ->addArgument('purge_count', InputArgument::OPTIONAL, 'The amount of items to purge'); + ->addArgument('purge-count', InputArgument::OPTIONAL, 'The amount of items to purge') + ->addOption('purge-unread', null, InputOption::VALUE_NONE, 'If unread items should be purged'); } protected function execute(InputInterface $input, OutputInterface $output): int { - $count = (int) $input->getArgument('purge_count'); + $count = $input->getArgument('purge-count'); + $removeUnread = $input->getOption('purge-unread'); - $output->writeln($this->itemService->purgeOverThreshold($count)); + if ($count !== null) { + $count = intval($count); + } + + $result = $this->itemService->purgeOverThreshold($count, $removeUnread); + if ($result === null) { + $output->writeln('No cleanup needed', $output::VERBOSITY_VERBOSE); + return 0; + } + + $output->writeln('Removed ' . $result . ' item(s)', $output::VERBOSITY_VERBOSE); return 0; } diff --git a/lib/Db/ItemMapperV2.php b/lib/Db/ItemMapperV2.php index 0c3191540..256621815 100644 --- a/lib/Db/ItemMapperV2.php +++ b/lib/Db/ItemMapperV2.php @@ -12,6 +12,7 @@ namespace OCA\News\Db; +use Doctrine\DBAL\FetchMode; use OCA\News\Utility\Time; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\Entity; @@ -138,20 +139,58 @@ class ItemMapperV2 extends NewsMapperV2 /** * Delete items from feed that are over the max item threshold * - * TODO: Implement + * @param int $threshold Deletion threshold + * @param bool $removeUnread If unread articles should be removed * - * @param int $threshold Deletion threshold + * @return int|null Removed items + * + * @throws \Doctrine\DBAL\Exception|\OCP\DB\Exception */ - public function deleteOverThreshold(int $threshold) + public function deleteOverThreshold(int $threshold, bool $removeUnread = false): ?int { - $builder = $this->db->getQueryBuilder(); + $feedQb = $this->db->getQueryBuilder(); + $feedQb->addSelect('feed_id', $feedQb->func()->count('*', 'itemCount'), 'feeds.articles_per_update') + ->from($this->tableName, 'items') + ->innerJoin('items', FeedMapperV2::TABLE_NAME, 'feeds', 'items.feed_id = feeds.id') + ->groupBy('feed_id'); + + $feeds = $this->db->executeQuery($feedQb->getSQL()) + ->fetchAll(FetchMode::ASSOCIATIVE); + + if ($feeds === []) { + return null; + } + + $rangeQuery = $this->db->getQueryBuilder(); + $rangeQuery->select('id') + ->from($this->tableName) + ->where('feed_id = :feedId') + ->andWhere('starred = 0') + ->orderBy('updated_date', 'DESC'); + + if ($removeUnread === false) { + $rangeQuery->andWhere('unread = 0'); + } + + $total_items = []; + foreach ($feeds as $feed) { + if ($feed['itemCount'] < $threshold) { + continue; + } + + $rangeQuery->setFirstResult(max($threshold, $feed['articles_per_update'])); + + $items = $this->db->executeQuery($rangeQuery->getSQL(), ['feedId' => $feed['feed_id']]) + ->fetchAll(FetchMode::COLUMN); + + $total_items = array_merge($total_items, $items); + } - $query = $builder->addSelect('COUNT(*)') - ->from($this->tableName) - ->groupBy('feed_id') - ->where(''); + $deleteQb = $this->db->getQueryBuilder(); + $deleteQb->delete($this->tableName) + ->where('id IN (?)'); - return $this->db->executeQuery($query->getSQL()); + return $this->db->executeUpdate($deleteQb->getSQL(), [$total_items], [IQueryBuilder::PARAM_INT_ARRAY]); } /** diff --git a/lib/Service/ItemServiceV2.php b/lib/Service/ItemServiceV2.php index 54cefa197..f13b249b8 100644 --- a/lib/Service/ItemServiceV2.php +++ b/lib/Service/ItemServiceV2.php @@ -113,22 +113,25 @@ class ItemServiceV2 extends Service return $this->mapper->findAllForFeed($feedId); } - - - public function purgeOverThreshold(int $threshold = null) + /** + * @param int|null $threshold + * @param bool $removeUnread + * + * @return int|null Amount of deleted items or null if not applicable + */ + public function purgeOverThreshold(int $threshold = null, bool $removeUnread = false): ?int { - - $threshold = (int) $threshold ?? $this->config->getAppValue( + $threshold = (int) ($threshold ?? $this->config->getAppValue( Application::NAME, 'autoPurgeCount', Application::DEFAULT_SETTINGS['autoPurgeCount'] - ); + )); - if ($threshold === 0) { - return ''; + if ($threshold <= 0) { + return null; } - return $this->mapper->deleteOverThreshold($threshold); + return $this->mapper->deleteOverThreshold($threshold, $removeUnread); } /** |