Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[draft] Introduce 'purgeUnread' config parameter #970

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class Application extends App implements IBootstrap
'useCronUpdates' => true,
'exploreUrl' => '',
'updateInterval' => 3600,
'purgeUnread' => false,
];

public function __construct(array $urlParams = [])
Expand Down
77 changes: 56 additions & 21 deletions lib/Db/ItemMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -346,48 +346,48 @@ public function findByGuidHash($guidHash, $feedId, $userId)

/**
* Delete all items for feeds that have over $threshold unread and not
* starred items
* starred items.
*
* This method uses 'purgeUnread' configuration parameter to decide
* whether unread items should be purged as well.
*
* @param int $threshold the number of items that should be deleted
*/
public function deleteReadOlderThanThreshold($threshold)
public function deleteReadOlderThanThreshold($threshold, $purgeUnread = false)
{
$params = [false, false, $threshold];

$sql = 'SELECT (COUNT(*) - `feeds`.`articles_per_update`) AS `size`, ' .
'`feeds`.`id` AS `feed_id`, `feeds`.`articles_per_update` ' .
'FROM `*PREFIX*news_items` `items` ' .
'JOIN `*PREFIX*news_feeds` `feeds` ' .
'ON `feeds`.`id` = `items`.`feed_id` ' .
'AND `items`.`unread` = ? ' .
'AND `items`.`starred` = ? ' .
'GROUP BY `feeds`.`id`, `feeds`.`articles_per_update` ' .
'HAVING COUNT(*) > ?';

$result = $this->execute($sql, $params);
// Count excessive items, i.e. those above the threshold, taking
// purging strategy into account.
$result = $purgeUnread
? $this->countAllItemsToPurge($threshold)
: $this->countUnreadItemsToPurge($threshold);

while ($row = $result->fetch()) {
$size = (int)$row['size'];
$limit = $size - $threshold;
$feed_id = $row['feed_id'];

if ($limit > 0) {
$params = [false, false, $feed_id, $limit];
$params = $purgeUnread
? [false, false, $feed_id, $limit]
: [false, $feed_id, $limit];
$sql = 'SELECT `id` FROM `*PREFIX*news_items` ' .
'WHERE `unread` = ? ' .
'AND `starred` = ? ' .
'WHERE `starred` = ? ' .
($purgeUnread ? '' : 'AND `unread` = ? ') .
'AND `feed_id` = ? ' .
'ORDER BY `id` ASC ' .
'LIMIT 1 ' .
'OFFSET ? ';
}
$limit_result = $this->execute($sql, $params);

if ($limit_row = $limit_result->fetch()) {
$limit_id = (int)$limit_row['id'];
$params = [false, false, $feed_id, $limit_id];
$params = $purgeUnread
? [false, false, $feed_id, $limit_id]
: [false, $feed_id, $limit_id];
$sql = 'DELETE FROM `*PREFIX*news_items` ' .
'WHERE `unread` = ? ' .
'AND `starred` = ? ' .
'WHERE `starred` = ? ' .
($purgeUnread ? '' : 'AND `unread` = ? ') .
'AND `feed_id` = ? ' .
'AND `id` < ? ';
$this->execute($sql, $params);
Expand All @@ -396,6 +396,41 @@ public function deleteReadOlderThanThreshold($threshold)
}


private function countAllItemsToPurge($threshold)
{
$params = [false, $threshold];

$sql = 'SELECT (COUNT(*) - `feeds`.`articles_per_update`) AS `size`, ' .
'`feeds`.`id` AS `feed_id`, `feeds`.`articles_per_update` ' .
'FROM `*PREFIX*news_items` `items` ' .
'JOIN `*PREFIX*news_feeds` `feeds` ' .
'ON `feeds`.`id` = `items`.`feed_id` ' .
'AND `items`.`starred` = ? ' .
'GROUP BY `feeds`.`id`, `feeds`.`articles_per_update` ' .
'HAVING COUNT(*) > ?';

return $this->execute($sql, $params);
}


private function countUnreadItemsToPurge($threshold)
{
$params = [false, false, $threshold];

$sql = 'SELECT (COUNT(*) - `feeds`.`articles_per_update`) AS `size`, ' .
'`feeds`.`id` AS `feed_id`, `feeds`.`articles_per_update` ' .
'FROM `*PREFIX*news_items` `items` ' .
'JOIN `*PREFIX*news_feeds` `feeds` ' .
'ON `feeds`.`id` = `items`.`feed_id` ' .
'AND `items`.`unread` = ? ' .
'AND `items`.`starred` = ? ' .
'GROUP BY `feeds`.`id`, `feeds`.`articles_per_update` ' .
'HAVING COUNT(*) > ?';

return $this->execute($sql, $params);
}


public function getNewestItemId($userId)
{
$sql = 'SELECT MAX(`items`.`id`) AS `max_id` ' .
Expand Down
19 changes: 18 additions & 1 deletion lib/Service/ItemService.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,10 @@ public function autoPurgeOld()
'autoPurgeCount',
Application::DEFAULT_SETTINGS['autoPurgeCount']
);
$purgeUnread = $this->readConfigParam('purgeUnread');

if ($count >= 0) {
$this->itemMapper->deleteReadOlderThanThreshold($count);
$this->itemMapper->deleteReadOlderThanThreshold($count, $purgeUnread);
}
}

Expand Down Expand Up @@ -342,4 +344,19 @@ public function findAll(): array
{
return $this->mapper->findAll();
}


/**
* Read configuration parameter from DB or take its default value from
* application.
*
* @param string $name Name of the configuration parameter.
*/
private function readConfigParam($name) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you think it's necessary to have an extra function please also replace the config value for autoPurgeCount.

return $this->config->getAppValue(
Application::NAME,
$name,
Application::DEFAULT_SETTINGS[$name]
);
}
}