Skip to content

Commit

Permalink
Merge pull request #8978 from chinpei215/per-column-collation
Browse files Browse the repository at this point in the history
Add support for per-column collation
  • Loading branch information
markstory committed Jun 25, 2016
2 parents 5552d07 + eed02ac commit 64ca29f
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 7 deletions.
5 changes: 5 additions & 0 deletions src/Database/Schema/MysqlSchema.php
Expand Up @@ -361,6 +361,11 @@ public function columnSql(Table $table, $name)
$out .= ' UNSIGNED';
}

$hasCollate = ['text', 'string'];
if (in_array($data['type'], $hasCollate, true) && isset($data['collate']) && $data['collate'] !== '') {
$out .= ' COLLATE ' . $data['collate'];
}

if (isset($data['null']) && $data['null'] === false) {
$out .= ' NOT NULL';
}
Expand Down
7 changes: 7 additions & 0 deletions src/Database/Schema/PostgresSchema.php
Expand Up @@ -42,6 +42,7 @@ public function describeColumnSql($tableName, $config)
data_type AS type,
is_nullable AS null, column_default AS default,
character_maximum_length AS char_length,
c.collation_name,
d.description as comment,
ordinal_position,
pg_get_serial_sequence(attr.attrelid::regclass::text, attr.attname) IS NOT NULL AS has_serial
Expand Down Expand Up @@ -153,6 +154,7 @@ public function convertColumnDescription(Table $table, $row)
$field += [
'default' => $this->_defaultValue($row['default']),
'null' => $row['null'] === 'YES' ? true : false,
'collate' => $row['collation_name'],
'comment' => $row['comment']
];
$field['length'] = $row['char_length'] ?: $field['length'];
Expand Down Expand Up @@ -370,6 +372,11 @@ public function columnSql(Table $table, $name)
}
}

$hasCollate = ['text', 'string'];
if (in_array($data['type'], $hasCollate, true) && isset($data['collate']) && $data['collate'] !== '') {
$out .= ' COLLATE "' . $data['collate'] . '"';
}

if ($data['type'] === 'float' && isset($data['precision'])) {
$out .= '(' . (int)$data['precision'] . ')';
}
Expand Down
9 changes: 8 additions & 1 deletion src/Database/Schema/SqlserverSchema.php
Expand Up @@ -50,7 +50,8 @@ public function describeColumnSql($tableName, $config)
AC.scale AS [scale],
AC.is_identity AS [autoincrement],
AC.is_nullable AS [null],
OBJECT_DEFINITION(AC.default_object_id) AS [default]
OBJECT_DEFINITION(AC.default_object_id) AS [default],
AC.collation_name AS [collation_name]
FROM sys.[objects] T
INNER JOIN sys.[schemas] S ON S.[schema_id] = T.[schema_id]
INNER JOIN sys.[all_columns] AC ON T.[object_id] = AC.[object_id]
Expand Down Expand Up @@ -162,6 +163,7 @@ public function convertColumnDescription(Table $table, $row)
$field += [
'null' => $row['null'] === '1' ? true : false,
'default' => $this->_defaultValue($row['default']),
'collate' => $row['collation_name'],
];
$table->addColumn($row['name'], $field);
}
Expand Down Expand Up @@ -373,6 +375,11 @@ public function columnSql(Table $table, $name)
$out .= sprintf('%s(%d)', $type, $data['length']);
}

$hasCollate = ['text', 'string'];
if (in_array($data['type'], $hasCollate, true) && isset($data['collate']) && $data['collate'] !== '') {
$out .= ' COLLATE ' . $data['collate'];
}

