From ce44ff1baaf7ee7415e7618ae2c35974e9f2c612 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Sat, 5 Nov 2016 14:57:35 +0100 Subject: [PATCH] Update [Database] to [DatabaseDriver] which can handle multiple databases --- build/api/core/ModuleRequest.php | 2 +- build/api/module/authentificationDefault.php | 2 +- build/api/module/clusterDefault.php | 2 +- build/api/module/machineDefault.php | 2 +- build/api/module/userDefault.php | 2 +- build/database/core/Database.php | 446 ------------------- build/database/core/DatabaseDriver.php | 327 ++++++++++++++ build/database/repo/action.php | 2 +- build/database/repo/action_merge.php | 2 +- build/database/repo/admin.php | 2 +- build/database/repo/chip.php | 2 +- build/database/repo/global_state.php | 2 +- build/database/repo/machine.php | 2 +- build/database/repo/machine_cluster.php | 2 +- build/database/repo/parentRepo.php | 12 +- build/database/repo/pin_merge.php | 2 +- build/database/repo/state.php | 4 +- build/database/repo/user.php | 6 +- build/database/repo/user_cluster.php | 2 +- build/database/repo/warehouse.php | 2 +- build/orm/core/Rows.php | 86 ++-- build/orm/core/SQLBuilder.php | 2 +- build/orm/core/Table.php | 24 +- config/database-driver.json | 16 + config/database-local.json | 6 - config/database.json | 6 - phpunit/tests/Database_construct.php | 22 +- phpunit/tests/Database_delNumeric.php | 12 +- public_html/index.php | 3 +- public_html/test/automate.php | 7 +- public_html/view/history.php | 2 +- todo.md | 8 +- 32 files changed, 439 insertions(+), 580 deletions(-) delete mode 100755 build/database/core/Database.php create mode 100755 build/database/core/DatabaseDriver.php create mode 100644 config/database-driver.json delete mode 100755 config/database-local.json delete mode 100755 config/database.json diff --git a/build/api/core/ModuleRequest.php b/build/api/core/ModuleRequest.php index 052d7c5..921bcbb 100755 --- a/build/api/core/ModuleRequest.php +++ b/build/api/core/ModuleRequest.php @@ -1,7 +1,7 @@ __ROOT__.'/config/database-local.json', - 'remote' => __ROOT__.'/config/database.json' - ]; - } - - private static $pdo; - private static $instance; - - - /* ATTRIBUTS */ - private $host; - private $dbname; - private $username; - private $password; - - public static $error; - - - public function __construct($host, $dbname, $username, $password){ - $this->host = $host; - $this->dbname = $dbname; - $this->username = $username; - $this->password = $password; - - try{ - self::$pdo = new \PDO('mysql:host='.$this->host.';dbname='.$this->dbname, $this->username, $this->password); - - // On signale que tout s'est bien passe - self::$error = Error::Success; - - }catch(Exception $e){ - // On signale qu'il y a une erreur - self::$error = Error::PDOConnection; - } - } - - - /* retourne une instance de la classe */ - public static function getInstance(){ - if( self::$instance == null || self::$error != Error::Success ){ // Si aucune instance existante OU erreur de connection - - // chargement de la configuration du server SQL - if( !checkdnsrr($_SERVER['SERVER_NAME'], 'NS') ) - $conf = json_decode( file_get_contents(self::config_path()['local']), true ); - else - $conf = json_decode( file_get_contents(self::config_path()['remote']), true ); - - // creation de l'instance en fonction des parametres - self::$instance = new DataBase($conf['host'], $conf['dbname'], $conf['user'], $conf['password']); - - } - - return self::$instance; - } - - /* retourne la connection statique */ - public static function getPDO(){ - $instance = self::getInstance(); - - return self::$pdo; - } - - - - - - - - - - public function getConfig(){ - return [ - 'host' => $this->host, - 'username' => $this->username - ]; - } - - - - - - - - /*************************************************************/ - /* _____ ______ _ _ ______ _____ _ */ - /* / ____| ____| \ | | ____| __ \ /\ | | */ - /* | | __| |__ | \| | |__ | |__) | / \ | | */ - /* | | |_ | __| | . ` | __| | _ / / /\ \ | | */ - /* | |__| | |____| |\ | |____| | \ \ / ____ \| |____ */ - /* \_____|______|_| \_|______|_| \_\/_/ \_\______| */ - /* */ - /*************************************************************/ - - /* SUPPRIME LES VALEURS À CLÉS NUMÉRIQUES DANS UN FETCH D'UNE TABLE DE LA BDD - * - * @fetchData le résultat d'une $requeteSQL->fetchAll() - * @oneDimension FAUX <=> fetchAll ; VRAI <=> fetch - * - * @return newFetchData retourne le tableau donné en paramètre mais sans les valeurs à clés numériques - * - */ - public static function delNumeric($fetchData, $oneDimension=false){ - // On quitte si ce n'est pas un tableau - if( !is_array($fetchData) ) - return []; - - $nextEquivalent = false; // Vaut VRAI si le prochain est peut-etre un equivalent numerique - - /* [1] 2 dimensions - ===============================================*/ - if( !$oneDimension && isset($fetchData[0]) && is_array($fetchData[0]) ){ - - // on supprime les doublons des entrées (indice numérique) - for( $i = 0 ; $i < count($fetchData) ; $i++ ) // pour toutes les lignes - foreach($fetchData[$i] as $col => $val){ // pour toutes les entrées - - if( !\mb_detect_encoding($val, 'UTF-8') ) - $fetchData[$i][$col] = utf8_encode($val); - - if( is_int($col) ){ // Si indice numerique - if( $nextEquivalent ) // Si suit un indice textuel - unset( $fetchData[$i][$col] ); // on supprime l'indice - - $nextEquivalent = false; // Dans tous les cas, on dit que le prochain ne pourra pas etre supprime si numerique - - }else // Si l'indice n'est pas un entier - $nextEquivalent = true; // On signale qu'il y aura peut etre un indice numerique suivant - - } - - /* [2] 1 dimensions - ===============================================*/ - }else{ - - // on supprime les doublons des entrées (indice numérique) - foreach($fetchData as $i=>$val){ // pour toutes les entrées - - if( !\mb_detect_encoding($val, 'UTF-8') ) - $fetchData[$i] = utf8_encode($val); - - if( is_int($i) ){ // Si indice numerique - if( $nextEquivalent ) // Si suit un indice textuel - unset( $fetchData[$i] ); // on supprime l'indice - - $nextEquivalent = false; // Dans tous les cas, on dit que le prochain ne pourra pas etre supprime si numerique - - }else // Si l'indice n'est pas un entier - $nextEquivalent = true; // On signale qu'il y aura peut etre un indice numerique suivant - - } - - } - - return $fetchData; - } - - - - - /* GESTION DE L'AUTO-TYPAGE D'UN TABLEAU A UN/PLUSIEURS NIVEAU(X) OU D'UNE VALEUR - * - * @data Tableau de données/Valeur - * - * @return autoTyped Tableau/Valeur auto-typé(e) - * - */ - public static function autotype($data){ - $autotyped = $data; - - /* [0] Gestion des types simples - =========================================================*/ - if( !is_array($autotyped) ){ - - /* (1) Si Numérique Entier -> INT */ - if( preg_match('/^(0|([1-9][0-9]*))$/i', $autotyped) ) - return intval($autotyped); - - /* (2) Si Numérique Décimal -> FLOAT */ - else if( preg_match('/^(0|(?:[1-9][0-9]*))[\.\,]([0-9]+)$/i', $autotyped, $m) ) - return floatval("${m[1]}.${m[2]}"); - - /* (3) Sinon on retourne la même chose */ - else - return $autotyped; - - /* [1] Gestion des types composés - =========================================================*/ - }else{ - - /* (1) Pour chaque valeur, on applique récursivement */ - foreach($autotyped as $k=>$v){ - - // Si on met '_nomColonne', on ne le traite pas - if( is_string($k) && $k[0] == '_' ) continue; - - $autotyped[$k] = self::autotype($v); - - } - - } - - - /* [2] On retourne le résultat auto-typé - =========================================================*/ - return $autotyped; - } - - - //////////////////////////////////////////////////////////////// - // _ __ _ _ _ - // __ _____ _ __(_)/ _(_) ___ __ _| |_(_) ___ _ __ ___ - // \ \ / / _ \ '__| | |_| |/ __/ _` | __| |/ _ \| '_ \/ __| - // \ V / __/ | | | _| | (_| (_| | |_| | (_) | | | \__ \ - // \_/ \___|_| |_|_| |_|\___\__,_|\__|_|\___/|_| |_|___/ - // - //////////////////////////////////////////////////////////////// - - - /* VERIFICATIONS DES TYPES UTILES GENERIQUES - * - * @type Type que l'on veut verifier - * @value Valeur a verifier - * - * @return match Retourne si oui ou non la valeur @value est du bon type @type - * - */ - public static function check($type, $value){ - $checker = true; - - /* [0] On verifie que $value n'est pas nul - =========================================================*/ - if( is_null($value) ) return false; - - - - /* [1] Si de type VARCHAR(min, max, flags) - =========================================================*/ - if( preg_match('/^varchar\((\d+), ?(\d+)((?:, ?\w+)+)?\)$/', $type, $match) ){ - // On recupere la taille min - $min = (int) $match[1]; - // On recupere la taille max - $max = (int) $match[2]; - - // On recupere le sous-type si défini - $flags = isset($match[3]) ? explode(',', substr($match[3], 1)) : null; - - // On effectue la verification de taille - $lenCheck = $checker && is_string($value) && strlen($value) <= $max && strlen($value) >= $min; - - // On vérifie les FLAGS s'il est donné - if( is_array($flags) ) - foreach( $flags as $flag ) - $lenCheck = $lenCheck && self::check($flag, $value); - - return $lenCheck; - } - - - /* [2] Si de type ARRAY(type_elements) - =========================================================*/ - if( preg_match('/^array<(.+)>$/', $type, $match) ){ - - // Si c'est pas un tableau on retourne une erreur - if( !is_array($value) ) - return false; - - - $elements_type = $match[1]; - - // On verifie le type pour chaque element - foreach($value as $element) - // Si erreur dans au moins 1 element, on retourne que c'est incorrect - if( !self::check($elements_type, trim($element) ) ) - return false; - - // Si aucune erreur, on retourne que tout est bon - return true; - } - - - /* [n] Sinon, tous les autres types definis - =========================================================*/ - switch($type){ - // Quoi que ce soit - case 'mixed': - return $checker && !is_null($value); - break; - - // Entier positif (id dans BDD) - case 'id': - return $checker && is_numeric($value) && $value <= 2147483647 && $value >= 0; - break; - - // Code RFID - case 'rfid': - return $checker && is_string($value) && preg_match('/^[\dA-F]{2}(\-[\dA-F]{2}){3,5}$/i', $value); - break; - - // String quelconque (peut etre vide) - case 'text': - return $checker && is_string($value); - - // Adresse mail (255 caracteres max) - case 'mail': - return $checker && is_string($value) && strlen($value) <= 50 && preg_match('/^[\w\.-]+@[\w\.-]+\.[a-z]{2,4}$/i', $value); - break; - - // Hash sha1/md5 - case 'hash': - return $checker && is_string($value) && preg_match('/^[\da-f]{40}$/i', $value); - break; - - case 'alphanumeric': - case 'user.username': - case 'group.name': - return $checker && is_string($value) && preg_match('/^[\w-]+$/i', $value); - break; - - case 'user.firstname': - case 'user.lastname': - case 'letters': - return $checker && is_string($value) && preg_match('/^[a-z -]+$/i', $value); - break; - - case 'status': - return $checker && is_numeric($value) && floor($value) == $value && $value >= 0 && $value <= 100; - break; - - // Tableau non vide - case 'array': - return $checker && is_array($value) && count($value) > 0; - break; - - // Boolean - case 'boolean': - return $checker && is_bool($value); - break; - - // Objet non vide - case 'object': - return $checker && is_object($value) && count((array) $value) > 0; - break; - - // Chaine JSON (on vérifie via le parser) - case 'json': - return $checker && is_string($value) && json_decode($value, true) !== NULL; - break; - - default: - return false; - break; - } - - return $checker; - - } - - - - - - /* FONCTION QUI FORMATTE UN NUMÉRO DE TÉLÉPHONE - * - * @number Numéro de téléphone en +336/336/06/0336/00336 - * - * @return formatted Numéro formatté (06), on FALSE si erreur - * - */ - public static function formatNumber($number){ - // On met en quel que soit le type - $number = (string) $number; - - // On supprime tous les espaces - $number = str_replace(' ', '', $number); - - // On formatte le numéro - if( preg_match("/^(?:\+33|0?0?33|0)(.+)/", $number, $m) ) - $number = '0'.$m[1]; - - // On retourne le numéro formatté - return $number; - } - - - public static function readableNumber($number){ - /* (1) On formatte le numéro si c'est pas fait */ - $formatted = self::formatNumber($number); - - for( $i = 1 ; $i < strlen($formatted) ; $i++ ) - if( ($i-2) % 3 == 0 ) - $formatted = substr($formatted, 0, $i).' '.substr($formatted, $i); - - return $formatted; - } - - - //////////////////////////////////// - // _ _ - // __| | __ _| |_ ___ ___ - // / _` |/ _` | __/ _ \/ __| - // | (_| | (_| | || __/\__ \ - // \__,_|\__,_|\__\___||___/ - // - //////////////////////////////////// - // 1) Convertis une date en en francais explicite - public static function frDate($date){ - /* [1] On definit les traductions - =========================================================*/ - // Jours de la semaine - $days = ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"]; - // Mois de l'annee - $months = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"]; - - /* [2] On recupere le timestamp et les indices - =========================================================*/ - $time = strtotime($date); // timestamp - $daynum = intval( date('N', $time)-1 ); // jour dans la semaine - $monthnum = intval( date('n', $time)-1 ); // numero du mois dans l'annee - - - /* [3] On recupere les infos independemment - =========================================================*/ - $result = [ - $days[$daynum], // nom de jour - date('j', $time), // jour du mois - $months[$monthnum], // nom du mois - date('Y', $time), // annee - ]; - - - return implode(" ", $result); - } - - } -?> diff --git a/build/database/core/DatabaseDriver.php b/build/database/core/DatabaseDriver.php new file mode 100755 index 0000000..a82218d --- /dev/null +++ b/build/database/core/DatabaseDriver.php @@ -0,0 +1,327 @@ + Database Server's host + * @dbname Database name + * @username Database username + * @password Database password + * + */ + private function __construct($host, $dbname, $username, $password){ + /* (2) Stores configuration */ + $this->host = $host; + $this->dbname = $dbname; + $this->username = $username; + $this->password = $password; + + try{ + + $this->pdo = new \PDO('mysql:host='.$this->host.';dbname='.$this->dbname, $this->username, $this->password); + + // On signale que tout s'est bien passe + $this->error = Error::Success; + + }catch(Exception $e){ + // On signale qu'il y a une erreur + $this->error = Error::PDOConnection; + } + } + + + + /************************************************ + **** Multiton Management (static) **** + ************************************************/ + + /* ADDS A NEW CONNECTION + * + * @label [optional] Database Label + * + * @return status If added successfully + * + */ + private static function add($label=null){ + $conf = self::conf(); + + /* [1] Default values + =========================================================*/ + /* (1) If label isn't given */ + is_null($label) && ($label = 'default'); + + /* (2) If label and no path */ + if( $label !== 'default' && !isset($conf[$label]) ) + return false; + + + /* [3] Instanciates the driver + =========================================================*/ + try{ + + /* (1) If local -> instanciates with local configuration */ + if( !checkdnsrr($_SERVER['SERVER_NAME'], 'NS') ) + self::$instance[$label] = new DatabaseDriver($conf[$label]['local']['host'], $conf[$label]['local']['dbname'], $conf[$label]['local']['user'], $conf[$label]['local']['password']); + /* (2) If Remote -> instanciates with Remote configuration */ + else + self::$instance[$label] = new DatabaseDriver($conf[$label]['remote']['host'], $conf[$label]['remote']['dbname'], $conf[$label]['remote']['user'], $conf[$label]['remote']['password']); + + return true; + + }catch(\Exception $e){ + + /* (3) If fails */ + return false; + + } + + } + + + /* GET A DATABASE DRIVER INSTANCE + * + * @label [optional] Driver's label + * + * @return driver Multiton + * + */ + public static function get($label=null){ + $conf = self::conf(); + + /* [1] Checks arguments + =========================================================*/ + /* (1) Label default value */ + is_null($label) && ($label = 'default'); + + /* (2) If no label, or unknown label */ + if( is_null($label) || !isset(self::$instance[$label]) ){ + + /* (2.1) Try to add the configuration if exists */ + if( isset($conf[$label]) ){ + self::add($label); + return self::get($label); + } + + + throw new \Exception('Database @label is incorrect.'); + } + + + /* [2] Returns instance + =========================================================*/ + return self::$instance[$label]; + } + + + /* retourne la connection statique */ + public static function getPDO($label=null){ + $instance = self::get($label); + + return $instance->pdo; + } + + + public function getConfig(){ + return [ + 'host' => $this->host, + 'dbname' => $this->dbname, + 'username' => $this->username + ]; + } + + + + + + + + /*************************************************************/ + /* _____ ______ _ _ ______ _____ _ */ + /* / ____| ____| \ | | ____| __ \ /\ | | */ + /* | | __| |__ | \| | |__ | |__) | / \ | | */ + /* | | |_ | __| | . ` | __| | _ / / /\ \ | | */ + /* | |__| | |____| |\ | |____| | \ \ / ____ \| |____ */ + /* \_____|______|_| \_|______|_| \_\/_/ \_\______| */ + /* */ + /*************************************************************/ + + /* SUPPRIME LES VALEURS À CLÉS NUMÉRIQUES DANS UN FETCH D'UNE TABLE DE LA BDD + * + * @fetchData le résultat d'une $requeteSQL->fetchAll() + * @oneDimension FAUX <=> fetchAll ; VRAI <=> fetch + * + * @return newFetchData retourne le tableau donné en paramètre mais sans les valeurs à clés numériques + * + */ + public static function delNumeric($fetchData, $oneDimension=false){ + // On quitte si ce n'est pas un tableau + if( !is_array($fetchData) ) + return []; + + $nextEquivalent = false; // Vaut VRAI si le prochain est peut-etre un equivalent numerique + + /* [1] 2 dimensions + ===============================================*/ + if( !$oneDimension && isset($fetchData[0]) && is_array($fetchData[0]) ){ + + // on supprime les doublons des entrées (indice numérique) + for( $i = 0 ; $i < count($fetchData) ; $i++ ) // pour tout les utilisateurs + foreach($fetchData[$i] as $col => $val){ // pour toutes les entrées + + if( !\mb_detect_encoding($val, 'UTF-8') ) + $fetchData[$i][$col] = utf8_encode($val); + + if( is_int($col) ){ // Si indice numerique + if( $nextEquivalent ) // Si suit un indice textuel + unset( $fetchData[$i][$col] ); // on supprime l'indice + + $nextEquivalent = false; // Dans tous les cas, on dit que le prochain ne pourra pas etre supprime si numerique + + }else // Si l'indice n'est pas un entier + $nextEquivalent = true; // On signale qu'il y aura peut etre un indice numerique suivant + + } + + /* [2] 1 dimensions + ===============================================*/ + }else{ + + // on supprime les doublons des entrées (indice numérique) + foreach($fetchData as $i=>$val){ // pour toutes les entrées + + if( !\mb_detect_encoding($val, 'UTF-8') ) + $fetchData[$i] = utf8_encode($val); + + if( is_int($i) ){ // Si indice numerique + if( $nextEquivalent ) // Si suit un indice textuel + unset( $fetchData[$i] ); // on supprime l'indice + + $nextEquivalent = false; // Dans tous les cas, on dit que le prochain ne pourra pas etre supprime si numerique + + }else // Si l'indice n'est pas un entier + $nextEquivalent = true; // On signale qu'il y aura peut etre un indice numerique suivant + + } + + } + + return $fetchData; + } + + + + + /* FONCTION QUI FORMATTE UN NUMÉRO DE TÉLÉPHONE + * + * @number Numéro de téléphone en +336/336/06/0336/00336 + * + * @return formatted Numéro formatté (06), on FALSE si erreur + * + */ + public static function formatNumber($number){ + // On met en quel que soit le type + $number = (string) $number; + + // On supprime tous les espaces + $number = str_replace(' ', '', $number); + + // On formatte le numéro + if( preg_match("/^(?:\+33|0?0?33|0)(.+)/", $number, $m) ) + $number = '0'.$m[1]; + + // On retourne le numéro formatté + return $number; + } + + + public static function readableNumber($number){ + /* (1) On formatte le numéro si c'est pas fait */ + $formatted = self::formatNumber($number); + + for( $i = 1 ; $i < strlen($formatted) ; $i++ ) + if( ($i-2) % 3 == 0 ) + $formatted = substr($formatted, 0, $i).' '.substr($formatted, $i); + + return $formatted; + } + + + //////////////////////////////////// + // _ _ + // __| | __ _| |_ ___ ___ + // / _` |/ _` | __/ _ \/ __| + // | (_| | (_| | || __/\__ \ + // \__,_|\__,_|\__\___||___/ + // + //////////////////////////////////// + // 1) Convertis une date en en francais explicite + public static function frDate($date){ + /* [1] On definit les traductions + =========================================================*/ + // Jours de la semaine + $days = ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"]; + // Mois de l'annee + $months = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"]; + + /* [2] On recupere le timestamp et les indices + =========================================================*/ + $time = strtotime($date); // timestamp + $daynum = intval( date('N', $time)-1 ); // jour dans la semaine + $monthnum = intval( date('n', $time)-1 ); // numero du mois dans l'annee + + + /* [3] On recupere les infos independemment + =========================================================*/ + $result = [ + $days[$daynum], // nom de jour + date('j', $time), // jour du mois + $months[$monthnum], // nom du mois + date('Y', $time), // annee + ]; + + + return implode(" ", $result); + } + + } +?> diff --git a/build/database/repo/action.php b/build/database/repo/action.php index 84c804a..c33b6ed 100644 --- a/build/database/repo/action.php +++ b/build/database/repo/action.php @@ -1,7 +1,7 @@ query('SHOW COLUMNS FROM '.static::table_name()); - $cols = Database::delNumeric( $getColumns->fetchAll() ); + $getColumns = DatabaseDriver::getPDO()->query('SHOW COLUMNS FROM '.static::table_name()); + $cols = DatabaseDriver::delNumeric( $getColumns->fetchAll() ); $table_columns = [ '_PRIMARY_' => [] // Contiendra les champs de la clé primaire @@ -95,7 +95,7 @@ $getRequestString .= ' ORDER BY 1 ASC'; // On prépare la requête - $getRequest = Database::getPDO()->prepare($getRequestString); + $getRequest = DatabaseDriver::getPDO()->prepare($getRequestString); /* [5] On exécute la requête @@ -128,12 +128,12 @@ // Si résultat else - return Database::delNumeric($result, true); + return DatabaseDriver::delNumeric($result, true); /* (2) Réponse multiple (getAll, ...) */ }else - return Database::delNumeric( $getRequest->fetchAll() ); + return DatabaseDriver::delNumeric( $getRequest->fetchAll() ); } } diff --git a/build/database/repo/pin_merge.php b/build/database/repo/pin_merge.php index 23b317b..bc4b754 100644 --- a/build/database/repo/pin_merge.php +++ b/build/database/repo/pin_merge.php @@ -1,7 +1,7 @@ prepare("SELECT s.state, pm.id_chip, GROUP_CONCAT(s.value ORDER BY pm.pin ASC) as pin_values + $req = DatabaseDriver::getPDO()->prepare("SELECT s.state, pm.id_chip, GROUP_CONCAT(s.value ORDER BY pm.pin ASC) as pin_values FROM state as s, pin_merge as pm WHERE s.id_pin_merge = pm.id_pin_merge AND pm.id_chip = :id_chip diff --git a/build/database/repo/user.php b/build/database/repo/user.php index 8e9b318..c49f358 100755 --- a/build/database/repo/user.php +++ b/build/database/repo/user.php @@ -1,7 +1,7 @@ prepare("SELECT * FROM user + $searchusers = DatabaseDriver::getPDO()->prepare("SELECT * FROM user WHERE id_warehouse = :id_warehouse AND ( code LIKE '%".$keyword."%' OR username LIKE '%".$keyword."%' @@ -81,7 +81,7 @@ ':id_warehouse' => $id_warehouse ]); - return Database::delNumeric( $searchusers->fetchAll() ); + return DatabaseDriver::delNumeric( $searchusers->fetchAll() ); } diff --git a/build/database/repo/user_cluster.php b/build/database/repo/user_cluster.php index 62e5e80..94b601f 100644 --- a/build/database/repo/user_cluster.php +++ b/build/database/repo/user_cluster.php @@ -1,7 +1,7 @@ Tableau contenant les informations de la requête + * @driver [optional] DatabaseDriver label * */ - public function __construct($schema){ - /* (1) On récupère les informations */ + public function __construct($schema, $driver=null){ + /* (1) Database Driver */ + $this->driver = $driver; + + /* (2) On récupère les informations */ $this->schema = $schema; - /* (2) On initialise les conditions */ + /* (3) On initialise les conditions */ $this->where = []; - /* (3) On initialise les champs à retourner */ + /* (4) On initialise les champs à retourner */ $this->select = []; - /* (4) On initialise l'ordonnancement' */ + /* (5) On initialise l'ordonnancement' */ $this->orderby = []; - /* (5) On initialise le caractère 'unique' du résultat */ + /* (6) On initialise le caractère 'unique' du résultat */ $this->unique = false; - /* (6) On initialise les jointures */ + /* (7) On initialise les jointures */ $this->joined = []; } - - /* FILTRE LES ENTREES D'UNE TABLE AVEC LA CLE PRIMAIRE SPECIFIEE * * @primary Clé primaire simple @@ -164,10 +167,6 @@ } - - - - /* FILTRAGE DYNAMIQUES * * @method Nom de la méthode @@ -244,9 +243,6 @@ } - - - /* SELECTIONNE UNIQUEMENT LE CHAMP SELECTIONNE * * @field Libellé du champ à afficher @@ -280,9 +276,19 @@ /* [2] On enregistre le champ =========================================================*/ - /* (1) Si aucun SELECT pour ce champ, on le crée */ - if( !isset($this->select[$field]) ) - $this->select[$field] = [$func, $distinct]; + /* (1) Si "SELECT *" on ajout tous les champs */ + if( $field === '*' ){ + + foreach($this->schema['columns'] as $f=>$c) + if( !isset($this->select[$f]) ) + $this->select[$f] = [$func, $distinct]; + + /* (2) Si aucun SELECT pour ce champ, on le crée */ + }else{ + + if( !isset($this->select[$field]) ) + $this->select[$field] = [$func, $distinct]; + } /* [3] On retourne l'object courant @@ -291,9 +297,6 @@ } - - - /* SELECTIONNE L'ORDONNANCEMENT DES RESULTATS * * @field Libellé du champ à afficher @@ -336,11 +339,6 @@ } - - - - - /* JOINT UNE SECONDE TABLE () * * @localField Nom d'une colonne locale @@ -420,11 +418,6 @@ } - - - - - /* PERMET DE DIRE QUE L'ON VEUT UN RESULTAT UNIQUE * * @return this Retourne l'object courant @@ -442,11 +435,6 @@ } - - - - - /* MODIFIE DES ENTREES (SANS MODIFICATION DE CLE PRIMAIRE POSSIBLE) * * @updates Tableau associatif contenant les nouvelles valeurs @@ -562,7 +550,7 @@ $requestString = SQLBuilder::BUILD($requestS).';'; /* (2) On prépare la requête */ - $request = Database::getPDO()->prepare($requestString); + $request = DatabaseDriver::getPDO($this->driver)->prepare($requestString); @@ -575,10 +563,6 @@ return $updated; } - - - - /* AJOUTE UNE ENTREE DANS LA TABLE * * @entry Tableau associatif de la forme (colonne => valeur) @@ -687,7 +671,7 @@ /* [2] On bind les paramètres et exécute la requête =========================================================*/ /* (0) On initialise la requête et les paramètres */ - $request = Database::getPDO()->prepare($requestS.';'); + $request = DatabaseDriver::getPDO($this->driver)->prepare($requestS.';'); $bound = []; /* (1) On bind les paramètres */ @@ -706,8 +690,6 @@ } - - /* SUPPRIME LES ENTREES * * @return status Retourne si TRUE ou FALSE les entrées ont bien été supprimées @@ -779,7 +761,7 @@ $requestString = SQLBuilder::BUILD($requestS).';'; /* (2) On prépare la requête */ - $request = Database::getPDO()->prepare($requestString); + $request = DatabaseDriver::getPDO($this->driver)->prepare($requestString); /* [5] On exécute la requête et retourne le résultat =========================================================*/ @@ -791,10 +773,6 @@ } - - - - /* RETOURNE LES DONNEES / NULL si une erreur survient * * @execute VRAI si on veut exécuter la requête, sinon renvoie [requete, boundParams] @@ -959,7 +937,7 @@ $requestString = SQLBuilder::BUILD($requestS).';'; /* (3) On prépare la requête */ - $request = Database::getPDO()->prepare($requestString); + $request = DatabaseDriver::getPDO($this->driver)->prepare($requestString); // var_dump($requestString); @@ -977,10 +955,6 @@ } - - - - /* ON FORMATTE LES DONNEES DE SORTIE * * @data Données / Tableau de données diff --git a/build/orm/core/SQLBuilder.php b/build/orm/core/SQLBuilder.php index 0208822..7a92c11 100644 --- a/build/orm/core/SQLBuilder.php +++ b/build/orm/core/SQLBuilder.php @@ -2,7 +2,7 @@ namespace orm\core; - use \database\core\Database; + use \database\core\DatabaseDriver; use \orm\core\Rows; diff --git a/build/orm/core/Table.php b/build/orm/core/Table.php index 7f70121..6154861 100644 --- a/build/orm/core/Table.php +++ b/build/orm/core/Table.php @@ -3,7 +3,7 @@ namespace orm\core; - use \database\core\Database; + use \database\core\DatabaseDriver; use \error\core\Error; use \orm\core\Rows; @@ -11,21 +11,20 @@ // CLASSE MAITRE class Table{ - private static $database = 'logauth'; - /* RENVOIE LES DONNEES D'UNE TABLE * * @table Nom de la table à selectionner + * @driver [optional] DatabaseDriver label * * @return this Retourne une instance de l'ORM * */ - public static function get($table_name){ + public static function get($table_name, $driver=null){ /* [0] Initialisation des attributs =========================================================*/ $schema = [ - 'database' => self::$database, + 'database' => DatabaseDriver::get($driver)->getConfig()['dbname'], 'table' => null, 'columns' => null ]; @@ -34,13 +33,13 @@ /* [1] On vérifie que la table existe =========================================================*/ /* (1) Requête */ - $checkTable = Database::getPDO()->query("SHOW tables FROM ".self::$database); - $checkTableResult = Database::delNumeric( $checkTable->fetchAll() ); + $checkTable = DatabaseDriver::getPDO($driver)->query("SHOW tables FROM ".$schema['database']); + $checkTableResult = DatabaseDriver::delNumeric( $checkTable->fetchAll() ); /* (2) On met en forme les données */ $tables = []; foreach($checkTableResult as $table) - $tables[] = $table['Tables_in_'.self::$database]; + $tables[] = $table['Tables_in_'.$schema['database']]; /* (3) Si n'existe pas, on renvoie une erreur */ if( !in_array($table_name, $tables) ) @@ -54,8 +53,8 @@ /* [2] Si la table existe, on récupère les colonnes =========================================================*/ /* (1) On récupère les colonnes */ - $getColumns = Database::getPDO()->query("SHOW columns FROM ".self::$database.'.'.$table_name); - $columnsResult = Database::delNumeric( $getColumns->fetchAll() ); + $getColumns = DatabaseDriver::getPDO($driver)->query("SHOW columns FROM ".$schema['database'].'.'.$table_name); + $columnsResult = DatabaseDriver::delNumeric( $getColumns->fetchAll() ); /* (2) On met en forme les données */ $columns = []; @@ -85,7 +84,7 @@ /* [3] On récupère les clés étrangères =========================================================*/ /* (1) On récupère le texte du 'CREATE TABLE' */ - $getCreateTable = Database::getPDO()->query("show create table ".$table_name); + $getCreateTable = DatabaseDriver::getPDO($driver)->query("show create table ".$table_name); $create_table = $getCreateTable->fetch()['Create Table']; /* (2) On découpte en lignes */ @@ -97,10 +96,9 @@ $schema['columns'][$m[1]]['references'] = [$m[2], $m[3]]; - /* [3] On renvoie une instance de 'Rows' =========================================================*/ - return new Rows($schema); + return new Rows($schema, $driver); } diff --git a/config/database-driver.json b/config/database-driver.json new file mode 100644 index 0000000..b3572e2 --- /dev/null +++ b/config/database-driver.json @@ -0,0 +1,16 @@ +{ + "default": { + "local": { + "host" : "localhost", + "dbname" : "logauth", + "user" : "php", + "password" : "Qt358nUdyeTxLDM8" + }, + "remote": { + "host" : "xdrm.io", + "dbname" : "logauth", + "user" : "php", + "password" : "QbzjZACndQM6NmuD" + } + } +} diff --git a/config/database-local.json b/config/database-local.json deleted file mode 100755 index a43a376..0000000 --- a/config/database-local.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "host" : "localhost", - "dbname" : "logauth", - "user" : "php", - "password" : "Qt358nUdyeTxLDM8" -} diff --git a/config/database.json b/config/database.json deleted file mode 100755 index d6f6850..0000000 --- a/config/database.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "host" : "xdrm.io", - "dbname" : "logauth", - "user" : "php", - "password" : "QbzjZACndQM6NmuD" -} diff --git a/phpunit/tests/Database_construct.php b/phpunit/tests/Database_construct.php index 4b22432..76b7307 100755 --- a/phpunit/tests/Database_construct.php +++ b/phpunit/tests/Database_construct.php @@ -5,17 +5,17 @@ /* [1] Verification du chargement de la config =========================================================*/ public function testGetInstanceWithNoSERVER(){ - $instance = \database\core\Database::getInstance(); + $instance = \database\core\DatabaseDriver::get(); $this->assertEquals( 'localhost', $instance->getConfig()['host'] ); } public function testGetInstanceWithSERVERLocal(){ // Pour regenerer une instance, on definit une erreur - \database\core\Database::$error = \error\core\Error::PDOConnection; + \database\core\DatabaseDriver::$error = \error\core\Error::PDOConnection; - $instance = \database\core\Database::getInstance(); + $instance = \database\core\DatabaseDriver::get(); $this->assertEquals( 'localhost', $instance->getConfig()['host'] ); } @@ -25,20 +25,20 @@ /* [2] Verification du singleton (getInstance) =========================================================*/ public function testInstancePersistence(){ - \database\core\Database::$error = \error\core\Error::PDOConnection; + \database\core\DatabaseDriver::$error = \error\core\Error::PDOConnection; - $instance_construct = \database\core\Database::getInstance(); - $instance_nextuse = \database\core\Database::getInstance(); + $instance_construct = \database\core\DatabaseDriver::get(); + $instance_nextuse = \database\core\DatabaseDriver::get(); $this->assertSame( $instance_construct, $instance_nextuse ); } public function testInstancePersistenceRefutation(){ - \database\core\Database::$error = \error\core\Error::PDOConnection; - $instance_construct = \database\core\Database::getInstance(); + \database\core\DatabaseDriver::$error = \error\core\Error::PDOConnection; + $instance_construct = \database\core\DatabaseDriver::get(); - \database\core\Database::$error = \error\core\Error::PDOConnection; - $instance_nextuse = \database\core\Database::getInstance(); + \database\core\DatabaseDriver::$error = \error\core\Error::PDOConnection; + $instance_nextuse = \database\core\DatabaseDriver::get(); $this->assertNotSame( $instance_construct, $instance_nextuse ); } @@ -48,7 +48,7 @@ /* [3] Verification de l'objet PDO =========================================================*/ public function testPDO(){ - $pdo = \database\core\Database::getPDO(); + $pdo = \database\core\DatabaseDriver::getPDO(); $this->assertGreaterThan( 10, count($pdo->query('SELECT * FROM user')->fetchAll()), '[!] Moins de 10 utilisateurs trouves.'); } diff --git a/phpunit/tests/Database_delNumeric.php b/phpunit/tests/Database_delNumeric.php index 726f462..1422640 100755 --- a/phpunit/tests/Database_delNumeric.php +++ b/phpunit/tests/Database_delNumeric.php @@ -5,11 +5,11 @@ /* [0] Verification du type =========================================================*/ public function testTypeInt(){ - $this->assertEquals( [], \database\core\Database::delNumeric(10) ); + $this->assertEquals( [], \database\core\DatabaseDriver::delNumeric(10) ); } public function testTypeString(){ - $this->assertEquals( [], \database\core\Database::delNumeric('notarray') ); + $this->assertEquals( [], \database\core\DatabaseDriver::delNumeric('notarray') ); } /* [1] Verification pour 2 dimensions @@ -23,7 +23,7 @@ 1 => 'Jean Dupont', ]]; - $computed_array = \database\core\Database::delNumeric( $fetchData ); + $computed_array = \database\core\DatabaseDriver::delNumeric( $fetchData ); $this->assertArrayHasKey( 'id', $computed_array[0] ); $this->assertArrayHasKey( 'nom', $computed_array[0] ); @@ -46,7 +46,7 @@ 7 => 'Bla' ]]; - $computed_array = \database\core\Database::delNumeric( $fetchData ); + $computed_array = \database\core\DatabaseDriver::delNumeric( $fetchData ); $this->assertArrayHasKey( 'id', $computed_array[0] ); $this->assertArrayHasKey( 'nom', $computed_array[0] ); @@ -73,7 +73,7 @@ 1 => 'Jean Dupont' ]; - $computed_array = \database\core\Database::delNumeric( $fetchData ); + $computed_array = \database\core\DatabaseDriver::delNumeric( $fetchData ); $this->assertArrayHasKey( 'id', $computed_array ); $this->assertArrayHasKey( 'nom', $computed_array ); @@ -96,7 +96,7 @@ 7 => 'Bla' ]; - $computed_array = \database\core\Database::delNumeric( $fetchData ); + $computed_array = \database\core\DatabaseDriver::delNumeric( $fetchData ); $this->assertArrayHasKey( 'id', $computed_array ); $this->assertArrayHasKey( 'nom', $computed_array ); diff --git a/public_html/index.php b/public_html/index.php index 4068037..5e02461 100755 --- a/public_html/index.php +++ b/public_html/index.php @@ -6,6 +6,7 @@ use \api\core\ModuleRequest; use \api\core\ModuleResponse; + use \database\core\DatabaseDriver; use \error\core\Error; use \api\core\Authentification; @@ -21,8 +22,6 @@ - - /* [1] Gestion des authentifications et des droits =========================================================*/ /* (1) On met à jour l'authentification et les permissions */ diff --git a/public_html/test/automate.php b/public_html/test/automate.php index d30d1ad..389f989 100755 --- a/public_html/test/automate.php +++ b/public_html/test/automate.php @@ -1,12 +1,15 @@ dispatch(); - + Table::add(); $state = Table::get('state') ->select('state') diff --git a/public_html/view/history.php b/public_html/view/history.php index 8d5a354..a9e4385 100755 --- a/public_html/view/history.php +++ b/public_html/view/history.php @@ -2,7 +2,7 @@ require_once __ROOT__.'/autoloader.php'; use \api\core\ModuleRequest; use \error\core\Error; - use \database\core\Database; + use \database\core\DatabaseDriver; use \database\core\Repo; use \orm\core\Table; use \orm\core\Rows; diff --git a/todo.md b/todo.md index 93c5704..ace0030 100755 --- a/todo.md +++ b/todo.md @@ -140,11 +140,11 @@ - [x] [sessionManager] Import de sessionManager - [x] [phpunit/tests/Database_*] Tests unitaire de delNumeric() - [x] [Database] Mise a jour des methodes de Database - - [x] [Database::check] Suite de l'implementation ajout de "user.status" + - [x] [DatabaseDriver::check] Suite de l'implementation ajout de "user.status" - [x] [phpunit/tests/Database_check] Tests associes - - [x] [Database::construct] Gestion du singleton et de la config - - [x] [Database::check] Suite de l'implementation (couverture des types de la BDD actuelle: 100%) - - [x] [Database::delNumeric] Prevention si oubli @oneDimension + ne supprime plus les indices numeriques associees a aucun indice textuel + - [x] [DatabaseDriver::construct] Gestion du singleton et de la config + - [x] [DatabaseDriver::check] Suite de l'implementation (couverture des types de la BDD actuelle: 100%) + - [x] [DatabaseDriver::delNumeric] Prevention si oubli @oneDimension + ne supprime plus les indices numeriques associees a aucun indice textuel - [x] [phpunit/tests/Database_check] Tests unitaire du checker - [x] [phpunit/] Install+Config phpunit - [x] [Database] Checker de type (types utilises dans la BDD)