max / makenotwork
| 1 | -- Per-user annotation repositories. |
| 2 | -- |
| 3 | -- An annotation repo holds nothing but refs/notes/*, addressing commits in |
| 4 | -- other people's repositories by SHA. Hashes are global, so a note stored here |
| 5 | -- annotates a commit this repository has never contained. That is what |
| 6 | -- "annotate without cloning or forking" means concretely, and it is why the |
| 7 | -- annotation lives in a repository of the user's own rather than in a reserved |
| 8 | -- namespace inside somebody else's graph or in a Postgres table. |
| 9 | -- |
| 10 | -- Wiki: mnw-server-git-notes, "the load-bearing rule". |
| 11 | |
| 12 | git_repos ADD COLUMN IF NOT EXISTS kind VARCHAR(16) NOT NULL DEFAULT 'source'; |
| 13 | |
| 14 | -- One annotation repository per account. Partial, so ordinary repos are |
| 15 | -- unaffected and the row cannot be duplicated by a concurrent first write. |
| 16 | NOT EXISTS idx_git_repos_one_annotation_repo |
| 17 | ON git_repos (user_id) WHERE kind = 'annotations'; |
| 18 | |
| 19 | -- 188 gives every new repository an issues notification list. An annotation |
| 20 | -- repository is private to one person and carries no issues, so the list would |
| 21 | -- be a row nobody reads and a toggle nobody wants. |
| 22 | RETURNS TRIGGER AS $$ |
| 23 | BEGIN |
| 24 | IF NEW.kind <> 'source' THEN |
| 25 | RETURN NEW; |
| 26 | END IF; |
| 27 | INSERT INTO lists (scope, scope_id, kind, title, required, owner_id) |
| 28 | VALUES ('repo', NEW.id, 'issues', NEW.name || ': issues', FALSE, NEW.user_id) |
| 29 | ON CONFLICT DO NOTHING; |
| 30 | RETURN NEW; |
| 31 | END; |
| 32 | $$ LANGUAGE plpgsql; |
| 33 |