Skip to content
10 changes: 3 additions & 7 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
name: Static Analysis (only informative)
name: Static Analysis

on:
push:
branches:
- master
on: [push, pull_request]

jobs:
phpstan:
Expand All @@ -13,9 +10,8 @@ jobs:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: 8.1
php-version: 8.5
coverage: none

- run: composer install --no-progress --prefer-dist
- run: composer phpstan -- --no-progress
continue-on-error: true # is only informative
18 changes: 16 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@ jobs:
--health-timeout 5s
--health-retries 5

postgres15:
image: postgres:15
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: nette_test
ports:
- 5434:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5

mssql:
image: mcr.microsoft.com/mssql/server:latest
env:
Expand Down Expand Up @@ -103,7 +117,7 @@ jobs:
run: docker exec -i mssql /opt/mssql-tools18/bin/sqlcmd -S localhost -U SA -P 'YourStrong!Passw0rd' -Q 'CREATE DATABASE nette_test' -N -C

- run: composer install --no-progress --prefer-dist
- run: vendor/bin/tester tests -s -C
- run: composer tester
- if: failure()
uses: actions/upload-artifact@v4
with:
Expand All @@ -125,4 +139,4 @@ jobs:
run: cp ./tests/databases.sqlite.ini ./tests/Database/databases.ini

- run: composer update --no-progress --prefer-dist --prefer-lowest --prefer-stable
- run: vendor/bin/tester tests -s -C
- run: composer tester
11 changes: 9 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@
"nette/utils": "^4.0"
},
"require-dev": {
"nette/tester": "^2.5",
"nette/tester": "^2.6",
"nette/di": "^3.1",
"mockery/mockery": "^1.6@stable",
"tracy/tracy": "^2.9",
"phpstan/phpstan-nette": "^2.0@stable",
"phpstan/phpstan": "^2.1@stable",
"phpstan/extension-installer": "^1.4@stable",
"nette/phpstan-rules": "^1.0",
"jetbrains/phpstorm-attributes": "^1.2"
},
"autoload": {
Expand All @@ -43,5 +45,10 @@
"branch-alias": {
"dev-master": "3.2-dev"
}
},
"config": {
"allow-plugins": {
"phpstan/extension-installer": true
}
}
}
3 changes: 0 additions & 3 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,3 @@ parameters:

paths:
- src

includes:
- vendor/phpstan/phpstan-nette/extension.neon
39 changes: 37 additions & 2 deletions src/Bridges/DatabaseDI/DatabaseExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@


/**
* Nette Framework Database services.
* Registers database Connection, Structure, and Explorer services in the DI container.
*/
class DatabaseExtension extends Nette\DI\CompilerExtension
{
Expand All @@ -36,6 +36,10 @@ public function getConfigSchema(): Nette\Schema\Schema
'explain' => Expect::bool(true),
'reflection' => Expect::string(), // BC
'conventions' => Expect::string('discovered'), // Nette\Database\Conventions\DiscoveredConventions
'mapping' => Expect::structure([
'convention' => Expect::string(''),
'tables' => Expect::arrayOf('string', 'string'),
])->before(fn($v) => is_string($v) ? ['convention' => $v] : $v),
'autowired' => Expect::bool(),
]),
)->before(fn($val) => is_array(reset($val)) || reset($val) === null
Expand Down Expand Up @@ -120,8 +124,15 @@ private function setupDatabase(\stdClass $config, string $name): void
$conventions = Nette\DI\Helpers::filterArguments([$config->conventions])[0];
}

$rowMapping = ($config->mapping->convention || $config->mapping->tables)
? new Nette\DI\Definitions\Statement([self::class, 'createRowMapping'], [
$config->mapping->convention,
(array) $config->mapping->tables,
])
: null;

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

$builder->addAlias($this->prefix("$name.context"), $this->prefix("$name.explorer"));
Expand All @@ -132,4 +143,28 @@ private function setupDatabase(\stdClass $config, string $name): void
$builder->addAlias("nette.database.$name.context", $this->prefix("$name.explorer"));
}
}


/**
* Creates a row mapping closure that resolves an ActiveRow subclass for each table name.
* @param array<string, string> $tables
* @return \Closure(string): string
*/
public static function createRowMapping(string $convention, array $tables): \Closure
{
return static function (string $table) use ($convention, $tables): string {
if (isset($tables[$table])) {
return $tables[$table];
}

if ($convention !== '') {
$class = str_replace('*', str_replace(' ', '', ucwords(strtr($table, '_', ' '))), $convention);
if (class_exists($class)) {
return $class;
}
}

return Nette\Database\Table\ActiveRow::class;
};
}
}
9 changes: 8 additions & 1 deletion src/Bridges/DatabaseTracy/ConnectionPanel.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


/**
* Debug panel for Nette\Database.
* Tracy Bar panel showing executed SQL queries with timing and EXPLAIN support.
*/
class ConnectionPanel implements Tracy\IBarPanel
{
Expand All @@ -26,10 +26,15 @@ class ConnectionPanel implements Tracy\IBarPanel
public float $performanceScale = 0.25;
private float $totalTime = 0;
private int $count = 0;

/** @var list<array{Connection, string, ?array<mixed>, list<array<string, mixed>>, ?float, ?int, ?string}> */
private array $queries = [];
private Tracy\BlueScreen $blueScreen;


/**
* Registers the panel with Tracy. Optionally adds it to the Tracy Bar.
*/
public static function initialize(
Connection $connection,
bool $addBarPanel = false,
Expand Down Expand Up @@ -61,6 +66,7 @@ public function __construct(Connection $connection, Tracy\BlueScreen $blueScreen
}


/** @param Nette\Database\ResultSet|\PDOException $result */
private function logQuery(Connection $connection, $result): void
{
if ($this->disabled) {
Expand Down Expand Up @@ -91,6 +97,7 @@ private function logQuery(Connection $connection, $result): void
}


/** @return array{tab: string, panel: string}|null */
public static function renderException(?\Throwable $e): ?array
{
if (!$e instanceof \PDOException) {
Expand Down
Loading