From 7b72b8ae3c3432e7d41987787709edadbdcbae0f Mon Sep 17 00:00:00 2001 From: Cyril Vazquez <cyril.vazquez@maarch.org> Date: Tue, 30 Jun 2015 08:57:31 +0000 Subject: [PATCH] FEAT #2482 Class Database with PDO, used on ObjectCOntrollerAbstract --- .../core/class/ObjectControlerAbstract.php | 12 +- core/trunk/core/class/class_db_pdo.php | 205 +++++++++++------- 2 files changed, 138 insertions(+), 79 deletions(-) diff --git a/core/trunk/core/class/ObjectControlerAbstract.php b/core/trunk/core/class/ObjectControlerAbstract.php index 1baa15942d6..b8a4c682762 100644 --- a/core/trunk/core/class/ObjectControlerAbstract.php +++ b/core/trunk/core/class/ObjectControlerAbstract.php @@ -298,22 +298,22 @@ abstract class ObjectControler require_once 'core/class/class_db_pdo.php'; $database = new Database(); $theQuery = "SELECT * FROM $table_name WHERE $table_id = :id " . $whereComp; - $database->query($theQuery); - $database->bind(':id', $id); + $queryParams = array(':id' => $id); if (count($params > 0)) { foreach ($params as $keyParam => $keyValue) { - $database->bind(":" . $keyParam, $keyValue); + $queryParams[":" . $keyParam] = $keyValue; } } - $database->execute(); + + $stmt = $database->query($theQuery, $queryParams); - if ($database->rowCount() == 0) { + if ($stmt->rowCount() == 0) { return null; } else { // Constructing result $object = new $object_name(); - $rows = $database->resultset(); + $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); for ($cpt=0;$cpt<count($rows);$cpt++) { foreach ($rows[$cpt] as $key => $value) { diff --git a/core/trunk/core/class/class_db_pdo.php b/core/trunk/core/class/class_db_pdo.php index 76d554eabc0..d69ec3034c3 100644 --- a/core/trunk/core/class/class_db_pdo.php +++ b/core/trunk/core/class/class_db_pdo.php @@ -1,22 +1,55 @@ <?php - -class Database { - - private $databasetype; +/* + * Copyright (C) 2015 Maarch + * + * This file is part of Maarch. + * + * Maarch is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Maarch is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Maarch. If not, see <http://www.gnu.org/licenses/>. + */ +/** + * Class for database queries + * + * @package Core + */ +class Database +{ + /** + * Prepared statements indexed by dsn and queryString + * @var array + */ + private static $preparedStmt = array(); + + private $driver; private $server; private $port; private $user; private $password; private $database; + private $dsn; - private $dbh; + private $pdo; + private $error; private $stmt; + /** + * Constructor. Connects to the database if connection parameters are available in the session config + */ public function __construct() { - if (isset($_SESSION['config']['databaseserver'])) { + if (isset($_SESSION['config']['databaseserver'])) { $this->server = $_SESSION['config']['databaseserver']; } if (isset($_SESSION['config']['databaseserverport'])) { @@ -32,112 +65,138 @@ class Database { $this->database = $_SESSION['config']['databasename']; } if (isset($_SESSION['config']['databasetype'])) { - $this->databasetype = $_SESSION['config']['databasetype']; - if ($this->databasetype == 'POSTGRESQL') { - $this->databasetype = 'pgsql'; - } elseif ($this->databasetype == 'MYSQL') { - $this->databasetype = 'mysql'; - } elseif ($this->databasetype == 'ORACLE') { - $this->databasetype = 'oracle'; + switch($_SESSION['config']['databasetype']) { + case 'POSTGRESQL': + $this->driver = 'pgsql'; + break; + case 'MYSQL': + $this->driver = 'mysql'; + break; + + case 'ORACLE': + $this->driver = 'oci'; + break; + + default: + print_r('DRIVER ERROR: Unknown database driver ' . $_SESSION['config']['databasetype']); } } // Set DSN - $dsn = $this->databasetype - . ':host=' . $this->server - . ';port=' . $this->port - . ';dbname=' . $this->database; + $this->dsn = $this->databasetype + . ':host=' . $this->server + . ';port=' . $this->port + . ';dbname=' . $this->database + ; + + if (!isset(self::$preparedStmt[$this->dsn])) { + self::$preparedStmt[$this->dsn] = array(); + } // Set options $options = array ( PDO::ATTR_PERSISTENT => true, - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_CASE => PDO::CASE_LOWER ); // Create a new PDO instanace try { - $this->dbh = new PDO($dsn, $this->user, $this->password, $options); - } - // Catch any errors - catch (PDOException $e) { - $this->error = $e->getMessage(); + $this->pdo = new PDO($this->dsn, $this->user, $this->password, $options); + } catch (PDOException $PDOException) { + $this->error = $PDOException->getMessage(); } if ($this->error && $_SESSION['config']['debug'] == 'true') { - print_r('SQL ERROR:' . $this->error); + print_r('SQL ERROR:' . $this->error); } } - public function query($query) + /** + * Begin a new transaction + * + * @return bool + */ + public function beginTransaction() { - $this->stmt = $this->dbh->prepare($query); + return $this->pdo->beginTransaction(); } - public function bind($param, $value, $type = null) + /** + * Commit a transaction + * + * @return bool + */ + public function commit() { - if (is_null($type)) { - switch (true) { - case is_int($value): - $type = PDO::PARAM_INT; - break; - case is_bool($value): - $type = PDO::PARAM_BOOL; - break; - case is_null($value): - $type = PDO::PARAM_NULL; - break; - default: - $type = PDO::PARAM_STR; - } - } - $this->stmt->bindValue($param, $value, $type); + return $this->pdo->commit(); } - public function execute() + /** + * Rollback a transaction + * + * @return bool + */ + public function rollback() { - return $this->stmt->execute(); + return $this->pdo->rollback(); } - public function resultset() + /** + * Check if in a transaction + * + * @return bool + */ + public function inTransaction() { - $this->execute(); - return $this->stmt->fetchAll(PDO::FETCH_ASSOC); + return $this->pdo->inTransaction(); } - public function single() + /** + * Prepare a query and returns the statement. + * Save the prepared statement for a later execution with parameters + * @param string $queryString The SQL query string to prepare + * + * @return PDOStatement + */ + public function prepare($queryString) { - $this->execute(); - return $this->stmt->fetch(PDO::FETCH_ASSOC); - } + if (!isset(self::$preparedStmt[$this->dsn][$queryString])) { + self::$preparedStmt[$this->dsn][$queryString] = $this->pdo->prepare($queryString); + } - public function rowCount() - { - return $this->stmt->rowCount(); + return self::$preparedStmt[$this->dsn][$queryString]; } - public function lastInsertId() + /** + * Prepare and execute a query. Returns the prepared and executed statement. + * Statement can be used to fetch resulting rows OR by a later call to a fetch method + * @param string $queryString The SQL query string + * @param array $parameters An indexed or associative array of parameters + * @param bool $catchExceptions Indicates wheter the PDO exceptions must be caught + * + * @return PDOStatement The prepared and executed statement + * + * @throws PDOException If a PDO error occurs during preparation or execution + */ + public function query($queryString, $parameters=null, $catchExceptions=false) { - return $this->dbh->lastInsertId(); - } + try { + $this->stmt = $this->prepare($queryString); - public function beginTransaction() - { - return $this->dbh->beginTransaction(); - } + $executed = $this->stmt->execute($parameters); + } catch (PDOException $PDOException) { + if ($catchExceptions) { + $this->error = $PDOException->getMessage(); - public function endTransaction() - { - return $this->dbh->commit(); - } + return false; + } else { + throw $PDOException; + } + } - public function cancelTransaction() - { - return $this->dbh->rollBack(); + return $this->stmt; } - public function debugDumpParams() - { - return $this->stmt->debugDumpParams(); - } } -- GitLab