Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port Settings DAO to use PDO #539

Merged
merged 4 commits into from
Dec 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion model/dao/BaseDAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

include_once(PHPREPORT_ROOT . '/util/ConfigurationParametersManager.php');
include_once(PHPREPORT_ROOT . '/model/dao/DAOFactory.php');
include_once(PHPREPORT_ROOT . '/util/DatabaseConnectionManager.php');
include_once(PHPREPORT_ROOT . '/util/DBConnectionErrorException.php');
include_once(PHPREPORT_ROOT . '/util/SQLQueryErrorException.php');

Expand All @@ -53,9 +54,23 @@ abstract class BaseDAO {
*/
protected $connect;

/** The connection to DB.
*
* PDO object with an open connection to the database, initialized in the
* class constructor.
*
* @var resource
* @see __construct()
*/
protected PDO $pdo;

/** Base constructor.
*
* This is the base constructor of all simple DAOs, and it just creates the connection with the parameters read from <i>{@link config.php}</i>, storing it in <var>{@link $connect}</var>.
* This is the base constructor of all simple DAOs, and it just creates the
* connection with the parameters read from <i>{@link config.php}</i>,
* storing it in <var>{@link $connect}</var>.
* It also sets up a connection using the PDO API, via
* DatabaseConnectionManager. Eventually, all DAOs should use it.
*
* @see ConfigurationParametersManager, config.php
* @throws {@link ConnectionErrorException}
Expand All @@ -75,6 +90,9 @@ protected function __construct() {
if ($this->connect == NULL) throw new DBConnectionErrorException($connectionString);

pg_set_error_verbosity($this->connect, PGSQL_ERRORS_VERBOSE);

// PDO setup for the DAOs that need it.
$this->pdo = DatabaseConnectionManager::getPDO();
}

/** Value object constructor.
Expand Down
8 changes: 0 additions & 8 deletions model/dao/ConfigDAO/ConfigDAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,6 @@ protected function __construct() {
parent::__construct();
}

/** Get version number.
*
* Get database version number.
*
* @return String a string containing the version number
*/
public abstract function getVersionNumber();

/** Query PhpReport task block configuration.
*
* Check if PhpReport configuration allows writing tasks on the specified
Expand Down
68 changes: 30 additions & 38 deletions model/dao/ConfigDAO/PostgreSQLConfigDAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,6 @@ function __construct() {
parent::__construct();
}

/** Get version number.
*
* Get database version number.
*
* @return String a string containing the version number
*/
public function getVersionNumber() {
$sql = "SELECT version FROM config";

$result = $this->execute($sql);

if (!is_null($result[0])) {
return $result[0];
}
}

/** Query PhpReport task block configuration.
*
* Check if PhpReport configuration allows writing tasks on the specified
Expand Down Expand Up @@ -117,20 +101,19 @@ public function getTaskBlockConfiguration() {
"block_tasks_by_date_enabled,".
"block_tasks_by_date_date ".
"FROM config";
$res = pg_query($this->connect, $sql);
if ($res == NULL) throw new SQLQueryErrorException(pg_last_error());

$config = array();

if(pg_num_rows($res) > 0) {
$config = pg_fetch_array($res);
try {
$statement = $this->pdo->prepare($sql);
$statement->execute();
$config = $statement->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
error_log('Query failed: ' . $e->getMessage());
throw new SQLQueryErrorException($e->getMessage());
}

pg_freeresult($res);

return array(
"dayLimitEnabled" => (strtolower($config["block_tasks_by_day_limit_enabled"]) == "t"),
"dateLimitEnabled" => (strtolower($config["block_tasks_by_date_enabled"]) == "t"),
"dayLimitEnabled" => $config["block_tasks_by_day_limit_enabled"],
"dateLimitEnabled" => $config["block_tasks_by_date_enabled"],
"numberOfDays" => $config["block_tasks_by_day_limit_number_of_days"],
"date" => is_null($config["block_tasks_by_date_date"])? NULL : date_create($config["block_tasks_by_date_date"]));
}
Expand All @@ -152,19 +135,28 @@ public function getTaskBlockConfiguration() {
*/
public function setTaskBlockConfiguration($dayLimitEnabled, $numberOfDays,
$dateLimitEnabled, $date) {
$affectedRows = 0;

$sql = "UPDATE config SET " .
"block_tasks_by_day_limit_enabled = " .
DBPostgres::boolToString($dayLimitEnabled) . "," .
"block_tasks_by_day_limit_number_of_days =" .
DBPostgres::checkNull($numberOfDays) . "," .
"block_tasks_by_date_enabled = " .
DBPostgres::boolToString($dateLimitEnabled) . "," .
"block_tasks_by_date_date = " .
DBPostgres::formatDate($date);

$res = pg_query($this->connect, $sql);

return ($res != NULL);
"block_tasks_by_day_limit_enabled = :dayLimitEnabled, " .
"block_tasks_by_day_limit_number_of_days = :numberOfDays, " .
"block_tasks_by_date_enabled = :dateLimitEnabled, " .
"block_tasks_by_date_date = :date";

try {
$statement = $this->pdo->prepare($sql);
$statement->bindValue(":dayLimitEnabled", $dayLimitEnabled, PDO::PARAM_BOOL);
$statement->bindValue(":numberOfDays", $numberOfDays, PDO::PARAM_INT);
$statement->bindValue(":dateLimitEnabled", $dateLimitEnabled, PDO::PARAM_BOOL);
$statement->bindValue(":date", DBPostgres::formatDate($date), PDO::PARAM_STR);
$statement->execute();

$affectedRows = $statement->rowCount();
} catch (PDOException $e) {
error_log('Query failed: ' . $e->getMessage());
throw new SQLQueryErrorException($e->getMessage());
}
return $affectedRows != 0;
}

}
43 changes: 3 additions & 40 deletions model/dao/TemplateDAO/PostgreSQLTemplateDAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@
* @package PhpReport
* @subpackage DAO
*/
include_once(PHPREPORT_ROOT . '/util/DBPostgres.php');
include_once(PHPREPORT_ROOT . '/model/vo/TemplateVO.php');
include_once(PHPREPORT_ROOT . '/model/dao/TemplateDAO/TemplateDAO.php');
include_once(PHPREPORT_ROOT . '/util/ConfigurationParametersManager.php');

