From 373ff7f9d465f35c32b278e6c8dc7d9f015f2d87 Mon Sep 17 00:00:00 2001 From: epriestley Date: Sun, 27 Dec 2015 04:27:58 -0800 Subject: [PATCH] Read materialized project members instead of real members Summary: Ref T10010. This will allow us to find superprojects with `withMemberPHIDs(...)` queries. - Copy all the current real member edges to materialized member edges. - Redirect all reads to look at materialized members. - This table is already kept in sync by earlier work with indexing. Basically, flow is: - Writes (joining, leaving, adding/removing members) write to the real member edge type. - After a project's members change, they're copied to the materialized member edge type for that project and all of its superprojects. - Reads look at materialized members, so "Parent" sees the members of "Child" and "Grandchild" as its own members, but we still have the "real members" edge type to keep track of "natural" or "direct" members. Test Plan: - Ran migration. - Ran unit tests. - Saw the same projects as projects I was a member of. - Added some `var_dump()` stuff to verify the Owners changed. - Used `grep` to look for other readers of this edge type. - Made some project updates. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10010 Differential Revision: https://secure.phabricator.com/D14893 --- .../20151227.proj.01.materialize.sql | 6 +++++ .../owners/storage/PhabricatorOwnersOwner.php | 26 +++++++++---------- .../PhabricatorProjectTransactionEditor.php | 22 +++++++++------- .../project/query/PhabricatorProjectQuery.php | 8 +++--- 4 files changed, 36 insertions(+), 26 deletions(-) create mode 100644 resources/sql/autopatches/20151227.proj.01.materialize.sql diff --git a/resources/sql/autopatches/20151227.proj.01.materialize.sql b/resources/sql/autopatches/20151227.proj.01.materialize.sql new file mode 100644 index 0000000000..ceac969e8f --- /dev/null +++ b/resources/sql/autopatches/20151227.proj.01.materialize.sql @@ -0,0 +1,6 @@ +/* PhabricatorProjectProjectHasMemberEdgeType::EDGECONST = 13 */ +/* PhabricatorProjectMaterializedMemberEdgeType::EDGECONST = 60 */ + +INSERT IGNORE INTO {$NAMESPACE}_project.edge (src, type, dst, dateCreated) + SELECT src, 60, dst, dateCreated FROM {$NAMESPACE}_project.edge + WHERE type = 13; diff --git a/src/applications/owners/storage/PhabricatorOwnersOwner.php b/src/applications/owners/storage/PhabricatorOwnersOwner.php index c3d1aaa605..07d5b59a20 100644 --- a/src/applications/owners/storage/PhabricatorOwnersOwner.php +++ b/src/applications/owners/storage/PhabricatorOwnersOwner.php @@ -40,6 +40,7 @@ final class PhabricatorOwnersOwner extends PhabricatorOwnersDAO { if (!$package_ids) { return array(); } + $owners = id(new PhabricatorOwnersOwner())->loadAllWhere( 'packageID IN (%Ls)', $package_ids); @@ -50,20 +51,19 @@ final class PhabricatorOwnersOwner extends PhabricatorOwnersDAO { PhabricatorPeopleUserPHIDType::TYPECONST, array()); - $users_in_project_phids = array(); - $project_phids = idx( - $all_phids, - PhabricatorProjectProjectPHIDType::TYPECONST); - if ($project_phids) { - $query = id(new PhabricatorEdgeQuery()) - ->withSourcePHIDs($project_phids) - ->withEdgeTypes(array( - PhabricatorProjectProjectHasMemberEdgeType::EDGECONST, - )); - $query->execute(); - $users_in_project_phids = $query->getDestinationPHIDs(); + if ($user_phids) { + $projects = id(new PhabricatorProjectQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withMemberPHIDs($user_phids) + ->withIsMilestone(false) + ->execute(); + $project_phids = mpull($projects, 'getPHID'); + } else { + $project_phids = array(); } - return array_unique(array_merge($users_in_project_phids, $user_phids)); + $all_phids = array_fuse($user_phids) + array_fuse($project_phids); + + return array_values($all_phids); } } diff --git a/src/applications/project/editor/PhabricatorProjectTransactionEditor.php b/src/applications/project/editor/PhabricatorProjectTransactionEditor.php index 7626729b8c..72ddc1470c 100644 --- a/src/applications/project/editor/PhabricatorProjectTransactionEditor.php +++ b/src/applications/project/editor/PhabricatorProjectTransactionEditor.php @@ -509,12 +509,13 @@ final class PhabricatorProjectTransactionEditor } protected function willPublish(PhabricatorLiskDAO $object, array $xactions) { - $member_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( - $object->getPHID(), - PhabricatorProjectProjectHasMemberEdgeType::EDGECONST); - $object->attachMemberPHIDs($member_phids); - - return $object; + // NOTE: We're using the omnipotent user here because the original actor + // may no longer have permission to view the object. + return id(new PhabricatorProjectQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withPHIDs(array($object->getPHID())) + ->needMembers(true) + ->executeOne(); } protected function shouldSendMail( @@ -719,9 +720,12 @@ final class PhabricatorProjectTransactionEditor $object_phid = $object->getPHID(); if ($object_phid) { - $members = PhabricatorEdgeQuery::loadDestinationPHIDs( - $object_phid, - PhabricatorProjectProjectHasMemberEdgeType::EDGECONST); + $project = id(new PhabricatorProjectQuery()) + ->setViewer($this->getActor()) + ->withPHIDs(array($object_phid)) + ->needMembers(true) + ->executeOne(); + $members = $project->getMemberPHIDs(); } else { $members = array(); } diff --git a/src/applications/project/query/PhabricatorProjectQuery.php b/src/applications/project/query/PhabricatorProjectQuery.php index 11a789ab31..bc14e93a88 100644 --- a/src/applications/project/query/PhabricatorProjectQuery.php +++ b/src/applications/project/query/PhabricatorProjectQuery.php @@ -201,11 +201,11 @@ final class PhabricatorProjectQuery $viewer_phid = $this->getViewer()->getPHID(); - $member_type = PhabricatorProjectProjectHasMemberEdgeType::EDGECONST; + $material_type = PhabricatorProjectMaterializedMemberEdgeType::EDGECONST; $watcher_type = PhabricatorObjectHasWatcherEdgeType::EDGECONST; $types = array(); - $types[] = $member_type; + $types[] = $material_type; if ($this->needWatchers) { $types[] = $watcher_type; } @@ -255,7 +255,7 @@ final class PhabricatorProjectQuery if ($any_edges) { $member_phids = $edge_query->getDestinationPHIDs( $source_phids, - array($member_type)); + array($material_type)); } else { $member_phids = array(); } @@ -488,7 +488,7 @@ final class PhabricatorProjectQuery $conn, 'JOIN %T e ON e.src = p.phid AND e.type = %d', PhabricatorEdgeConfig::TABLE_NAME_EDGE, - PhabricatorProjectProjectHasMemberEdgeType::EDGECONST); + PhabricatorProjectMaterializedMemberEdgeType::EDGECONST); } if ($this->slugs !== null) {