Skip to content

Commit

Permalink
Merge pull request #149 from csthomas/quoteBinary
Browse files Browse the repository at this point in the history
Add support for binary data
  • Loading branch information
mbabker authored Dec 27, 2018
2 parents a5fd31d + c88c8ff commit 3b2ef25
Show file tree
Hide file tree
Showing 17 changed files with 1,185 additions and 32 deletions.
112 changes: 112 additions & 0 deletions Tests/DatabaseSqliteCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php
/**
* @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/

namespace Joomla\Database\Tests;

use Joomla\Database\DatabaseDriver;
use Joomla\Database\Sqlite\SqliteDriver;
use Joomla\Test\TestDatabase;

/**
* Abstract test case class for MySQLi database testing.
*
* @since 1.0
*/
abstract class DatabaseSqliteCase extends TestDatabase
{
/**
* @var array The database driver options for the connection.
* @since 1.0
*/
private static $options = array('driver' => 'sqlite');

/**
* This method is called before the first test of this test class is run.
*
* @return void
*
* @since 1.0
*/
public static function setUpBeforeClass()
{
if (!class_exists('\\Joomla\\Database\\DatabaseDriver'))
{
static::markTestSkipped('The joomla/database package is not installed, cannot use this test case.');
}

// Make sure the driver is supported
if (!SqliteDriver::isSupported())
{
static::markTestSkipped('The SQLite driver is not supported on this platform.');
}

// We always want the default database test case to use an SQLite memory database.
$options = array(
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => 'jos_',
);

try
{
// Attempt to instantiate the driver.
static::$driver = DatabaseDriver::getInstance($options);
static::$driver->connect();

// Get the PDO instance for an SQLite memory database and load the test schema into it.
static::$driver->getConnection()->exec(file_get_contents(__DIR__ . '/Stubs/ddl.sql'));
}
catch (\RuntimeException $e)
{
static::$driver = null;
}
}

/**
* This method is called after the last test of this test class is run.
*
* @return void
*
* @since 1.0
*/
public static function tearDownAfterClass()
{
if (static::$driver !== null)
{
static::$driver->disconnect();
static::$driver = null;
}
}

/**
* Gets the data set to be loaded into the database during setup
*
* @return \PHPUnit_Extensions_Database_DataSet_XmlDataSet
*
* @since 1.0
*/
protected function getDataSet()
{
return $this->createXMLDataSet(__DIR__ . '/Stubs/database.xml');
}

/**
* Returns the default database connection for running the tests.
*
* @return \PHPUnit_Extensions_Database_DB_IDatabaseConnection
*
* @since 1.0
*/
protected function getConnection()
{
if (!is_null(static::$driver))
{
return $this->createDefaultDBConnection(static::$driver->getConnection(), ':memory:');
}

return null;
}
}
12 changes: 11 additions & 1 deletion Tests/DatabaseSqlsrvCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,17 @@ protected function getConnection()

// Create the PDO object from the DSN and options.
$pdo = new \PDO($dsn, self::$options['user'], self::$options['password']);
$pdo->exec('create table [jos_dbtest]([id] [int] IDENTITY(1,1) NOT NULL, [title] [nvarchar](50) NOT NULL, [start_date] [datetime] NOT NULL, [description] [nvarchar](max) NOT NULL, CONSTRAINT [PK_jos_dbtest_id] PRIMARY KEY CLUSTERED ([id] ASC) WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF))');
$pdo->exec("
IF OBJECT_ID('jos_dbtest', 'U') IS NOT NULL DROP TABLE [jos_dbtest];
CREATE TABLE [jos_dbtest] (
[id] [int] IDENTITY(1,1) NOT NULL,
[title] nvarchar(50) NOT NULL,
[start_date] datetime NOT NULL,
[description] nvarchar(max) NOT NULL,
[data] varbinary(max),
CONSTRAINT [PK_jos_dbtest_id] PRIMARY KEY CLUSTERED ([id] ASC) WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
);"
);

