diff options
-rw-r--r-- | lib/VNWeb/VN/Page.pm | 23 | ||||
-rw-r--r-- | sql/func.sql | 55 | ||||
-rw-r--r-- | sql/perms.sql | 1 | ||||
-rw-r--r-- | sql/schema.sql | 9 | ||||
-rw-r--r-- | sql/tableattrs.sql | 2 | ||||
-rw-r--r-- | util/updates/2022-08-03-tags_vn_direct.sql | 10 |
6 files changed, 66 insertions, 34 deletions
diff --git a/lib/VNWeb/VN/Page.pm b/lib/VNWeb/VN/Page.pm index 884f4864..77e4883b 100644 --- a/lib/VNWeb/VN/Page.pm +++ b/lib/VNWeb/VN/Page.pm @@ -35,20 +35,17 @@ sub enrich_vn { ); enrich_extlinks r => $v->{releases}; - $v->{reviews} = tuwf->dbRowi('SELECT COUNT(*) FILTER(WHERE isfull) AS full, COUNT(*) FILTER(WHERE NOT isfull) AS mini, COUNT(*) AS total FROM reviews WHERE NOT c_flagged AND vid =', \$v->{id}); - - $v->{tags} = tuwf->dbAlli(" - SELECT t.id, t.name, t.cat, avg(tv.vote) as rating - , coalesce(avg(tv.spoiler), t.defaultspoil) as spoiler - , count(lie) filter(where lie) > 0 AND count(lie) filter (where lie) >= count(lie)>>1 AS lie + $v->{reviews} = tuwf->dbRowi(' + SELECT COUNT(*) FILTER(WHERE isfull) AS full, COUNT(*) FILTER(WHERE NOT isfull) AS mini, COUNT(*) AS total + FROM reviews + WHERE NOT c_flagged AND vid =', \$v->{id} + ); + $v->{tags} = tuwf->dbAlli(' + SELECT t.id, t.name, t.cat, tv.rating, tv.spoiler, tv.lie FROM tags t - JOIN tags_vn tv ON tv.tag = t.id - LEFT JOIN users u ON u.id = tv.uid - WHERE NOT t.hidden AND tv.vid =", \$v->{id}, " - AND NOT tv.ignore AND (u.id IS NULL OR u.perm_tag) - GROUP BY t.id, t.name, t.cat - HAVING avg(tv.vote) > 0 - ORDER BY rating DESC, t.name" + JOIN tags_vn_direct tv ON t.id = tv.tag + WHERE tv.vid =', \$v->{id}, ' + ORDER BY rating DESC, t.name' ); } diff --git a/sql/func.sql b/sql/func.sql index c9559cff..842d477b 100644 --- a/sql/func.sql +++ b/sql/func.sql @@ -235,13 +235,37 @@ $$ LANGUAGE plpgsql; -- Don't use "LANGUAGE SQL" here; Make sure to generate a n --- Recalculate tags_vn_inherit. +-- Recalculate tags_vn_direct & tags_vn_inherit. -- When a vid is given, only the tags for that vid will be updated. These -- incremental updates do not affect tags.c_items, so that may still get -- out-of-sync. CREATE OR REPLACE FUNCTION tag_vn_calc(uvid vndbid) RETURNS void AS $$ BEGIN IF uvid IS NULL THEN + DROP INDEX IF EXISTS tags_vn_direct_tag_vid; + DROP INDEX IF EXISTS tags_vn_direct_vid; + TRUNCATE tags_vn_direct; + ELSE + DELETE FROM tags_vn_direct WHERE vid = uvid; + END IF; + + INSERT INTO tags_vn_direct (tag, vid, rating, spoiler, lie) + SELECT tv.tag, tv.vid, avg(tv.vote) + , CASE WHEN COUNT(spoiler) = 0 THEN MIN(t.defaultspoil) WHEN AVG(spoiler) > 1.3 THEN 2 WHEN AVG(spoiler) > 0.4 THEN 1 ELSE 0 END + , count(lie) filter(where lie) > 0 AND count(lie) filter (where lie) >= count(lie)>>1 + FROM tags_vn tv + JOIN tags t ON t.id = tv.tag + LEFT JOIN users u ON u.id = tv.uid + WHERE NOT t.hidden + AND NOT tv.ignore AND (u.id IS NULL OR u.perm_tag) + AND vid NOT IN(SELECT id FROM vn WHERE hidden) + AND (uvid IS NULL OR vid = uvid) + GROUP BY tv.tag, tv.vid + HAVING avg(tv.vote) > 0; + + IF uvid IS NULL THEN + CREATE INDEX tags_vn_direct_tag_vid ON tags_vn_direct (tag, vid); + CREATE INDEX tags_vn_direct_vid ON tags_vn_direct (vid); DROP INDEX IF EXISTS tags_vn_inherit_tag_vid; TRUNCATE tags_vn_inherit; ELSE @@ -249,31 +273,19 @@ BEGIN END IF; INSERT INTO tags_vn_inherit (tag, vid, rating, spoiler) - -- Group votes to generate a list of directly-upvoted (vid, tag) pairs. - -- This is essentually the same as the tag listing on VN pages. - WITH RECURSIVE t_avg(tag, vid, vote, spoiler) AS ( - SELECT tv.tag, tv.vid, AVG(tv.vote)::real, CASE WHEN COUNT(tv.spoiler) = 0 THEN MIN(t.defaultspoil) ELSE AVG(tv.spoiler)::real END - FROM tags_vn tv - JOIN tags t ON t.id = tv.tag - LEFT JOIN users u ON u.id = tv.uid - WHERE NOT tv.ignore AND NOT t.hidden - AND (u.id IS NULL OR u.perm_tag) - AND vid NOT IN(SELECT id FROM vn WHERE hidden) - AND (uvid IS NULL OR vid = uvid) - GROUP BY tv.tag, tv.vid - HAVING AVG(tv.vote) > 0 - -- Add parent tags - ), t_all(lvl, tag, vid, vote, spoiler) AS ( - SELECT 15, * FROM t_avg + -- Add parent tags to each row in tags_vn_direct + WITH RECURSIVE t_all(lvl, tag, vid, vote, spoiler) AS ( + SELECT 15, tag, vid, rating, spoiler + FROM tags_vn_direct + WHERE (uvid IS NULL OR vid = uvid) UNION ALL SELECT ta.lvl-1, tp.parent, ta.vid, ta.vote, ta.spoiler FROM t_all ta JOIN tags_parents tp ON tp.id = ta.tag WHERE ta.lvl > 0 ) - -- Merge - SELECT tag, vid, AVG(vote) - , (CASE WHEN MIN(spoiler) > 1.3 THEN 2 WHEN MIN(spoiler) > 0.4 THEN 1 ELSE 0 END)::smallint + -- Merge duplicates + SELECT tag, vid, AVG(vote), MIN(spoiler) FROM t_all WHERE tag IN(SELECT id FROM tags WHERE searchable) GROUP BY tag, vid; @@ -452,9 +464,10 @@ DECLARE BEGIN SELECT id INTO xoldchid FROM changes WHERE itemid = nitemid AND rev = nrev-1; - -- Update c_search + -- Update vn.c_search and tags_vn_* IF vndbid_type(nitemid) = 'v' THEN UPDATE vn SET c_search = search_gen_vn(id) WHERE id = nitemid; + PERFORM tag_vn_calc(nitemid); -- actually only necessary when the hidden flag is changed END IF; -- Update vn.c_search when diff --git a/sql/perms.sql b/sql/perms.sql index 0ea27afa..816a45c6 100644 --- a/sql/perms.sql +++ b/sql/perms.sql @@ -64,6 +64,7 @@ GRANT SELECT, INSERT ON tags_hist TO vndb_site; GRANT SELECT, INSERT, DELETE ON tags_parents TO vndb_site; GRANT SELECT, INSERT ON tags_parents_hist TO vndb_site; GRANT SELECT, INSERT, UPDATE, DELETE ON tags_vn TO vndb_site; +GRANT SELECT ON tags_vn_direct TO vndb_site; GRANT SELECT ON tags_vn_inherit TO vndb_site; GRANT SELECT, INSERT, UPDATE, DELETE ON threads TO vndb_site; GRANT SELECT, INSERT, UPDATE, DELETE ON threads_boards TO vndb_site; diff --git a/sql/schema.sql b/sql/schema.sql index 31a706ef..99916231 100644 --- a/sql/schema.sql +++ b/sql/schema.sql @@ -845,6 +845,15 @@ CREATE TABLE tags_vn ( lie boolean -- [pub] implies spoiler=0 ); +-- tags_vn_direct +CREATE TABLE tags_vn_direct ( + tag vndbid NOT NULL, + vid vndbid NOT NULL, + rating real NOT NULL, + spoiler smallint NOT NULL, + lie boolean NOT NULL +); + -- tags_vn_inherit CREATE TABLE tags_vn_inherit ( tag vndbid NOT NULL, diff --git a/sql/tableattrs.sql b/sql/tableattrs.sql index f4220808..1fc957c3 100644 --- a/sql/tableattrs.sql +++ b/sql/tableattrs.sql @@ -22,6 +22,8 @@ CREATE INDEX staff_alias_id ON staff_alias (id); CREATE UNIQUE INDEX tags_vn_pkey ON tags_vn (tag,vid,uid); CREATE UNIQUE INDEX threads_boards_pkey ON threads_boards (tid,type,COALESCE(iid, 'r1')); -- 'r1' is an invalid board id CREATE INDEX tags_vn_date ON tags_vn (date); +CREATE INDEX tags_vn_direct_tag_vid ON tags_vn_direct (tag, vid); +CREATE INDEX tags_vn_direct_vid ON tags_vn_direct (vid); CREATE INDEX tags_vn_inherit_tag_vid ON tags_vn_inherit (tag, vid); CREATE INDEX tags_vn_uid ON tags_vn (uid) WHERE uid IS NOT NULL; CREATE INDEX tags_vn_vid ON tags_vn (vid); diff --git a/util/updates/2022-08-03-tags_vn_direct.sql b/util/updates/2022-08-03-tags_vn_direct.sql new file mode 100644 index 00000000..e8a2445c --- /dev/null +++ b/util/updates/2022-08-03-tags_vn_direct.sql @@ -0,0 +1,10 @@ +CREATE TABLE tags_vn_direct ( + tag vndbid NOT NULL, + vid vndbid NOT NULL, + rating real NOT NULL, + spoiler smallint NOT NULL, + lie boolean NOT NULL +); +\i sql/func.sql +\i sql/perms.sql +SELECT tag_vn_calc(NULL); |