From feb1c4096d96eb8ac2c7cfd1a2e2f672913fa783 Mon Sep 17 00:00:00 2001 From: Dominique Fournier Date: Wed, 10 May 2017 12:38:01 +0000 Subject: [PATCH] - dblayeroo: Add the GROUP BY feature and the function support git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@3631 bf3deb0d-5f1a-0410-827f-c0cc1f45334c --- dblayeroo.php | 97 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 12 deletions(-) diff --git a/dblayeroo.php b/dblayeroo.php index 11650ba..ee9ca2f 100644 --- a/dblayeroo.php +++ b/dblayeroo.php @@ -1266,6 +1266,9 @@ class dblayeroo /** The values for each parameter for the WHERE condition */ private $whereValues = array (); + /** The columns in GROUP BY condition + */ + private $groupByExpression = array (); /** The ORDER expression */ private $orderExpression = array (); @@ -1446,18 +1449,76 @@ class dblayeroo $columnNames = explode (",", $columnNames); if ($this->displayColumn === null) $this->displayColumn = array (); - foreach ($columnNames as $name) + foreach ($columnNames as $display) { - $name = trim ($name); + $display = $name = trim ($display); + $pos = strpos ($display, "("); + if ($pos !== false) + { + $func = strtoupper (trim (substr ($name, 0, $pos))); + $name = trim (substr ($name, $pos+1, -1)); + if (in_array ($func, array ("AVG", "COUNT", "GROUP_CONCAT", "MAX", + "MIN","SUM"))) + { + // Aggregate function. Add the non aggregate fields to the GROUP BY + // expression, if not already done + if ($this->groupByExpression === array ()) + { + $aggregateFunction = true; + $this->groupByExpression = $this->displayColumn; + } + } + $display = "$func($name)"; + } if (! array_key_exists ($name, $this->fields)) $this->DBException (sprintf ( "Invalid field to display '%s' : not defined in table", $name)); - $this->displayColumn[$this->getSortOrder()] = $this->sep.$name.$this->sep; + $getSortOrder = $this->getSortOrder(); + if (! isset ($func)) + $this->displayColumn[$getSortOrder] = $this->sep.$display.$this->sep; + else + $this->displayColumn[$getSortOrder] = + "$func($this->sep$name$this->sep)"; + if ($this->groupByExpression !== array () && ! isset ($aggregateFunction)) + { + // Not a aggregate function, but groupBy is set : add the new field name + $this->groupByExpression[$getSortOrder] = $this->sep.$name.$this->sep; + } } return $this; } /* }}} */ + /** Return the name of the display field, with $this->sep + * Add the table prefix/name if full is set + * Allow name, $this->sep.$name.$this->sep, func(name), + * func($this->sep.$name.$this->sep), + * func($this->sep.$this->tableprefix.$this->table.$this->sep.".". + * $this->sep.$name.$this->sep) + * @param string $field The name of the field + * @param boolean|null $full Add the table prefix/name if set + */ + private function displayConvert ($name, $full = false) + /* {{{ */ + { + $pos = strpos ($name, "("); + if ($pos !== false) + { + $func = strtoupper (trim (substr ($name, 0, $pos))); + $name = trim (substr ($name, $pos+1, -1)); + } + if ($name[0] !== $this->sep) + $name = $this->sep.$name; + if (substr ($name, -1) !== $this->sep) + $name = $name.$this->sep; + if ($full !== false) + $name = $this->sep.$this->tableprefix.$this->table.$this->sep.".".$name; + if (isset ($func)) + $name = "$func($name)"; + return $name; + } + /* }}} */ + /** Get the columns set in the query by displayColumn. If the $full parameter * is set, add the table prefix/name to the result. * If the join object is set, ask to it the columns too @@ -1481,7 +1542,7 @@ class dblayeroo { foreach (array_keys ($this->fields) as $name) { - $displayColumn[$this->getSortOrder()] = $this->sep.$name.$this->sep; + $displayColumn[$this->getSortOrder()] = $this->displayConvert ($name); } } else @@ -1495,7 +1556,7 @@ class dblayeroo { foreach (array_keys ($this->fields) as $name) { - $displayColumn[$this->getSortOrder()] = $this->sep.$name.$this->sep; + $displayColumn[$this->getSortOrder()] = $this->displayConvert ($name); } } else @@ -1503,13 +1564,12 @@ class dblayeroo $displayColumn = $this->displayColumn; } } - foreach ($displayColumn as $pos=>$d) + foreach ($displayColumn as $pos=>$name) { if ($full !== false) - $columns[$pos] = $this->sep.$this->tableprefix.$this->table.$this->sep. - ".".$d; + $columns[$pos] = $this->displayConvert ($name, true); else - $columns[$pos] = $d; + $columns[$pos] = $this->displayConvert ($name); } if ($this->joinObject) { @@ -2429,11 +2489,16 @@ class dblayeroo $fieldsAll = $this->fieldsAll (false); if ($this->joinObject === null && count ($this->displayGet (false))) { - // Remove the columns names as there is no collisions risk + // Remove the table name as there is no collisions risk $columns = array (); foreach ($this->displayGet (false) as $col) { - $columns[] = substr ($col, 1 + strrpos ($col, $this->sep, -2), -1); + $pos = strpos ($col, "("); + if ($pos !== false) + $columns[] = substr ($col, 0, $pos+1). + substr ($col, $pos+2, -2).")"; + else + $columns[] = substr ($col, 1 + strrpos ($col, $this->sep, -2), -1); } } else @@ -2446,7 +2511,15 @@ class dblayeroo foreach ($row as $colNb=>$val) { // Harmonize the fetchAll result between all the databases drivers - if (strtolower ($fieldsAll[$columns[$colNb]][0]) === + if (strpos ($columns[$colNb], "(")) + { + // Function. The function that return an int must be added in this + // list, to cast correctely the value + $func = strtoupper (trim (substr ($columns[$colNb], 0, $pos))); + if (in_array ($func, array ("AVG", "COUNT", "MAX", "MIN", "SUM"))) + $val = intval ($val); + } + elseif (strtolower ($fieldsAll[$columns[$colNb]][0]) === "integer") $val = intval ($val); $colName = str_replace ($this->sep, "", $columns[$colNb]);