Skip to content

Commit

Permalink
[#513] Port Extra Hour DAO to use PDO.
Browse files Browse the repository at this point in the history
Merge pull request #575 from Igalia/pdo-extra-hour
  • Loading branch information
jaragunde authored Apr 19, 2022
2 parents e88429e + 1976c0e commit 0faa34d
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 203 deletions.
23 changes: 0 additions & 23 deletions model/dao/ExtraHourDAO/ExtraHourDAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,6 @@
*/
abstract class ExtraHourDAO extends BaseDAO{

/** Extra Hour DAO constructor.
*
* This is the base constructor of Extra Hour DAOs, and it just calls its parent's constructor.
*
* @throws {@link ConnectionErrorException}
* @see BaseDAO::__construct()
*/
protected function __construct() {
parent::__construct();
}

/** Extra Hour retriever by id.
*
* This function retrieves the row from Extra Hour table with the id <var>$extraHourId</var> and creates an {@link ExtraHourVO} with its data.
Expand All @@ -61,18 +50,6 @@ protected function __construct() {
*/
public abstract function getById($extraHourId);

/** Extra Hours retriever by User id.
*
* This function retrieves the rows from Extra Hour table that are associated with the User with
* the id <var>$userId</var> and creates an {@link ExtraHourVO} with data from each row.
*
* @param int $userId the id of the User whose Extra Hours we want to retrieve.
* @return array an array with value objects {@link ExtraHourVO} with their properties set to the values from the rows
* and ordered ascendantly by their database internal identifier.
* @throws {@link OperationErrorException}
*/
public abstract function getByUserId($userId);

/** Extra Hour last entry retriever by User id and date.
*
* This function retrieves the latest row from Extra Hour table that is associated with the User with
Expand Down
217 changes: 63 additions & 154 deletions model/dao/ExtraHourDAO/PostgreSQLExtraHourDAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,27 +53,6 @@ function __construct() {
parent::__construct();
}

/** Extra Hour value object constructor for PostgreSQL.
*
* This function creates a new {@link ExtraHourVO} with data retrieved from database.
*
* @param array $row an array with the Extra Hour values from a row.
* @return ExtraHourVO an {@link ExtraHourVO} with its properties set to the values from <var>$row</var>.
* @see ExtraHourVO
*/
protected function setValues($row)
{
$extraHourVO = new ExtraHourVO();

$extraHourVO->setId($row['id']);
$extraHourVO->setDate(date_create($row['_date']));
$extraHourVO->setHours($row['hours']);
$extraHourVO->setUserId($row['usrid']);
$extraHourVO->setComment($row['comment']);

return $extraHourVO;
}

/** Extra Hour retriever by id for PostgreSQL.
*
* This function retrieves the row from Extra Hour table with the id <var>$extraHourId</var> and creates an {@link ExtraHourVO} with its data.
Expand All @@ -83,32 +62,11 @@ protected function setValues($row)
* @throws {@link SQLQueryErrorException}
*/
public function getById($extraHourId) {
if (!is_numeric($extraHourId))
throw new SQLIncorrectTypeException($extraHourId);
$sql = "SELECT * FROM extra_hour WHERE id=".$extraHourId;
$result = $this->execute($sql);

if (empty($result))
return NULL;
return $result[0];
}

/** Extra Hours retriever by User id for PostgreSQL.
*
* This function retrieves the rows from Extra Hour table that are associated with the User with
* the id <var>$userId</var> and creates an {@link ExtraHourVO} with data from each row.
*
* @param int $userId the id of the User whose Extra Hours we want to retrieve.
* @return array an array with value objects {@link ExtraHourVO} with their properties set to the values from the rows
* and ordered ascendantly by their database internal identifier.
* @throws {@link SQLQueryErrorException}
*/
public function getByUserId($userId) {
if (!is_numeric($userId))
throw new SQLIncorrectTypeException($userId);
$sql = "SELECT * FROM extra_hour WHERE usrid=" . $userId . " ORDER BY id ASC";
$result = $this->execute($sql);
return $result;
$result = $this->runSelectQuery(
"SELECT * FROM extra_hour WHERE id=:extraHourId",
[':extraHourId' => $extraHourId],
'ExtraHourVO');
return $result[0] ?? NULL;
}

/** Extra Hour last entry retriever by User id and date for PostgreSQL.
Expand All @@ -124,12 +82,13 @@ public function getByUserId($userId) {
public function getLastByUserId($userId, DateTime $nowadays) {
if (!is_numeric($userId))
throw new SQLIncorrectTypeException($userId);
$sql = "SELECT * FROM extra_hour WHERE usrid=" . $userId . " AND _date <=" . DBPostgres::formatDate($nowadays) . " ORDER BY _date DESC LIMIT 1";
$result = $this->execute($sql);

if (empty($result))
return NULL;
return $result[0];
$result = $this->runSelectQuery(
"SELECT * FROM extra_hour " .
"WHERE usrid=:userId AND _date <= :nowadays " .
"ORDER BY _date DESC LIMIT 1",
[':userId' => $userId, ':nowadays' => DBPostgres::formatDate($nowadays)],
'ExtraHourVO');
return $result[0] ?? NULL;
}

/** Extra Hours retriever for PostgreSQL.
Expand All @@ -142,7 +101,7 @@ public function getLastByUserId($userId, DateTime $nowadays) {
*/
public function getAll() {
$sql = "SELECT * FROM extra_hour ORDER BY id ASC";
return $this->execute($sql);
return $this->runSelectQuery($sql, [], 'ExtraHourVO');
}

/** Extra Hour updater for PostgreSQL.
Expand All @@ -154,32 +113,28 @@ public function getAll() {
* @throws {@link SQLQueryErrorException}, {@link SQLUniqueViolationException}
*/
public function update(ExtraHourVO $extraHourVO) {
$affectedRows = 0;

if($extraHourVO->getId() != "") {
$currExtraHourVO = $this->getById($extraHourVO->getId());
}

// If the query returned a row then update
if(sizeof($currExtraHourVO) > 0) {

$sql = "UPDATE extra_hour SET " .
"_date=" .DBPostgres::formatDate($extraHourVO->getDate()) .
", hours=" . DBPostgres::checkNull($extraHourVO->getHours()) .
", usrid=" . DBPostgres::checkNull($extraHourVO->getUserId()) .
", comment=" . DBPostgres::checkStringNull($extraHourVO->getComment()) .
" WHERE id=".$extraHourVO->getId();

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

if ($res == NULL)
if (strpos(pg_last_error(), "unique_extra_hour_user_date"))
throw new SQLUniqueViolationException(pg_last_error());
else throw new SQLQueryErrorException(pg_last_error());
$affectedRows = 0;

$affectedRows = pg_affected_rows($res);
$sql = "UPDATE extra_hour " .
"SET _date=:date, hours=:hours, usrid=:usrid, comment=:comment " .
"WHERE id=:id";
try {
$statement = $this->pdo->prepare($sql);
$statement->bindValue(":date", DBPostgres::formatDate($extraHourVO->getDate()), PDO::PARAM_STR);
$statement->bindValue(":usrid", $extraHourVO->getUserId(), PDO::PARAM_INT);
$statement->bindValue(":comment", $extraHourVO->getComment(), PDO::PARAM_STR);
$statement->bindValue(":id", $extraHourVO->getId(), PDO::PARAM_INT);
// Notice there is no specific parameter for floating point values. A proposal
// existed but did not land: https://wiki.php.net/rfc/pdo_float_type
// The current recommended practice is to use PDO::PARAM_STR.
$statement->bindValue(":hours", $extraHourVO->getHours(), PDO::PARAM_STR);
$statement->execute();

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

return $affectedRows;
}

Expand All @@ -195,25 +150,27 @@ public function update(ExtraHourVO $extraHourVO) {
public function create(ExtraHourVO $extraHourVO) {
$affectedRows = 0;

$sql = "INSERT INTO extra_hour (_date, hours, usrid, comment) VALUES(" .
DBPostgres::formatDate($extraHourVO->getDate()) . ", " .
DBPostgres::checkNull($extraHourVO->getHours()) . "," .
DBPostgres::checkNull($extraHourVO->getUserId()) . "," .
DBPostgres::checkStringNull($extraHourVO->getComment()) . ")";

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

if ($res == NULL)
if (strpos(pg_last_error(), "unique_extra_hour_user_date"))
throw new SQLUniqueViolationException(pg_last_error());
else throw new SQLQueryErrorException(pg_last_error());

$extraHourVO->setId(DBPostgres::getId($this->connect, "extra_hour_id_seq"));

$affectedRows = pg_affected_rows($res);

$sql = "INSERT INTO extra_hour (_date, hours, usrid, comment) " .
"VALUES (:date, :hours, :usrid, :comment)";
try {
$statement = $this->pdo->prepare($sql);
$statement->bindValue(":date", DBPostgres::formatDate($extraHourVO->getDate()), PDO::PARAM_STR);
$statement->bindValue(":usrid", $extraHourVO->getUserId(), PDO::PARAM_INT);
$statement->bindValue(":comment", $extraHourVO->getComment(), PDO::PARAM_STR);
// Notice there is no specific parameter for floating point values. A proposal
// existed but did not land: https://wiki.php.net/rfc/pdo_float_type
// The current recommended practice is to use PDO::PARAM_STR.
$statement->bindValue(":hours", $extraHourVO->getHours(), PDO::PARAM_STR);
$statement->execute();

$extraHourVO->setId($this->pdo->lastInsertId('extra_hour_id_seq'));

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

}

/** Extra Hour deleter for PostgreSQL.
Expand All @@ -227,65 +184,17 @@ public function create(ExtraHourVO $extraHourVO) {
public function delete(ExtraHourVO $extraHourVO) {
$affectedRows = 0;

// Check for a user ID.
if($extraHourVO->getId() >= 0) {
$currExtraHourVO = $this->getById($extraHourVO->getId());
}

// Otherwise delete a user.
if(sizeof($currExtraHourVO) > 0) {
$sql = "DELETE FROM extra_hour WHERE id=".$extraHourVO->getId();

$res = pg_query($this->connect, $sql);
if ($res == NULL) throw new SQLQueryErrorException(pg_last_error());
$affectedRows = pg_affected_rows($res);
}
$sql = "DELETE FROM extra_hour WHERE id=:id";
try {
$statement = $this->pdo->prepare($sql);
$statement->bindValue(":id", $extraHourVO->getId(), PDO::PARAM_INT);
$statement->execute();

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




/*//Uncomment these lines in order to do a simple test of the Dao
$dao = new PostgreSQLExtraHourDAO();
// We create a new extra hour
$extraHour = new ExtraHourVO();
$extraHour->setDate(date_create('2005-12-21'));
$extraHour->setHours(3);
$extraHour->setUserId(1);
$dao->create($extraHour);
print ("New extra hour Id is ". $extraHour->getId() ."\n");
// We search for the new Id
$extraHour = $dao->getById($extraHour->getId());
print ("New extra hour Id found is ". $extraHour->getId() ."\n");
print ("New extra hour Date found is ". DBPostgres::formatDate($extraHour->getDate()) ."\n");
// We update the extra hour with a differente number of hours
$extraHour->setHours(5);
$dao->update($extraHour);
// We search for the new value of hours
$extraHour = $dao->getById($extraHour->getId());
print ("New extra hour hours value found is ". $extraHour->getHours() ."\n");
// We delete the new extra hour
$dao->delete($extraHour);*/
41 changes: 31 additions & 10 deletions model/vo/ExtraHourVO.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,25 @@
*
* This class just stores Extra Hour data.
*
* NOTICE: properties must match column names in the DB, for PDO::FETCH_CLASS
* to work properly.
*
* @property int $id database internal identifier.
* @property int $userId database internal identifier of the associated User.
* @property int $usrid database internal identifier of the associated User.
* @property DateTime $date date of the Extra Hour.
* @property double $hours number of extra hours.
*/
class ExtraHourVO {
protected $id = NULL;
protected $userId = NULL;
protected $usrid = NULL;
protected $date = NULL;
protected $hours = NULL;
protected $comment = NULL;

public function setId($id) {
if (is_null($id))
$this->id = $id;
else
$this->id = $id;
else
$this->id = (int) $id;
}

Expand All @@ -58,13 +61,13 @@ public function getId() {

public function setUserId($userId) {
if (is_null($userId))
$this->userId = $userId;
else
$this->userId = (int) $userId;
$this->usrid = $userId;
else
$this->usrid = (int) $userId;
}

public function getUserId() {
return $this->userId;
return $this->usrid;
}

public function setDate(DateTime $date = NULL) {
Expand All @@ -77,8 +80,8 @@ public function getDate() {

public function setHours($hours) {
if (is_null($hours))
$this->hours = $hours;
else
$this->hours = $hours;
else
$this->hours = (double) $hours;
}

Expand All @@ -93,4 +96,22 @@ public function setComment($comment) {
public function getComment() {
return $this->comment;
}

/* PHP will magically call this function to set the value of a property that
* does not exist yet. We can take advantage of this to properly set the
* $date property from the string stored in the DB during PDO::FETCH_CLASS.
* When PDO::FETCH_CLASS calls `__set('_date', $dateString)`, we will
* convert the string into a DateTime object.
*
* See:
* https://www.php.net/manual/en/language.oop5.overloading.php#object.set
* https://stackoverflow.com/a/69641430
*/
public function __set($property, $value) {
if ($property === '_date') {
$this->date = date_create($value);
} else {
$this->$property = $value;
}
}
}
1 change: 0 additions & 1 deletion web/hourCompensationManagement.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
define('PHPREPORT_ROOT', __DIR__ . '/../');

/* We check authentication and authorization */
$sid = $_GET["sid"];
require_once(PHPREPORT_ROOT . '/web/auth.php');

/* Include the generic header and sidebar */
Expand Down
Loading

0 comments on commit 0faa34d

Please sign in to comment.