Add an assocations-like "Edges" framework
Summary:
We have a lot of cases where we store object relationships, but it's all kind of messy and custom. Some particular problems:
- We go to great lengths to enforce order stability in Differential revisions, but the implementation is complex and inelegant.
- Some relationships are stored on-object, so we can't pull the inverses easily. For example, Maniphest shows child tasks but not parent tasks.
- I want to add more of these and don't want to continue building custom stuff.
- UIs like the "attach stuff to other stuff" UI need custom branches for each object type.
- Stuff like "allow commits to close tasks" is notrivial because of nonstandard metadata storage.
Provide an association-like "edge" framework to fix these problems. This is nearly identical to associations, with a few differences:
- I put edge metadata in a separate table and don't load it by default, to keep edge rows small and allow large metadata if necessary. The on-edge metadata seemed to get abused a lot at Facebook.
- I put a 'seq' column on the edges to ensure they have an explicit, stable ordering within a source and type.
This isn't actually used anywhere yet, but my first target is attaching commits to tasks for T904.
Test Plan: Made a mock page that used Editor and Query. Verified adding and removing edges, overwriting edges, writing and loading edge data, sequence number generation.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran, 20after4
Differential Revision: https://secure.phabricator.com/D2088
2012-04-05 00:30:21 +02:00
|
|
|
@title Using Edges
|
|
|
|
@group developer
|
|
|
|
|
|
|
|
Guide to the Edges infrastructure.
|
|
|
|
|
|
|
|
= Overview =
|
|
|
|
|
2014-07-10 00:12:48 +02:00
|
|
|
Edges are a generic way of storing a relationship between two objects (like a
|
|
|
|
Task and its attached files). If you are familiar with the Facebook associations
|
|
|
|
framework, Phabricator Edges are substantially similar.
|
Add an assocations-like "Edges" framework
Summary:
We have a lot of cases where we store object relationships, but it's all kind of messy and custom. Some particular problems:
- We go to great lengths to enforce order stability in Differential revisions, but the implementation is complex and inelegant.
- Some relationships are stored on-object, so we can't pull the inverses easily. For example, Maniphest shows child tasks but not parent tasks.
- I want to add more of these and don't want to continue building custom stuff.
- UIs like the "attach stuff to other stuff" UI need custom branches for each object type.
- Stuff like "allow commits to close tasks" is notrivial because of nonstandard metadata storage.
Provide an association-like "edge" framework to fix these problems. This is nearly identical to associations, with a few differences:
- I put edge metadata in a separate table and don't load it by default, to keep edge rows small and allow large metadata if necessary. The on-edge metadata seemed to get abused a lot at Facebook.
- I put a 'seq' column on the edges to ensure they have an explicit, stable ordering within a source and type.
This isn't actually used anywhere yet, but my first target is attaching commits to tasks for T904.
Test Plan: Made a mock page that used Editor and Query. Verified adding and removing edges, overwriting edges, writing and loading edge data, sequence number generation.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran, 20after4
Differential Revision: https://secure.phabricator.com/D2088
2012-04-05 00:30:21 +02:00
|
|
|
|
|
|
|
An edge is defined by a source PHID (the edge origin), a destination PHID
|
|
|
|
(the edge destination) and an edge type (which describes the relationship,
|
|
|
|
like "is subscribed to" or "has attached file").
|
|
|
|
|
|
|
|
Every edge is directional, and stored alongside the source object. Some edges
|
|
|
|
are configured to automatically write an inverse edge, effectively building
|
|
|
|
a bidirectional relationship. The strength of storing relationships like this
|
|
|
|
is that they work when databases are partitioned or sharded.
|
|
|
|
|
|
|
|
= Reading Edges =
|
|
|
|
|
|
|
|
You can load edges with @{class:PhabricatorEdgeQuery}.
|
|
|
|
|
|
|
|
= Writing Edges =
|
|
|
|
|
|
|
|
You can edit edges with @{class:PhabricatorEdgeEditor}.
|
|
|
|
|
|
|
|
= Edges and Lisk =
|
|
|
|
|
|
|
|
@{class:PhabricatorLiskDAO} includes some builtin support for edges.
|