if ($data['type'] === 'float' && isset($data['precision'])) {
$out .= '(' . (int)$data['precision'] . ')';
}
Expand Down
4 changes: 4 additions & 0 deletions src/Database/Schema/Table.php
Expand Up @@ -137,6 +137,10 @@ class Table
protected static $_columnExtras = [
'string' => [
'fixed' => null,
'collate' => null,
],
'text' => [
'collate' => null,
],
'integer' => [
'unsigned' => null,
Expand Down
24 changes: 22 additions & 2 deletions tests/TestCase/Database/Schema/MysqlSchemaTest.php
Expand Up @@ -181,13 +181,13 @@ public function testConvertColumn($type, $expected)
'Type' => $type,
'Null' => 'YES',
'Default' => 'Default value',
'Collation' => 'Collate information',
'Collation' => 'utf8_general_ci',
'Comment' => 'Comment section',
];
$expected += [
'null' => true,
'default' => 'Default value',
'collate' => 'Collate information',
'collate' => 'utf8_general_ci',
'comment' => 'Comment section',
];

Expand Down Expand Up @@ -291,6 +291,7 @@ public function testDescribeTable()
'precision' => null,
'comment' => 'A title',
'fixed' => null,
'collate' => 'utf8_general_ci',
],
'body' => [
'type' => 'text',
Expand All @@ -299,6 +300,7 @@ public function testDescribeTable()
'length' => null,
'precision' => null,
'comment' => null,
'collate' => 'utf8_general_ci',
],
'author_id' => [
'type' => 'integer',
Expand Down Expand Up @@ -481,6 +483,11 @@ public static function columnSqlProvider()
['type' => 'uuid'],
'`id` CHAR(36)'
],
[
'title',
['type' => 'string', 'length' => 255, 'null' => false, 'collate' => 'utf8_unicode_ci'],
'`title` VARCHAR(255) COLLATE utf8_unicode_ci NOT NULL'
],
// Text
[
'body',
Expand All @@ -502,6 +509,11 @@ public static function columnSqlProvider()
['type' => 'text', 'length' => Table::LENGTH_LONG, 'null' => false],
'`body` LONGTEXT NOT NULL'
],
[
'body',
['type' => 'text', 'null' => false, 'collate' => 'utf8_unicode_ci'],
'`body` TEXT COLLATE utf8_unicode_ci NOT NULL'
],
// Blob / binary
[
'body',
Expand Down Expand Up @@ -933,6 +945,13 @@ public function testCreateSql()
'type' => 'text',
'comment' => ''
])
->addColumn('hash', [
'type' => 'string',
'fixed' => true,
'length' => 40,
'collate' => 'latin1_bin',
'null' => false,
])
->addColumn('created', 'datetime')
->addConstraint('primary', [
'type' => 'primary',
Expand All @@ -949,6 +968,7 @@ public function testCreateSql()
`id` INTEGER NOT NULL AUTO_INCREMENT,
`title` VARCHAR(255) NOT NULL COMMENT 'The title',
`body` TEXT,
`hash` CHAR(40) COLLATE latin1_bin NOT NULL,
`created` DATETIME,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci
Expand Down
23 changes: 23 additions & 0 deletions tests/TestCase/Database/Schema/PostgresSchemaTest.php
Expand Up @@ -217,11 +217,13 @@ public function testConvertColumn($type, $expected)
'default' => 'Default value',
'comment' => 'Comment section',
'char_length' => null,
'collation_name' => 'ja_JP.utf8',
];
$expected += [
'null' => true,
'default' => 'Default value',
'comment' => 'Comment section',
'collate' => 'ja_JP.utf8',
];

$driver = $this->getMockBuilder('Cake\Database\Driver\Postgres')->getMock();
Expand Down Expand Up @@ -299,6 +301,7 @@ public function testDescribeTable()
'precision' => null,
'comment' => 'a title',
'fixed' => null,
'collate' => null,
],
'body' => [
'type' => 'text',
Expand All @@ -307,6 +310,7 @@ public function testDescribeTable()
'length' => null,
'precision' => null,
'comment' => null,
'collate' => null,
],
'author_id' => [
'type' => 'integer',
Expand Down Expand Up @@ -417,6 +421,7 @@ public function testDescribeTableWithDefaults()
'precision' => null,
'comment' => null,
'fixed' => null,
'collate' => null,
],
'bio' => [
'type' => 'date',
Expand Down Expand Up @@ -623,6 +628,11 @@ public static function columnSqlProvider()
['type' => 'string'],
'"title" VARCHAR'
],
[
'title',
['type' => 'string', 'length' => 255, 'null' => false, 'collate' => 'C'],
'"title" VARCHAR(255) COLLATE "C" NOT NULL'
],
// Text
[
'body',
Expand All @@ -644,6 +654,11 @@ public static function columnSqlProvider()
['type' => 'text', 'length' => Table::LENGTH_LONG, 'null' => false],
'"body" TEXT NOT NULL'
],
[
'body',
['type' => 'text', 'null' => false, 'collate' => 'C'],
'"body" TEXT COLLATE "C" NOT NULL'
],
// Integers
[
'post_id',
Expand Down Expand Up @@ -981,6 +996,13 @@ public function testCreateSql()
'comment' => 'This is the title',
])
->addColumn('body', ['type' => 'text'])
->addColumn('hash', [
'type' => 'string',
'fixed' => true,
'length' => 40,
'collate' => 'C',
'null' => false,
])
->addColumn('created', 'datetime')
->addConstraint('primary', [
'type' => 'primary',
Expand All @@ -996,6 +1018,7 @@ public function testCreateSql()
"id" SERIAL,
"title" VARCHAR NOT NULL,
"body" TEXT,
"hash" CHAR(40) COLLATE "C" NOT NULL,
"created" TIMESTAMP,
PRIMARY KEY ("id")
)
Expand Down
4 changes: 4 additions & 0 deletions tests/TestCase/Database/Schema/SqliteSchemaTest.php
Expand Up @@ -296,6 +296,7 @@ public function testDescribeTable()
'precision' => null,
'fixed' => null,
'comment' => null,
'collate' => null,
],
'body' => [
'type' => 'text',
Expand All @@ -304,6 +305,7 @@ public function testDescribeTable()
'length' => null,
'precision' => null,
'comment' => null,
'collate' => null,
],
'author_id' => [
'type' => 'integer',
Expand Down Expand Up @@ -339,6 +341,7 @@ public function testDescribeTable()
'precision' => null,
'fixed' => null,
'comment' => null,
'collate' => null,
],
'field2' => [
'type' => 'string',
Expand All @@ -348,6 +351,7 @@ public function testDescribeTable()
'precision' => null,
'fixed' => null,
'comment' => null,
'collate' => null,
],
];
$this->assertInstanceOf('Cake\Database\Schema\Table', $result);
Expand Down

0 comments on commit 64ca29f

Please sign in to comment.