private function loadRevisions($phid) { $table = new DifferentialRevision(); $conn_r = $table->establishConnection('r'); $rows = queryfx_all($conn_r, 'SELECT revisions.* FROM %T revisions ' . 'JOIN %T comments ON comments.revisionID = revisions.id ' . 'JOIN (' . ' SELECT revisionID FROM %T WHERE objectPHID = %s ' . ' UNION ALL ' . ' SELECT id from differential_revision WHERE authorPHID = %s) rel ' . 'ON (comments.revisionID = rel.revisionID)' . 'WHERE comments.action = %s' . 'AND comments.authorPHID = %s', $table->getTableName(), id(new DifferentialComment())->getTableName(), DifferentialRevision::RELATIONSHIP_TABLE, $phid, $phid, $this->filter, $phid); return $table->loadAllFromArray($rows); }
private function loadData() { $table = new DifferentialRevision(); $conn_r = $table->establishConnection('r'); if ($this->draftAuthors) { $draft_key = 'differential-comment-'; $drafts = id(new PhabricatorDraft())->loadAllWhere('authorPHID IN (%Ls) AND draftKey LIKE %> AND draft != %s', $this->draftAuthors, $draft_key, ''); $this->draftRevisions = array(); $len = strlen($draft_key); foreach ($drafts as $draft) { $this->draftRevisions[] = substr($draft->getDraftKey(), $len); } } $select = qsprintf($conn_r, 'SELECT r.* FROM %T r', $table->getTableName()); $joins = $this->buildJoinsClause($conn_r); $where = $this->buildWhereClause($conn_r); $group_by = $this->buildGroupByClause($conn_r); $order_by = $this->buildOrderByClause($conn_r); $limit = ''; if ($this->offset || $this->limit) { $limit = qsprintf($conn_r, 'LIMIT %d, %d', (int) $this->offset, $this->limit); } return queryfx_all($conn_r, '%Q %Q %Q %Q %Q %Q', $select, $joins, $where, $group_by, $order_by, $limit); }
/** * Update the table connecting revisions to DVCS local hashes, so we can * identify revisions by commit/tree hashes. */ private function updateRevisionHashTable(DifferentialRevision $revision, DifferentialDiff $diff) { $vcs = $diff->getSourceControlSystem(); if ($vcs == DifferentialRevisionControlSystem::SVN) { // Subversion has no local commit or tree hash information, so we don't // have to do anything. return; } $property = id(new DifferentialDiffProperty())->loadOneWhere('diffID = %d AND name = %s', $diff->getID(), 'local:commits'); if (!$property) { return; } $hashes = array(); $data = $property->getData(); switch ($vcs) { case DifferentialRevisionControlSystem::GIT: foreach ($data as $commit) { $hashes[] = array(ArcanistDifferentialRevisionHash::HASH_GIT_COMMIT, $commit['commit']); $hashes[] = array(ArcanistDifferentialRevisionHash::HASH_GIT_TREE, $commit['tree']); } break; case DifferentialRevisionControlSystem::MERCURIAL: foreach ($data as $commit) { $hashes[] = array(ArcanistDifferentialRevisionHash::HASH_MERCURIAL_COMMIT, $commit['rev']); } break; } $conn_w = $revision->establishConnection('w'); $sql = array(); foreach ($hashes as $info) { list($type, $hash) = $info; $sql[] = qsprintf($conn_w, '(%d, %s, %s)', $revision->getID(), $type, $hash); } queryfx($conn_w, 'DELETE FROM %T WHERE revisionID = %d', ArcanistDifferentialRevisionHash::TABLE_NAME, $revision->getID()); if ($sql) { queryfx($conn_w, 'INSERT INTO %T (revisionID, type, hash) VALUES %Q', ArcanistDifferentialRevisionHash::TABLE_NAME, implode(', ', $sql)); } }
private function loadData() { $table = new DifferentialRevision(); $conn_r = $table->establishConnection('r'); $selects = array(); // NOTE: If the query includes "responsiblePHIDs", we execute it as a // UNION of revisions they own and revisions they're reviewing. This has // much better performance than doing it with JOIN/WHERE. if ($this->responsibles) { $basic_authors = $this->authors; $basic_reviewers = $this->reviewers; $authority_projects = id(new PhabricatorProjectQuery())->setViewer($this->getViewer())->withMemberPHIDs($this->responsibles)->execute(); $authority_phids = mpull($authority_projects, 'getPHID'); try { // Build the query where the responsible users are authors. $this->authors = array_merge($basic_authors, $this->responsibles); $this->reviewers = $basic_reviewers; $selects[] = $this->buildSelectStatement($conn_r); // Build the query where the responsible users are reviewers, or // projects they are members of are reviewers. $this->authors = $basic_authors; $this->reviewers = array_merge($basic_reviewers, $this->responsibles, $authority_phids); $selects[] = $this->buildSelectStatement($conn_r); // Put everything back like it was. $this->authors = $basic_authors; $this->reviewers = $basic_reviewers; } catch (Exception $ex) { $this->authors = $basic_authors; $this->reviewers = $basic_reviewers; throw $ex; } } else { $selects[] = $this->buildSelectStatement($conn_r); } if (count($selects) > 1) { $this->buildingGlobalOrder = true; $query = qsprintf($conn_r, '%Q %Q %Q', implode(' UNION DISTINCT ', $selects), $this->buildOrderClause($conn_r), $this->buildLimitClause($conn_r)); } else { $query = head($selects); } return queryfx_all($conn_r, '%Q', $query); }
<?php echo pht('Migrating Differential unsubscribed users to edges...') . "\n"; $table = new DifferentialRevision(); $table->openTransaction(); // We couldn't use new LiskMigrationIterator($table) because the $unsubscribed // property gets deleted. $revs = queryfx_all($table->establishConnection('w'), 'SELECT id, phid, unsubscribed FROM differential_revision'); foreach ($revs as $rev) { echo '.'; $unsubscribed = json_decode($rev['unsubscribed']); if (!$unsubscribed) { continue; } $editor = new PhabricatorEdgeEditor(); foreach ($unsubscribed as $user_phid => $_) { $editor->addEdge($rev['phid'], PhabricatorObjectHasUnsubscriberEdgeType::EDGECONST, $user_phid); } $editor->save(); } $table->saveTransaction(); echo pht('Done.') . "\n";
private function loadAllOpenWithCCs(array $ccphids) { $rev = new DifferentialRevision(); $revision = new DifferentialRevision(); $data = queryfx_all($rev->establishConnection('r'), 'SELECT revision.* FROM %T revision JOIN %T relationship ON relationship.revisionID = revision.id AND relationship.relation = %s AND relationship.objectPHID in (%Ls) WHERE revision.status in (%Ld) %Q', $revision->getTableName(), DifferentialRevision::RELATIONSHIP_TABLE, DifferentialRevision::RELATION_SUBSCRIBED, $ccphids, $this->getOpenStatuses(), $this->getOrderClause()); return $revision->loadAllFromArray($data); }
<?php $revision_table = new DifferentialRevision(); $conn_w = $revision_table->establishConnection('w'); $conn_w->openTransaction(); $src_table = 'differential_inlinecomment'; $dst_table = 'differential_transaction_comment'; echo pht('Migrating Differential inline comments to new format...') . "\n"; $content_source = PhabricatorContentSource::newForSource(PhabricatorOldWorldContentSource::SOURCECONST)->serialize(); $rows = new LiskRawMigrationIterator($conn_w, $src_table); foreach ($rows as $row) { $id = $row['id']; $revision_id = $row['revisionID']; echo pht('Migrating inline #%d (%s)...', $id, "D{$revision_id}") . "\n"; $revision_row = queryfx_one($conn_w, 'SELECT phid FROM %T WHERE id = %d', $revision_table->getTableName(), $revision_id); if (!$revision_row) { continue; } $revision_phid = $revision_row['phid']; if ($row['commentID']) { $xaction_phid = PhabricatorPHID::generateNewPHID(PhabricatorApplicationTransactionTransactionPHIDType::TYPECONST, DifferentialRevisionPHIDType::TYPECONST); } else { $xaction_phid = null; } $comment_phid = PhabricatorPHID::generateNewPHID(PhabricatorPHIDConstants::PHID_TYPE_XCMT, DifferentialRevisionPHIDType::TYPECONST); queryfx($conn_w, 'INSERT IGNORE INTO %T (id, phid, transactionPHID, authorPHID, viewPolicy, editPolicy, commentVersion, content, contentSource, isDeleted, dateCreated, dateModified, revisionPHID, changesetID, isNewFile, lineNumber, lineLength, hasReplies, legacyCommentID) VALUES (%d, %s, %ns, %s, %s, %s,
* you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ $root = dirname(dirname(dirname(__FILE__))); require_once $root . '/scripts/__init_script__.php'; phutil_require_module('phutil', 'console'); $revision = new DifferentialRevision(); $empty_revisions = queryfx_all($revision->establishConnection('r'), 'select distinct r.id from differential_revision r left join ' . 'differential_diff d on r.id=d.revisionID where d.revisionID is NULL'); $empty_revisions = ipull($empty_revisions, 'id'); if (!$empty_revisions) { echo "No empty revisions found.\n"; exit(0); } echo phutil_console_wrap("The following revision don't contain any diff:\n" . implode(', ', $empty_revisions)); if (!phutil_console_confirm('Do you want to delete them?')) { echo "Cancelled.\n"; exit(1); } foreach ($empty_revisions as $revision_id) { $revision = id(new DifferentialRevision())->load($revision_id); $revision->delete(); } echo "Done.\n";
<?php $table = new DifferentialRevision(); $table->openTransaction(); $table->beginReadLocking(); $conn_w = $table->establishConnection('w'); echo 'Migrating revisions'; do { $revisions = $table->loadAllWhere('branchName IS NULL LIMIT 1000'); foreach ($revisions as $revision) { echo '.'; $diff = $revision->loadActiveDiff(); if (!$diff) { continue; } $branch_name = $diff->getBranch(); $arc_project_phid = $diff->getArcanistProjectPHID(); queryfx($conn_w, 'UPDATE %T SET branchName = %s, arcanistProjectPHID = %s WHERE id = %d', $table->getTableName(), $branch_name, $arc_project_phid, $revision->getID()); } } while (count($revisions) == 1000); $table->endReadLocking(); $table->saveTransaction(); echo "\nDone.\n";
protected function willFilterPage(array $revisions) { $viewer = $this->getViewer(); $repository_phids = mpull($revisions, 'getRepositoryPHID'); $repository_phids = array_filter($repository_phids); $repositories = array(); if ($repository_phids) { $repositories = id(new PhabricatorRepositoryQuery())->setViewer($this->getViewer())->withPHIDs($repository_phids)->execute(); $repositories = mpull($repositories, null, 'getPHID'); } // If a revision is associated with a repository: // // - the viewer must be able to see the repository; or // - the viewer must have an automatic view capability. // // In the latter case, we'll load the revision but not load the repository. $can_view = PhabricatorPolicyCapability::CAN_VIEW; foreach ($revisions as $key => $revision) { $repo_phid = $revision->getRepositoryPHID(); if (!$repo_phid) { // The revision has no associated repository. Attach `null` and move on. $revision->attachRepository(null); continue; } $repository = idx($repositories, $repo_phid); if ($repository) { // The revision has an associated repository, and the viewer can see // it. Attach it and move on. $revision->attachRepository($repository); continue; } if ($revision->hasAutomaticCapability($can_view, $viewer)) { // The revision has an associated repository which the viewer can not // see, but the viewer has an automatic capability on this revision. // Load the revision without attaching a repository. $revision->attachRepository(null); continue; } if ($this->getViewer()->isOmnipotent()) { // The viewer is omnipotent. Allow the revision to load even without // a repository. $revision->attachRepository(null); continue; } // The revision has an associated repository, and the viewer can't see // it, and the viewer has no special capabilities. Filter out this // revision. $this->didRejectResult($revision); unset($revisions[$key]); } if (!$revisions) { return array(); } $table = new DifferentialRevision(); $conn_r = $table->establishConnection('r'); if ($this->needRelationships) { $this->loadRelationships($conn_r, $revisions); } if ($this->needCommitPHIDs) { $this->loadCommitPHIDs($conn_r, $revisions); } $need_active = $this->needActiveDiffs; $need_ids = $need_active || $this->needDiffIDs; if ($need_ids) { $this->loadDiffIDs($conn_r, $revisions); } if ($need_active) { $this->loadActiveDiffs($conn_r, $revisions); } if ($this->needHashes) { $this->loadHashes($conn_r, $revisions); } if ($this->needReviewerStatus || $this->needReviewerAuthority) { $this->loadReviewers($conn_r, $revisions); } return $revisions; }
private function loadData() { $table = new DifferentialRevision(); $conn_r = $table->establishConnection('r'); $select = qsprintf($conn_r, 'SELECT r.* FROM %T r', $table->getTableName()); $joins = $this->buildJoinsClause($conn_r); $where = $this->buildWhereClause($conn_r); $group_by = $this->buildGroupByClause($conn_r); $order_by = $this->buildOrderByClause($conn_r); $limit = ''; if ($this->offset || $this->limit) { $limit = qsprintf($conn_r, 'LIMIT %d, %d', (int) $this->offset, $this->limit); } return queryfx_all($conn_r, '%Q %Q %Q %Q %Q %Q', $select, $joins, $where, $group_by, $order_by, $limit); }
public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); if ($request->isFormPost()) { $phid_arr = $request->getArr('view_user'); $view_target = head($phid_arr); return id(new AphrontRedirectResponse())->setURI($request->getRequestURI()->alter('phid', $view_target)); } $filters = array('User Revisions', 'active' => array('name' => 'Active Revisions', 'queries' => array(array('query' => DifferentialRevisionListData::QUERY_NEED_ACTION_FROM_SELF, 'header' => 'Action Required', 'nodata' => 'You have no revisions requiring action.'), array('query' => DifferentialRevisionListData::QUERY_NEED_ACTION_FROM_OTHERS, 'header' => 'Waiting on Others', 'nodata' => 'You have no revisions waiting on others'))), 'open' => array('name' => 'Open Revisions', 'queries' => array(array('query' => DifferentialRevisionListData::QUERY_OPEN_OWNED, 'header' => 'Your Open Revisions'))), 'reviews' => array('name' => 'Open Reviews', 'queries' => array(array('query' => DifferentialRevisionListData::QUERY_OPEN_REVIEWER, 'header' => 'Your Open Reviews'))), 'all' => array('name' => 'All Revisions', 'queries' => array(array('query' => DifferentialRevisionListData::QUERY_OWNED, 'header' => 'Your Revisions'))), 'related' => array('name' => 'All Revisions and Reviews', 'queries' => array(array('query' => DifferentialRevisionListData::QUERY_OWNED_OR_REVIEWER, 'header' => 'Your Revisions and Reviews'))), 'updates' => array('name' => 'Updates', 'queries' => array(array('query' => DifferentialRevisionListData::QUERY_UPDATED_SINCE, 'header' => 'Diffs that have been updated since you\'ve last viewed them'))), '<hr />', 'All Revisions', 'allopen' => array('name' => 'Open', 'nofilter' => true, 'queries' => array(array('query' => DifferentialRevisionListData::QUERY_ALL_OPEN, 'header' => 'All Open Revisions')))); if (empty($filters[$this->filter])) { $this->filter = 'active'; } $view_phid = nonempty($request->getStr('phid'), $user->getPHID()); $queries = array(); $filter = $filters[$this->filter]; foreach ($filter['queries'] as $query) { $query_object = new DifferentialRevisionListData($query['query'], array($view_phid)); $queries[] = array('object' => $query_object) + $query; } $side_nav = new AphrontSideNavView(); $query = null; if ($view_phid) { $query = '?phid=' . $view_phid; } foreach ($filters as $filter_name => $filter_desc) { if (is_int($filter_name)) { $side_nav->addNavItem(phutil_render_tag('span', array(), $filter_desc)); continue; } $selected = $filter_name == $this->filter; $side_nav->addNavItem(phutil_render_tag('a', array('href' => '/differential/filter/' . $filter_name . '/' . $query, 'class' => $selected ? 'aphront-side-nav-selected' : null), phutil_escape_html($filter_desc['name']))); } $phids = array(); $phids[$view_phid] = true; $rev_ids = array(); foreach ($queries as $key => $query) { $revisions = $query['object']->loadRevisions(); foreach ($revisions as $revision) { $phids[$revision->getAuthorPHID()] = true; $rev_ids[$revision->getID()] = true; } $queries[$key]['revisions'] = $revisions; } $rev = new DifferentialRevision(); if ($rev_ids) { $rev_ids = array_keys($rev_ids); $reviewers = queryfx_all($rev->establishConnection('r'), 'SELECT revisionID, objectPHID FROM %T revision JOIN %T relationship ON revision.id = relationship.revisionID WHERE revision.id IN (%Ld) AND relationship.relation = %s ORDER BY sequence', $rev->getTableName(), DifferentialRevision::RELATIONSHIP_TABLE, $rev_ids, DifferentialRevision::RELATION_REVIEWER); $reviewer_map = array(); foreach ($reviewers as $reviewer) { $reviewer_map[$reviewer['revisionID']][] = $reviewer['objectPHID']; } foreach ($reviewer_map as $revision_id => $reviewer_ids) { $phids[reset($reviewer_ids)] = true; } } else { $reviewer_map = array(); } if ($phids) { $phids = array_keys($phids); $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles(); } else { $handles = array(); } if (empty($filters[$this->filter]['nofilter'])) { $filter_form = id(new AphrontFormView())->setUser($user)->appendChild(id(new AphrontFormTokenizerControl())->setDatasource('/typeahead/common/users/')->setLabel('View User')->setName('view_user')->setValue(array($view_phid => $handles[$view_phid]->getFullName()))->setLimit(1)); $filter_view = new AphrontListFilterView(); $filter_view->appendChild($filter_form); $side_nav->appendChild($filter_view); } foreach ($queries as $query) { $table = $this->renderRevisionTable($query['revisions'], $query['header'], idx($query, 'nodata'), $handles, $reviewer_map); $side_nav->appendChild($table); } return $this->buildStandardPageResponse($side_nav, array('title' => 'Differential Home', 'tab' => 'revisions')); }
private static function alterRelationships(DifferentialRevision $revision, array $stable_phids, array $rem_phids, array $add_phids, $reason_phid, $relation_type) { $rem_map = array_fill_keys($rem_phids, true); $add_map = array_fill_keys($add_phids, true); $seq_map = array_values($stable_phids); $seq_map = array_flip($seq_map); foreach ($rem_map as $phid => $ignored) { if (!isset($seq_map[$phid])) { $seq_map[$phid] = count($seq_map); } } foreach ($add_map as $phid => $ignored) { if (!isset($seq_map[$phid])) { $seq_map[$phid] = count($seq_map); } } $raw = $revision->getRawRelations($relation_type); $raw = ipull($raw, null, 'objectPHID'); $sequence = count($seq_map); foreach ($raw as $phid => $ignored) { if (isset($seq_map[$phid])) { $raw[$phid]['sequence'] = $seq_map[$phid]; } else { $raw[$phid]['sequence'] = $sequence++; } } $raw = isort($raw, 'sequence'); foreach ($raw as $phid => $ignored) { if (isset($rem_map[$phid])) { unset($raw[$phid]); } } foreach ($add_phids as $add) { $raw[$add] = array('objectPHID' => $add, 'sequence' => idx($seq_map, $add, $sequence++), 'reasonPHID' => $reason_phid); } $conn_w = $revision->establishConnection('w'); $sql = array(); foreach ($raw as $relation) { $sql[] = qsprintf($conn_w, '(%d, %s, %s, %d, %s)', $revision->getID(), $relation_type, $relation['objectPHID'], $relation['sequence'], $relation['reasonPHID']); } $conn_w->openTransaction(); queryfx($conn_w, 'DELETE FROM %T WHERE revisionID = %d AND relation = %s', DifferentialRevision::RELATIONSHIP_TABLE, $revision->getID(), $relation_type); if ($sql) { queryfx($conn_w, 'INSERT INTO %T (revisionID, relation, objectPHID, sequence, reasonPHID) VALUES %Q', DifferentialRevision::RELATIONSHIP_TABLE, implode(', ', $sql)); } $conn_w->saveTransaction(); $revision->loadRelationships(); }