packages/sql-fixture/tests/Unit/Platform/PostgreSql/Schema/CatalogSchemaTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Platform\PostgreSql\Schema;
6
7use PDO;
8use PHPUnit\Framework\Attributes\CoversClass;
9use PHPUnit\Framework\TestCase;
10use SqlFixture\Platform\PostgreSql\Schema\CatalogSchema as Subject;
11
12#[CoversClass(Subject::class)]
13#[\PHPUnit\Framework\Attributes\Medium]
14#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFixture\Platform\PostgreSql\Schema\CatalogColumn::class)]
15#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFixture\Platform\PostgreSql\Schema\CatalogQuery::class)]
16#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFixture\Schema\ColumnDefinition::class)]
17#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFixture\Schema\TableSchema::class)]
18final class CatalogSchemaTest extends TestCase
19{
20    public function testFetchSchemaFromInformationSchemaRetainsColumnMetadata(): void
21    {
22        $pdo = new PDO(
23            (string) getenv('SQL_FIXTURE_PGSQL_DSN'),
24            (string) getenv('SQL_FIXTURE_PGSQL_USER'),
25            (string) getenv('SQL_FIXTURE_PGSQL_PASSWORD'),
26            [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_STRINGIFY_FETCHES => true],
27        );
28        $pdo->exec('CREATE TEMPORARY TABLE users (id INTEGER PRIMARY KEY, name VARCHAR(30) NOT NULL DEFAULT \'ready\')');
29        $statement = $pdo->query('SELECT pg_my_temp_schema()::regnamespace::text');
30        self::assertNotFalse($statement);
31        $namespace = $statement->fetchColumn();
32        self::assertIsString($namespace);
33        $schema = (new Subject())->fetchSchemaFromInformationSchema($pdo, $namespace . '.users');
34        self::assertSame('users', $schema->tableName);
35        self::assertFalse($schema->columns['id']->nullable);
36        self::assertSame(30, $schema->columns['name']->length);
37        self::assertSame('ready', $schema->columns['name']->default);
38    }
39
40    public function testFetchSchemaPreservesNullableSerialAndDecimalMetadata(): void
41    {
42        $pdo = new PDO(
43            (string) getenv('SQL_FIXTURE_PGSQL_DSN'),
44            (string) getenv('SQL_FIXTURE_PGSQL_USER'),
45            (string) getenv('SQL_FIXTURE_PGSQL_PASSWORD'),
46            [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_STRINGIFY_FETCHES => true],
47        );
48        $pdo->exec('CREATE TEMPORARY TABLE prices (id SERIAL, amount NUMERIC(7,2), note TEXT)');
49        $statement = $pdo->query('SELECT pg_my_temp_schema()::regnamespace::text');
50        self::assertNotFalse($statement);
51        $namespace = $statement->fetchColumn();
52        self::assertIsString($namespace);
53        $schema = (new Subject())->fetchSchemaFromInformationSchema($pdo, $namespace . '.prices');
54        self::assertSame('prices', $schema->tableName);
55        self::assertTrue($schema->columns['id']->autoIncrement);
56        self::assertFalse($schema->columns['id']->nullable);
57        self::assertNull($schema->columns['id']->default);
58        self::assertTrue($schema->columns['amount']->nullable);
59        self::assertFalse($schema->columns['amount']->autoIncrement);
60        self::assertNull($schema->columns['amount']->length);
61        self::assertSame(7, $schema->columns['amount']->precision);
62        self::assertSame(2, $schema->columns['amount']->scale);
63        self::assertFalse($schema->columns['amount']->unsigned);
64        self::assertFalse($schema->columns['amount']->generated);
65        self::assertNull($schema->columns['note']->precision);
66        self::assertNull($schema->columns['note']->scale);
67        self::assertNull($schema->columns['note']->default);
68    }
69}
70