mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 13:12:41 +00:00
More sub soft-delete fixes
This commit is contained in:
parent
d1876773e8
commit
de6760d5d7
5 changed files with 84 additions and 66 deletions
|
@ -566,7 +566,7 @@ class Database {
|
|||
coalesce(feeds,0) as feeds
|
||||
from arsse_folders
|
||||
left join (select parent,count(id) as children from arsse_folders group by parent) as child_stats on child_stats.parent = arsse_folders.id
|
||||
left join (select folder,count(id) as feeds from arsse_subscriptions group by folder) as sub_stats on sub_stats.folder = arsse_folders.id",
|
||||
left join (select folder,count(id) as feeds from arsse_subscriptions where deleted = 0 group by folder) as sub_stats on sub_stats.folder = arsse_folders.id",
|
||||
["str", "strict int"],
|
||||
[$user, $parent]
|
||||
);
|
||||
|
@ -1139,7 +1139,7 @@ class Database {
|
|||
return V::normalize($out, V::T_DATE | V::M_NULL, "sql");
|
||||
}
|
||||
|
||||
/** Evalutes the filter rules specified for a subscription against every article associated with the subscription's feed
|
||||
/** Evalutes the filter rules specified for a subscription against every article associated with the subscription
|
||||
*
|
||||
* @param string $user The user who owns the subscription
|
||||
* @param integer $id The identifier of the subscription whose rules are to be evaluated
|
||||
|
@ -1458,7 +1458,7 @@ class Database {
|
|||
* @param string $user The user whose subscription icons are to be retrieved
|
||||
*/
|
||||
public function iconList(string $user): Db\Result {
|
||||
return $this->db->prepare("SELECT distinct i.id, i.url, i.type, i.data from arsse_icons as i join arsse_subscriptions as s on s.icon = i.id where s.owner = ?", "str")->run($user);
|
||||
return $this->db->prepare("SELECT distinct i.id, i.url, i.type, i.data from arsse_icons as i join arsse_subscriptions as s on s.icon = i.id where s.owner = ? and s.deleted = 0", "str")->run($user);
|
||||
}
|
||||
|
||||
/** Deletes orphaned icons from the database
|
||||
|
@ -1571,7 +1571,7 @@ class Database {
|
|||
select
|
||||
$outColumns
|
||||
from arsse_articles
|
||||
join arsse_subscriptions on arsse_subscriptions.id = arsse_articles.subscription and arsse_subscriptions.owner = ? and deleted = 0
|
||||
join arsse_subscriptions on arsse_subscriptions.id = arsse_articles.subscription and arsse_subscriptions.owner = ? and arsse_subscriptions.deleted = 0
|
||||
left join arsse_article_contents on arsse_article_contents.id = arsse_articles.id
|
||||
left join folder_data on arsse_subscriptions.folder = folder_data.id
|
||||
left join arsse_enclosures on arsse_enclosures.article = arsse_articles.id
|
||||
|
@ -1884,10 +1884,10 @@ class Database {
|
|||
*
|
||||
* @param string $user The user who owns the articles to be modified
|
||||
* @param array $data An associative array of properties to modify. Anything not specified will remain unchanged
|
||||
* @param Context|UnionContext $context The query context to match articles against
|
||||
* @param Context $context The query context to match articles against
|
||||
* @param bool $updateTimestamp Whether to also update the timestamp. This should only be false if a mark is changed as a result of an automated action not taken by the user
|
||||
*/
|
||||
public function articleMark(string $user, array $data, RootContext $context = null, bool $updateTimestamp = true): int {
|
||||
public function articleMark(string $user, array $data, Context $context = null, bool $updateTimestamp = true): int {
|
||||
$data = [
|
||||
'read' => $data['read'] ?? null,
|
||||
'starred' => $data['starred'] ?? null,
|
||||
|
@ -2011,7 +2011,7 @@ class Database {
|
|||
coalesce(sum(abs(\"read\" - 1)),0) as unread,
|
||||
coalesce(sum(\"read\"),0) as \"read\"
|
||||
FROM (
|
||||
select \"read\" from arsse_articles where starred = 1 and hidden <> 1 and subscription in (select id from arsse_subscriptions where owner = ?)
|
||||
select \"read\" from arsse_articles where starred = 1 and hidden <> 1 and subscription in (select id from arsse_subscriptions where owner = ? and deleted = 0)
|
||||
) as starred_data",
|
||||
"str"
|
||||
)->run($user)->getRow();
|
||||
|
@ -2148,7 +2148,7 @@ class Database {
|
|||
join arsse_articles on arsse_articles.id = arsse_editions.article
|
||||
join arsse_subscriptions on arsse_subscriptions.id = arsse_articles.subscription
|
||||
join (select article, max(id) as edition from arsse_editions group by article) as edition_stats on edition_stats.article = arsse_editions.article
|
||||
where arsse_editions.id = ? and arsse_subscriptions.owner = ?",
|
||||
where arsse_editions.id = ? and arsse_subscriptions.owner = ? and arsse_subscriptions.deleted = 0",
|
||||
["int", "str"]
|
||||
)->run($id, $user)->getRow();
|
||||
if (!$out) {
|
||||
|
@ -2211,7 +2211,13 @@ class Database {
|
|||
cast(coalesce(marked, 0) as $integerType) as \"read\" -- this cast is required for MySQL for unclear reasons
|
||||
from arsse_labels
|
||||
left join (
|
||||
SELECT label, sum(assigned) as articles from arsse_label_members group by label
|
||||
SELECT
|
||||
label,
|
||||
sum(assigned) as articles
|
||||
from arsse_label_members
|
||||
join arsse_articles on arsse_articles.id = arsse_label_members.article
|
||||
join arsse_subscriptions on arsse_articles.subscription = arsse_subscriptions.id and arsse_subscriptions.deleted = 0
|
||||
group by label
|
||||
) as label_stats on label_stats.label = arsse_labels.id
|
||||
left join (
|
||||
SELECT
|
||||
|
@ -2221,7 +2227,7 @@ class Database {
|
|||
from arsse_articles
|
||||
join arsse_subscriptions on arsse_subscriptions.id = arsse_articles.subscription
|
||||
join arsse_label_members on arsse_label_members.article = arsse_articles.id
|
||||
where arsse_subscriptions.owner = ?
|
||||
where arsse_subscriptions.owner = ? and arsse_subscriptions.deleted = 0
|
||||
group by label
|
||||
) as mark_stats on mark_stats.label = arsse_labels.id
|
||||
WHERE owner = ?
|
||||
|
@ -2275,7 +2281,13 @@ class Database {
|
|||
coalesce(marked, 0) as \"read\"
|
||||
FROM arsse_labels
|
||||
left join (
|
||||
SELECT label, sum(assigned) as articles from arsse_label_members group by label
|
||||
SELECT
|
||||
label,
|
||||
sum(assigned) as articles
|
||||
from arsse_label_members
|
||||
join arsse_articles on arsse_articles.id = arsse_label_members.article
|
||||
join arsse_subscriptions on arsse_articles.subscription = arsse_subscriptions.id and arsse_subscriptions.deleted = 0
|
||||
group by label
|
||||
) as label_stats on label_stats.label = arsse_labels.id
|
||||
left join (
|
||||
SELECT
|
||||
|
@ -2285,7 +2297,7 @@ class Database {
|
|||
from arsse_articles
|
||||
join arsse_subscriptions on arsse_subscriptions.id = arsse_articles.subscription
|
||||
join arsse_label_members on arsse_label_members.article = arsse_articles.id
|
||||
where arsse_subscriptions.owner = ?
|
||||
where arsse_subscriptions.owner = ? and arsse_subscriptions.deleted = 0
|
||||
group by label
|
||||
) as mark_stats on mark_stats.label = arsse_labels.id
|
||||
WHERE $field = ? and owner = ?",
|
||||
|
@ -2374,7 +2386,7 @@ class Database {
|
|||
if (!sizeof($articles)) {
|
||||
if ($mode == self::ASSOC_REPLACE) {
|
||||
// replacing with an empty set means setting everything to zero
|
||||
return $this->db->prepare("UPDATE arsse_label_members set assigned = 0, modified = CURRENT_TIMESTAMP where label = ? and assigned = 1", "int")->run($id)->changes();
|
||||
return $this->db->prepare("UPDATE arsse_label_members set assigned = 0, modified = CURRENT_TIMESTAMP where label = ? and assigned = 1 and article not in (select id from arsse_articles where subscription in (select id from arsse_subscriptions where deleted = 1))", "int")->run($id)->changes();
|
||||
} else {
|
||||
// adding or removing is a no-op
|
||||
return 0;
|
||||
|
@ -2384,7 +2396,7 @@ class Database {
|
|||
}
|
||||
// prepare up to three queries: removing requires one, adding two, and replacing three
|
||||
[$inClause, $inTypes, $inValues] = $this->generateIn($articles, "int");
|
||||
$updateQ = "UPDATE arsse_label_members set assigned = ?, modified = CURRENT_TIMESTAMP where label = ? and assigned <> ? and article %in% ($inClause)";
|
||||
$updateQ = "UPDATE arsse_label_members set assigned = ?, modified = CURRENT_TIMESTAMP where label = ? and assigned <> ? and article %in% ($inClause) and article not in (select id from arsse_articles where subscription in (select id from arsse_subscriptions where deleted = 1))";
|
||||
$updateT = ["bool", "int", "bool", $inTypes];
|
||||
$insertQ = "INSERT INTO arsse_label_members(label,article) SELECT ?,a.id from arsse_articles as a join arsse_subscriptions as s on a.subscription = s.id where s.owner = ? and a.id not in (select article from arsse_label_members where label = ?) and a.id in ($inClause)";
|
||||
$insertT = ["int", "str", "int", $inTypes];
|
||||
|
|
|
@ -129,7 +129,7 @@ trait SeriesArticle {
|
|||
[208,14,null, null, null, null, null, null, "", "", "", "2010-01-01 00:00:00",0,0,0,null, ''],
|
||||
[801,15,'http://example.com/1','Article title 1','', '2000-01-01 00:00:00','2000-01-01 00:00:01','e433653cef2e572eee4215fa299a4a5af9137b2cefd6283c85bd69a32915beda','f5cb8bfc1c7396dc9816af212a3e2ac5221585c2a00bf7ccb6aabd95dcfcd6a6','fb0bc8f8cb08913dc5a497db700e327f1d34e4987402687d494a5891f24714d4','18fdd4fa93d693128c43b004399e5c9cea6c261ddfa002518d3669f55d8c2207','2000-01-01 01:00:00',0,0,0,null, ''],
|
||||
[802,15,'http://example.com/2','Article title 2','', '2000-01-02 00:00:00','2000-01-02 00:00:02','5be8a5a46ecd52ed132191c8d27fb1af6b3d4edc00234c5d9f8f0e10562ed3b7','0e86d2de822a174fe3c44a466953e63ca1f1a58a19cbf475fce0855d4e3d5153','13075894189c47ffcfafd1dfe7fbb539f7c74a69d35a399b3abf8518952714f9','2abd0a8cba83b8214a66c8f0293ba63e467d720540e29ff8ddcdab069d4f1c9e','2000-01-02 02:00:00',0,0,0,null, ''],
|
||||
[999,16,null, null, null, null, null, null, "", "", "", "2000-01-01 00:00:00",0,0,0,null, ''],
|
||||
[999,16,null, null, null, null, null, null, "", "", "", "2000-01-01 00:00:00",0,1,0,null, ''],
|
||||
],
|
||||
],
|
||||
'arsse_article_contents' => [
|
||||
|
@ -208,7 +208,6 @@ trait SeriesArticle {
|
|||
[ 802,802],
|
||||
[ 902,802],
|
||||
[ 999,999],
|
||||
[9999,999],
|
||||
],
|
||||
],
|
||||
'arsse_enclosures' => [
|
||||
|
@ -250,14 +249,15 @@ trait SeriesArticle {
|
|||
'arsse_label_members' => [
|
||||
'columns' => ["label", "article", "assigned", "modified"],
|
||||
'rows' => [
|
||||
[1, 1,1,'2000-01-01 00:00:00'],
|
||||
[2, 1,1,'2000-01-01 00:00:00'],
|
||||
[1,19,1,'2000-01-01 00:00:00'],
|
||||
[2,20,1,'2000-01-01 00:00:00'],
|
||||
[1, 5,0,'2000-01-01 00:00:00'],
|
||||
[2, 5,1,'2000-01-01 00:00:00'],
|
||||
[4, 7,0,'2000-01-01 00:00:00'],
|
||||
[4, 8,1,'2015-01-01 00:00:00'],
|
||||
[1, 1,1,'2000-01-01 00:00:00'],
|
||||
[2, 1,1,'2000-01-01 00:00:00'],
|
||||
[1, 19,1,'2000-01-01 00:00:00'],
|
||||
[2, 20,1,'2000-01-01 00:00:00'],
|
||||
[1, 5,0,'2000-01-01 00:00:00'],
|
||||
[2, 5,1,'2000-01-01 00:00:00'],
|
||||
[4, 7,0,'2000-01-01 00:00:00'],
|
||||
[4, 8,1,'2015-01-01 00:00:00'],
|
||||
[1,999,1,'2000-01-01 00:00:00'],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
@ -889,7 +889,7 @@ trait SeriesArticle {
|
|||
|
||||
public function testMarkAnEditionOfADeletedSubscription(): void {
|
||||
$this->assertException("subjectMissing", "Db", "ExceptionInput");
|
||||
Arsse::$db->articleMark("john.doe@example.com", ['starred' => true], (new Context)->edition(9999));
|
||||
Arsse::$db->articleMark("john.doe@example.com", ['starred' => false], (new Context)->edition(999));
|
||||
}
|
||||
|
||||
public function testMarkByOldestEdition(): void {
|
||||
|
|
|
@ -42,19 +42,20 @@ trait SeriesFolder {
|
|||
],
|
||||
],
|
||||
'arsse_subscriptions' => [
|
||||
'columns' => ["id", "owner", "url", "title", "folder"],
|
||||
'columns' => ["id", "owner", "url", "title", "folder", "deleted"],
|
||||
'rows' => [
|
||||
[1, "john.doe@example.com","http://example.com/1", "Feed 1", null],
|
||||
[2, "john.doe@example.com","http://example.com/2", "Feed 2", null],
|
||||
[3, "john.doe@example.com","http://example.com/3", "Feed 3", 1],
|
||||
[4, "john.doe@example.com","http://example.com/4", "Feed 4", 6],
|
||||
[5, "john.doe@example.com","http://example.com/5", "Feed 5", 5],
|
||||
[6, "john.doe@example.com","http://example.com/10", "Feed 10", 5],
|
||||
[7, "jane.doe@example.com","http://example.com/1", "Feed 1", null],
|
||||
[8, "jane.doe@example.com","http://example.com/10", "Feed 10",null],
|
||||
[9, "jane.doe@example.com","http://example.com/2", "Feed 2", 4],
|
||||
[10,"jane.doe@example.com","http://example.com/3", "Feed 3", 4],
|
||||
[11,"jane.doe@example.com","http://example.com/4", "Feed 4", 4],
|
||||
[1, "john.doe@example.com", "http://example.com/1", "Feed 1", null, 0],
|
||||
[2, "john.doe@example.com", "http://example.com/2", "Feed 2", null, 0],
|
||||
[3, "john.doe@example.com", "http://example.com/3", "Feed 3", 1, 0],
|
||||
[4, "john.doe@example.com", "http://example.com/4", "Feed 4", 6, 0],
|
||||
[5, "john.doe@example.com", "http://example.com/5", "Feed 5", 5, 0],
|
||||
[6, "john.doe@example.com", "http://example.com/10", "Feed 10", 5, 0],
|
||||
[101, "john.doe@example.com", "http://example.com/101", "Feed 101", 1, 1],
|
||||
[7, "jane.doe@example.com", "http://example.com/1", "Feed 1", null, 0],
|
||||
[8, "jane.doe@example.com", "http://example.com/10", "Feed 10", null, 0],
|
||||
[9, "jane.doe@example.com", "http://example.com/2", "Feed 2", 4, 0],
|
||||
[10, "jane.doe@example.com", "http://example.com/3", "Feed 3", 4, 0],
|
||||
[11, "jane.doe@example.com", "http://example.com/4", "Feed 4", 4, 0],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
|
|
@ -31,14 +31,15 @@ trait SeriesIcon {
|
|||
],
|
||||
],
|
||||
'arsse_subscriptions' => [
|
||||
'columns' => ["id", "owner", "url", "title", "icon"],
|
||||
'columns' => ["id", "owner", "url", "title", "icon", "deleted"],
|
||||
'rows' => [
|
||||
[1,'john.doe@example.com',"http://localhost:8000/Feed/Matching/3", "Ook", 1],
|
||||
[2,'john.doe@example.com',"http://localhost:8000/Feed/Matching/1", "Eek", 2],
|
||||
[3,'john.doe@example.com',"http://localhost:8000/Feed/Fetching/Error?code=404", "Ack", 3],
|
||||
[4,'john.doe@example.com',"http://localhost:8000/Feed/NextFetch/NotModified?t=".time(), "Ooook", null],
|
||||
[5,'john.doe@example.com',"http://localhost:8000/Feed/Parsing/Valid", "Ooook", 2],
|
||||
[6,'jane.doe@example.com',"http://localhost:8000/Feed/Parsing/Valid", "Ooook", 2],
|
||||
[1,'john.doe@example.com',"http://localhost:8000/Feed/Matching/3", "Ook", 1, 0],
|
||||
[2,'john.doe@example.com',"http://localhost:8000/Feed/Matching/1", "Eek", 2, 0],
|
||||
[3,'john.doe@example.com',"http://localhost:8000/Feed/Fetching/Error?code=404", "Ack", 3, 0],
|
||||
[4,'john.doe@example.com',"http://localhost:8000/Feed/NextFetch/NotModified?t=".time(), "Ooook", null, 0],
|
||||
[5,'john.doe@example.com',"http://localhost:8000/Feed/Parsing/Valid", "Ooook", 2, 0],
|
||||
[6,'john.doe@example.com',"http://localhost:8000/Feed/Discovery/Valid", "Aaack", 4, 1],
|
||||
[7,'jane.doe@example.com',"http://localhost:8000/Feed/Parsing/Valid", "Ooook", 2, 0],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
|
|
@ -40,22 +40,23 @@ trait SeriesLabel {
|
|||
],
|
||||
],
|
||||
'arsse_subscriptions' => [
|
||||
'columns' => ["id", "owner", "url", "folder"],
|
||||
'columns' => ["id", "owner", "url", "folder", "deleted"],
|
||||
'rows' => [
|
||||
[1, "john.doe@example.com","http://example.com/1",null],
|
||||
[2, "john.doe@example.com","http://example.com/2",null],
|
||||
[3, "john.doe@example.com","http://example.com/3",1],
|
||||
[4, "john.doe@example.com","http://example.com/4",6],
|
||||
[5, "john.doe@example.com","http://example.com/10",5],
|
||||
[6, "jane.doe@example.com","http://example.com/1",null],
|
||||
[7, "jane.doe@example.com","http://example.com/10",null],
|
||||
[8, "john.doe@example.org","http://example.com/11",null],
|
||||
[9, "john.doe@example.org","http://example.com/12",null],
|
||||
[10,"john.doe@example.org","http://example.com/13",null],
|
||||
[11,"john.doe@example.net","http://example.com/10",null],
|
||||
[12,"john.doe@example.net","http://example.com/2",9],
|
||||
[13,"john.doe@example.net","http://example.com/3",8],
|
||||
[14,"john.doe@example.net","http://example.com/4",7],
|
||||
[1, "john.doe@example.com", "http://example.com/1", null, 0],
|
||||
[2, "john.doe@example.com", "http://example.com/2", null, 0],
|
||||
[3, "john.doe@example.com", "http://example.com/3", 1, 0],
|
||||
[4, "john.doe@example.com", "http://example.com/4", 6, 0],
|
||||
[5, "john.doe@example.com", "http://example.com/10" ,5, 0],
|
||||
[6, "jane.doe@example.com", "http://example.com/1", null, 0],
|
||||
[7, "jane.doe@example.com", "http://example.com/10", null, 0],
|
||||
[8, "john.doe@example.org", "http://example.com/11", null, 0],
|
||||
[9, "john.doe@example.org", "http://example.com/12", null, 0],
|
||||
[10, "john.doe@example.org", "http://example.com/13", null, 0],
|
||||
[11, "john.doe@example.net", "http://example.com/10", null, 0],
|
||||
[12, "john.doe@example.net", "http://example.com/2", 9, 0],
|
||||
[13, "john.doe@example.net", "http://example.com/3", 8, 0],
|
||||
[14, "john.doe@example.net", "http://example.com/4", 7, 0],
|
||||
[16, "john.doe@example.com", "http://example.com/16", null, 1],
|
||||
],
|
||||
],
|
||||
'arsse_articles' => [
|
||||
|
@ -92,6 +93,7 @@ trait SeriesLabel {
|
|||
[206,13,null, null, "Jane Doe",null, null, null, "", "", "", "2010-01-01 00:00:00",0,0,0,null, ''],
|
||||
[207,14,null, null, "Jane Doe",null, null, null, "", "", "", "2000-01-01 00:00:00",0,0,0,null, ''],
|
||||
[208,14,null, null, null, null, null, null, "", "", "", "2010-01-01 00:00:00",0,0,0,null, ''],
|
||||
[999,16,null, null, null, null, null, null, "", "", "", "2000-01-01 00:00:00",1,1,0,null, ''],
|
||||
],
|
||||
],
|
||||
'arsse_article_contents' => [
|
||||
|
@ -204,13 +206,15 @@ trait SeriesLabel {
|
|||
'arsse_label_members' => [
|
||||
'columns' => ["label", "article", "assigned"],
|
||||
'rows' => [
|
||||
[1, 1,1],
|
||||
[2, 1,1],
|
||||
[1,19,1],
|
||||
[2,20,1],
|
||||
[1, 5,0],
|
||||
[2, 5,1],
|
||||
[2, 8,1],
|
||||
[1, 1,1],
|
||||
[2, 1,1],
|
||||
[1, 19,1],
|
||||
[2, 20,1],
|
||||
[1, 5,0],
|
||||
[2, 5,1],
|
||||
[2, 8,1],
|
||||
[1,999,1],
|
||||
[2,999,1],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
|
Loading…
Reference in a new issue