From 1bdf3d4ce66910f07842c7be1043938bccf0a462 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 12 Jan 2022 17:07:42 +0100 Subject: [statistics] Make query builder a bit more OOP --- .../statistics/inc/hardwarequerycolumn.inc.php | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 modules-available/statistics/inc/hardwarequerycolumn.inc.php (limited to 'modules-available/statistics/inc/hardwarequerycolumn.inc.php') diff --git a/modules-available/statistics/inc/hardwarequerycolumn.inc.php b/modules-available/statistics/inc/hardwarequerycolumn.inc.php new file mode 100644 index 00000000..d073530b --- /dev/null +++ b/modules-available/statistics/inc/hardwarequerycolumn.inc.php @@ -0,0 +1,88 @@ +classId = ++self::$id; + $this->global = $global; + $this->tableAlias = self::getId(); + $this->virtualColumnName = $column; + $this->alias = $alias ?? $column; + } + + /** + * Add necessary conditions, joins, columns to final SQL arrays. To be called + * from HardwareQuery::buildQuery(). + * @param bool $groupConcat whether to add distinct GROUP_CONCAT to column. + */ + public function generate(array &$joins, array &$columns, array &$params, bool $groupConcat) + { + if ($this->global) { + $srcTable = 'shw'; + $table = 'statistic_hw_prop'; + $column = 'hwid'; + } else { + $srcTable = 'mxhw'; + $table = 'machine_x_hw_prop'; + $column = 'machinehwid'; + } + $tid = $this->tableAlias; + $pid = self::getId(); + $this->conditions[] = "$srcTable.$column = $tid.$column AND $tid.prop = :$pid"; + $params[$pid] = $this->virtualColumnName; // value of property column is our virtual column + // If we have just one condition, it's the join condition itself. Since we pretend we're just adding + // a column to the query, do a left join, so the "column" is NULL if the join doesn't match. + // If however any conditions were added to this class via the addCondition() method, do a regular + // INNER JOIN, so the result will be empty if the condition doesn't match. + $type = count($this->conditions) === 1 ? 'LEFT' : 'INNER'; + $joins[] = "$type JOIN $table $tid ON (" . implode(' AND ', $this->conditions) . ")"; + if ($groupConcat) { + $columns[] = "Group_Concat(DISTINCT $tid.`value` SEPARATOR ', ') AS `{$this->alias}`"; + } else { + $columns[] = "$tid.`value` AS `{$this->alias}`"; + } + $params += $this->params; + } + + /** + * @param string $op Operator (<>=, IN, LIKE) + * @param string|string[]|HardwareQueryColumn $other value to compare with. + * Can be a literal, an array (if opererator is IN), or another Column + * @return void + */ + public function addCondition(string $op, $other) + { + $valueCol = ($op === '<' || $op === '>' || $op === '<=' || $op === '>=') ? 'numeric' : 'value'; + if ($other instanceof HardwareQueryColumn) { + $cond = "{$this->tableAlias}.`$valueCol` $op {$other->tableAlias}.`$valueCol`"; + // Don't reference a column of a table that hasn't been joined yet + if ($this->classId > $other->classId) { + $this->conditions[] = $cond; + } else { + $other->conditions[] = $cond; + } + } else { + $pid = self::getId(); + $this->conditions[] = "{$this->tableAlias}.`$valueCol` $op (:$pid)"; + $this->params[$pid] = $other; + } + } + +} \ No newline at end of file -- cgit v1.2.3-55-g7522