Skip to content

Commit

Permalink
merging Connection & Explorer classes into one (BC break) [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Aug 29, 2024
1 parent 8426b6c commit 4525881
Show file tree
Hide file tree
Showing 111 changed files with 302 additions and 328 deletions.
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Database Core
To create a new database connection just create a new instance of `Nette\Database\Connection` class:

```php
$database = new Nette\Database\Connection($dsn, $user, $password); // the same arguments as uses PDO
$database = new Nette\Database\Explorer($dsn, $user, $password); // the same arguments as uses PDO
```

Connection allows you to easily query your database by calling `query` method:
Expand Down
26 changes: 9 additions & 17 deletions src/Bridges/DatabaseDI/DatabaseExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,38 +93,30 @@ private function setupDatabase(\stdClass $config, string $name): void
$cacheId = 'Nette.Database.' . hash('xxh128', $name . $config->dsn);
$cache = new Statement(Nette\Caching\Cache::class, [1 => $cacheId]);

$connection = $builder->addDefinition($this->prefix("$name.connection"))
->setFactory(Nette\Database\Connection::class, [$config->dsn, $config->user, $config->password, $config->options])
$explorer = $builder->addDefinition($this->prefix($name))
->setFactory(Nette\Database\Explorer::class, [$config->dsn, $config->user, $config->password, $config->options])
->addSetup('setCache', [$cache])
->setAutowired($config->autowired);

$structure = $builder->addDefinition($this->prefix("$name.structure"))
->setFactory(Nette\Database\Structure::class)
->setArguments([new Statement([$connection, 'getDatabaseEngine']), $cache])
->setAutowired($config->autowired);

if (!$config->conventions) {
$conventions = null;
if (!$config->conventions || $config->conventions === 'discovered') {

} elseif (is_string($config->conventions)) {
$conventions = $builder->addDefinition($this->prefix("$name.conventions"))
->setFactory(preg_match('#^[a-z]+$#Di', $config->conventions)
? 'Nette\Database\Conventions\\' . ucfirst($config->conventions) . 'Conventions'
: $config->conventions)
->setArguments(strtolower($config->conventions) === 'discovered' ? [$structure] : [])
->setAutowired($config->autowired);
$explorer->addSetup('setConventions', [$conventions]);

} else {
$conventions = Nette\DI\Helpers::filterArguments([$config->conventions])[0];
$explorer->addSetup('setConventions', [Nette\DI\Helpers::filterArguments([$config->conventions])[0]]);
}

$builder->addDefinition($this->prefix("$name.explorer"))
->setFactory(Nette\Database\Explorer::class, [$connection, $structure, $conventions, $cache])
->setAutowired($config->autowired);

$builder->addAlias($this->prefix("$name.context"), $this->prefix("$name.explorer"));
$builder->addAlias($this->prefix("$name.connection"), $this->prefix($name));
$builder->addAlias($this->prefix("$name.context"), $this->prefix($name));
$builder->addAlias($this->prefix("$name.explorer"), $this->prefix($name));

if ($this->name === 'database') {
$builder->addAlias($this->prefix($name), $this->prefix("$name.connection"));
$builder->addAlias("nette.database.$name", $this->prefix($name));
$builder->addAlias("nette.database.$name.context", $this->prefix("$name.explorer"));
}
Expand Down
14 changes: 7 additions & 7 deletions src/Bridges/DatabaseTracy/ConnectionPanel.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
namespace Nette\Bridges\DatabaseTracy;

use Nette;
use Nette\Database\Connection;
use Nette\Database\DriverException;
use Nette\Database\Explorer;
use Nette\Database\Helpers;
use Nette\Database\Result;
use Tracy;
Expand All @@ -34,7 +34,7 @@ class ConnectionPanel implements Tracy\IBarPanel


public static function initialize(
Connection $connection,
Explorer $explorer,
bool $addBarPanel = true,
string $name = '',
bool $explain = true,
Expand All @@ -46,7 +46,7 @@ public static function initialize(
$blueScreen->addPanel(self::renderException(...));

if ($addBarPanel) {
$panel = new self($connection, $blueScreen);
$panel = new self($explorer, $blueScreen);
$panel->explain = $explain;
$panel->name = $name;
$bar ??= Tracy\Debugger::getBar();
Expand All @@ -57,14 +57,14 @@ public static function initialize(
}


public function __construct(Connection $connection, Tracy\BlueScreen $blueScreen)
public function __construct(Explorer $explorer, Tracy\BlueScreen $blueScreen)
{
$connection->onQuery[] = $this->logQuery(...);
$explorer->onQuery[] = $this->logQuery(...);
$this->blueScreen = $blueScreen;
}


private function logQuery(Connection $connection, $result): void
private function logQuery(Explorer $connection, $result): void
{
if ($this->disabled) {
return;
Expand All @@ -82,7 +82,7 @@ private function logQuery(Connection $connection, $result): void
&& preg_match('~\.(php.?|phtml)$~', $row['file'])
&& !$this->blueScreen->isCollapsed($row['file']))
&& ($row['class'] ?? '') !== self::class
&& !is_a($row['class'] ?? '', Connection::class, allow_string: true)
&& !is_a($row['class'] ?? '', Explorer::class, allow_string: true)
) {
$source = [$row['file'], (int) $row['line']];
break;
Expand Down
86 changes: 73 additions & 13 deletions src/Database/Connection.php → src/Database/Explorer.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@

use JetBrains\PhpStorm\Language;
use Nette;
use Nette\Caching\Cache;
use Nette\Utils\Arrays;


/**
* Represents a connection between PHP and a database server.
* The central access point to Nette Database functionality.
*/
class Connection
class Explorer
{
/** @var array<callable(self): void> Occurs after connection is established */
public array $onConnect = [];
Expand All @@ -31,22 +32,28 @@ class Connection
private TypeConverter $typeConverter;
private ?SqlLiteral $query = null;
private int $transactionDepth = 0;
private ?Cache $cache = null;
private ?Conventions $conventions = null;
private ?IStructure $structure = null;


public function __construct(
private readonly string $dsn,
?string $user = null,
#[\SensitiveParameter]
?string $password = null,
array $options = [],
Drivers\Driver|string $driver,
) {
$lazy = $options['lazy'] ?? false;
unset($options['lazy']);
if (is_string($driver)) { // compatibility with version 3.x
[$dsn, $user, $password, $options] = func_get_args() + [null, null, null, []];

Factory::configure($this, $options);
$this->driver = Factory::createDriverFromDsn($dsn, $user, $password, $options);
if (!$lazy) {
$this->connect();
$lazy = $options['lazy'] ?? false;
unset($options['lazy']);

Factory::configure($this, $options);
$this->driver = Factory::createDriverFromDsn($dsn, $user, $password, $options);
if (!$lazy) {
$this->connect();
}

} else {
$this->driver = $driver;
}
}

Expand Down Expand Up @@ -346,4 +353,57 @@ public static function literal(string $value, ...$params): SqlLiteral
{
return new SqlLiteral($value, $params);
}


/********************* active row ****************d*g**/


public function table(string $table): Table\Selection
{
return new Table\Selection($this, $table);
}


public function setCache(Cache $cache): static
{
if (isset($this->structure)) {
throw new \LogicException('Cannot set cache after structure is created.');
}
$this->cache = $cache;
return $this;
}


/** @internal */
public function getCache(): ?Cache
{
return $this->cache;
}


public function setConventions(Conventions $conventions): static
{
if (isset($this->conventions)) {
throw new \LogicException('Conventions are already set.');
}
$this->conventions = $conventions;
return $this;
}


/** @internal */
public function getConventions(): Conventions
{
return $this->conventions ??= new Conventions\DiscoveredConventions($this->getStructure());
}


/** @internal */
public function getStructure(): IStructure
{
return $this->structure ??= new Structure($this->getDatabaseEngine(), $this->getCache());
}
}


class_exists(Connection::class);
4 changes: 2 additions & 2 deletions src/Database/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ public static function createDriverFromDsn(


/** @internal */
public static function configure(Connection $connection, array $options): void
public static function configure(Explorer $explorer, array $options): void
{
$converter = $connection->getTypeConverter();
$converter = $explorer->getTypeConverter();
foreach (self::TypeConverterOptions as $opt) {
if (isset($options[$opt])) {
$converter->$opt = (bool) $options[$opt];
Expand Down
18 changes: 9 additions & 9 deletions src/Database/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public static function dumpResult(Result $result): void
/**
* Returns syntax highlighted SQL command.
*/
public static function dumpSql(SqlLiteral $query, ?Connection $connection = null): string
public static function dumpSql(SqlLiteral $query, ?Explorer $explorer = null): string
{
$keywords1 = 'SELECT|(?:ON\s+DUPLICATE\s+KEY)?UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|DELETE|CALL|UNION|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|OFFSET|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN|TRUNCATE';
$keywords2 = 'ALL|DISTINCT|DISTINCTROW|IGNORE|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|[RI]?LIKE|REGEXP|TRUE|FALSE';
Expand Down Expand Up @@ -110,7 +110,7 @@ public static function dumpSql(SqlLiteral $query, ?Connection $connection = null

// parameters
$params = $query->getParameters();
$sql = preg_replace_callback('#\?#', function () use ($params, $connection): string {
$sql = preg_replace_callback('#\?#', function () use ($params, $explorer): string {
static $i = 0;
$param = $params[$i++] ?? null;
if ($param === null) {
Expand All @@ -128,7 +128,7 @@ public static function dumpSql(SqlLiteral $query, ?Connection $connection = null
} elseif (is_string($param)) {
$length = Nette\Utils\Strings::length($param);
$truncated = Nette\Utils\Strings::truncate($param, self::$maxLength);
$text = htmlspecialchars($connection ? $connection->quote($truncated) : '\'' . $truncated . '\'', ENT_NOQUOTES, 'UTF-8');
$text = htmlspecialchars($explorer ? $explorer->quote($truncated) : '\'' . $truncated . '\'', ENT_NOQUOTES, 'UTF-8');
return '<span title="Length ' . $length . ' characters">' . $text . '</span>';

} elseif (is_resource($param)) {
Expand Down Expand Up @@ -157,7 +157,7 @@ public static function dumpSql(SqlLiteral $query, ?Connection $connection = null
* @param ?array<callable(int, ?float): void> $onProgress
* @return int count of commands
*/
public static function loadFromFile(Connection $connection, string $file, ?callable $onProgress = null): int
public static function loadFromFile(Explorer $explorer, string $file, ?callable $onProgress = null): int
{
@set_time_limit(0); // @ function may be disabled

Expand All @@ -170,15 +170,15 @@ public static function loadFromFile(Connection $connection, string $file, ?calla
$count = $size = 0;
$delimiter = ';';
$sql = '';
$driver = $connection->getConnection(); // native query without logging
$connection = $explorer->getConnection(); // native query without logging
while (($s = fgets($handle)) !== false) {
$size += strlen($s);
if (!strncasecmp($s, 'DELIMITER ', 10)) {
$delimiter = trim(substr($s, 10));

} elseif (str_ends_with($ts = rtrim($s), $delimiter)) {
$sql .= substr($ts, 0, -strlen($delimiter));
$driver->query($sql);
$connection->query($sql);
$sql = '';
$count++;
if ($onProgress) {
Expand All @@ -190,7 +190,7 @@ public static function loadFromFile(Connection $connection, string $file, ?calla
}

if (rtrim($sql) !== '') {
$driver->query($sql);
$connection->query($sql);
$count++;
if ($onProgress) {
$onProgress($count, isset($stat['size']) ? 100 : null);
Expand All @@ -204,7 +204,7 @@ public static function loadFromFile(Connection $connection, string $file, ?calla

/** @deprecated use Nette\Bridges\DatabaseTracy\ConnectionPanel::initialize() */
public static function createDebugPanel(
Connection $connection,
Explorer $connection,
bool $explain,
string $name,
Tracy\Bar $bar,
Expand All @@ -218,7 +218,7 @@ public static function createDebugPanel(

/** @deprecated use Nette\Bridges\DatabaseTracy\ConnectionPanel::initialize() */
public static function initializeTracy(
Connection $connection,
Explorer $connection,
bool $addBarPanel = false,
string $name = '',
bool $explain = true,
Expand Down
10 changes: 5 additions & 5 deletions src/Database/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Result implements \Iterator


public function __construct(
private readonly Connection $connection,
private readonly Explorer $explorer,
private readonly SqlLiteral $query,
private readonly ?Drivers\Result $result,
private float $time,
Expand All @@ -36,10 +36,10 @@ public function __construct(


/** @deprecated */
public function getConnection(): Connection
public function getConnection(): Explorer
{
trigger_error(__METHOD__ . '() is deprecated.', E_USER_DEPRECATED);
return $this->connection;
return $this->explorer;
}


Expand Down Expand Up @@ -237,8 +237,8 @@ private function normalizeRow(array $row): array
private function resolveColumnConverters(): array
{
$res = [];
$engine = $this->connection->getDatabaseEngine();
$converter = $this->connection->getTypeConverter();
$engine = $this->explorer->getDatabaseEngine();
$converter = $this->explorer->getTypeConverter();
foreach ($this->result->getColumnsInfo() as $meta) {
$res[$meta['name']] = isset($meta['nativeType'])
? $engine->resolveColumnConverter($meta, $converter)
Expand Down
6 changes: 3 additions & 3 deletions src/Database/SqlPreprocessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ class SqlPreprocessor
private ?string $arrayMode;


public function __construct(Connection $connection)
public function __construct(Explorer $explorer)
{
$this->connection = $connection->getConnection();
$this->engine = $connection->getDatabaseEngine();
$this->connection = $explorer->getConnection();
$this->engine = $explorer->getDatabaseEngine();
}


Expand Down
8 changes: 8 additions & 0 deletions src/compatibility.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,11 @@ class ResultSet extends Result
} elseif (!class_exists(ResultSet::class)) {
class_alias(Result::class, ResultSet::class);
}

if (false) {
class Connection extends Explorer
{
}
} elseif (!class_exists(Connection::class)) {
class_alias(Explorer::class, Connection::class);
}
Loading

0 comments on commit 4525881

Please sign in to comment.