1<?php
2
3function get_default_host(): string {
4    static $host = null;
5    if ($host === null) {
6        $host = getenv('MYSQL_TEST_HOST') ?: '127.0.0.1';
7    }
8    return $host;
9}
10function get_default_port(): int {
11    static $port = null;
12    if ($port === null) {
13        $port = getenv('MYSQL_TEST_PORT') ?: 3306;
14    }
15    return $port;
16}
17function get_default_user(): string {
18    static $user = null;
19    if ($user === null) {
20        $user = getenv('MYSQL_TEST_USER') ?: 'root';
21    }
22    return $user;
23}
24function get_default_password(): string {
25    static $password = null;
26    if ($password === null) {
27        $password = getenv('MYSQL_TEST_PASSWD') ?: '';
28    }
29    return $password;
30}
31function get_default_database(): string {
32    static $db = null;
33    if ($db === null) {
34        $db = getenv('MYSQL_TEST_DB') ?: 'test';
35    }
36    return $db;
37}
38function get_default_db_engine(): string {
39    static $engine = null;
40    if ($engine === null) {
41        $engine = getenv('MYSQL_TEST_ENGINE') ?: 'InnoDB';
42    }
43    return $engine;
44}
45function get_default_socket(): ?string {
46    /*
47    static $socket = null;
48    if ($socket === null) {
49        $socket = getenv('MYSQL_TEST_ENGINE') ?: null;
50        if ($socket) {
51            ini_set('mysqli.default_socket', $socket);
52        }
53    }
54    return $socket;
55    */
56    return null;
57}
58function get_environment_connection_flags(): int {
59    static $connect_flags = null;
60    if ($connect_flags === null) {
61        $connect_flags = (int)getenv("MYSQL_TEST_CONNECT_FLAGS") ?: 0;
62    }
63    return $connect_flags;
64}
65
66/**
67 * Whenever possible, please use this wrapper to make testing of MYSQLI_CLIENT_COMPRESS (and potentially SSL) possible
68 *
69 * @param bool $enable_env_flags Enable setting of connection flags through 	env(MYSQL_TEST_CONNECT_FLAGS)?
70 */
71function my_mysqli_connect(
72    string $host,
73    string $user,
74    string $password,
75    string $db,
76    int $port,
77    ?string $socket = null,
78    bool $enable_env_flags = true
79): \mysqli {
80    // Because the tests are meant to test both error modes, they can set the report_mode to a different value,
81    // which we do not want to override. However, we want to make sure that if a connection cannot be made,
82    // the constuctor will throw an exception. We store current report_mode in variable and restore it later.
83    $driver = new mysqli_driver;
84    $report_mode = $driver->report_mode;
85    $driver->report_mode = MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT;
86    $flags = $enable_env_flags ? get_environment_connection_flags() : 0;
87    if ($flags !== 0) {
88        $link = mysqli_init();
89        mysqli_real_connect($link, $host, $user, $password, $db, $port, $socket, $flags);
90    } else {
91        /* TODO Investigate why on LINUX_X64_RELEASE_NTS CI pipeline
92         * Warning: mysqli_connect(): php_network_getaddresses: getaddrinfo for mysql failed:
93         * Temporary failure in name resolution in test_helpers.inc on line 91 */
94        $link = @mysqli_connect($host, $user, $password, $db, $port, $socket);
95    }
96    // Restore error mode
97    $driver->report_mode = $report_mode;
98    return $link;
99}
100function default_mysqli_connect(): \mysqli{
101    return my_mysqli_connect(
102        get_default_host(),
103        get_default_user(),
104        get_default_password(),
105        get_default_database(),
106        get_default_port(),
107        null,
108    );
109}
110function mysqli_check_skip_test(): void {
111    try {
112        $link = default_mysqli_connect();
113    } catch (\mysqli_sql_exception) {
114        die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));
115    }
116}
117function have_innodb(mysqli $link): bool {
118    $res = $link->query("SELECT SUPPORT FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE = 'InnoDB'");
119    $supported = $res->fetch_column();
120    return $supported === 'YES' || $supported === 'DEFAULT';
121}
122function mysqli_check_innodb_support_skip_test(): void {
123    try {
124        $link = default_mysqli_connect();
125    } catch (\mysqli_sql_exception) {
126        die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));
127    }
128    if (! have_innodb($link)) {
129        die(sprintf("skip Needs InnoDB support"));
130    }
131}
132function tear_down_table_on_default_connection(string $table) {
133    $link = default_mysqli_connect();
134    mysqli_query($link, 'DROP TABLE IF EXISTS ' . $table);
135}
136
137function setup_table_with_data_on_default_connection(string $table): mysqli {
138    $link = default_mysqli_connect();
139    mysqli_query($link, 'SET SESSION sql_mode=\'\'');
140    mysqli_query($link, 'CREATE TABLE '. $table .'(id INT DEFAULT 0, label CHAR(1), PRIMARY KEY(id)) ENGINE=' . get_default_db_engine());
141    mysqli_query($link, 'INSERT INTO '. $table .'(id, label) VALUES (1, "a"), (2, "b"), (3, "c"), (4, "d"), (5, "e"), (6, "f")');
142    return $link;
143}
144
145/* Development setting: test experimental features and/or feature requests that never worked before? */
146//$TEST_EXPERIMENTAL = 1 == getenv("MYSQL_TEST_EXPERIMENTAL");
147//$engine    = getenv("MYSQL_TEST_ENGINE")   ?: "InnoDB";
148