[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/diffusion/query/ -> DiffusionSymbolQuery.php (source)

   1  <?php
   2  
   3  /**
   4   * Query symbol information (class and function names and location), returning
   5   * a list of matching @{class:PhabricatorRepositorySymbol} objects and possibly
   6   * attached data.
   7   *
   8   * @task config   Configuring the Query
   9   * @task exec     Executing the Query
  10   * @task internal Internals
  11   */
  12  final class DiffusionSymbolQuery extends PhabricatorOffsetPagedQuery {
  13  
  14    private $context;
  15    private $namePrefix;
  16    private $name;
  17  
  18    private $projectIDs;
  19    private $language;
  20    private $type;
  21  
  22    private $needPaths;
  23    private $needArcanistProject;
  24    private $needRepositories;
  25  
  26  
  27  /* -(  Configuring the Query  )---------------------------------------------- */
  28  
  29  
  30    /**
  31     * @task config
  32     */
  33    public function setContext($context) {
  34      $this->context = $context;
  35      return $this;
  36    }
  37  
  38  
  39    /**
  40     * @task config
  41     */
  42    public function setName($name) {
  43      $this->name = $name;
  44      return $this;
  45    }
  46  
  47  
  48    /**
  49     * @task config
  50     */
  51    public function setNamePrefix($name_prefix) {
  52      $this->namePrefix = $name_prefix;
  53      return $this;
  54    }
  55  
  56  
  57    /**
  58     * @task config
  59     */
  60    public function setProjectIDs(array $project_ids) {
  61      $this->projectIDs = $project_ids;
  62      return $this;
  63    }
  64  
  65  
  66    /**
  67     * @task config
  68     */
  69    public function setLanguage($language) {
  70      $this->language = $language;
  71      return $this;
  72    }
  73  
  74  
  75    /**
  76     * @task config
  77     */
  78    public function setType($type) {
  79      $this->type = $type;
  80      return $this;
  81    }
  82  
  83  
  84    /**
  85     * @task config
  86     */
  87    public function needPaths($need_paths) {
  88      $this->needPaths = $need_paths;
  89      return $this;
  90    }
  91  
  92  
  93    /**
  94     * @task config
  95     */
  96    public function needArcanistProjects($need_arcanist_projects) {
  97      $this->needArcanistProjects = $need_arcanist_projects;
  98      return $this;
  99    }
 100  
 101  
 102    /**
 103     * @task config
 104     */
 105    public function needRepositories($need_repositories) {
 106      $this->needRepositories = $need_repositories;
 107      return $this;
 108    }
 109  
 110  
 111  /* -(  Executing the Query  )------------------------------------------------ */
 112  
 113  
 114    /**
 115     * @task exec
 116     */
 117    public function execute() {
 118      if ($this->name && $this->namePrefix) {
 119        throw new Exception(
 120          'You can not set both a name and a name prefix!');
 121      } else if (!$this->name && !$this->namePrefix) {
 122        throw new Exception(
 123          'You must set a name or a name prefix!');
 124      }
 125  
 126      $symbol = new PhabricatorRepositorySymbol();
 127      $conn_r = $symbol->establishConnection('r');
 128  
 129      $data = queryfx_all(
 130        $conn_r,
 131        'SELECT * FROM %T %Q %Q %Q',
 132        $symbol->getTableName(),
 133        $this->buildWhereClause($conn_r),
 134        $this->buildOrderClause($conn_r),
 135        $this->buildLimitClause($conn_r));
 136  
 137      $symbols = $symbol->loadAllFromArray($data);
 138  
 139      if ($symbols) {
 140        if ($this->needPaths) {
 141          $this->loadPaths($symbols);
 142        }
 143        if ($this->needArcanistProjects || $this->needRepositories) {
 144          $this->loadArcanistProjects($symbols);
 145        }
 146        if ($this->needRepositories) {
 147          $this->loadRepositories($symbols);
 148        }
 149  
 150      }
 151  
 152      return $symbols;
 153    }
 154  
 155  
 156  /* -(  Internals  )---------------------------------------------------------- */
 157  
 158  
 159    /**
 160     * @task internal
 161     */
 162    private function buildOrderClause($conn_r) {
 163      return qsprintf(
 164        $conn_r,
 165        'ORDER BY symbolName ASC');
 166    }
 167  
 168  
 169    /**
 170     * @task internal
 171     */
 172    private function buildWhereClause($conn_r) {
 173      $where = array();
 174  
 175      if (isset($this->context)) {
 176        $where[] = qsprintf(
 177          $conn_r,
 178          'symbolContext = %s',
 179          $this->context);
 180      }
 181  
 182      if ($this->name) {
 183        $where[] = qsprintf(
 184          $conn_r,
 185          'symbolName = %s',
 186          $this->name);
 187      }
 188  
 189      if ($this->namePrefix) {
 190        $where[] = qsprintf(
 191          $conn_r,
 192          'symbolName LIKE %>',
 193          $this->namePrefix);
 194      }
 195  
 196      if ($this->projectIDs) {
 197        $where[] = qsprintf(
 198          $conn_r,
 199          'arcanistProjectID IN (%Ld)',
 200          $this->projectIDs);
 201      }
 202  
 203      if ($this->language) {
 204        $where[] = qsprintf(
 205          $conn_r,
 206          'symbolLanguage = %s',
 207          $this->language);
 208      }
 209  
 210      if ($this->type) {
 211        $where[] = qsprintf(
 212          $conn_r,
 213          'symbolType = %s',
 214          $this->type);
 215      }
 216  
 217      return $this->formatWhereClause($where);
 218    }
 219  
 220  
 221    /**
 222     * @task internal
 223     */
 224    private function loadPaths(array $symbols) {
 225      assert_instances_of($symbols, 'PhabricatorRepositorySymbol');
 226      $path_map = queryfx_all(
 227        id(new PhabricatorRepository())->establishConnection('r'),
 228        'SELECT * FROM %T WHERE id IN (%Ld)',
 229        PhabricatorRepository::TABLE_PATH,
 230        mpull($symbols, 'getPathID'));
 231      $path_map = ipull($path_map, 'path', 'id');
 232      foreach ($symbols as $symbol) {
 233        $symbol->attachPath(idx($path_map, $symbol->getPathID()));
 234      }
 235    }
 236  
 237  
 238    /**
 239     * @task internal
 240     */
 241    private function loadArcanistProjects(array $symbols) {
 242      assert_instances_of($symbols, 'PhabricatorRepositorySymbol');
 243      $projects = id(new PhabricatorRepositoryArcanistProject())->loadAllWhere(
 244        'id IN (%Ld)',
 245        mpull($symbols, 'getArcanistProjectID'));
 246      foreach ($symbols as $symbol) {
 247        $project = idx($projects, $symbol->getArcanistProjectID());
 248        $symbol->attachArcanistProject($project);
 249      }
 250    }
 251  
 252  
 253    /**
 254     * @task internal
 255     */
 256    private function loadRepositories(array $symbols) {
 257      assert_instances_of($symbols, 'PhabricatorRepositorySymbol');
 258  
 259      $projects = mpull($symbols, 'getArcanistProject');
 260      $projects = array_filter($projects);
 261  
 262      $repo_ids = mpull($projects, 'getRepositoryID');
 263      $repo_ids = array_filter($repo_ids);
 264  
 265      if ($repo_ids) {
 266        // TODO: (T603) Provide a viewer here.
 267        $repos = id(new PhabricatorRepository())->loadAllWhere(
 268          'id IN (%Ld)',
 269          $repo_ids);
 270      } else {
 271        $repos = array();
 272      }
 273  
 274      foreach ($symbols as $symbol) {
 275        $proj = $symbol->getArcanistProject();
 276        if ($proj) {
 277          $symbol->attachRepository(idx($repos, $proj->getRepositoryID()));
 278        } else {
 279          $symbol->attachRepository(null);
 280        }
 281      }
 282    }
 283  
 284  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1