Commit d3f94a52 authored by Steve Müller's avatar Steve Müller

introduce BinaryType

parent 8fe74105
......@@ -20,6 +20,7 @@ vendors:
- BigInt
- String (string with maximum length, for example 255)
- Text (strings without maximum length)
- Binary (binary string with maximum length, for example 255)
- Decimal (restricted floats, *NOTE* Only works with a setlocale()
configuration that uses decimal points!)
- Boolean
......
......@@ -231,6 +231,28 @@ abstract class AbstractPlatform
return $this->getVarcharTypeDeclarationSQLSnippet($field['length'], $fixed);
}
/**
* Returns the SQL snippet used to declare a BINARY/VARBINARY column type.
*
* @param array $field The column definition.
*
* @return string
*/
public function getBinaryTypeDeclarationSQL(array $field)
{
if ( ! isset($field['length'])) {
$field['length'] = $this->getBinaryDefaultLength();
}
$fixed = isset($field['fixed']) ? $field['fixed'] : false;
if ($field['length'] > $this->getBinaryMaxLength()) {
return $this->getBlobTypeDeclarationSQL($field);
}
return $this->getBinaryTypeDeclarationSQLSnippet($field['length'], $fixed);
}
/**
* Returns the SQL snippet to declare a GUID/UUID field.
*
......@@ -259,6 +281,21 @@ abstract class AbstractPlatform
throw DBALException::notSupported('VARCHARs not supported by Platform.');
}
/**
* Returns the SQL snippet used to declare a BINARY/VARBINARY column type.
*
* @param integer $length The length of the column.
* @param boolean $fixed Whether the column length is fixed.
*
* @return string
*
* @throws \Doctrine\DBAL\DBALException If not supported on this platform.
*/
protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
{
throw DBALException::notSupported('BINARY/VARBINARY column types are not supported by this platform.');
}
/**
* Returns the SQL snippet used to declare a CLOB column type.
*
......@@ -478,6 +515,26 @@ abstract class AbstractPlatform
return 255;
}
/**
* Gets the maximum length of a binary field.
*
* @return integer
*/
public function getBinaryMaxLength()
{
return 4000;
}
/**
* Gets the default length of a binary field.
*
* @return integer
*/
public function getBinaryDefaultLength()
{
return 255;
}
/**
* Gets all SQL wildcard characters of the platform.
*
......
......@@ -25,6 +25,22 @@ use Doctrine\DBAL\Schema\TableDiff;
class DB2Platform extends AbstractPlatform
{
/**
* {@inheritdoc}
*/
public function getBinaryMaxLength()
{
return 32704;
}
/**
* {@inheritdoc}
*/
public function getBinaryDefaultLength()
{
return 1;
}
/**
* {@inheritDoc}
*/
......@@ -47,6 +63,8 @@ class DB2Platform extends AbstractPlatform
'date' => 'date',
'varchar' => 'string',
'character' => 'string',
'varbinary' => 'binary',
'binary' => 'binary',
'clob' => 'text',
'blob' => 'blob',
'decimal' => 'decimal',
......@@ -65,6 +83,14 @@ class DB2Platform extends AbstractPlatform
: ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
}
/**
* {@inheritdoc}
*/
protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
{
return $fixed ? 'BINARY(' . ($length ?: 255) . ')' : 'VARBINARY(' . ($length ?: 255) . ')';
}
/**
* {@inheritDoc}
*/
......
......@@ -23,6 +23,7 @@ use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\BinaryType;
/**
* Drizzle platform
......@@ -165,6 +166,14 @@ class DrizzlePlatform extends AbstractPlatform
return $length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)';
}
/**
* {@inheritdoc}
*/
protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
{
return 'VARBINARY(' . ($length ?: 255) . ')';
}
/**
* {@inheritDoc}
*/
......@@ -173,8 +182,9 @@ class DrizzlePlatform extends AbstractPlatform
$this->doctrineTypeMapping = array(
'boolean' => 'boolean',
'varchar' => 'string',
'varbinary' => 'binary',
'integer' => 'integer',
'blob' => 'text',
'blob' => 'blob',
'decimal' => 'decimal',
'datetime' => 'datetime',
'date' => 'date',
......@@ -425,6 +435,17 @@ class DrizzlePlatform extends AbstractPlatform
/* @var $columnDiff \Doctrine\DBAL\Schema\ColumnDiff */
$column = $columnDiff->column;
$columnArray = $column->toArray();
// Do not generate column alteration clause if type is binary and only fixed property has changed.
// Drizzle only supports binary type columns with variable length.
// Avoids unnecessary table alteration statements.
if ($column['type'] instanceof BinaryType &&
$columnDiff->hasChanged('fixed') &&
count($columnDiff->changedProperties) === 1
) {
continue;
}
$columnArray['comment'] = $this->getColumnComment($column);
$queryParts[] = 'CHANGE ' . ($columnDiff->getOldColumnName()->getQuotedName($this)) . ' '
. $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
......
......@@ -252,6 +252,14 @@ class MySqlPlatform extends AbstractPlatform
: ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
}
/**
* {@inheritdoc}
*/
protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
{
return $fixed ? 'BINARY(' . ($length ?: 255) . ')' : 'VARBINARY(' . ($length ?: 255) . ')';
}
/**
* Gets the SQL snippet used to declare a CLOB column type.
* TINYTEXT : 2 ^ 8 - 1 = 255
......@@ -809,8 +817,8 @@ class MySqlPlatform extends AbstractPlatform
'blob' => 'blob',
'mediumblob' => 'blob',
'tinyblob' => 'blob',
'binary' => 'blob',
'varbinary' => 'blob',
'binary' => 'binary',
'varbinary' => 'binary',
'set' => 'simple_array',
);
}
......@@ -823,6 +831,14 @@ class MySqlPlatform extends AbstractPlatform
return 65535;
}
/**
* {@inheritdoc}
*/
public function getBinaryMaxLength()
{
return 65535;
}
/**
* {@inheritDoc}
*/
......
......@@ -25,6 +25,7 @@ use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Types\BinaryType;
/**
* OraclePlatform.
......@@ -335,6 +336,22 @@ class OraclePlatform extends AbstractPlatform
: ($length ? 'VARCHAR2(' . $length . ')' : 'VARCHAR2(4000)');
}
/**
* {@inheritdoc}
*/
protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
{
return 'RAW(' . ($length ?: $this->getBinaryMaxLength()) . ')';
}
/**
* {@inheritdoc}
*/
public function getBinaryMaxLength()
{
return 2000;
}
/**
* {@inheritDoc}
*/
......@@ -644,7 +661,19 @@ LEFT JOIN user_cons_columns r_cols
continue;
}
/* @var $columnDiff \Doctrine\DBAL\Schema\ColumnDiff */
$column = $columnDiff->column;
// Do not generate column alteration clause if type is binary and only fixed property has changed.
// Oracle only supports binary type columns with variable length.
// Avoids unnecessary table alteration statements.
if ($column->getType() instanceof BinaryType &&
$columnDiff->hasChanged('fixed') &&
count($columnDiff->changedProperties) === 1
) {
continue;
}
$columnHasChangedComment = $columnDiff->hasChanged('comment');
/**
......@@ -903,8 +932,8 @@ LEFT JOIN user_cons_columns r_cols
'long' => 'string',
'clob' => 'text',
'nclob' => 'text',
'raw' => 'text',
'long raw' => 'text',
'raw' => 'binary',
'long raw' => 'blob',
'rowid' => 'string',
'urowid' => 'string',
'blob' => 'blob',
......
......@@ -19,7 +19,11 @@
namespace Doctrine\DBAL\Platforms;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\ColumnDiff;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\Types\BinaryType;
use Doctrine\DBAL\Types\BlobType;
/**
* PostgreSqlPlatform.
......@@ -458,6 +462,10 @@ class PostgreSqlPlatform extends AbstractPlatform
continue;
}
if ($this->isUnchangedBinaryColumn($columnDiff)) {
continue;
}
$oldColumnName = $columnDiff->getOldColumnName()->getQuotedName($this);
$column = $columnDiff->column;
......@@ -533,6 +541,47 @@ class PostgreSqlPlatform extends AbstractPlatform
return array_merge($sql, $tableSql, $columnSql);
}
/**
* Checks whether a given column diff is a logically unchanged binary type column.
*
* Used to determine whether a column alteration for a binary type column can be skipped.
* Doctrine's {@link \Doctrine\DBAL\Types\BinaryType} and {@link \Doctrine\DBAL\Types\BlobType}
* are mapped to the same database column type on this platform as this platform
* does not have a native VARBINARY/BINARY column type. Therefore the {@link \Doctrine\DBAL\Schema\Comparator}
* might detect differences for binary type columns which do not have to be propagated
* to database as there actually is no difference at database level.
*
* @param ColumnDiff $columnDiff The column diff to check against.
*
* @return boolean True if the given column diff is an unchanged binary type column, false otherwise.
*/
private function isUnchangedBinaryColumn(ColumnDiff $columnDiff)
{
$columnType = $columnDiff->column->getType();
if ( ! $columnType instanceof BinaryType && ! $columnType instanceof BlobType) {
return false;
}
$fromColumn = $columnDiff->fromColumn instanceof Column ? $columnDiff->fromColumn : null;
if ($fromColumn) {
$fromColumnType = $fromColumn->getType();
if ( ! $fromColumnType instanceof BinaryType && ! $fromColumnType instanceof BlobType) {
return false;
}
return count(array_diff($columnDiff->changedProperties, array('type', 'length', 'fixed'))) === 0;
}
if ($columnDiff->hasChanged('type')) {
return false;
}
return count(array_diff($columnDiff->changedProperties, array('length', 'fixed'))) === 0;
}
/**
* {@inheritdoc}
*/
......@@ -792,6 +841,14 @@ class PostgreSqlPlatform extends AbstractPlatform
: ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
}
/**
* {@inheritdoc}
*/
protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
{
return 'BYTEA';
}
/**
* {@inheritDoc}
*/
......@@ -905,6 +962,22 @@ class PostgreSqlPlatform extends AbstractPlatform
return 65535;
}
/**
* {@inheritdoc}
*/
public function getBinaryMaxLength()
{
return 0;
}
/**
* {@inheritdoc}
*/
public function getBinaryDefaultLength()
{
return 0;
}
/**
* {@inheritDoc}
*/
......
......@@ -307,6 +307,22 @@ class SQLAnywherePlatform extends AbstractPlatform
return $this->_getCommonIntegerTypeDeclarationSQL($columnDef);
}
/**
* {@inheritdoc}
*/
public function getBinaryDefaultLength()
{
return 1;
}
/**
* {@inheritdoc}
*/
public function getBinaryMaxLength()
{
return 32767;
}
/**
* {@inheritdoc}
*/
......@@ -1319,6 +1335,16 @@ class SQLAnywherePlatform extends AbstractPlatform
return $sql;
}
/**
* {@inheritdoc}
*/
protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
{
return $fixed
? 'BINARY(' . ($length ?: $this->getBinaryDefaultLength()) . ')'
: 'VARBINARY(' . ($length ?: $this->getBinaryDefaultLength()) . ')';
}
/**
* Returns the SQL snippet for creating a table constraint.
*
......@@ -1447,11 +1473,11 @@ class SQLAnywherePlatform extends AbstractPlatform
'smalldatetime' => 'datetime',
'time' => 'time',
'timestamp' => 'datetime',
'binary' => 'blob',
'binary' => 'binary',
'image' => 'blob',
'long binary' => 'blob',
'uniqueidentifier' => 'guid',
'varbinary' => 'blob',
'varbinary' => 'binary',
);
}
}
......@@ -1029,6 +1029,22 @@ class SQLServerPlatform extends AbstractPlatform
return $fixed ? ($length ? 'NCHAR(' . $length . ')' : 'CHAR(255)') : ($length ? 'NVARCHAR(' . $length . ')' : 'NVARCHAR(255)');
}
/**
* {@inheritdoc}
*/
protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
{
return $fixed ? 'BINARY(' . ($length ?: 255) . ')' : 'VARBINARY(' . ($length ?: 255) . ')';
}
/**
* {@inheritdoc}
*/
public function getBinaryMaxLength()
{
return 8000;
}
/**
* {@inheritDoc}
*/
......@@ -1258,8 +1274,8 @@ class SQLServerPlatform extends AbstractPlatform
'nchar' => 'string',
'nvarchar' => 'string',
'ntext' => 'text',
'binary' => 'blob',
'varbinary' => 'blob',
'binary' => 'binary',
'varbinary' => 'binary',
'image' => 'blob',
'uniqueidentifier' => 'guid',
);
......
......@@ -361,6 +361,30 @@ class SqlitePlatform extends AbstractPlatform
: ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
}
/**
* {@inheritdoc}
*/
protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
{
return 'BLOB';
}
/**
* {@inheritdoc}
*/
public function getBinaryMaxLength()
{
return 0;
}
/**
* {@inheritdoc}
*/
public function getBinaryDefaultLength()
{
return 0;
}
/**
* {@inheritDoc}
*/
......
......@@ -385,7 +385,11 @@ class Comparator
$changedProperties[] = 'unsigned';
}
if ($column1->getType() instanceof \Doctrine\DBAL\Types\StringType) {
$column1Type = $column1->getType();
if ($column1Type instanceof \Doctrine\DBAL\Types\StringType ||
$column1Type instanceof \Doctrine\DBAL\Types\BinaryType
) {
// check if value of length is set at all, default value assumed otherwise.
$length1 = $column1->getLength() ?: 255;
$length2 = $column2->getLength() ?: 255;
......
......@@ -128,6 +128,7 @@ class MySqlSchemaManager extends AbstractSchemaManager
switch ($dbType) {
case 'char':
case 'binary':
$fixed = true;
break;
case 'float':
......
......@@ -79,19 +79,14 @@ class SQLServerSchemaManager extends AbstractSchemaManager
break;
}
if ('char' === $dbType || 'nchar' === $dbType || 'binary' === $dbType) {
$fixed = true;
}
$type = $this->_platform->getDoctrineTypeMapping($dbType);
$type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type);
$tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type);
switch ($type) {
case 'char':
$fixed = true;
break;
case 'text':
$fixed = false;
break;
}
$options = array(
'length' => ($length == 0 || !in_array($type, array('text', 'string'))) ? null : $length,
'unsigned' => false,
......
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Types;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* Type that maps ab SQL BINARY/VARBINARY to a PHP resource stream.
*
* @author Steve Müller <st.mueller@dzh-online.de>
* @since 2.5
*/
class BinaryType extends Type
{
/**
* {@inheritdoc}
*/
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return $platform->getBinaryTypeDeclarationSQL($fieldDeclaration);
}
/**
* {@inheritdoc}
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if (null === $value) {
return null;
}
if (is_string($value)) {
$value = fopen('data://text/plain;base64,' . base64_encode($value), 'r');
}
if ( ! is_resource($value)) {
throw ConversionException::conversionFailed($value, self::BINARY);
}
return $value;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return Type::BINARY;
}
/**
* {@inheritdoc}
*/
public function getBindingType()
{
return \PDO::PARAM_LOB;
}
}
......@@ -48,6 +48,7 @@ abstract class Type
const SMALLINT = 'smallint';
const STRING = 'string';
const TEXT = 'text';
const BINARY = 'binary';
const BLOB = 'blob';
const FLOAT = 'float';
const GUID = 'guid';
......@@ -81,6 +82,7 @@ abstract class Type
self::TIME => 'Doctrine\DBAL\Types\TimeType',
self::DECIMAL => 'Doctrine\DBAL\Types\DecimalType',
self::FLOAT => 'Doctrine\DBAL\Types\FloatType',
self::BINARY => 'Doctrine\DBAL\Types\BinaryType',
self::BLOB => 'Doctrine\DBAL\Types\BlobType',
self::GUID => 'Doctrine\DBAL\Types\GuidType',
);
......
......@@ -23,6 +23,7 @@ class BlobTest extends \Doctrine\Tests\DbalFunctionalTestCase
$table->addColumn('id', 'integer');
$table->addColumn('clobfield', 'text');
$table->addColumn('blobfield', 'blob');
$table->addColumn('binaryfield', 'binary', array('length' => 50));
$table->setPrimaryKey(array('id'));
$sm = $this->_conn->getSchemaManager();
......@@ -36,8 +37,8 @@ class BlobTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testInsert()
{
$ret = $this->_conn->insert('blob_table',
array('id' => 1, 'clobfield' => 'test', 'blobfield' => 'test'),
array(\PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_LOB)
array('id' => 1, 'clobfield' => 'test', 'blobfield' => 'test', 'binaryfield' => 'test'),
array(\PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_LOB, \PDO::PARAM_LOB)
);
$this->assertEquals(1, $ret);
}
......@@ -45,8 +46,8 @@ class BlobTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testSelect()
{
$ret = $this->_conn->insert('blob_table',
array('id' => 1, 'clobfield' => 'test', 'blobfield' => 'test'),
array(\PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_LOB)
array('id' => 1, 'clobfield' => 'test', 'blobfield' => 'test', 'binaryfield' => 'test'),
array(\PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_LOB, \PDO::PARAM_LOB)
);
$this->assertBlobContains('test');
......@@ -55,17 +56,31 @@ class BlobTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testUpdate()
{
$ret = $this->_conn->insert('blob_table',
array('id' => 1, 'clobfield' => 'test', 'blobfield' => 'test'),
array(\PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_LOB)
array('id' => 1, 'clobfield' => 'test', 'blobfield' => 'test', 'binaryfield' => 'test'),
array(\PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_LOB, \PDO::PARAM_LOB)
);
$this->_conn->update('blob_table',
array('blobfield' => 'test2'),
array('blobfield' => 'test2', 'binaryfield' => 'test2'),
array('id' => 1),
array(\PDO::PARAM_LOB, \PDO::PARAM_INT)
array(\PDO::PARAM_LOB, \PDO::PARAM_LOB, \PDO::PARAM_INT)
);
$this->assertBlobContains('test2');
$this->assertBinaryContains('test2');
}
private function assertBinaryContains($text)
{
$rows = $this->_conn->fetchAll('SELECT * FROM blob_table');
$this->assertEquals(1, count($rows));
$row = array_change_key_case($rows[0], CASE_LOWER);
$blobValue = Type::getType('binary')->convertToPHPValue($row['binaryfield'], $this->_conn->getDatabasePlatform());
$this->assertInternalType('resource', $blobValue);
$this->assertEquals($text, stream_get_contents($blobValue));
}
private function assertBlobContains($text)
......
......@@ -2,11 +2,28 @@
namespace Doctrine\Tests\DBAL\Functional\Schema;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\Schema;
require_once __DIR__ . '/../../../TestInit.php';
class DrizzleSchemaManagerTest extends SchemaManagerFunctionalTestCase
{
}
\ No newline at end of file
public function testListTableWithBinary()
{
$tableName = 'test_binary_table';
$table = new \Doctrine\DBAL\Schema\Table($tableName);
$table->addColumn('id', 'integer');
$table->addColumn('column_varbinary', 'binary', array());
$table->addColumn('column_binary', 'binary', array('fixed' => true));
$table->setPrimaryKey(array('id'));
$this->_sm->createTable($table);
$table = $this->_sm->listTableDetails($tableName);
$this->assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_varbinary')->getType());
$this->assertFalse($table->getColumn('column_varbinary')->getFixed());
$this->assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_binary')->getType());
$this->assertFalse($table->getColumn('column_binary')->getFixed());
}
}
......@@ -36,4 +36,25 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase
$this->assertHasTable($tables, 'list_tables_test_new_name');
}
}
\ No newline at end of file
public function testListTableWithBinary()
{
$tableName = 'test_binary_table';
$table = new \Doctrine\DBAL\Schema\Table($tableName);
$table->addColumn('id', 'integer');
$table->addColumn('column_varbinary', 'binary', array());
$table->addColumn('column_binary', 'binary', array('fixed' => true));
$table->setPrimaryKey(array('id'));
$this->_sm->createTable($table);
$table = $this->_sm->listTableDetails($tableName);
$this->assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_varbinary')->getType());
$this->assertFalse($table->getColumn('column_varbinary')->getFixed());
$this->assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_binary')->getType());
$this->assertFalse($table->getColumn('column_binary')->getFixed());
}
}
......@@ -280,6 +280,27 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
$this->assertFalse($diff);
}
public function testListTableWithBinary()
{
$tableName = 'test_binary_table';
$table = new \Doctrine\DBAL\Schema\Table($tableName);
$table->addColumn('id', 'integer');
$table->addColumn('column_varbinary', 'binary', array());
$table->addColumn('column_binary', 'binary', array('fixed' => true));
$table->setPrimaryKey(array('id'));
$this->_sm->createTable($table);
$table = $this->_sm->listTableDetails($tableName);
$this->assertInstanceOf('Doctrine\DBAL\Types\BlobType', $table->getColumn('column_varbinary')->getType());
$this->assertFalse($table->getColumn('column_varbinary')->getFixed());
$this->assertInstanceOf('Doctrine\DBAL\Types\BlobType', $table->getColumn('column_binary')->getType());
$this->assertFalse($table->getColumn('column_binary')->getFixed());
}
}
class MoneyType extends Type
......
......@@ -722,4 +722,25 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
$this->assertSame('', $columns['column5']->getDefault());
$this->assertSame('666', $columns['column6']->getDefault());
}
public function testListTableWithBinary()
{
$tableName = 'test_binary_table';
$table = new \Doctrine\DBAL\Schema\Table($tableName);
$table->addColumn('id', 'integer');
$table->addColumn('column_varbinary', 'binary', array());
$table->addColumn('column_binary', 'binary', array('fixed' => true));
$table->setPrimaryKey(array('id'));
$this->_sm->createTable($table);
$table = $this->_sm->listTableDetails($tableName);
$this->assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_varbinary')->getType());
$this->assertFalse($table->getColumn('column_varbinary')->getFixed());
$this->assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_binary')->getType());
$this->assertTrue($table->getColumn('column_binary')->getFixed());
}
}
......@@ -72,4 +72,25 @@ EOS
$this->assertEquals($expected, $this->_sm->listTableForeignKeys('user'));
}
public function testListTableWithBinary()
{
$tableName = 'test_binary_table';
$table = new \Doctrine\DBAL\Schema\Table($tableName);
$table->addColumn('id', 'integer');
$table->addColumn('column_varbinary', 'binary', array());
$table->addColumn('column_binary', 'binary', array('fixed' => true));
$table->setPrimaryKey(array('id'));
$this->_sm->createTable($table);
$table = $this->_sm->listTableDetails($tableName);
$this->assertInstanceOf('Doctrine\DBAL\Types\BlobType', $table->getColumn('column_varbinary')->getType());
$this->assertFalse($table->getColumn('column_varbinary')->getFixed());
$this->assertInstanceOf('Doctrine\DBAL\Types\BlobType', $table->getColumn('column_binary')->getType());
$this->assertFalse($table->getColumn('column_binary')->getFixed());
}
}
......@@ -31,6 +31,14 @@ class MockPlatform extends \Doctrine\DBAL\Platforms\AbstractPlatform
return 'DUMMYCLOB';
}
/**
* {@inheritdoc}
*/
public function getBinaryTypeDeclarationSQL(array $field)
{
return 'DUMMYBINARY';
}
public function getVarcharDefaultLength()
{
return 255;
......
......@@ -547,4 +547,32 @@ abstract class AbstractPlatformTestCase extends \Doctrine\Tests\DbalTestCase
{
$this->_platform->getIdentitySequenceName('mytable', 'mycolumn');
}
public function testReturnsBinaryDefaultLength()
{
$this->assertSame($this->getBinaryDefaultLength(), $this->_platform->getBinaryDefaultLength());
}
protected function getBinaryDefaultLength()
{
return 255;
}
public function testReturnsBinaryMaxLength()
{
$this->assertSame($this->getBinaryMaxLength(), $this->_platform->getBinaryMaxLength());
}
protected function getBinaryMaxLength()
{
return 4000;
}
/**
* @expectedException \Doctrine\DBAL\DBALException
*/
public function testReturnsBinaryTypeDeclarationSQL()
{
$this->_platform->getBinaryTypeDeclarationSQL(array());
}
}
......@@ -379,4 +379,35 @@ class MySqlPlatformTest extends AbstractPlatformTestCase
"ALTER TABLE mytable ADD PRIMARY KEY (foo)",
), $sql);
}
public function testInitializesDoctrineTypeMappings()
{
$this->assertTrue($this->_platform->hasDoctrineTypeMappingFor('binary'));
$this->assertSame('binary', $this->_platform->getDoctrineTypeMapping('binary'));
$this->assertTrue($this->_platform->hasDoctrineTypeMappingFor('varbinary'));
$this->assertSame('binary', $this->_platform->getDoctrineTypeMapping('varbinary'));
}
protected function getBinaryMaxLength()
{
return 65535;
}
public function testReturnsBinaryTypeDeclarationSQL()
{
$this->assertSame('VARBINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array()));
$this->assertSame('VARBINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 0)));
$this->assertSame('VARBINARY(65535)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 65535)));
$this->assertSame('MEDIUMBLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 65536)));
$this->assertSame('MEDIUMBLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 16777215)));
$this->assertSame('LONGBLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 16777216)));
$this->assertSame('BINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true)));
$this->assertSame('BINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 0)));
$this->assertSame('BINARY(65535)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 65535)));
$this->assertSame('MEDIUMBLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 65536)));
$this->assertSame('MEDIUMBLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 16777215)));
$this->assertSame('LONGBLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 16777216)));
}
}
......@@ -3,6 +3,8 @@
namespace Doctrine\Tests\DBAL\Platforms;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\Type;
require_once __DIR__ . '/../../TestInit.php';
......@@ -331,6 +333,50 @@ class OraclePlatformTest extends AbstractPlatformTestCase
$this->assertEquals($expectedSql, $this->_platform->getAlterTableSQL($tableDiff));
}
public function testInitializesDoctrineTypeMappings()
{
$this->assertTrue($this->_platform->hasDoctrineTypeMappingFor('long raw'));
$this->assertSame('blob', $this->_platform->getDoctrineTypeMapping('long raw'));
$this->assertTrue($this->_platform->hasDoctrineTypeMappingFor('raw'));
$this->assertSame('binary', $this->_platform->getDoctrineTypeMapping('raw'));
}
protected function getBinaryMaxLength()
{
return 2000;
}
public function testReturnsBinaryTypeDeclarationSQL()
{
$this->assertSame('RAW(255)', $this->_platform->getBinaryTypeDeclarationSQL(array()));
$this->assertSame('RAW(2000)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 0)));
$this->assertSame('RAW(2000)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 2000)));
$this->assertSame('BLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 2001)));
$this->assertSame('RAW(255)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true)));
$this->assertSame('RAW(2000)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 0)));
$this->assertSame('RAW(2000)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 2000)));
$this->assertSame('BLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 2001)));
}
public function testDoesNotPropagateUnnecessaryTableAlterationOnBinaryType()
{
$table1 = new Table('mytable');
$table1->addColumn('column_varbinary', 'binary');
$table1->addColumn('column_binary', 'binary', array('fixed' => true));
$table2 = new Table('mytable');
$table2->addColumn('column_varbinary', 'binary', array('fixed' => true));
$table2->addColumn('column_binary', 'binary');
$comparator = new Comparator();
// VARBINARY -> BINARY
// BINARY -> VARBINARY
$this->assertEmpty($this->_platform->getAlterTableSQL($comparator->diffTable($table1, $table2)));
}
/**
* @group DBAL-563
*/
......
......@@ -3,6 +3,7 @@
namespace Doctrine\Tests\DBAL\Platforms;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff;
......@@ -339,6 +340,7 @@ class PostgreSqlPlatformTest extends AbstractPlatformTestCase
public function testAlterDecimalPrecisionScale()
{
$table = new Table('mytable');
$table->addColumn('dfoo1', 'decimal');
$table->addColumn('dfoo2', 'decimal', array('precision' => 10, 'scale' => 6));
......@@ -443,4 +445,65 @@ class PostgreSqlPlatformTest extends AbstractPlatformTestCase
array(3, 'CACHE 3')
);
}
protected function getBinaryDefaultLength()
{
return 0;
}
protected function getBinaryMaxLength()
{
return 0;
}
public function testReturnsBinaryTypeDeclarationSQL()
{
$this->assertSame('BYTEA', $this->_platform->getBinaryTypeDeclarationSQL(array()));
$this->assertSame('BYTEA', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 0)));
$this->assertSame('BYTEA', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 9999999)));
$this->assertSame('BYTEA', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true)));
$this->assertSame('BYTEA', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 0)));
$this->assertSame('BYTEA', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 9999999)));
}
public function testDoesNotPropagateUnnecessaryTableAlterationOnBinaryType()
{
$table1 = new Table('mytable');
$table1->addColumn('column_varbinary', 'binary');
$table1->addColumn('column_binary', 'binary', array('fixed' => true));
$table1->addColumn('column_blob', 'blob');
$table2 = new Table('mytable');
$table2->addColumn('column_varbinary', 'binary', array('fixed' => true));
$table2->addColumn('column_binary', 'binary');
$table2->addColumn('column_blob', 'binary');
$comparator = new Comparator();
// VARBINARY -> BINARY
// BINARY -> VARBINARY
// BLOB -> VARBINARY
$this->assertEmpty($this->_platform->getAlterTableSQL($comparator->diffTable($table1, $table2)));
$table2 = new Table('mytable');
$table2->addColumn('column_varbinary', 'binary', array('length' => 42));
$table2->addColumn('column_binary', 'blob');
$table2->addColumn('column_blob', 'binary', array('length' => 11, 'fixed' => true));
// VARBINARY -> VARBINARY with changed length
// BINARY -> BLOB
// BLOB -> BINARY
$this->assertEmpty($this->_platform->getAlterTableSQL($comparator->diffTable($table1, $table2)));
$table2 = new Table('mytable');
$table2->addColumn('column_varbinary', 'blob');
$table2->addColumn('column_binary', 'binary', array('length' => 42, 'fixed' => true));
$table2->addColumn('column_blob', 'blob');
// VARBINARY -> BLOB
// BINARY -> BINARY with changed length
// BLOB -> BLOB
$this->assertEmpty($this->_platform->getAlterTableSQL($comparator->diffTable($table1, $table2)));
}
}
......@@ -752,4 +752,36 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase
{
$this->assertFalse($this->_platform->canEmulateSchemas());
}
public function testInitializesDoctrineTypeMappings()
{
$this->assertTrue($this->_platform->hasDoctrineTypeMappingFor('binary'));
$this->assertSame('binary', $this->_platform->getDoctrineTypeMapping('binary'));
$this->assertTrue($this->_platform->hasDoctrineTypeMappingFor('varbinary'));
$this->assertSame('binary', $this->_platform->getDoctrineTypeMapping('varbinary'));
}
protected function getBinaryDefaultLength()
{
return 1;
}
protected function getBinaryMaxLength()
{
return 32767;
}
public function testReturnsBinaryTypeDeclarationSQL()
{
$this->assertSame('VARBINARY(1)', $this->_platform->getBinaryTypeDeclarationSQL(array()));
$this->assertSame('VARBINARY(1)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 0)));
$this->assertSame('VARBINARY(32767)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 32767)));
$this->assertSame('LONG BINARY', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 32768)));
$this->assertSame('BINARY(1)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true)));
$this->assertSame('BINARY(1)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 0)));
$this->assertSame('BINARY(32767)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 32767)));
$this->assertSame('LONG BINARY', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 32768)));
}
}
......@@ -665,10 +665,10 @@ class SQLServerPlatformTest extends AbstractPlatformTestCase
$this->assertSame('text', $this->_platform->getDoctrineTypeMapping('ntext'));
$this->assertTrue($this->_platform->hasDoctrineTypeMappingFor('binary'));
$this->assertSame('blob', $this->_platform->getDoctrineTypeMapping('binary'));
$this->assertSame('binary', $this->_platform->getDoctrineTypeMapping('binary'));
$this->assertTrue($this->_platform->hasDoctrineTypeMappingFor('varbinary'));
$this->assertSame('blob', $this->_platform->getDoctrineTypeMapping('varbinary'));
$this->assertSame('binary', $this->_platform->getDoctrineTypeMapping('varbinary'));
$this->assertTrue($this->_platform->hasDoctrineTypeMappingFor('image'));
$this->assertSame('blob', $this->_platform->getDoctrineTypeMapping('image'));
......@@ -676,4 +676,22 @@ class SQLServerPlatformTest extends AbstractPlatformTestCase
$this->assertTrue($this->_platform->hasDoctrineTypeMappingFor('uniqueidentifier'));
$this->assertSame('guid', $this->_platform->getDoctrineTypeMapping('uniqueidentifier'));
}
protected function getBinaryMaxLength()
{
return 8000;
}
public function testReturnsBinaryTypeDeclarationSQL()
{
$this->assertSame('VARBINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array()));
$this->assertSame('VARBINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 0)));
$this->assertSame('VARBINARY(8000)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 8000)));
$this->assertSame('VARBINARY(MAX)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 8001)));
$this->assertSame('BINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true)));
$this->assertSame('BINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 0)));
$this->assertSame('BINARY(8000)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 8000)));
$this->assertSame('VARBINARY(MAX)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 8001)));
}
}
......@@ -302,4 +302,25 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
'CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar") REFERENCES "foo-bar" ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE)',
);
}
protected function getBinaryDefaultLength()
{
return 0;
}
protected function getBinaryMaxLength()
{
return 0;
}
public function testReturnsBinaryTypeDeclarationSQL()
{
$this->assertSame('BLOB', $this->_platform->getBinaryTypeDeclarationSQL(array()));
$this->assertSame('BLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 0)));
$this->assertSame('BLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 9999999)));
$this->assertSame('BLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true)));
$this->assertSame('BLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 0)));
$this->assertSame('BLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 9999999)));
}
}
......@@ -935,6 +935,28 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
}
public function testCompareChangedBinaryColumn()
{
$oldSchema = new Schema();
$tableFoo = $oldSchema->createTable('foo');
$tableFoo->addColumn('id', 'binary');
$newSchema = new Schema();
$table = $newSchema->createTable('foo');
$table->addColumn('id', 'binary', array('length' => 42, 'fixed' => true));
$expected = new SchemaDiff();
$expected->fromSchema = $oldSchema;
$tableDiff = $expected->changedTables['foo'] = new TableDiff('foo');
$tableDiff->fromTable = $tableFoo;
$columnDiff = $tableDiff->changedColumns['id'] = new ColumnDiff('id', $table->getColumn('id'));
$columnDiff->fromColumn = $tableFoo->getColumn('id');
$columnDiff->changedProperties = array('length', 'fixed');
$this->assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
}
/**
* @group DBAL-617
*/
......
<?php
namespace Doctrine\Tests\DBAL\Types;
use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DBAL\Mocks;
require_once __DIR__ . '/../../TestInit.php';
class BinaryTest extends \Doctrine\Tests\DbalTestCase
{
/**
* @var \Doctrine\Tests\DBAL\Mocks\MockPlatform
*/
protected $platform;
/**
* @var \Doctrine\DBAL\Types\BinaryType
*/
protected $type;
/**
* {@inheritdoc}
*/
protected function setUp()
{
$this->platform = new \Doctrine\Tests\DBAL\Mocks\MockPlatform();
$this->type = Type::getType('binary');
}
public function testReturnsBindingType()
{
$this->assertSame(\PDO::PARAM_LOB, $this->type->getBindingType());
}
public function testReturnsName()
{
$this->assertSame(Type::BINARY, $this->type->getName());
}
public function testReturnsSQLDeclaration()
{
$this->assertSame('DUMMYBINARY', $this->type->getSQLDeclaration(array(), $this->platform));
}
public function testBinaryNullConvertsToPHPValue()
{
$this->assertNull($this->type->convertToPHPValue(null, $this->platform));
}
public function testBinaryStringConvertsToPHPValue()
{
$databaseValue = 'binary string';
$phpValue = $this->type->convertToPHPValue($databaseValue, $this->platform);
$this->assertInternalType('resource', $phpValue);
$this->assertEquals($databaseValue, stream_get_contents($phpValue));
}
public function testBinaryResourceConvertsToPHPValue()
{
$databaseValue = fopen('data://text/plain;base64,' . base64_encode('binary string'), 'r');
$phpValue = $this->type->convertToPHPValue($databaseValue, $this->platform);
$this->assertSame($databaseValue, $phpValue);
}
/**
* @dataProvider getInvalidDatabaseValues
* @expectedException \Doctrine\DBAL\Types\ConversionException
*/
public function testThrowsConversionExceptionOnInvalidDatabaseValue($value)
{
$this->type->convertToPHPValue($value, $this->platform);
}
public function getInvalidDatabaseValues()
{
return array(
array(false),
array(true),
array(0),
array(1),
array(-1),
array(0.0),
array(1.1),
array(-1.1),
);
}
}
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