/Framework/Packages/Framework/Database/MysqlDatabase.php
PHP | 426 lines | 223 code | 59 blank | 144 comment | 44 complexity | c3a7303b90a6616a51258cab67abad9f MD5 | raw file
- <?php
- class MysqlDatabase implements Database
- {
- //////////////////////////
- // Attributs
- /////////
- /**
- * Objet base de donnée
- * @var PDO
- */
- private $pdo;
- /**
- * Objet de gestion du cache
- * @var Cache
- */
- private $cache;
- /**
- * Active ou désactive la mise en cache des requêtes
- * @var boolean
- */
- private $cache_enable;
- /**
- * Nom du prefix des tables
- * @var string
- */
- private $prefix;
- /**
- * Définis le fetchMode suivant une classe
- * @var string | boolean
- */
- private $fetchClass = false;
- /**
- * Définis des jointures dans la requête
- * @var array | boolean
- */
- private $join = false;
- /**
- * Liste des configurations
- * @var array
- */
- private $conf = [];
- //////////////////////////
- // Constructeur
- /////////
- /**
- * Initialisation de la base de données
- *
- * @param array $config : Liste des configuration
- * host : Url vers la base de donnée
- * user : Nom d'utilisateur
- * password : Mot de passe
- * db_type : Type de base de donnée (mysql, ...)
- * db_name : Nom de la base de donnée
- * prefix : Préfix des tables
- * charset : Charset de la base de donnée
- * debug_level : Niveau de débugage des erreurs sql
- * #cache_duration : Durée de mise en cache (0 pour désactiver)
- * #cache_directory : Répertoire de sauvegarde du cache
- */
- public function __construct(array $config)
- {
- $this->conf = $config;
- $this->cache_enable = (isset($config['cache_duration']) && $config['cache_duration']) > 0 ? true : false;
- $this->cache = new Cache($config['cache_directory'] ? $config['cache_directory'] : '',
- $config['cache_duration'] ? $config['cache_duration'] : 0);
- $this->prefix = $config['prefix'];
- }
- //////////////////////////
- // Public Methods
- /////////
- /**
- * Définis une class comme valeur de retour
- *
- * @param string $class : Nom de la classe
- *
- * @return Database
- */
- public function setFetch($class)
- {
- $this->fetchClass = $class;
- return $this;
- }
- /**
- * Définis une liste de r$egle pour les jointures
- *
- * @param array $join : Liste des jointure
- *
- * @return Database
- */
- public function setJoin(array $join)
- {
- $this->join = $join;
- return $this;
- }
- /**
- * Retourne la structure de la table
- *
- * @param string $table : Nom de la table
- *
- * @return mixed
- */
- public function describe($table)
- {
- return $this->query('DESCRIBE ' . $this->prefix . $table, [], true);
- }
- /**
- * Recherche une/des entrée(s) suivant les le/les critère(s)
- *
- * @param string $table : Nom de la table à utiliser
- * @param array $criteres : Critères de séléction Array['critere' => 'valeur'(, 'critere' => 'valeur')]
- * @param string $data : Elements à retourner Array['Element'(, 'Element')] (default *)
- * @param mixed $limit : Limite d'elements à retourner (default 50)
- * @param mixed $order : Ordre des elements à retourner (default false)
- *
- * @return mixed Résultat de la requête sql
- */
- public function search($table, $criteres = [], $data = '*', $limit = 50, $order = false)
- {
- if (!is_array($criteres)) {
- return [];
- }
- $class = $this->fetchClass;
- $this->fetchClass = false;
- if (is_array($data)) {
- foreach ($data as $col) {
- $column[] = $this->prefix . $table . '.' . $col;
- }
- } else {
- $column[] = $this->prefix . $table . '.' . $data;
- }
- if ($order) {
- $order = ' ORDER BY ' . $table . '.' . $order;
- }
- $one = $limit === 1 ? true : false;
- if ($limit !== false) {
- $limit = ' LIMIT ' . $limit;
- }
- if ($this->join) {
- $join = '';
- foreach ($this->join as $table_join => $columns) {
- foreach ($this->describe($table_join) as $structure) {
- $column[] = $this->prefix . $table_join . '.' . $structure['Field'] . ' AS ' . $table_join . '_' .
- $structure['Field'];
- }
- $join .=
- ' LEFT JOIN ' . $this->prefix . $table_join . ' ON ' . $this->prefix . $table . '.' . $columns[0] .
- ' = ' . $this->prefix . $table_join . '.' . $columns[1];
- }
- $this->join = false;
- } else {
- $join = false;
- }
- $column = implode($column, ', ');
- $this->fetchClass = $class;
- return $this->query('SELECT ' . $column . ' FROM ' . $this->prefix . $table . $join .
- $this->parseSQLWhere($criteres, $table) . $order . $limit, $criteres, true, $one);
- }
- /**
- * Execution d'une requête sql par PDO::prepare
- *
- * @param string $query : Requête sql
- * @param array $data : Données d'execution de la requête
- * @param boolean $fetch : Execute fetchAll (defaut false)
- * @param boolean $one : Retourne un element de la base
- *
- * @return mixed Résultat de la requête si fetch à true
- */
- public function query($query, $data = [], $fetch = false, $one = false)
- {
- Benchmark::mark('database');
- $hash = hash('md2', $query . implode($data, '-'));
- if ($fetch) {
- if ($content = $this->cache->read($hash)) {
- Benchmark::end('database');
- return $content;
- }
- }
- $requete = $this->getPdo()->prepare($query);
- $data = $requete->execute($data);
- if ($fetch) {
- if ($this->fetchClass !== false) {
- $requete->setFetchMode(PDO::FETCH_CLASS, $this->fetchClass);
- $this->fetchClass = false;
- }
- if ($one) {
- $data = $requete->fetch();
- } else {
- $data = $requete->fetchAll();
- }
- }
- if ($fetch && !$one && $this->cache_enable) {
- $this->cache->write($hash, $data);
- }
- Benchmark::end('database');
- return $data;
- }
- /**
- * Transforme un tableau en critères de recherche SQL
- *
- * @param array $criteres : Array['critere' => 'valeur'(, 'critere' => 'valeur')]
- * @param mixed $table : Nom de la table d'identification
- *
- * @return string Critères de recherche de requête SQL 'WHERE'
- */
- public function parseSQLWhere($criteres, $table = false)
- {
- if (count($criteres) > 0) {
- $where = ' WHERE ';
- foreach ($criteres as $key => $value) {
- $already = strpos($key, '.') === false;
- if (strpos($value, '%') !== false) {
- $where .= ($already && $table !== false ? $this->prefix . $table . '.' : '') . $key . ' LIKE \'' .
- $value .
- '\' AND ';
- } else {
- $where .=
- ($already && $table !== false ? $this->prefix . $table . '.' : '') . $key . ' = :' . $key .
- ' AND ';
- }
- }
- return substr($where, 0, -5);
- } else {
- return '';
- }
- }
- /**
- * Efface une/des entrée(s) suivant les le/les critère(s)
- *
- * @param string $table : Nom de la table à utiliser
- * @param array $criteres : Array['critere' => 'valeur'(, 'critere' => 'valeur')]
- *
- * @return boolean False si une erreur est survenue
- */
- public function delete($table, $criteres)
- {
- if (!isset($criteres) || !is_array($criteres)) {
- return false;
- }
- $this->cache->clear();
- return $this->query('DELETE FROM ' . $this->prefix . $table . $this->parseSQLWhere($criteres), $criteres);
- }
- /**
- * Insert dans la table la/les valeur(s) contenu dans le tableau
- *
- * @param string $table : Nom de la table à utiliser
- * @param array $data : Array['critere' => 'valeur'(, 'critere' => 'valeur')]
- *
- * @return boolean False si une erreur est survenue
- */
- public function insert($table, array $data)
- {
- if (!isset($data) || !is_array($data)) {
- return false;
- }
- $tables = '';
- $values = '';
- if (count($data) > 0) {
- foreach ($data as $key => $value) {
- $tables .= '`' . $key . '`, ';
- $values .= ':' . $key . ', ';
- }
- $tables = substr($tables, 0, -2);
- $values = substr($values, 0, -2);
- }
- $this->cache->clear();
- if ($this->query('INSERT INTO ' . $this->prefix . $table . ' (' . $tables . ') VALUES (' .
- $values . ')', $data)
- ) {
- return $this->getPdo()->lastInsertId();
- } else {
- return false;
- }
- }
- /**
- * Modifie la/les donnée(s) suivant le/les critère(s)
- *
- * @param string $table : Nom de la table à utiliser
- * @param array $data : Array['critere' => 'valeur'(, 'critere' => 'valeur')]
- * @param array $criteres : Array['critere' => 'valeur'(, 'critere' => 'valeur')]
- *
- * @return boolean False si une erreur est survenue
- */
- public function update($table, $data, $criteres)
- {
- if (!isset($data) || !is_array($data) || !isset($criteres) || !is_array($criteres)) {
- return false;
- }
- $update = $criteres;
- $values = '';
- if (count($data) > 0) {
- foreach ($data as $key => $value) {
- if ("" !== $value) {
- $values .= $key . ' = :val_' . $key . ', ';
- $update['val_' . $key] = $value;
- }
- }
- $values = substr($values, 0, -2);
- }
- $this->cache->clear();
- if ($this->query('UPDATE ' . $this->prefix . $table . ' SET ' . $values . $this->parseSQLWhere($criteres),
- $update)
- ) {
- return $this->getPdo()->lastInsertId();
- } else {
- return false;
- }
- }
- /**
- * Recherche si le/les critère(s) sont présent dans la base de données
- *
- * @param string $table : Nom de la table à utiliser
- * @param array $criteres : Array['critere' => 'valeur'(, 'critere' => 'valeur')]
- *
- * @return boolean True si présent dans la base de données
- */
- public function isexist($table, $criteres)
- {
- if (!is_array($criteres)) {
- return false;
- }
- $data = $this->query('SELECT COUNT(*) AS nb FROM ' . $this->prefix . $table . $this->parseSQLWhere($criteres),
- $criteres, true);
- if ($data['0']['nb'] > 0) {
- return $data['0']['nb'];
- }
- return false;
- }
- //////////////////////////
- // Private Methods
- /////////
- /**
- * Retourne l'instance pdo ou la crée si necessaire
- *
- * @return PDO
- * @throws Exception
- */
- private function getPdo()
- {
- if (!isset($this->pdo)) {
- try {
- $charset = '' != $this->conf['charset'] ? ';charset=' . $this->conf['charset'] : '';
- $this->pdo = new PDO($this->conf['db_type'] . ':host=' . $this->conf['host'] . ';dbname=' .
- $this->conf['db_name'] . $charset, $this->conf['user'], $this->conf['password']);
- $this->pdo->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_EMPTY_STRING);
- $this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
- switch ($this->conf['debug_level']) {
- case 0:
- $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
- break;
- case 1:
- $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
- break;
- case 2:
- $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- break;
- default:
- break;
- }
- } catch (PDOException $Exception) {
- if ($this->conf['debug_level'] > 0) {
- throw new Exception($Exception->getMessage(), $Exception->getCode());
- }
- }
- }
- return $this->pdo;
- }
- }