innerQuery === null) { $this->innerQuery = $this->prepareInnerQuery(); } return $this->innerQuery; } /** * Get our rollup query * * @return Select */ protected function rollupQuery() { if ($this->rollupQuery === null) { $this->rollupQuery = $this->prepareRollupQuery(); } return $this->rollupQuery; } /** * Add a specific named dimension * * @param string $name * @return $this */ public function addDimensionByName($name) { $this->addDimension($this->createDimension($name)); return $this; } /** * Set whether to show problems only * * @param bool $problemOnly * * @return $this */ public function problemsOnly(bool $problemOnly = true): self { $this->problemsOnly = $problemOnly; return $this; } /** * Get whether to show problems only * * @return bool */ public function isProblemsOnly(): bool { return $this->problemsOnly; } /** * Fetch the host variable dimensions * * @return array */ public function fetchHostVariableDimensions(): array { $query = Host::on($this->getDb()) ->with('customvar_flat') ->columns('customvar_flat.flatname') ->orderBy('customvar_flat.flatname'); $this->applyRestrictions($query); $query->getSelectBase()->groupBy('flatname'); $dimensions = []; foreach ($query as $row) { // Replaces array index notations with [*] to get results for arbitrary indexes $name = preg_replace('/\\[\d+](?=\\.|$)/', '[*]', $row->customvar_flat->flatname); $name = strtolower($name); $dimensions[CustomVariableDimension::HOST_PREFIX . $name] = 'Host ' . $name; } return $dimensions; } /** * Fetch the service variable dimensions * * @return array */ public function fetchServiceVariableDimensions(): array { $query = Service::on($this->getDb()) ->with('customvar_flat') ->columns('customvar_flat.flatname') ->orderBy('customvar_flat.flatname'); $this->applyRestrictions($query); $query->getSelectBase()->groupBy('flatname'); $dimensions = []; foreach ($query as $row) { // Replaces array index notations with [*] to get results for arbitrary indexes $name = preg_replace('/\\[\d+](?=\\.|$)/', '[*]', $row->customvar_flat->flatname); $name = strtolower($name); $dimensions[CustomVariableDimension::SERVICE_PREFIX . $name] = 'Service ' . $name; } return $dimensions; } /** * Set sort by columns * * @param ?string $sortBy * * @return $this */ public function sortBy(?string $sortBy): self { if (empty($sortBy)) { return $this; } $this->sortBy = SortUtil::createOrderBy($sortBy)[0]; return $this; } /** * Get sort by columns * * @return ?array Column as key and direction as value */ public function getSortBy(): ?array { return $this->sortBy; } /** * We first prepare the queries and to finalize it later on * * This way dimensions can be added one by one, they will be allowed to * optionally join additional tables or apply other modifications late * in the process * * @return void */ protected function finalizeInnerQuery() { $query = $this->innerQuery(); $select = $query->getSelectBase(); $columns = []; foreach ($this->dimensions as $name => $dimension) { $quotedDimension = $this->getDb()->quoteIdentifier([$name]); $dimension->addToCube($this); $columns[$quotedDimension] = $dimension->getColumnExpression($this); if ($this->hasSlice($name)) { $select->where( $dimension->getColumnExpression($this) . ' = ?', $this->slices[$name] ); } else { $columns[$quotedDimension] = $dimension->getColumnExpression($this); } } $select->columns($columns); $this->applyRestrictions($query); if ($this->hasBaseFilter()) { $query->filter($this->getBaseFilter()); } } protected function prepareRollupQuery() { $dimensions = $this->listDimensions(); $this->finalizeInnerQuery(); $columns = []; $groupBy = []; foreach ($dimensions as $name => $dimension) { $quotedDimension = $this->getDb()->quoteIdentifier([$name]); $columns[$quotedDimension] = 'f.' . $quotedDimension; $groupBy[] = $quotedDimension; } $availableFacts = $this->getAvailableFactColumns(); foreach ($this->chosenFacts as $alias) { $columns[$alias] = new Expression('SUM(f.' . $availableFacts[$alias] . ')'); } if (! empty($groupBy)) { if ($this->getDb()->getAdapter() instanceof Pgsql) { $groupBy = 'ROLLUP(' . implode(', ', $groupBy) . ')'; } else { $groupBy[count($groupBy) - 1] .= ' WITH ROLLUP'; } } $rollupQuery = new Select(); $rollupQuery->from(['f' => $this->innerQuery()->assembleSelect()]) ->columns($columns) ->groupBy($groupBy); return $rollupQuery; } protected function prepareFullQuery() { $rollupQuery = $this->rollupQuery(); $columns = []; $orderBy = []; $sortBy = $this->getSortBy(); foreach ($this->listColumns() as $column) { $quotedColumn = $this->getDb()->quoteIdentifier([$column]); $columns[$quotedColumn] = 'rollup.' . $quotedColumn; if ($this->hasDimension($column)) { $orderBy["($quotedColumn IS NOT NULL)"] = null; $sortDir = 'ASC'; if ($sortBy && self::DIMENSION_VALUE_SORT_PARAM === $sortBy[0]) { $sortDir = $sortBy[1] ?? 'ASC'; } $orderBy[$quotedColumn] = $sortDir; } } return (new Select()) ->from(['rollup' => $rollupQuery]) ->columns($columns) ->orderBy($orderBy); } /** * Lazy-load our full query * * @return Select */ protected function fullQuery() { if ($this->fullQuery === null) { $this->fullQuery = $this->prepareFullQuery(); } return $this->fullQuery; } public function fetchAll() { $query = $this->fullQuery(); return $this->getDb()->fetchAll($query); } }