packages/ztd-query-mysqli-adapter/tests/Unit/Native/MysqliStatementPropertyReaderTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Native;
6
7use Container\Endpoint;
8use Container\MySqlRelease;
9use mysqli;
10use mysqli_stmt;
11use PHPUnit\Framework\Attributes\CoversClass;
12use PHPUnit\Framework\Attributes\Large;
13use PHPUnit\Framework\TestCase;
14use Testcontainers\Testcontainers;
15use ZtdQuery\Adapter\Mysqli\Native\MysqliStatementPropertyReader;
16
17#[CoversClass(MysqliStatementPropertyReader::class)]
18#[Large]
19final class MysqliStatementPropertyReaderTest extends TestCase
20{
21 public function testReadPreservesPreparedMetadataAndBufferedRowCounts(): void
22 {
23 $container = Testcontainers::run(MySqlRelease::fromEnvironment());
24 $endpoint = $container->getData(Endpoint::class);
25 try {
26 $connection = new mysqli($endpoint->host, $endpoint->username, $endpoint->password, $endpoint->database, $endpoint->port);
27 $connection->set_charset('utf8mb4');
28 $statement = $connection->prepare('SELECT ? AS value UNION ALL SELECT ?');
29 self::assertInstanceOf(mysqli_stmt::class, $statement);
30 $reader = new MysqliStatementPropertyReader();
31 self::assertSame(2, $reader->read($statement, 'param_count'));
32 self::assertSame(1, $reader->read($statement, 'field_count'));
33 self::assertSame($statement->id, $reader->read($statement, 'id'));
34 self::assertTrue($statement->execute([7, 8]));
35 self::assertTrue($statement->store_result());
36 self::assertSame(2, $reader->read($statement, 'num_rows'));
37 self::assertSame(2, $reader->read($statement, 'affected_rows'));
38 self::assertSame(0, $reader->read($statement, 'errno'));
39 self::assertSame('', $reader->read($statement, 'error'));
40 self::assertSame([], $reader->read($statement, 'error_list'));
41 self::assertSame('00000', $reader->read($statement, 'sqlstate'));
42 self::assertNull($reader->read($statement, 'unsupported'));
43 $statement->close();
44 $connection->close();
45 } finally {
46 $container->stop();
47 }
48 }
49
50 public function testReadPreservesGeneratedIdsAndWriteCounts(): void
51 {
52 $container = Testcontainers::run(MySqlRelease::fromEnvironment());
53 $endpoint = $container->getData(Endpoint::class);
54 try {
55 $connection = new mysqli($endpoint->host, $endpoint->username, $endpoint->password, $endpoint->database, $endpoint->port);
56 $connection->set_charset('utf8mb4');
57 $connection->query('CREATE TABLE generated_rows (id INT AUTO_INCREMENT PRIMARY KEY, value INT)');
58 $statement = $connection->prepare('INSERT INTO generated_rows (value) VALUES (?), (?)');
59 self::assertInstanceOf(mysqli_stmt::class, $statement);
60 self::assertTrue($statement->execute([7, 8]));
61 $reader = new MysqliStatementPropertyReader();
62 self::assertSame(1, $reader->read($statement, 'insert_id'));
63 self::assertSame(2, $reader->read($statement, 'affected_rows'));
64 self::assertSame(0, $reader->read($statement, 'field_count'));
65 self::assertSame(0, $reader->read($statement, 'num_rows'));
66 $statement->close();
67 $connection->close();
68 } finally {
69 $container->stop();
70 }
71 }
72
73 public function testReadPreservesNativeFailureDetails(): void
74 {
75 $container = Testcontainers::run(MySqlRelease::fromEnvironment());
76 $endpoint = $container->getData(Endpoint::class);
77 try {
78 $connection = new mysqli($endpoint->host, $endpoint->username, $endpoint->password, $endpoint->database, $endpoint->port);
79 $connection->set_charset('utf8mb4');
80 $connection->query('CREATE TABLE unique_rows (id INT PRIMARY KEY)');
81 $statement = $connection->prepare('INSERT INTO unique_rows VALUES (?)');
82 self::assertInstanceOf(mysqli_stmt::class, $statement);
83 self::assertTrue($statement->execute([1]));
84 mysqli_report(MYSQLI_REPORT_OFF);
85 try {
86 self::assertFalse($statement->execute([1]));
87 $reader = new MysqliStatementPropertyReader();
88 self::assertSame(1062, $reader->read($statement, 'errno'));
89 self::assertSame('23000', $reader->read($statement, 'sqlstate'));
90 self::assertStringContainsString('Duplicate entry', $statement->error);
91 self::assertSame($statement->error, $reader->read($statement, 'error'));
92 self::assertSame([['errno' => 1062, 'sqlstate' => '23000', 'error' => $statement->error]], $reader->read($statement, 'error_list'));
93 } finally {
94 mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
95 $statement->close();
96 $connection->close();
97 }
98 } finally {
99 $container->stop();
100 }
101 }
102}
103