Badges can't take additional metadata individually, so in order to give each badge basic information (date given, giver, etc) we need to store this data in another table / object.
Revisions and Commits
|Resolved||lpriestley||T8940 Annotate badges with awarder, date|
|Resolved||lpriestley||T8996 Move Badge awards to be an actual object, not an edge|
Feel free to ignore me if you don't have the time to explain, but what's the difference between an edge and an object. More specifically, why do we want badges to be objects rather than edges?
(I'm not questioning the validity of this task, just genuinely interested as a contributor)
Edges have a data field, but you can't put keys on any of the data since it's just stored as a JSON blob. For example, it would be possible to store an awarderPHID in the data, but then as soon as you want to show a view of "all badges given by epriestley to other users" you can't query by it (since you'd have to load every edge, then deserialize all their JSON data, then look through it).
Edges have a data field primarily because the similar abstraction at Facebook had a data field, but it hasn't been as useful in Phabricator as it was at Facebook, primarily because we don't do sharding/partitioning within apps can use tables a lot more easily than Facebook can.
In practice, I think only one thing uses the data field (Differential reviewers) and that use feels really clunky. My tentative plan is to move that to a separate table eventually and get rid of the data field on edges.
(Edges are kind of nice because you get so much Transaction support for free nowadays, but the actual cost to add support for an edge-like table is usually pretty small.)
I don't remember the last edge -> object conversion we did, I don't think we've done one for a while.
The actual migration is pretty straightforward (iterate over the old table and just do inserts into the new table), but I'll yell if I remember something relevant.
We want to be able to store metadata about badge awards (like who awarded a badge, when, why, a little commemorative note, etc) but currently can not because they use a very simple storage mechanism (edges). For example, see T8940.
- Create a new BadgeAward table or something.
- Convert all the code which deals with badge edges to read/write that table instead of the edge table.
- Migrate all the existing data from edges.
- PhabricatorTokenGiven might be a useful example.
If you aren't sure about the migration, do everything else -- I can do the migration easily if you get reads/writes working against a different datasource.