Failed Conditions
Push — master ( 656579...2742cd )
by Marco
11:55
created

Doctrine/Tests/DBAL/Functional/ConnectionTest.php (3 issues)

1
<?php
2
3
namespace Doctrine\Tests\DBAL\Functional;
4
5
use Doctrine\DBAL\ConnectionException;
6
use Doctrine\DBAL\DriverManager;
7
use Doctrine\DBAL\Platforms\AbstractPlatform;
8
use Doctrine\DBAL\Types\Type;
9
10
class ConnectionTest extends \Doctrine\Tests\DbalFunctionalTestCase
11
{
12
    protected function setUp()
13
    {
14
        $this->resetSharedConn();
15
        parent::setUp();
16
    }
17
18
    protected function tearDown()
19
    {
20
        parent::tearDown();
21
        $this->resetSharedConn();
22
    }
23
24
    public function testGetWrappedConnection()
25
    {
26
        self::assertInstanceOf('Doctrine\DBAL\Driver\Connection', $this->_conn->getWrappedConnection());
27
    }
28
29
    public function testCommitWithRollbackOnlyThrowsException()
30
    {
31
        $this->_conn->beginTransaction();
32
        $this->_conn->setRollbackOnly();
33
34
        $this->expectException(ConnectionException::class);
35
        $this->_conn->commit();
36
    }
37
38
    public function testTransactionNestingBehavior()
39
    {
40
        try {
41
            $this->_conn->beginTransaction();
42
            self::assertEquals(1, $this->_conn->getTransactionNestingLevel());
43
44
            try {
45
                $this->_conn->beginTransaction();
46
                self::assertEquals(2, $this->_conn->getTransactionNestingLevel());
47
                throw new \Exception;
48
                $this->_conn->commit(); // never reached
0 ignored issues
show
$this->_conn->commit() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
49
            } catch (\Exception $e) {
50
                $this->_conn->rollBack();
51
                self::assertEquals(1, $this->_conn->getTransactionNestingLevel());
52
                //no rethrow
53
            }
54
            self::assertTrue($this->_conn->isRollbackOnly());
55
56
            $this->_conn->commit(); // should throw exception
57
            $this->fail('Transaction commit after failed nested transaction should fail.');
58
        } catch (ConnectionException $e) {
59
            self::assertEquals(1, $this->_conn->getTransactionNestingLevel());
60
            $this->_conn->rollBack();
61
            self::assertEquals(0, $this->_conn->getTransactionNestingLevel());
62
        }
63
    }
64
65
    public function testTransactionNestingBehaviorWithSavepoints()
66
    {
67
        if (!$this->_conn->getDatabasePlatform()->supportsSavepoints()) {
68
            $this->markTestSkipped('This test requires the platform to support savepoints.');
69
        }
70
71
        $this->_conn->setNestTransactionsWithSavepoints(true);
72
        try {
73
            $this->_conn->beginTransaction();
74
            self::assertEquals(1, $this->_conn->getTransactionNestingLevel());
75
76
            try {
77
                $this->_conn->beginTransaction();
78
                self::assertEquals(2, $this->_conn->getTransactionNestingLevel());
79
                $this->_conn->beginTransaction();
80
                self::assertEquals(3, $this->_conn->getTransactionNestingLevel());
81
                $this->_conn->commit();
82
                self::assertEquals(2, $this->_conn->getTransactionNestingLevel());
83
                throw new \Exception;
84
                $this->_conn->commit(); // never reached
0 ignored issues
show
$this->_conn->commit() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
85
            } catch (\Exception $e) {
86
                $this->_conn->rollBack();
87
                self::assertEquals(1, $this->_conn->getTransactionNestingLevel());
88
                //no rethrow
89
            }
90
            self::assertFalse($this->_conn->isRollbackOnly());
91
            try {
92
                $this->_conn->setNestTransactionsWithSavepoints(false);
93
                $this->fail('Should not be able to disable savepoints in usage for nested transactions inside an open transaction.');
94
            } catch (ConnectionException $e) {
95
                self::assertTrue($this->_conn->getNestTransactionsWithSavepoints());
96
            }
97
            $this->_conn->commit(); // should not throw exception
98
        } catch (ConnectionException $e) {
99
            $this->fail('Transaction commit after failed nested transaction should not fail when using savepoints.');
100
            $this->_conn->rollBack();
101
        }
102
    }
103
104
    public function testTransactionNestingBehaviorCantBeChangedInActiveTransaction()
105
    {
106
        if (!$this->_conn->getDatabasePlatform()->supportsSavepoints()) {
107
            $this->markTestSkipped('This test requires the platform to support savepoints.');
108
        }
109
110
        $this->_conn->beginTransaction();
111
        $this->expectException(ConnectionException::class);
112
        $this->_conn->setNestTransactionsWithSavepoints(true);
113
    }
114
115 View Code Duplication
    public function testSetNestedTransactionsThroughSavepointsNotSupportedThrowsException()
116
    {
117
        if ($this->_conn->getDatabasePlatform()->supportsSavepoints()) {
118
            $this->markTestSkipped('This test requires the platform not to support savepoints.');
119
        }
120
121
        $this->expectException(ConnectionException::class);
122
        $this->expectExceptionMessage("Savepoints are not supported by this driver.");
123
124
        $this->_conn->setNestTransactionsWithSavepoints(true);
125
    }
126
127 View Code Duplication
    public function testCreateSavepointsNotSupportedThrowsException()
128
    {
129
        if ($this->_conn->getDatabasePlatform()->supportsSavepoints()) {
130
            $this->markTestSkipped('This test requires the platform not to support savepoints.');
131
        }
132
133
        $this->expectException(ConnectionException::class);
134
        $this->expectExceptionMessage("Savepoints are not supported by this driver.");
135
136
        $this->_conn->createSavepoint('foo');
137
    }
138
139 View Code Duplication
    public function testReleaseSavepointsNotSupportedThrowsException()
140
    {
141
        if ($this->_conn->getDatabasePlatform()->supportsSavepoints()) {
142
            $this->markTestSkipped('This test requires the platform not to support savepoints.');
143
        }
144
145
        $this->expectException(ConnectionException::class);
146
        $this->expectExceptionMessage("Savepoints are not supported by this driver.");
147
148
        $this->_conn->releaseSavepoint('foo');
149
    }
150
151 View Code Duplication
    public function testRollbackSavepointsNotSupportedThrowsException()
152
    {
153
        if ($this->_conn->getDatabasePlatform()->supportsSavepoints()) {
154
            $this->markTestSkipped('This test requires the platform not to support savepoints.');
155
        }
156
157
        $this->expectException(ConnectionException::class);
158
        $this->expectExceptionMessage("Savepoints are not supported by this driver.");
159
160
        $this->_conn->rollbackSavepoint('foo');
161
    }
162
163 View Code Duplication
    public function testTransactionBehaviorWithRollback()
164
    {
165
        try {
166
            $this->_conn->beginTransaction();
167
            self::assertEquals(1, $this->_conn->getTransactionNestingLevel());
168
169
            throw new \Exception;
170
171
            $this->_conn->commit(); // never reached
0 ignored issues
show
$this->_conn->commit() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
172
        } catch (\Exception $e) {
173
            self::assertEquals(1, $this->_conn->getTransactionNestingLevel());
174
            $this->_conn->rollBack();
175
            self::assertEquals(0, $this->_conn->getTransactionNestingLevel());
176
        }
177
    }
178
179 View Code Duplication
    public function testTransactionBehaviour()
180
    {
181
        try {
182
            $this->_conn->beginTransaction();
183
            self::assertEquals(1, $this->_conn->getTransactionNestingLevel());
184
            $this->_conn->commit();
185
        } catch (\Exception $e) {
186
            $this->_conn->rollBack();
187
            self::assertEquals(0, $this->_conn->getTransactionNestingLevel());
188
        }
189
190
        self::assertEquals(0, $this->_conn->getTransactionNestingLevel());
191
    }
192
193
    public function testTransactionalWithException()
194
    {
195
        try {
196
            $this->_conn->transactional(function($conn) {
197
                /* @var $conn \Doctrine\DBAL\Connection */
198
                $conn->executeQuery($conn->getDatabasePlatform()->getDummySelectSQL());
199
                throw new \RuntimeException("Ooops!");
200
            });
201
            $this->fail('Expected exception');
202
        } catch (\RuntimeException $expected) {
203
            self::assertEquals(0, $this->_conn->getTransactionNestingLevel());
204
        }
205
    }
206
207
    public function testTransactionalWithThrowable()
208
    {
209
        if (version_compare(PHP_VERSION, '7.0', '<')) {
210
            $this->markTestSkipped('Only for PHP 7.0 and above.');
211
        }
212
213
        try {
214
            $this->_conn->transactional(function($conn) {
215
                /* @var $conn \Doctrine\DBAL\Connection */
216
                $conn->executeQuery($conn->getDatabasePlatform()->getDummySelectSQL());
217
                throw new \Error("Ooops!");
218
            });
219
            $this->fail('Expected exception');
220
        } catch (\Error $expected) {
221
            self::assertEquals(0, $this->_conn->getTransactionNestingLevel());
222
        }
223
    }
224
225
    public function testTransactional()
226
    {
227
        $res = $this->_conn->transactional(function($conn) {
228
            /* @var $conn \Doctrine\DBAL\Connection */
229
            $conn->executeQuery($conn->getDatabasePlatform()->getDummySelectSQL());
230
        });
231
232
        self::assertNull($res);
233
    }
234
235
    public function testTransactionalReturnValue()
236
    {
237
        $res = $this->_conn->transactional(function() {
238
            return 42;
239
        });
240
241
        self::assertEquals(42, $res);
242
    }
243
244
    /**
245
     * Tests that the quote function accepts DBAL and PDO types.
246
     */
247
    public function testQuote()
248
    {
249
        self::assertEquals($this->_conn->quote("foo", Type::STRING), $this->_conn->quote("foo", \PDO::PARAM_STR));
250
    }
251
252
    public function testPingDoesTriggersConnect()
253
    {
254
        self::assertTrue($this->_conn->ping());
255
        self::assertTrue($this->_conn->isConnected());
256
    }
257
258
    /**
259
     * @group DBAL-1025
260
     */
261
    public function testConnectWithoutExplicitDatabaseName()
262
    {
263 View Code Duplication
        if (in_array($this->_conn->getDatabasePlatform()->getName(), array('oracle', 'db2'), true)) {
264
            $this->markTestSkipped('Platform does not support connecting without database name.');
265
        }
266
267
        $params = $this->_conn->getParams();
268
        unset($params['dbname']);
269
270
        $connection = DriverManager::getConnection(
271
            $params,
272
            $this->_conn->getConfiguration(),
273
            $this->_conn->getEventManager()
274
        );
275
276
        self::assertTrue($connection->connect());
277
278
        $connection->close();
279
    }
280
281
    /**
282
     * @group DBAL-990
283
     */
284
    public function testDeterminesDatabasePlatformWhenConnectingToNonExistentDatabase()
285
    {
286 View Code Duplication
        if (in_array($this->_conn->getDatabasePlatform()->getName(), ['oracle', 'db2'], true)) {
287
            $this->markTestSkipped('Platform does not support connecting without database name.');
288
        }
289
290
        $params = $this->_conn->getParams();
291
        $params['dbname'] = 'foo_bar';
292
293
        $connection = DriverManager::getConnection(
294
            $params,
295
            $this->_conn->getConfiguration(),
296
            $this->_conn->getEventManager()
297
        );
298
299
        self::assertInstanceOf(AbstractPlatform::class, $connection->getDatabasePlatform());
300
        self::assertFalse($connection->isConnected());
301
        self::assertSame($params, $connection->getParams());
302
303
        $connection->close();
304
    }
305
}
306