ExceptionTest.php 13.7 KB
Newer Older
1 2 3
<?php
namespace Doctrine\Tests\DBAL\Functional;

4
use Doctrine\DBAL\Driver\ExceptionConverterDriver;
5
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
6
use Doctrine\DBAL\Schema\Table;
7 8 9

class ExceptionTest extends \Doctrine\Tests\DbalFunctionalTestCase
{
10
    protected function setUp()
11 12 13
    {
        parent::setUp();

14
        if ( !($this->_conn->getDriver() instanceof ExceptionConverterDriver)) {
15 16 17 18
            $this->markTestSkipped('Driver does not support special exception handling.');
        }
    }

19
    public function testPrimaryConstraintViolationException()
20 21 22 23 24
    {
        $table = new \Doctrine\DBAL\Schema\Table("duplicatekey_table");
        $table->addColumn('id', 'integer', array());
        $table->setPrimaryKey(array('id'));

jeroendedauw's avatar
jeroendedauw committed
25
        foreach ($this->_conn->getDatabasePlatform()->getCreateTableSQL($table) as $sql) {
26 27 28 29 30
            $this->_conn->executeQuery($sql);
        }

        $this->_conn->insert("duplicatekey_table", array('id' => 1));

31 32
        $this->setExpectedException(
            '\Doctrine\DBAL\Exception\UniqueConstraintViolationException');
33 34
        $this->_conn->insert("duplicatekey_table", array('id' => 1));
    }
35

36
    public function testTableNotFoundException()
37 38 39
    {
        $sql = "SELECT * FROM unknown_table";

40
        $this->setExpectedException('\Doctrine\DBAL\Exception\TableNotFoundException');
41 42
        $this->_conn->executeQuery($sql);
    }
43

44
    public function testTableExistsException()
45
    {
46
        $table = new \Doctrine\DBAL\Schema\Table("alreadyexist_table");
47 48 49
        $table->addColumn('id', 'integer', array());
        $table->setPrimaryKey(array('id'));

50
        $this->setExpectedException('\Doctrine\DBAL\Exception\TableExistsException');
jeroendedauw's avatar
jeroendedauw committed
51
        foreach ($this->_conn->getDatabasePlatform()->getCreateTableSQL($table) as $sql) {
52 53
            $this->_conn->executeQuery($sql);
        }
jeroendedauw's avatar
jeroendedauw committed
54
        foreach ($this->_conn->getDatabasePlatform()->getCreateTableSQL($table) as $sql) {
55 56 57
            $this->_conn->executeQuery($sql);
        }
    }
58

Possum's avatar
Possum committed
59
    public function testForeignKeyConstraintViolationExceptionOnInsert()
60 61 62 63 64
    {
        if ( ! $this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
            $this->markTestSkipped("Only fails on platforms with foreign key constraints.");
        }

65
        $this->setUpForeignKeyConstraintViolationExceptionTest();
66

67 68 69 70 71 72 73 74
        try {
            $this->_conn->insert("constraint_error_table", array('id' => 1));
            $this->_conn->insert("owning_table", array('id' => 1, 'constraint_id' => 1));
        } catch (\Exception $exception) {
            $this->tearDownForeignKeyConstraintViolationExceptionTest();

            throw $exception;
        }
75

76
        $this->setExpectedException('\Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException');
77 78 79 80 81 82

        try {
            $this->_conn->insert('owning_table', array('id' => 2, 'constraint_id' => 2));
        } catch (ForeignKeyConstraintViolationException $exception) {
            $this->tearDownForeignKeyConstraintViolationExceptionTest();

83 84 85 86
            throw $exception;
        } catch (\Exception $exception) {
            $this->tearDownForeignKeyConstraintViolationExceptionTest();

87 88
            throw $exception;
        }
89

90 91 92
        $this->tearDownForeignKeyConstraintViolationExceptionTest();
    }

Possum's avatar
Possum committed
93
    public function testForeignKeyConstraintViolationExceptionOnUpdate()
94 95 96
    {
        if ( ! $this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
            $this->markTestSkipped("Only fails on platforms with foreign key constraints.");
97 98
        }

99 100
        $this->setUpForeignKeyConstraintViolationExceptionTest();

101 102 103 104 105 106 107 108
        try {
            $this->_conn->insert("constraint_error_table", array('id' => 1));
            $this->_conn->insert("owning_table", array('id' => 1, 'constraint_id' => 1));
        } catch (\Exception $exception) {
            $this->tearDownForeignKeyConstraintViolationExceptionTest();

            throw $exception;
        }
109 110

        $this->setExpectedException('\Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException');
111 112 113 114 115 116

        try {
            $this->_conn->update('constraint_error_table', array('id' => 2), array('id' => 1));
        } catch (ForeignKeyConstraintViolationException $exception) {
            $this->tearDownForeignKeyConstraintViolationExceptionTest();

117 118 119 120
            throw $exception;
        } catch (\Exception $exception) {
            $this->tearDownForeignKeyConstraintViolationExceptionTest();

121 122
            throw $exception;
        }
123 124 125 126

        $this->tearDownForeignKeyConstraintViolationExceptionTest();
    }

Possum's avatar
Possum committed
127
    public function testForeignKeyConstraintViolationExceptionOnDelete()
128 129 130 131 132 133 134
    {
        if ( ! $this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
            $this->markTestSkipped("Only fails on platforms with foreign key constraints.");
        }

        $this->setUpForeignKeyConstraintViolationExceptionTest();

135 136 137 138 139 140 141 142
        try {
            $this->_conn->insert("constraint_error_table", array('id' => 1));
            $this->_conn->insert("owning_table", array('id' => 1, 'constraint_id' => 1));
        } catch (\Exception $exception) {
            $this->tearDownForeignKeyConstraintViolationExceptionTest();

            throw $exception;
        }
143

144
        $this->setExpectedException('\Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException');
145 146 147 148 149 150

        try {
            $this->_conn->delete('constraint_error_table', array('id' => 1));
        } catch (ForeignKeyConstraintViolationException $exception) {
            $this->tearDownForeignKeyConstraintViolationExceptionTest();

151 152 153 154
            throw $exception;
        } catch (\Exception $exception) {
            $this->tearDownForeignKeyConstraintViolationExceptionTest();

155 156
            throw $exception;
        }
157 158 159 160

        $this->tearDownForeignKeyConstraintViolationExceptionTest();
    }

Possum's avatar
Possum committed
161
    public function testForeignKeyConstraintViolationExceptionOnTruncate()
162 163 164
    {
        $platform = $this->_conn->getDatabasePlatform();

165
        if (!$platform->supportsForeignKeyConstraints()) {
166 167 168 169 170
            $this->markTestSkipped("Only fails on platforms with foreign key constraints.");
        }

        $this->setUpForeignKeyConstraintViolationExceptionTest();

171 172 173 174 175 176 177 178
        try {
            $this->_conn->insert("constraint_error_table", array('id' => 1));
            $this->_conn->insert("owning_table", array('id' => 1, 'constraint_id' => 1));
        } catch (\Exception $exception) {
            $this->tearDownForeignKeyConstraintViolationExceptionTest();

            throw $exception;
        }
179 180

        $this->setExpectedException('\Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException');
181 182 183 184 185 186

        try {
            $this->_conn->executeUpdate($platform->getTruncateTableSQL('constraint_error_table'));
        } catch (ForeignKeyConstraintViolationException $exception) {
            $this->tearDownForeignKeyConstraintViolationExceptionTest();

187 188 189 190
            throw $exception;
        } catch (\Exception $exception) {
            $this->tearDownForeignKeyConstraintViolationExceptionTest();

191 192
            throw $exception;
        }
193 194

        $this->tearDownForeignKeyConstraintViolationExceptionTest();
195
    }
196

197
    public function testNotNullConstraintViolationException()
198 199 200 201 202 203 204 205
    {
        $schema = new \Doctrine\DBAL\Schema\Schema();

        $table = $schema->createTable("notnull_table");
        $table->addColumn('id', 'integer', array());
        $table->addColumn('value', 'integer', array('notnull' => true));
        $table->setPrimaryKey(array('id'));

jeroendedauw's avatar
jeroendedauw committed
206
        foreach ($schema->toSql($this->_conn->getDatabasePlatform()) as $sql) {
207 208 209
            $this->_conn->executeQuery($sql);
        }

210
        $this->setExpectedException('\Doctrine\DBAL\Exception\NotNullConstraintViolationException');
211
        $this->_conn->insert("notnull_table", array('id' => 1, 'value' => null));
212
    }
213

214
    public function testInvalidFieldNameException()
215 216 217
    {
        $schema = new \Doctrine\DBAL\Schema\Schema();

218 219
        $table = $schema->createTable("bad_fieldname_table");
        $table->addColumn('id', 'integer', array());
220

jeroendedauw's avatar
jeroendedauw committed
221
        foreach ($schema->toSql($this->_conn->getDatabasePlatform()) as $sql) {
222 223 224
            $this->_conn->executeQuery($sql);
        }

225
        $this->setExpectedException('\Doctrine\DBAL\Exception\InvalidFieldNameException');
226 227 228 229 230 231 232 233 234 235 236 237 238
        $this->_conn->insert("bad_fieldname_table", array('name' => 5));
    }

