Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for native UUID column type #1915

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/Propel/Generator/Model/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,16 @@ public function isTemporalType(): bool
return PropelTypes::isTemporalType($this->getType());
}

/**
* Returns whether this column is a uuid type.
*
* @return bool
*/
public function isUuidType(): bool
{
return PropelTypes::isUuidType($this->getType());
}

/**
* Returns whether the column is an array column.
*
Expand Down
27 changes: 27 additions & 0 deletions src/Propel/Generator/Model/PropelTypes.php
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,16 @@ class PropelTypes
*/
public const JSON_TYPE = 'string';

/**
* @var string
*/
public const UUID = 'UUID';

/**
* @var string
*/
public const UUID_NATIVE_TYPE = 'string';

/**
* Propel mapping types.
*
Expand Down Expand Up @@ -381,6 +391,7 @@ class PropelTypes
self::BU_TIMESTAMP,
self::SET,
self::JSON,
self::UUID,
];

/**
Expand Down Expand Up @@ -421,6 +432,7 @@ class PropelTypes
self::SET => self::SET_NATIVE_TYPE,
self::GEOMETRY => self::GEOMETRY,
self::JSON => self::JSON_TYPE,
self::UUID => self::UUID_NATIVE_TYPE,
];

/**
Expand Down Expand Up @@ -466,6 +478,7 @@ class PropelTypes
self::BU_DATE => PDO::PARAM_STR,
self::BU_TIMESTAMP => PDO::PARAM_STR,
self::JSON => PDO::PARAM_STR,
self::UUID => PDO::PARAM_STR,
];

/**
Expand Down Expand Up @@ -615,6 +628,20 @@ public static function isLobType(string $mappingType): bool
return in_array($mappingType, [self::VARBINARY, self::LONGVARBINARY, self::BLOB, self::OBJECT, self::GEOMETRY]);
}

/**
* Returns whether the given type is a UUID type.
*
* @param string $type
*
* @return bool
*/
public static function isUuidType(string $type): bool
{
return in_array($type, [
self::UUID,
dereuromark marked this conversation as resolved.
Show resolved Hide resolved
]);
}

