From febfc7c5f5b63675847b6662e021227e3872463f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 11 Dec 2020 14:47:27 +0100 Subject: [PATCH] Use SQL typecasting for Array persistence (#804) --- composer.json | 2 +- src/Persistence/Array_.php | 14 ++++++++++++++ tests/ContainsManyTest.php | 25 ++++++++++++++++++++----- tests/ContainsOneTest.php | 22 +++++++++++++++++++--- tests/PersistentArrayOfStringsTest.php | 14 +++++++------- 5 files changed, 61 insertions(+), 16 deletions(-) diff --git a/composer.json b/composer.json index 97bf1b95b..102504eea 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "homepage": "https://mvorisek.cz/" } ], - "version": "2.3.5", + "version": "2.3.6", "minimum-stability": "dev", "prefer-stable": true, "config": { diff --git a/src/Persistence/Array_.php b/src/Persistence/Array_.php index 27a1dcf85..95a7cbd94 100644 --- a/src/Persistence/Array_.php +++ b/src/Persistence/Array_.php @@ -84,6 +84,20 @@ private function addIdToLoadRow(Model $model, array &$row, $id): void } } + public function typecastSaveRow(Model $model, array $row): array + { + $sqlPersistence = (new \ReflectionClass(Sql::class))->newInstanceWithoutConstructor(); + + return $sqlPersistence->typecastSaveRow($model, $row); + } + + public function typecastLoadRow(Model $model, array $row): array + { + $sqlPersistence = (new \ReflectionClass(Sql::class))->newInstanceWithoutConstructor(); + + return $sqlPersistence->typecastLoadRow($model, $row); + } + /** * {@inheritdoc} */ diff --git a/tests/ContainsManyTest.php b/tests/ContainsManyTest.php index fdd76f706..613e8f107 100644 --- a/tests/ContainsManyTest.php +++ b/tests/ContainsManyTest.php @@ -268,17 +268,32 @@ public function testNestedContainsMany() // let's test how it all looks in persistence without typecasting $exp_lines = $i->setOrder('id')->export(null, null, false)[0]['lines']; + $formatDtForCompareFunc = function (\DateTimeInterface $dt): string { + $dt = (clone $dt)->setTimeZone(new \DateTimeZone('UTC')); // @phpstan-ignore-line + + return $dt->format('Y-m-d H:i:s.u'); + }; $this->assertSame( json_encode([ '1' => [ - 'id' => 1, 'vat_rate_id' => '1', 'price' => '10', 'qty' => '2', 'add_date' => (new \DateTime('2019-06-01'))->format('Y-m-d\TH:i:sP'), 'discounts' => json_encode([ - '1' => ['id' => 1, 'percent' => '5', 'valid_till' => (new \DateTime('2019-07-15'))->format('Y-m-d\TH:i:sP')], - '2' => ['id' => 2, 'percent' => '10', 'valid_till' => (new \DateTime('2019-07-30'))->format('Y-m-d\TH:i:sP')], + 'id' => 1, + 'vat_rate_id' => 1, + 'price' => 10, + 'qty' => 2, + 'add_date' => $formatDtForCompareFunc(new \DateTime('2019-06-01')), + 'discounts' => json_encode([ + '1' => ['id' => 1, 'percent' => 5, 'valid_till' => $formatDtForCompareFunc(new \DateTime('2019-07-15'))], + '2' => ['id' => 2, 'percent' => 10, 'valid_till' => $formatDtForCompareFunc(new \DateTime('2019-07-30'))], ]), ], '2' => [ - 'id' => 2, 'vat_rate_id' => '2', 'price' => '15', 'qty' => '5', 'add_date' => (new \DateTime('2019-07-01'))->format('Y-m-d\TH:i:sP'), 'discounts' => json_encode([ - '1' => ['id' => 1, 'percent' => '20', 'valid_till' => (new \DateTime('2019-12-31'))->format('Y-m-d\TH:i:sP')], + 'id' => 2, + 'vat_rate_id' => 2, + 'price' => 15, + 'qty' => 5, + 'add_date' => $formatDtForCompareFunc(new \DateTime('2019-07-01')), + 'discounts' => json_encode([ + '1' => ['id' => 1, 'percent' => 20, 'valid_till' => $formatDtForCompareFunc(new \DateTime('2019-12-31'))], ]), ], ]), diff --git a/tests/ContainsOneTest.php b/tests/ContainsOneTest.php index fa9f75e60..f4c78b0be 100644 --- a/tests/ContainsOneTest.php +++ b/tests/ContainsOneTest.php @@ -142,7 +142,7 @@ public function testContainsOne() $this->assertFalse($a->loaded()); // now store some address - $a->setMulti($row = ['id' => 1, 'country_id' => 1, 'address' => 'foo', 'built_date' => new \DateTime('2019-01-01 UTC'), 'tags' => ['foo', 'bar'], 'door_code' => null]); + $a->setMulti($row = ['id' => 1, 'country_id' => 1, 'address' => 'foo', 'built_date' => new \DateTime('2019-01-01'), 'tags' => ['foo', 'bar'], 'door_code' => null]); $a->save(); // now reload invoice and see if it is saved @@ -156,7 +156,7 @@ public function testContainsOne() // now add nested containsOne - DoorCode $c = $i->ref('addr')->ref('door_code'); - $c->setMulti($row = ['id' => 1, 'code' => 'ABC', 'valid_till' => new \DateTime('2019-07-01 UTC')]); + $c->setMulti($row = ['id' => 1, 'code' => 'ABC', 'valid_till' => new \DateTime('2019-07-01')]); $c->save(); $this->assertEquals($row, $i->ref('addr')->ref('door_code')->get()); @@ -174,8 +174,24 @@ public function testContainsOne() // let's test how it all looks in persistence without typecasting $exp_addr = $i->setOrder('id')->export(null, null, false)[0]['addr']; + $formatDtForCompareFunc = function (\DateTimeInterface $dt): string { + $dt = (clone $dt)->setTimeZone(new \DateTimeZone('UTC')); // @phpstan-ignore-line + + return $dt->format('Y-m-d H:i:s.u'); + }; $this->assertSame( - '{"id":1,"country_id":"2","address":"bar","built_date":"2019-01-01T00:00:00+00:00","tags":"[\"foo\",\"bar\"]","door_code":"{\"id\":1,\"code\":\"DEF\",\"valid_till\":\"2019-07-01T00:00:00+00:00\"}"}', + json_encode([ + 'id' => 1, + 'country_id' => 2, + 'address' => 'bar', + 'built_date' => $formatDtForCompareFunc(new \DateTime('2019-01-01')), + 'tags' => json_encode(['foo', 'bar']), + 'door_code' => json_encode([ + 'id' => 1, + 'code' => 'DEF', + 'valid_till' => $formatDtForCompareFunc(new \DateTime('2019-07-01')), + ]), + ]), $exp_addr ); diff --git a/tests/PersistentArrayOfStringsTest.php b/tests/PersistentArrayOfStringsTest.php index ad2a17e8c..09e77cffb 100644 --- a/tests/PersistentArrayOfStringsTest.php +++ b/tests/PersistentArrayOfStringsTest.php @@ -57,14 +57,14 @@ public function testTypecasting() 'id' => 1, 'string' => 'TwoLines', 'text' => "Two\nLines", - 'integer' => '123', - 'money' => '123.45', - 'float' => '123.456789', - 'boolean' => '1', - 'boolean_enum' => '0', + 'integer' => 123, + 'money' => 123.45, + 'float' => 123.456789, + 'boolean' => 1, + 'boolean_enum' => 'N', 'date' => '2019-01-20', - 'datetime' => '2019-01-20T12:23:34+00:00', - 'time' => '12:23:34', + 'datetime' => '2019-01-20 12:23:34.000000', + 'time' => '12:23:34.000000', 'array' => '{"foo":"bar","int":123,"rows":["a","b"]}', 'object' => '{"foo":"bar","int":123,"rows":["a","b"]}', ]], $data);