From e4a7e6622be87bf29fa315877c640116fa43cc51 Mon Sep 17 00:00:00 2001 From: "J. King" Date: Mon, 6 Jun 2022 19:54:48 -0400 Subject: [PATCH] Fix most problems with the new schema Some issues remain with MySQL --- lib/Database.php | 7 ++-- sql/MySQL/7.sql | 7 ++-- sql/PostgreSQL/7.sql | 25 +++++++++------ sql/SQLite3/7.sql | 46 +++++++++++++-------------- tests/cases/Database/TestDatabase.php | 2 +- tests/cases/Db/BaseUpdate.php | 2 +- tests/phpunit.dist.xml | 16 +++++----- 7 files changed, 56 insertions(+), 49 deletions(-) diff --git a/lib/Database.php b/lib/Database.php index 68cc43df..2049f279 100644 --- a/lib/Database.php +++ b/lib/Database.php @@ -27,9 +27,8 @@ use JKingWeb\Arsse\Rule\Exception as RuleException; * - Subscriptions to feeds, which belong to users * - Folders, which belong to users and contain subscriptions * - Tags, which belong to users and can be assigned to multiple subscriptions - * - Feeds to which users are subscribed - * - Icons, which are associated with feeds - * - Articles, which belong to feeds and for which users can only affect metadata + * - Icons, which are associated with subscriptions + * - Articles, which belong to subscriptions * - Editions, identifying authorial modifications to articles * - Labels, which belong to users and can be assigned to multiple articles * - Sessions, used by some protocols to identify users across periods of time @@ -49,7 +48,7 @@ use JKingWeb\Arsse\Rule\Exception as RuleException; */ class Database { /** The version number of the latest schema the interface is aware of */ - public const SCHEMA_VERSION = 7; + public const SCHEMA_VERSION = 8; /** Makes tag/label association change operations remove members */ public const ASSOC_REMOVE = 0; /** Makes tag/label association change operations add members */ diff --git a/sql/MySQL/7.sql b/sql/MySQL/7.sql index af16a8cc..e3e91afb 100644 --- a/sql/MySQL/7.sql +++ b/sql/MySQL/7.sql @@ -10,7 +10,10 @@ create table arsse_articles_map( subscription bigint unsigned not null, id serial ); -alter table arsse_articles_map auto_increment = (select max(id) + 1 from arsse_articles); +-- alter table arsse_articles_map auto_increment = (select max(id) + 1 from arsse_articles); +insert into arsse_articles_map + select 0, 0, max(id) from arsse_articles; +delete from arsse_articles_map; insert into arsse_articles_map(article, subscription) select a.id as article, @@ -73,7 +76,7 @@ insert into arsse_articles(id,feed,subscription,"read",starred,hidden,published, a.author, a.guid, a.url_title_hash, - a_url_content_hash, + a.url_content_hash, a.title_content_hash, coalesce(m.note,'') from arsse_articles_map as i diff --git a/sql/PostgreSQL/7.sql b/sql/PostgreSQL/7.sql index 5eb8571d..4d64370b 100644 --- a/sql/PostgreSQL/7.sql +++ b/sql/PostgreSQL/7.sql @@ -5,12 +5,12 @@ -- Create a temporary table mapping old article IDs to new article IDs per-user. -- Any articles which have only one subscription will be unchanged, which will -- limit the amount of disruption -create table arsse_articles_map( +create temp table arsse_articles_map( article bigint not null, subscription bigint not null, id bigserial primary key ); -alter sequence arsse_articles_map_id_seq restart with (select max(id) + 1 from arsse_articles); +select setval('arsse_articles_map_id_seq', (select max(id) from arsse_articles)); insert into arsse_articles_map(article, subscription) select a.id as article, @@ -55,30 +55,35 @@ alter table arsse_articles add column marked timestamp(0) without time zone; alter table arsse_articles add column note text collate "und-x-icu" not null default ''; -- Populate the articles table with new information; this either inserts or updates in-place -insert into arsse_articles(id,feed,subscription,read,starred,hidden,published,edited,modified,marked,url,title,author,guid,url_title_hash,url_content_hash,title_content_hash,note) +with new_data as ( select i.id, a.feed, i.subscription, - coalesce(m.read,0), - coalesce(m.starred,0), - coalesce(m.hidden,0), + coalesce(m.read,0) as read, + coalesce(m.starred,0) as starred, + coalesce(m.hidden,0) as hidden, a.published, a.edited, a.modified, - m.modified, + m.modified as marked, a.url, a.title, a.author, a.guid, a.url_title_hash, - a_url_content_hash, + a.url_content_hash, a.title_content_hash, - coalesce(m.note,'') + coalesce(m.note,'') as note from arsse_articles_map as i left join arsse_articles as a on a.id = i.article left join arsse_marks as m on a.id = m.article -on conflict do update set (id,feed,subscription,read,starred,hidden,published,edited,modified,marked,url,title,author,guid,url_title_hash,url_content_hash,title_content_hash,note) = row; +) +insert into arsse_articles(id,feed,subscription,read,starred,hidden,published,edited,modified,marked,url,title,author,guid,url_title_hash,url_content_hash,title_content_hash,note) + select * from new_data +on conflict (id) do update set (subscription,read,starred,hidden,marked,note) = ( + select subscription, read, starred, hidden, marked, note from new_data where id = excluded.id +); -- Create one edition for each renumbered article insert into arsse_editions(article) select id from arsse_articles_map where id <> article; diff --git a/sql/SQLite3/7.sql b/sql/SQLite3/7.sql index cd905380..bdc877f1 100644 --- a/sql/SQLite3/7.sql +++ b/sql/SQLite3/7.sql @@ -5,30 +5,30 @@ -- Create a temporary table mapping old article IDs to new article IDs per-user. -- Any articles which have only one subscription will be unchanged, which will -- limit the amount of disruption -create table arsse_articles_map( +create temp table arsse_articles_map( article int not null, subscription int not null, id integer primary key autoincrement ); -insert into arsse_articles_map(article, subscription) values(1, 1, ''); +insert into arsse_articles_map(article, subscription) values(1, 1); delete from arsse_articles_map; -update sqlite_sequence set seq = (select max(id) from arsse_articles) where name = 'arsse_articles_map'; +update temp.sqlite_sequence set seq = (select max(id) from arsse_articles) where name = 'arsse_articles_map'; insert into arsse_articles_map(article, subscription) - select - a.id as article, - s.id as subscription + select + a.id as article, + s.id as subscription from arsse_articles as a join arsse_subscriptions as s using(feed) where feed in ( - select feed from (select feed, count(*) as count from arsse_subscriptions group by feed) as c where c.count > 1 + select feed from (select feed, count(*) as count from arsse_subscriptions group by feed) as c where count > 1 ); insert into arsse_articles_map(article, subscription, id) - select - a.id as article, - s.id as subscription, + select + a.id as article, + s.id as subscription, a.id as id from arsse_articles as a join arsse_subscriptions as s using(feed) where feed in ( - select feed from (select feed, count(*) as count from arsse_subscriptions group by feed) as c where c.count = 1 + select feed from (select feed, count(*) as count from arsse_subscriptions group by feed) as c where count = 1 ); -- Create a new articles table which combines the marks table but does not include content @@ -68,7 +68,7 @@ insert into arsse_articles_new a.author, a.guid, a.url_title_hash, - a_url_content_hash, + a.url_content_hash, a.title_content_hash, coalesce(m.note,'') from arsse_articles_map as i @@ -94,8 +94,8 @@ delete from arsse_editions where article in (select article from arsse_articles_ -- Create enclures for renumbered articles and delete obsolete enclosures insert into arsse_enclosures(article, url, type) - select - m.id, url, type + select + m.id, url, type from arsse_articles_map as m join arsse_enclosures as e on m.article = e.article where m.id <> m.article; @@ -103,8 +103,8 @@ delete from arsse_enclosures where article in (select article from arsse_article -- Create categories for renumbered articles and delete obsolete categories insert into arsse_categories(article, name) - select - m.id, name + select + m.id, name from arsse_articles_map as m join arsse_categories as c on m.article = c.article where m.id <> m.article; @@ -154,16 +154,16 @@ create table arsse_subscriptions_new( ); insert into arsse_subscriptions_new select - s.id, - s.owner, - f.url, - f.title, - s.title, + s.id, + s.owner, + f.url, + f.title, + s.title, s.folder, f.modified, - f.etag + f.etag, f.next_fetch, - f.added, + s.added, f.source, f.updated, f.err_count, diff --git a/tests/cases/Database/TestDatabase.php b/tests/cases/Database/TestDatabase.php index 00838b3a..2809366f 100644 --- a/tests/cases/Database/TestDatabase.php +++ b/tests/cases/Database/TestDatabase.php @@ -55,7 +55,7 @@ class TestDatabase extends \JKingWeb\Arsse\Test\AbstractTest { ["?,?", [null, null], [null, null], "str"], ["null", [], array_fill(0, $l, null), "str"], ["$intList", [], $ints, "int"], - ["$intList,".($l + 1), [], array_merge($ints, [$l + 1]), "int"], + ["$intList,".($l + 1), [], array_merge($ints, [$l + 1]), "int"], ["$intList,0", [], array_merge($ints, ["OOK"]), "int"], ["$intList", [], array_merge($ints, [null]), "int"], ["$stringList,''", [], array_merge($strings, [""]), "str"], diff --git a/tests/cases/Db/BaseUpdate.php b/tests/cases/Db/BaseUpdate.php index 5b645721..88127084 100644 --- a/tests/cases/Db/BaseUpdate.php +++ b/tests/cases/Db/BaseUpdate.php @@ -11,7 +11,7 @@ use JKingWeb\Arsse\Database; use JKingWeb\Arsse\Db\Exception; use org\bovigo\vfs\vfsStream; -class BaseUpdate extends \JKingWeb\Arsse\Test\AbstractTest { +abstract class BaseUpdate extends \JKingWeb\Arsse\Test\AbstractTest { protected static $interface; protected $drv; protected $vfs; diff --git a/tests/phpunit.dist.xml b/tests/phpunit.dist.xml index bd01e8f6..ec6e34ce 100644 --- a/tests/phpunit.dist.xml +++ b/tests/phpunit.dist.xml @@ -75,13 +75,13 @@ cases/Db/SQLite3/TestCreation.php cases/Db/SQLite3/TestDriver.php cases/Db/SQLite3/TestUpdate.php - cases/Db/SQLite3/TestDatabase.php + cases/Db/SQLite3PDO/TestResult.php cases/Db/SQLite3PDO/TestStatement.php cases/Db/SQLite3PDO/TestCreation.php cases/Db/SQLite3PDO/TestDriver.php cases/Db/SQLite3PDO/TestUpdate.php - cases/Db/SQLite3PDO/TestDatabase.php + cases/Db/PostgreSQL/TestResult.php @@ -89,13 +89,13 @@ cases/Db/PostgreSQL/TestCreation.php cases/Db/PostgreSQL/TestDriver.php cases/Db/PostgreSQL/TestUpdate.php - cases/Db/PostgreSQL/TestDatabase.php + cases/Db/PostgreSQLPDO/TestResult.php cases/Db/PostgreSQLPDO/TestStatement.php cases/Db/PostgreSQLPDO/TestCreation.php cases/Db/PostgreSQLPDO/TestDriver.php cases/Db/PostgreSQLPDO/TestUpdate.php - cases/Db/PostgreSQLPDO/TestDatabase.php + cases/Db/MySQL/TestResult.php @@ -103,13 +103,13 @@ cases/Db/MySQL/TestCreation.php cases/Db/MySQL/TestDriver.php cases/Db/MySQL/TestUpdate.php - cases/Db/MySQL/TestDatabase.php + cases/Db/MySQLPDO/TestResult.php cases/Db/MySQLPDO/TestStatement.php cases/Db/MySQLPDO/TestCreation.php cases/Db/MySQLPDO/TestDriver.php cases/Db/MySQLPDO/TestUpdate.php - cases/Db/MySQLPDO/TestDatabase.php + cases/REST/TestREST.php @@ -147,9 +147,9 @@ cases/TestArsse.php - cases/ImportExport/TestFile.php +