/**
* Returns whether a passed-in PHP type is a primitive type.
*
Expand Down
1 change: 1 addition & 0 deletions src/Propel/Generator/Platform/MssqlPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ protected function initialize(): void
$this->setSchemaDomainMapping(new Domain(PropelTypes::PHP_ARRAY, 'VARCHAR(MAX)'));
$this->setSchemaDomainMapping(new Domain(PropelTypes::ENUM, 'TINYINT'));
$this->setSchemaDomainMapping(new Domain(PropelTypes::SET, 'INT'));
$this->setSchemaDomainMapping(new Domain(PropelTypes::UUID, 'UNIQUEIDENTIFIER'));
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/Propel/Generator/Platform/MysqlPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class MysqlPlatform extends DefaultPlatform
protected function initialize(): void
{
parent::initialize();
unset($this->schemaDomainMap[PropelTypes::UUID]);
$this->setSchemaDomainMapping(new Domain(PropelTypes::BOOLEAN, 'TINYINT', 1));
$this->setSchemaDomainMapping(new Domain(PropelTypes::NUMERIC, 'DECIMAL'));
$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, 'TEXT'));
Expand Down
1 change: 1 addition & 0 deletions src/Propel/Generator/Platform/OraclePlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ protected function initialize(): void
$this->setSchemaDomainMapping(new Domain(PropelTypes::PHP_ARRAY, 'NVARCHAR2', 2000));
$this->setSchemaDomainMapping(new Domain(PropelTypes::ENUM, 'NUMBER', 3, 0));
$this->setSchemaDomainMapping(new Domain(PropelTypes::SET, 'NUMBER'));
$this->setSchemaDomainMapping(new Domain(PropelTypes::UUID, 'UUID'));
}

/**
Expand Down
36 changes: 22 additions & 14 deletions src/Propel/Generator/Platform/PgsqlPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ protected function initialize(): void
$this->setSchemaDomainMapping(new Domain(PropelTypes::SET, 'INT4'));
$this->setSchemaDomainMapping(new Domain(PropelTypes::DECIMAL, 'NUMERIC'));
$this->setSchemaDomainMapping(new Domain(PropelTypes::DATETIME, 'TIMESTAMP'));
$this->setSchemaDomainMapping(new Domain(PropelTypes::UUID, 'uuid'));
}

/**
Expand Down Expand Up @@ -670,9 +671,6 @@ public function getModifyColumnDDL(ColumnDiff $columnDiff): string
}

if (!$toColumn->isAutoIncrement() && $fromColumn->isAutoIncrement()) {
$changedProperties['defaultValueValue'] = [$fromColumn->getDefaultValueString(), null];
$toColumn->setDefaultValue(null);

//remove sequence
if ($fromTable->getDatabase()->hasSequence($seqName)) {
$this->createOrDropSequences .= sprintf(
Expand Down Expand Up @@ -730,6 +728,18 @@ public function getModifyColumnDDL(ColumnDiff $columnDiff): string
return $ret;
}

/**
* @param string $type
*
* @return bool
*/
public function isUuid(string $type): bool
{
$strings = ['UUID'];

return in_array(strtoupper($type), $strings);
dereuromark marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* @param string $type
*
Expand Down Expand Up @@ -766,10 +776,6 @@ public function getUsingCast(Column $fromColumn, Column $toColumn): string
$toSqlType = strtoupper($toColumn->getDomain()->getSqlType());
$name = $fromColumn->getName();

if ($this->isNumber($fromSqlType) && $this->isString($toSqlType)) {
//cast from int to string
return ' ';
}
if ($this->isString($fromSqlType) && $this->isNumber($toSqlType)) {
//cast from string to int
return "
Expand All @@ -782,16 +788,18 @@ public function getUsingCast(Column $fromColumn, Column $toColumn): string
return " USING decode(CAST($name as text), 'escape')";
}

if ($fromSqlType === 'DATE' && $toSqlType === 'TIME') {
return ' USING NULL';
}
Comment on lines -785 to -787
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This DATE and TIME handling is dropped, why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function returns USING NULL per default, so this was just an extra step to get to the same result.


if ($this->isNumber($fromSqlType) && $this->isNumber($toSqlType)) {
if (
($this->isNumber($fromSqlType) && $this->isNumber($toSqlType)) ||
($this->isString($fromSqlType) && $this->isString($toSqlType)) ||
($this->isNumber($fromSqlType) && $this->isString($toSqlType)) ||
($this->isUuid($fromSqlType) && $this->isString($toSqlType))
) {
// no cast necessary
return '';
}

if ($this->isString($fromSqlType) && $this->isString($toSqlType)) {
return '';
if ($this->isString($fromSqlType) && $this->isUuid($toSqlType)) {
return " USING $name::uuid";
}

return ' USING NULL';
Expand Down
2 changes: 2 additions & 0 deletions src/Propel/Generator/Platform/SqlitePlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ protected function initialize(): void

$this->foreignKeySupport = version_compare($version, '3.6.19') >= 0;

unset($this->schemaDomainMap[PropelTypes::UUID]);

$this->setSchemaDomainMapping(new Domain(PropelTypes::NUMERIC, 'DECIMAL'));
$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, 'MEDIUMTEXT'));
$this->setSchemaDomainMapping(new Domain(PropelTypes::DATE, 'DATETIME'));
Expand Down
6 changes: 1 addition & 5 deletions src/Propel/Generator/Reverse/AbstractSchemaParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,7 @@ protected function getMappedPropelType(string $nativeType): ?string
$this->nativeToPropelTypeMap = $this->getTypeMapping();
}

if (isset($this->nativeToPropelTypeMap[$nativeType])) {
return $this->nativeToPropelTypeMap[$nativeType];
}

return null;
return $this->nativeToPropelTypeMap[$nativeType] ?? null;
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/Propel/Generator/Reverse/SqliteSchemaParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class SqliteSchemaParser extends AbstractSchemaParser
'text' => PropelTypes::LONGVARCHAR,
'enum' => PropelTypes::CHAR,
'set' => PropelTypes::CHAR,
'uuid' => PropelTypes::UUID,
];

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Propel/Runtime/ActiveQuery/Criteria.php
Original file line number Diff line number Diff line change
Expand Up @@ -2357,7 +2357,7 @@ public function getPrimaryKey(?self $criteria = null): ?ColumnMap
* WHERE some_column = some value AND could_have_another_column =
* another value AND so on.
*
* @param \Propel\Runtime\ActiveQuery\Criteria|array $updateValues A Criteria object containing values used in set clause.
* @param \Propel\Runtime\ActiveQuery\Criteria $updateValues A Criteria object containing values used in set clause.
* @param \Propel\Runtime\Connection\ConnectionInterface $con The ConnectionInterface connection object to use.
*
* @return int The number of rows affected by last update statement.
Expand All @@ -2366,7 +2366,7 @@ public function getPrimaryKey(?self $criteria = null): ?ColumnMap
* Note that the return value does require that this information is returned
* (supported) by the Propel db driver.
*/
public function doUpdate($updateValues, ConnectionInterface $con): int
public function doUpdate(Criteria $updateValues, ConnectionInterface $con): int
{
return UpdateQueryExecutor::execute($this, $updateValues, $con);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ protected function buildSimpleColumnNamesCsv(array $qualifiedColumnNames): strin
}

