ORM: Refactor 'fetch'

This commit is contained in:
xdrm-brackets 2016-07-25 10:34:06 +02:00
parent 2bce5ab3bb
commit 0ae728f460
4 changed files with 128 additions and 109 deletions

View File

@ -27,6 +27,7 @@
const SEL_MAX = '__MAX__'; const SEL_MAX = '__MAX__';
const SEL_MIN = '__MIN__'; const SEL_MIN = '__MIN__';
const SEL_COUNT = '__COUNT__'; const SEL_COUNT = '__COUNT__';
const SEL_CONCAT = '__GROUP_CONCAT__';
const SEL_DISTINCT = true; const SEL_DISTINCT = true;
@ -261,7 +262,7 @@
return $this; return $this;
/* (3) On vérifie @func */ /* (3) On vérifie @func */
$funcList = [self::SEL_AVG, self::SEL_SUM, self::SEL_MAX, self::SEL_MIN, self::SEL_COUNT]; $funcList = [self::SEL_AVG, self::SEL_SUM, self::SEL_MAX, self::SEL_MIN, self::SEL_COUNT, self::SEL_CONCAT];
// Si condition non nulle et pas référencée, on quitte // Si condition non nulle et pas référencée, on quitte
if( !is_null($func) && !in_array($func, $funcList) ) if( !is_null($func) && !in_array($func, $funcList) )
@ -761,6 +762,11 @@
/* (2) On initialise le conteneur des variables "bindés" */ /* (2) On initialise le conteneur des variables "bindés" */
$bound = []; $bound = [];
/* (3) On récupère la requête générée par chaque @rows de jointure */
$joinedFetched = [];
foreach($this->joined as $field=>$data)
$joinedFetched[$field] = $data['object']->fetch(false);
/* [1] On rédige la clause SELECT /* [1] On rédige la clause SELECT
@ -771,11 +777,20 @@
/* (2) On ajoute les champs locaux */ /* (2) On ajoute les champs locaux */
$selectTables[$this->schema['table']] = $this->select; $selectTables[$this->schema['table']] = $this->select;
/* (3) On ajoute les champs des jointures */
foreach($this->joined as $rows)
$selectTables[$rows['object']->schema['table']] = $rows['object']->select;
/* (4) On génère la clause SELECT */ /* (4) On ajoute les champs des jointures (récursif)*/
foreach($joinedFetched as $field=>$data){
foreach($data['request']['SELECT'] as $table=>$fields)
foreach($fields as $field=>$sel){
// Si aucune entrée pour cette table, on l'ajoute
if( !isset($selectTables[$table]) )
$selectTables[$table] = [];
$selectTables[$table][$field] = $sel;
}
}
/* (3) On génère la clause SELECT */
$requestS['SELECT'] = SQLBuilder::SELECT($selectTables); $requestS['SELECT'] = SQLBuilder::SELECT($selectTables);
@ -790,25 +805,9 @@
/* (2) On ajoute les tables de jointures */ /* (2) On ajoute les tables de jointures */
// Note: On ajoute les tables de jointures dans la clause FROM avec comme alias le nom de la table // Note: On ajoute les tables de jointures dans la clause FROM avec comme alias le nom de la table
foreach($this->joined as $field=>$data){ foreach($joinedFetched as $field=>$data)
// {1} On récupère la requête/les params de chaque jointure // // On ajoute la clause FROM de jointure à la clause FROM locale //
$joinedFetched = $data['object']->fetch(false); $requestS['FROM'] = array_merge($data['request']['FROM'], $requestS['FROM']);
// {2} On met '*' pour la clause SELECT //
$joinedFetched['request']['SELECT'] = [ $data['object']->schema['table'].'.*' ];
// {3} On construit la nouvelle requête //
$joinedRequest = SQLBuilder::BUILD($joinedFetched['request']);
// {4} On supprime les retours à la ligne //
$joinedRequest = str_replace("\n", " ", $joinedRequest);
// {5} On l'ajoute à la clause FROM avec comme alias le nom de la table de @data['object'] //
$requestS['FROM'][] = "($joinedRequest) as ".$data['object']->schema['table'];
// {6} On ajoute les variables à la requête courante //
$bound = array_merge($bound, $joinedFetched['bound']);
}
@ -834,40 +833,40 @@
$c++; $c++;
} }
/* (3) On ajoute les conditions des jointures */
foreach($joinedFetched as $field=>$data){
/* On ajoute la clause WHERE de jointure à la clause WHERE locale */
$requestS['WHERE'] = array_merge($data['request']['WHERE'], $requestS['WHERE']);
/* On ajoute les variables à la requête courante */
$bound = array_merge($bound, $data['bound']);
}
/* [6] Clause GROUP BY /* [6] Clause GROUP BY
=========================================================*/ =========================================================*/
/* (0) On initialise la liste des @rows non aggrégés */ /* (0) On initialise la liste des @rows non aggrégés */
$notAggregatedRows = [];
/* (1) On cherche dans les champs locaux local */
foreach($this->select as $field=>$sel)
if( is_null($sel[0]) )
$notAggregatedRows[] = $this;
/* (2) On cherche dans les champs des jointures */
foreach($this->joined as $data)
foreach($data['object']->select as $field=>$sel)
if( is_null($sel[0]) )
$notAggregatedRows[] = $data['object'];
/* (3) Pour chaque table, on récupère les clés primaires */
$groupBy = []; $groupBy = [];
foreach($notAggregatedRows as $i=>$rows){ /* (1) On cherche dans les champs locaux local */
$groupBy[$rows->schema['table']] = []; foreach($selectTables as $table=>$fields)
foreach($fields as $field=>$sel)
if( is_null($sel[0]) ){
if( !isset($groupBy[$table]) )
$groupBy[$table] = [];
foreach($rows->schema['columns'] as $field=>$data) $groupBy[$table][] = $field;
if( $data['primary'] )
$groupBy[$rows->schema['table']][] = $field;
} }
/* (4) On rédige la clause GROUP BY */
/* (2) On rédige la clause GROUP BY */
if( count($groupBy) > 0) if( count($groupBy) > 0)
$requestS['GROUPBY'] = SQLBuilder::GROUPBY($groupBy); $requestS['GROUPBY'] = SQLBuilder::GROUPBY($groupBy);
/* [6] Clause LIMIT /* [6] Clause LIMIT
=========================================================*/ =========================================================*/
$requestS['LIMIT'] = ($this->unique) ? SQLBuilder::LIMIT(1) : SQLBuilder::LIMIT([]); $requestS['LIMIT'] = ($this->unique) ? SQLBuilder::LIMIT(1) : SQLBuilder::LIMIT([]);
@ -881,6 +880,8 @@
/* (2) On compose la requête */ /* (2) On compose la requête */
$requestString = SQLBuilder::BUILD($requestS).';'; $requestString = SQLBuilder::BUILD($requestS).';';
var_dump($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,43 +11,13 @@
/* CONSTRUIT LA REQUETE FORMATTEE "SELECT" AVEC UNE LISTE DE CHAMPS /* CONSTRUIT LA REQUETE FORMATTEE "SELECT" AVEC UNE LISTE DE CHAMPS
* *
* @sqlFields<Array> Liste de champs : [table => field => func, alias] * @sqlFields<Array> Liste de champs : [table => field => [func, alias] ]
* *
* @return sql<Array> Renvoie un tableau formatté * @return sql<Array> Renvoie un tableau formatté
* *
*/ */
public static function SELECT($sqlFields){ public static function SELECT($sqlFields){
/* [0] Initialisation return $sqlFields;
=========================================================*/
$sql = [];
/* [1] On construit la requête
=========================================================*/
$c = 0;
foreach($sqlFields as $table=>$tableContent)
foreach($tableContent as $field=>$select){
/* (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 */
if( $field != '*' ) $sql[$c] = "$fieldStr as $field";
else $sql[$c] = "$fieldStr";
$c++;
}
return $sql;
} }
@ -64,20 +34,7 @@
* *
*/ */
public static function GROUPBY($tables){ public static function GROUPBY($tables){
/* [0] Initialisation return $tables;
=========================================================*/
$sql = [];
/* [1] On construit la requête
=========================================================*/
$c = 0;
foreach($tables as $table=>$fields)
foreach($fields as $field){
$sql[] = "$table.$field";
$c++;
}
return $sql;
} }
@ -255,7 +212,7 @@
public static function LIMIT($count=null){ public static function LIMIT($count=null){
/* [0] Initialisation /* [0] Initialisation
=========================================================*/ =========================================================*/
$sql = []; $sql = '';
/* [1] On construit la requête /* [1] On construit la requête
@ -299,11 +256,27 @@
/* (1) Clause SELECT /* (1) Clause SELECT
---------------------------------------------------------*/ ---------------------------------------------------------*/
case 'SELECT': case 'SELECT':
$sql .= 'SELECT '; $sql .= "SELECT ";
$c = 0; $c = 0;
foreach($statements as $field){ foreach($statements as $table=>$fields)
$sql .= ($c==0) ? $field : ", $field"; foreach($fields as $field=>$select){
/* (1) On construit le nom du champ */
$fieldStr = ($c==0) ? "$table.$field" : ", $table.$field";
/* (2) On ajout le DISTINCT s'il y a lieu */
if( isset($select[1]) && $select[1] )
$fieldStr = "DISTINCT $fieldStr";
/* (3) On ajoute la fonction d'aggrégation s'il y a lieu */
if( isset($select[0]) && !is_null($select[0]) )
$fieldStr = substr($select[0], 2, -2)."($fieldStr)";
/* (4) On ajoute l'alias */
$sql .= "$fieldStr";
$c++; $c++;
} }
@ -317,7 +290,7 @@
$c = 0; $c = 0;
foreach($statements as $field){ foreach($statements as $field){
$sql .= ($c==0) ? $field : ", $field"; $sql .= ($c==0) ? "$field" : ", $field";
$c++; $c++;
} }
@ -379,8 +352,9 @@
$sql .= 'GROUP BY '; $sql .= 'GROUP BY ';
$c = 0; $c = 0;
foreach($statements as $field){ foreach($statements as $table=>$fields)
$sql .= ($c==0) ? $field : ", $field"; foreach($fields as $field){
$sql .= ($c==0) ? "$table.$field" : ", $table.$field";
$c++; $c++;
} }

View File

@ -4,7 +4,9 @@
use \manager\Database; use \manager\Database;
use \manager\Repo; use \manager\Repo;
use \manager\ManagerError; use \manager\ManagerError;
use \manager\repo\cluster as clusterRepo; use \manager\ORM\Table;
use \manager\ORM\Rows;
class action_merge extends parentRepo{ class action_merge extends parentRepo{

View File

@ -445,15 +445,57 @@
// var_dump($myUser); // var_dump($myUser);
$module_merge = Table::get('module_merge') $getPermissions = Database::getPDO()->prepare("SELECT u.id_user, u.code, GROUP_CONCAT(DISTINCT a.id_action ORDER BY a.id_action ASC) as actions
->whereIdWarehouse(7); FROM
user as u,
user_cluster as uc,
user_cluster_merge as ucm,
machine as m,
machine_cluster as mc,
machine_cluster_merge as mcm,
action as a,
action_merge as am
WHERE u.id_user = ucm.id_user
AND uc.id_user_cluster = ucm.id_user_cluster
AND am.id_source = uc.id_user_cluster
AND m.id_warehouse = u.id_warehouse
AND m.id_warehouse = :id_warehouse
AND m.id_machine = :id_machine
AND m.id_machine = mcm.id_machine
AND mc.id_machine_cluster = mcm.id_machine_cluster
AND am.id_target = mc.id_machine_cluster
AND a.id_action = am.id_action
GROUP BY u.id_user, u.code");
$getPermissions->execute([
':id_warehouse' => 7,
':id_machine' => 5
]);
$chip = Table::get('chip') var_dump( Database::delNumeric( $getPermissions->fetchAll() ) );
->join('id_module', $module_merge)
->select('*');
var_dump($chip->fetch()); $u = Table::get('user')
->select('id_user')
->select('code');
$ucm = Table::get('user_cluster_merge')
->join('id_user', $u);
$m = Table::get('machine')
->whereId(5);
$mcm = Table::get('machine_cluster_merge')
->join('id_machine', $m);
$a = Table::get('action_merge')
->join('id_source', $ucm)
->join('id_target', $mcm)
->select('id_action', Rows::SEL_CONCAT, Rows::SEL_DISTINCT);
var_dump($a->fetch());
// $a = new ModuleRequest('authentificationDefault/warehouse', [ // $a = new ModuleRequest('authentificationDefault/warehouse', [