packages/ztd-query-mysqli-adapter/tests/Unit/Native/MysqliStatementBindingBridgeTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Native;
6
7use Container\MySql80Container;
8use Container\MySql84Container;
9use mysqli;
10use mysqli_result;
11use mysqli_stmt;
12use PHPUnit\Framework\Attributes\CoversClass;
13use PHPUnit\Framework\Attributes\Large;
14use PHPUnit\Framework\TestCase;
15use Testcontainers\Testcontainers;
16use ZtdQuery\Adapter\Mysqli\Native\MysqliStatementBindingBridge;
17
18#[CoversClass(MysqliStatementBindingBridge::class)]
19#[Large]
20final class MysqliStatementBindingBridgeTest extends TestCase
21{
22    public function testBind_paramRetainsReferencesAcrossExecutions(): void
23    {
24        $container = Testcontainers::run(getenv('MYSQL_VERSION') === '8.4.7' ? MySql84Container::class : MySql80Container::class);
25        try {
26            $connection = new mysqli(str_replace('localhost', '127.0.0.1', $container->getHost()), 'root', 'root', 'test', $container->getMappedPort(3306));
27            $connection->set_charset('utf8mb4');
28            $statement = $connection->prepare('SELECT ? AS value');
29            self::assertInstanceOf(mysqli_stmt::class, $statement);
30            $bridge = new class ($statement) extends MysqliStatementBindingBridge {};
31            $value = 7;
32            self::assertTrue($bridge->bind_param('i', $value));
33            $value = 42;
34            self::assertTrue($statement->execute());
35            $result = $statement->get_result();
36            self::assertInstanceOf(mysqli_result::class, $result);
37            self::assertSame([['value' => 42]], $result->fetch_all(MYSQLI_ASSOC));
38            $statement->close();
39        } finally {
40            $container->stop();
41        }
42    }
43
44    public function testBind_resultWritesBackToCallerVariables(): void
45    {
46        $container = Testcontainers::run(getenv('MYSQL_VERSION') === '8.4.7' ? MySql84Container::class : MySql80Container::class);
47        try {
48            $connection = new mysqli(str_replace('localhost', '127.0.0.1', $container->getHost()), 'root', 'root', 'test', $container->getMappedPort(3306));
49            $connection->set_charset('utf8mb4');
50            $statement = $connection->prepare("SELECT 7 AS id, 'Alice' AS name");
51            self::assertInstanceOf(mysqli_stmt::class, $statement);
52            $bridge = new class ($statement) extends MysqliStatementBindingBridge {};
53            $id = null;
54            $name = null;
55            self::assertTrue($statement->execute());
56            self::assertTrue($bridge->bind_result($id, $name));
57            self::assertTrue($statement->fetch());
58            self::assertSame(7, $id);
59            self::assertSame('Alice', $name);
60            self::assertNull($statement->fetch());
61            $statement->close();
62        } finally {
63            $container->stop();
64        }
65    }
66}
67