/** DAO for Templates in PostgreSQL
*
Expand All @@ -40,49 +38,14 @@
*/
class PostgreSQLTemplateDAO extends TemplateDAO{

/** The connection to DB.
/** Template DAO constructor.
*
* PDO object with an open connection to the database, initialized in the
* class constructor.
* Default constructor of TemplateDAO, it just calls parent constructor.
*
* @var resource
* @see __construct()
*/
protected PDO $pdo;

/** Template DAO for PostgreSQL constructor.
*
* This is the constructor of the implementation for PostgreSQL of
* {@link TemplateDAO}. It sets up everything for database connection, using
* the parameters read from <i>{@link config.php}</i> and saving the open
* connection in <var>{@link $pdo}</var>.
* Notice this DAO connects to the DB through PDO, unlike the rest of the
* application.
*
* @throws {@link DBConnectionErrorException}
* @see BaseDAO::__construct()
*/
function __construct() {
// Call parent to initialize non-PDO database access, while we don't
// migrate all the methods here.
parent::__construct();

// TODO: EXTRA_DB_CONNECTION_PARAMETERS used to expect pg_connect
// parameters, which were space-separated, but PDO requires semicolons
$connectionString = sprintf("pgsql:host=%s;port=%d;user=%s;dbname=%s;password=%s;%s",
ConfigurationParametersManager::getParameter('DB_HOST'),
ConfigurationParametersManager::getParameter('DB_PORT'),
ConfigurationParametersManager::getParameter('DB_USER'),
ConfigurationParametersManager::getParameter('DB_NAME'),
ConfigurationParametersManager::getParameter('DB_PASSWORD'),
ConfigurationParametersManager::getParameter('EXTRA_DB_CONNECTION_PARAMETERS'));

try {
$this->pdo = new PDO($connectionString);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
error_log('Connection failed: ' . $e->getMessage());
throw new DBConnectionErrorException($connectionString);
}
}

/**
Expand Down
74 changes: 74 additions & 0 deletions util/DatabaseConnectionManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
/*
* Copyright (C) 2021 Igalia, S.L. <[email protected]>
*
* This file is part of PhpReport.
*
* PhpReport 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.
*
* PhpReport 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 PhpReport. If not, see <http://www.gnu.org/licenses/>.
*/

include_once(PHPREPORT_ROOT . '/util/ConfigurationParametersManager.php');

class DatabaseConnectionManager {

/** The connection to DB.
*
* PDO object with an open connection to the database.
*
* @var resource
* @see __construct()
*/
private static PDO $pdo;

/** Setup database connection via PDO.
*
* It sets up everything for database connection via the PDO API, using th
* parameters read from config.php, and saves the open connection in the
* static property $pdo.
*
* @throws {@link DBConnectionErrorException}
*/
private static function setupPDOConnection() {
// TODO: EXTRA_DB_CONNECTION_PARAMETERS used to expect pg_connect
// parameters, which were space-separated, but PDO requires semicolons
$connectionString = sprintf("pgsql:host=%s;port=%d;user=%s;dbname=%s;password=%s;%s",
ConfigurationParametersManager::getParameter('DB_HOST'),
ConfigurationParametersManager::getParameter('DB_PORT'),
ConfigurationParametersManager::getParameter('DB_USER'),
ConfigurationParametersManager::getParameter('DB_NAME'),
ConfigurationParametersManager::getParameter('DB_PASSWORD'),
ConfigurationParametersManager::getParameter('EXTRA_DB_CONNECTION_PARAMETERS'));

try {
self::$pdo = new PDO($connectionString);
self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
error_log('Connection failed: ' . $e->getMessage());
throw new DBConnectionErrorException($connectionString);
}
}

/** Get or create a PDO object for database connection.
*
* Retrieve a PDO object for database connection. The first time this method
* is called, it will create the object, and it will be reused in subsequent
* calls.
*/
public static function getPDO(): PDO {
if (!isset(self::$pdo)) {
self::setupPDOConnection();
}
return self::$pdo;
}
}