Unverified Commit d48ea9c2 authored by Sergei Morozov's avatar Sergei Morozov Committed by GitHub

Merge pull request #3133 from Majkl578/travis-db2

Enable testing with IBM DB2 on Travis 
parents 75d6c444 e2e0de25
......@@ -21,7 +21,7 @@ before_commands:
tools:
external_code_coverage:
timeout: 3600
runs: 21 # 17x Travis (jobs with COVERAGE=yes) + 3x AppVeyor (jobs with coverage=yes) + 1x ContinuousPHP
runs: 22 # 18x Travis (jobs with COVERAGE=yes) + 3x AppVeyor (jobs with coverage=yes) + 1x ContinuousPHP
filter:
excluded_paths:
......
......@@ -356,6 +356,24 @@ jobs:
- bash ./tests/travis/install-mssql-$DB.sh
- bash ./tests/travis/install-mssql.sh
- stage: Test
env: DB=ibm_db2 COVERAGE=yes
sudo: required
services:
- docker
before_script:
- bash ./tests/travis/install-db2.sh
- bash ./tests/travis/install-db2-$DB.sh
- stage: Test
php: 7.2
env: DB=ibm_db2
sudo: required
services:
- docker
before_script:
- bash ./tests/travis/install-db2.sh
- bash ./tests/travis/install-db2-$DB.sh
- stage: Test
php: 7.1
env: DB=sqlite DEPENDENCIES=low
......
......@@ -289,17 +289,17 @@ class DB2Statement implements \IteratorAggregate, Statement
switch ($fetchMode) {
case FetchMode::CUSTOM_OBJECT:
while ($row = call_user_func_array([$this, 'fetch'], func_get_args())) {
while (($row = $this->fetch(...func_get_args())) !== false) {
$rows[] = $row;
}
break;
case FetchMode::COLUMN:
while ($row = $this->fetchColumn()) {
while (($row = $this->fetchColumn()) !== false) {
$rows[] = $row;
}
break;
default:
while ($row = $this->fetch($fetchMode)) {
while (($row = $this->fetch($fetchMode)) !== false) {
$rows[] = $row;
}
}
......
......@@ -299,7 +299,11 @@ abstract class AbstractPlatform
$fixed = $field['fixed'] ?? false;
if ($field['length'] > $this->getVarcharMaxLength()) {
$maxLength = $fixed
? $this->getCharMaxLength()
: $this->getVarcharMaxLength();
if ($field['length'] > $maxLength) {
return $this->getClobTypeDeclarationSQL($field);
}
......@@ -594,6 +598,14 @@ abstract class AbstractPlatform
return "\n";
}
/**
* Gets the maximum length of a char field.
*/
public function getCharMaxLength() : int
{
return $this->getVarcharMaxLength();
}
/**
* Gets the maximum length of a varchar field.
*
......
......@@ -39,6 +39,14 @@ use function strtoupper;
class DB2Platform extends AbstractPlatform
{
/**
* {@inheritdoc}
*/
public function getCharMaxLength() : int
{
return 254;
}
/**
* {@inheritdoc}
*/
......@@ -55,6 +63,19 @@ class DB2Platform extends AbstractPlatform
return 1;
}
/**
* {@inheritDoc}
*/
public function getVarcharTypeDeclarationSQL(array $field)
{
// for IBM DB2, the CHAR max length is less than VARCHAR default length
if (! isset($field['length']) && ! empty($field['fixed'])) {
$field['length'] = $this->getCharMaxLength();
}
return parent::getVarcharTypeDeclarationSQL($field);
}
/**
* {@inheritDoc}
*/
......@@ -107,7 +128,7 @@ class DB2Platform extends AbstractPlatform
*/
protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
{
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(254)')
: ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
}
......@@ -116,7 +137,7 @@ class DB2Platform extends AbstractPlatform
*/
protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
{
return $fixed ? 'BINARY(' . ($length ?: 255) . ')' : 'VARBINARY(' . ($length ?: 255) . ')';
return $this->getVarcharTypeDeclarationSQLSnippet($length, $fixed) . ' FOR BIT DATA';
}
/**
......
......@@ -26,7 +26,6 @@ class DateIntervalType extends Type
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
$fieldDeclaration['length'] = 255;
$fieldDeclaration['fixed'] = true;
return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration);
}
......
......@@ -2,7 +2,9 @@
namespace Doctrine\Tests\DBAL\Functional;
use Doctrine\DBAL\Driver\PDOSqlsrv\Driver as PDOSQLSrvDriver;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\Type;
use const CASE_LOWER;
use function array_change_key_case;
......@@ -17,25 +19,19 @@ class BlobTest extends \Doctrine\Tests\DbalFunctionalTestCase
{
parent::setUp();
if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlsrv\Driver) {
if ($this->_conn->getDriver() instanceof PDOSQLSrvDriver) {
$this->markTestSkipped('This test does not work on pdo_sqlsrv driver due to a bug. See: http://social.msdn.microsoft.com/Forums/sqlserver/en-US/5a755bdd-41e9-45cb-9166-c9da4475bb94/how-to-set-null-for-varbinarymax-using-bindvalue-using-pdosqlsrv?forum=sqldriverforphp');
}
try {
/* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
$table = new \Doctrine\DBAL\Schema\Table("blob_table");
$table->addColumn('id', 'integer');
$table->addColumn('clobfield', 'text');
$table->addColumn('blobfield', 'blob');
$table->addColumn('binaryfield', 'binary', array('length' => 50));
$table->setPrimaryKey(array('id'));
/* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
$table = new Table('blob_table');
$table->addColumn('id', 'integer');
$table->addColumn('clobfield', 'text');
$table->addColumn('blobfield', 'blob');
$table->setPrimaryKey(['id']);
$sm = $this->_conn->getSchemaManager();
$sm->createTable($table);
} catch(\Exception $e) {
}
$this->_conn->exec($this->_conn->getDatabasePlatform()->getTruncateTableSQL('blob_table'));
$sm = $this->_conn->getSchemaManager();
$sm->dropAndCreateTable($table);
}
public function testInsert()
......@@ -44,12 +40,10 @@ class BlobTest extends \Doctrine\Tests\DbalFunctionalTestCase
'id' => 1,
'clobfield' => 'test',
'blobfield' => 'test',
'binaryfield' => 'test',
], [
ParameterType::INTEGER,
ParameterType::STRING,
ParameterType::LARGE_OBJECT,
ParameterType::LARGE_OBJECT,
]);
self::assertEquals(1, $ret);
......@@ -61,12 +55,10 @@ class BlobTest extends \Doctrine\Tests\DbalFunctionalTestCase
'id' => 1,
'clobfield' => 'test',
'blobfield' => 'test',
'binaryfield' => 'test',
], [
ParameterType::INTEGER,
ParameterType::STRING,
ParameterType::LARGE_OBJECT,
ParameterType::LARGE_OBJECT,
]);
$this->assertBlobContains('test');
......@@ -78,38 +70,20 @@ class BlobTest extends \Doctrine\Tests\DbalFunctionalTestCase
'id' => 1,
'clobfield' => 'test',
'blobfield' => 'test',
'binaryfield' => 'test',
], [
ParameterType::INTEGER,
ParameterType::STRING,
ParameterType::LARGE_OBJECT,
ParameterType::LARGE_OBJECT,
]);
$this->_conn->update('blob_table', [
'blobfield' => 'test2',
'binaryfield' => 'test2',
], ['id' => 1], [
ParameterType::LARGE_OBJECT,
ParameterType::LARGE_OBJECT,
ParameterType::INTEGER,
]);
$this->assertBlobContains('test2');
$this->assertBinaryContains('test2');
}
private function assertBinaryContains($text)
{
$rows = $this->_conn->fetchAll('SELECT * FROM blob_table');
self::assertCount(1, $rows);
$row = array_change_key_case($rows[0], CASE_LOWER);
$blobValue = Type::getType('binary')->convertToPHPValue($row['binaryfield'], $this->_conn->getDatabasePlatform());
self::assertInternalType('resource', $blobValue);
self::assertEquals($text, stream_get_contents($blobValue));
}
private function assertBlobContains($text)
......
......@@ -15,8 +15,8 @@ class DateExpressionTest extends DbalFunctionalTestCase
public function testDifference(string $date1, string $date2, int $expected) : void
{
$table = new Table('date_expr_test');
$table->addColumn('date1', 'date');
$table->addColumn('date2', 'date');
$table->addColumn('date1', 'datetime');
$table->addColumn('date2', 'datetime');
$this->_conn->getSchemaManager()->dropAndCreateTable($table);
$this->_conn->insert('date_expr_test', [
'date1' => $date1,
......
......@@ -25,4 +25,9 @@ class Db2SchemaManagerTest extends SchemaManagerFunctionalTestCase
self::assertNull($columns['bool']->getComment());
self::assertSame("That's a comment", $columns['bool_commented']->getComment());
}
public function testListTableWithBinary()
{
self::markTestSkipped('Binary data type is currently not supported on DB2 LUW');
}
}
<?php
declare(strict_types=1);
namespace Doctrine\Tests\DBAL\Functional\Types;
use Doctrine\DBAL\Driver\IBMDB2\DB2Driver;
use Doctrine\DBAL\Driver\OCI8\Driver as OCI8Driver;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Schema\Table;
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
{
protected function setUp()
{
parent::setUp();
/** @see https://github.com/doctrine/dbal/issues/2787 */
if ($this->_conn->getDriver() instanceof OCI8Driver) {
$this->markTestSkipped('Filtering by binary fields is currently not supported on Oracle');
}
$table = new Table('binary_table');
$table->addColumn('id', 'binary', [
'length' => 16,
'fixed' => true,
]);
$table->addColumn('val', 'binary', ['length' => 64]);
$table->setPrimaryKey(['id']);
$sm = $this->_conn->getSchemaManager();
$sm->dropAndCreateTable($table);
}
public function testInsertAndSelect()
{
$id1 = random_bytes(16);
$id2 = random_bytes(16);
$value1 = random_bytes(64);
$value2 = random_bytes(64);
/** @see https://bugs.php.net/bug.php?id=76322 */
if ($this->_conn->getDriver() instanceof DB2Driver) {
$value1 = str_replace("\x00", "\xFF", $value1);
$value2 = str_replace("\x00", "\xFF", $value2);
}
$this->insert($id1, $value1);
$this->insert($id2, $value2);
$this->assertSame($value1, $this->select($id1));
$this->assertSame($value2, $this->select($id2));
}
private function insert(string $id, string $value) : void
{
$result = $this->_conn->insert('binary_table', [
'id' => $id,
'val' => $value,
], [
ParameterType::LARGE_OBJECT,
ParameterType::LARGE_OBJECT,
]);
self::assertSame(1, $result);
}
private function select(string $id)
{
$value = $this->_conn->fetchColumn(
'SELECT val FROM binary_table WHERE id = ?',
[$id],
0,
[ParameterType::LARGE_OBJECT]
);
// 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;
}
}
......@@ -216,7 +216,7 @@ class DB2PlatformTest extends AbstractPlatformTestCase
self::assertEquals('VARCHAR(255)', $this->_platform->getVarcharTypeDeclarationSQL(array()));
self::assertEquals('VARCHAR(10)', $this->_platform->getVarcharTypeDeclarationSQL(array('length' => 10)));
self::assertEquals('CHAR(255)', $this->_platform->getVarcharTypeDeclarationSQL(array('fixed' => true)));
self::assertEquals('CHAR(254)', $this->_platform->getVarcharTypeDeclarationSQL(['fixed' => true]));
self::assertEquals('CHAR(10)', $this->_platform->getVarcharTypeDeclarationSQL($fullColumnDef));
self::assertEquals('SMALLINT', $this->_platform->getSmallIntTypeDeclarationSQL(array()));
......@@ -419,15 +419,14 @@ class DB2PlatformTest extends AbstractPlatformTestCase
public function testReturnsBinaryTypeDeclarationSQL()
{
self::assertSame('VARBINARY(1)', $this->_platform->getBinaryTypeDeclarationSQL(array()));
self::assertSame('VARBINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 0)));
self::assertSame('VARBINARY(32704)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 32704)));
self::assertSame('BLOB(1M)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 32705)));
self::assertSame('VARCHAR(1) FOR BIT DATA', $this->_platform->getBinaryTypeDeclarationSQL([]));
self::assertSame('VARCHAR(255) FOR BIT DATA', $this->_platform->getBinaryTypeDeclarationSQL(['length' => 0]));
self::assertSame('VARCHAR(32704) FOR BIT DATA', $this->_platform->getBinaryTypeDeclarationSQL(['length' => 32704]));
self::assertSame('BLOB(1M)', $this->_platform->getBinaryTypeDeclarationSQL(['length' => 32705]));
self::assertSame('BINARY(1)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true)));
self::assertSame('BINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 0)));
self::assertSame('BINARY(32704)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 32704)));
self::assertSame('BLOB(1M)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 32705)));
self::assertSame('CHAR(1) FOR BIT DATA', $this->_platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
self::assertSame('CHAR(254) FOR BIT DATA', $this->_platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
self::assertSame('BLOB(1M)', $this->_platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 32705]));
}
/**
......
<?xml version="1.0" encoding="utf-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
failOnRisky="true"
failOnWarning="true"
>
<php>
<ini name="error_reporting" value="-1" />
<var name="db_type" value="ibm_db2"/>
<var name="db_host" value="127.0.0.1"/>
<var name="db_username" value="db2inst1"/>
<var name="db_password" value="Doctrine2018"/>
<var name="db_name" value="HOSTNAME=127.0.0.1;UID=db2inst1;PWD=Doctrine2018;DATABASE=doctrine"/>
<var name="db_port" value="50000"/>
<var name="tmpdb_type" value="ibm_db2"/>
<var name="tmpdb_host" value="127.0.0.1"/>
<var name="tmpdb_username" value="db2inst1"/>
<var name="tmpdb_password" value="Doctrine2018"/>
<var name="tmpdb_name" value="HOSTNAME=127.0.0.1;UID=db2inst1;PWD=Doctrine2018;DATABASE=doctrine"/>
<var name="tmpdb_port" value="50000"/>
</php>
<testsuites>
<testsuite name="Doctrine DBAL Test Suite">
<directory>../Doctrine/Tests/DBAL</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">../../lib/Doctrine</directory>
</whitelist>
</filter>
<listeners>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
</listeners>
<groups>
<exclude>
<group>performance</group>
<group>locking_functional</group>
</exclude>
</groups>
</phpunit>
#!/usr/bin/env bash
set -ex
echo "Installing extension"
(
sudo apt install ksh
cd /tmp
wget http://cdn1.netmake.com.br/download/Conexao/DB2/Linux/x64_v10.5fp8_linuxx64_dsdriver.tar.gz
tar xf x64_v10.5fp8_linuxx64_dsdriver.tar.gz
ksh dsdriver/installDSDriver
pecl download ibm_db2
tar xf ibm_db2-*
rm ibm_db2-*.tgz
cd ibm_db2-*
phpize
./configure --with-IBM_DB2=/tmp/dsdriver
make -j `nproc`
make install
echo -e 'extension=ibm_db2.so\nibm_db2.instance_name=db2inst1' > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/ibm_db2.ini
)
#!/usr/bin/env bash
set -ex
echo Setting up IBM DB2
sudo docker pull ibmcom/db2express-c:10.5.0.5-3.10.0
sudo docker run \
-d \
-p 50000:50000 \
-e DB2INST1_PASSWORD=Doctrine2018 \
-e LICENSE=accept \
--name db2 \
ibmcom/db2express-c:10.5.0.5-3.10.0 \
db2start
sleep 15
sudo docker exec db2 su - db2inst1 -c \
'db2 CREATE DB doctrine && db2 CONNECT TO doctrine && db2 CREATE USER TEMPORARY TABLESPACE doctrine_tbsp PAGESIZE 4 K'
echo DB2 started
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