Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

add support for BLOB data in OCI8 driver #396

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .ci/oracle_fixtures.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

echo "Configure Oracle test database"

"CREATE DATABASE test DATAFILE 'zenddb_test' SIZE 10M"
12 changes: 12 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ matrix:
- LEGACY_DEPS="phpunit/phpunit zendframework/zend-hydrator"
- TEST_INTEGRATION=true
- TESTS_ZEND_DB_ADAPTER_DRIVER_MYSQL=true
- TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8=true
- php: 5.6
env:
- DEPS=latest
Expand All @@ -36,6 +37,14 @@ matrix:
- LEGACY_DEPS="phpunit/phpunit zendframework/zend-hydrator"
- TEST_INTEGRATION=true
- TESTS_ZEND_DB_ADAPTER_DRIVER_MYSQL=true
- php: 7.0
services:
- oci8
env:
- DEPS=locked
- LEGACY_DEPS="phpunit/phpunit zendframework/zend-hydrator"
- TEST_INTEGRATION=true
- TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8=true
- php: 7.0
env:
- DEPS=latest
Expand All @@ -52,6 +61,7 @@ matrix:
- TEST_COVERAGE=true
- TEST_INTEGRATION=true
- TESTS_ZEND_DB_ADAPTER_DRIVER_MYSQL=true
- TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8=true
- php: 7.1
env:
- DEPS=latest
Expand All @@ -65,6 +75,7 @@ matrix:
- DEPS=locked
- TEST_INTEGRATION=true
- TESTS_ZEND_DB_ADAPTER_DRIVER_MYSQL=true
- TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8=true
- php: 7.2
services:
- postgresql
Expand All @@ -74,6 +85,7 @@ matrix:
- DEPS=locked
- TEST_INTEGRATION=true
- TESTS_ZEND_DB_ADAPTER_DRIVER_PGSQL=true
- TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8=true
- php: 7.2
env:
- DEPS=latest
Expand Down
5 changes: 3 additions & 2 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@
<env name="TESTS_ZEND_DB_ADAPTER_DRIVER_SQLSRV_PASSWORD" value="Password123" />
<env name="TESTS_ZEND_DB_ADAPTER_DRIVER_SQLSRV_DATABASE" value="zenddb_test" />

<env name="TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8" value="false" />
<env name="TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8_HOSTNAME" value="" />
<env name="TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8" value="true"/>
<env name="TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8_USERNAME" value="" />
<env name="TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8_PASSWORD" value="" />
<env name="TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8_DATABASE" value="" />
<env name="TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8_CHARSET" value=""/>
<env name="TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8_CONNECTIONSTRING" value=""/>

<env name="TESTS_ZEND_DB_ADAPTER_DRIVER_IBMDB2" value="false" />
<env name="TESTS_ZEND_DB_ADAPTER_DRIVER_IBMDB2_HOSTNAME" value="" />
Expand Down
7 changes: 7 additions & 0 deletions src/Adapter/Driver/Oci8/Statement.php
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,18 @@ protected function bindParametersFromContainer()
$type = SQLT_BIN;
break;
case ParameterContainer::TYPE_LOB:
case ParameterContainer::TYPE_CLOB:
$type = OCI_B_CLOB;
$clob = oci_new_descriptor($this->driver->getConnection()->getResource(), OCI_DTYPE_LOB);
$clob->writetemporary($value, OCI_TEMP_CLOB);
$value = $clob;
break;
case ParameterContainer::TYPE_BLOB:
$type = OCI_B_BLOB;
$blob = oci_new_descriptor($this->driver->getConnection()->getResource(), OCI_DTYPE_LOB);
$blob->writetemporary($value, OCI_TEMP_BLOB);
$value = $blob;
break;
case ParameterContainer::TYPE_STRING:
default:
$type = SQLT_CHR;
Expand Down
2 changes: 2 additions & 0 deletions src/Adapter/ParameterContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class ParameterContainer implements Iterator, ArrayAccess, Countable
const TYPE_BINARY = 'binary';
const TYPE_STRING = 'string';
const TYPE_LOB = 'lob';
const TYPE_BLOB = 'blob';
const TYPE_CLOB = 'clob';

