diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 82341ac212..8b1e8fadbc 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -501,6 +501,7 @@ phutil_register_library_map(array( 'DiffusionInlineCommentPreviewController' => 'applications/diffusion/controller/DiffusionInlineCommentPreviewController.php', 'DiffusionLastModifiedController' => 'applications/diffusion/controller/DiffusionLastModifiedController.php', 'DiffusionLintController' => 'applications/diffusion/controller/DiffusionLintController.php', + 'DiffusionLintCountQuery' => 'applications/diffusion/query/DiffusionLintCountQuery.php', 'DiffusionLintDetailsController' => 'applications/diffusion/controller/DiffusionLintDetailsController.php', 'DiffusionLintSaveRunner' => 'applications/diffusion/DiffusionLintSaveRunner.php', 'DiffusionLowLevelCommitFieldsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelCommitFieldsQuery.php', @@ -3141,6 +3142,7 @@ phutil_register_library_map(array( 'DiffusionInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController', 'DiffusionLastModifiedController' => 'DiffusionController', 'DiffusionLintController' => 'DiffusionController', + 'DiffusionLintCountQuery' => 'PhabricatorQuery', 'DiffusionLintDetailsController' => 'DiffusionController', 'DiffusionLowLevelCommitFieldsQuery' => 'DiffusionLowLevelQuery', 'DiffusionLowLevelCommitQuery' => 'DiffusionLowLevelQuery', diff --git a/src/applications/diffusion/query/DiffusionLintCountQuery.php b/src/applications/diffusion/query/DiffusionLintCountQuery.php new file mode 100644 index 0000000000..1b227815f7 --- /dev/null +++ b/src/applications/diffusion/query/DiffusionLintCountQuery.php @@ -0,0 +1,120 @@ +branchIDs = $branch_ids; + return $this; + } + + public function withPaths(array $paths) { + $this->paths = $paths; + return $this; + } + + public function withCodes(array $codes) { + $this->codes = $codes; + return $this; + } + + public function execute() { + if (!$this->paths) { + throw new Exception(pht("Call withPaths() before execute()!")); + } + + if (!$this->branchIDs) { + throw new Exception(pht("Call withBranchIDs() before execute()!")); + } + + $conn_r = id(new PhabricatorRepositoryCommit())->establishConnection('r'); + + $this->paths = array_unique($this->paths); + list($dirs, $paths) = $this->processPaths(); + + $parts = array(); + foreach ($dirs as $dir) { + $parts[$dir] = qsprintf( + $conn_r, + 'path LIKE %>', + $dir); + } + foreach ($paths as $path) { + $parts[$path] = qsprintf( + $conn_r, + 'path = %s', + $path); + } + + $queries = array(); + foreach ($parts as $key => $part) { + $queries[] = qsprintf( + $conn_r, + 'SELECT %s path_prefix, COUNT(*) N FROM %T %Q', + $key, + PhabricatorRepository::TABLE_LINTMESSAGE, + $this->buildWhereClause($conn_r, $part)); + } + + $huge_union_query = '('.implode(') UNION ALL (', $queries).')'; + + $data = queryfx_all( + $conn_r, + '%Q', + $huge_union_query); + + return $this->processResults($data); + } + + private function buildWhereClause(AphrontDatabaseConnection $conn_r, $part) { + $where = array(); + + $where[] = $part; + + if ($this->codes !== null) { + $where[] = qsprintf( + $conn_r, + 'code IN (%Ls)', + $this->codes); + } + + if ($this->branchIDs !== null) { + $where[] = qsprintf( + $conn_r, + 'branchID IN (%Ld)', + $this->branchIDs); + } + + return $this->formatWhereClause($where); + } + + private function processPaths() { + $dirs = array(); + $paths = array(); + foreach ($this->paths as $path) { + $path = '/'.$path; + if (substr($path, -1) == '/') { + $dirs[] = $path; + } else { + $paths[] = $path; + } + } + return array($dirs, $paths); + } + + private function processResults(array $data) { + $data = ipull($data, 'N', 'path_prefix'); + + // Strip the leading "/" back off each path. + $output = array(); + foreach ($data as $path => $count) { + $output[substr($path, 1)] = $count; + } + + return $output; + } + +} diff --git a/src/applications/diffusion/view/DiffusionBrowseTableView.php b/src/applications/diffusion/view/DiffusionBrowseTableView.php index cf64a18d7c..26ab5efcf1 100644 --- a/src/applications/diffusion/view/DiffusionBrowseTableView.php +++ b/src/applications/diffusion/view/DiffusionBrowseTableView.php @@ -87,28 +87,24 @@ final class DiffusionBrowseTableView extends DiffusionView { } private static function loadLintMessagesCount(DiffusionRequest $drequest) { + $path = $drequest->getPath(); $branch = $drequest->loadBranch(); if (!$branch) { return null; } - $conn = $drequest->getRepository()->establishConnection('r'); + $query = id(new DiffusionLintCountQuery()) + ->withBranchIDs(array($branch->getID())) + ->withPaths(array($path)); - $path = '/'.$drequest->getPath(); - $where = (substr($path, -1) == '/' - ? qsprintf($conn, 'AND path LIKE %>', $path) - : qsprintf($conn, 'AND path = %s', $path)); - - if ($drequest->getLint()) { - $where .= qsprintf($conn, ' AND code = %s', $drequest->getLint()); + $code = $drequest->getLint(); + if ($code) { + $query->withCodes(array($code)); } - return head(queryfx_one( - $conn, - 'SELECT COUNT(*) FROM %T WHERE branchID = %d %Q', - PhabricatorRepository::TABLE_LINTMESSAGE, - $branch->getID(), - $where)); + $result = $query->execute(); + + return idx($result, $path); } public function render() {