Mirror of the Rel4tion website/wiki source, view at <http://rel4tion.org>
Clone
HTTPS:
git clone https://vervis.peers.community/repos/yEzqv
SSH:
git clone USERNAME@vervis.peers.community:yEzqv
Branches
Tags
28.mdwn
[[!template id=ticket class=task assigned=fr33domlover done=yes]]
[[!meta title=“Comment system”]]
Issue
Plan and implement a generic comment system which allows commenting on various objects, a comment tree, potentially integration with email and other systems in the future.
Progress
Model
I already made plans for a comment system in my ontology and diagram work: [[/projects/kiwi/data/discussion.dia]]. In addition to the model considerations, I also now need to take into account the limitations of relational databases, since I use SQL. At least until I move to some sort of triplestore.
What should people be able to comment on? GitLab has these:
- Commits
- Issues
- Merge requests
- Snippets
I’m not sure it’s a good idea to enable comments for commits, so for now, the only object that can be commented on is: Ticket. Each ticket can have a tree of comments.
Hmmm I found a problem. How does the link between objects and their comments work? Each object can have any number of top-level comments. If we still point from an object to its comments, at least we can have a single Comment type and database table. But if we make comments point to their target object, we’ll be able to maintain a foreign key constraint only if each object type has its own table for comments.
We can still have a single comment table with all the fields, and each object type has a table with 3 records:
- id, like any table
- comment foreign key
- object foreign key, e.g. a ticket
Another option is to have a top comment for each ticket. That comment is fake and isn’t really shown in the UI at all, and can’t be queried from the outside in any way. The ugliness of that approach is that comment filtering will need to ignore these dummy comments, and all ways to do that are ugly. A variation of this approach is to have a separate table for them, but I’m not sure it’s good. You still need to have a table which links between comment roots to the comments under them. The only thing gained by that is that:
- You have a single comment-under-root table instead of one per object
- You have an extra comment root table which contains just an
id
field
Abstractions can get ugly easily. Perhaps it’s better to have a comment table per object. It’s still O(1)
because even in the worst case, we’ll have 3-4 object types which can be commented on.
Also note that in order to make it possible to select all the comments under a given ticket, each comment must point not only to its optional parent comment, but also to the object being commented on. This allows to get all the object’s comments in O(1)
queries. This is a limitation of SQL which I need to live with for now.
Considering the above, we can have a nice compact model like this:
- There are 2 tables: Ticket, comment
- Tickets don’t point to comments at all
- A comment has content, author, creation time and so on
- A comment points to an optional parent comment
- A comment points to a ticket
The top-level comments of a ticket are the ones that point to it but don’t have a parent comment.
The problem is that the comment details are in a ticket-specific table, which means duplication if we have more objects which can have comments. Instead we can do this:
- There are 3 tables: Ticket, message and comment
- Tickets don’t point to comments at all
- A message has content, author, creation time and so on
- A comment points to a message
- A comment points to an optional parent comment
- A comment points to a ticket
Then we have a single message table in the database, and one comment table per object type.
There’s also room for one variation: Instead of having comments point to parent comments, we can make messages point to parent messages. In that case, a comment has just two fields: id
like any table, and a ticket foreign key.
Now let’s see how GitLab does it: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/db/schema.rb. Hmmmm it seems to have a single “notes” table. Each note has a string specifying the type of the object being commented, and an integer specifying the ID of that object.
Now, how did Snowdrift do it? Well, it had a dummy Discussion table, much like the “comment root” idea I mentioned above. Then wiki pages, projects, tickets and so on can point to their discussion ID.
DONE.
User Interface
Basics done.
Result
Basics done.