From 1918a646bf63d7225aeb17100930b87282e154c0 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Sat, 23 Jul 2016 00:41:38 +0200 Subject: [PATCH] Gestion des jointures --- manager/ORM/Rows.php | 160 +++++++++++++++++++++++++++++++++++-------- test/automate.php | 11 ++- 2 files changed, 138 insertions(+), 33 deletions(-) diff --git a/manager/ORM/Rows.php b/manager/ORM/Rows.php index 7048d05..a363d6c 100644 --- a/manager/ORM/Rows.php +++ b/manager/ORM/Rows.php @@ -8,10 +8,11 @@ class Rows{ /* Attributs */ - public $where; // Tableau associatif contenant les conditions - public $select; // Tableau contenant la liste des champs à afficher - public $unique; // VRAI si on attend une valeur unique - public $schema; // Tableau contenant les informations associées aux données + private $where; // Tableau associatif contenant les conditions + private $select; // Tableau contenant la liste des champs à afficher + 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 /* CONSTRUCTEUR @@ -31,6 +32,9 @@ /* (4) On initialise le caractère 'unique' du résultat */ $this->unique = false; + + /* (5) On initialise les jointures */ + $this->joined = []; } @@ -219,6 +223,48 @@ + /* JOINT UNE SECONDE TABLE () + * + * @field Nom d'une colonne + * @rows Rows d'une autre table + * + * @return this Retourne l'object courant + * + */ + public function join($field, $rows){ + /* [0] Vérification des paramètres + =========================================================*/ + if( !is_string($field) || !($rows instanceof Rows) ) + return $this; + + + /* [1] On vérifie que la clé étrangère est correcte + =========================================================*/ + /* (1) On vérifie que la colonne existe et qu'elle est étrangère*/ + if( !isset($this->schema['columns'][$field]['references']) ) + return $this; + + /* (2) On vérifie que la table de @rows est correcte */ + if( $this->schema['columns'][$field]['references'][0] != $rows->schema['table'] ) + return $this; + + + /* [2] On enregistre la référence + =========================================================*/ + $this->joined[$field] = $rows; + + + /* [3] On retourne l'object courant + =========================================================*/ + return $this; + } + + + + + + + /* PERMET DE DIRE QUE L'ON VEUT UN RESULTAT UNIQUE * * @return this Retourne l'object courant @@ -281,60 +327,114 @@ $unique = !is_bool($unique) ? $this->unique : $unique; - /* [1] On rédige la requête + /* [1] On rédige la clause SELECT =========================================================*/ /* (1) On initialise la requête */ $requestS = "SELECT "; - /* (2) Si aucun champ, on sélectionne tous les champs */ - if( count($this->select) == 0 ) - $requestS .= "* "; + /* (2) Si aucun SELECT local, on prend tout */ + $c = 0; + if( count($this->select) == 0 ){ + $requestS .= $this->schema['table'].".*"; + $c++; + } - /* (3) Sinon, on sélectionne les champs que l'on veut */ - else - foreach($this->select as $f=>$field) - if( $f == 0 ) $requestS .= $field; - else $requestS .= ', '.$field; + /* (3) Si aucun SELECT de jointure, on prend tout */ + foreach($this->joined as $rows) + if( count($rows->select) == 0 ){ + if( $c == 0 ) $requestS .= $rows->schema['table'].".*"; + else $requestS .= ', '.$rows->schema['table'].".*"; + $c++; + } - /* (4) Clause FROM */ - $requestS .= "\nFROM ".$this->schema['table']."\n"; + /* (5) Sinon, on sélectionne les champs locaux */ + foreach($this->select as $field){ + if( $c == 0 ) $requestS .= $this->schema['table'].'.'.$field; + else $requestS .= ', '.$this->schema['table'].'.'.$field; + $c++; + } + + /* (5) Sinon, on sélectionne les champs de jointure */ + foreach($this->joined as $rows) + foreach($rows->select as $field){ + if( $c == 0 ) $requestS .= $rows->schema['table'].'.'.$field; + else $requestS .= ', '.$rows->schema['table'].'.'.$field; + $c++; + } - /* (5) On ajoute les conditions */ + + /* [2] On rédige la clause FROM + ========================================================*/ + /* (1) Table locale */ + $requestS .= "\nFROM ".$this->schema['table']; + + /* (2) Tables de jointure */ + foreach($this->joined as $j=>$rows) + $requestS .= ", ".$rows->schema['table']; + + /* (3) Retour à la ligne */ + $requestS .= "\n"; + + + + /* [5] On rédige la clause WHERE/AND + =========================================================*/ + /* (1) On met les conditions locales */ $c = 0; foreach($this->where as $field=>$value){ - if( $c == 0 ) $requestS .= ' WHERE '.$field.' = :'.$field."\n"; - else $requestS .= ' AND '.$field.' = :'.$field."\n"; + if( $c == 0 ) $requestS .= 'WHERE '.$this->schema['table'].'.'.$field.' = :'.$this->schema['table'].'_x_'.$field."\n"; + else $requestS .= 'AND '.$this->schema['table'].'.'.$field.' = :'.$this->schema['table'].'_x_'.$field."\n"; $c++; } - /* (6) On prépare la requête */ - $request = Database::getPDO()->prepare($requestS); + /* (2) On ajoute les jointures */ + foreach($this->joined as $localField=>$rows){ + if( $c == 0 ) $requestS .= 'WHERE '.$this->schema['table'].'.'.$localField.' = '.$this->schema['columns'][$localField]['references'][0].'.'.$this->schema['columns'][$localField]['references'][1]."\n"; + else $requestS .= 'AND '.$this->schema['table'].'.'.$localField.' = '.$this->schema['columns'][$localField]['references'][0].'.'.$this->schema['columns'][$localField]['references'][1]."\n"; + $c++; + } + + /* (3) On ajoute les conditions des jointures */ + foreach($this->joined as $rows) + foreach($rows->where as $field=>$value){ + if( $c == 0 ) $requestS .= 'WHERE '.$rows->schema['table'].'.'.$field.' = :'.$rows->schema['table'].'_x_'.$field."\n"; + else $requestS .= 'AND '.$rows->schema['table'].'.'.$field.' = :'.$rows->schema['table'].'_x_'.$field."\n"; + + $c++; + } - - /* [5] On exécute la requête et 'bind' les paramètres + /* [6] On exécute la requête et 'bind' les paramètres =========================================================*/ - /* (1) On bind tous les paramètres */ + /* (0) On prépare la requête */ + $request = Database::getPDO()->prepare($requestS); $binded = []; + /* (1) On bind tous les paramètres locaux */ foreach($this->where as $field=>$value) - $binded[':'.$field] = $value; + $binded[':'.$this->schema['table'].'_x_'.$field] = $value; - /* (2) On exécute la requête */ + /* (3) On bind tous les paramètres des jointures */ + foreach($this->joined as $rows) + foreach($rows->where as $field=>$value) + $binded[':'.$rows->schema['table'].'_x_'.$field] = $value; + + + + /* [6] On exécute la requête et retourne le résultat + =========================================================*/ + /* (1) On exécute la requête */ $request->execute($binded); - - /* [6] On retourne le résultat - =========================================================*/ - /* (1) Si unique */ + /* (2) Si unique */ if( $unique ) return $this->format( $request->fetch() ); - /* (2) Si tout */ + /* (3) Si tout */ return $this->format( $request->fetchAll() ); } diff --git a/test/automate.php b/test/automate.php index 93fe9d5..c830ec6 100755 --- a/test/automate.php +++ b/test/automate.php @@ -342,14 +342,19 @@ debug(); + $warehouse = Table::get('warehouse')->getByName('stef-montauban'); + $myUser = Table::get('user') - ->getByIdWarehouse(7) + ->getById(3) // PRIMARY KEY (if composed, all arguments in array) + ->getByUsername('gediaz') // Dynamic getter 'getByMySuperColumn' -> 'my_super_column' ->select(['mail', 'username', 'firstname']) ->select('id_user') - ->unique(); + ->unique() + ->join('id_warehouse', $warehouse) + ->fetch(); - var_dump($myUser->schema['columns']); + var_dump($myUser); ?>