diff options
author | Simon Rettberg | 2022-01-12 17:07:42 +0100 |
---|---|---|
committer | Simon Rettberg | 2022-03-09 15:06:54 +0100 |
commit | 1bdf3d4ce66910f07842c7be1043938bccf0a462 (patch) | |
tree | d6a4e1f0185687c224e4a3a901186fe3b0cbd3d9 /modules-available/statistics/inc/hardwarequerycolumn.inc.php | |
parent | api: Don't use mb_strtolower (diff) | |
download | slx-admin-1bdf3d4ce66910f07842c7be1043938bccf0a462.tar.gz slx-admin-1bdf3d4ce66910f07842c7be1043938bccf0a462.tar.xz slx-admin-1bdf3d4ce66910f07842c7be1043938bccf0a462.zip |
[statistics] Make query builder a bit more OOP
Diffstat (limited to 'modules-available/statistics/inc/hardwarequerycolumn.inc.php')
-rw-r--r-- | modules-available/statistics/inc/hardwarequerycolumn.inc.php | 88 |
1 files changed, 88 insertions, 0 deletions
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 @@ +<?php + +class HardwareQueryColumn +{ + /** @var int For unique table names in join */ + private static $id = 0; + + private $global; + private $tableAlias; + private $virtualColumnName; + private $alias; + private $conditions = []; + private $params = []; + private $classId; + + private static function getId(): string + { + return 't' . ++self::$id; + } + + public function __construct(bool $global, string $column, string $alias = null) + { + $this->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 |