Skip to content

Commit

Permalink
Merge branch 'master' into ease-local-testing
Browse files Browse the repository at this point in the history
  • Loading branch information
arogachev committed Dec 2, 2024
2 parents b87162d + 47ded78 commit 059b30e
Show file tree
Hide file tree
Showing 13 changed files with 237 additions and 295 deletions.
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@
- Chg #339: Replace call of `SchemaInterface::getRawTableName()` to `QuoterInterface::getRawTableName()` (@Tigrov)
- New #342: Add JSON overlaps condition builder (@Tigrov)
- Enh #344: Update `bit` type according to main PR yiisoft/db#860 (@Tigrov)
- New #346: Implement `ColumnFactory` class (@Tigrov)
- New #346, #361: Implement `ColumnFactory` class (@Tigrov)
- Enh #347, #353: Raise minimum PHP version to `^8.1` with minor refactoring (@Tigrov)
- Bug #349, #352: Restore connection if closed by connection timeout (@Tigrov)
- Enh #354: Separate column type constants (@Tigrov)
- New #355: Realize `ColumnBuilder` class (@Tigrov)
- Enh #357: Update according changes in `ColumnSchemaInterface` (@Tigrov)
- New #358: Add `ColumnDefinitionBuilder` class (@Tigrov)
- New #358, #365: Add `ColumnDefinitionBuilder` class (@Tigrov)
- Enh #359: Refactor `Dsn` class (@Tigrov)
- Enh #361, #362: Refactor `Schema::findColumns()` method (@Tigrov)
- Enh #363: Refactor `Schema::normalizeDefaultValue()` method and move it to `ColumnFactory` class (@Tigrov)
- Enh #366: Refactor `Quoter::quoteValue()` method (@Tigrov)

## 1.2.0 March 21, 2024

Expand Down
2 changes: 1 addition & 1 deletion src/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ protected function buildCommentString(): string
return '';
}

return ' COMMENT ' . (string) (new Quoter('`', '`'))->quoteValue($this->getComment());
return ' COMMENT ' . (new Quoter('`', '`'))->quoteValue($this->getComment() ?? '');
}

