Passed
Push — type-registry ( f9a1df...0931f1 )
by Michael
24:09
created

TestUtil::getSpecifiedConnectionParams()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 35
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 19
dl 0
loc 35
rs 9.6333
c 0
b 0
f 0
cc 4
nc 3
nop 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A TestUtil::initializeDatabase() 0 27 3
1
<?php
2
3
namespace Doctrine\Tests;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\DriverManager;
7
use PHPUnit\Framework\Assert;
8
use function explode;
9
use function extension_loaded;
10
use function unlink;
11
12
/**
13
 * TestUtil is a class with static utility methods used during tests.
14
 */
15
class TestUtil
16
{
17
    /** @var bool Whether the database schema is initialized. */
18
    private static $initialized = false;
19
20
    /**
21
     * Gets a <b>real</b> database connection using the following parameters
22
     * of the $GLOBALS array:
23
     *
24
     * 'db_type' : The name of the Doctrine DBAL database driver to use.
25
     * 'db_username' : The username to use for connecting.
26
     * 'db_password' : The password to use for connecting.
27
     * 'db_host' : The hostname of the database to connect to.
28
     * 'db_server' : The server name of the database to connect to
29
     *               (optional, some vendors allow multiple server instances with different names on the same host).
30
     * 'db_name' : The name of the database to connect to.
31
     * 'db_port' : The port of the database to connect to.
32
     *
33
     * Usually these variables of the $GLOBALS array are filled by PHPUnit based
34
     * on an XML configuration file. If no such parameters exist, an SQLite
35
     * in-memory database is used.
36
     *
37
     * IMPORTANT: Each invocation of this method returns a NEW database connection.
38
     *
39
     * @return Connection The database connection instance.
40
     */
41
    public static function getConnection()
42
    {
43
        if (self::hasRequiredConnectionParams() && ! self::$initialized) {
44
            self::initializeDatabase();
45
            self::$initialized = true;
46
        }
47
48
        $conn = DriverManager::getConnection(self::getConnectionParams());
49
50
        self::addDbEventSubscribers($conn);
51
52
        return $conn;
53
    }
54
55
    public static function getConnectionParams()
56
    {
57
        if (self::hasRequiredConnectionParams()) {
58
            return self::getParamsForMainConnection();
59
        }
60
61
        return self::getFallbackConnectionParams();
62
    }
63
64
    private static function hasRequiredConnectionParams()
65
    {
66
        return isset(
67
            $GLOBALS['db_type'],
68
            $GLOBALS['db_username'],
69
            $GLOBALS['db_password'],
70
            $GLOBALS['db_host'],
71
            $GLOBALS['db_name'],
72
            $GLOBALS['db_port']
73
        )
74
        && isset(
75
            $GLOBALS['tmpdb_type'],
76
            $GLOBALS['tmpdb_username'],
77
            $GLOBALS['tmpdb_password'],
78
            $GLOBALS['tmpdb_host'],
79
            $GLOBALS['tmpdb_port']
80
        );
81
    }
82
83
    private static function initializeDatabase() : void
84
    {
85
        $realDbParams = self::getParamsForMainConnection();
86
        $tmpDbParams  = self::getParamsForTemporaryConnection();
87
88
        $realConn = DriverManager::getConnection($realDbParams);
89
90
        // Connect to tmpdb in order to drop and create the real test db.
91
        $tmpConn = DriverManager::getConnection($tmpDbParams);
92
93
        $platform = $tmpConn->getDatabasePlatform();
94
95
        if ($platform->supportsCreateDropDatabase()) {
96
            $dbname = $realConn->getDatabase();
97
            $realConn->close();
98
99
            $tmpConn->getSchemaManager()->dropAndCreateDatabase($dbname);
100
101
            $tmpConn->close();
102
        } else {
103
            $sm = $realConn->getSchemaManager();
104
105
            $schema = $sm->createSchema();
106
            $stmts  = $schema->toDropSql($realConn->getDatabasePlatform());
107
108
            foreach ($stmts as $stmt) {
109
                $realConn->exec($stmt);
110
            }
111
        }
112
    }
113
114
    private static function getFallbackConnectionParams()
115
    {
116
        if (! extension_loaded('pdo_sqlite')) {
117
            Assert::markTestSkipped('PDO SQLite extension is not loaded');
118
        }
119
120
        $params = [
121
            'driver' => 'pdo_sqlite',
122
            'memory' => true,
123
        ];
124
125
        if (isset($GLOBALS['db_path'])) {
126
            $params['path'] = $GLOBALS['db_path'];
127
            unlink($GLOBALS['db_path']);
128
        }
129
130
        return $params;
131
    }
132
133
    private static function addDbEventSubscribers(Connection $conn)
134
    {
135
        if (! isset($GLOBALS['db_event_subscribers'])) {
136
            return;
137
        }
138
139
        $evm = $conn->getEventManager();
140
        foreach (explode(',', $GLOBALS['db_event_subscribers']) as $subscriberClass) {
141
            $subscriberInstance = new $subscriberClass();
142
            $evm->addEventSubscriber($subscriberInstance);
143
        }
144
    }
145
146
    private static function getParamsForTemporaryConnection()
147
    {
148
        $connectionParams = [
149
            'driver' => $GLOBALS['tmpdb_type'],
150
            'user' => $GLOBALS['tmpdb_username'],
151
            'password' => $GLOBALS['tmpdb_password'],
152
            'host' => $GLOBALS['tmpdb_host'],
153
            'dbname' => null,
154
            'port' => $GLOBALS['tmpdb_port'],
155
        ];
156
157
        if (isset($GLOBALS['tmpdb_name'])) {
158
            $connectionParams['dbname'] = $GLOBALS['tmpdb_name'];
159
        }
160
161
        if (isset($GLOBALS['tmpdb_server'])) {
162
            $connectionParams['server'] = $GLOBALS['tmpdb_server'];
163
        }
164
165
        if (isset($GLOBALS['tmpdb_unix_socket'])) {
166
            $connectionParams['unix_socket'] = $GLOBALS['tmpdb_unix_socket'];
167
        }
168
169
        return $connectionParams;
170
    }
171
172
    private static function getParamsForMainConnection()
173
    {
174
        $connectionParams = [
175
            'driver' => $GLOBALS['db_type'],
176
            'user' => $GLOBALS['db_username'],
177
            'password' => $GLOBALS['db_password'],
178
            'host' => $GLOBALS['db_host'],
179
            'dbname' => $GLOBALS['db_name'],
180
            'port' => $GLOBALS['db_port'],
181
        ];
182
183
        if (isset($GLOBALS['db_server'])) {
184
            $connectionParams['server'] = $GLOBALS['db_server'];
185
        }
186
187
        if (isset($GLOBALS['db_unix_socket'])) {
188
            $connectionParams['unix_socket'] = $GLOBALS['db_unix_socket'];
189
        }
190
191
        return $connectionParams;
192
    }
193
194
    /**
195
     * @return Connection
196
     */
197
    public static function getTempConnection()
198
    {
199
        return DriverManager::getConnection(self::getParamsForTemporaryConnection());
200
    }
201
}
202