%PDF- %PDF-
| Direktori : /www/varak.net/losik.varak.net/vendor/nette/database/src/Database/ |
| Current File : /www/varak.net/losik.varak.net/vendor/nette/database/src/Database/ResultSet.php |
<?php
/**
* This file is part of the Nette Framework (https://nette.org)
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
*/
declare(strict_types=1);
namespace Nette\Database;
use Nette;
use PDO;
/**
* Represents a result set.
*/
class ResultSet implements \Iterator, IRowContainer
{
use Nette\SmartObject;
/** @var Connection */
private $connection;
/** @var \PDOStatement|null */
private $pdoStatement;
/** @var callable(array, ResultSet): array */
private $normalizer;
/** @var Row|false|null */
private $lastRow;
/** @var int */
private $lastRowKey = -1;
/** @var Row[] */
private $rows;
/** @var float */
private $time;
/** @var string */
private $queryString;
/** @var array */
private $params;
/** @var array */
private $types;
public function __construct(
Connection $connection,
string $queryString,
array $params,
?callable $normalizer = null
) {
$time = microtime(true);
$this->connection = $connection;
$this->queryString = $queryString;
$this->params = $params;
$this->normalizer = $normalizer;
try {
if (substr($queryString, 0, 2) === '::') {
$connection->getPdo()->{substr($queryString, 2)}();
} elseif ($queryString !== null) {
$types = ['boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, 'resource' => PDO::PARAM_LOB, 'NULL' => PDO::PARAM_NULL];
$this->pdoStatement = $connection->getPdo()->prepare($queryString);
foreach ($params as $key => $value) {
$type = gettype($value);
$this->pdoStatement->bindValue(is_int($key) ? $key + 1 : $key, $value, $types[$type] ?? PDO::PARAM_STR);
}
$this->pdoStatement->setFetchMode(PDO::FETCH_ASSOC);
@$this->pdoStatement->execute(); // @ PHP generates warning when ATTR_ERRMODE = ERRMODE_EXCEPTION bug #73878
}
} catch (\PDOException $e) {
$e = $connection->getDriver()->convertException($e);
$e->queryString = $queryString;
$e->params = $params;
throw $e;
}
$this->time = microtime(true) - $time;
}
/** @deprecated */
public function getConnection(): Connection
{
return $this->connection;
}
/**
* @internal
*/
public function getPdoStatement(): ?\PDOStatement
{
return $this->pdoStatement;
}
public function getQueryString(): string
{
return $this->queryString;
}
public function getParameters(): array
{
return $this->params;
}
public function getColumnCount(): ?int
{
return $this->pdoStatement ? $this->pdoStatement->columnCount() : null;
}
public function getRowCount(): ?int
{
return $this->pdoStatement ? $this->pdoStatement->rowCount() : null;
}
public function getColumnTypes(): array
{
if ($this->types === null) {
$this->types = $this->connection->getDriver()->getColumnTypes($this->pdoStatement);
}
return $this->types;
}
public function getTime(): float
{
return $this->time;
}
/** @internal */
public function normalizeRow(array $row): array
{
return $this->normalizer
? ($this->normalizer)($row, $this)
: $row;
}
/********************* misc tools ****************d*g**/
/**
* Displays complete result set as HTML table for debug purposes.
*/
public function dump(): void
{
Helpers::dumpResult($this);
}
/********************* interface Iterator ****************d*g**/
public function rewind(): void
{
if ($this->lastRow === false) {
throw new Nette\InvalidStateException(self::class . ' implements only one way iterator.');
}
}
#[\ReturnTypeWillChange]
public function current()
{
return $this->lastRow;
}
#[\ReturnTypeWillChange]
public function key()
{
return $this->lastRowKey;
}
public function next(): void
{
$this->lastRow = false;
}
public function valid(): bool
{
if ($this->lastRow) {
return true;
}
return $this->fetch() !== null;
}
/**
* Fetches single row object.
*/
public function fetch(): ?Row
{
$data = $this->pdoStatement ? $this->pdoStatement->fetch() : null;
if (!$data) {
$this->pdoStatement->closeCursor();
return null;
} elseif ($this->lastRow === null && count($data) !== $this->pdoStatement->columnCount()) {
$duplicates = Helpers::findDuplicates($this->pdoStatement);
trigger_error("Found duplicate columns in database result set: $duplicates.", E_USER_NOTICE);
}
$row = new Row;
foreach ($this->normalizeRow($data) as $key => $value) {
if ($key !== '') {
$row->$key = $value;
}
}
$this->lastRowKey++;
return $this->lastRow = $row;
}
/**
* Fetches single field.
* @return mixed
*/
public function fetchField($column = 0)
{
if (func_num_args()) {
trigger_error(__METHOD__ . '() argument is deprecated.', E_USER_DEPRECATED);
}
$row = $this->fetch();
return $row ? $row[$column] : null;
}
/**
* Fetches array of fields.
*/
public function fetchFields(): ?array
{
$row = $this->fetch();
return $row ? array_values((array) $row) : null;
}
/**
* Fetches all rows as associative array.
* @param string|int $key column name used for an array key or null for numeric index
* @param string|int $value column name used for an array value or null for the whole row
*/
public function fetchPairs($key = null, $value = null): array
{
return Helpers::toPairs($this->fetchAll(), $key, $value);
}
/**
* Fetches all rows.
* @return Row[]
*/
public function fetchAll(): array
{
if ($this->rows === null) {
$this->rows = iterator_to_array($this);
}
return $this->rows;
}
/**
* Fetches all rows and returns associative tree.
* @param string $path associative descriptor
*/
public function fetchAssoc(string $path): array
{
return Nette\Utils\Arrays::associate($this->fetchAll(), $path);
}
}