Skip to content

Commit

Permalink
Added integration test for json column describe in Mysql
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Mar 19, 2016
1 parent 518ac1b commit 5ac1f7d
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 19 deletions.
32 changes: 32 additions & 0 deletions src/Database/Driver/Mysql.php
Expand Up @@ -44,6 +44,20 @@ class Mysql extends Driver
'init' => [],
];

/**
* The server version
*
* @var string
*/
protected $_version;

/**
* Whether or not the server supports native JSON
*
* @var bool
*/
protected $_supportsNativeJson;

/**
* Establishes a connection to the database server
*
Expand Down Expand Up @@ -141,4 +155,22 @@ public function supportsDynamicConstraints()
{
return true;
}

/**
* Returns true if the server supports native JSON columns
*
* @return bool
*/
public function supportsNativeJson()
{
if ($this->_supportsNativeJson !== null) {
return $this->_supportsNativeJson;
}

if ($this->_version === null) {
$this->_version = $this->_connection->getAttribute(PDO::ATTR_SERVER_VERSION);
}

return $this->_supportsNativeJson = version_compare($this->_version, '5.7.0', '>=');
}
}
3 changes: 3 additions & 0 deletions src/Database/Schema/MysqlSchema.php
Expand Up @@ -287,6 +287,8 @@ public function columnSql(Table $table, $name)
{
$data = $table->column($name);
$out = $this->_driver->quoteIdentifier($name);
$nativeJson = $this->_driver->supportsNativeJson();

$typeMap = [
'integer' => ' INTEGER',
'biginteger' => ' BIGINT',
Expand All @@ -300,6 +302,7 @@ public function columnSql(Table $table, $name)
'datetime' => ' DATETIME',
'timestamp' => ' TIMESTAMP',
'uuid' => ' CHAR(36)',
'json' => $nativeJson ? ' JSON' : ' LONGTEXT'
];
$specialMap = [
'string' => true,
Expand Down
78 changes: 59 additions & 19 deletions tests/TestCase/Database/Schema/MysqlSchemaTest.php
Expand Up @@ -196,32 +196,43 @@ protected function _createTables($connection)
$this->_needsConnection();
$connection->execute('DROP TABLE IF EXISTS schema_articles');
$connection->execute('DROP TABLE IF EXISTS schema_authors');
$connection->execute('DROP TABLE IF EXISTS schema_json');

$table = <<<SQL
CREATE TABLE schema_authors (
id INT(11) PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
bio TEXT,
created DATETIME
)ENGINE=InnoDB
CREATE TABLE schema_authors (
id INT(11) PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
bio TEXT,
created DATETIME
)ENGINE=InnoDB
SQL;
$connection->execute($table);

$table = <<<SQL
CREATE TABLE schema_articles (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(20) COMMENT 'A title',
body TEXT,
author_id INT(11) NOT NULL,
published BOOLEAN DEFAULT 0,
allow_comments TINYINT(1) DEFAULT 0,
created DATETIME,
KEY `author_idx` (`author_id`),
UNIQUE KEY `length_idx` (`title`(4)),
FOREIGN KEY `author_idx` (`author_id`) REFERENCES `schema_authors`(`id`) ON UPDATE CASCADE ON DELETE RESTRICT
) ENGINE=InnoDB COLLATE=utf8_general_ci
CREATE TABLE schema_articles (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(20) COMMENT 'A title',
body TEXT,
author_id INT(11) NOT NULL,
published BOOLEAN DEFAULT 0,
allow_comments TINYINT(1) DEFAULT 0,
created DATETIME,
KEY `author_idx` (`author_id`),
UNIQUE KEY `length_idx` (`title`(4)),
FOREIGN KEY `author_idx` (`author_id`) REFERENCES `schema_authors`(`id`) ON UPDATE CASCADE ON DELETE RESTRICT
) ENGINE=InnoDB COLLATE=utf8_general_ci
SQL;
$connection->execute($table);

if ($connection->driver()->supportsNativeJson()) {
$table = <<<SQL
CREATE TABLE schema_json (
id INT(11) PRIMARY KEY AUTO_INCREMENT,
data JSON NOT NULL
)
SQL;
$connection->execute($table);
}
}

/**
Expand Down Expand Up @@ -1032,6 +1043,35 @@ public function testConstructConnectsDriver()
$schema = new MysqlSchema($driver);
}

/**
* Tests json column parsing on Mysql 5.7+
*
* @return void
*/
public function testDescribeJson()
{
$connection = ConnectionManager::get('test');
$this->_createTables($connection);
$this->skipIf(!$connection->driver()->supportsNativeJson(), 'Does not support native json');

$schema = new SchemaCollection($connection);
$result = $schema->describe('schema_json');
$this->assertInstanceOf('Cake\Database\Schema\Table', $result);
$expected = [
'type' => 'json',
'null' => false,
'default' => null,
'length' => null,
'precision' => null,
'comment' => null,
];
$this->assertEquals(
$expected,
$result->column('data'),
'Field definition does not match for'
);
}

/**
* Get a schema instance with a mocked driver/pdo instances
*
Expand All @@ -1040,7 +1080,7 @@ public function testConstructConnectsDriver()
protected function _getMockedDriver()
{
$driver = new \Cake\Database\Driver\Mysql();
$mock = $this->getMock('FakePdo', ['quote', 'quoteIdentifier']);
$mock = $this->getMock('FakePdo', ['quote', 'quoteIdentifier', 'getAttribute']);
$mock->expects($this->any())
->method('quote')
->will($this->returnCallback(function ($value) {
Expand Down

0 comments on commit 5ac1f7d

Please sign in to comment.