Skip to main content

max / makenotwork

2.7 KB · 60 lines History Blame Raw
1 -- Per-repo notification lists.
2 --
3 -- Step 6 of wiki [[mnw-mailing-lists]], the last structural piece. Git activity
4 -- rode users.notify_issues, one account-wide bool, so somebody who wanted out
5 -- of one noisy repo had to leave every repo they could see. That is not a
6 -- preference anybody would choose; it is the only one that was on offer.
7 --
8 -- SEMANTICS, unchanged on purpose. Who is ELIGIBLE for an issue email is still
9 -- what it was: the repo owner for a new issue, and the issue's participants for
10 -- a comment. This migration changes only what a person can opt out OF. Making
11 -- the repo list decide eligibility instead would mean commenting once on one
12 -- issue subscribed you to every issue in the repo, which is more mail than
13 -- anybody asked for.
14 --
15 -- So the gate reads "not opted out of this repo" rather than "opted in to it".
16 -- An absent row means nothing has been said, which is what it meant before.
17
18 -- One issues list per existing repo. `releases` waits for something to release:
19 -- an empty list on every repo is a row nobody reads and a toggle nobody wants,
20 -- and adding it later costs one INSERT.
21 INSERT INTO lists (scope, scope_id, kind, title, required, owner_id)
22 SELECT 'repo', r.id, 'issues', r.name || ': issues', FALSE, r.user_id
23 FROM git_repos r
24 ON CONFLICT DO NOTHING;
25
26 -- Give every new repo the same list, for the same reason 187 uses a trigger:
27 -- repos are created by the web handler, the git-over-SSH push path and the
28 -- seed flow, and a creation path that forgets is a repo whose watchers can
29 -- never opt out.
30 CREATE OR REPLACE FUNCTION seed_repo_notification_lists() RETURNS TRIGGER AS $$
31 BEGIN
32 INSERT INTO lists (scope, scope_id, kind, title, required, owner_id)
33 VALUES ('repo', NEW.id, 'issues', NEW.name || ': issues', FALSE, NEW.user_id)
34 ON CONFLICT DO NOTHING;
35 RETURN NEW;
36 END;
37 $$ LANGUAGE plpgsql;
38
39 DROP TRIGGER IF EXISTS trg_seed_repo_notification_lists ON git_repos;
40 CREATE TRIGGER trg_seed_repo_notification_lists
41 AFTER INSERT ON git_repos
42 FOR EACH ROW EXECUTE FUNCTION seed_repo_notification_lists();
43
44 -- A repo rename should not leave the old name on the unsubscribe page, which is
45 -- the one place a subscriber reads it.
46 CREATE OR REPLACE FUNCTION rename_repo_notification_lists() RETURNS TRIGGER AS $$
47 BEGIN
48 IF NEW.name IS DISTINCT FROM OLD.name THEN
49 UPDATE lists SET title = NEW.name || ': issues'
50 WHERE scope = 'repo' AND scope_id = NEW.id AND kind = 'issues';
51 END IF;
52 RETURN NEW;
53 END;
54 $$ LANGUAGE plpgsql;
55
56 DROP TRIGGER IF EXISTS trg_rename_repo_notification_lists ON git_repos;
57 CREATE TRIGGER trg_rename_repo_notification_lists
58 AFTER UPDATE ON git_repos
59 FOR EACH ROW EXECUTE FUNCTION rename_repo_notification_lists();
60