0
0
Fork 0
mirror of https://github.com/nextcloud/server.git synced 2025-02-12 12:09:14 +00:00
nextcloud_server/tests/lib/AppFramework/Db/QBMapperDBTest.php
Ferdinand Thiessen ee02e3246d
feat(AppFramework): Add full support for date / time / datetime columns
This adds support for all Doctrine supported types, for the column types only the immutable variants needed to be added.
But especially those types are the important ones, as our **Entity** class works by detecting changes through setters.
Meaning if it is mutable, changes like `$entity->date->modfiy()` can not be detected, so the immutable types make more sense here.

Similar the parameter types needed to be added.

`Enity` and `QBMapper` needed to be adjusted so they support (auto map) those types, required when insert or update an entity.

Also added more tests, especially to make sure the mapper really serializes the values correctly.

Co-authored-by: Ferdinand Thiessen <opensource@fthiessen.de>
Co-authored-by: Côme Chilliet <91878298+come-nc@users.noreply.github.com>
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2024-10-17 18:31:42 +02:00

159 lines
4.6 KiB
PHP

<?php
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\AppFramework\Db;
use Doctrine\DBAL\Schema\SchemaException;
use OCP\AppFramework\Db\Entity;
use OCP\AppFramework\Db\QBMapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\Types;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\Server;
use Test\TestCase;
/**
* @method void setTime(?\DateTime $time)
* @method ?\DateTime getTime()
* @method void setDatetime(?\DateTimeImmutable $datetime)
* @method ?\DateTimeImmutable getDatetime()
*/
class QBDBTestEntity extends Entity {
protected ?\DateTime $time = null;
protected ?\DateTimeImmutable $datetime = null;
public function __construct() {
$this->addType('time', Types::TIME);
$this->addType('datetime', Types::DATETIME_IMMUTABLE);
}
}
/**
* Class QBDBTestMapper
*
* @package Test\AppFramework\Db
*/
class QBDBTestMapper extends QBMapper {
public function __construct(IDBConnection $db) {
parent::__construct($db, 'testing', QBDBTestEntity::class);
}
public function getParameterTypeForPropertyForTest(Entity $entity, string $property) {
return parent::getParameterTypeForProperty($entity, $property);
}
public function getById(int $id): QBDBTestEntity {
$qb = $this->db->getQueryBuilder();
$query = $qb
->select('*')
->from($this->tableName)
->where(
$qb->expr()->eq('id', $qb->createPositionalParameter($id, IQueryBuilder::PARAM_INT)),
);
return $this->findEntity($query);
}
}
/**
* Test real database handling (serialization)
* @group DB
*/
class QBMapperDBTest extends TestCase {
/** @var \Doctrine\DBAL\Connection|\OCP\IDBConnection */
protected $connection;
protected $schemaSetup = false;
protected function setUp(): void {
parent::setUp();
$this->connection = \OCP\Server::get(IDBConnection::class);
$this->prepareTestingTable();
}
public function testInsertDateTime(): void {
$mapper = new QBDBTestMapper($this->connection);
$entity = new QBDBTestEntity();
$entity->setTime(new \DateTime('2003-01-01 12:34:00'));
$entity->setDatetime(new \DateTimeImmutable('2000-01-01 23:45:00'));
$result = $mapper->insert($entity);
$this->assertNotNull($result->getId());
}
public function testRetrieveDateTime(): void {
$time = new \DateTime('2000-01-01 01:01:00');
$datetime = new \DateTimeImmutable('2000-01-01 02:02:00');
$mapper = new QBDBTestMapper($this->connection);
$entity = new QBDBTestEntity();
$entity->setTime($time);
$entity->setDatetime($datetime);
$result = $mapper->insert($entity);
$this->assertNotNull($result->getId());
$dbEntity = $mapper->getById($result->getId());
$this->assertEquals($time->format('H:i:s'), $dbEntity->getTime()->format('H:i:s'));
$this->assertEquals($datetime->format('Y-m-d H:i:s'), $dbEntity->getDatetime()->format('Y-m-d H:i:s'));
// The date is not saved for "time"
$this->assertNotEquals($time->format('Y'), $dbEntity->getTime()->format('Y'));
}
public function testUpdateDateTime(): void {
$time = new \DateTime('2000-01-01 01:01:00');
$datetime = new \DateTimeImmutable('2000-01-01 02:02:00');
$mapper = new QBDBTestMapper($this->connection);
$entity = new QBDBTestEntity();
$entity->setTime('now');
$entity->setDatetime('now');
/** @var QBDBTestEntity */
$entity = $mapper->insert($entity);
$this->assertNotNull($entity->getId());
// Update the values
$entity->setTime($time);
$entity->setDatetime($datetime);
$mapper->update($entity);
$dbEntity = $mapper->getById($entity->getId());
$this->assertEquals($time->format('H:i:s'), $dbEntity->getTime()->format('H:i:s'));
$this->assertEquals($datetime->format('Y-m-d H:i:s'), $dbEntity->getDatetime()->format('Y-m-d H:i:s'));
}
protected function prepareTestingTable(): void {
if ($this->schemaSetup) {
$this->connection->getQueryBuilder()->delete('testing')->executeStatement();
}
$prefix = Server::get(IConfig::class)->getSystemValueString('dbtableprefix', 'oc_');
$schema = $this->connection->createSchema();
try {
$schema->getTable($prefix . 'testing');
$this->connection->getQueryBuilder()->delete('testing')->executeStatement();
} catch (SchemaException $e) {
$this->schemaSetup = true;
$table = $schema->createTable($prefix . 'testing');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
]);
$table->addColumn('time', Types::TIME, [
'notnull' => false,
]);
$table->addColumn('datetime', Types::DATETIME_IMMUTABLE, [
'notnull' => false,
]);
$table->setPrimaryKey(['id']);
$this->connection->migrateToSchema($schema);
}
}
}