Gestion des jointures

This commit is contained in:
xdrm-brackets 2016-07-23 00:41:38 +02:00
parent 1cd1df9a26
commit 1918a646bf
2 changed files with 138 additions and 33 deletions

View File

@ -8,10 +8,11 @@
class Rows{ class Rows{
/* Attributs */ /* Attributs */
public $where; // Tableau associatif contenant les conditions private $where; // Tableau associatif contenant les conditions
public $select; // Tableau contenant la liste des champs à afficher private $select; // Tableau contenant la liste des champs à afficher
public $unique; // VRAI si on attend une valeur unique private $unique; // VRAI si on attend une valeur unique
public $schema; // Tableau contenant les informations associées aux données private $schema; // Tableau contenant les informations associées aux données
private $joined; // Tableau contenant les Rows liés
/* CONSTRUCTEUR /* CONSTRUCTEUR
@ -31,6 +32,9 @@
/* (4) On initialise le caractère 'unique' du résultat */ /* (4) On initialise le caractère 'unique' du résultat */
$this->unique = false; $this->unique = false;
/* (5) On initialise les jointures */
$this->joined = [];
} }
@ -219,6 +223,48 @@
/* JOINT UNE SECONDE TABLE ()
*
* @field<String> Nom d'une colonne
* @rows<Rows> Rows d'une autre table
*
* @return this<Rows> 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 /* PERMET DE DIRE QUE L'ON VEUT UN RESULTAT UNIQUE
* *
* @return this<Rows> Retourne l'object courant * @return this<Rows> Retourne l'object courant
@ -281,60 +327,114 @@
$unique = !is_bool($unique) ? $this->unique : $unique; $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 */ /* (1) On initialise la requête */
$requestS = "SELECT "; $requestS = "SELECT ";
/* (2) Si aucun champ, on sélectionne tous les champs */ /* (2) Si aucun SELECT local, on prend tout */
if( count($this->select) == 0 ) $c = 0;
$requestS .= "* "; if( count($this->select) == 0 ){
$requestS .= $this->schema['table'].".*";
$c++;
}
/* (3) Sinon, on sélectionne les champs que l'on veut */ /* (3) Si aucun SELECT de jointure, on prend tout */
else foreach($this->joined as $rows)
foreach($this->select as $f=>$field) if( count($rows->select) == 0 ){
if( $f == 0 ) $requestS .= $field; if( $c == 0 ) $requestS .= $rows->schema['table'].".*";
else $requestS .= ', '.$field; else $requestS .= ', '.$rows->schema['table'].".*";
$c++;
}
/* (4) Clause FROM */ /* (5) Sinon, on sélectionne les champs locaux */
$requestS .= "\nFROM ".$this->schema['table']."\n"; 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; $c = 0;
foreach($this->where as $field=>$value){ foreach($this->where as $field=>$value){
if( $c == 0 ) $requestS .= ' WHERE '.$field.' = :'.$field."\n"; if( $c == 0 ) $requestS .= 'WHERE '.$this->schema['table'].'.'.$field.' = :'.$this->schema['table'].'_x_'.$field."\n";
else $requestS .= ' AND '.$field.' = :'.$field."\n"; else $requestS .= 'AND '.$this->schema['table'].'.'.$field.' = :'.$this->schema['table'].'_x_'.$field."\n";
$c++; $c++;
} }
/* (6) On prépare la requête */ /* (2) On ajoute les jointures */
$request = Database::getPDO()->prepare($requestS); 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++;
}
/* [6] On exécute la requête et 'bind' les paramètres
/* [5] 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 = []; $binded = [];
/* (1) On bind tous les paramètres locaux */
foreach($this->where as $field=>$value) 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); $request->execute($binded);
/* (2) Si unique */
/* [6] On retourne le résultat
=========================================================*/
/* (1) Si unique */
if( $unique ) if( $unique )
return $this->format( $request->fetch() ); return $this->format( $request->fetch() );
/* (2) Si tout */ /* (3) Si tout */
return $this->format( $request->fetchAll() ); return $this->format( $request->fetchAll() );
} }

View File

@ -342,14 +342,19 @@
debug(); debug();
$warehouse = Table::get('warehouse')->getByName('stef-montauban');
$myUser = $myUser =
Table::get('user') 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(['mail', 'username', 'firstname'])
->select('id_user') ->select('id_user')
->unique(); ->unique()
->join('id_warehouse', $warehouse)
->fetch();
var_dump($myUser->schema['columns']); var_dump($myUser);
?> ?>