Skip to content

Commit 0084e73

Browse files
committed
merging Connection & Explorer classes into one (BC break)
1 parent 8426b6c commit 0084e73

111 files changed

Lines changed: 302 additions & 328 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ Database Core
5959
To create a new database connection just create a new instance of `Nette\Database\Connection` class:
6060

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

6565
Connection allows you to easily query your database by calling `query` method:

src/Bridges/DatabaseDI/DatabaseExtension.php

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -93,38 +93,30 @@ private function setupDatabase(\stdClass $config, string $name): void
9393
$cacheId = 'Nette.Database.' . hash('xxh128', $name . $config->dsn);
9494
$cache = new Statement(Nette\Caching\Cache::class, [1 => $cacheId]);
9595

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

100-
$structure = $builder->addDefinition($this->prefix("$name.structure"))
101-
->setFactory(Nette\Database\Structure::class)
102-
->setArguments([new Statement([$connection, 'getDatabaseEngine']), $cache])
103-
->setAutowired($config->autowired);
104-
105-
if (!$config->conventions) {
106-
$conventions = null;
101+
if (!$config->conventions || $config->conventions === 'discovered') {
107102

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

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

120-
$builder->addDefinition($this->prefix("$name.explorer"))
121-
->setFactory(Nette\Database\Explorer::class, [$connection, $structure, $conventions, $cache])
122-
->setAutowired($config->autowired);
123-
124-
$builder->addAlias($this->prefix("$name.context"), $this->prefix("$name.explorer"));
115+
$builder->addAlias($this->prefix("$name.connection"), $this->prefix($name));
116+
$builder->addAlias($this->prefix("$name.context"), $this->prefix($name));
117+
$builder->addAlias($this->prefix("$name.explorer"), $this->prefix($name));
125118

126119
if ($this->name === 'database') {
127-
$builder->addAlias($this->prefix($name), $this->prefix("$name.connection"));
128120
$builder->addAlias("nette.database.$name", $this->prefix($name));
129121
$builder->addAlias("nette.database.$name.context", $this->prefix("$name.explorer"));
130122
}

src/Bridges/DatabaseTracy/ConnectionPanel.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
namespace Nette\Bridges\DatabaseTracy;
1111

1212
use Nette;
13-
use Nette\Database\Connection;
1413
use Nette\Database\DriverException;
14+
use Nette\Database\Explorer;
1515
use Nette\Database\Helpers;
1616
use Nette\Database\Result;
1717
use Tracy;
@@ -34,7 +34,7 @@ class ConnectionPanel implements Tracy\IBarPanel
3434

3535

3636
public static function initialize(
37-
Connection $connection,
37+
Explorer $explorer,
3838
bool $addBarPanel = true,
3939
string $name = '',
4040
bool $explain = true,
@@ -46,7 +46,7 @@ public static function initialize(
4646
$blueScreen->addPanel(self::renderException(...));
4747

4848
if ($addBarPanel) {
49-
$panel = new self($connection, $blueScreen);
49+
$panel = new self($explorer, $blueScreen);
5050
$panel->explain = $explain;
5151
$panel->name = $name;
5252
$bar ??= Tracy\Debugger::getBar();
@@ -57,14 +57,14 @@ public static function initialize(
5757
}
5858

5959

60-
public function __construct(Connection $connection, Tracy\BlueScreen $blueScreen)
60+
public function __construct(Explorer $explorer, Tracy\BlueScreen $blueScreen)
6161
{
62-
$connection->onQuery[] = $this->logQuery(...);
62+
$explorer->onQuery[] = $this->logQuery(...);
6363
$this->blueScreen = $blueScreen;
6464
}
6565

6666

67-
private function logQuery(Connection $connection, $result): void
67+
private function logQuery(Explorer $connection, $result): void
6868
{
6969
if ($this->disabled) {
7070
return;
@@ -82,7 +82,7 @@ private function logQuery(Connection $connection, $result): void
8282
&& preg_match('~\.(php.?|phtml)$~', $row['file'])
8383
&& !$this->blueScreen->isCollapsed($row['file']))
8484
&& ($row['class'] ?? '') !== self::class
85-
&& !is_a($row['class'] ?? '', Connection::class, allow_string: true)
85+
&& !is_a($row['class'] ?? '', Explorer::class, allow_string: true)
8686
) {
8787
$source = [$row['file'], (int) $row['line']];
8888
break;
Lines changed: 73 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@
1111

1212
use JetBrains\PhpStorm\Language;
1313
use Nette;
14+
use Nette\Caching\Cache;
1415
use Nette\Utils\Arrays;
1516

1617

1718
/**
18-
* Represents a connection between PHP and a database server.
19+
* The central access point to Nette Database functionality.
1920
*/
20-
class Connection
21+
class Explorer
2122
{
2223
/** @var array<callable(self): void> Occurs after connection is established */
2324
public array $onConnect = [];
@@ -31,22 +32,28 @@ class Connection
3132
private TypeConverter $typeConverter;
3233
private ?SqlLiteral $query = null;
3334
private int $transactionDepth = 0;
35+
private ?Cache $cache = null;
36+
private ?Conventions $conventions = null;
37+
private ?IStructure $structure = null;
3438

3539

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

46-
Factory::configure($this, $options);
47-
$this->driver = Factory::createDriverFromDsn($dsn, $user, $password, $options);
48-
if (!$lazy) {
49-
$this->connect();
46+
$lazy = $options['lazy'] ?? false;
47+
unset($options['lazy']);
48+
49+
Factory::configure($this, $options);
50+
$this->driver = Factory::createDriverFromDsn($dsn, $user, $password, $options);
51+
if (!$lazy) {
52+
$this->connect();
53+
}
54+
55+
} else {
56+
$this->driver = $driver;
5057
}
5158
}
5259

@@ -346,4 +353,57 @@ public static function literal(string $value, ...$params): SqlLiteral
346353
{
347354
return new SqlLiteral($value, $params);
348355
}
356+
357+
358+
/********************* active row ****************d*g**/
359+
360+
361+
public function table(string $table): Table\Selection
362+
{
363+
return new Table\Selection($this, $table);
364+
}
365+
366+
367+
public function setCache(Cache $cache): static
368+
{
369+
if (isset($this->structure)) {
370+
throw new \LogicException('Cannot set cache after structure is created.');
371+
}
372+
$this->cache = $cache;
373+
return $this;
374+
}
375+
376+
377+
/** @internal */
378+
public function getCache(): ?Cache
379+
{
380+
return $this->cache;
381+
}
382+
383+
384+
public function setConventions(Conventions $conventions): static
385+
{
386+
if (isset($this->conventions)) {
387+
throw new \LogicException('Conventions are already set.');
388+
}
389+
$this->conventions = $conventions;
390+
return $this;
391+
}
392+
393+
394+
/** @internal */
395+
public function getConventions(): Conventions
396+
{
397+
return $this->conventions ??= new Conventions\DiscoveredConventions($this->getStructure());
398+
}
399+
400+
401+
/** @internal */
402+
public function getStructure(): IStructure
403+
{
404+
return $this->structure ??= new Structure($this->getDatabaseEngine(), $this->getCache());
405+
}
349406
}
407+
408+
409+
class_exists(Connection::class);

src/Database/Factory.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ public static function createDriverFromDsn(
5555

5656

5757
/** @internal */
58-
public static function configure(Connection $connection, array $options): void
58+
public static function configure(Explorer $explorer, array $options): void
5959
{
60-
$converter = $connection->getTypeConverter();
60+
$converter = $explorer->getTypeConverter();
6161
foreach (self::TypeConverterOptions as $opt) {
6262
if (isset($options[$opt])) {
6363
$converter->$opt = (bool) $options[$opt];

src/Database/Helpers.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public static function dumpResult(Result $result): void
7575
/**
7676
* Returns syntax highlighted SQL command.
7777
*/
78-
public static function dumpSql(SqlLiteral $query, ?Connection $connection = null): string
78+
public static function dumpSql(SqlLiteral $query, ?Explorer $explorer = null): string
7979
{
8080
$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';
8181
$keywords2 = 'ALL|DISTINCT|DISTINCTROW|IGNORE|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|[RI]?LIKE|REGEXP|TRUE|FALSE';
@@ -110,7 +110,7 @@ public static function dumpSql(SqlLiteral $query, ?Connection $connection = null
110110

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

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

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

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

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

205205
/** @deprecated use Nette\Bridges\DatabaseTracy\ConnectionPanel::initialize() */
206206
public static function createDebugPanel(
207-
Connection $connection,
207+
Explorer $connection,
208208
bool $explain,
209209
string $name,
210210
Tracy\Bar $bar,
@@ -218,7 +218,7 @@ public static function createDebugPanel(
218218

219219
/** @deprecated use Nette\Bridges\DatabaseTracy\ConnectionPanel::initialize() */
220220
public static function initializeTracy(
221-
Connection $connection,
221+
Explorer $connection,
222222
bool $addBarPanel = false,
223223
string $name = '',
224224
bool $explain = true,

src/Database/Result.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class Result implements \Iterator
2727

2828

2929
public function __construct(
30-
private readonly Connection $connection,
30+
private readonly Explorer $explorer,
3131
private readonly SqlLiteral $query,
3232
private readonly ?Drivers\Result $result,
3333
private float $time,
@@ -36,10 +36,10 @@ public function __construct(
3636

3737

3838
/** @deprecated */
39-
public function getConnection(): Connection
39+
public function getConnection(): Explorer
4040
{
4141
trigger_error(__METHOD__ . '() is deprecated.', E_USER_DEPRECATED);
42-
return $this->connection;
42+
return $this->explorer;
4343
}
4444

4545

@@ -237,8 +237,8 @@ private function normalizeRow(array $row): array
237237
private function resolveColumnConverters(): array
238238
{
239239
$res = [];
240-
$engine = $this->connection->getDatabaseEngine();
241-
$converter = $this->connection->getTypeConverter();
240+
$engine = $this->explorer->getDatabaseEngine();
241+
$converter = $this->explorer->getTypeConverter();
242242
foreach ($this->result->getColumnsInfo() as $meta) {
243243
$res[$meta['name']] = isset($meta['nativeType'])
244244
? $engine->resolveColumnConverter($meta, $converter)

src/Database/SqlPreprocessor.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ class SqlPreprocessor
5959
private ?string $arrayMode;
6060

6161

62-
public function __construct(Connection $connection)
62+
public function __construct(Explorer $explorer)
6363
{
64-
$this->connection = $connection->getConnection();
65-
$this->engine = $connection->getDatabaseEngine();
64+
$this->connection = $explorer->getConnection();
65+
$this->engine = $explorer->getDatabaseEngine();
6666
}
6767

6868

src/compatibility.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,11 @@ class ResultSet extends Result
2626
} elseif (!class_exists(ResultSet::class)) {
2727
class_alias(Result::class, ResultSet::class);
2828
}
29+
30+
if (false) {
31+
class Connection extends Explorer
32+
{
33+
}
34+
} elseif (!class_exists(Connection::class)) {
35+
class_alias(Explorer::class, Connection::class);
36+
}

0 commit comments

Comments
 (0)