Skip to content

Commit a0ba636

Browse files
committed
Explorer, Selection, Structure: change of constructor dependencies (BC break)
1 parent 544a1ea commit a0ba636

File tree

11 files changed

+57
-74
lines changed

11 files changed

+57
-74
lines changed

src/Bridges/DatabaseDI/DatabaseExtension.php

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

1212
use Nette;
13+
use Nette\DI\Definitions\Statement;
1314
use Nette\Schema\Expect;
1415
use Tracy;
1516
use function is_array, is_string;
@@ -95,13 +96,16 @@ private function setupDatabase(\stdClass $config, string $name): void
9596
}
9697
}
9798

99+
$cacheId = 'Nette.Database.' . hash('xxh128', $name . $config->dsn);
100+
$cache = new Statement(Nette\Caching\Cache::class, [1 => $cacheId]);
101+
98102
$connection = $builder->addDefinition($this->prefix("$name.connection"))
99103
->setFactory(Nette\Database\Connection::class, [$config->dsn, $config->user, $config->password, $config->options])
100104
->setAutowired($config->autowired);
101105

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

107111
if (!$config->conventions) {
@@ -120,7 +124,7 @@ private function setupDatabase(\stdClass $config, string $name): void
120124
}
121125

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

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

src/Database/Explorer.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function __construct(
2727
private readonly Connection $connection,
2828
private readonly IStructure $structure,
2929
?Conventions $conventions = null,
30-
private readonly ?Nette\Caching\Storage $cacheStorage = null,
30+
private readonly ?Nette\Caching\Cache $cache = null,
3131
) {
3232
$this->conventions = $conventions ?: new StaticConventions;
3333
}
@@ -87,7 +87,7 @@ public function queryArgs(string $sql, array $params): Result
8787
*/
8888
public function table(string $table): Table\Selection
8989
{
90-
return new Table\Selection($this, $this->conventions, $table, $this->cacheStorage);
90+
return new Table\Selection($this, $table);
9191
}
9292

9393

@@ -128,7 +128,13 @@ public function createGroupedSelection(
128128
string $column,
129129
): Table\GroupedSelection
130130
{
131-
return new Table\GroupedSelection($this, $this->conventions, $table, $column, $refSelection, $this->cacheStorage);
131+
return new Table\GroupedSelection($this, $table, $column, $refSelection);
132+
}
133+
134+
135+
public function getCache(): ?Nette\Caching\Cache
136+
{
137+
return $this->cache;
132138
}
133139

134140