/**
* Build a comma separated list of placeholders, i.e. ":p1,:p2,:p3" for 3 placeholders.
*
* @param int $numberOfPlaceholders
*
* @return string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class UpdateQuerySqlBuilder extends AbstractSqlQueryBuilder

/**
* @psalm-var array<string, array<string>>
* @var array<string>
* @var array<array<string>>
*/
protected $updateTablesColumns;

Expand Down
10 changes: 10 additions & 0 deletions src/Propel/Runtime/Map/ColumnMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,16 @@ public function isText(): bool
]);
}

/**
* Whether this column contains UUIDs.
*
* @return bool
*/
public function isUUID(): bool
dereuromark marked this conversation as resolved.
Show resolved Hide resolved
{
return $this->type === PropelTypes::UUID;
}

/**
* Set the size of this column.
*
Expand Down
26 changes: 26 additions & 0 deletions tests/Propel/Tests/Generator/Model/ColumnTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ public function providePdoTypes()
['ENUM', PDO::PARAM_INT],
['BU_DATE', PDO::PARAM_STR],
['BU_TIMESTAMP', PDO::PARAM_STR],
['UUID', PDO::PARAM_STR],
];
}

Expand Down Expand Up @@ -709,6 +710,31 @@ public function provideMappingNumericTypes()
];
}

/**
* @return void
*/
public function testUuidType()
{
$domain = $this->getDomainMock();
$domain
->expects($this->once())
->method('setType')
->with($this->equalTo(PropelTypes::UUID));

$domain
->expects($this->any())
->method('getType')
->will($this->returnValue(PropelTypes::UUID));

$column = new Column('');
$column->setDomain($domain);
$column->setType(PropelTypes::UUID);

$this->assertSame('string', $column->getPhpType());
$this->assertTrue($column->isPhpPrimitiveType());
$this->assertTrue($column->isUuidType());
}

/**
* @dataProvider provideMappingTextTypes
*
Expand Down
19 changes: 19 additions & 0 deletions tests/Propel/Tests/Generator/Platform/MssqlPlatformTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -697,4 +697,23 @@ public function testGetCommentBlockDDL()
";
$this->assertEquals($expected, $this->getPlatform()->getCommentBlockDDL('foo bar'));
}

/**
* @dataProvider providerForTestCreateSchemaWithUuidColumns
*
* @return void
*/
public function testCreateSchemaWithUuidColumns($schema)
{
$table = $this->getTableFromSchema($schema);
$expected = "
CREATE TABLE [foo]
(
[uuid] UNIQUEIDENTIFIER DEFAULT vendor_specific_default() NOT NULL,
[other_uuid] UNIQUEIDENTIFIER NULL,
CONSTRAINT [foo_pk] PRIMARY KEY ([uuid])
);
";
$this->assertEquals($expected, $this->getPlatform()->getAddTableDDL($table));
}
}
29 changes: 29 additions & 0 deletions tests/Propel/Tests/Generator/Platform/MysqlPlatformTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -974,4 +974,33 @@ public function testTypeMapping(string $propelDataType, string $expectedMysqlDat
$actualMysqlDataType = $this->getPlatform()->getDomainForType($propelDataType)->getSqlType();
$this->assertEquals($expectedMysqlDataType, $actualMysqlDataType);
}

public function unavailableTypesDataProvider()
{
return [
[PropelTypes::UUID],
];
}

/**
* @dataProvider unavailableTypesDataProvider
*/
public function testExceptionOnAccessOfUnavailableType(string $propelDataType)
{
$this->expectException(\Propel\Generator\Exception\EngineException::class);

$this->getPlatform()->getDomainForType($propelDataType);
}

/**
* @dataProvider providerForTestCreateSchemaWithUuidColumns
*
* @return void
*/
public function testCreateSchemaWithUuidColumns($schema)
{
$this->expectException(\Propel\Generator\Exception\EngineException::class);

$table = $this->getTableFromSchema($schema);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -518,4 +518,22 @@ public function testGetModifyDatabaseWithBlockStorageDDL()
";
$this->assertEquals($expected, $this->getPlatform()->getModifyDatabaseDDL($databaseDiff));
}

/**
* @dataProvider providerForTestMigrateToUUIDColumn
*
* @return void
*/
public function testMigrateToUUIDColumn($tableDiff)
{
$expected = <<<END

ALTER TABLE foo MODIFY
(
id UUID DEFAULT vendor_specific_uuid_generator_function() NOT NULL
);

END;
$this->assertEquals($expected, $this->getPlatform()->getModifyTableColumnsDDL($tableDiff));
}
}
Loading