ORM: Gestion du 'GROUP BY' -> fonctionne notamment pour l'aggrégation

This commit is contained in:
xdrm-brackets 2016-10-03 12:07:20 +02:00
parent 5d1cac0c97
commit fd3478f923
5 changed files with 135 additions and 11 deletions

View File

@ -31,12 +31,17 @@
const SEL_DISTINCT = true;
// {3} Gestion du Order By //
const ORDER_ASC = '__ASC__';
const ORDER_DESC = '__DESC__';
// {3} Constantes d'insertion //
const INSERT_DEFAULT = '__DEFAULT__'; // Valeur DEFAULT (pour insertion)
/* Attributs */
private $where; // Tableau associatif contenant les conditions
private $select; // Tableau contenant la liste des champs à afficher
private $orderby; // Tableau contenant la liste des orderby
private $unique; // VRAI si on attend une valeur unique
private $schema; // Tableau contenant les informations associées aux données
private $joined; // Tableau contenant les Rows liés
@ -57,18 +62,19 @@
/* (3) On initialise les champs à retourner */
$this->select = [];
/* (4) On initialise le caractère 'unique' du résultat */
/* (4) On initialise l'ordonnancement' */
$this->orderby = [];
/* (5) On initialise le caractère 'unique' du résultat */
$this->unique = false;
/* (5) On initialise les jointures */
/* (6) On initialise les jointures */
$this->joined = [];
}
/* FILTRE LES ENTREES D'UNE TABLE AVEC LA CLE PRIMAIRE SPECIFIEE
*
* @primary<mixed> Clé primaire simple
@ -288,6 +294,51 @@
/* SELECTIONNE L'ORDONNANCEMENT DES RESULTATS
*
* @field<String> Libellé du champ à afficher
* @order<CONST> Gestion de l'ordre ASC/DESC (ou NULL)
*
* @return this<Rows> Retourne l'object courant
*
*/
public function orderby($field=null, $order=null){
/* [1] On formatte les champs
=========================================================*/
/* (1) On vérifie le type de @field */
if( !is_string($field) )
return $this;
/* (2) On vérifie que la colonne @field existe, sinon on quitte */
if( !isset($this->schema['columns'][$field]) && $field != '*' )
return $this;
/* (3) On vérifie @order */
$orderList = [self::ORDER_ASC, self::ORDER_DESC];
// Valeur si NULL
$order = is_null($order) ? $orderList[0] : $order;
// Si ordre non référencée, on quitte
if( !in_array($order, $orderList) )
return $this;
/* [2] On enregistre le champ
=========================================================*/
/* (1) On crée le ORDER_BY pour ce champ */
$this->orderby[$field] = $order;
/* [3] On retourne l'object courant
=========================================================*/
return $this;
}
/* JOINT UNE SECONDE TABLE ()
@ -746,7 +797,7 @@
/* RETOURNE LES DONNEES / NULL si une erreur survient
*
* @execute<Boolean> VRAI si on veut exécuter la requête, sinon renvoie [requete, boundParams]
* @execute<Boolean> VRAI si on veut exécuter la requête, sinon renvoie [requete, boundParams]
*
* @return data<Array> Tableau contenant les champs sélectionnés
* @return data<mixed> Valeur du champ sélectionné (si 1 seul champ)
@ -768,7 +819,6 @@
$joinedFetched[$field] = $data['object']->fetch(false);
/* [1] On rédige la clause SELECT
=========================================================*/
/* (1) On formatte les données */
@ -794,7 +844,6 @@
$requestS['SELECT'] = SQLBuilder::SELECT($selectTables);
/* [2] On rédige la clause FROM
========================================================*/
/* (0) On initialise la clause */
@ -810,7 +859,6 @@
$requestS['FROM'] = array_merge($data['request']['FROM'], $requestS['FROM']);
/* [5] On rédige la clause WHERE/AND
=========================================================*/
/* (1) On met les conditions locales */
@ -843,8 +891,6 @@
}
/* [6] Clause GROUP BY
=========================================================*/
/* (0) On initialise la liste des @rows non aggrégés */
@ -876,7 +922,27 @@
if( count($groupBy) > 0)
$requestS['GROUPBY'] = SQLBuilder::GROUPBY($groupBy);
/* [6] Clause ORDER BY
=========================================================*/
/* (1) On formatte les données */
$orderTables = [];
/* (2) On ajoute les champs locaux */
if( count($this->orderby) > 0 )
$orderTables[$this->schema['table']] = $this->orderby;
/* (4) On ajoute les champs des jointures (récursif)*/
foreach($joinedFetched as $field=>$data){
foreach($data['request']['ORDERBY'] as $table=>$fields) // pour chaque ensemble de champ de chaque table
foreach($fields as $field=>$orderBy) // Pour chaque orderby de chaque champ
if( count($orderBy) > 0 )
$orderTables[$table][$field] = $orderBy;
}
/* (3) On génère la clause SELECT */
$requestS['ORDERBY'] = SQLBuilder::ORDERBY($orderTables);
/* [6] Clause LIMIT
=========================================================*/
@ -896,6 +962,7 @@
$request = Database::getPDO()->prepare($requestString);
// var_dump($requestString);
/* [8] On exécute la requête et retourne le résultat
=========================================================*/
/* (1) On exécute la requête */

View File

@ -26,6 +26,23 @@
/* CONSTRUIT LA REQUETE FORMATTEE "ORDER BY" AVEC UNE LISTE DE CHAMPS
*
* @tables<Array> Liste de champs : [table => fields]
*
* @return sql<Array> Renvoie un tableau formatté
*
*/
public static function ORDERBY($tables){
return $tables;
}
/* CONSTRUIT LA REQUETE FORMATTEE "GROUP BY" AVEC UNE LISTE DE CHAMPS
*
* @tables<Array> Liste de champs : [table => fields]
@ -336,7 +353,6 @@
case 'UPDATE':
$sql .= "UPDATE $statements\n";
break;
break;
/* (7) Clause SET
@ -364,6 +380,30 @@
$sql .= "\n";
break;
/* (9) Clause ORDER BY
---------------------------------------------------------*/
case 'ORDERBY':
// si aucun ORDER BY, on quitte
if( count($statements) == 0 )
continue;
$sql .= 'ORDER BY ';
$c = 0;
foreach($statements as $table=>$fields)
foreach($fields as $field=>$order){
if( $c > 0 ) $sql .= ', ';
$sql .= "$table.$field ". substr($order, 2, -2);
$c++;
}
$sql .= "\n";
break;
}

0
router/Route.php Executable file → Normal file
View File

0
router/Router.php Executable file → Normal file
View File

View File

@ -453,4 +453,21 @@
// ]);
//
// $a->dispatch();
$state = Table::get('state')
->select('state')
->select('value', Rows::SEL_CONCAT);
// ->orderby('state');
$pm = Table::get('pin_merge')
->whereIdChip(1, Rows::COND_EQUAL)
->select('id_chip')
->orderby('id_chip')
// ->orderby('pin')
->join('id_pin_merge', $state);
$resultA = $pm->fetch();
var_dump($resultA);
?>