Add support, custom, and other queries

This commit is contained in:
2024-06-03 23:10:12 -04:00
parent 98bfceb7c9
commit b705130624
13 changed files with 576 additions and 8 deletions

117
src/Custom.php Normal file
View File

@@ -0,0 +1,117 @@
<?php declare(strict_types=1);
namespace BitBadger\PDODocument;
use BitBadger\PDODocument\Mapper\Mapper;
use PDO;
use PDOStatement;
/**
* Functions to execute custom queries
*/
class Custom
{
/**
* Prepare a query for execution and run it
*
* @param string $query The query to be run
* @param array $parameters The parameters for the query
* @param PDO $pdo The database connection on which the query should be run
* @return PDOStatement The result of executing the query
*/
public static function runQuery(string $query, array $parameters, PDO $pdo): PDOStatement
{
$debug = defined('PDO_DOC_DEBUG_SQL');
$stmt = $pdo->prepare($query);
foreach ($parameters as $key => $value) {
if ($debug) echo "<pre>Binding $value to $key\n</pre>";
$stmt->bindValue($key, $value);
}
if ($debug) echo '<pre>SQL: ' . $stmt->queryString . '</pre>';
$stmt->execute();
return $stmt;
}
/**
* Execute a query that returns a list of results (lazy)
*
* @template TDoc The domain type of the document to retrieve
* @param string $query The query to be executed
* @param array $parameters Parameters to use in executing the query
* @param Mapper<TDoc> $mapper Mapper to deserialize the result
* @return DocumentList<TDoc> The items matching the query
* @throws DocumentException If any is encountered
*/
public static function list(string $query, array $parameters, Mapper $mapper): DocumentList
{
return DocumentList::create($query, $parameters, $mapper);
}
/**
* Execute a query that returns an array of results (eager)
*
* @template TDoc The domain type of the document to retrieve
* @param string $query The query to be executed
* @param array $parameters Parameters to use in executing the query
* @param Mapper<TDoc> $mapper Mapper to deserialize the result
* @return TDoc[] The items matching the query
* @throws DocumentException If any is encountered
*/
public static function array(string $query, array $parameters, Mapper $mapper): array
{
return iterator_to_array(self::list($query, $parameters, $mapper)->items());
}
/**
* Execute a query that returns one or no results (returns false if not found)
*
* @template TDoc The domain type of the document to retrieve
* @param string $query The query to be executed (will have "LIMIT 1" appended)
* @param array $parameters Parameters to use in executing the query
* @param Mapper<TDoc> $mapper Mapper to deserialize the result
* @return false|TDoc The item if it is found, false if not
* @throws DocumentException If any is encountered
*/
public static function single(string $query, array $parameters, Mapper $mapper): mixed
{
return empty($results = self::array("$query LIMIT 1", $parameters, $mapper)) ? false : $results[0];
}
/**
* Execute a query that does not return a value
*
* @param string $query The query to execute
* @param array $parameters Parameters to use in executing the query
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @throws DocumentException If any is encountered
*/
public static function nonQuery(string $query, array $parameters, ?PDO $pdo = null): void
{
$stmt = self::runQuery($query, $parameters, $pdo ?? Configuration::dbConn());
if ($stmt->errorCode()) throw new DocumentException('Error executing command: ' . $stmt->errorCode());
}
/**
* Execute a query that returns a scalar value
*
* @template T The scalar type to return
* @param string $query The query to retrieve the value
* @param array $parameters Parameters to use in executing the query
* @param Mapper<T> $mapper The mapper to obtain the result
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @return mixed|false|T The scalar value if found, false if not
* @throws DocumentException If any is encountered
*/
public static function scalar(string $query, array $parameters, Mapper $mapper, ?PDO $pdo = null): mixed
{
$stmt = self::runQuery($query, $parameters, $pdo ?? Configuration::dbConn());
if ($stmt->errorCode()) {
throw new DocumentException('Error retrieving scalar value: ' . $stmt->errorCode());
}
if ($stmt->rowCount() > 0) {
$first = $stmt->fetch(PDO::FETCH_NUM);
return $first ? $mapper->map($first) : false;
}
return false;
}
}