diff --git a/resources/sql/patches/20130926.dinline.php b/resources/sql/patches/20130926.dinline.php new file mode 100644 index 0000000000..75d67efdbd --- /dev/null +++ b/resources/sql/patches/20130926.dinline.php @@ -0,0 +1,90 @@ +establishConnection('w'); +$conn_w->openTransaction(); + +$src_table = 'differential_inlinecomment'; +$dst_table = 'differential_transaction_comment'; + +echo "Migrating Differential inline comments to new format...\n"; + +$content_source = PhabricatorContentSource::newForSource( + PhabricatorContentSource::SOURCE_LEGACY, + array())->serialize(); + +$rows = new LiskRawMigrationIterator($conn_w, $src_table); +foreach ($rows as $row) { + $id = $row['id']; + + $revision_id = $row['revisionID']; + + echo "Migrating inline #{$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( + PhabricatorApplicationTransactionPHIDTypeTransaction::TYPECONST, + DifferentialPHIDTypeRevision::TYPECONST); + } else { + $xaction_phid = null; + } + + $comment_phid = PhabricatorPHID::generateNewPHID( + PhabricatorPHIDConstants::PHID_TYPE_XCMT, + DifferentialPHIDTypeRevision::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, + %d, %s, %s, %d, + %d, %d, %s, %nd, + %d, %d, %d, %d, %nd)', + $dst_table, + + // id, phid, transactionPHID, authorPHID, viewPolicy, editPolicy + $row['id'], + $comment_phid, + $xaction_phid, + $row['authorPHID'], + 'public', + $row['authorPHID'], + + // commentVersion, content, contentSource, isDeleted + 1, + $row['content'], + $content_source, + 0, + + // dateCreated, dateModified, revisionPHID, changesetID + $row['dateCreated'], + $row['dateModified'], + $revision_phid, + $row['changesetID'], + + // isNewFile, lineNumber, lineLength, hasReplies, legacyCommentID + $row['isNewFile'], + $row['lineNumber'], + $row['lineLength'], + 0, + $row['commentID']); + +} + +$conn_w->saveTransaction(); +echo "Done.\n"; diff --git a/src/applications/differential/controller/DifferentialInlineCommentEditController.php b/src/applications/differential/controller/DifferentialInlineCommentEditController.php index 62c5d6c781..c09caa9374 100644 --- a/src/applications/differential/controller/DifferentialInlineCommentEditController.php +++ b/src/applications/differential/controller/DifferentialInlineCommentEditController.php @@ -1,76 +1,76 @@ revisionID = $data['id']; } protected function createComment() { // Verify revision and changeset correspond to actual objects. $revision_id = $this->revisionID; $changeset_id = $this->getChangesetID(); $viewer = $this->getRequest()->getUser(); $revision = id(new DifferentialRevisionQuery()) ->setViewer($viewer) ->withIDs(array($revision_id)) ->executeOne(); if (!$revision) { throw new Exception("Invalid revision ID!"); } if (!id(new DifferentialChangeset())->load($changeset_id)) { throw new Exception("Invalid changeset ID!"); } return id(new DifferentialInlineComment()) - ->setRevisionID($revision_id) + ->setRevision($revision) ->setChangesetID($changeset_id); } protected function loadComment($id) { return id(new DifferentialInlineCommentQuery()) ->withIDs(array($id)) ->executeOne(); } protected function loadCommentForEdit($id) { $request = $this->getRequest(); $user = $request->getUser(); $inline = $this->loadComment($id); if (!$this->canEditInlineComment($user, $inline)) { throw new Exception("That comment is not editable!"); } return $inline; } private function canEditInlineComment( PhabricatorUser $user, DifferentialInlineComment $inline) { // Only the author may edit a comment. if ($inline->getAuthorPHID() != $user->getPHID()) { return false; } // Saved comments may not be edited. if ($inline->getCommentID()) { return false; } // Inline must be attached to the active revision. if ($inline->getRevisionID() != $this->revisionID) { return false; } return true; } } diff --git a/src/applications/differential/query/DifferentialInlineCommentQuery.php b/src/applications/differential/query/DifferentialInlineCommentQuery.php index 215a4d61b6..8eb59760c1 100644 --- a/src/applications/differential/query/DifferentialInlineCommentQuery.php +++ b/src/applications/differential/query/DifferentialInlineCommentQuery.php @@ -1,129 +1,168 @@ revisionIDs = $ids; return $this; } public function withNotDraft($not_draft) { $this->notDraft = $not_draft; return $this; } public function withIDs(array $ids) { $this->ids = $ids; return $this; } public function withViewerAndChangesetIDs($author_phid, array $ids) { $this->viewerAndChangesetIDs = array($author_phid, $ids); return $this; } public function withDraftComments($author_phid, $revision_id) { $this->draftComments = array($author_phid, $revision_id); return $this; } public function withDraftsByAuthors(array $author_phids) { $this->draftsByAuthors = $author_phids; return $this; } public function withCommentIDs(array $comment_ids) { $this->commentIDs = $comment_ids; return $this; } public function execute() { - $table = new DifferentialInlineComment(); + $table = new DifferentialTransactionComment(); $conn_r = $table->establishConnection('r'); $data = queryfx_all( $conn_r, 'SELECT * FROM %T %Q %Q', $table->getTableName(), $this->buildWhereClause($conn_r), $this->buildLimitClause($conn_r)); - return $table->loadAllFromArray($data); + $comments = $table->loadAllFromArray($data); + + foreach ($comments as $key => $value) { + $comments[$key] = DifferentialInlineComment::newFromModernComment( + $value); + } + + return $comments; } public function executeOne() { return head($this->execute()); } private function buildWhereClause(AphrontDatabaseConnection $conn_r) { $where = array(); + // Only find inline comments. + $where[] = qsprintf( + $conn_r, + 'changesetID IS NOT NULL'); + if ($this->revisionIDs) { - $where[] = qsprintf( + + // Look up revision PHIDs. + $revision_phids = queryfx_all( $conn_r, - 'revisionID IN (%Ld)', + 'SELECT phid FROM %T WHERE id IN (%Ld)', + id(new DifferentialRevision())->getTableName(), $this->revisionIDs); + + if (!$revision_phids) { + throw new PhabricatorEmptyQueryException(); + } + $revision_phids = ipull($revision_phids, 'phid'); + + $where[] = qsprintf( + $conn_r, + 'revisionPHID IN (%Ls)', + $revision_phids); } if ($this->notDraft) { $where[] = qsprintf( $conn_r, - 'commentID IS NOT NULL'); + 'transactionPHID IS NOT NULL'); } if ($this->ids) { $where[] = qsprintf( $conn_r, 'id IN (%Ld)', $this->ids); } if ($this->viewerAndChangesetIDs) { list($phid, $ids) = $this->viewerAndChangesetIDs; $where[] = qsprintf( $conn_r, - 'changesetID IN (%Ld) AND (authorPHID = %s OR commentID IS NOT NULL)', + 'changesetID IN (%Ld) AND + (authorPHID = %s OR transactionPHID IS NOT NULL)', $ids, $phid); } if ($this->draftComments) { list($phid, $rev_id) = $this->draftComments; + + $rev_phid = queryfx_one( + $conn_r, + 'SELECT phid FROM %T WHERE id = %d', + id(new DifferentialRevision())->getTableName(), + $rev_id); + + if (!$rev_phid) { + throw new PhabricatorEmptyQueryException(); + } + + $rev_phid = $rev_phid['phid']; + $where[] = qsprintf( $conn_r, - 'authorPHID = %s AND revisionID = %d AND commentID IS NULL', + 'authorPHID = %s AND revisionPHID = %s AND transactionPHID IS NULL', $phid, - $rev_id); + $rev_phid); } if ($this->draftsByAuthors) { $where[] = qsprintf( $conn_r, - 'authorPHID IN (%Ls) AND commentID IS NULL', + 'authorPHID IN (%Ls) AND transactionPHID IS NULL', $this->draftsByAuthors); } if ($this->commentIDs) { $where[] = qsprintf( $conn_r, - 'commentID IN (%Ld)', + 'legacyCommentID IN (%Ld)', $this->commentIDs); } return $this->formatWhereClause($where); } } diff --git a/src/applications/differential/query/DifferentialRevisionQuery.php b/src/applications/differential/query/DifferentialRevisionQuery.php index 90284fefb9..556ec6a83c 100644 --- a/src/applications/differential/query/DifferentialRevisionQuery.php +++ b/src/applications/differential/query/DifferentialRevisionQuery.php @@ -1,1188 +1,1195 @@ withStatus(DifferentialRevisionQuery::STATUS_OPEN) * ->execute(); * * @task config Query Configuration * @task exec Query Execution * @task internal Internals */ final class DifferentialRevisionQuery extends PhabricatorCursorPagedPolicyAwareQuery { private $pathIDs = array(); private $status = 'status-any'; const STATUS_ANY = 'status-any'; const STATUS_OPEN = 'status-open'; const STATUS_ACCEPTED = 'status-accepted'; const STATUS_NEEDS_REVIEW = 'status-needs-review'; const STATUS_NEEDS_REVISION = 'status-needs-revision'; const STATUS_CLOSED = 'status-closed'; // NOTE: Same as 'committed' const STATUS_COMMITTED = 'status-committed'; // TODO: Remove. const STATUS_ABANDONED = 'status-abandoned'; private $authors = array(); private $draftAuthors = array(); private $ccs = array(); private $reviewers = array(); private $revIDs = array(); private $commitHashes = array(); private $phids = array(); private $subscribers = array(); private $responsibles = array(); private $branches = array(); private $arcanistProjectPHIDs = array(); private $draftRevisions = array(); private $repositoryPHIDs; private $order = 'order-modified'; const ORDER_MODIFIED = 'order-modified'; const ORDER_CREATED = 'order-created'; /** * This is essentially a denormalized copy of the revision modified time that * should perform better for path queries with a LIMIT. Critically, when you * browse "/", every revision in that repository for all time will match so * the query benefits from being able to stop before fully materializing the * result set. */ const ORDER_PATH_MODIFIED = 'order-path-modified'; private $needRelationships = false; private $needActiveDiffs = false; private $needDiffIDs = false; private $needCommitPHIDs = false; private $needHashes = false; private $needReviewerStatus = false; private $needReviewerAuthority; private $buildingGlobalOrder; /* -( Query Configuration )------------------------------------------------ */ /** * Filter results to revisions which affect a Diffusion path ID in a given * repository. You can call this multiple times to select revisions for * several paths. * * @param int Diffusion repository ID. * @param int Diffusion path ID. * @return this * @task config */ public function withPath($repository_id, $path_id) { $this->pathIDs[] = array( 'repositoryID' => $repository_id, 'pathID' => $path_id, ); return $this; } /** * Filter results to revisions authored by one of the given PHIDs. Calling * this function will clear anything set by previous calls to * @{method:withAuthors}. * * @param array List of PHIDs of authors * @return this * @task config */ public function withAuthors(array $author_phids) { $this->authors = $author_phids; return $this; } /** * Filter results to revisions with comments authored bythe given PHIDs * * @param array List of PHIDs of authors * @return this * @task config */ public function withDraftRepliesByAuthors(array $author_phids) { $this->draftAuthors = $author_phids; return $this; } /** * Filter results to revisions which CC one of the listed people. Calling this * function will clear anything set by previous calls to @{method:withCCs}. * * @param array List of PHIDs of subscribers * @return this * @task config */ public function withCCs(array $cc_phids) { $this->ccs = $cc_phids; return $this; } /** * Filter results to revisions that have one of the provided PHIDs as * reviewers. Calling this function will clear anything set by previous calls * to @{method:withReviewers}. * * @param array List of PHIDs of reviewers * @return this * @task config */ public function withReviewers(array $reviewer_phids) { $this->reviewers = $reviewer_phids; return $this; } /** * Filter results to revisions that have one of the provided commit hashes. * Calling this function will clear anything set by previous calls to * @{method:withCommitHashes}. * * @param array List of pairs * @return this * @task config */ public function withCommitHashes(array $commit_hashes) { $this->commitHashes = $commit_hashes; return $this; } /** * Filter results to revisions with a given status. Provide a class constant, * such as ##DifferentialRevisionQuery::STATUS_OPEN##. * * @param const Class STATUS constant, like STATUS_OPEN. * @return this * @task config */ public function withStatus($status_constant) { $this->status = $status_constant; return $this; } /** * Filter results to revisions on given branches. * * @param list List of branch names. * @return this * @task config */ public function withBranches(array $branches) { $this->branches = $branches; return $this; } /** * Filter results to only return revisions whose ids are in the given set. * * @param array List of revision ids * @return this * @task config */ public function withIDs(array $ids) { $this->revIDs = $ids; return $this; } /** * Filter results to only return revisions whose PHIDs are in the given set. * * @param array List of revision PHIDs * @return this * @task config */ public function withPHIDs(array $phids) { $this->phids = $phids; return $this; } /** * Given a set of users, filter results to return only revisions they are * responsible for (i.e., they are either authors or reviewers). * * @param array List of user PHIDs. * @return this * @task config */ public function withResponsibleUsers(array $responsible_phids) { $this->responsibles = $responsible_phids; return $this; } /** * Filter results to only return revisions with a given set of subscribers * (i.e., they are authors, reviewers or CC'd). * * @param array List of user PHIDs. * @return this * @task config */ public function withSubscribers(array $subscriber_phids) { $this->subscribers = $subscriber_phids; return $this; } /** * Filter results to only return revisions with a given set of arcanist * projects. * * @param array List of project PHIDs. * @return this * @task config */ public function withArcanistProjectPHIDs(array $arc_project_phids) { $this->arcanistProjectPHIDs = $arc_project_phids; return $this; } public function withRepositoryPHIDs(array $repository_phids) { $this->repositoryPHIDs = $repository_phids; return $this; } /** * Set result ordering. Provide a class constant, such as * ##DifferentialRevisionQuery::ORDER_CREATED##. * * @task config */ public function setOrder($order_constant) { $this->order = $order_constant; return $this; } /** * Set whether or not the query will load and attach relationships. * * @param bool True to load and attach relationships. * @return this * @task config */ public function needRelationships($need_relationships) { $this->needRelationships = $need_relationships; return $this; } /** * Set whether or not the query should load the active diff for each * revision. * * @param bool True to load and attach diffs. * @return this * @task config */ public function needActiveDiffs($need_active_diffs) { $this->needActiveDiffs = $need_active_diffs; return $this; } /** * Set whether or not the query should load the associated commit PHIDs for * each revision. * * @param bool True to load and attach diffs. * @return this * @task config */ public function needCommitPHIDs($need_commit_phids) { $this->needCommitPHIDs = $need_commit_phids; return $this; } /** * Set whether or not the query should load associated diff IDs for each * revision. * * @param bool True to load and attach diff IDs. * @return this * @task config */ public function needDiffIDs($need_diff_ids) { $this->needDiffIDs = $need_diff_ids; return $this; } /** * Set whether or not the query should load associated commit hashes for each * revision. * * @param bool True to load and attach commit hashes. * @return this * @task config */ public function needHashes($need_hashes) { $this->needHashes = $need_hashes; return $this; } /** * Set whether or not the query should load associated reviewer status. * * @param bool True to load and attach reviewers. * @return this * @task config */ public function needReviewerStatus($need_reviewer_status) { $this->needReviewerStatus = $need_reviewer_status; return $this; } /** * Request information about the viewer's authority to act on behalf of each * reviewer. In particular, they have authority to act on behalf of projects * they are a member of. * * @param bool True to load and attach authority. * @return this * @task config */ public function needReviewerAuthority($need_reviewer_authority) { $this->needReviewerAuthority = $need_reviewer_authority; return $this; } /* -( Query Execution )---------------------------------------------------- */ /** * Execute the query as configured, returning matching * @{class:DifferentialRevision} objects. * * @return list List of matching DifferentialRevision objects. * @task exec */ public function loadPage() { $table = new DifferentialRevision(); $conn_r = $table->establishConnection('r'); $data = $this->loadData(); return $table->loadAllFromArray($data); } public 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; } // 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'); if ($this->draftAuthors) { $this->draftRevisions = array(); $draft_key = 'differential-comment-'; $drafts = id(new PhabricatorDraft())->loadAllWhere( 'authorPHID IN (%Ls) AND draftKey LIKE %> AND draft != %s', $this->draftAuthors, $draft_key, ''); $len = strlen($draft_key); foreach ($drafts as $draft) { $this->draftRevisions[] = substr($draft->getDraftKey(), $len); } + // TODO: Restore this after drafts are sorted out. It's now very + // expensive to get revision IDs. + + /* + $inlines = id(new DifferentialInlineCommentQuery()) ->withDraftsByAuthors($this->draftAuthors) ->execute(); foreach ($inlines as $inline) { $this->draftRevisions[] = $inline->getRevisionID(); } + */ + if (!$this->draftRevisions) { return array(); } } $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); } private function buildSelectStatement(AphrontDatabaseConnection $conn_r) { $table = new DifferentialRevision(); $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); $this->buildingGlobalOrder = false; $order_by = $this->buildOrderClause($conn_r); $limit = $this->buildLimitClause($conn_r); return qsprintf( $conn_r, '(%Q %Q %Q %Q %Q %Q)', $select, $joins, $where, $group_by, $order_by, $limit); } /* -( Internals )---------------------------------------------------------- */ /** * @task internal */ private function buildJoinsClause($conn_r) { $joins = array(); if ($this->pathIDs) { $path_table = new DifferentialAffectedPath(); $joins[] = qsprintf( $conn_r, 'JOIN %T p ON p.revisionID = r.id', $path_table->getTableName()); } if ($this->commitHashes) { $joins[] = qsprintf( $conn_r, 'JOIN %T hash_rel ON hash_rel.revisionID = r.id', ArcanistDifferentialRevisionHash::TABLE_NAME); } if ($this->ccs) { $joins[] = qsprintf( $conn_r, 'JOIN %T cc_rel ON cc_rel.revisionID = r.id '. 'AND cc_rel.relation = %s '. 'AND cc_rel.objectPHID in (%Ls)', DifferentialRevision::RELATIONSHIP_TABLE, DifferentialRevision::RELATION_SUBSCRIBED, $this->ccs); } if ($this->reviewers) { $joins[] = qsprintf( $conn_r, 'JOIN %T e_reviewers ON e_reviewers.src = r.phid '. 'AND e_reviewers.type = %s '. 'AND e_reviewers.dst in (%Ls)', PhabricatorEdgeConfig::TABLE_NAME_EDGE, PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER, $this->reviewers); } if ($this->subscribers) { // TODO: These can be expressed as a JOIN again (and the corresponding // WHERE clause removed) once subscribers move to edges. $joins[] = qsprintf( $conn_r, 'LEFT JOIN %T sub_rel_cc ON sub_rel_cc.revisionID = r.id '. 'AND sub_rel_cc.relation = %s '. 'AND sub_rel_cc.objectPHID in (%Ls)', DifferentialRevision::RELATIONSHIP_TABLE, DifferentialRevision::RELATION_SUBSCRIBED, $this->subscribers); $joins[] = qsprintf( $conn_r, 'LEFT JOIN %T sub_rel_reviewer ON sub_rel_reviewer.src = r.phid '. 'AND sub_rel_reviewer.type = %s '. 'AND sub_rel_reviewer.dst in (%Ls)', PhabricatorEdgeConfig::TABLE_NAME_EDGE, PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER, $this->subscribers); } $joins = implode(' ', $joins); return $joins; } /** * @task internal */ private function buildWhereClause($conn_r) { $where = array(); if ($this->pathIDs) { $path_clauses = array(); $repo_info = igroup($this->pathIDs, 'repositoryID'); foreach ($repo_info as $repository_id => $paths) { $path_clauses[] = qsprintf( $conn_r, '(p.repositoryID = %d AND p.pathID IN (%Ld))', $repository_id, ipull($paths, 'pathID')); } $path_clauses = '('.implode(' OR ', $path_clauses).')'; $where[] = $path_clauses; } if ($this->authors) { $where[] = qsprintf( $conn_r, 'r.authorPHID IN (%Ls)', $this->authors); } if ($this->draftRevisions) { $where[] = qsprintf( $conn_r, 'r.id IN (%Ld)', $this->draftRevisions); } if ($this->revIDs) { $where[] = qsprintf( $conn_r, 'r.id IN (%Ld)', $this->revIDs); } if ($this->repositoryPHIDs) { $where[] = qsprintf( $conn_r, 'r.repositoryPHID IN (%Ls)', $this->repositoryPHIDs); } if ($this->commitHashes) { $hash_clauses = array(); foreach ($this->commitHashes as $info) { list($type, $hash) = $info; $hash_clauses[] = qsprintf( $conn_r, '(hash_rel.type = %s AND hash_rel.hash = %s)', $type, $hash); } $hash_clauses = '('.implode(' OR ', $hash_clauses).')'; $where[] = $hash_clauses; } if ($this->phids) { $where[] = qsprintf( $conn_r, 'r.phid IN (%Ls)', $this->phids); } if ($this->branches) { $where[] = qsprintf( $conn_r, 'r.branchName in (%Ls)', $this->branches); } if ($this->arcanistProjectPHIDs) { $where[] = qsprintf( $conn_r, 'r.arcanistProjectPHID in (%Ls)', $this->arcanistProjectPHIDs); } if ($this->subscribers) { $where[] = qsprintf( $conn_r, '(sub_rel_cc.objectPHID IS NOT NULL) OR (sub_rel_reviewer.dst IS NOT NULL)'); } switch ($this->status) { case self::STATUS_ANY: break; case self::STATUS_OPEN: $where[] = qsprintf( $conn_r, 'r.status IN (%Ld)', array( ArcanistDifferentialRevisionStatus::NEEDS_REVIEW, ArcanistDifferentialRevisionStatus::NEEDS_REVISION, ArcanistDifferentialRevisionStatus::ACCEPTED, )); break; case self::STATUS_NEEDS_REVIEW: $where[] = qsprintf( $conn_r, 'r.status IN (%Ld)', array( ArcanistDifferentialRevisionStatus::NEEDS_REVIEW, )); break; case self::STATUS_NEEDS_REVISION: $where[] = qsprintf( $conn_r, 'r.status IN (%Ld)', array( ArcanistDifferentialRevisionStatus::NEEDS_REVISION, )); break; case self::STATUS_ACCEPTED: $where[] = qsprintf( $conn_r, 'r.status IN (%Ld)', array( ArcanistDifferentialRevisionStatus::ACCEPTED, )); break; case self::STATUS_COMMITTED: phlog( "WARNING: DifferentialRevisionQuery using deprecated ". "STATUS_COMMITTED constant. This will be removed soon. ". "Use STATUS_CLOSED."); // fallthrough case self::STATUS_CLOSED: $where[] = qsprintf( $conn_r, 'r.status IN (%Ld)', array( ArcanistDifferentialRevisionStatus::CLOSED, )); break; case self::STATUS_ABANDONED: $where[] = qsprintf( $conn_r, 'r.status IN (%Ld)', array( ArcanistDifferentialRevisionStatus::ABANDONED, )); break; default: throw new Exception( "Unknown revision status filter constant '{$this->status}'!"); } $where[] = $this->buildPagingClause($conn_r); return $this->formatWhereClause($where); } /** * @task internal */ private function buildGroupByClause($conn_r) { $join_triggers = array_merge( $this->pathIDs, $this->ccs, $this->reviewers, $this->subscribers); $needs_distinct = (count($join_triggers) > 1); if ($needs_distinct) { return 'GROUP BY r.id'; } else { return ''; } } private function loadCursorObject($id) { $results = id(new DifferentialRevisionQuery()) ->setViewer($this->getPagingViewer()) ->withIDs(array((int)$id)) ->execute(); return head($results); } protected function buildPagingClause(AphrontDatabaseConnection $conn_r) { $default = parent::buildPagingClause($conn_r); $before_id = $this->getBeforeID(); $after_id = $this->getAfterID(); if (!$before_id && !$after_id) { return $default; } if ($before_id) { $cursor = $this->loadCursorObject($before_id); } else { $cursor = $this->loadCursorObject($after_id); } if (!$cursor) { return null; } $columns = array(); switch ($this->order) { case self::ORDER_CREATED: return $default; case self::ORDER_MODIFIED: $columns[] = array( 'name' => 'r.dateModified', 'value' => $cursor->getDateModified(), 'type' => 'int', ); break; case self::ORDER_PATH_MODIFIED: $columns[] = array( 'name' => 'p.epoch', 'value' => $cursor->getDateCreated(), 'type' => 'int', ); break; } $columns[] = array( 'name' => 'r.id', 'value' => $cursor->getID(), 'type' => 'int', ); return $this->buildPagingClauseFromMultipleColumns( $conn_r, $columns, array( 'reversed' => (bool)($before_id xor $this->getReversePaging()), )); } protected function getPagingColumn() { $is_global = $this->buildingGlobalOrder; switch ($this->order) { case self::ORDER_MODIFIED: if ($is_global) { return 'dateModified'; } return 'r.dateModified'; case self::ORDER_CREATED: if ($is_global) { return 'id'; } return 'r.id'; case self::ORDER_PATH_MODIFIED: if (!$this->pathIDs) { throw new Exception( "To use ORDER_PATH_MODIFIED, you must specify withPath()."); } return 'p.epoch'; default: throw new Exception("Unknown query order constant '{$this->order}'."); } } private function loadRelationships($conn_r, array $revisions) { assert_instances_of($revisions, 'DifferentialRevision'); $relationships = queryfx_all( $conn_r, 'SELECT * FROM %T WHERE revisionID in (%Ld) AND relation != %s ORDER BY sequence', DifferentialRevision::RELATIONSHIP_TABLE, mpull($revisions, 'getID'), DifferentialRevision::RELATION_REVIEWER); $relationships = igroup($relationships, 'revisionID'); $type_reviewer = PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER; $edges = id(new PhabricatorEdgeQuery()) ->withSourcePHIDs(mpull($revisions, 'getPHID')) ->withEdgeTypes(array($type_reviewer)) ->setOrder(PhabricatorEdgeQuery::ORDER_OLDEST_FIRST) ->execute(); foreach ($revisions as $revision) { $data = idx($relationships, $revision->getID(), array()); $revision_edges = $edges[$revision->getPHID()][$type_reviewer]; foreach ($revision_edges as $dst_phid => $edge_data) { $data[] = array( 'relation' => DifferentialRevision::RELATION_REVIEWER, 'objectPHID' => $dst_phid, 'reasonPHID' => null, ); } $revision->attachRelationships($data); } } private function loadCommitPHIDs($conn_r, array $revisions) { assert_instances_of($revisions, 'DifferentialRevision'); $commit_phids = queryfx_all( $conn_r, 'SELECT * FROM %T WHERE revisionID IN (%Ld)', DifferentialRevision::TABLE_COMMIT, mpull($revisions, 'getID')); $commit_phids = igroup($commit_phids, 'revisionID'); foreach ($revisions as $revision) { $phids = idx($commit_phids, $revision->getID(), array()); $phids = ipull($phids, 'commitPHID'); $revision->attachCommitPHIDs($phids); } } private function loadDiffIDs($conn_r, array $revisions) { assert_instances_of($revisions, 'DifferentialRevision'); $diff_table = new DifferentialDiff(); $diff_ids = queryfx_all( $conn_r, 'SELECT revisionID, id FROM %T WHERE revisionID IN (%Ld) ORDER BY id DESC', $diff_table->getTableName(), mpull($revisions, 'getID')); $diff_ids = igroup($diff_ids, 'revisionID'); foreach ($revisions as $revision) { $ids = idx($diff_ids, $revision->getID(), array()); $ids = ipull($ids, 'id'); $revision->attachDiffIDs($ids); } } private function loadActiveDiffs($conn_r, array $revisions) { assert_instances_of($revisions, 'DifferentialRevision'); $diff_table = new DifferentialDiff(); $load_ids = array(); foreach ($revisions as $revision) { $diffs = $revision->getDiffIDs(); if ($diffs) { $load_ids[] = max($diffs); } } $active_diffs = array(); if ($load_ids) { $active_diffs = $diff_table->loadAllWhere( 'id IN (%Ld)', $load_ids); } $active_diffs = mpull($active_diffs, null, 'getRevisionID'); foreach ($revisions as $revision) { $revision->attachActiveDiff(idx($active_diffs, $revision->getID())); } } private function loadHashes( AphrontDatabaseConnection $conn_r, array $revisions) { assert_instances_of($revisions, 'DifferentialRevision'); $data = queryfx_all( $conn_r, 'SELECT * FROM %T WHERE revisionID IN (%Ld)', 'differential_revisionhash', mpull($revisions, 'getID')); $data = igroup($data, 'revisionID'); foreach ($revisions as $revision) { $hashes = idx($data, $revision->getID(), array()); $list = array(); foreach ($hashes as $hash) { $list[] = array($hash['type'], $hash['hash']); } $revision->attachHashes($list); } } private function loadReviewers( AphrontDatabaseConnection $conn_r, array $revisions) { assert_instances_of($revisions, 'DifferentialRevision'); $edge_type = PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER; $edges = id(new PhabricatorEdgeQuery()) ->withSourcePHIDs(mpull($revisions, 'getPHID')) ->withEdgeTypes(array($edge_type)) ->needEdgeData(true) ->setOrder(PhabricatorEdgeQuery::ORDER_OLDEST_FIRST) ->execute(); $viewer = $this->getViewer(); $viewer_phid = $viewer->getPHID(); // Figure out which of these reviewers the viewer has authority to act as. if ($this->needReviewerAuthority && $viewer_phid) { $allow_key = 'differential.allow-self-accept'; $allow_self = PhabricatorEnv::getEnvConfig($allow_key); $authority = $this->loadReviewerAuthority( $revisions, $edges, $allow_self); } foreach ($revisions as $revision) { $revision_edges = $edges[$revision->getPHID()][$edge_type]; $reviewers = array(); foreach ($revision_edges as $reviewer_phid => $edge) { $reviewer = new DifferentialReviewer($reviewer_phid, $edge['data']); if ($this->needReviewerAuthority) { if (!$viewer_phid) { // Logged-out users never have authority. $has_authority = false; } else if ((!$allow_self) && ($revision->getAuthorPHID() == $viewer_phid)) { // The author can never have authority unless we allow self-accept. $has_authority = false; } else { // Otherwise, look up whether th viewer has authority. $has_authority = isset($authority[$reviewer_phid]); } $reviewer->attachAuthority($viewer, $has_authority); } $reviewers[$reviewer_phid] = $reviewer; } $revision->attachReviewerStatus($reviewers); } } public static function splitResponsible(array $revisions, array $user_phids) { $blocking = array(); $active = array(); $waiting = array(); $status_review = ArcanistDifferentialRevisionStatus::NEEDS_REVIEW; // Bucket revisions into $blocking (revisions where you are blocking // others), $active (revisions you need to do something about) and $waiting // (revisions you're waiting on someone else to do something about). foreach ($revisions as $revision) { $needs_review = ($revision->getStatus() == $status_review); $filter_is_author = in_array($revision->getAuthorPHID(), $user_phids); if (!$revision->getReviewers()) { $needs_review = false; } // If exactly one of "needs review" and "the user is the author" is // true, the user needs to act on it. Otherwise, they're waiting on // it. if ($needs_review ^ $filter_is_author) { if ($needs_review) { array_unshift($blocking, $revision); } else { $active[] = $revision; } } else { $waiting[] = $revision; } } return array($blocking, $active, $waiting); } private function loadReviewerAuthority( array $revisions, array $edges, $allow_self) { $revision_map = mpull($revisions, null, 'getPHID'); $viewer_phid = $this->getViewer()->getPHID(); // Find all the project reviewers which the user may have authority over. $project_phids = array(); $project_type = PhabricatorProjectPHIDTypeProject::TYPECONST; $edge_type = PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER; foreach ($edges as $src => $types) { if (!$allow_self) { if ($revision_map[$src]->getAuthorPHID() == $viewer_phid) { // If self-review isn't permitted, the user will never have // authority over projects on revisions they authored because you // can't accept your own revisions, so we don't need to load any // data about these reviewers. continue; } } $edge_data = idx($types, $edge_type, array()); foreach ($edge_data as $dst => $data) { if (phid_get_type($dst) == $project_type) { $project_phids[] = $dst; } } } // Now, figure out which of these projects the viewer is actually a // member of. $project_authority = array(); if ($project_phids) { $project_authority = id(new PhabricatorProjectQuery()) ->setViewer($this->getViewer()) ->withPHIDs($project_phids) ->withMemberPHIDs(array($viewer_phid)) ->execute(); $project_authority = mpull($project_authority, 'getPHID'); } // Finally, the viewer has authority over themselves. return array( $viewer_phid => true, ) + array_fuse($project_authority); } } diff --git a/src/applications/differential/storage/DifferentialInlineComment.php b/src/applications/differential/storage/DifferentialInlineComment.php index 469bd3ea5d..af30563776 100644 --- a/src/applications/differential/storage/DifferentialInlineComment.php +++ b/src/applications/differential/storage/DifferentialInlineComment.php @@ -1,134 +1,202 @@ proxy = new DifferentialTransactionComment(); + } - private $syntheticAuthor; + public function __clone() { + $this->proxy = clone $this->proxy; + } + + public function save() { + $content_source = PhabricatorContentSource::newForSource( + PhabricatorContentSource::SOURCE_LEGACY, + array()); + + $this->proxy + ->setViewPolicy('public') + ->setEditPolicy($this->getAuthorPHID()) + ->setContentSource($content_source) + ->setCommentVersion(1) + ->save(); + + return $this; + } + + public function delete() { + $this->proxy->delete(); + + return $this; + } + + public function getID() { + return $this->proxy->getID(); + } + + public static function newFromModernComment( + DifferentialTransactionComment $comment) { + + $obj = new DifferentialInlineComment(); + $obj->proxy = $comment; + + return $obj; + } public function setSyntheticAuthor($synthetic_author) { $this->syntheticAuthor = $synthetic_author; return $this; } public function getSyntheticAuthor() { return $this->syntheticAuthor; } public function isCompatible(PhabricatorInlineCommentInterface $comment) { return ($this->getAuthorPHID() === $comment->getAuthorPHID()) && ($this->getSyntheticAuthor() === $comment->getSyntheticAuthor()) && ($this->getContent() === $comment->getContent()); } public function setContent($content) { - $this->setCache(null); - $this->writeField('content', $content); + $this->proxy->setContent($content); return $this; } public function getContent() { - return $this->readField('content'); + return $this->proxy->getContent(); } public function isDraft() { return !$this->getCommentID(); } - // NOTE: We need to provide implementations so we conform to the shared - // interface; these are all trivial and just explicit versions of the Lisk - // defaults. - public function setChangesetID($id) { - $this->writeField('changesetID', $id); + $this->proxy->setChangesetID($id); return $this; } public function getChangesetID() { - return $this->readField('changesetID'); + return $this->proxy->getChangesetID(); } public function setIsNewFile($is_new) { - $this->writeField('isNewFile', $is_new); + $this->proxy->setIsNewFile($is_new); return $this; } public function getIsNewFile() { - return $this->readField('isNewFile'); + return $this->proxy->getIsNewFile(); } public function setLineNumber($number) { - $this->writeField('lineNumber', $number); + $this->proxy->setLineNumber($number); return $this; } public function getLineNumber() { - return $this->readField('lineNumber'); + return $this->proxy->getLineNumber(); } public function setLineLength($length) { - $this->writeField('lineLength', $length); + $this->proxy->setLineLength($length); return $this; } public function getLineLength() { - return $this->readField('lineLength'); + return $this->proxy->getLineLength(); } public function setCache($cache) { - $this->writeField('cache', $cache); return $this; } public function getCache() { - return $this->readField('cache'); + return null; } public function setAuthorPHID($phid) { - $this->writeField('authorPHID', $phid); + $this->proxy->setAuthorPHID($phid); return $this; } public function getAuthorPHID() { - return $this->readField('authorPHID'); + return $this->proxy->getAuthorPHID(); + } + + public function setRevision(DifferentialRevision $revision) { + $this->proxy->setRevisionPHID($revision->getPHID()); + return $this; + } + + // Although these are purely transitional, they're also *extra* dumb. + + public function setRevisionID($revision_id) { + $revision = id(new DifferentialRevision())->load($revision_id); + return $this->setRevision($revision); + } + + public function getRevisionID() { + $phid = $this->proxy->getRevisionPHID(); + if (!$phid) { + return null; + } + + $revision = id(new DifferentialRevision())->loadOneWhere( + 'phid = %s', + $phid); + if (!$revision) { + return null; + } + return $revision->getID(); + } + + // When setting a comment ID, we also generate a phantom transaction PHID for + // the future transaction. + + public function setCommentID($id) { + $this->proxy->setLegacyCommentID($id); + $this->proxy->setTransactionPHID( + PhabricatorPHID::generateNewPHID( + PhabricatorApplicationTransactionPHIDTypeTransaction::TYPECONST, + DifferentialPHIDTypeRevision::TYPECONST)); + return $this; + } + + public function getCommentID() { + return $this->proxy->getLegacyCommentID(); } /* -( PhabricatorMarkupInterface Implementation )-------------------------- */ public function getMarkupFieldKey($field) { // We can't use ID because synthetic comments don't have it. return 'DI:'.PhabricatorHash::digest($this->getContent()); } public function newMarkupEngine($field) { return PhabricatorMarkupEngine::newDifferentialMarkupEngine(); } public function getMarkupText($field) { return $this->getContent(); } public function didMarkupText($field, $output, PhutilMarkupEngine $engine) { return $output; } public function shouldUseMarkupCache($field) { // Only cache submitted comments. return ($this->getID() && $this->getCommentID()); } } diff --git a/src/applications/differential/storage/DifferentialTransactionComment.php b/src/applications/differential/storage/DifferentialTransactionComment.php index c46d0c4b58..d527c44100 100644 --- a/src/applications/differential/storage/DifferentialTransactionComment.php +++ b/src/applications/differential/storage/DifferentialTransactionComment.php @@ -1,24 +1,24 @@ getTransactionPHID() != null); } } diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php index 638d1cf283..fab4e35706 100644 --- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php +++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php @@ -1,1685 +1,1689 @@ array( 'type' => 'db', 'name' => 'audit', 'after' => array( /* First Patch */ ), ), 'db.calendar' => array( 'type' => 'db', 'name' => 'calendar', ), 'db.chatlog' => array( 'type' => 'db', 'name' => 'chatlog', ), 'db.conduit' => array( 'type' => 'db', 'name' => 'conduit', ), 'db.countdown' => array( 'type' => 'db', 'name' => 'countdown', ), 'db.daemon' => array( 'type' => 'db', 'name' => 'daemon', ), 'db.differential' => array( 'type' => 'db', 'name' => 'differential', ), 'db.draft' => array( 'type' => 'db', 'name' => 'draft', ), 'db.drydock' => array( 'type' => 'db', 'name' => 'drydock', ), 'db.feed' => array( 'type' => 'db', 'name' => 'feed', ), 'db.file' => array( 'type' => 'db', 'name' => 'file', ), 'db.flag' => array( 'type' => 'db', 'name' => 'flag', ), 'db.harbormaster' => array( 'type' => 'db', 'name' => 'harbormaster', ), 'db.herald' => array( 'type' => 'db', 'name' => 'herald', ), 'db.maniphest' => array( 'type' => 'db', 'name' => 'maniphest', ), 'db.meta_data' => array( 'type' => 'db', 'name' => 'meta_data', ), 'db.metamta' => array( 'type' => 'db', 'name' => 'metamta', ), 'db.oauth_server' => array( 'type' => 'db', 'name' => 'oauth_server', ), 'db.owners' => array( 'type' => 'db', 'name' => 'owners', ), 'db.pastebin' => array( 'type' => 'db', 'name' => 'pastebin', ), 'db.phame' => array( 'type' => 'db', 'name' => 'phame', ), 'db.phriction' => array( 'type' => 'db', 'name' => 'phriction', ), 'db.project' => array( 'type' => 'db', 'name' => 'project', ), 'db.repository' => array( 'type' => 'db', 'name' => 'repository', ), 'db.search' => array( 'type' => 'db', 'name' => 'search', ), 'db.slowvote' => array( 'type' => 'db', 'name' => 'slowvote', ), 'db.timeline' => array( 'type' => 'db', 'name' => 'timeline', 'dead' => true, ), 'db.user' => array( 'type' => 'db', 'name' => 'user', ), 'db.worker' => array( 'type' => 'db', 'name' => 'worker', ), 'db.xhpastview' => array( 'type' => 'db', 'name' => 'xhpastview', ), 'db.cache' => array( 'type' => 'db', 'name' => 'cache', ), 'db.fact' => array( 'type' => 'db', 'name' => 'fact', ), 'db.ponder' => array( 'type' => 'db', 'name' => 'ponder', ), 'db.xhprof' => array( 'type' => 'db', 'name' => 'xhprof', ), 'db.pholio' => array( 'type' => 'db', 'name' => 'pholio', ), 'db.conpherence' => array( 'type' => 'db', 'name' => 'conpherence', ), 'db.config' => array( 'type' => 'db', 'name' => 'config', ), 'db.token' => array( 'type' => 'db', 'name' => 'token', ), 'db.releeph' => array( 'type' => 'db', 'name' => 'releeph', ), 'db.phlux' => array( 'type' => 'db', 'name' => 'phlux', ), 'db.phortune' => array( 'type' => 'db', 'name' => 'phortune', ), 'db.phrequent' => array( 'type' => 'db', 'name' => 'phrequent', ), 'db.diviner' => array( 'type' => 'db', 'name' => 'diviner', ), 'db.auth' => array( 'type' => 'db', 'name' => 'auth', ), 'db.doorkeeper' => array( 'type' => 'db', 'name' => 'doorkeeper', ), 'db.legalpad' => array( 'type' => 'db', 'name' => 'legalpad', ), 'db.policy' => array( 'type' => 'db', 'name' => 'policy', ), '0000.legacy.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('0000.legacy.sql'), 'legacy' => 0, ), '000.project.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('000.project.sql'), 'legacy' => 0, ), '001.maniphest_projects.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('001.maniphest_projects.sql'), 'legacy' => 1, ), '002.oauth.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('002.oauth.sql'), 'legacy' => 2, ), '003.more_oauth.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('003.more_oauth.sql'), 'legacy' => 3, ), '004.daemonrepos.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('004.daemonrepos.sql'), 'legacy' => 4, ), '005.workers.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('005.workers.sql'), 'legacy' => 5, ), '006.repository.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('006.repository.sql'), 'legacy' => 6, ), '007.daemonlog.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('007.daemonlog.sql'), 'legacy' => 7, ), '008.repoopt.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('008.repoopt.sql'), 'legacy' => 8, ), '009.repo_summary.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('009.repo_summary.sql'), 'legacy' => 9, ), '010.herald.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('010.herald.sql'), 'legacy' => 10, ), '011.badcommit.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('011.badcommit.sql'), 'legacy' => 11, ), '012.dropphidtype.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('012.dropphidtype.sql'), 'legacy' => 12, ), '013.commitdetail.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('013.commitdetail.sql'), 'legacy' => 13, ), '014.shortcuts.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('014.shortcuts.sql'), 'legacy' => 14, ), '015.preferences.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('015.preferences.sql'), 'legacy' => 15, ), '016.userrealnameindex.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('016.userrealnameindex.sql'), 'legacy' => 16, ), '017.sessionkeys.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('017.sessionkeys.sql'), 'legacy' => 17, ), '018.owners.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('018.owners.sql'), 'legacy' => 18, ), '019.arcprojects.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('019.arcprojects.sql'), 'legacy' => 19, ), '020.pathcapital.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('020.pathcapital.sql'), 'legacy' => 20, ), '021.xhpastview.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('021.xhpastview.sql'), 'legacy' => 21, ), '022.differentialcommit.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('022.differentialcommit.sql'), 'legacy' => 22, ), '023.dxkeys.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('023.dxkeys.sql'), 'legacy' => 23, ), '024.mlistkeys.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('024.mlistkeys.sql'), 'legacy' => 24, ), '025.commentopt.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('025.commentopt.sql'), 'legacy' => 25, ), '026.diffpropkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('026.diffpropkey.sql'), 'legacy' => 26, ), '027.metamtakeys.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('027.metamtakeys.sql'), 'legacy' => 27, ), '028.systemagent.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('028.systemagent.sql'), 'legacy' => 28, ), '029.cursors.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('029.cursors.sql'), 'legacy' => 29, ), '030.imagemacro.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('030.imagemacro.sql'), 'legacy' => 30, ), '031.workerrace.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('031.workerrace.sql'), 'legacy' => 31, ), '032.viewtime.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('032.viewtime.sql'), 'legacy' => 32, ), '033.privtest.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('033.privtest.sql'), 'legacy' => 33, ), '034.savedheader.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('034.savedheader.sql'), 'legacy' => 34, ), '035.proxyimage.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('035.proxyimage.sql'), 'legacy' => 35, ), '036.mailkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('036.mailkey.sql'), 'legacy' => 36, ), '037.setuptest.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('037.setuptest.sql'), 'legacy' => 37, ), '038.admin.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('038.admin.sql'), 'legacy' => 38, ), '039.userlog.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('039.userlog.sql'), 'legacy' => 39, ), '040.transform.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('040.transform.sql'), 'legacy' => 40, ), '041.heraldrepetition.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('041.heraldrepetition.sql'), 'legacy' => 41, ), '042.commentmetadata.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('042.commentmetadata.sql'), 'legacy' => 42, ), '043.pastebin.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('043.pastebin.sql'), 'legacy' => 43, ), '044.countdown.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('044.countdown.sql'), 'legacy' => 44, ), '045.timezone.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('045.timezone.sql'), 'legacy' => 45, ), '046.conduittoken.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('046.conduittoken.sql'), 'legacy' => 46, ), '047.projectstatus.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('047.projectstatus.sql'), 'legacy' => 47, ), '048.relationshipkeys.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('048.relationshipkeys.sql'), 'legacy' => 48, ), '049.projectowner.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('049.projectowner.sql'), 'legacy' => 49, ), '050.taskdenormal.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('050.taskdenormal.sql'), 'legacy' => 50, ), '051.projectfilter.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('051.projectfilter.sql'), 'legacy' => 51, ), '052.pastelanguage.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('052.pastelanguage.sql'), 'legacy' => 52, ), '053.feed.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('053.feed.sql'), 'legacy' => 53, ), '054.subscribers.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('054.subscribers.sql'), 'legacy' => 54, ), '055.add_author_to_files.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('055.add_author_to_files.sql'), 'legacy' => 55, ), '056.slowvote.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('056.slowvote.sql'), 'legacy' => 56, ), '057.parsecache.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('057.parsecache.sql'), 'legacy' => 57, ), '058.missingkeys.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('058.missingkeys.sql'), 'legacy' => 58, ), '059.engines.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('059.engines.php'), 'legacy' => 59, ), '060.phriction.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('060.phriction.sql'), 'legacy' => 60, ), '061.phrictioncontent.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('061.phrictioncontent.sql'), 'legacy' => 61, ), '062.phrictionmenu.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('062.phrictionmenu.sql'), 'legacy' => 62, ), '063.pasteforks.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('063.pasteforks.sql'), 'legacy' => 63, ), '064.subprojects.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('064.subprojects.sql'), 'legacy' => 64, ), '065.sshkeys.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('065.sshkeys.sql'), 'legacy' => 65, ), '066.phrictioncontent.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('066.phrictioncontent.sql'), 'legacy' => 66, ), '067.preferences.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('067.preferences.sql'), 'legacy' => 67, ), '068.maniphestauxiliarystorage.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('068.maniphestauxiliarystorage.sql'), 'legacy' => 68, ), '069.heraldxscript.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('069.heraldxscript.sql'), 'legacy' => 69, ), '070.differentialaux.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('070.differentialaux.sql'), 'legacy' => 70, ), '071.contentsource.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('071.contentsource.sql'), 'legacy' => 71, ), '072.blamerevert.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('072.blamerevert.sql'), 'legacy' => 72, ), '073.reposymbols.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('073.reposymbols.sql'), 'legacy' => 73, ), '074.affectedpath.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('074.affectedpath.sql'), 'legacy' => 74, ), '075.revisionhash.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('075.revisionhash.sql'), 'legacy' => 75, ), '076.indexedlanguages.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('076.indexedlanguages.sql'), 'legacy' => 76, ), '077.originalemail.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('077.originalemail.sql'), 'legacy' => 77, ), '078.nametoken.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('078.nametoken.sql'), 'legacy' => 78, ), '079.nametokenindex.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('079.nametokenindex.php'), 'legacy' => 79, ), '080.filekeys.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('080.filekeys.sql'), 'legacy' => 80, ), '081.filekeys.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('081.filekeys.php'), 'legacy' => 81, ), '082.xactionkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('082.xactionkey.sql'), 'legacy' => 82, ), '083.dxviewtime.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('083.dxviewtime.sql'), 'legacy' => 83, ), '084.pasteauthorkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('084.pasteauthorkey.sql'), 'legacy' => 84, ), '085.packagecommitrelationship.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('085.packagecommitrelationship.sql'), 'legacy' => 85, ), '086.formeraffil.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('086.formeraffil.sql'), 'legacy' => 86, ), '087.phrictiondelete.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('087.phrictiondelete.sql'), 'legacy' => 87, ), '088.audit.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('088.audit.sql'), 'legacy' => 88, ), '089.projectwiki.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('089.projectwiki.sql'), 'legacy' => 89, ), '090.forceuniqueprojectnames.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('090.forceuniqueprojectnames.php'), 'legacy' => 90, ), '091.uniqueslugkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('091.uniqueslugkey.sql'), 'legacy' => 91, ), '092.dropgithubnotification.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('092.dropgithubnotification.sql'), 'legacy' => 92, ), '093.gitremotes.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('093.gitremotes.php'), 'legacy' => 93, ), '094.phrictioncolumn.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('094.phrictioncolumn.sql'), 'legacy' => 94, ), '095.directory.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('095.directory.sql'), 'legacy' => 95, ), '096.filename.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('096.filename.sql'), 'legacy' => 96, ), '097.heraldruletypes.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('097.heraldruletypes.sql'), 'legacy' => 97, ), '098.heraldruletypemigration.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('098.heraldruletypemigration.php'), 'legacy' => 98, ), '099.drydock.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('099.drydock.sql'), 'legacy' => 99, ), '100.projectxaction.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('100.projectxaction.sql'), 'legacy' => 100, ), '101.heraldruleapplied.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('101.heraldruleapplied.sql'), 'legacy' => 101, ), '102.heraldcleanup.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('102.heraldcleanup.php'), 'legacy' => 102, ), '103.heraldedithistory.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('103.heraldedithistory.sql'), 'legacy' => 103, ), '104.searchkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('104.searchkey.sql'), 'legacy' => 104, ), '105.mimetype.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('105.mimetype.sql'), 'legacy' => 105, ), '106.chatlog.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('106.chatlog.sql'), 'legacy' => 106, ), '107.oauthserver.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('107.oauthserver.sql'), 'legacy' => 107, ), '108.oauthscope.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('108.oauthscope.sql'), 'legacy' => 108, ), '109.oauthclientphidkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('109.oauthclientphidkey.sql'), 'legacy' => 109, ), '110.commitaudit.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('110.commitaudit.sql'), 'legacy' => 110, ), '111.commitauditmigration.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('111.commitauditmigration.php'), 'legacy' => 111, ), '112.oauthaccesscoderedirecturi.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('112.oauthaccesscoderedirecturi.sql'), 'legacy' => 112, ), '113.lastreviewer.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('113.lastreviewer.sql'), 'legacy' => 113, ), '114.auditrequest.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('114.auditrequest.sql'), 'legacy' => 114, ), '115.prepareutf8.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('115.prepareutf8.sql'), 'legacy' => 115, ), '116.utf8-backup-first-expect-wait.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('116.utf8-backup-first-expect-wait.sql'), 'legacy' => 116, ), '117.repositorydescription.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('117.repositorydescription.php'), 'legacy' => 117, ), '118.auditinline.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('118.auditinline.sql'), 'legacy' => 118, ), '119.filehash.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('119.filehash.sql'), 'legacy' => 119, ), '120.noop.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('120.noop.sql'), 'legacy' => 120, ), '121.drydocklog.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('121.drydocklog.sql'), 'legacy' => 121, ), '122.flag.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('122.flag.sql'), 'legacy' => 122, ), '123.heraldrulelog.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('123.heraldrulelog.sql'), 'legacy' => 123, ), '124.subpriority.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('124.subpriority.sql'), 'legacy' => 124, ), '125.ipv6.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('125.ipv6.sql'), 'legacy' => 125, ), '126.edges.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('126.edges.sql'), 'legacy' => 126, ), '127.userkeybody.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('127.userkeybody.sql'), 'legacy' => 127, ), '128.phabricatorcom.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('128.phabricatorcom.sql'), 'legacy' => 128, ), '129.savedquery.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('129.savedquery.sql'), 'legacy' => 129, ), '130.denormalrevisionquery.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('130.denormalrevisionquery.sql'), 'legacy' => 130, ), '131.migraterevisionquery.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('131.migraterevisionquery.php'), 'legacy' => 131, ), '132.phame.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('132.phame.sql'), 'legacy' => 132, ), '133.imagemacro.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('133.imagemacro.sql'), 'legacy' => 133, ), '134.emptysearch.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('134.emptysearch.sql'), 'legacy' => 134, ), '135.datecommitted.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('135.datecommitted.sql'), 'legacy' => 135, ), '136.sex.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('136.sex.sql'), 'legacy' => 136, ), '137.auditmetadata.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('137.auditmetadata.sql'), 'legacy' => 137, ), '138.notification.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('138.notification.sql'), ), 'holidays.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('holidays.sql'), ), 'userstatus.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('userstatus.sql'), ), 'emailtable.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('emailtable.sql'), ), 'emailtableport.sql' => array( 'type' => 'php', 'name' => $this->getPatchPath('emailtableport.php'), ), 'emailtableremove.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('emailtableremove.sql'), ), 'phiddrop.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('phiddrop.sql'), ), 'testdatabase.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('testdatabase.sql'), ), 'ldapinfo.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('ldapinfo.sql'), ), 'threadtopic.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('threadtopic.sql'), ), 'usertranslation.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('usertranslation.sql'), ), 'differentialbookmarks.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('differentialbookmarks.sql'), ), 'harbormasterobject.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('harbormasterobject.sql'), ), 'markupcache.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('markupcache.sql'), ), 'maniphestxcache.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('maniphestxcache.sql'), ), 'migrate-maniphest-dependencies.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('migrate-maniphest-dependencies.php'), ), 'migrate-differential-dependencies.php' => array( 'type' => 'php', 'name' => $this->getPatchPath( 'migrate-differential-dependencies.php'), ), 'phameblog.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('phameblog.sql'), ), 'migrate-maniphest-revisions.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('migrate-maniphest-revisions.php'), ), 'daemonstatus.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('daemonstatus.sql'), ), 'symbolcontexts.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('symbolcontexts.sql'), ), 'migrate-project-edges.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('migrate-project-edges.php'), ), 'fact-raw.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('fact-raw.sql'), ), 'ponder.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('ponder.sql') ), 'policy-project.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('policy-project.sql'), ), 'daemonstatuskey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('daemonstatuskey.sql'), ), 'edgetype.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('edgetype.sql'), ), 'ponder-comments.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('ponder-comments.sql'), ), 'pastepolicy.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('pastepolicy.sql'), ), 'xhprof.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('xhprof.sql'), ), 'draft-metadata.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('draft-metadata.sql'), ), 'phamedomain.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('phamedomain.sql'), ), 'ponder-mailkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('ponder-mailkey.sql'), ), 'ponder-mailkey-populate.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('ponder-mailkey-populate.php'), ), 'phamepolicy.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('phamepolicy.sql'), ), 'phameoneblog.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('phameoneblog.sql'), ), 'statustxt.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('statustxt.sql'), ), 'daemontaskarchive.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('daemontaskarchive.sql'), ), 'drydocktaskid.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('drydocktaskid.sql'), ), 'drydockresoucetype.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('drydockresourcetype.sql'), ), 'liskcounters.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('liskcounters.sql'), ), 'liskcounters.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('liskcounters.php'), ), 'dropfileproxyimage.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('dropfileproxyimage.sql'), ), 'repository-lint.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('repository-lint.sql'), ), 'liskcounters-task.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('liskcounters-task.sql'), ), 'pholio.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('pholio.sql'), ), 'owners-exclude.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('owners-exclude.sql'), ), '20121209.pholioxactions.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20121209.pholioxactions.sql'), ), '20121209.xmacroadd.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20121209.xmacroadd.sql'), ), '20121209.xmacromigrate.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20121209.xmacromigrate.php'), ), '20121209.xmacromigratekey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20121209.xmacromigratekey.sql'), ), '20121220.generalcache.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20121220.generalcache.sql'), ), '20121226.config.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20121226.config.sql'), ), '20130101.confxaction.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130101.confxaction.sql'), ), '20130102.metamtareceivedmailmessageidhash.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130102.metamtareceivedmailmessageidhash.sql'), ), '20130103.filemetadata.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130103.filemetadata.sql'), ), '20130111.conpherence.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130111.conpherence.sql'), ), '20130127.altheraldtranscript.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130127.altheraldtranscript.sql'), ), '20130201.revisionunsubscribed.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130201.revisionunsubscribed.php'), ), '20130201.revisionunsubscribed.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130201.revisionunsubscribed.sql'), ), '20130131.conpherencepics.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130131.conpherencepics.sql'), ), '20130214.chatlogchannel.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130214.chatlogchannel.sql'), ), '20130214.chatlogchannelid.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130214.chatlogchannelid.sql'), ), '20130214.token.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130214.token.sql'), ), '20130215.phabricatorfileaddttl.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130215.phabricatorfileaddttl.sql'), ), '20130217.cachettl.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130217.cachettl.sql'), ), '20130218.updatechannelid.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130218.updatechannelid.php'), ), '20130218.longdaemon.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130218.longdaemon.sql'), ), '20130219.commitsummary.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130219.commitsummary.sql'), ), '20130219.commitsummarymig.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130219.commitsummarymig.php'), ), '20130222.dropchannel.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130222.dropchannel.sql'), ), '20130226.commitkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130226.commitkey.sql'), ), '20131302.maniphestvalue.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20131302.maniphestvalue.sql'), ), '20130304.lintauthor.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130304.lintauthor.sql'), ), 'releeph.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('releeph.sql'), ), '20130319.phabricatorfileexplicitupload.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath( '20130319.phabricatorfileexplicitupload.sql') ), '20130319.conpherence.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130319.conpherence.sql'), ), '20130320.phlux.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130320.phlux.sql'), ), '20130317.phrictionedge.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130317.phrictionedge.sql'), ), '20130321.token.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130321.token.sql'), ), '20130310.xactionmeta.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130310.xactionmeta.sql'), ), '20130322.phortune.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130322.phortune.sql'), ), '20130323.phortunepayment.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130323.phortunepayment.sql'), ), '20130324.phortuneproduct.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130324.phortuneproduct.sql'), ), '20130330.phrequent.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130330.phrequent.sql'), ), '20130403.conpherencecache.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130403.conpherencecache.sql'), ), '20130403.conpherencecachemig.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130403.conpherencecachemig.php'), ), '20130409.commitdrev.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130409.commitdrev.php'), ), '20130417.externalaccount.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130417.externalaccount.sql'), ), '20130423.updateexternalaccount.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130423.updateexternalaccount.sql'), ), '20130423.phortunepaymentrevised.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130423.phortunepaymentrevised.sql'), ), '20130423.conpherenceindices.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130423.conpherenceindices.sql'), ), '20130426.search_savedquery.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130426.search_savedquery.sql'), ), '20130502.countdownrevamp1.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130502.countdownrevamp1.sql'), ), '20130502.countdownrevamp2.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130502.countdownrevamp2.php'), ), '20130502.countdownrevamp3.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130502.countdownrevamp3.sql'), ), '20130507.releephrqsimplifycols.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130507.releephrqsimplifycols.sql'), ), '20130507.releephrqmailkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130507.releephrqmailkey.sql'), ), '20130507.releephrqmailkeypop.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130507.releephrqmailkeypop.php'), ), '20130508.search_namedquery.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130508.search_namedquery.sql'), ), '20130508.releephtransactions.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130508.releephtransactions.sql'), ), '20130508.releephtransactionsmig.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130508.releephtransactionsmig.php'), ), '20130513.receviedmailstatus.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130513.receviedmailstatus.sql'), ), '20130519.diviner.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130519.diviner.sql'), ), '20130521.dropconphimages.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130521.dropconphimages.sql'), ), '20130523.maniphest_owners.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130523.maniphest_owners.sql'), ), '20130524.repoxactions.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130524.repoxactions.sql'), ), '20130529.macroauthor.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130529.macroauthor.sql'), ), '20130529.macroauthormig.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130529.macroauthormig.php'), ), '20130530.sessionhash.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130530.sessionhash.php'), ), '20130530.macrodatekey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130530.macrodatekey.sql'), ), '20130530.pastekeys.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130530.pastekeys.sql'), ), '20130531.filekeys.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130531.filekeys.sql'), ), '20130602.morediviner.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130602.morediviner.sql'), ), '20130602.namedqueries.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130602.namedqueries.sql'), ), '20130606.userxactions.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130606.userxactions.sql'), ), '20130607.xaccount.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130607.xaccount.sql'), ), '20130611.migrateoauth.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130611.migrateoauth.php'), ), '20130611.nukeldap.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130611.nukeldap.php'), ), '20130613.authdb.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130613.authdb.sql'), ), '20130619.authconf.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130619.authconf.php'), ), '20130620.diffxactions.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130620.diffxactions.sql'), ), '20130621.diffcommentphid.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130621.diffcommentphid.sql'), ), '20130621.diffcommentphidmig.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130621.diffcommentphidmig.php'), ), '20130621.diffcommentunphid.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130621.diffcommentunphid.sql'), ), '20130622.doorkeeper.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130622.doorkeeper.sql'), ), '20130628.legalpadv0.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130628.legalpadv0.sql'), ), '20130701.conduitlog.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130701.conduitlog.sql'), ), 'legalpad-mailkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('legalpad-mailkey.sql'), ), 'legalpad-mailkey-populate.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('legalpad-mailkey-populate.php'), ), '20130703.legalpaddocdenorm.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130703.legalpaddocdenorm.sql'), ), '20130703.legalpaddocdenorm.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130703.legalpaddocdenorm.php'), ), '20130709.legalpadsignature.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130709.legalpadsignature.sql'), ), '20130709.droptimeline.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130709.droptimeline.sql'), ), '20130711.trimrealnames.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130711.trimrealnames.php'), ), '20130714.votexactions.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130714.votexactions.sql'), ), '20130715.votecomments.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130715.votecomments.php'), ), '20130715.voteedges.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130715.voteedges.sql'), ), '20130711.pholioimageobsolete.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130711.pholioimageobsolete.sql'), ), '20130711.pholioimageobsolete.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130711.pholioimageobsolete.php'), ), '20130711.pholioimageobsolete2.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130711.pholioimageobsolete2.sql'), ), '20130716.archivememberlessprojects.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130716.archivememberlessprojects.php'), ), '20130722.pholioreplace.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130722.pholioreplace.sql'), ), '20130723.taskstarttime.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130723.taskstarttime.sql'), ), '20130727.ponderquestionstatus.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130727.ponderquestionstatus.sql'), ), '20130726.ponderxactions.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130726.ponderxactions.sql'), ), '20130728.ponderunique.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130728.ponderunique.php'), ), '20130728.ponderuniquekey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130728.ponderuniquekey.sql'), ), '20130728.ponderxcomment.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130728.ponderxcomment.php'), ), '20130801.pastexactions.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130801.pastexactions.sql'), ), '20130801.pastexactions.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130801.pastexactions.php'), ), '20130805.pastemailkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130805.pastemailkey.sql'), ), '20130805.pasteedges.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130805.pasteedges.sql'), ), '20130805.pastemailkeypop.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130805.pastemailkeypop.php'), ), '20130802.heraldphid.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130802.heraldphid.sql'), ), '20130802.heraldphids.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130802.heraldphids.php'), ), '20130802.heraldphidukey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130802.heraldphidukey.sql'), ), '20130802.heraldxactions.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130802.heraldxactions.sql'), ), '20130731.releephrepoid.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130731.releephrepoid.sql'), ), '20130731.releephproject.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130731.releephproject.sql'), ), '20130731.releephcutpointidentifier.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130731.releephcutpointidentifier.sql'), ), '20130814.usercustom.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130814.usercustom.sql'), ), '20130820.releephxactions.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130820.releephxactions.sql'), ), '20130826.divinernode.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130826.divinernode.sql'), ), '20130820.filexactions.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130820.filexactions.sql'), ), '20130820.filemailkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130820.filemailkey.sql'), ), '20130820.file-mailkey-populate.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130820.file-mailkey-populate.php'), ), '20130912.maniphest.1.touch.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130912.maniphest.1.touch.sql'), ), '20130912.maniphest.2.created.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130912.maniphest.2.created.sql'), ), '20130912.maniphest.3.nameindex.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130912.maniphest.3.nameindex.sql'), ), '20130912.maniphest.4.fillindex.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130912.maniphest.4.fillindex.php'), ), '20130913.maniphest.1.migratesearch.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130913.maniphest.1.migratesearch.php'), ), '20130914.usercustom.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130914.usercustom.sql'), ), '20130915.maniphestcustom.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130915.maniphestcustom.sql'), ), '20130915.maniphestmigrate.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130915.maniphestmigrate.php'), ), '20130919.mfieldconf.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130919.mfieldconf.php'), ), '20130920.repokeyspolicy.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130920.repokeyspolicy.sql'), ), '20130921.mtransactions.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130921.mtransactions.sql'), ), '20130921.xmigratemaniphest.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20130921.xmigratemaniphest.php'), ), '20130923.mrename.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130923.mrename.sql'), ), '20130924.mdraftkey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130924.mdraftkey.sql'), ), '20130925.mpolicy.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130925.mpolicy.sql'), ), '20130925.xpolicy.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130925.xpolicy.sql'), ), '20130926.dcustom.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130926.dcustom.sql'), ), '20130926.dinkeys.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130926.dinkeys.sql'), ), '20130927.audiomacro.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130927.audiomacro.sql'), ), '20130929.filepolicy.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130929.filepolicy.sql'), ), '20131004.dxedgekey.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20131004.dxedgekey.sql'), ), '20131004.dxreviewers.php' => array( 'type' => 'php', 'name' => $this->getPatchPath('20131004.dxreviewers.php'), ), '20131006.hdisable.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20131006.hdisable.sql'), ), '20131010.pstorage.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20131010.pstorage.sql'), ), '20131015.cpolicy.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20131015.cpolicy.sql'), ), '20130915.maniphestqdrop.sql' => array( 'type' => 'sql', 'name' => $this->getPatchPath('20130915.maniphestqdrop.sql'), ), + '20130926.dinline.php' => array( + 'type' => 'php', + 'name' => $this->getPatchPath('20130926.dinline.php'), + ), ); } }