summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elm/User/Edit.elm70
-rw-r--r--lib/VNWeb/Chars/Page.pm49
-rw-r--r--lib/VNWeb/Chars/VNTab.pm1
-rw-r--r--lib/VNWeb/User/Edit.pm13
-rw-r--r--lib/VNWeb/VN/Page.pm18
-rw-r--r--sql/perms.sql1
-rw-r--r--sql/schema.sql9
-rw-r--r--sql/tableattrs.sql2
-rw-r--r--util/updates/2022-08-30-tag-trait-prefs.sql (renamed from util/updates/wip-tag-prefs.sql)11
9 files changed, 140 insertions, 34 deletions
diff --git a/elm/User/Edit.elm b/elm/User/Edit.elm
index 5f32f588..d44f64cd 100644
--- a/elm/User/Edit.elm
+++ b/elm/User/Edit.elm
@@ -55,6 +55,7 @@ type alias Model =
, mailConfirm : Bool
, traitSearch : A.Model GApi.ApiTraitResult
, tagpSearch : A.Model GApi.ApiTagResult
+ , traitpSearch: A.Model GApi.ApiTraitResult
}
@@ -75,6 +76,7 @@ init d =
, mailConfirm = False
, traitSearch = A.init ""
, tagpSearch = A.init ""
+ , traitpSearch= A.init ""
}
@@ -130,6 +132,9 @@ type PrefMsg
| TagPSpoil Int Int
| TagPChilds Int Bool
| TagPDel Int
+ | TraitPSpoil Int Int
+ | TraitPChilds Int Bool
+ | TraitPDel Int
type PassMsg
= CPass Bool
@@ -147,6 +152,7 @@ type Msg
| Pass PassMsg
| TraitSearch (A.Msg GApi.ApiTraitResult)
| TagPrefSearch (A.Msg GApi.ApiTagResult)
+ | TraitPrefSearch (A.Msg GApi.ApiTraitResult)
| Submit
| Submitted GApi.Response
@@ -157,6 +163,9 @@ traitConfig = { wrap = TraitSearch, id = "traitadd", source = A.traitSource }
tagpConfig : A.Config Msg GApi.ApiTagResult
tagpConfig = { wrap = TagPrefSearch, id = "tagpadd", source = A.tagSource }
+traitpConfig : A.Config Msg GApi.ApiTraitResult
+traitpConfig = { wrap = TraitPrefSearch, id = "traitpadd", source = A.traitSource }
+
updateAdmin : AdminMsg -> GUE.SendAdmin -> GUE.SendAdmin
updateAdmin msg model =
@@ -244,6 +253,9 @@ updatePrefs msg model =
TagPSpoil i s -> { model | tagprefs = modidx i (\e -> { e | spoil = s }) model.tagprefs }
TagPChilds i b-> { model | tagprefs = modidx i (\e -> { e | childs = b }) model.tagprefs }
TagPDel idx -> { model | tagprefs = delidx idx model.tagprefs }
+ TraitPSpoil i s -> { model | traitprefs = modidx i (\e -> { e | spoil = s }) model.traitprefs }
+ TraitPChilds i b-> { model | traitprefs = modidx i (\e -> { e | childs = b }) model.traitprefs }
+ TraitPDel idx -> { model | traitprefs = delidx idx model.traitprefs }
updatePass : PassMsg -> PassData -> PassData
updatePass msg model =
@@ -297,10 +309,21 @@ update msg model =
if t.hidden || List.any (\l -> l.tid == t.id) p.tagprefs
then ({ model | tagpSearch = A.clear nm "" }, c)
else
- let np = { p | tagprefs = p.tagprefs ++ [{ tid = t.id, name = t.name, spoil = 0, childs = False }] }
+ let np = { p | tagprefs = p.tagprefs ++ [{ tid = t.id, name = t.name, spoil = 0, childs = True }] }
in ({ model | saved = False, tagpSearch = A.clear nm "", prefs = Just np }, c)
_ -> ({ model | tagpSearch = nm }, c)
+ TraitPrefSearch m ->
+ let (nm, c, res) = A.update traitpConfig m model.traitpSearch
+ in case (res, model.prefs) of
+ (Just t, Just p) ->
+ if t.hidden || List.any (\l -> l.tid == t.id) p.traitprefs
+ then ({ model | traitpSearch = A.clear nm "" }, c)
+ else
+ let np = { p | traitprefs = p.traitprefs ++ [{ tid = t.id, name = t.name, group = t.group_name, spoil = 0, childs = True }] }
+ in ({ model | saved = False, traitpSearch = A.clear nm "", prefs = Just np }, c)
+ _ -> ({ model | traitpSearch = nm }, c)
+
Submit ->
if Maybe.withDefault False (Maybe.map (\p -> p.cpass && p.pass1 /= p.pass2) model.pass)
then ({ model | passNeq = True }, Cmd.none )
@@ -468,17 +491,27 @@ view model =
, formField "css::Custom CSS" [ inputTextArea "css" m.customcss (Prefs << Css) ([ rows 5, cols 60 ] ++ GUE.valPrefsCustomcss) ]
]
- ttprefsform m =
- [ formField "Tags"
+ ttspoil =
+ [ (-1, "Always show & highlight")
+ , (0, "Always show")
+ , (1, "Force minor spoiler")
+ , (2, "Force major spoiler")
+ , (3, "Always hide") ]
+
+ ttprefsform m = div []
+ [ p [ style "margin" "0 20px 20px 20px", style "max-width" "800px" ]
+ [ text "Here you can set display preferences for individual tags & traits."
+ , text " This feature can be used to completely hide tags/traits you'd rather not see at all"
+ , text " or you'd like to highlight as a possible trigger warning instead."
+ , br [] []
+ , text "These settings are applied on visual novel and character pages, other listings on the site are unaffected."
+ ]
+ , h2 [] [ text "Tags" ]
+ , div [ style "margin" "5px 0 20px 20px" ]
[ if List.isEmpty m.tagprefs then text ""
else table [] <| List.indexedMap (\i t -> tr []
[ td [] [ a [ href <| "/" ++ t.tid ] [ text t.name ] ]
- , td [] [ inputSelect "" t.spoil (Prefs << TagPSpoil i) [ style "width" "200px" ]
- [ (-1, "Always show & highlight")
- , (0, "Always show")
- , (1, "Force minor spoiler")
- , (2, "Force major spoiler")
- , (3, "Always hide") ] ]
+ , td [] [ inputSelect "" t.spoil (Prefs << TagPSpoil i) [ style "width" "200px" ] ttspoil ]
, td [] [ label [] [ inputCheck "" t.childs (Prefs << TagPChilds i), text " also apply to child tags" ] ]
, td [] [ inputButton "remove" (Prefs (TagPDel i)) [] ]
]
@@ -486,6 +519,21 @@ view model =
, if List.length m.traits >= 500 then text ""
else A.view tagpConfig model.tagpSearch [placeholder "Add tag..."]
]
+ , h2 [] [ text "Traits" ]
+ , div [ style "margin" "5px 0 20px 20px" ]
+ [ if List.isEmpty m.traitprefs then text ""
+ else table [] <| List.indexedMap (\i t -> tr []
+ [ td []
+ [ Maybe.withDefault (text "") <| Maybe.map (\g -> b [ class "grayedout" ] [ text <| g ++ " / " ]) t.group
+ , a [ href <| "/" ++ t.tid ] [ text t.name ] ]
+ , td [] [ inputSelect "" t.spoil (Prefs << TraitPSpoil i) [ style "width" "200px" ] ttspoil ]
+ , td [] [ label [] [ inputCheck "" t.childs (Prefs << TraitPChilds i), text " also apply to child traits" ] ]
+ , td [] [ inputButton "remove" (Prefs (TraitPDel i)) [] ]
+ ]
+ ) m.traitprefs
+ , if List.length m.traits >= 500 then text ""
+ else A.view traitpConfig model.traitpSearch [placeholder "Add trait..."]
+ ]
]
in form_ "mainform" Submit (model.state == Api.Loading)
@@ -528,9 +576,7 @@ view model =
, table [ class "formtable" ] <| Maybe.withDefault [] (Maybe.map prefsform model.prefs)
]
, div [ class "mainbox", classList [("hidden", model.tab /= TTPref)] ]
- [ h1 [] [ text "Tags & traits" ]
- , table [ class "formtable" ] <| Maybe.withDefault [] (Maybe.map ttprefsform model.prefs)
- ]
+ [ h1 [] [ text "Tags & traits" ], Maybe.withDefault (text "") (Maybe.map ttprefsform model.prefs) ]
, div [ class "mainbox" ]
[ fieldset [ class "submit" ]
[ submitButton "Submit" model.state (not model.passNeq)
diff --git a/lib/VNWeb/Chars/Page.pm b/lib/VNWeb/Chars/Page.pm
index 4829fe54..2c8dc24c 100644
--- a/lib/VNWeb/Chars/Page.pm
+++ b/lib/VNWeb/Chars/Page.pm
@@ -16,6 +16,18 @@ sub enrich_seiyuu {
}, @chars;
}
+sub sql_trait_overrides {
+ sql '(
+ WITH RECURSIVE trait_overrides (tid, spoil, childs, lvl) AS (
+ SELECT tid, spoil, childs, 0 FROM users_prefs_traits WHERE id =', \auth->uid, '
+ UNION ALL
+ SELECT tp.id, x.spoil, true, lvl+1
+ FROM trait_overrides x
+ JOIN traits_parents tp ON tp.parent = x.tid
+ WHERE x.childs
+ ) SELECT DISTINCT ON(tid) tid, spoil FROM trait_overrides ORDER BY tid, lvl
+ )';
+}
sub enrich_item {
my($c) = @_;
@@ -23,9 +35,17 @@ sub enrich_item {
enrich_image_obj image => $c;
enrich_merge vid => 'SELECT id AS vid, title, alttitle, c_released AS vn_released FROM vnt WHERE id IN', $c->{vns};
enrich_merge rid => 'SELECT id AS rid, title AS rtitle, original AS roriginal, released AS rel_released FROM releases WHERE id IN', grep $_->{rid}, $c->{vns}->@*;
- enrich_merge tid =>
- 'SELECT t.id AS tid, t.name, t.hidden, t.locked, t.applicable, t.sexual, coalesce(g.id, t.id) AS group, coalesce(g.name, t.name) AS groupname, coalesce(g.order,0) AS order
- FROM traits t LEFT JOIN traits g ON t.group = g.id WHERE t.id IN', $c->{traits};
+
+ # Even with trait overrides, we'll want to see the raw data in revision diffs,
+ # so fetch the raw spoil as a separate column and do filtering/processing later.
+ enrich_merge tid => sub { sql '
+ SELECT t.id AS tid, t.name, t.hidden, t.locked, t.applicable, t.sexual, x.spoil AS override
+ , coalesce(g.id, t.id) AS group, coalesce(g.name, t.name) AS groupname, coalesce(g.order,0) AS order
+ FROM traits t
+ LEFT JOIN traits g ON t.group = g.id
+ LEFT JOIN', sql_trait_overrides(), 'x ON x.tid = t.id
+ WHERE t.id IN', $_
+ }, $c->{traits};
$c->{vns} = [ sort { $a->{vn_released} <=> $b->{vn_released} || ($a->{rel_released}||0) <=> ($b->{rel_released}||0)
|| $a->{title} cmp $b->{title} || idcmp($a->{vid}, $b->{vid}) || idcmp($a->{rid}||'r999999', $b->{rid}||'r999999') } $c->{vns}->@* ];
@@ -53,12 +73,14 @@ sub fetch_chars {
}, $l;
enrich traits => id => id => sub { sql '
- SELECT ct.id, ct.tid, ct.spoil, t.name, t.hidden, t.locked, t.sexual, coalesce(g.id, t.id) AS group, coalesce(g.name, t.name) AS groupname, coalesce(g.order,0) AS order
- FROM chars_traits ct
- JOIN traits t ON t.id = ct.tid
- LEFT JOIN traits g ON t.group = g.id
- WHERE ct.id IN', $_, '
- ORDER BY g.order NULLS FIRST, coalesce(g.name, t.name), t.name'
+ SELECT ct.id, ct.tid, COALESCE(x.spoil, ct.spoil) AS spoil, t.name, t.hidden, t.locked, t.sexual
+ , coalesce(g.id, t.id) AS group, coalesce(g.name, t.name) AS groupname, coalesce(g.order,0) AS order
+ FROM chars_traits ct
+ JOIN traits t ON t.id = ct.tid
+ LEFT JOIN traits g ON t.group = g.id
+ LEFT JOIN', sql_trait_overrides(), 'x ON x.tid = ct.tid
+ WHERE x.spoil IS DISTINCT FROM 1+1+1 AND ct.id IN', $_, '
+ ORDER BY g.order NULLS FIRST, coalesce(g.name, t.name), t.name'
}, $l;
enrich_seiyuu $vid, $l;
@@ -160,13 +182,16 @@ sub chartable_ {
} if defined $c->{age};
my @groups;
- for(grep !$_->{hidden} && $_->{spoil} <= $view->{spoilers} && (!$_->{sexual} || $view->{traits_sexual}), $c->{traits}->@*) {
+ for(grep !$_->{hidden} && ($_->{override}//$_->{spoil}) <= $view->{spoilers} && (!$_->{sexual} || $view->{traits_sexual}), $c->{traits}->@*) {
push @groups, $_ if !@groups || $groups[$#groups]{group} ne $_->{group};
push $groups[$#groups]{traits}->@*, $_;
}
tr_ class => "trait_group_$_->{group}", sub {
td_ class => 'key', sub { a_ href => "/$_->{group}", $_->{groupname} };
- td_ sub { join_ ', ', sub { a_ href => "/$_->{tid}", $_->{name}; spoil_ $_->{spoil} }, $_->{traits}->@* };
+ td_ sub { join_ ', ', sub {
+ my $spoil = $_->{override}//$_->{spoil};
+ a_ href => "/$_->{tid}", class => $spoil==-1?'standout':undef, $_->{name}; spoil_ $spoil
+ }, $_->{traits}->@* };
} for @groups;
my @visvns = grep $_->{spoil} <= $view->{spoilers}, $c->{vns}->@*;
@@ -246,7 +271,7 @@ TUWF::get qr{/$RE{crev}} => sub {
my $max_spoil = max(
$inst_maxspoil||0,
- (map $_->{spoil}, grep !$_->{hidden}, $c->{traits}->@*),
+ (map $_->{override}//$_->{spoil}, grep !$_->{hidden} && !(($_->{override}//0) == 3), $c->{traits}->@*),
(map $_->{spoil}, $c->{vns}->@*),
defined $c->{spoil_gender} ? 2 : 0,
$c->{desc} =~ /\[spoiler\]/i ? 2 : 0, # crude
diff --git a/lib/VNWeb/Chars/VNTab.pm b/lib/VNWeb/Chars/VNTab.pm
index 3c6fba75..4b4a07d0 100644
--- a/lib/VNWeb/Chars/VNTab.pm
+++ b/lib/VNWeb/Chars/VNTab.pm
@@ -21,6 +21,7 @@ sub chars_ {
my sub opts_ {
p_ class => 'mainopts', sub {
+ debug_ $chars;
if($max_spoil) {
a_ mkclass(checked => $view->{spoilers} == 0), href => '?view='.viewset(spoilers=>0,traits_sexual=>$view->{traits_sexual}).'#chars', 'Hide spoilers';
a_ mkclass(checked => $view->{spoilers} == 1), href => '?view='.viewset(spoilers=>1,traits_sexual=>$view->{traits_sexual}).'#chars', 'Show minor spoilers';
diff --git a/lib/VNWeb/User/Edit.pm b/lib/VNWeb/User/Edit.pm
index 41353615..e52758ff 100644
--- a/lib/VNWeb/User/Edit.pm
+++ b/lib/VNWeb/User/Edit.pm
@@ -62,12 +62,19 @@ my $FORM = {
title_langs => { langpref => 1 },
alttitle_langs => { langpref => 1 },
- tagprefs => { sort_keys => 'tag', maxlength => 500, aoh => {
+ tagprefs => { sort_keys => 'tid', maxlength => 500, aoh => {
tid => { vndbid => 'g' },
spoil => { int => 1, range => [ -1, 3 ] },
childs => { anybool => 1 },
name => {},
} },
+ traitprefs => { sort_keys => 'tid', maxlength => 500, aoh => {
+ tid => { vndbid => 'i' },
+ spoil => { int => 1, range => [ -1, 3 ] },
+ childs => { anybool => 1 },
+ name => {},
+ group => { required => 0 },
+ } },
# Supporter options
nodistract_noads => { anybool => 1 },
@@ -120,6 +127,7 @@ TUWF::get qr{/$RE{uid}/edit}, sub {
$u->{prefs}{alttitle_langs} = langpref_parse($u->{prefs}{alttitle_langs}) // $DEFAULT_ALTTITLE_LANGS;
$u->{prefs}{traits} = tuwf->dbAlli('SELECT u.tid, t.name, g.name AS "group" FROM users_traits u JOIN traits t ON t.id = u.tid LEFT JOIN traits g ON g.id = t.group WHERE u.id =', \$u->{id}, 'ORDER BY g.order, t.name');
$u->{prefs}{tagprefs} = tuwf->dbAlli('SELECT u.tid, u.spoil, u.childs, t.name FROM users_prefs_tags u JOIN tags t ON t.id = u.tid WHERE u.id =', \$u->{id}, 'ORDER BY t.name');
+ $u->{prefs}{traitprefs} = tuwf->dbAlli('SELECT u.tid, u.spoil, u.childs, t.name, g.name as "group" FROM users_prefs_traits u JOIN traits t ON t.id = u.tid LEFT JOIN traits g ON g.id = t.group WHERE u.id =', \$u->{id}, 'ORDER BY g.order, t.name');
}
$u->{admin} = auth->permDbmod || auth->permUsermod || auth->permTagmod || auth->permBoardmod ?
@@ -172,6 +180,9 @@ elm_api UserEdit => $FORM_OUT, $FORM_IN, sub {
tuwf->dbExeci('DELETE FROM users_prefs_tags WHERE id =', \$data->{id});
tuwf->dbExeci('INSERT INTO users_prefs_tags', { id => $data->{id}, tid => $_->{tid}, spoil => $_->{spoil}, childs => $_->{childs} }) for $p->{tagprefs}->@*;
+
+ tuwf->dbExeci('DELETE FROM users_prefs_traits WHERE id =', \$data->{id});
+ tuwf->dbExeci('INSERT INTO users_prefs_traits', { id => $data->{id}, tid => $_->{tid}, spoil => $_->{spoil}, childs => $_->{childs} }) for $p->{traitprefs}->@*;
}
if(auth->permUsermod) {
diff --git a/lib/VNWeb/VN/Page.pm b/lib/VNWeb/VN/Page.pm
index 68b31c54..ec54dbe7 100644
--- a/lib/VNWeb/VN/Page.pm
+++ b/lib/VNWeb/VN/Page.pm
@@ -47,19 +47,19 @@ sub enrich_vn {
WHERE tv.vid =', \$v->{id}, '
ORDER BY rating DESC, t.name'
) : tuwf->dbAlli('
- WITH RECURSIVE tag_prefs (tid, spoil, childs) AS (
- SELECT tid, spoil, childs FROM users_prefs_tags WHERE id =', \auth->uid, '
- ), tag_overrides (tid, spoil, childs) AS (
- SELECT tid, spoil, childs FROM tag_prefs
+ WITH RECURSIVE tag_overrides (tid, spoil, childs, lvl) AS (
+ SELECT tid, spoil, childs, 0 FROM users_prefs_tags WHERE id =', \auth->uid, '
UNION ALL
- SELECT tp.id, x.spoil, true
+ SELECT tp.id, x.spoil, true, lvl+1
FROM tag_overrides x
- JOIN tags_parents tp ON tp.parent = x.tid AND tp.main
- WHERE x.childs AND NOT EXISTS(SELECT 1 FROM tag_prefs y WHERE y.tid = tp.id)
+ JOIN tags_parents tp ON tp.parent = x.tid
+ WHERE x.childs
+ ), tag_overrides_grouped (tid, spoil) AS (
+ SELECT DISTINCT ON(tid) tid, spoil FROM tag_overrides ORDER BY tid, lvl
) SELECT t.id, t.name, t.cat, tv.rating, COALESCE(x.spoil, tv.spoiler) AS spoiler, tv.lie, x.tid IS NOT NULL AS override
FROM tags t
JOIN tags_vn_direct tv ON t.id = tv.tag
- LEFT JOIN tag_overrides x ON x.tid = tv.tag
+ LEFT JOIN tag_overrides_grouped x ON x.tid = tv.tag
WHERE tv.vid =', \$v->{id}, 'AND x.spoil IS DISTINCT FROM 1+1+1
ORDER BY rating DESC, t.name'
);
@@ -923,7 +923,7 @@ sub tags_ {
standout => $t->{spoiler} == -1,
lie => $view->{spoilers} > 1 && $t->{lie},
parent => !$t->{rating}), $t->{name};
- spoil_ max 0, $t->{spoiler};
+ spoil_ $t->{spoiler};
} if $lvl;
if($t->{childs}) {
diff --git a/sql/perms.sql b/sql/perms.sql
index 2a09c83a..f13e9d54 100644
--- a/sql/perms.sql
+++ b/sql/perms.sql
@@ -83,6 +83,7 @@ GRANT SELECT, INSERT, UPDATE, DELETE ON ulist_vns_labels TO vndb_site;
GRANT SELECT, INSERT, UPDATE ON users TO vndb_site;
GRANT SELECT, INSERT, UPDATE ON users_prefs TO vndb_site;
GRANT SELECT, INSERT, UPDATE, DELETE ON users_prefs_tags TO vndb_site;
+GRANT SELECT, INSERT, UPDATE, DELETE ON users_prefs_traits TO vndb_site;
GRANT SELECT (id, perm_usermod), INSERT (id, mail, ip) ON users_shadow TO vndb_site;
GRANT SELECT, INSERT ON users_username_hist TO vndb_site;
GRANT SELECT, INSERT, UPDATE, DELETE ON users_traits TO vndb_site;
diff --git a/sql/schema.sql b/sql/schema.sql
index 8f9cc30f..47cda09b 100644
--- a/sql/schema.sql
+++ b/sql/schema.sql
@@ -1107,6 +1107,15 @@ CREATE TABLE users_prefs_tags (
PRIMARY KEY(id, tid)
);
+-- users_prefs_traits
+CREATE TABLE users_prefs_traits (
+ id vndbid NOT NULL,
+ tid vndbid NOT NULL,
+ spoil smallint NOT NULL,
+ childs boolean NOT NULL,
+ PRIMARY KEY(id, tid)
+);
+
-- Additional fields for the 'users' table, but with some protected columns.
-- (Separated from the users table to simplify permission management)
CREATE TABLE users_shadow (
diff --git a/sql/tableattrs.sql b/sql/tableattrs.sql
index 794d0c55..a94fed5f 100644
--- a/sql/tableattrs.sql
+++ b/sql/tableattrs.sql
@@ -144,6 +144,8 @@ ALTER TABLE ulist_vns_labels ADD CONSTRAINT ulist_vns_labels_uid_vid_fke
ALTER TABLE users_prefs ADD CONSTRAINT users_prefs_id_fkey FOREIGN KEY (id) REFERENCES users (id) ON DELETE CASCADE;
ALTER TABLE users_prefs_tags ADD CONSTRAINT users_prefs_tags_id_fkey FOREIGN KEY (id) REFERENCES users (id) ON DELETE CASCADE;
ALTER TABLE users_prefs_tags ADD CONSTRAINT users_prefs_tags_tag_fkey FOREIGN KEY (tag) REFERENCES tags (id) ON DELETE CASCADE;
+ALTER TABLE users_prefs_traits ADD CONSTRAINT users_prefs_traits_id_fkey FOREIGN KEY (id) REFERENCES users (id) ON DELETE CASCADE;
+ALTER TABLE users_prefs_traits ADD CONSTRAINT users_prefs_traits_tid_fkey FOREIGN KEY (tid) REFERENCES traits (id) ON DELETE CASCADE;
ALTER TABLE users_shadow ADD CONSTRAINT users_shadow_id_fkey FOREIGN KEY (id) REFERENCES users (id) ON DELETE CASCADE;
ALTER TABLE users_traits ADD CONSTRAINT users_traits_id_fkey FOREIGN KEY (id) REFERENCES users (id) ON DELETE CASCADE;
ALTER TABLE users_traits ADD CONSTRAINT users_traits_tid_fkey FOREIGN KEY (tid) REFERENCES traits (id);
diff --git a/util/updates/wip-tag-prefs.sql b/util/updates/2022-08-30-tag-trait-prefs.sql
index c5ee7312..db2bec02 100644
--- a/util/updates/wip-tag-prefs.sql
+++ b/util/updates/2022-08-30-tag-trait-prefs.sql
@@ -9,4 +9,15 @@ CREATE TABLE users_prefs_tags (
ALTER TABLE users_prefs_tags ADD CONSTRAINT users_prefs_tags_id_fkey FOREIGN KEY (id) REFERENCES users (id) ON DELETE CASCADE;
ALTER TABLE users_prefs_tags ADD CONSTRAINT users_prefs_tags_tid_fkey FOREIGN KEY (tid) REFERENCES tags (id) ON DELETE CASCADE;
+CREATE TABLE users_prefs_traits (
+ id vndbid NOT NULL,
+ tid vndbid NOT NULL,
+ spoil smallint NOT NULL,
+ childs boolean NOT NULL,
+ PRIMARY KEY(id, tid)
+);
+
+ALTER TABLE users_prefs_traits ADD CONSTRAINT users_prefs_traits_id_fkey FOREIGN KEY (id) REFERENCES users (id) ON DELETE CASCADE;
+ALTER TABLE users_prefs_traits ADD CONSTRAINT users_prefs_traits_tid_fkey FOREIGN KEY (tid) REFERENCES traits (id) ON DELETE CASCADE;
+
\i sql/perms.sql