ORM: Gestion des fonctions d'aggrégation (AVG, SUM, COUNT, MIN, MAX) + possibilité d'ajouter 'DISTINCT', GROUP BY pas encore géré

This commit is contained in:
xdrm-brackets 2016-07-25 00:26:58 +02:00
parent 33a0df3065
commit d8a828f9a3
13 changed files with 105 additions and 74 deletions

View File

@ -10,6 +10,8 @@
/* CONSTANTES */ /* CONSTANTES */
// {1} Conditions //
const COND_EQUAL = '__=__'; const COND_EQUAL = '__=__';
const COND_NOTEQ = '__<>__'; const COND_NOTEQ = '__<>__';
const COND_INF = '__<__'; const COND_INF = '__<__';
@ -19,6 +21,16 @@
const COND_LIKE = '__LIKE__'; const COND_LIKE = '__LIKE__';
const COND_IN = '__IN__'; const COND_IN = '__IN__';
// {2} Fonctions d'aggrégation //
const SEL_AVG = '__AVG__';
const SEL_SUM = '__SUM__';
const SEL_MAX = '__MAX__';
const SEL_MIN = '__MIN__';
const SEL_COUNT = '__COUNT__';
const SEL_DISTINCT = true;
// {3} Constantes d'insertion //
const INSERT_DEFAULT = '__DEFAULT__'; // Valeur DEFAULT (pour insertion) const INSERT_DEFAULT = '__DEFAULT__'; // Valeur DEFAULT (pour insertion)
/* Attributs */ /* Attributs */
@ -228,33 +240,42 @@
/* SELECTIONNE UNIQUEMENT LES CHAMPS SELECTIONNES /* SELECTIONNE UNIQUEMENT LE CHAMP SELECTIONNE
* *
* @fields<Array> Libellé du champ à afficher * @field<String> Libellé du champ à afficher
* @func<CONST> Fonction d'aggrégation (ou NULL)
* @distinct<Boolean> Clause DISTINCT
* *
* @return this<Rows> Retourne l'object courant * @return this<Rows> Retourne l'object courant
* *
*/ */
public function select($fields=[]){ public function select($field=null, $func=null, $distinct=false){
/* [1] On formatte les champs /* [1] On formatte les champs
=========================================================*/ =========================================================*/
/* (1) On met en tableau quoi qu'il en soit */ /* (1) On vérifie le type de @field */
$fields = is_array($fields) ? $fields : [$fields]; if( !is_string($field) )
return $this;
/* (2) On vérifie que chaque champ existe, sinon on le retire */ /* (2) On vérifie que la colonne @field existe, sinon on quitte */
foreach($fields as $f=>$field) if( !isset($this->schema['columns'][$field]) && $field != '*' )
if( !isset($this->schema['columns'][$field]) && $field != '*' ) return $this;
unset($fields[$f]);
/* (3) Permet d'avoir les indices de 0 à count-1 */ /* (3) On vérifie @func */
sort($fields); $funcList = [self::SEL_AVG, self::SEL_SUM, self::SEL_MAX, self::SEL_MIN, self::SEL_COUNT];
// Si condition non nulle et pas référencée, on quitte
if( !is_null($func) && !in_array($func, $funcList) )
return $this;
/* (4) On met la valeur par défaut à @distinct si type mauvais */
$distinct = !is_bool($distinct) ? false : $distinct;
/* [2] On enregistre la liste des champs /* [2] On enregistre le champ
=========================================================*/ =========================================================*/
foreach($fields as $f=>$field) /* (1) Si aucun SELECT pour ce champ, on le crée */
if( !in_array($field, $this->select) ) // On ajoute si pas déja if( !isset($this->select[$field]) )
$this->select[] = $field; $this->select[$field] = [$func, $distinct];
/* [3] On retourne l'object courant /* [3] On retourne l'object courant
@ -815,6 +836,16 @@
/* [6] Clause GROUP BY
=========================================================*/
$nonAggregatedTables = [];
foreach($this->select as $field=>$sel){
}
/* [6] Clause LIMIT /* [6] Clause LIMIT
=========================================================*/ =========================================================*/
$requestS['LIMIT'] = ($this->unique) ? SQLBuilder::LIMIT(1) : SQLBuilder::LIMIT([]); $requestS['LIMIT'] = ($this->unique) ? SQLBuilder::LIMIT(1) : SQLBuilder::LIMIT([]);
@ -828,6 +859,7 @@
/* (2) On compose la requête */ /* (2) On compose la requête */
$requestString = SQLBuilder::BUILD($requestS).';'; $requestString = SQLBuilder::BUILD($requestS).';';
var_dump($requestString);
/* (3) On prépare la requête */ /* (3) On prépare la requête */
$request = Database::getPDO()->prepare($requestString); $request = Database::getPDO()->prepare($requestString);

View File

@ -11,7 +11,7 @@
/* CONSTRUIT LA REQUETE FORMATTEE "SELECT" AVEC UNE LISTE DE CHAMPS /* CONSTRUIT LA REQUETE FORMATTEE "SELECT" AVEC UNE LISTE DE CHAMPS
* *
* @sqlFields<Array> Liste de champ/tables contenant des champs * @sqlFields<Array> Liste de champs : [table => field => func, alias]
* *
* @return sql<Array> Renvoie un tableau formatté * @return sql<Array> Renvoie un tableau formatté
* *
@ -24,9 +24,22 @@
/* [1] On construit la requête /* [1] On construit la requête
=========================================================*/ =========================================================*/
$c = 0; $c = 0;
foreach($sqlFields as $table=>$fields) foreach($sqlFields as $table=>$tableContent)
foreach($fields as $field){ foreach($tableContent as $field=>$select){
$sql[$c] = $table.'.'.$field;
/* (1) On construit le nom du champ */
$fieldStr = "$table.$field";
/* (2) On ajout le DISTINCT s'il y a lieu */
if( $select[1] )
$fieldStr = "DISTINCT $fieldStr";
/* (3) On ajoute la fonction d'aggrégation s'il y a lieu */
if( !is_null($select[0]) )
$fieldStr = substr($select[0], 2, -2)."($fieldStr)";
/* (4) On ajoute l'alias */
$sql[] = "$fieldStr as $field";
$c++; $c++;
} }

View File

@ -105,7 +105,7 @@
/* [2] On vérifie que le template existe /* [2] On vérifie que le template existe
=========================================================*/ =========================================================*/
$class = '\\manager\\view\\'.$match[1].'\\'.$match[2]; $class = '\\manager\\views\\'.$match[1].'\\'.$match[2];
$method = 'view'; $method = 'view';
/* (1) On vérifie que la classe existe */ /* (1) On vérifie que la classe existe */

View File

@ -1,6 +1,6 @@
<?php <?php
namespace manager\view\group; namespace manager\views\group;
use \manager\View; use \manager\View;
use \manager\ModuleRequest; use \manager\ModuleRequest;
use \manager\ManagerError; use \manager\ManagerError;

View File

@ -1,6 +1,6 @@
<?php <?php
namespace manager\view\group; namespace manager\views\group;
use \manager\View; use \manager\View;
use \manager\ModuleRequest; use \manager\ModuleRequest;
use \manager\ManagerError; use \manager\ManagerError;

View File

@ -1,6 +1,6 @@
<?php <?php
namespace manager\view\group; namespace manager\views\group;
use \manager\View; use \manager\View;
use \manager\ModuleRequest; use \manager\ModuleRequest;
use \manager\Authentification; use \manager\Authentification;

View File

@ -1,6 +1,6 @@
<?php <?php
namespace manager\view\machine; namespace manager\views\machine;
use \manager\View; use \manager\View;
use \manager\ModuleRequest; use \manager\ModuleRequest;
use \manager\Authentification; use \manager\Authentification;

View File

@ -1,6 +1,6 @@
<?php <?php
namespace manager\view\machine; namespace manager\views\machine;
use \manager\View; use \manager\View;
use \manager\ModuleRequest; use \manager\ModuleRequest;
use \manager\Authentification; use \manager\Authentification;

View File

@ -1,6 +1,6 @@
<?php <?php
namespace manager\view\user; namespace manager\views\user;
use \manager\View; use \manager\View;
use \manager\ModuleRequest; use \manager\ModuleRequest;
use \manager\Authentification; use \manager\Authentification;

View File

@ -1,6 +1,6 @@
<?php <?php
namespace manager\view\user; namespace manager\views\user;
use \manager\View; use \manager\View;
use \manager\ModuleRequest; use \manager\ModuleRequest;
use \manager\Authentification; use \manager\Authentification;

View File

@ -345,24 +345,24 @@
/* [1] FETCH /* [1] FETCH
=========================================================*/ =========================================================*/
$warehouse = // $warehouse =
Table::get('warehouse') // Table : WAREHOUSE // Table::get('warehouse') // Table : WAREHOUSE
->whereName(['stef-montauban', Rows::COND_EQUAL]) // condition : name = 'stef-montauban' // ->whereName(['stef-montauban', Rows::COND_EQUAL]) // condition : name = 'stef-montauban'
->select('name') // select : warehouse.name // ->select('name') // select : warehouse.name
->unique(); // limit : 1 // ->unique(); // limit : 1
//
$myUser = // $myUser =
Table::get('user') // Table : USER // Table::get('user') // Table : USER
->whereId([100, Rows::COND_INF]) // condition : clé primaire(id_user) < 100 // ->whereId([100, Rows::COND_INF]) // condition : clé primaire(id_user) < 100
->whereId([[94, 95, 96], Rows::COND_IN]) // condition : clé primaire(id_user) parmi les valeurs [94, 95, 96] // ->whereId([[94, 95, 96], Rows::COND_IN]) // condition : clé primaire(id_user) parmi les valeurs [94, 95, 96]
->whereUsername(['%e%', Rows::COND_LIKE]) // condition : username LIKE '%e%' // ->whereUsername(['%e%', Rows::COND_LIKE]) // condition : username LIKE '%e%'
->select(['mail', 'username', 'firstname']) // select : user.mail, user.username, user.firstname // ->select('name') // Select : user.id_user
->select('id_user') // Select : user.id_user // ->select('id_user', Rows::SEL_COUNT)
->join('id_warehouse', $warehouse) // jointure la table WAREHOUSE (automatique, soit référence, soit primaire soit même référence) // ->join('id_warehouse', $warehouse) // jointure la table WAREHOUSE (automatique, soit référence, soit primaire soit même référence)
//
// SELECT // // SELECT
->fetch(); // ->fetch();
var_dump($myUser); // var_dump($myUser);
// SELECT user.firstname, user.mail, user.username, user.id_user, warehouse.name // SELECT user.firstname, user.mail, user.username, user.id_user, warehouse.name
@ -447,32 +447,12 @@
// $warehouse = Table::get('warehouse') $selReq = Database::getPDO()->query("select m.*, max(h.timestamp) as last
// ->whereName(['stef%', Rows::COND_LIKE]) from history as h, machine as m
// ->select('id_warehouse'); where h.id_machine = m.id_machine
// group by h.id_machine");
// $module_merge = Table::get('module_merge') $selected = Database::delNumeric( $selReq->fetchAll() );
// ->join('id_warehouse', $warehouse) var_dump($selected);
// ->select('id_module_merge');
//
// $module = Table::get('module')
// ->join('id_module', $module_merge)
// ->select('id_module');
//
// $chip = Table::get('chip')
// ->select('id_chip')
// ->join('id_module', $module);
//
// var_dump($chip->fetch());
// SELECT module.id_module
// FROM chip,
// (SELECT * FROM module) as module,
// (SELECT * FROM module_merge) as module_merge,
// (SELECT * FROM warehouse WHERE warehouse.name LIKE 'stef%') as warehouse
// WHERE chip.id_module = module.id_module
// AND module.id_module = module_merge.id_module
// AND module_merge.id_warehouse = warehouse.id_warehouse

View File

@ -4,6 +4,8 @@
use \manager\ManagerError; use \manager\ManagerError;
use \manager\Database; use \manager\Database;
use \manager\Repo; use \manager\Repo;
use \manager\ORM\Table; use \manager\ORM\Rows;
?> ?>
<!-- [1] Gestion du sous-menu de gauche --> <!-- [1] Gestion du sous-menu de gauche -->
@ -55,12 +57,14 @@
/* (1) On récupère les données /* (1) On récupère les données
---------------------------------------------------------*/ ---------------------------------------------------------*/
$selReq = Database::getPDO()->query("select m.*, count(distinct h.id_user) as users, max(h.timestamp) as last $selReq = Database::getPDO()->query("select m.*, max(h.timestamp) as last
from history as h, machine as m from history as h, machine as m
where h.id_machine = m.id_machine where h.id_machine = m.id_machine
group by h.id_machine"); group by h.id_machine");
$selected = Database::delNumeric( $selReq->fetchAll() ); $selected = Database::delNumeric( $selReq->fetchAll() );
// $selected = Table::get('history');
echo "<article class='inline-row' style='border: 0; box-shadow: none;background: transparent;'>"; echo "<article class='inline-row' style='border: 0; box-shadow: none;background: transparent;'>";
echo "<span>Machine</span>"; echo "<span>Machine</span>";
@ -82,8 +86,8 @@
echo "<span>"; echo "<span>";
echo "<span>".$mac['users']." conducteur(s)</span>"; echo "<span>test conducteur(s)</span>";
echo "<span>".$mac['users']."</span>"; echo "<span>test</span>";
echo "</span>"; echo "</span>";
echo "<span>"; echo "<span>";

View File

@ -1,3 +1,5 @@
<?php namespace view; ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>