packages/ztd-query-postgres/tests/Unit/Sql/Diagnostic/PgSqlReadOnlyDiagnosticStatementTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql\Diagnostic;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\Attributes\UsesClass;
10use PHPUnit\Framework\TestCase;
11use ZtdQuery\Platform\Postgres\Sql\Diagnostic\PgSqlReadOnlyDiagnosticStatement;
12
13#[CoversClass(PgSqlReadOnlyDiagnosticStatement::class)]
14#[UsesClass(\ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::class)]
15#[CoversClass(\ZtdQuery\Platform\Postgres\Sql\Diagnostic\KeywordSearch::class)]
16final class PgSqlReadOnlyDiagnosticStatementTest extends TestCase
17{
18    #[DataProvider('providerStatement')]
19    public function testIsSafeClassifiesOnlySafePostgreSqlDiagnostics(string $sql, bool $expected): void
20    {
21        self::assertSame($expected, PgSqlReadOnlyDiagnosticStatement::isSafe($sql));
22    }
23
24    /**
25     * @return iterable<string, array{string, bool}>
26     */
27    public static function providerStatement(): iterable
28    {
29        yield 'explain select' => ['EXPLAIN SELECT * FROM users', true];
30        yield 'non-executing update' => ['EXPLAIN UPDATE users SET active = FALSE', true];
31        yield 'analyze select' => ['EXPLAIN (ANALYZE TRUE, FORMAT JSON) SELECT * FROM users', true];
32        yield 'analyse select' => ['EXPLAIN ANALYSE SELECT * FROM users', true];
33        yield 'executing update' => ['EXPLAIN ANALYZE UPDATE users SET active = FALSE', false];
34        yield 'data-modifying cte' => ['EXPLAIN ANALYZE WITH d AS (DELETE FROM users RETURNING id) SELECT * FROM d', false];
35        yield 'show setting' => ['SHOW server_version', true];
36        yield 'show without setting' => ['SHOW', false];
37        yield 'mysql describe' => ['DESCRIBE users', false];
38        yield 'multiple statements' => ['EXPLAIN SELECT 1; DELETE FROM users', false];
39        yield 'empty explain' => ['EXPLAIN', false];
40    }
41}
42