public function asString(): string
Expand Down
14 changes: 10 additions & 4 deletions src/Column/ColumnDefinitionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ final class ColumnDefinitionBuilder extends AbstractColumnDefinitionBuilder
{
protected const AUTO_INCREMENT_KEYWORD = 'AUTO_INCREMENT';

protected const GENERATE_UUID_EXPRESSION = 'uuid_to_bin(uuid())';
protected const GENERATE_UUID_EXPRESSION = "unhex(replace(uuid(),'-',''))";

protected const TYPES_WITH_SIZE = [
'bit',
Expand Down Expand Up @@ -64,13 +64,13 @@ protected function buildComment(ColumnSchemaInterface $column): string
{
$comment = $column->getComment();

return $comment === null ? '' : ' COMMENT ' . (string) $this->queryBuilder->quoter()->quoteValue($comment);
return $comment === null ? '' : ' COMMENT ' . $this->queryBuilder->quoter()->quoteValue($comment);
}

protected function getDbType(ColumnSchemaInterface $column): string
{
/** @psalm-suppress DocblockTypeContradiction */
return match ($column->getType()) {
$dbType = $column->getDbType() ?? match ($column->getType()) {
ColumnType::BOOLEAN => 'bit(1)',
ColumnType::BIT => 'bit',
ColumnType::TINYINT => 'tinyint',
Expand All @@ -82,7 +82,7 @@ protected function getDbType(ColumnSchemaInterface $column): string
ColumnType::DECIMAL => 'decimal',
ColumnType::MONEY => 'decimal',
ColumnType::CHAR => 'char',
ColumnType::STRING => 'varchar',
ColumnType::STRING => 'varchar(' . ($column->getSize() ?? 255) . ')',
ColumnType::TEXT => 'text',
ColumnType::BINARY => 'blob',
ColumnType::UUID => 'binary(16)',
Expand All @@ -95,5 +95,11 @@ protected function getDbType(ColumnSchemaInterface $column): string
ColumnType::JSON => 'json',
default => 'varchar',
};

if ($dbType === 'double' && $column->getSize() !== null) {
return 'double(' . $column->getSize() . ',' . ($column->getScale() ?? 0) . ')';
}

return $dbType;
}
}
65 changes: 56 additions & 9 deletions src/Column/ColumnFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,25 @@
namespace Yiisoft\Db\Mysql\Column;

use Yiisoft\Db\Constant\ColumnType;
use Yiisoft\Db\Expression\Expression;
use Yiisoft\Db\Schema\Column\AbstractColumnFactory;
use Yiisoft\Db\Schema\Column\ColumnSchemaInterface;

use function bindec;
use function in_array;
use function preg_match;
use function str_starts_with;
use function substr;

final class ColumnFactory extends AbstractColumnFactory
{
/**
* Mapping from physical column types (keys) to abstract column types (values).
*
* @var string[]
*
* @psalm-suppress MissingClassConstType
* @psalm-var array<string, ColumnType::*>
*/
private const TYPE_MAP = [
protected const TYPE_MAP = [
'bit' => ColumnType::BIT,
'tinyint' => ColumnType::TINYINT,
'smallint' => ColumnType::SMALLINT,
Expand Down Expand Up @@ -50,17 +57,57 @@ final class ColumnFactory extends AbstractColumnFactory

protected function getType(string $dbType, array $info = []): string
{
$type = self::TYPE_MAP[$dbType] ?? ColumnType::STRING;

if ($type === ColumnType::BIT && isset($info['size']) && $info['size'] === 1) {
if ($dbType === 'bit' && isset($info['size']) && $info['size'] === 1) {
return ColumnType::BOOLEAN;
}

return $type;
return parent::getType($dbType, $info);
}

protected function normalizeDefaultValue(string|null $defaultValue, ColumnSchemaInterface $column): mixed
{
if (
$defaultValue === null
|| $column->isPrimaryKey()
|| $column->isComputed()
) {
return null;
}

return $this->normalizeNotNullDefaultValue($defaultValue, $column);
}

protected function isDbType(string $dbType): bool
protected function normalizeNotNullDefaultValue(string $defaultValue, ColumnSchemaInterface $column): mixed
{
return isset(self::TYPE_MAP[$dbType]);
if ($defaultValue === '') {
return $column->phpTypecast($defaultValue);
}

if (
in_array($column->getType(), [ColumnType::TIMESTAMP, ColumnType::DATETIME, ColumnType::DATE, ColumnType::TIME], true)
&& preg_match('/^current_timestamp(?:\((\d*)\))?$/i', $defaultValue, $matches) === 1
) {
return new Expression('CURRENT_TIMESTAMP' . (!empty($matches[1]) ? '(' . $matches[1] . ')' : ''));
}

if (!empty($column->getExtra())) {
return new Expression($defaultValue);
}

if ($defaultValue[0] === "'" && $defaultValue[-1] === "'") {
$value = substr($defaultValue, 1, -1);
$value = str_replace("''", "'", $value);

return $column->phpTypecast($value);
}

if (
str_starts_with($defaultValue, "b'")
&& in_array($column->getType(), [ColumnType::BOOLEAN, ColumnType::BIT], true)
) {
return $column->phpTypecast(bindec(substr($defaultValue, 2, -1)));
}

return $column->phpTypecast($defaultValue);
}
}
4 changes: 2 additions & 2 deletions src/DDLQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public function addCommentOnColumn(string $table, string $column, string $commen
. $this->quoter->quoteColumnName($column)
. (empty($definition) ? '' : ' ' . $definition)
. ' COMMENT '
. (string) $this->quoter->quoteValue($comment);
. $this->quoter->quoteValue($comment);

if ($check === 1) {
$alterSql .= ' ' . $checkMatches[0];
Expand All @@ -70,7 +70,7 @@ public function addCommentOnTable(string $table, string $comment): string
return 'ALTER TABLE '
. $this->quoter->quoteTableName($table)
. ' COMMENT '
. (string) $this->quoter->quoteValue($comment);
. $this->quoter->quoteValue($comment);
}

public function addDefaultValue(string $table, string $name, string $column, mixed $value): string
Expand Down
23 changes: 11 additions & 12 deletions src/Quoter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,23 @@

use Yiisoft\Db\Schema\Quoter as BaseQuoter;

use function is_string;
use function str_replace;
use function strtr;

/**
* Implements MySQL, MariaDB quoting and unquoting methods.
*/
final class Quoter extends BaseQuoter
{
public function quoteValue(mixed $value): mixed
public function quoteValue(string $value): string
{
if (!is_string($value)) {
return $value;
}

return "'" . str_replace(
['\\', "\x00", "\n", "\r", "'", '"', "\x1a"],
['\\\\', '\\0', '\\n', '\\r', "\'", '\"', '\\Z'],
$value
) . "'";
return "'" . strtr($value, [
'\\' => '\\\\',
"\x00" => '\\0',
"\n" => '\\n',
"\r" => '\\r',
"'" => "\'",
'"' => '\"',
"\x1a" => '\\Z',
]) . "'";
}
}
Loading

0 comments on commit 059b30e

Please sign in to comment.