From fd3478f923ea01f39a1c2143198d2f761a2eb043 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 3 Oct 2016 12:07:20 +0200 Subject: [PATCH] =?UTF-8?q?ORM:=20Gestion=20du=20'GROUP=20BY'=20->=20fonct?= =?UTF-8?q?ionne=20notamment=20pour=20l'aggr=C3=A9gation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manager/ORM/Rows.php | 87 +++++++++++++++++++++++++++++++++----- manager/ORM/SQLBuilder.php | 42 +++++++++++++++++- router/Route.php | 0 router/Router.php | 0 test/automate.php | 17 ++++++++ 5 files changed, 135 insertions(+), 11 deletions(-) mode change 100755 => 100644 router/Route.php mode change 100755 => 100644 router/Router.php diff --git a/manager/ORM/Rows.php b/manager/ORM/Rows.php index 85bbffd..8cba1a8 100644 --- a/manager/ORM/Rows.php +++ b/manager/ORM/Rows.php @@ -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 Clé primaire simple @@ -288,6 +294,51 @@ + /* SELECTIONNE L'ORDONNANCEMENT DES RESULTATS + * + * @field Libellé du champ à afficher + * @order Gestion de l'ordre ASC/DESC (ou NULL) + * + * @return this 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 VRAI si on veut exécuter la requête, sinon renvoie [requete, boundParams] + * @execute VRAI si on veut exécuter la requête, sinon renvoie [requete, boundParams] * * @return data Tableau contenant les champs sélectionnés * @return data 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 */ diff --git a/manager/ORM/SQLBuilder.php b/manager/ORM/SQLBuilder.php index 58e182b..f494881 100644 --- a/manager/ORM/SQLBuilder.php +++ b/manager/ORM/SQLBuilder.php @@ -26,6 +26,23 @@ + /* CONSTRUIT LA REQUETE FORMATTEE "ORDER BY" AVEC UNE LISTE DE CHAMPS + * + * @tables Liste de champs : [table => fields] + * + * @return sql Renvoie un tableau formatté + * + */ + public static function ORDERBY($tables){ + return $tables; + } + + + + + + + /* CONSTRUIT LA REQUETE FORMATTEE "GROUP BY" AVEC UNE LISTE DE CHAMPS * * @tables 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; } diff --git a/router/Route.php b/router/Route.php old mode 100755 new mode 100644 diff --git a/router/Router.php b/router/Router.php old mode 100755 new mode 100644 diff --git a/test/automate.php b/test/automate.php index 6a4a4f7..ff0db82 100755 --- a/test/automate.php +++ b/test/automate.php @@ -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); ?>