/**
* Data
Expand Down
29 changes: 29 additions & 0 deletions test/integration/Adapter/Driver/Oci8/ConnectionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
/**
* @see https://github.com/zendframework/zend-db for the canonical source repository
* @copyright Copyright (c) 2019 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-db/blob/master/LICENSE.md New BSD License
*/

namespace ZendIntegrationTest\Db\Adapter\Driver\Oci8;

use PHPUnit\Framework\TestCase;
use Zend\Db\Adapter\Driver\Oci8\Connection;

/**
* @group integration
* @group integration-oci8
*/
class ConnectionTest extends TestCase
{
use TraitSetup;

public function testConnectionOk()
{
$connection = new Connection($this->variables);
$connection->connect();

self::assertTrue($connection->isConnected());
$connection->disconnect();
}
}
155 changes: 155 additions & 0 deletions test/integration/Adapter/Driver/Oci8/TableGatewayTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<?php
/**
* @see https://github.com/zendframework/zend-db for the canonical source repository
* @copyright Copyright (c) 2019 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-db/blob/master/LICENSE.md New BSD License
*/

namespace ZendIntegrationTest\Db\Adapter\Driver\Oci8;

use PHPUnit\Framework\TestCase;
use Zend\Db\Adapter\Adapter;
use Zend\Db\Adapter\ParameterContainer;
use Zend\Db\TableGateway\TableGateway;

