src/Zephyrus/Database/DatabaseBroker.php
<?php namespace Zephyrus\Database;
use stdClass;
use Zephyrus\Database\Core\Database;
use Zephyrus\Database\Core\DatabaseStatement;
abstract class DatabaseBroker
{
private Database $database;
private ?DatabaseStatement $lastStatement = null;
/**
* Broker constructor called by children. Simply get the database reference for further use by queries. If no
* database is given, the registered database instance in DatabaseSession will be used.
*
* @param null|Database $database
*/
public function __construct(?Database $database = null)
{
$this->database = $database ?? DatabaseSession::getInstance()->getDatabase();
}
/**
* Fetches the value associated with the given session variable's name. Returns NULL if not found (instead of an
* exception).
*
* @param string $name
* @return mixed
*/
public function findSessionVariable(string $name): mixed
{
return $this->selectSingle("SELECT current_setting(?, true) as var", [$name])->var;
}
/**
* Retrieves the current database instance used for this broker.
*
* @return Database
*/
public function getDatabase(): Database
{
return $this->database;
}
public function getLastAffectedCount(): int
{
return $this->lastStatement?->count() ?? 0;
}
public function getLastStatement(): ?DatabaseStatement
{
return $this->lastStatement;
}
/**
* Executes any type of query and simply returns the DatabaseStatement object ready to be fetched. Will throw a
* DatabaseException (silent as a RuntimeException) is the query fails to execute.
*
* @param string $query
* @param array $parameters
* @return DatabaseStatement
*/
protected function rawQuery(string $query, array $parameters = []): DatabaseStatement
{
$this->lastStatement = $this->prepareStatement($query, $parameters);
return $this->lastStatement;
}
/**
* Executes any type of query and returns the first returned element is any (useful for INSERT type query with a
* RETURNING directive). Will throw a DatabaseException (silent as a RuntimeException) is the query fails to
* execute.
*
* @param string $query
* @param array $parameters
* @return null|stdClass
*/
protected function query(string $query, array $parameters = []): ?stdClass
{
$this->lastStatement = $this->prepareStatement($query, $parameters);
return $this->lastStatement->next();
}
/**
* Executes a SELECT query which should return a single data row. Best suited for queries involving primary key in
* where. Will return null if the query did not fetch any result. Will throw a DatabaseException (silent as a
* RuntimeException) is the query fails to execute.
*
* @param string $query
* @param array $parameters
* @return stdClass|null
*/
protected function selectSingle(string $query, array $parameters = []): ?stdClass
{
$this->lastStatement = $this->prepareStatement($query, $parameters);
return $this->lastStatement->next();
}
/**
* Execute a SELECT query which return the entire set of rows in an array. Will return an empty array if the query
* did not return any results. Will throw a DatabaseException (silent as a RuntimeException) is the query fails to
* execute.
*
* @param string $query
* @param array $parameters
* @param callable|null $callback
* @return stdClass[]
*/
protected function select(string $query, array $parameters = [], ?callable $callback = null): array
{
$this->lastStatement = $this->prepareStatement($query, $parameters);
$result = new SqlResult($this->lastStatement);
return $result->toArray($callback);
}
/**
* Proceeds to include the given variable into the database environnement so that the executed queries, triggers or
* stored procedures could have access to the variable. Useful for example to pass a user id to register for
* automated log triggers.
*
* @param string $name
* @param string $value
*/
protected function addSessionVariable(string $name, string $value)
{
$this->database->addSessionVariable($name, $value);
}
private function prepareStatement(string $query, array $parameters = []): DatabaseStatement
{
// TODO: Sanitize input
$statement = $this->database->query($query, $parameters); // TODO: Database exceptions should be runtime?
//if (!is_null($this->sanitizeCallback)) {
// $statement->setSanitizeCallback($this->sanitizeCallback);
//}
return $statement;
}
}