From 54c3aa3f997aa843be84880d518d1a36ba265926 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 22 Oct 2024 11:20:38 +0200 Subject: [PATCH] fix(entity): Fix mapping of old/sub-types to actually supported database types Signed-off-by: Joas Schilling --- lib/public/AppFramework/Db/Entity.php | 22 ++++++++++++ tests/lib/AppFramework/Db/EntityTest.php | 44 +++++++++++++++++++++--- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/lib/public/AppFramework/Db/Entity.php b/lib/public/AppFramework/Db/Entity.php index cd15df134f1bd..d90d3ed4837a1 100644 --- a/lib/public/AppFramework/Db/Entity.php +++ b/lib/public/AppFramework/Db/Entity.php @@ -112,6 +112,15 @@ protected function setter(string $name, array $args): void { } switch ($type) { + case Types::BIGINT: + case Types::SMALLINT: + settype($args[0], Types::INTEGER); + break; + case Types::BINARY: + case Types::DECIMAL: + case Types::TEXT: + settype($args[0], Types::STRING); + break; case Types::TIME: case Types::DATE: case Types::DATETIME: @@ -260,9 +269,22 @@ public function getUpdatedFields(): array { * * @param string $fieldName the name of the attribute * @param \OCP\DB\Types::* $type the type which will be used to match a cast + * @since 31.0.0 Parameter $type is now restricted to {@see \OCP\DB\Types} constants. The formerly accidentally supported types 'int'|'bool'|'double' are mapped to Types::INTEGER|Types::BOOLEAN|Types::FLOAT accordingly. * @since 7.0.0 */ protected function addType(string $fieldName, string $type): void { + /** @psalm-suppress TypeDoesNotContainType */ + if (in_array($type, ['bool', 'double', 'int', 'array', 'object'], true)) { + // Mapping legacy strings to the actual types + $type = match ($type) { + 'int' => Types::INTEGER, + 'bool' => Types::BOOLEAN, + 'double' => Types::FLOAT, + 'array', + 'object' => Types::STRING, + }; + } + $this->_fieldTypes[$fieldName] = $type; } diff --git a/tests/lib/AppFramework/Db/EntityTest.php b/tests/lib/AppFramework/Db/EntityTest.php index 5b953a25c1a2e..3c844780b07d0 100644 --- a/tests/lib/AppFramework/Db/EntityTest.php +++ b/tests/lib/AppFramework/Db/EntityTest.php @@ -39,20 +39,31 @@ class TestEntity extends Entity { protected $name; protected $email; protected $testId; + protected $smallInt; + protected $bigInt; protected $preName; protected $trueOrFalse; protected $anotherBool; + protected $text; protected $longText; protected $time; protected $datetime; public function __construct($name = null) { $this->addType('testId', Types::INTEGER); - $this->addType('trueOrFalse', 'bool'); + $this->addType('smallInt', Types::SMALLINT); + $this->addType('bigInt', Types::BIGINT); $this->addType('anotherBool', Types::BOOLEAN); + $this->addType('text', Types::TEXT); $this->addType('longText', Types::BLOB); $this->addType('time', Types::TIME); $this->addType('datetime', Types::DATETIME_IMMUTABLE); + + // Legacy types + $this->addType('trueOrFalse', 'bool'); + $this->addType('legacyInt', 'int'); + $this->addType('doubleNowFloat', 'double'); + $this->name = $name; } @@ -200,10 +211,28 @@ public function testSlugify(): void { } - public function testSetterCasts(): void { + public function dataSetterCasts(): array { + return [ + ['Id', '3', 3], + ['smallInt', '3', 3], + ['bigInt', '' . PHP_INT_MAX, PHP_INT_MAX], + ['trueOrFalse', 0, false], + ['trueOrFalse', 1, true], + ['anotherBool', 0, false], + ['anotherBool', 1, true], + ['text', 33, '33'], + ['longText', PHP_INT_MAX, '' . PHP_INT_MAX], + ]; + } + + + /** + * @dataProvider dataSetterCasts + */ + public function testSetterCasts(string $field, mixed $in, mixed $out): void { $entity = new TestEntity(); - $entity->setId('3'); - $this->assertSame(3, $entity->getId()); + $entity->{'set' . $field}($in); + $this->assertSame($out, $entity->{'get' . $field}()); } @@ -248,11 +277,16 @@ public function testGetFieldTypes(): void { $this->assertEquals([ 'id' => Types::INTEGER, 'testId' => Types::INTEGER, - 'trueOrFalse' => 'bool', + 'smallInt' => Types::SMALLINT, + 'bigInt' => Types::BIGINT, 'anotherBool' => Types::BOOLEAN, + 'text' => Types::TEXT, 'longText' => Types::BLOB, 'time' => Types::TIME, 'datetime' => Types::DATETIME_IMMUTABLE, + 'trueOrFalse' => Types::BOOLEAN, + 'legacyInt' => Types::INTEGER, + 'doubleNowFloat' => Types::FLOAT, ], $entity->getFieldTypes()); }