From 81ff8d158ea2cb682c2f241b03cb1453e8d81be5 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Sun, 24 Jul 2016 12:00:49 +0200 Subject: [PATCH] =?UTF-8?q?ORM:=20fetch=20avec=20condition=20'IN'=20ajout?= =?UTF-8?q?=C3=A9e=20+=20D=C3=A9l=C3=A9gation=20au=20manager=20\manager\OR?= =?UTF-8?q?M\SQLBuilder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manager/ORM/Row.php | 78 ------------ manager/ORM/Rows.php | 196 +++++++++++++----------------- manager/ORM/SQLBuilder.php | 152 +++++++++++++++++++++++ manager/module/machineDefault.php | 2 +- manager/repo/chip.php | 18 ++- manager/repo/warehouse.php | 3 +- test/automate.php | 45 +++---- 7 files changed, 270 insertions(+), 224 deletions(-) delete mode 100644 manager/ORM/Row.php create mode 100644 manager/ORM/SQLBuilder.php diff --git a/manager/ORM/Row.php b/manager/ORM/Row.php deleted file mode 100644 index bd92050..0000000 --- a/manager/ORM/Row.php +++ /dev/null @@ -1,78 +0,0 @@ - Tableau contenant les informations de la requête - * - */ - public function __construct($schema){ - /* (1) On récupère les informations */ - $this->schema = $schema; - } - - - - - - - /* RETOURNE UNIQUEMENT LES CHAMPS SELECTIONNES - * - * @fields Libellé du champ à afficher - * - * @return data Tableau contenant les champs sélectionnés - * @return data Valeur du champ sélectionné (si 1 seul champ) - * - */ - public function select($fields){} - - - - - - /* MODIFIE UNE ENTREE - * - * @updates Tableau associatif contenant les nouvelles valeurs - * - * @return this Retourne l'objet courant (modifié) - * - */ - public function edit($updates){} - - - - - - /* SUPPRIME UNE ENTREE - * - * @return status Retourne si TRUE ou FALSE l'entrée a bien été supprimée - * - */ - public function delete(){} - - - - - - /* SUIT UNE CLE ETRANGERE - * - * @foreign Nom de la table dans laquelle la clé étrangère est PRIMAIRE - * - * @return associated Retourne une instance 'Row' associée à l'entrée en cours (Unique car primaire) - * - */ - public function associated($foreign){} - } - - - -?> diff --git a/manager/ORM/Rows.php b/manager/ORM/Rows.php index 37cb09e..9cb658b 100644 --- a/manager/ORM/Rows.php +++ b/manager/ORM/Rows.php @@ -3,19 +3,21 @@ namespace manager\ORM; use \manager\Database; + use \manager\ORM\SQLBuilder; class Rows{ /* CONSTANTES */ - const COND_EQUAL = '='; - const COND_NOTEQ = '<>'; - const COND_INF = '<'; - const COND_SUP = '>'; - const COND_INFEQ = '<='; - const COND_SUPEQ = '>='; - const COND_LIKE = 'LIKE'; + const COND_EQUAL = '__=__'; + const COND_NOTEQ = '__<>__'; + const COND_INF = '__<__'; + const COND_SUP = '__>__'; + const COND_INFEQ = '__<=__'; + const COND_SUPEQ = '__>=__'; + const COND_LIKE = '__LIKE__'; + const COND_IN = '__IN__'; const DEFAULT = '__DEFAULT__'; // Valeur DEFAULT (pour insertion) @@ -79,78 +81,64 @@ /* [2] Si clé simple =========================================================*/ - if( count($keys) == 1 ){ + /* (1) On met au même format qu'une clé composée */ + if( count($keys) == 1 ) + $primary = [ $primary ]; - /* (1) Si on a juste la valeur, on ajoute le type de condition */ - if( !is_array($primary) ) - $primary = [ $primary, self::COND_EQUAL ]; - - /* (2) Si type INT et pas numérique */ - if( $this->schema['columns'][$keys[0]]['type'] == 'int' && !is_numeric($primary[0]) ) - return $this; - - /* (3) Si type FLOAT et pas numérique */ - if( $this->schema['columns'][$keys[0]]['type'] == 'float' && !is_numeric($primary[0]) ) - return $this; - - /* (4) Si type STRING et pas string */ - if( $this->schema['columns'][$keys[0]]['type'] == 'text' && !is_string($primary[0]) ) - return $this; - - /* (5) Si type OK, on enregistre la condition */ - // {1} Si aucune condition pour ce champ, on crée un tableau // - if( !isset($this->where[$keys[0]]) ) - $this->where[$keys[0]] = []; - - // {2} On ajoute la condition // - $this->where[$keys[0]][] = $primary; /* [3] Si clé composée =========================================================*/ - }else{ + $defaultWhere = $this->where; - $defaultWhere = $this->where; + /* (1) Pour chaque clé, On vérifie les TYPES */ + foreach($keys as $i=>$key){ - /* (1) Pour chaque clé, On vérifie les TYPES */ - foreach($keys as $i=>$key){ + $inCond = is_array($primary[$i]) && count($primary[$i]) >= 2 && is_array($primary[$i][0]) && $primary[$i][1] == self::COND_IN; + /* (1) Si c'est une condition "IN" + ---------------------------------------------------------*/ + if( $inCond ){ - /* (2) Si c'est un paramètre seul, on ajoute par défaut self::COND_EQUAL */ + /* (1) On vérifie le type de chaque valeur du IN */ + $type = $this->schema['columns'][$key]['type']; + + foreach($primary[$i][0] as $value){ + if( $type == 'int' && !is_numeric($value) ){ $this->where = $defaultWhere; return $this; } + if( $type == 'float' && !is_numeric($value) ){ $this->where = $defaultWhere; return $this; } + if( in_array($type, ['text', 'varchar']) && !is_string($value) ){ $this->where = $defaultWhere; return $this; } + } + + /* (2) Si c'est une condition "simple" + ---------------------------------------------------------*/ + }else{ + + /* (1) Si le type de condition est manquant, on met EQUAL par défaut */ if( !is_array($primary[$i]) ) $primary[$i] = [ $primary[$i], self::COND_EQUAL ]; - /* (3) Si type INT et pas numérique */ - if( $this->schema['columns'][$column_name]['type'] == 'int' && !is_numeric($primary[$i][0]) ){ - $this->where = $defaultWhere; // On réinitialise les conditions si au moins 1 est fausse - return $this; - } + /* (2) On vérifie le type de chaque valeur */ + $type = $this->schema['columns'][$key]['type']; - /* (4) Si type FLOAT et pas numérique */ - if( $this->schema['columns'][$column_name]['type'] == 'float' && !is_numeric($primary[$i][0]) ){ - $this->where = $defaultWhere; // On réinitialise les conditions si au moins 1 est fausse - return $this; - } + if( $type == 'int' && !is_numeric($primary[$i][0]) ){ $this->where = $defaultWhere; return $this; } + if( $type == 'float' && !is_numeric($primary[$i][0]) ){ $this->where = $defaultWhere; return $this; } + if( in_array($type, ['text', 'varchar']) && !is_string($primary[$i][0]) ){ $this->where = $defaultWhere; return $this; } - /* (5) Si type STRING et pas string */ - if( $this->schema['columns'][$column_name]['type'] == 'text' && !is_string($primary[$i][0]) ){ - $this->where = $defaultWhere; // On réinitialise les conditions si au moins 1 est fausse - return $this; - } - - /* (6) Si type OK, on enregistre la condition */ - // {1} Si aucune condition pour ce champ, on crée un tableau // - if( !isset($this->where[$key]) ) - $this->where[$key] = []; - - // {2} On ajoute la condition // - $this->where[$key][] = $primary[$i]; } + /* (6) Si type OK, on enregistre la condition */ + if( !isset($this->where[$key]) ) + $this->where[$key] = []; + + /* (7) On ajoute la condition */ + $this->where[$key][] = $primary[$i]; + } + + /* [4] On renvoie l'object courant =========================================================*/ return $this; @@ -413,8 +401,8 @@ $c = 0; foreach($this->where as $field=>$conditions) foreach($conditions as $cdt=>$value){ - if( $c == 0 ) $requestS .= 'WHERE '.$this->schema['table'].'.'.$field.' '.$value[1].' :'.$this->schema['table'].'_x_'.$field.'_'.$cdt."\n"; - else $requestS .= 'AND '.$this->schema['table'].'.'.$field.' '.$value[1].' :'.$this->schema['table'].'_x_'.$field.'_'.$cdt."\n"; + if( $c == 0 ) $requestS .= 'WHERE '.$this->schema['table'].'.'.$field.' '.substr($value[1], 2, -2).' :'.$this->schema['table'].'_x_'.$field.'_'.$cdt."\n"; + else $requestS .= 'AND '.$this->schema['table'].'.'.$field.' '.substr($value[1], 2, -2).' :'.$this->schema['table'].'_x_'.$field.'_'.$cdt."\n"; $c++; } @@ -437,8 +425,8 @@ $c2 = 0; foreach($rows->where as $field=>$conditions) foreach($conditions as $cdt=>$value){ - if( $c2 == 0 ) $requestS .= "\tWHERE ".$rows->schema['table'].'.'.$field.' '.$value[1].' :'.$rows->schema['table'].'_x_'.$field.'_'.$cdt."\n"; - else $requestS .= "\tAND ".$rows->schema['table'].'.'.$field.' '.$value[1].' :'.$rows->schema['table'].'_x_'.$field.'_'.$cdt."\n"; + if( $c2 == 0 ) $requestS .= "\tWHERE ".$rows->schema['table'].'.'.$field.' '.substr($value[1], 2, -2).' :'.$rows->schema['table'].'_x_'.$field.'_'.$cdt."\n"; + else $requestS .= "\tAND ".$rows->schema['table'].'.'.$field.' '.substr($value[1], 2, -2).' :'.$rows->schema['table'].'_x_'.$field.'_'.$cdt."\n"; $c2++; } @@ -627,8 +615,8 @@ $c = 0; foreach($this->where as $field=>$conditions) foreach($conditions as $cdt=>$value){ - if( $c == 0 ) $requestS .= 'WHERE '.$this->schema['table'].'.'.$field.' '.$value[1].' :'.$this->schema['table'].'_x_'.$field.'_'.$cdt."\n"; - else $requestS .= 'AND '.$this->schema['table'].'.'.$field.' '.$value[1].' :'.$this->schema['table'].'_x_'.$field.'_'.$cdt."\n"; + if( $c == 0 ) $requestS .= 'WHERE '.$this->schema['table'].'.'.$field.' '.substr($value[1], 2, -2).' :'.$this->schema['table'].'_x_'.$field.'_'.$cdt."\n"; + else $requestS .= 'AND '.$this->schema['table'].'.'.$field.' '.substr($value[1], 2, -2).' :'.$this->schema['table'].'_x_'.$field.'_'.$cdt."\n"; $c++; } @@ -651,8 +639,8 @@ $c2 = 0; foreach($rows->where as $field=>$conditions) foreach($conditions as $cdt=>$value){ - if( $c2 == 0 ) $requestS .= "\tWHERE ".$rows->schema['table'].'.'.$field.' '.$value[1].' :'.$rows->schema['table'].'_x_'.$field.'_'.$cdt."\n"; - else $requestS .= "\tAND ".$rows->schema['table'].'.'.$field.' '.$value[1].' :'.$rows->schema['table'].'_x_'.$field.'_'.$cdt."\n"; + if( $c2 == 0 ) $requestS .= "\tWHERE ".$rows->schema['table'].'.'.$field.' '.substr($value[1], 2, -2).' :'.$rows->schema['table'].'_x_'.$field.'_'.$cdt."\n"; + else $requestS .= "\tAND ".$rows->schema['table'].'.'.$field.' '.substr($value[1], 2, -2).' :'.$rows->schema['table'].'_x_'.$field.'_'.$cdt."\n"; $c2++; } @@ -709,92 +697,72 @@ /* [1] On rédige la clause SELECT =========================================================*/ - /* (1) On initialise la requête */ - $requestS = "SELECT "; + /* (1) On formatte les données */ + $selectTables = []; - $c = 0; - /* (2) 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++; - } + /* (2) On ajoute les champs locaux */ + $selectTables[$this->schema['table']] = $this->select; - /* (3) Sinon, on sélectionne les champs de jointure */ + /* (3) On ajoute les champs des jointures */ 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++; - } + $selectTables[$rows->schema['table']] = $rows->select; + + /* (4) On génère la clause SELECT */ + $requestS = SQLBuilder::SELECT($selectTables)."\n"; /* [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"; + $requestS .= SQLBuilder::FROM( array_keys($selectTables) )."\n"; /* [5] On rédige la clause WHERE/AND =========================================================*/ + /* (0) On initialise le conteneur des variables "bindés" */ + $binded = []; + + /* (1) On met les conditions locales */ $c = 0; foreach($this->where as $field=>$conditions) - foreach($conditions as $cdt=>$value){ - if( $c == 0 ) $requestS .= 'WHERE '.$this->schema['table'].'.'.$field.' '.$value[1].' :'.$this->schema['table'].'_x_'.$field.'_'.$cdt."\n"; - else $requestS .= 'AND '.$this->schema['table'].'.'.$field.' '.$value[1].' :'.$this->schema['table'].'_x_'.$field.'_'.$cdt."\n"; + + if( $value[1] === self::COND_IN ) // Si condition IN + $requestS .= SQLBuilder::IN([$this->schema['table'], $field], $value[0], $c, $binded)."\n"; + else // Sinon + $requestS .= SQLBuilder::WHERE([$this->schema['table'], $field], $value, $c, $binded)."\n"; $c++; } /* (2) On ajoute les jointures */ - foreach($this->joined as $localField=>$rows){ + 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=>$conditions) foreach($conditions as $cdt=>$value){ - if( $c == 0 ) $requestS .= 'WHERE '.$rows->schema['table'].'.'.$field.' '.$value[1].' :'.$rows->schema['table'].'_x_'.$field.'_'.$cdt."\n"; - else $requestS .= 'AND '.$rows->schema['table'].'.'.$field.' '.$value[1].' :'.$rows->schema['table'].'_x_'.$field.'_'.$cdt."\n"; + + if( $value[1] === self::COND_IN ) // Si condition IN + $requestS .= SQLBuilder::IN([$rows->schema['table'], $field], $value[0], $c, $binded)."\n"; + else // Sinon + $requestS .= SQLBuilder::WHERE([$rows->schema['table'], $field], $value, $c, $binded)."\n"; $c++; } - /* [6] On exécute la requête et 'bind' les paramètres + /* [6] On exécute la requête =========================================================*/ /* (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=>$conditions) - foreach($conditions as $cdt=>$value) - $binded[':'.$this->schema['table'].'_x_'.$field.'_'.$cdt] = $value[0]; - - /* (3) On bind tous les paramètres des jointures */ - foreach($this->joined as $rows) - foreach($rows->where as $field=>$conditions) - foreach($conditions as $cdt=>$value) - $binded[':'.$rows->schema['table'].'_x_'.$field.'_'.$cdt] = $value[0]; - - - - /* [6] On exécute la requête et retourne le résultat + /* [7] On exécute la requête et retourne le résultat =========================================================*/ /* (1) On exécute la requête */ $request->execute($binded); diff --git a/manager/ORM/SQLBuilder.php b/manager/ORM/SQLBuilder.php new file mode 100644 index 0000000..565aaf6 --- /dev/null +++ b/manager/ORM/SQLBuilder.php @@ -0,0 +1,152 @@ + Liste de tables contenant des champs + * + * @return sql Renvoie la clause remplie + * + */ + public static function SELECT($tables){ + /* [0] Initialisation + =========================================================*/ + $sql = 'SELECT '; + + /* [1] On construit la requête + =========================================================*/ + $c = 0; + foreach($tables as $table=>$fields) + foreach($fields as $field){ + if( $c > 0 ) $sql .= ', '; + + $sql .= $table.'.'.$field; + + $c++; + } + + return $sql; + } + + + + + + + /* CONSTRUIT LA REQUETE TEXTUELLE "FROM" AVEC UNE LISTE DE TABLES + * + * @tables Liste de tables + * + * @return sql Renvoie la clause remplie + * + */ + public static function FROM($tables){ + /* [0] Initialisation + =========================================================*/ + $sql = 'FROM '; + + /* [1] On construit la requête + =========================================================*/ + $c = 0; + foreach($tables as $table){ + if( $c > 0 ) $sql .= ', '; + + $sql .= $table; + + $c++; + } + + return $sql; + } + + + + + + + /* CONSTRUIT LA REQUETE TEXTUELLE "IN" AVEC UNE LISTE DE TABLES + * + * @field Tableau contenant [table, field] + * @array Valeurs de la clause IN + * @offset Permet de rendre la condition unique (nommage des variables) + * @binded Tableau associatif contenant les variables "bindés" -> ajout des champs + * + * @return sql Renvoie la clause remplie + * + */ + public static function IN($field, $array, $offset=0, &$binded){ + /* [0] Initialisation + =========================================================*/ + $sql = ( $offset == 0 ) ? 'WHERE ' : 'AND '; + + /* [1] On construit la requête + =========================================================*/ + /* (1) Champ */ + $sql .= $field[0].'.'.$field[1].' IN ('; + + /* (2) Valeurs */ + $c = 0; + foreach($array as $i=>$value){ + if( $c > 0 ) $sql .= ', '; + + $sql .= ':'.$field[0].'_x_'.$field[1].'_'.$offset.'_'.$i; + + $binded[':'.$field[0].'_x_'.$field[1].'_'.$offset.'_'.$i] = $value; + + $c++; + } + + return $sql.")"; + } + + + + + + /* CONSTRUIT LA REQUETE TEXTUELLE "WHERE" AVEC UNE LISTE DE TABLES + * + * @field Tableau contenant [table, field] + * @valeur Valeurs de la clause WHERE [valeur, opérateur] + * @offset Permet de rendre la condition unique (nommage des variables) + * @binded Tableau associatif contenant les variables "bindés" -> ajout des champs + * + * @return sql Renvoie la clause remplie + * + */ + public static function WHERE($field, $value, $offset=0, &$binded){ + /* [0] Initialisation + =========================================================*/ + $sql = ( $offset == 0 ) ? 'WHERE ' : 'AND '; + + + /* [1] On construit la requête + =========================================================*/ + /* (1) Chamo */ + $sql .= $field[0].'.'.$field[1].' '; + + /* (2) Opérateur */ + $sql .= substr($value[1], 2, -2).' '; + + /* (3) Variable */ + $sql .= ':'.$field[0].'_x_'.$field[1].'_'.$offset; + + $binded[':'.$field[0].'_x_'.$field[1].'_'.$offset] = $value[0]; + + + return $sql; + } + + + + } + + +?> diff --git a/manager/module/machineDefault.php b/manager/module/machineDefault.php index 1a538ae..30dae0d 100755 --- a/manager/module/machineDefault.php +++ b/manager/module/machineDefault.php @@ -357,7 +357,7 @@ /* [4] On récupère la liste des MODULES (puces) =========================================================*/ - $chipsReq = new Repo('chip/getAll'); + $chipsReq = new Repo('chip/getAll', [$_SESSION['WAREHOUSE']['id']]); $chips = ($chipsReq->error==0) ? $chipsReq->answer() : []; diff --git a/manager/repo/chip.php b/manager/repo/chip.php index 925374a..a2434e2 100644 --- a/manager/repo/chip.php +++ b/manager/repo/chip.php @@ -4,13 +4,29 @@ use \manager\Database; use \manager\Repo; use \manager\ManagerError; - use \manager\repo\cluster as clusterRepo; + use \manager\ORM\Table; + use \manager\ORM\Rows; class chip extends parentRepo{ protected static function table_name(){ static $table_name = 'chip'; return $table_name; } + /* RENVOIE LA LISTE DES CARTES/PUCES DISPONIBLES EN FONCTION DES MODULES DE L'ENTREPOT + * + * @return chips Liste des puces/cartes disponibles + * + */ + public static function getAll($id_warehouse){ + /* [1] On récupère les modules de l'entrepot courant + =========================================================*/ + $module = Table::get('module'); + // ->where + + + /* [2] On retourne le résultat + =========================================================*/ + } } diff --git a/manager/repo/warehouse.php b/manager/repo/warehouse.php index da76573..6981e4e 100644 --- a/manager/repo/warehouse.php +++ b/manager/repo/warehouse.php @@ -98,7 +98,8 @@ /* [1] On récupère les modules =========================================================*/ $module = Table::get('module') - ->select('name'); + ->select('id_module') + ->select('name'); $merge = Table::get('module_merge') ->whereIdWarehouse($id_warehouse) diff --git a/test/automate.php b/test/automate.php index 33d7715..020991a 100755 --- a/test/automate.php +++ b/test/automate.php @@ -12,6 +12,7 @@ use \manager\ORM\Table; use \manager\ORM\Rows; use \manager\ORM\Row; + use \manager\ORM\SQLBuilder; debug(); @@ -344,23 +345,24 @@ /* [1] FETCH =========================================================*/ - // $warehouse = - // Table::get('warehouse') // Access to table 'warehouse' - // ->whereName(['stef-montauban', Rows::COND_NOTEQ]); // condition : name = 'my-warehouse' - // - // - // $myUser = - // Table::get('user') // Access to table 'user' - // ->whereId([100, Rows::COND_INF]) // PRIMARY KEY (other condition on same field) - // ->whereUsername(['jo%', Rows::COND_LIKE]) // Dynamic getter 'getByMySuperColumn' -> 'my_super_column' - // ->select(['mail', 'username', 'firstname']) // Select clause - // ->select('id_user') // Select clause (added) - // ->join('id_warehouse', $warehouse) // joins warehouse (with name 'my-warehouse') to column 'id_warehouse' + $warehouse = + Table::get('warehouse') // Access to table 'warehouse' + ->whereName(['stef-montauban', Rows::COND_EQUAL]); // condition : name = 'my-warehouse' + + + $myUser = + Table::get('user') // Access to table 'user' + ->whereId([100, Rows::COND_INF]) // PRIMARY KEY (other condition on same field) + ->whereId([[1,4,6,9], Rows::COND_IN]) // PRIMARY KEY (other condition on same field) + ->whereUsername(['%e%', Rows::COND_LIKE]) // Dynamic getter 'getByMySuperColumn' -> 'my_super_column' + ->select(['mail', 'username', 'firstname']) // Select clause + ->select('id_user') // Select clause (added) + ->join('id_warehouse', $warehouse) // joins warehouse (with name 'my-warehouse') to column 'id_warehouse' // ->unique() // unique result // SELECT - // ->fetch(); // Result - + ->fetch(); // Result + var_dump($myUser); /* [2] Modification =========================================================*/ @@ -427,19 +429,4 @@ // ->delete(); - $id_warehouse = 7; - $id_user_cluster = 2; - //////////////////////////// - - $module = Table::get('module') - ->select('name'); - - $merge = Table::get('module_merge') - ->whereIdWarehouse($id_warehouse) - ->join('id_module', $module); - - - $modules = $merge->fetch(); - var_dump($modules); - ?>