%PDF- %PDF-
| Direktori : /www/varak.net/losik.varak.net/vendor/dibi/dibi/src/Dibi/ |
| Current File : /www/varak.net/losik.varak.net/vendor/dibi/dibi/src/Dibi/DataSource.php |
<?php
/**
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
declare(strict_types=1);
namespace Dibi;
/**
* Default implementation of IDataSource.
*/
class DataSource implements IDataSource
{
use Strict;
/** @var Connection */
private $connection;
/** @var string */
private $sql;
/** @var Result|null */
private $result;
/** @var int|null */
private $count;
/** @var int|null */
private $totalCount;
/** @var array */
private $cols = [];
/** @var array */
private $sorting = [];
/** @var array */
private $conds = [];
/** @var int|null */
private $offset;
/** @var int|null */
private $limit;
/**
* @param string $sql command or table or view name, as data source
*/
public function __construct(string $sql, Connection $connection)
{
$this->sql = strpbrk($sql, " \t\r\n") === false
? $connection->getDriver()->escapeIdentifier($sql) // table name
: '(' . $sql . ') t'; // SQL command
$this->connection = $connection;
}
/**
* Selects columns to query.
* @param string|array $col column name or array of column names
* @param string $as column alias
*/
public function select($col, ?string $as = null): self
{
if (is_array($col)) {
$this->cols = $col;
} else {
$this->cols[$col] = $as;
}
$this->result = null;
return $this;
}
/**
* Adds conditions to query.
*/
public function where($cond): self
{
$this->conds[] = is_array($cond)
? $cond // TODO: not consistent with select and orderBy
: func_get_args();
$this->result = $this->count = null;
return $this;
}
/**
* Selects columns to order by.
* @param string|array $row column name or array of column names
*/
public function orderBy($row, string $direction = 'ASC'): self
{
if (is_array($row)) {
$this->sorting = $row;
} else {
$this->sorting[$row] = $direction;
}
$this->result = null;
return $this;
}
/**
* Limits number of rows.
*/
public function applyLimit(int $limit, ?int $offset = null): self
{
$this->limit = $limit;
$this->offset = $offset;
$this->result = $this->count = null;
return $this;
}
final public function getConnection(): Connection
{
return $this->connection;
}
/********************* executing ****************d*g**/
/**
* Returns (and queries) Result.
*/
public function getResult(): Result
{
if ($this->result === null) {
$this->result = $this->connection->nativeQuery($this->__toString());
}
return $this->result;
}
public function getIterator(): ResultIterator
{
return $this->getResult()->getIterator();
}
/**
* Generates, executes SQL query and fetches the single row.
*/
public function fetch(): ?Row
{
return $this->getResult()->fetch();
}
/**
* Like fetch(), but returns only first field.
* @return mixed value on success, null if no next record
*/
public function fetchSingle()
{
return $this->getResult()->fetchSingle();
}
/**
* Fetches all records from table.
*/
public function fetchAll(): array
{
return $this->getResult()->fetchAll();
}
/**
* Fetches all records from table and returns associative tree.
*/
public function fetchAssoc(string $assoc): array
{
return $this->getResult()->fetchAssoc($assoc);
}
/**
* Fetches all records from table like $key => $value pairs.
*/
public function fetchPairs(?string $key = null, ?string $value = null): array
{
return $this->getResult()->fetchPairs($key, $value);
}
/**
* Discards the internal cache.
*/
public function release(): void
{
$this->result = $this->count = $this->totalCount = null;
}
/********************* exporting ****************d*g**/
/**
* Returns this data source wrapped in Fluent object.
*/
public function toFluent(): Fluent
{
return $this->connection->select('*')->from('(%SQL) t', $this->__toString());
}
/**
* Returns this data source wrapped in DataSource object.
*/
public function toDataSource(): self
{
return new self($this->__toString(), $this->connection);
}
/**
* Returns SQL query.
*/
public function __toString(): string
{
try {
return $this->connection->translate(
"\nSELECT %n",
(empty($this->cols) ? '*' : $this->cols),
"\nFROM %SQL",
$this->sql,
"\n%ex",
$this->conds ? ['WHERE %and', $this->conds] : null,
"\n%ex",
$this->sorting ? ['ORDER BY %by', $this->sorting] : null,
"\n%ofs %lmt",
$this->offset,
$this->limit
);
} catch (\Throwable $e) {
trigger_error($e->getMessage(), E_USER_ERROR);
return '';
}
}
/********************* counting ****************d*g**/
/**
* Returns the number of rows in a given data source.
*/
public function count(): int
{
if ($this->count === null) {
$this->count = $this->conds || $this->offset || $this->limit
? Helpers::intVal($this->connection->nativeQuery(
'SELECT COUNT(*) FROM (' . $this->__toString() . ') t'
)->fetchSingle())
: $this->getTotalCount();
}
return $this->count;
}
/**
* Returns the number of rows in a given data source.
*/
public function getTotalCount(): int
{
if ($this->totalCount === null) {
$this->totalCount = Helpers::intVal($this->connection->nativeQuery(
'SELECT COUNT(*) FROM ' . $this->sql
)->fetchSingle());
}
return $this->totalCount;
}
}