src/Database/Structure.php

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,15 @@
1818
*/
1919
class Structure implements IStructure
2020
{
21-
protected readonly Connection $connection;
22-
protected readonly Nette\Caching\Cache $cache;
23-
2421
/** @var array{tables: array, columns: array, primary: array, aliases: array, hasMany: array, belongsTo: array} */
2522
protected array $structure;
2623
protected bool $isRebuilt = false;
2724

2825

29-
public function __construct(Connection $connection, Nette\Caching\Storage $cacheStorage)
30-
{
31-
$this->connection = $connection;
32-
$this->cache = new Nette\Caching\Cache($cacheStorage, 'Nette.Database.Structure.' . hash('xxh128', $connection->getDsn()));
26+
public function __construct(
27+
protected readonly Drivers\Engine $engine,
28+
protected readonly Nette\Caching\Cache $cache,
29+
) {
3330
}
3431

3532

@@ -95,7 +92,7 @@ public function getPrimaryKeySequence(string $table): ?string
9592
$this->needStructure();
9693
$table = $this->resolveFQTableName($table);
9794

98-
if (!$this->connection->getDatabaseEngine()->isSupported(Drivers\Engine::SupportSequence)) {
95+
if (!$this->engine->isSupported(Drivers\Engine::SupportSequence)) {
9996
return null;
10097
}
10198

@@ -162,10 +159,8 @@ protected function needStructure(): void
162159
*/
163160
protected function loadStructure(): array
164161
{
165-
$engine = $this->connection->getDatabaseEngine();
166-
167162
$structure = [];
168-
$structure['tables'] = $engine->getTables();
163+
$structure['tables'] = $this->engine->getTables();
169164

170165
foreach ($structure['tables'] as $tablePair) {
171166
if (isset($tablePair['fullName'])) {
@@ -175,7 +170,7 @@ protected function loadStructure(): array
175170
$table = $tablePair['name'];
176171
}
177172

178-
$structure['columns'][strtolower($table)] = $columns = $engine->getColumns($table);
173+
$structure['columns'][strtolower($table)] = $columns = $this->engine->getColumns($table);
179174

180175
if (!$tablePair['view']) {
181176
$structure['primary'][strtolower($table)] = $this->analyzePrimaryKey($columns);
@@ -218,7 +213,7 @@ protected function analyzeForeignKeys(array &$structure, string $table): void
218213
{
219214
$lowerTable = strtolower($table);
220215

221-
$foreignKeys = $this->connection->getDatabaseEngine()->getForeignKeys($table);
216+
$foreignKeys = $this->engine->getForeignKeys($table);
222217

223218
usort($foreignKeys, fn($a, $b): int => count($b['local']) <=> count($a['local']));
224219

src/Database/Table/GroupedSelection.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
namespace Nette\Database\Table;
1111

1212
use Nette;
13-
use Nette\Database\Conventions;
1413
use Nette\Database\Explorer;
1514
use function array_keys, count, iterator_to_array, preg_match, reset;
1615

@@ -39,15 +38,13 @@ class GroupedSelection extends Selection
3938
*/
4039
public function __construct(
4140
Explorer $explorer,
42-
Conventions $conventions,
4341
string $tableName,
4442
string $column,
4543
Selection $refTable,
46-
?Nette\Caching\Storage $cacheStorage = null,
4744
) {
4845
$this->refTable = $refTable;
4946
$this->column = $column;
50-
parent::__construct($explorer, $conventions, $tableName, $cacheStorage);
47+
parent::__construct($explorer, $tableName);
5148
}
5249

5350

src/Database/Table/Selection.php

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
namespace Nette\Database\Table;
1111

1212
use Nette;
13-
use Nette\Database\Conventions;
1413
use Nette\Database\Explorer;
1514
use function array_filter, array_intersect_key, array_keys, array_map, array_merge, array_values, ceil, count, current, explode, func_num_args, hash, implode, is_array, is_int, iterator_to_array, key, next, reset, serialize, str_contains, substr_count;
1615

@@ -25,10 +24,6 @@
2524
class Selection implements \Iterator, \ArrayAccess, \Countable
2625
{
2726
protected readonly Explorer $explorer;
28-
29-
/** back compatibility */
30-
protected Explorer $context;
31-
protected readonly Conventions $conventions;
3227
protected readonly ?Nette\Caching\Cache $cache;
3328
protected SqlBuilder $sqlBuilder;
3429

@@ -73,18 +68,12 @@ class Selection implements \Iterator, \ArrayAccess, \Countable
7368
*/
7469
public function __construct(
7570
Explorer $explorer,
76-
Conventions $conventions,
7771
string $tableName,
78-
?Nette\Caching\Storage $cacheStorage = null,
7972
) {
80-
$this->explorer = $this->context = $explorer;
81-
$this->conventions = $conventions;
73+
$this->explorer = $explorer;
8274
$this->name = $tableName;
83-
84-
$this->cache = $cacheStorage
85-
? new Nette\Caching\Cache($cacheStorage, 'Nette.Database.' . hash('xxh128', $explorer->getConnection()->getDsn()))
86-
: null;
87-
$this->primary = $conventions->getPrimary($tableName);
75+
$this->cache = $explorer->getCache();
76+
$this->primary = $explorer->getConventions()->getPrimary($tableName);
8877
$this->sqlBuilder = new SqlBuilder($tableName, $explorer);
8978
$this->refCache = &$this->getRefTable($refPath)->globalRefCache[$refPath];
9079
}
@@ -907,7 +896,7 @@ public function delete(): int
907896
public function getReferencedTable(ActiveRow $row, ?string $table, ?string $column = null): ActiveRow|false|null
908897
{
909898
if (!$column) {
910-
$belongsTo = $this->conventions->getBelongsToReference($this->name, $table);
899+
$belongsTo = $this->explorer->getConventions()->getBelongsToReference($this->name, $table);
911900
if (!$belongsTo) {
912901
return false;
913902
}
@@ -960,7 +949,7 @@ public function getReferencingTable(
960949
if (str_contains($table, '.')) {
961950
[$table, $column] = explode('.', $table);
962951
} elseif (!$column) {
963-
$hasMany = $this->conventions->getHasManyReference($this->name, $table);
952+
$hasMany = $this->explorer->getConventions()->getHasManyReference($this->name, $table);
964953
if (!$hasMany) {
965954
return null;
966955
}

tests/Database/Explorer/Explorer.cache.observer.phpt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ $connection = $explorer->getConnection();
1818
Nette\Database\Helpers::loadFromFile($connection, __DIR__ . "/../files/{$driverName}-nette_test1.sql");
1919

2020

21-
$cacheStorage = Mockery::mock(Nette\Caching\Storage::class);
22-
$cacheStorage->shouldReceive('read')->withAnyArgs()->once()->andReturn(['id' => true]);
23-
$cacheStorage->shouldReceive('read')->withAnyArgs()->times(2)->andReturn(['id' => true, 'author_id' => true]);
24-
$cacheStorage->shouldReceive('write')->with(Mockery::any(), ['id' => true, 'author_id' => true, 'title' => true], []);
21+
$cache = Mockery::mock(Nette\Caching\Cache::class);
22+
$cache->shouldReceive('load')->withAnyArgs()->once()->andReturn(['id' => true]);
23+
$cache->shouldReceive('load')->withAnyArgs()->times(2)->andReturn(['id' => true, 'author_id' => true]);
24+
$cache->shouldReceive('save')->with(Mockery::any(), ['id' => true, 'author_id' => true, 'title' => true]);
2525

26-
$explorer = new Nette\Database\Explorer($connection, $explorer->getStructure(), $explorer->getConventions(), $cacheStorage);
26+
$explorer = new Nette\Database\Explorer($connection, $explorer->getStructure(), $explorer->getConventions(), $cache);
2727

2828
$queries = 0;
2929
$connection->onQuery[] = function ($dao, Result $result) use (&$queries) {

tests/Database/Explorer/Explorer.cache.observer2.phpt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
declare(strict_types=1);
99

10+
use Nette\Caching\Cache;
1011
use Nette\Caching\Storages\MemoryStorage;
1112
use Tester\Assert;
1213

@@ -18,20 +19,20 @@ $connection = $explorer->getConnection();
1819
Nette\Database\Helpers::loadFromFile($connection, __DIR__ . "/../files/{$driverName}-nette_test1.sql");
1920

2021

21-
class CacheMock extends MemoryStorage
22+
class CacheMock extends Cache
2223
{
2324
public int $writes = 0;
2425

2526

26-
public function write(string $key, $data, array $dependencies): void
27+
public function save(mixed $key, mixed $data, ?array $dependencies = null): mixed
2728
{
2829
$this->writes++;
29-
parent::write($key, $data, $dependencies);
30+
return parent::save($key, $data, $dependencies);
3031
}
3132
}
3233

33-
$cacheStorage = new CacheMock;
34-
$explorer = new Nette\Database\Explorer($connection, $explorer->getStructure(), $explorer->getConventions(), $cacheStorage);
34+
$cache = new CacheMock(new MemoryStorage);
35+
$explorer = new Nette\Database\Explorer($connection, $explorer->getStructure(), $explorer->getConventions(), $cache);
3536

3637
for ($i = 0; $i < 2; ++$i) {
3738
$authors = $explorer->table('author');
@@ -52,4 +53,4 @@ for ($i = 0; $i < 2; ++$i) {
5253
}
5354

5455
Assert::same(reformat('SELECT [id], [name] FROM [author]'), $sql);
55-
Assert::same(2, $cacheStorage->writes);
56+
Assert::same(2, $cache->writes);

tests/Database/Explorer/bugs/staticReflection.undeclaredColumn.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ $explorer = connectToDB();
1515
$connection = $explorer->getConnection();
1616

1717
$conventions = new Nette\Database\Conventions\StaticConventions;
18-
$cacheStorage = new Nette\Caching\Storages\MemoryStorage;
19-
$explorer = new Nette\Database\Explorer($explorer->getConnection(), $explorer->getStructure(), $conventions, $cacheStorage);
18+
$cache = new Nette\Caching\Cache(new Nette\Caching\Storages\MemoryStorage);
19+
$explorer = new Nette\Database\Explorer($explorer->getConnection(), $explorer->getStructure(), $conventions, $cache);
2020

2121
Nette\Database\Helpers::loadFromFile($connection, __DIR__ . "/../../files/{$driverName}-nette_test1.sql");
2222

tests/Database/Structure.phpt

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
declare(strict_types=1);
88

9+
use Mockery\MockInterface;
910
use Nette\Database\Structure;
1011
use Tester\Assert;
1112
use Tester\TestCase;
@@ -29,21 +30,17 @@ class StructureMock extends Structure
2930
*/
3031
class StructureTestCase extends TestCase
3132
{
32-
private Nette\Database\Connection $connection;
33-
private Nette\Database\Drivers\Engine $engine;
34-
private Nette\Caching\Storage $storage;
35-
private Structure $structure;
33+
private Nette\Database\Drivers\Engine|MockInterface $engine;
34+
private Nette\Caching\Cache|MockInterface $cache;
35+
private Structure|MockInterface $structure;
3636

3737

3838
protected function setUp()
3939
{
4040
parent::setUp();
4141
$this->engine = Mockery::mock(Nette\Database\Drivers\Engine::class);
42-
$this->connection = Mockery::mock(Nette\Database\Connection::class);
43-
$this->storage = Mockery::mock(Nette\Caching\Storage::class);
42+
$this->cache = Mockery::mock(Nette\Caching\Cache::class);
4443

45-
$this->connection->shouldReceive('getDsn')->once()->andReturn('');
46-
$this->connection->shouldReceive('getDatabaseEngine')->once()->andReturn($this->engine);
4744
$this->engine->shouldReceive('getTables')->once()->andReturn([
4845
['name' => 'authors', 'view' => false],
4946
['name' => 'Books', 'view' => false],
@@ -71,7 +68,6 @@ class StructureTestCase extends TestCase
7168
['name' => 'id', 'primary' => false, 'autoIncrement' => false, 'vendor' => []],
7269
['name' => 'title', 'primary' => false, 'autoIncrement' => false, 'vendor' => []],
7370
]);
74-
$this->connection->shouldReceive('getDatabaseEngine')->times(4)->andReturn($this->engine);
7571
$this->engine->shouldReceive('getForeignKeys')->with('authors')->once()->andReturn([]);
7672
$this->engine->shouldReceive('getForeignKeys')->with('Books')->once()->andReturn([
7773
['local' => ['author_id'], 'table' => 'authors', 'foreign' => ['id'], 'name' => 'authors_fk1'],
@@ -83,7 +79,7 @@ class StructureTestCase extends TestCase
8379
['local' => ['tag_id'], 'table' => 'tags', 'foreign' => ['id'], 'name' => 'books_x_tags_fk2'],
8480
]);
8581

86-
$this->structure = new StructureMock($this->connection, $this->storage);
82+
$this->structure = new StructureMock($this->engine, $this->cache);
8783
}
8884

8985

@@ -132,7 +128,6 @@ class StructureTestCase extends TestCase
132128

133129
public function testGetPrimaryKeySequence()
134130
{
135-
$this->connection->shouldReceive('getDatabaseEngine')->times(4)->andReturn($this->engine);
136131
$this->engine->shouldReceive('isSupported')->with('sequence')->once()->andReturn(false);
137132
$this->engine->shouldReceive('isSupported')->with('sequence')->times(3)->andReturn(true);
138133

tests/Database/Structure.schemas.phpt

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
declare(strict_types=1);
88

9+
use Mockery\MockInterface;
910
use Nette\Database\Structure;
1011
use Tester\Assert;
1112
use Tester\TestCase;
@@ -29,21 +30,17 @@ class StructureMock extends Structure
2930
*/
3031
class StructureSchemasTestCase extends TestCase
3132
{
32-
private Nette\Database\Connection $connection;
33-
private Nette\Database\Drivers\Engine $engine;
34-
private Nette\Caching\Storage $storage;
35-
private Structure $structure;
33+
private Nette\Database\Drivers\Engine|MockInterface $engine;
34+
private Nette\Caching\Cache|MockInterface $cache;
35+
private Structure|MockInterface $structure;
3636

3737

3838
protected function setUp()
3939
{
4040
parent::setUp();
4141
$this->engine = Mockery::mock(Nette\Database\Drivers\Engine::class);
42-
$this->connection = Mockery::mock(Nette\Database\Connection::class);
43-
$this->storage = Mockery::mock(Nette\Caching\Storage::class);
42+
$this->cache = Mockery::mock(Nette\Caching\Cache::class);
4443

45-
$this->connection->shouldReceive('getDsn')->once()->andReturn('');
46-
$this->connection->shouldReceive('getDatabaseEngine')->once()->andReturn($this->engine);
4744
$this->engine->shouldReceive('getTables')->once()->andReturn([
4845
['name' => 'authors', 'view' => false, 'fullName' => 'authors.authors'],
4946
['name' => 'books', 'view' => false, 'fullName' => 'books.books'],
@@ -57,14 +54,13 @@ class StructureSchemasTestCase extends TestCase
5754
['name' => 'title', 'primary' => false, 'vendor' => []],
5855
]);
5956

60-
$this->connection->shouldReceive('getDatabaseEngine')->times(2)->andReturn($this->engine);
6157
$this->engine->shouldReceive('getForeignKeys')->with('authors.authors')->once()->andReturn([]);
6258
$this->engine->shouldReceive('getForeignKeys')->with('books.books')->once()->andReturn([
6359
['local' => ['author_id'], 'table' => 'authors.authors', 'foreign' => ['id'], 'name' => 'authors_authors_fk1'],
6460
['local' => ['translator_id'], 'table' => 'authors.authors', 'foreign' => ['id'], 'name' => 'authors_authors_fk2'],
6561
]);
6662

67-
$this->structure = new StructureMock($this->connection, $this->storage);
63+
$this->structure = new StructureMock($this->engine, $this->cache);
6864
}
6965

7066

0 commit comments

Comments
 (0)