summaryrefslogtreecommitdiff
path: root/lib/VNWeb
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2021-05-21 13:07:06 +0200
committerYorhel <git@yorhel.nl>2021-05-21 13:07:08 +0200
commit09062eaba0297123eaf298827c803db5a5fe0e2e (patch)
treec19d133b0f05f80ca586f4196e4e8153fd2bb195 /lib/VNWeb
parent892af2bbbc9c7b6675708bf01f0ebd304014fa0f (diff)
Tags/Traits: Add main/primary flag to parents list
This way there is always a single canonical path for each tag/trait, which fixes the problem with traits that could belong to multiple groups yet you couldn't control which one was selected, and this also removes duplication in the VN->tags tab, which now doesn't have to non-canonical tag paths.
Diffstat (limited to 'lib/VNWeb')
-rw-r--r--lib/VNWeb/TT/Lib.pm8
-rw-r--r--lib/VNWeb/TT/TagEdit.pm4
-rw-r--r--lib/VNWeb/TT/TagPage.pm3
-rw-r--r--lib/VNWeb/TT/TraitEdit.pm13
-rw-r--r--lib/VNWeb/TT/TraitPage.pm3
-rw-r--r--lib/VNWeb/VN/Page.pm2
6 files changed, 22 insertions, 11 deletions
diff --git a/lib/VNWeb/TT/Lib.pm b/lib/VNWeb/TT/Lib.pm
index cb0cc074..d40f5d46 100644
--- a/lib/VNWeb/TT/Lib.pm
+++ b/lib/VNWeb/TT/Lib.pm
@@ -74,11 +74,11 @@ sub parents_ {
my %t;
my $table = $type eq 'g' ? 'tags' : 'traits';
push $t{$_->{child}}->@*, $_ for tuwf->dbAlli("
- WITH RECURSIVE p(id,child,name) AS (
- SELECT id, ", \$t->{id}, "::vndbid, name FROM $table WHERE id IN", [ map $_->{parent}, $t->{parents}->@* ], "
+ WITH RECURSIVE p(id,child,name,main) AS (
+ SELECT t.id, tp.id, t.name, tp.main FROM ${table}_parents tp JOIN $table t ON t.id = tp.parent WHERE tp.id =", \$t->{id}, "
UNION
- SELECT t.id, p.id, t.name FROM p JOIN ${table}_parents tp ON tp.id = p.id JOIN $table t ON t.id = tp.parent
- ) SELECT * FROM p ORDER BY name
+ SELECT t.id, p.id, t.name, (p.main and tp.main) FROM p JOIN ${table}_parents tp ON tp.id = p.id JOIN $table t ON t.id = tp.parent
+ ) SELECT * FROM p ORDER BY main DESC, name
")->@*;
my sub rec {
diff --git a/lib/VNWeb/TT/TagEdit.pm b/lib/VNWeb/TT/TagEdit.pm
index 1b4a86df..be4b9964 100644
--- a/lib/VNWeb/TT/TagEdit.pm
+++ b/lib/VNWeb/TT/TagEdit.pm
@@ -15,6 +15,7 @@ my $FORM = {
defaultspoil => { uint => 1, range => [0,2] },
parents => { aoh => {
parent => { vndbid => 'g' },
+ main => { anybool => 1 },
name => { _when => 'out' },
} },
wipevotes => { _when => 'in', anybool => 1 },
@@ -60,7 +61,7 @@ TUWF::get qr{/(?:$RE{gid}/add|g/new)}, sub {
my $e = elm_empty($FORM_OUT);
$e->{authmod} = auth->permTagmod;
if($id) {
- $e->{parents} = [{ parent => $g->{id}, name => $g->{name} }];
+ $e->{parents} = [{ parent => $g->{id}, main => 1, name => $g->{name} }];
$e->{cat} = $g->{cat};
}
@@ -112,6 +113,7 @@ elm_api TagEdit => $FORM_OUT, $FORM_IN, sub {
$new ? () : sql('id NOT IN(WITH RECURSIVE t(id) AS (SELECT', \$data->{id}, '::vndbid UNION SELECT tp.id FROM tags_parents tp JOIN t ON t.id = tp.parent) SELECT id FROM t)'),
sql 'id IN', $_[0]
}, map $_->{parent}, $data->{parents}->@*;
+ die "No or multiple primary parents" if $data->{parents}->@* && 1 != grep $_->{main}, $data->{parents}->@*;
$data->{description} = bb_subst_links($data->{description});
diff --git a/lib/VNWeb/TT/TagPage.pm b/lib/VNWeb/TT/TagPage.pm
index 819a6bd1..e7b63f31 100644
--- a/lib/VNWeb/TT/TagPage.pm
+++ b/lib/VNWeb/TT/TagPage.pm
@@ -11,6 +11,7 @@ sub rev_ {
my($t) = @_;
sub enrich_item {
enrich_merge parent => 'SELECT id AS parent, name FROM tags WHERE id IN', $_[0]{parents};
+ $_[0]{parents} = [ sort { $a->{name} cmp $b->{name} || $a->{parent} <=> $b->{parent} } $_[0]{parents}->@* ];
}
enrich_item $t;
revision_ $t, \&enrich_item,
@@ -21,7 +22,7 @@ sub rev_ {
[ searchable => 'Searchable', fmt => 'bool' ],
[ applicable => 'Applicable', fmt => 'bool' ],
[ defaultspoil => 'Default spoiler level' ],
- [ parents => 'Parent tags', fmt => sub { a_ href => "/$_->{parent}", $_->{name}; } ];
+ [ parents => 'Parent tags', fmt => sub { a_ href => "/$_->{parent}", $_->{name}; txt_ ' (primary)' if $_->{main} } ];
}
diff --git a/lib/VNWeb/TT/TraitEdit.pm b/lib/VNWeb/TT/TraitEdit.pm
index 7744e181..2c3a43ae 100644
--- a/lib/VNWeb/TT/TraitEdit.pm
+++ b/lib/VNWeb/TT/TraitEdit.pm
@@ -13,6 +13,7 @@ my $FORM = {
defaultspoil => { uint => 1, range => [0,2] },
parents => { aoh => {
parent => { vndbid => 'i' },
+ main => { anybool => 1 },
name => { _when => 'out' },
group => { _when => 'out', required => 0 },
} },
@@ -56,6 +57,7 @@ TUWF::get qr{/(?:$RE{iid}/add|i/new)}, sub {
my $e = elm_empty($FORM_OUT);
$e->{authmod} = auth->permTagmod;
if($id) {
+ $i->{main} = 1;
$e->{parents} = [$i];
$e->{sexual} = $i->{sexual};
}
@@ -98,9 +100,9 @@ elm_api TraitEdit => $FORM_OUT, $FORM_IN, sub {
$new ? () : sql('id NOT IN(WITH RECURSIVE t(id) AS (SELECT', \$e->{id}, '::vndbid UNION SELECT tp.id FROM traits_parents tp JOIN t ON t.id = tp.parent) SELECT id FROM t)'),
sql 'id IN', $_[0]
}, @parents;
+ die "No or multiple primary parents" if $data->{parents}->@* && 1 != grep $_->{main}, $data->{parents}->@*;
- # It's technically possible for a trait to be in multiple groups, but the DB schema doesn't support that so let's get the group from the first parent (sorted by id).
- my $group = tuwf->dbVali('SELECT coalesce("group",id) FROM traits WHERE id IN', \@parents, 'ORDER BY id LIMIT 1');
+ my $group = tuwf->dbVali('SELECT coalesce("group",id) FROM traits WHERE id =', \[grep $_->{main}, $data->{parents}->@*]->[0]{parent});
$data->{description} = bb_subst_links($data->{description});
@@ -120,7 +122,12 @@ elm_api TraitEdit => $FORM_OUT, $FORM_IN, sub {
return elm_Unchanged if !$new && !form_changed $FORM_CMP, $data, $e;
my $ch = db_edit i => $e->{id}, $data;
- tuwf->dbExeci('UPDATE traits SET "group" =', \$group, 'WHERE id =', \$ch->{nitemid});
+ tuwf->dbExeci('UPDATE traits SET "group" = null WHERE id =', \$ch->{nitemid}) if !$group;
+ tuwf->dbExeci('
+ WITH RECURSIVE childs (id) AS (
+ SELECT ', \$ch->{nitemid}, '::vndbid UNION ALL SELECT tp.id FROM childs JOIN traits_parents tp ON tp.parent = childs.id AND tp.main
+ ) UPDATE traits SET "group" =', \$group, 'WHERE id IN(SELECT id FROM childs) AND "group" IS DISTINCT FROM', \$group
+ ) if $group;
elm_Redirect "/$ch->{nitemid}.$ch->{nrev}";
};
diff --git a/lib/VNWeb/TT/TraitPage.pm b/lib/VNWeb/TT/TraitPage.pm
index a759eb6b..8ccb629d 100644
--- a/lib/VNWeb/TT/TraitPage.pm
+++ b/lib/VNWeb/TT/TraitPage.pm
@@ -11,6 +11,7 @@ sub rev_ {
my($t) = @_;
sub enrich_item {
enrich_merge parent => 'SELECT id AS parent, name FROM traits WHERE id IN', $_[0]{parents};
+ $_[0]{parents} = [ sort { $a->{name} cmp $b->{name} || $a->{parent} <=> $b->{parent} } $_[0]{parents}->@* ];
}
enrich_item $t;
revision_ $t, \&enrich_item,
@@ -22,7 +23,7 @@ sub rev_ {
[ applicable => 'Applicable', fmt => 'bool' ],
[ defaultspoil => 'Default spoiler level' ],
[ order => 'Sort order' ],
- [ parents => 'Parent traits', fmt => sub { a_ href => "/$_->{parent}", $_->{name}; } ];
+ [ parents => 'Parent traits', fmt => sub { a_ href => "/$_->{parent}", $_->{name}; txt_ ' (primary)' if $_->{main} } ];
}
diff --git a/lib/VNWeb/VN/Page.pm b/lib/VNWeb/VN/Page.pm
index 6cfc0230..29d8e905 100644
--- a/lib/VNWeb/VN/Page.pm
+++ b/lib/VNWeb/VN/Page.pm
@@ -760,7 +760,7 @@ sub tags_ {
WITH RECURSIVE parents (tag, child) AS (
SELECT tag::vndbid, NULL::vndbid FROM (VALUES", sql_join(',', map sql('(',\$_,')'), keys %tags), ") AS x(tag)
UNION
- SELECT tp.parent, tp.id FROM tags_parents tp, parents a WHERE a.tag = tp.id
+ SELECT tp.parent, tp.id FROM tags_parents tp, parents a WHERE a.tag = tp.id AND tp.main
) SELECT * FROM parents WHERE child IS NOT NULL"
);