BlobTest.php 4.88 KB
Newer Older
1 2 3 4
<?php

namespace Doctrine\Tests\DBAL\Functional;

5
use Doctrine\DBAL\Driver\OCI8\Driver as OCI8Driver;
6
use Doctrine\DBAL\FetchMode;
7
use Doctrine\DBAL\ParameterType;
Sergei Morozov's avatar
Sergei Morozov committed
8
use Doctrine\DBAL\Schema\AbstractSchemaManager;
Sergei Morozov's avatar
Sergei Morozov committed
9
use Doctrine\DBAL\Schema\Table;
10
use Doctrine\DBAL\Types\Type;
Sergei Morozov's avatar
Sergei Morozov committed
11
use Doctrine\Tests\DbalFunctionalTestCase;
12 13
use function fopen;
use function str_repeat;
14
use function stream_get_contents;
15 16 17 18

/**
 * @group DBAL-6
 */
Sergei Morozov's avatar
Sergei Morozov committed
19
class BlobTest extends DbalFunctionalTestCase
20
{
21
    protected function setUp()
22 23 24
    {
        parent::setUp();

Sergei Morozov's avatar
Sergei Morozov committed
25
        /** @var AbstractSchemaManager $sm */
Sergei Morozov's avatar
Sergei Morozov committed
26 27 28 29 30
        $table = new Table('blob_table');
        $table->addColumn('id', 'integer');
        $table->addColumn('clobfield', 'text');
        $table->addColumn('blobfield', 'blob');
        $table->setPrimaryKey(['id']);
31

Sergei Morozov's avatar
Sergei Morozov committed
32
        $sm = $this->connection->getSchemaManager();
Sergei Morozov's avatar
Sergei Morozov committed
33
        $sm->dropAndCreateTable($table);
34 35 36 37
    }

    public function testInsert()
    {
Sergei Morozov's avatar
Sergei Morozov committed
38
        $ret = $this->connection->insert('blob_table', [
39 40 41 42 43 44 45 46 47
            'id'          => 1,
            'clobfield'   => 'test',
            'blobfield'   => 'test',
        ], [
            ParameterType::INTEGER,
            ParameterType::STRING,
            ParameterType::LARGE_OBJECT,
        ]);

48
        self::assertEquals(1, $ret);
49 50
    }

51 52
    public function testInsertProcessesStream()
    {
53 54 55
        // https://github.com/doctrine/dbal/issues/3290
        if ($this->connection->getDriver() instanceof OCI8Driver) {
            $this->markTestIncomplete('The oci8 driver does not support stream resources as parameters');
56 57 58
        }

        $longBlob = str_repeat('x', 4 * 8192); // send 4 chunks
Sergei Morozov's avatar
Sergei Morozov committed
59
        $this->connection->insert('blob_table', [
60 61 62 63 64 65 66 67 68 69 70 71
            'id'        => 1,
            'clobfield' => 'ignored',
            'blobfield' => fopen('data://text/plain,' . $longBlob, 'r'),
        ], [
            ParameterType::INTEGER,
            ParameterType::STRING,
            ParameterType::LARGE_OBJECT,
        ]);

        $this->assertBlobContains($longBlob);
    }

72 73
    public function testSelect()
    {
Sergei Morozov's avatar
Sergei Morozov committed
74
        $this->connection->insert('blob_table', [
Sergei Morozov's avatar
Sergei Morozov committed
75 76 77 78 79 80 81 82
            'id'          => 1,
            'clobfield'   => 'test',
            'blobfield'   => 'test',
        ], [
            ParameterType::INTEGER,
            ParameterType::STRING,
            ParameterType::LARGE_OBJECT,
        ]);
83 84 85 86 87 88

        $this->assertBlobContains('test');
    }

    public function testUpdate()
    {
Sergei Morozov's avatar
Sergei Morozov committed
89
        $this->connection->insert('blob_table', [
Sergei Morozov's avatar
Sergei Morozov committed
90 91 92 93 94 95 96 97
            'id' => 1,
            'clobfield' => 'test',
            'blobfield' => 'test',
        ], [
            ParameterType::INTEGER,
            ParameterType::STRING,
            ParameterType::LARGE_OBJECT,
        ]);
98

Sergei Morozov's avatar
Sergei Morozov committed
99
        $this->connection->update('blob_table', ['blobfield' => 'test2'], ['id' => 1], [
Sergei Morozov's avatar
Sergei Morozov committed
100 101 102
            ParameterType::LARGE_OBJECT,
            ParameterType::INTEGER,
        ]);
103 104 105 106

        $this->assertBlobContains('test2');
    }

107 108
    public function testUpdateProcessesStream()
    {
109 110 111
        // https://github.com/doctrine/dbal/issues/3290
        if ($this->connection->getDriver() instanceof OCI8Driver) {
            $this->markTestIncomplete('The oci8 driver does not support stream resources as parameters');
112 113
        }

Sergei Morozov's avatar
Sergei Morozov committed
114
        $this->connection->insert('blob_table', [
115 116 117 118 119 120 121 122 123
            'id'          => 1,
            'clobfield'   => 'ignored',
            'blobfield'   => 'test',
        ], [
            ParameterType::INTEGER,
            ParameterType::STRING,
            ParameterType::LARGE_OBJECT,
        ]);

Sergei Morozov's avatar
Sergei Morozov committed
124
        $this->connection->update('blob_table', [
125 126 127 128 129 130 131 132 133 134 135 136
            'id'          => 1,
            'blobfield'   => fopen('data://text/plain,test2', 'r'),
        ], ['id' => 1], [
            ParameterType::INTEGER,
            ParameterType::LARGE_OBJECT,
        ]);

        $this->assertBlobContains('test2');
    }

    public function testBindParamProcessesStream()
    {
137 138
        if ($this->connection->getDriver() instanceof OCI8Driver) {
            $this->markTestIncomplete('The oci8 driver does not support stream resources as parameters');
139 140
        }

Sergei Morozov's avatar
Sergei Morozov committed
141
        $stmt = $this->connection->prepare("INSERT INTO blob_table(id, clobfield, blobfield) VALUES (1, 'ignored', ?)");
142 143 144 145 146 147 148 149 150 151 152 153

        $stream = null;
        $stmt->bindParam(1, $stream, ParameterType::LARGE_OBJECT);

        // Bind param does late binding (bind by reference), so create the stream only now:
        $stream = fopen('data://text/plain,test', 'r');

        $stmt->execute();

        $this->assertBlobContains('test');
    }

154 155
    private function assertBlobContains($text)
    {
Sergei Morozov's avatar
Sergei Morozov committed
156
        $rows = $this->connection->query('SELECT blobfield FROM blob_table')->fetchAll(FetchMode::COLUMN);
157

Gabriel Caruso's avatar
Gabriel Caruso committed
158
        self::assertCount(1, $rows);
159

Sergei Morozov's avatar
Sergei Morozov committed
160
        $blobValue = Type::getType('blob')->convertToPHPValue($rows[0], $this->connection->getDatabasePlatform());
161

162 163
        self::assertInternalType('resource', $blobValue);
        self::assertEquals($text, stream_get_contents($blobValue));
164
    }
165
}