Removed the logic of using BLOB columns for BINARY type of fields

parent 69b8cefa
......@@ -102,6 +102,12 @@ The Drizzle project is abandoned and is therefore not supported by Doctrine DBAL
- `Configuration::getSQLLogger()` does not return `null` anymore, but a `NullLogger` implementation.
- `Configuration::setSQLLogger()` does not allow `null` anymore.
## BC BREAK: Changes to handling binary fields
- Binary fields whose length exceeds the maximum field size on a given platform are no longer represented as `BLOB`s.
Use binary fields of a size which fits all target platforms, or use blob explicitly instead.
- Binary fields are no longer represented as streams in PHP. They are represented as strings.
# Upgrade to 2.9
## Deprecated `Configuration::getFilterSchemaAssetsExpression()`, `::setFilterSchemaAssetsExpression()` and `AbstractSchemaManager::getFilterSchemaAssetsExpression()`.
......
......@@ -28,7 +28,6 @@ use Doctrine\DBAL\TransactionIsolationLevel;
use Doctrine\DBAL\Types;
use Doctrine\DBAL\Types\Type;
use InvalidArgumentException;
use const E_USER_DEPRECATED;
use function addcslashes;
use function array_map;
use function array_merge;
......@@ -53,7 +52,6 @@ use function strlen;
use function strpos;
use function strtolower;
use function strtoupper;
use function trigger_error;
/**
* Base class for all DatabasePlatforms. The DatabasePlatforms are the central
......@@ -281,20 +279,6 @@ abstract class AbstractPlatform
$fixed = $field['fixed'] ?? false;
$maxLength = $this->getBinaryMaxLength();
if ($field['length'] > $maxLength) {
if ($maxLength > 0) {
@trigger_error(sprintf(
'Binary field length %d is greater than supported by the platform (%d). Reduce the field length or use a BLOB field instead.',
$field['length'],
$maxLength
), E_USER_DEPRECATED);
}
return $this->getBlobTypeDeclarationSQL($field);
}
return $this->getBinaryTypeDeclarationSQLSnippet($field['length'], $fixed);
}
......
......@@ -4,11 +4,9 @@ namespace Doctrine\DBAL\Types;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use function fopen;
use function fseek;
use function fwrite;
use function is_resource;
use function is_string;
use function stream_get_contents;
/**
* Type that maps ab SQL BINARY/VARBINARY to a PHP resource stream.
......@@ -32,14 +30,11 @@ class BinaryType extends Type
return null;
}
if (is_string($value)) {
$fp = fopen('php://temp', 'rb+');
fwrite($fp, $value);
fseek($fp, 0);
$value = $fp;
if (is_resource($value)) {
$value = stream_get_contents($value);
}
if (! is_resource($value)) {
if (! is_string($value)) {
throw ConversionException::conversionFailed($value, self::BINARY);
}
......
......@@ -7,11 +7,10 @@ namespace Doctrine\Tests\DBAL\Functional\Types;
use Doctrine\DBAL\Driver\IBMDB2\DB2Driver;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DbalFunctionalTestCase;
use function is_resource;
use function random_bytes;
use function str_replace;
use function stream_get_contents;
class BinaryTest extends DbalFunctionalTestCase
{
......@@ -74,14 +73,6 @@ class BinaryTest extends DbalFunctionalTestCase
[ParameterType::BINARY]
);
// Currently, `BinaryType` mistakenly converts string values fetched from the DB to a stream.
// It should be the opposite. Streams should be used to represent large objects, not binary
// strings. The confusion comes from the PostgreSQL's type system where binary strings and
// large objects are represented by the same BYTEA type
if (is_resource($value)) {
$value = stream_get_contents($value);
}
return $value;
return Type::getType('binary')->convertToPHPValue($value, $this->connection->getDatabasePlatform());
}
}
......@@ -509,27 +509,21 @@ abstract class AbstractMySQLPlatformTestCase extends AbstractPlatformTestCase
self::assertSame('VARBINARY(255)', $this->platform->getBinaryTypeDeclarationSQL([]));
self::assertSame('VARBINARY(255)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 0]));
self::assertSame('VARBINARY(65535)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 65535]));
self::assertSame('VARBINARY(65536)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 65536]));
self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
self::assertSame('BINARY(65535)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 65535]));
}
/**
* @group legacy
* @expectedDeprecation Binary field length 65536 is greater than supported by the platform (65535). Reduce the field length or use a BLOB field instead.
* @expectedDeprecation Binary field length 16777215 is greater than supported by the platform (65535). Reduce the field length or use a BLOB field instead.
* @expectedDeprecation Binary field length 16777216 is greater than supported by the platform (65535). Reduce the field length or use a BLOB field instead.
*/
public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL()
{
self::assertSame('MEDIUMBLOB', $this->platform->getBinaryTypeDeclarationSQL(['length' => 65536]));
self::assertSame('MEDIUMBLOB', $this->platform->getBinaryTypeDeclarationSQL(['length' => 16777215]));
self::assertSame('LONGBLOB', $this->platform->getBinaryTypeDeclarationSQL(['length' => 16777216]));
self::assertSame('MEDIUMBLOB', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 65536]));
self::assertSame('MEDIUMBLOB', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 16777215]));
self::assertSame('LONGBLOB', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 16777216]));
self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL([
'fixed' => true,
'length' => 0,
]));
self::assertSame('BINARY(65535)', $this->platform->getBinaryTypeDeclarationSQL([
'fixed' => true,
'length' => 65535,
]));
self::assertSame('BINARY(65536)', $this->platform->getBinaryTypeDeclarationSQL([
'fixed' => true,
'length' => 65536,
]));
}
public function testDoesNotPropagateForeignKeyCreationForNonSupportingEngines()
......
......@@ -848,11 +848,6 @@ abstract class AbstractPlatformTestCase extends DbalTestCase
$this->platform->getBinaryTypeDeclarationSQL([]);
}
public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL()
{
$this->markTestSkipped('Not applicable to the platform');
}
/**
* @group DBAL-553
*/
......
......@@ -985,18 +985,14 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
self::assertSame('VARBINARY(8000)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 8000]));
self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
self::assertSame('BINARY(8000)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 8000]));
}
/**
* @group legacy
* @expectedDeprecation Binary field length 8001 is greater than supported by the platform (8000). Reduce the field length or use a BLOB field instead.
*/
public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL()
{
self::assertSame('VARBINARY(MAX)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 8001]));
self::assertSame('VARBINARY(MAX)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 8001]));
self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL([
'fixed' => true,
'length' => 0,
]));
self::assertSame('BINARY(8000)', $this->platform->getBinaryTypeDeclarationSQL([
'fixed' => true,
'length' => 8000,
]));
}
/**
......
......@@ -415,16 +415,6 @@ class DB2PlatformTest extends AbstractPlatformTestCase
self::assertSame('CHAR(254) FOR BIT DATA', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
}
/**
* @group legacy
* @expectedDeprecation Binary field length 32705 is greater than supported by the platform (32704). Reduce the field length or use a BLOB field instead.
*/
public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL()
{
self::assertSame('BLOB(1M)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 32705]));
self::assertSame('BLOB(1M)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 32705]));
}
/**
* @group DBAL-234
*/
......
......@@ -481,18 +481,14 @@ class OraclePlatformTest extends AbstractPlatformTestCase
self::assertSame('RAW(2000)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 2000]));
self::assertSame('RAW(255)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
self::assertSame('RAW(2000)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
self::assertSame('RAW(2000)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 2000]));
}
/**
* @group legacy
* @expectedDeprecation Binary field length 2001 is greater than supported by the platform (2000). Reduce the field length or use a BLOB field instead.
*/
public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL()
{
self::assertSame('BLOB', $this->platform->getBinaryTypeDeclarationSQL(['length' => 2001]));
self::assertSame('BLOB', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 2001]));
self::assertSame('RAW(2000)', $this->platform->getBinaryTypeDeclarationSQL([
'fixed' => true,
'length' => 0,
]));
self::assertSame('RAW(2000)', $this->platform->getBinaryTypeDeclarationSQL([
'fixed' => true,
'length' => 2000,
]));
}
public function testDoesNotPropagateUnnecessaryTableAlterationOnBinaryType()
......
......@@ -926,18 +926,14 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase
self::assertSame('VARBINARY(32767)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 32767]));
self::assertSame('BINARY(1)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
self::assertSame('BINARY(1)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
self::assertSame('BINARY(32767)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 32767]));
}
/**
* @group legacy
* @expectedDeprecation Binary field length 32768 is greater than supported by the platform (32767). Reduce the field length or use a BLOB field instead.
*/
public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL()
{
self::assertSame('LONG BINARY', $this->platform->getBinaryTypeDeclarationSQL(['length' => 32768]));
self::assertSame('LONG BINARY', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 32768]));
self::assertSame('BINARY(1)', $this->platform->getBinaryTypeDeclarationSQL([
'fixed' => true,
'length' => 0,
]));
self::assertSame('BINARY(32767)', $this->platform->getBinaryTypeDeclarationSQL([
'fixed' => true,
'length' => 32767,
]));
}
/**
......
......@@ -7,9 +7,11 @@ use Doctrine\DBAL\Types\BinaryType;
use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DBAL\Mocks\MockPlatform;
use Doctrine\Tests\DbalTestCase;
use function array_map;
use function base64_encode;
use function fopen;
use function stream_get_contents;
use function implode;
use function range;
class BinaryTest extends DbalTestCase
{
......@@ -50,11 +52,10 @@ class BinaryTest extends DbalTestCase
public function testBinaryStringConvertsToPHPValue()
{
$databaseValue = 'binary string';
$databaseValue = $this->getBinaryString();
$phpValue = $this->type->convertToPHPValue($databaseValue, $this->platform);
self::assertInternalType('resource', $phpValue);
self::assertEquals($databaseValue, stream_get_contents($phpValue));
self::assertSame($databaseValue, $phpValue);
}
public function testBinaryResourceConvertsToPHPValue()
......@@ -62,7 +63,15 @@ class BinaryTest extends DbalTestCase
$databaseValue = fopen('data://text/plain;base64,' . base64_encode('binary string'), 'r');
$phpValue = $this->type->convertToPHPValue($databaseValue, $this->platform);
self::assertSame($databaseValue, $phpValue);
self::assertSame('binary string', $phpValue);
}
/**
* Creates a binary string containing all possible byte values.
*/
private function getBinaryString() : string
{
return implode(array_map('chr', range(0, 255)));
}
/**
......
......@@ -6,10 +6,6 @@ use Doctrine\DBAL\Types\BlobType;
use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DBAL\Mocks\MockPlatform;
use Doctrine\Tests\DbalTestCase;
use function base64_encode;
use function chr;
use function fopen;
use function stream_get_contents;
class BlobTest extends DbalTestCase
{
......@@ -32,37 +28,4 @@ class BlobTest extends DbalTestCase
{
self::assertNull($this->type->convertToPHPValue(null, $this->platform));
}
public function testBinaryStringConvertsToPHPValue()
{
$databaseValue = $this->getBinaryString();
$phpValue = $this->type->convertToPHPValue($databaseValue, $this->platform);
self::assertInternalType('resource', $phpValue);
self::assertSame($databaseValue, stream_get_contents($phpValue));
}
public function testBinaryResourceConvertsToPHPValue()
{
$databaseValue = fopen('data://text/plain;base64,' . base64_encode($this->getBinaryString()), 'r');
$phpValue = $this->type->convertToPHPValue($databaseValue, $this->platform);
self::assertSame($databaseValue, $phpValue);
}
/**
* Creates a binary string containing all possible byte values.
*
* @return string
*/
private function getBinaryString()
{
$string = '';
for ($i = 0; $i < 256; $i++) {
$string .= chr($i);
}
return $string;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment