From d61b7618d9c04ff90fdf8d3b584ad5976faedad9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 14 Apr 2024 15:16:36 +0200 Subject: Adding upstream version 1.3.2. Signed-off-by: Daniel Baumann --- library/Cube/IcingaDb/IcingaDbCube.php | 338 +++++++++++++++++++++++++++++++++ 1 file changed, 338 insertions(+) create mode 100644 library/Cube/IcingaDb/IcingaDbCube.php (limited to 'library/Cube/IcingaDb/IcingaDbCube.php') diff --git a/library/Cube/IcingaDb/IcingaDbCube.php b/library/Cube/IcingaDb/IcingaDbCube.php new file mode 100644 index 0000000..44c7619 --- /dev/null +++ b/library/Cube/IcingaDb/IcingaDbCube.php @@ -0,0 +1,338 @@ +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); + } +} -- cgit v1.2.3