Skip to content

Commit

Permalink
Merge pull request #13843 from karmicdice/4.x-char-support
Browse files Browse the repository at this point in the history
Added TableSchema::TYPE_CHAR to replace fixed-length strings
  • Loading branch information
markstory committed Nov 7, 2019
2 parents fa662cc + f5b643a commit 0a646fa
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 68 deletions.
10 changes: 7 additions & 3 deletions src/Database/Schema/MysqlSchema.php
Expand Up @@ -124,7 +124,7 @@ protected function _convertColumn(string $column): array
return ['type' => TableSchema::TYPE_UUID, 'length' => null];
}
if ($col === 'char') {
return ['type' => TableSchema::TYPE_STRING, 'length' => $length, 'fixed' => true];
return ['type' => TableSchema::TYPE_CHAR, 'length' => $length];
}
if (strpos($col, 'char') !== false) {
return ['type' => TableSchema::TYPE_STRING, 'length' => $length];
Expand Down Expand Up @@ -327,12 +327,14 @@ public function columnSql(TableSchema $schema, string $name): string
TableSchema::TYPE_TIME => ' TIME',
TableSchema::TYPE_DATETIME => ' DATETIME',
TableSchema::TYPE_TIMESTAMP => ' TIMESTAMP',
TableSchema::TYPE_CHAR => ' CHAR',
TableSchema::TYPE_UUID => ' CHAR(36)',
TableSchema::TYPE_JSON => $nativeJson ? ' JSON' : ' LONGTEXT',
];
$specialMap = [
'string' => true,
'text' => true,
'char' => true,
'binary' => true,
];
if (isset($typeMap[$data['type']])) {
Expand All @@ -341,7 +343,7 @@ public function columnSql(TableSchema $schema, string $name): string
if (isset($specialMap[$data['type']])) {
switch ($data['type']) {
case TableSchema::TYPE_STRING:
$out .= !empty($data['fixed']) ? ' CHAR' : ' VARCHAR';
$out .= ' VARCHAR';
if (!isset($data['length'])) {
$data['length'] = 255;
}
Expand Down Expand Up @@ -382,12 +384,13 @@ public function columnSql(TableSchema $schema, string $name): string
}
$hasLength = [
TableSchema::TYPE_INTEGER,
TableSchema::TYPE_CHAR,
TableSchema::TYPE_SMALLINTEGER,
TableSchema::TYPE_TINYINTEGER,
TableSchema::TYPE_STRING,
];
if (in_array($data['type'], $hasLength, true) && isset($data['length'])) {
$out .= '(' . (int)$data['length'] . ')';
$out .= '(' . $data['length'] . ')';
}

$hasPrecision = [TableSchema::TYPE_FLOAT, TableSchema::TYPE_DECIMAL];
Expand Down Expand Up @@ -417,6 +420,7 @@ public function columnSql(TableSchema $schema, string $name): string

$hasCollate = [
TableSchema::TYPE_TEXT,
TableSchema::TYPE_CHAR,
TableSchema::TYPE_STRING,
];
if (in_array($data['type'], $hasCollate, true) && isset($data['collate']) && $data['collate'] !== '') {
Expand Down
38 changes: 20 additions & 18 deletions src/Database/Schema/PostgresSchema.php
Expand Up @@ -111,15 +111,15 @@ protected function _convertColumn(string $column): array
if ($col === 'uuid') {
return ['type' => TableSchema::TYPE_UUID, 'length' => null];
}
if ($col === 'char' || $col === 'character') {
return ['type' => TableSchema::TYPE_STRING, 'fixed' => true, 'length' => $length];
if ($col === 'char') {
return ['type' => TableSchema::TYPE_CHAR, 'length' => $length];
}
if (strpos($col, 'character') !== false) {
return ['type' => TableSchema::TYPE_STRING, 'length' => $length];
}
// money is 'string' as it includes arbitrary text content
// before the number value.
if (
strpos($col, 'char') !== false ||
strpos($col, 'money') !== false
) {
if (strpos($col, 'money') !== false || $col === 'string') {
return ['type' => TableSchema::TYPE_STRING, 'length' => $length];
}
if (strpos($col, 'text') !== false) {
Expand All @@ -142,7 +142,9 @@ protected function _convertColumn(string $column): array
return ['type' => TableSchema::TYPE_JSON, 'length' => null];
}

return ['type' => TableSchema::TYPE_STRING, 'length' => null];
$length = is_numeric($length) ? $length : null;

return ['type' => TableSchema::TYPE_STRING, 'length' => $length];
}

/**
Expand Down Expand Up @@ -372,6 +374,7 @@ public function columnSql(TableSchema $schema, string $name): string
TableSchema::TYPE_DATETIME => ' TIMESTAMP',
TableSchema::TYPE_TIMESTAMP => ' TIMESTAMP',
TableSchema::TYPE_UUID => ' UUID',
TableSchema::TYPE_CHAR => ' CHAR',
TableSchema::TYPE_JSON => ' JSONB',
];

Expand All @@ -395,31 +398,30 @@ public function columnSql(TableSchema $schema, string $name): string
$out .= ' BYTEA';
}

if ($data['type'] === TableSchema::TYPE_CHAR) {
$out .= '(' . $data['length'] . ')';
}

if (
$data['type'] === TableSchema::TYPE_STRING ||
(
$data['type'] === TableSchema::TYPE_TEXT &&
$data['length'] === TableSchema::LENGTH_TINY
)
) {
$isFixed = !empty($data['fixed']);
$type = ' VARCHAR';
if ($isFixed) {
$type = ' CHAR';
}
$out .= $type;
if (isset($data['length'])) {
$out .= '(' . (int)$data['length'] . ')';
$out .= ' VARCHAR';
if (isset($data['length']) && $data['length'] !== '') {
$out .= '(' . $data['length'] . ')';
}
}

$hasCollate = [TableSchema::TYPE_TEXT, TableSchema::TYPE_STRING];
$hasCollate = [TableSchema::TYPE_TEXT, TableSchema::TYPE_STRING, TableSchema::TYPE_CHAR];
if (in_array($data['type'], $hasCollate, true) && isset($data['collate']) && $data['collate'] !== '') {
$out .= ' COLLATE "' . $data['collate'] . '"';
}

if ($data['type'] === TableSchema::TYPE_FLOAT && isset($data['precision'])) {
$out .= '(' . (int)$data['precision'] . ')';
$out .= '(' . $data['precision'] . ')';
}

if (
Expand All @@ -429,7 +431,7 @@ public function columnSql(TableSchema $schema, string $name): string
isset($data['precision'])
)
) {
$out .= '(' . (int)$data['length'] . ',' . (int)$data['precision'] . ')';
$out .= '(' . $data['length'] . ',' . (int)$data['precision'] . ')';
}

if (isset($data['null']) && $data['null'] === false) {
Expand Down
11 changes: 8 additions & 3 deletions src/Database/Schema/SqliteSchema.php
Expand Up @@ -108,7 +108,7 @@ protected function _convertColumn(string $column): array
return ['type' => TableSchema::TYPE_UUID, 'length' => null];
}
if ($col === 'char') {
return ['type' => TableSchema::TYPE_STRING, 'fixed' => true, 'length' => $length];
return ['type' => TableSchema::TYPE_CHAR, 'length' => $length];
}
if (strpos($col, 'char') !== false) {
return ['type' => TableSchema::TYPE_STRING, 'length' => $length];
Expand Down Expand Up @@ -307,6 +307,7 @@ public function columnSql(TableSchema $schema, string $name): string
$typeMap = [
TableSchema::TYPE_BINARY_UUID => ' BINARY(16)',
TableSchema::TYPE_UUID => ' CHAR(36)',
TableSchema::TYPE_CHAR => ' CHAR',
TableSchema::TYPE_TINYINTEGER => ' TINYINT',
TableSchema::TYPE_SMALLINTEGER => ' SMALLINT',
TableSchema::TYPE_INTEGER => ' INTEGER',
Expand Down Expand Up @@ -349,6 +350,10 @@ public function columnSql(TableSchema $schema, string $name): string
$out .= ' TEXT';
}

if ($data['type'] === TableSchema::TYPE_CHAR) {
$out .= '(' . $data['length'] . ')';
}

if (
$data['type'] === TableSchema::TYPE_STRING ||
(
Expand All @@ -359,13 +364,13 @@ public function columnSql(TableSchema $schema, string $name): string
$out .= ' VARCHAR';

if (isset($data['length'])) {
$out .= '(' . (int)$data['length'] . ')';
$out .= '(' . $data['length'] . ')';
}
}

if ($data['type'] === TableSchema::TYPE_BINARY) {
if (isset($data['length'])) {
$out .= ' BLOB(' . (int)$data['length'] . ')';
$out .= ' BLOB(' . $data['length'] . ')';
} else {
$out .= ' BLOB';
}
Expand Down
25 changes: 13 additions & 12 deletions src/Database/Schema/SqlserverSchema.php
Expand Up @@ -94,6 +94,10 @@ protected function _convertColumn(
return ['type' => TableSchema::TYPE_TIMESTAMP, 'length' => null];
}

if ($col === 'char') {
return ['type' => TableSchema::TYPE_CHAR, 'length' => $length];
}

if ($col === 'tinyint') {
return ['type' => TableSchema::TYPE_TINYINTEGER, 'length' => $precision ?: 3];
}
Expand Down Expand Up @@ -134,7 +138,7 @@ protected function _convertColumn(
}

if (strpos($col, 'char') !== false) {
return ['type' => TableSchema::TYPE_STRING, 'fixed' => true, 'length' => $length];
return ['type' => TableSchema::TYPE_CHAR, 'length' => $length];
}

if (strpos($col, 'text') !== false) {
Expand Down Expand Up @@ -357,6 +361,7 @@ public function columnSql(TableSchema $schema, string $name): string
TableSchema::TYPE_BIGINTEGER => ' BIGINT',
TableSchema::TYPE_BINARY_UUID => ' UNIQUEIDENTIFIER',
TableSchema::TYPE_BOOLEAN => ' BIT',
TableSchema::TYPE_CHAR => ' NCHAR',
TableSchema::TYPE_FLOAT => ' FLOAT',
TableSchema::TYPE_DECIMAL => ' DECIMAL',
TableSchema::TYPE_DATE => ' DATE',
Expand All @@ -382,6 +387,10 @@ public function columnSql(TableSchema $schema, string $name): string
$out .= ' NVARCHAR(MAX)';
}

if ($data['type'] === TableSchema::TYPE_CHAR) {
$out .= '(' . $data['length'] . ')';
}

if ($data['type'] === TableSchema::TYPE_BINARY) {
if (
!isset($data['length'])
Expand All @@ -407,19 +416,11 @@ public function columnSql(TableSchema $schema, string $name): string
)
) {
$type = ' NVARCHAR';

if (!empty($data['fixed'])) {
$type = ' NCHAR';
}

if (!isset($data['length'])) {
$data['length'] = 255;
}

$out .= sprintf('%s(%d)', $type, $data['length']);
$length = $data['length'] ?? TableSchema::LENGTH_TINY;
$out .= sprintf('%s(%d)', $type, $length);
}

$hasCollate = [TableSchema::TYPE_TEXT, TableSchema::TYPE_STRING];
$hasCollate = [TableSchema::TYPE_TEXT, TableSchema::TYPE_STRING, TableSchema::TYPE_CHAR];
if (in_array($data['type'], $hasCollate, true) && isset($data['collate']) && $data['collate'] !== '') {
$out .= ' COLLATE ' . $data['collate'];
}
Expand Down
4 changes: 3 additions & 1 deletion src/Database/Schema/TableSchema.php
Expand Up @@ -137,7 +137,9 @@ class TableSchema implements TableSchemaInterface, SqlGeneratorInterface
*/
protected static $_columnExtras = [
'string' => [
'fixed' => null,
'collate' => null,
],
'char' => [
'collate' => null,
],
'text' => [
Expand Down
7 changes: 7 additions & 0 deletions src/Database/Schema/TableSchemaInterface.php
Expand Up @@ -79,6 +79,13 @@ interface TableSchemaInterface extends SchemaInterface
*/
public const TYPE_STRING = 'string';

/**
* Char column type
*
* @var string
*/
public const TYPE_CHAR = 'char';

/**
* Text column type
*
Expand Down
1 change: 1 addition & 0 deletions src/Database/TypeFactory.php
Expand Up @@ -44,6 +44,7 @@ class TypeFactory
'float' => Type\FloatType::class,
'json' => Type\JsonType::class,
'string' => Type\StringType::class,
'char' => Type\StringType::class,
'text' => Type\StringType::class,
'time' => Type\TimeType::class,
'timestamp' => Type\DateTimeType::class,
Expand Down
12 changes: 8 additions & 4 deletions tests/TestCase/Database/Schema/MysqlSchemaTest.php
Expand Up @@ -114,7 +114,7 @@ public static function convertColumnProvider()
],
[
'CHAR(25)',
['type' => 'string', 'length' => 25, 'fixed' => true, 'collate' => 'utf8_general_ci'],
['type' => 'char', 'length' => 25],
],
[
'CHAR(36)',
Expand Down Expand Up @@ -335,7 +335,6 @@ public function testDescribeTable()
'length' => 20,
'precision' => null,
'comment' => 'A title',
'fixed' => null,
'collate' => 'utf8_general_ci',
],
'body' => [
Expand Down Expand Up @@ -525,7 +524,7 @@ public static function columnSqlProvider()
],
[
'id',
['type' => 'string', 'length' => 32, 'fixed' => true, 'null' => false],
['type' => 'char', 'length' => 32, 'fixed' => true, 'null' => false],
'`id` CHAR(32) NOT NULL',
],
[
Expand All @@ -538,6 +537,11 @@ public static function columnSqlProvider()
['type' => 'uuid'],
'`id` CHAR(36)',
],
[
'id',
['type' => 'char', 'length' => 36],
'`id` CHAR(36)',
],
[
'id',
['type' => 'binaryuuid'],
Expand Down Expand Up @@ -1079,7 +1083,7 @@ public function testCreateSql()
'type' => 'json',
])
->addColumn('hash', [
'type' => 'string',
'type' => 'char',
'fixed' => true,
'length' => 40,
'collate' => 'latin1_bin',
Expand Down

0 comments on commit 0a646fa

Please sign in to comment.