From 26f0d8096756cb82d30c34c4848e6047a85758d5 Mon Sep 17 00:00:00 2001 From: Norbert Orzechowicz <1921950+norberttech@users.noreply.github.com> Date: Mon, 22 Jan 2024 20:19:11 +0100 Subject: [PATCH] Automatically cast datetime bulk entries into DateTime objects (#929) * Automatically cast datetime bulk entries into DateTime objects * Satisfy psalm --- .../src/Flow/Doctrine/Bulk/BulkData.php | 23 +++++++++++++------ .../Integration/PostgreSqlBulkInsertTest.php | 4 +++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/lib/doctrine-dbal-bulk/src/Flow/Doctrine/Bulk/BulkData.php b/src/lib/doctrine-dbal-bulk/src/Flow/Doctrine/Bulk/BulkData.php index 9090abc0f..58b8b109f 100644 --- a/src/lib/doctrine-dbal-bulk/src/Flow/Doctrine/Bulk/BulkData.php +++ b/src/lib/doctrine-dbal-bulk/src/Flow/Doctrine/Bulk/BulkData.php @@ -17,8 +17,6 @@ final class BulkData private array $rows; /** - * @psalm-suppress DocblockTypeContradiction - * * @param array> $rows */ public function __construct(array $rows) @@ -29,6 +27,7 @@ public function __construct(array $rows) $firstRow = \reset($rows); + /** @psalm-suppress DocblockTypeContradiction */ if (!\is_array($firstRow)) { throw new RuntimeException('Each row must be an array'); } @@ -36,6 +35,7 @@ public function __construct(array $rows) $columns = \array_keys($firstRow); foreach ($rows as $row) { + /** @psalm-suppress DocblockTypeContradiction */ if (!\is_array($row)) { throw new RuntimeException('Each row must be an array'); } @@ -121,11 +121,20 @@ public function toSqlParameters(TableDefinition $table) : array * @var mixed $entry */ foreach ($row as $column => $entry) { - if (\is_string($entry) && ($table->dbalColumn($column)->getType()->getName() === Types::JSON || $table->dbalColumn($column)->getType()->getName() === 'json_array')) { - $rows[$index][$column . '_' . $index] = \json_decode($entry, true, 512, JSON_THROW_ON_ERROR); - } else { - $rows[$index][$column . '_' . $index] = $entry; - } + $rows[$index][$column . '_' . $index] = match (\gettype($entry)) { + 'string' => match ($table->dbalColumn($column)->getType()->getName()) { + Types::JSON, 'json_array' => \json_decode($entry, true, 512, JSON_THROW_ON_ERROR), + Types::DATETIME_IMMUTABLE, + Types::DATETIMETZ_IMMUTABLE, + Types::DATE_IMMUTABLE, + Types::TIME_IMMUTABLE => new \DateTimeImmutable($entry), + Types::DATE_MUTABLE, + Types::DATETIME_MUTABLE, + Types::DATETIMETZ_MUTABLE => new \DateTime($entry), + default => $entry + }, + default => $entry + }; } } diff --git a/src/lib/doctrine-dbal-bulk/tests/Flow/Doctrine/Bulk/Tests/Integration/PostgreSqlBulkInsertTest.php b/src/lib/doctrine-dbal-bulk/tests/Flow/Doctrine/Bulk/Tests/Integration/PostgreSqlBulkInsertTest.php index 6429f94c9..87d59b976 100644 --- a/src/lib/doctrine-dbal-bulk/tests/Flow/Doctrine/Bulk/Tests/Integration/PostgreSqlBulkInsertTest.php +++ b/src/lib/doctrine-dbal-bulk/tests/Flow/Doctrine/Bulk/Tests/Integration/PostgreSqlBulkInsertTest.php @@ -32,11 +32,13 @@ public function test_inserts_multiple_rows_at_once() : void ->setPrimaryKey(['id']) ); + $date1 = new \DateTimeImmutable(); + Bulk::create()->insert( $this->databaseContext->connection(), $table, new BulkData([ - ['id' => $id1 = \bin2hex(\random_bytes(5)), 'age' => 20, 'name' => 'Name One', 'description' => 'Description One', 'active' => false, 'updated_at' => $date1 = new \DateTimeImmutable(), 'tags' => \json_encode(['a', 'b', 'c'])], + ['id' => $id1 = \bin2hex(\random_bytes(5)), 'age' => 20, 'name' => 'Name One', 'description' => 'Description One', 'active' => false, 'updated_at' => $date1->format(\DateTimeInterface::ATOM), 'tags' => \json_encode(['a', 'b', 'c'])], ['id' => $id2 = \bin2hex(\random_bytes(5)), 'age' => 30, 'name' => 'Name Two', 'description' => null, 'active' => true, 'updated_at' => $date2 = new \DateTimeImmutable(), 'tags' => \json_encode(['a', 'b', 'c'])], ['id' => $id3 = \bin2hex(\random_bytes(5)), 'age' => 40, 'name' => 'Name Three', 'description' => 'Description Three', 'active' => false, 'updated_at' => $date3 = new \DateTimeImmutable(), 'tags' => \json_encode(['a', 'b', 'c'])], ])