return $this->createDefaultDBConnection($pdo, self::$options['database']);
}
Expand Down
161 changes: 156 additions & 5 deletions Tests/DriverMysqlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ public function dataTestEscape()
);
}

/**
* Data for the testQuoteBinary test.
*
* @return array
*
* @since __DEPLOY_VERSION__
*/
public function dataTestQuoteBinary()
{
return array(
array('DATA', "X'" . bin2hex('DATA') . "'"),
array("\x00\x01\x02\xff", "X'000102ff'"),
array("\x01\x01\x02\xff", "X'010102ff'"),
);
}

/**
* Data for the testQuoteName test.
*
Expand Down Expand Up @@ -128,6 +144,25 @@ public function testEscape($text, $extra, $expected)
);
}

/**
* Test the quoteBinary method.
*
* @param string $data The binary quoted input string.
*
* @return void
*
* @dataProvider dataTestQuoteBinary
* @since __DEPLOY_VERSION__
*/
public function testQuoteBinary($data, $expected)
{
$this->assertThat(
self::$driver->quoteBinary($data),
$this->equalTo($expected),
'The binary data was not quoted properly'
);
}

/**
* Test the quoteName method.
*
Expand Down Expand Up @@ -261,7 +296,13 @@ public function testGetTableCreate()
*/
public function testGetTableColumns()
{
$tableCol = array('id' => 'int unsigned', 'title' => 'varchar', 'start_date' => 'datetime', 'description' => 'text');
$tableCol = array(
'id' => 'int unsigned',
'title' => 'varchar',
'start_date' => 'datetime',
'description' => 'text',
'data' => 'blob',
);

$this->assertThat(
self::$driver->getTableColumns('jos_dbtest'),
Expand Down Expand Up @@ -314,14 +355,26 @@ public function testGetTableColumns()
$description->Privileges = 'select,insert,update,references';
$description->Comment = '';

$data = new \stdClass;
$data->Default = null;
$data->Field = 'data';
$data->Type = 'blob';
$data->Null = 'YES';
$data->Key = '';
$data->Collation = null;
$data->Extra = '';
$data->Privileges = 'select,insert,update,references';
$data->Comment = '';

$this->assertThat(
self::$driver->getTableColumns('jos_dbtest', false),
$this->equalTo(
array(
'id' => $id,
'title' => $title,
'start_date' => $start_date,
'description' => $description
'description' => $description,
'data' => $data,
)
),
__LINE__
Expand Down Expand Up @@ -474,6 +527,7 @@ public function testLoadObject()
$objCompare->title = 'Testing3';
$objCompare->start_date = '1980-04-18 00:00:00';
$objCompare->description = 'three';
$objCompare->data = null;

$this->assertThat($result, $this->equalTo($objCompare), __LINE__);
}
Expand Down Expand Up @@ -501,6 +555,7 @@ public function testLoadObjectList()
$objCompare->title = 'Testing';
$objCompare->start_date = '1980-04-18 00:00:00';
$objCompare->description = 'one';
$objCompare->data = null;

$expected[] = clone $objCompare;

Expand All @@ -509,6 +564,7 @@ public function testLoadObjectList()
$objCompare->title = 'Testing2';
$objCompare->start_date = '1980-04-18 00:00:00';
$objCompare->description = 'one';
$objCompare->data = null;

$expected[] = clone $objCompare;

Expand All @@ -517,6 +573,7 @@ public function testLoadObjectList()
$objCompare->title = 'Testing3';
$objCompare->start_date = '1980-04-18 00:00:00';
$objCompare->description = 'three';
$objCompare->data = null;

$expected[] = clone $objCompare;

Expand All @@ -525,6 +582,7 @@ public function testLoadObjectList()
$objCompare->title = 'Testing4';
$objCompare->start_date = '1980-04-18 00:00:00';
$objCompare->description = 'four';
$objCompare->data = null;

$expected[] = clone $objCompare;

Expand Down Expand Up @@ -567,7 +625,7 @@ public function testLoadRow()
self::$driver->setQuery($query);
$result = self::$driver->loadRow();

$expected = array(3, 'Testing3', '1980-04-18 00:00:00', 'three');
$expected = array(3, 'Testing3', '1980-04-18 00:00:00', 'three', null);

$this->assertThat($result, $this->equalTo($expected), __LINE__);
}
Expand All @@ -588,8 +646,101 @@ public function testLoadRowList()
self::$driver->setQuery($query);
$result = self::$driver->loadRowList();

$expected = array(array(1, 'Testing', '1980-04-18 00:00:00', 'one'), array(2, 'Testing2', '1980-04-18 00:00:00', 'one'));
$expected = array(
array(1, 'Testing', '1980-04-18 00:00:00', 'one', null),
array(2, 'Testing2', '1980-04-18 00:00:00', 'one', null)
);

$this->assertThat($result, $this->equalTo($expected), __LINE__);
}