class TableGatewayTest extends TestCase
{
use TraitSetup;

/**
* @see https://github.com/zendframework/zend-db/issues/330
*/
public function testSelectWithEmptyCurrentWithBufferResult()
{
$adapter = new Adapter([
'driver' => 'OCI8',
'connection_string' => $this->variables['connectionstring'],
'username' => $this->variables['username'],
'password' => $this->variables['password'],
'character_set' => $this->variables['charset'],
'options' => ['buffer_results' => true]
]);
$tableGateway = new TableGateway('TEST', $adapter);
$rowset = $tableGateway->select('ID = 0');

$this->assertNull($rowset->current());
}

/**
* @see https://github.com/zendframework/zend-db/issues/330
*/
public function testSelectWithEmptyCurrentWithoutBufferResult()
{
$adapter = new Adapter([
'driver' => 'OCI8',
'connection_string' => $this->variables['connectionstring'],
'username' => $this->variables['username'],
'password' => $this->variables['password'],
'character_set' => $this->variables['charset'],
'options' => ['buffer_results' => false]
]);
$tableGateway = new TableGateway('TEST', $adapter);
$rowset = $tableGateway->select('ID = 0');

$this->assertNull($rowset->current());
}

/**
* @see https://github.com/zendframework/zend-db/pull/396
*/
public function testBlobWithOci8()
{
$adapter = new Adapter([
'driver' => 'OCI8',
'connection_string' => $this->variables['connectionstring'],
'username' => $this->variables['username'],
'password' => $this->variables['password'],
'character_set' => $this->variables['charset'],
'options' => ['buffer_results' => false]
]);
$tableGateway = new TableGateway('TEST', $adapter);

$blob = 'very long sentence that is in fact not very long that tests blob';

$data = new ParameterContainer();
$data->setFromArray(['CONTENT_BLOB' => $blob]);
$data->offsetSetErrata('CONTENT_BLOB', ParameterContainer::TYPE_BLOB);

$sql = 'UPDATE TEST SET CONTENT_BLOB = :CONTENT_BLOB WHERE ID = 1';
$stm = $tableGateway->getAdapter()->getDriver()->createStatement($sql);
$stm->setParameterContainer($data);
$stm->execute();

$rowset = $tableGateway->select('ID = 1')->current();

$this->assertInstanceOf('OCI-Lob', $rowset['CONTENT_BLOB']);
$value = $rowset['CONTENT_BLOB']->read($rowset['CONTENT_BLOB']->size());
$this->assertEquals($blob, $value);
}

/**
* @see https://github.com/zendframework/zend-db/pull/396
*/
public function testClobWithOci8()
{
$adapter = new Adapter([
'driver' => 'OCI8',
'connection_string' => $this->variables['connectionstring'],
'username' => $this->variables['username'],
'password' => $this->variables['password'],
'character_set' => $this->variables['charset'],
'options' => ['buffer_results' => false]
]);
$tableGateway = new TableGateway('TEST', $adapter);

$clob = 'very long sentence that is in fact not very long that tests clob';

$data = new ParameterContainer();
$data->setFromArray(['CONTENT_CLOB' => $clob]);
$data->offsetSetErrata('CONTENT_CLOB', ParameterContainer::TYPE_CLOB);

$sql = 'UPDATE TEST SET CONTENT_CLOB = :CONTENT_CLOB WHERE ID = 1';
$stm = $tableGateway->getAdapter()->getDriver()->createStatement($sql);
$stm->setParameterContainer($data);
$stm->execute();

$rowset = $tableGateway->select('ID = 1')->current();

$this->assertInstanceOf('OCI-Lob', $rowset['CONTENT_CLOB']);
$value = $rowset['CONTENT_CLOB']->read($rowset['CONTENT_CLOB']->size());
$this->assertEquals($clob, $value);
}

/**
* @see https://github.com/zendframework/zend-db/pull/396
*/
public function testLobWithOci8()
{
$adapter = new Adapter([
'driver' => 'OCI8',
'connection_string' => $this->variables['connectionstring'],
'username' => $this->variables['username'],
'password' => $this->variables['password'],
'character_set' => $this->variables['charset'],
'options' => ['buffer_results' => false]
]);
$tableGateway = new TableGateway('TEST', $adapter);

$clob = 'very long sentence that is in fact not very long that tests lob';

$data = new ParameterContainer();
$data->setFromArray(['CONTENT_CLOB' => $clob]);
$data->offsetSetErrata('CONTENT_CLOB', ParameterContainer::TYPE_LOB);

$sql = 'UPDATE TEST SET CONTENT_CLOB = :CONTENT_CLOB WHERE ID = 2';
$stm = $tableGateway->getAdapter()->getDriver()->createStatement($sql);
$stm->setParameterContainer($data);
$stm->execute();

$rowset = $tableGateway->select('ID = 2')->current();

$this->assertInstanceOf('OCI-Lob', $rowset['CONTENT_CLOB']);
$value = $rowset['CONTENT_CLOB']->read($rowset['CONTENT_CLOB']->size());
$this->assertEquals($clob, $value);
}
}
44 changes: 44 additions & 0 deletions test/integration/Adapter/Driver/Oci8/TraitSetup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php
/**
* @see https://github.com/zendframework/zend-db for the canonical source repository
* @copyright Copyright (c) 2019 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-db/blob/master/LICENSE.md New BSD License
*/

namespace ZendIntegrationTest\Db\Adapter\Driver\Oci8;

trait TraitSetup
{
protected $variables = [
'connectionstring' => 'TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8_CONNECTIONSTRING',
'username' => 'TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8_USERNAME',
'password' => 'TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8_PASSWORD',
'charset' => 'TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8_CHARSET',
'database' => 'TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8_DATABASE',
];

/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
if (!getenv('TESTS_ZEND_DB_ADAPTER_DRIVER_OCI8')) {
$this->markTestSkipped('Oci8 integration test disabled');
}

if (!extension_loaded('oci8')) {
$this->fail('The phpunit group integration-oci8 was enabled, but the extension is not loaded.');
}

foreach ($this->variables as $name => $value) {
if (!getenv($value)) {
$this->markTestSkipped(sprintf(
'Missing required variable %s from phpunit.xml for this integration test',
$value
));
}
$this->variables[$name] = getenv($value);
}
}
}
Loading