    public function testNonUniqueFieldNameException()
    {
        $schema = new \Doctrine\DBAL\Schema\Schema();

        $table = $schema->createTable("ambiguous_list_table");
        $table->addColumn('id', 'integer');

        $table2 = $schema->createTable("ambiguous_list_table_2");
        $table2->addColumn('id', 'integer');

jeroendedauw's avatar
jeroendedauw committed
239
        foreach ($schema->toSql($this->_conn->getDatabasePlatform()) as $sql) {
240 241 242 243
            $this->_conn->executeQuery($sql);
        }

        $sql = 'SELECT id FROM ambiguous_list_table, ambiguous_list_table_2';
244
        $this->setExpectedException('\Doctrine\DBAL\Exception\NonUniqueFieldNameException');
245
        $this->_conn->executeQuery($sql);
246 247
    }

248
    public function testUniqueConstraintViolationException()
249 250 251 252 253 254 255
    {
        $schema = new \Doctrine\DBAL\Schema\Schema();

        $table = $schema->createTable("unique_field_table");
        $table->addColumn('id', 'integer');
        $table->addUniqueIndex(array('id'));

jeroendedauw's avatar
jeroendedauw committed
256
        foreach ($schema->toSql($this->_conn->getDatabasePlatform()) as $sql) {
257 258
            $this->_conn->executeQuery($sql);
        }
259

260
        $this->_conn->insert("unique_field_table", array('id' => 5));
261
        $this->setExpectedException('\Doctrine\DBAL\Exception\UniqueConstraintViolationException');
262
        $this->_conn->insert("unique_field_table", array('id' => 5));
263 264
    }

265 266 267 268 269 270
    public function testSyntaxErrorException()
    {
        $table = new \Doctrine\DBAL\Schema\Table("syntax_error_table");
        $table->addColumn('id', 'integer', array());
        $table->setPrimaryKey(array('id'));

jeroendedauw's avatar
jeroendedauw committed
271
        foreach ($this->_conn->getDatabasePlatform()->getCreateTableSQL($table) as $sql) {
272 273 274 275
            $this->_conn->executeQuery($sql);
        }

        $sql = 'SELECT id FRO syntax_error_table';
276
        $this->setExpectedException('\Doctrine\DBAL\Exception\SyntaxErrorException');
277 278 279
        $this->_conn->executeQuery($sql);
    }

280 281 282
    /**
     * @dataProvider getSqLiteOpenConnection
     */
283
    public function testConnectionExceptionSqLite($mode, $exceptionClass)
284 285 286 287 288 289 290 291
    {
        if ($this->_conn->getDatabasePlatform()->getName() != 'sqlite') {
            $this->markTestSkipped("Only fails this way on sqlite");
        }

        $filename = sprintf('%s/%s', sys_get_temp_dir(), 'doctrine_failed_connection.db');

        if (file_exists($filename)) {
292 293
            unlink($filename);
        }
294 295 296 297 298

        touch($filename);
        chmod($filename, $mode);

        $params = array(
299 300 301
            'driver' => 'pdo_sqlite',
            'path'   => $filename,
        );
302 303 304 305 306 307
        $conn = \Doctrine\DBAL\DriverManager::getConnection($params);

        $schema = new \Doctrine\DBAL\Schema\Schema();
        $table = $schema->createTable("no_connection");
        $table->addColumn('id', 'integer');

308
        $this->setExpectedException($exceptionClass);
jeroendedauw's avatar
jeroendedauw committed
309
        foreach ($schema->toSql($conn->getDatabasePlatform()) as $sql) {
310 311
            $conn->executeQuery($sql);
        }
312 313
    }

314 315 316
    public function getSqLiteOpenConnection()
    {
        return array(
317 318
            array(0000, '\Doctrine\DBAL\Exception\ConnectionException'),
            array(0444, '\Doctrine\DBAL\Exception\ReadOnlyException'),
319
        );
320 321
    }

322 323 324
    /**
     * @dataProvider getConnectionParams
     */
325
    public function testConnectionException($params)
326 327 328 329 330
    {
        if ($this->_conn->getDatabasePlatform()->getName() == 'sqlite') {
            $this->markTestSkipped("Only skipped if platform is not sqlite");
        }

331 332 333 334
        if ($this->_conn->getDatabasePlatform()->getName() == 'drizzle') {
            $this->markTestSkipped("Drizzle does not always support authentication");
        }

335
        if ($this->_conn->getDatabasePlatform()->getName() == 'postgresql' && isset($params['password'])) {
Benjamin Eberlei's avatar
Benjamin Eberlei committed
336 337 338
            $this->markTestSkipped("Does not work on Travis");
        }

339 340 341 342 343 344 345 346 347
        $defaultParams = $this->_conn->getParams();
        $params = array_merge($defaultParams, $params);

        $conn = \Doctrine\DBAL\DriverManager::getConnection($params);

        $schema = new \Doctrine\DBAL\Schema\Schema();
        $table = $schema->createTable("no_connection");
        $table->addColumn('id', 'integer');

348
        $this->setExpectedException('Doctrine\DBAL\Exception\ConnectionException');
349

jeroendedauw's avatar
jeroendedauw committed
350
        foreach ($schema->toSql($conn->getDatabasePlatform()) as $sql) {
351
            $conn->executeQuery($sql);
352
        }
353 354 355 356
    }

    public function getConnectionParams()
    {
357
        return array(
358 359 360
            array(array('user' => 'not_existing')),
            array(array('password' => 'really_not')),
            array(array('host' => 'localnope')),
361
        );
362
    }
363

364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
    private function setUpForeignKeyConstraintViolationExceptionTest()
    {
        $schemaManager = $this->_conn->getSchemaManager();

        $table = new Table("constraint_error_table");
        $table->addColumn('id', 'integer', array());
        $table->setPrimaryKey(array('id'));

        $owningTable = new Table("owning_table");
        $owningTable->addColumn('id', 'integer', array());
        $owningTable->addColumn('constraint_id', 'integer', array());
        $owningTable->setPrimaryKey(array('id'));
        $owningTable->addForeignKeyConstraint($table, array('constraint_id'), array('id'));

        $schemaManager->createTable($table);
        $schemaManager->createTable($owningTable);
    }

    private function tearDownForeignKeyConstraintViolationExceptionTest()
    {
        $schemaManager = $this->_conn->getSchemaManager();

        $schemaManager->dropTable('owning_table');
        $schemaManager->dropTable('constraint_error_table');
    }
}