/**
* Test quoteBinary and decodeBinary methods
*
* @return void
*
* @since __DEPLOY_VERSION__
*/
public function testLoadBinary()
{
// Add binary data with null byte
$query = self::$driver->getQuery(true)
->update('jos_dbtest')
->set('data = ' . self::$driver->quoteBinary("\x00\x01\x02\xff"))
->where('id = 3');

self::$driver->setQuery($query)->execute();

// Add binary data with invalid UTF-8
$query = self::$driver->getQuery(true)
->update('jos_dbtest')
->set('data = ' . self::$driver->quoteBinary("\x01\x01\x02\xff"))
->where('id = 4');

self::$driver->setQuery($query)->execute();

$selectRow3 = self::$driver->getQuery(true)
->select('id')
->from('jos_dbtest')
->where('data = ' . self::$driver->quoteBinary("\x00\x01\x02\xff"));

$selectRow4 = self::$driver->getQuery(true)
->select('id')
->from('jos_dbtest')
->where('data = '. self::$driver->quoteBinary("\x01\x01\x02\xff"));

$result = self::$driver->setQuery($selectRow3)->loadResult();
$this->assertThat($result, $this->equalTo(3), __LINE__);

$result = self::$driver->setQuery($selectRow4)->loadResult();
$this->assertThat($result, $this->equalTo(4), __LINE__);

$selectRows = self::$driver->getQuery(true)
->select('data')
->from('jos_dbtest')
->order('id');

// Test loadColumn
$result = self::$driver->setQuery($selectRows)->loadColumn();

foreach ($result as $i => $v)
{
$result[$i] = self::$driver->decodeBinary($v);
}

$expected = array(null, null, "\x00\x01\x02\xff", "\x01\x01\x02\xff");
$this->assertThat($result, $this->equalTo($expected), __LINE__);

// Test loadAssocList
$result = self::$driver->setQuery($selectRows)->loadAssocList();

foreach ($result as $i => $v)
{
$result[$i]['data'] = self::$driver->decodeBinary($v['data']);
}

$expected = array(
array('data' => null),
array('data' => null),
array('data' => "\x00\x01\x02\xff"),
array('data' => "\x01\x01\x02\xff"),
);
$this->assertThat($result, $this->equalTo($expected), __LINE__);

// Test loadObjectList
$result = self::$driver->setQuery($selectRows)->loadObjectList();

foreach ($result as $i => $v)
{
$result[$i]->data = self::$driver->decodeBinary($v->data);
}

$expected = array(
(object) array('data' => null),
(object) array('data' => null),
(object) array('data' => "\x00\x01\x02\xff"),
(object) array('data' => "\x01\x01\x02\xff"),
);
$this->assertThat($result, $this->equalTo($expected), __LINE__);
}

Expand Down Expand Up @@ -683,7 +834,7 @@ public function testTransactionCommit()
self::$driver->setQuery($queryCheck);
$result = self::$driver->loadRow();

$expected = array('6', 'testTitle', '1970-01-01 00:00:00', 'testDescription');
$expected = array('6', 'testTitle', '1970-01-01 00:00:00', 'testDescription', null);

$this->assertThat($result, $this->equalTo($expected), __LINE__);
}
Expand Down
Loading

0 comments on commit 3b2ef25

Please sign in to comment.