Skip to content

Commit

Permalink
Merge pull request #95 from xavierleune/feature/more-serializer
Browse files Browse the repository at this point in the history
Feature: Serializer for dateTimeZone and Uuid
  • Loading branch information
vgreb authored Dec 26, 2024
2 parents dee53db + 2171390 commit 9aa676c
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 14 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* Remove hard dependency to pimple, add it in suggest
* Collection is now JsonSerializable
* Add DateTimeImmutable serialization
* Add DateTimeZone serialization
* Add uuid support with symfony/uid
* Refacto: use, when possible, Weakmap for UnitOfWork internal storage instead of uuid indexed array
* Fix: Query Generator now handle null values

Expand Down
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@
"atoum/atoum": "^4.0",
"atoum/stubs": "^2.0",
"brick/geo": "^0.5.1",
"pimple/pimple": "^3.0"
"pimple/pimple": "^3.0",
"symfony/uid": "^6.0 || ^7.0"
},
"suggest": {
"brick/geo": "Allow support of MariaDB Geometry type",
"pimple/pimple": "Service container."
"pimple/pimple": "Service container.",
"symfony/uid": "To work with Uuid."
},
"autoload": {
"psr-4" : {
Expand Down
25 changes: 13 additions & 12 deletions src/Ting/Repository/Metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@
use CCMBenchmark\Ting\Query\Generator;
use CCMBenchmark\Ting\Query\PreparedQuery;
use CCMBenchmark\Ting\Query\QueryFactoryInterface;
use CCMBenchmark\Ting\Serializer\SerializerFactoryInterface;
use CCMBenchmark\Ting\Serializer\SerializerInterface;

use CCMBenchmark\Ting\Serializer;
/**
* @template T of object
* @phpstan-type Field array{
Expand All @@ -45,15 +43,15 @@
* type: string,
* primary?: bool,
* autoincrement?: bool,
* serializer?: class-string<SerializerInterface>,
* serializer?: class-string<Serializer\SerializerInterface>,
* serializer_options?: array{serialize?: array<mixed>, unserialize?: array<mixed>}
* }
*/
class Metadata
{

/**
* @var SerializerFactoryInterface|null
* @var Serializer\SerializerFactoryInterface|null
*/
protected $serializerFactory = null;
protected $connectionName = null;
Expand All @@ -71,16 +69,19 @@ class Metadata
protected $primaries = [];
protected $autoincrement = null;
protected $defaultSerializers = [
'datetime' => '\CCMBenchmark\Ting\Serializer\DateTime',
'json' => '\CCMBenchmark\Ting\Serializer\Json',
'ip' => '\CCMBenchmark\Ting\Serializer\Ip',
'geometry' => '\CCMBenchmark\Ting\Serializer\Geometry'
'datetime' => Serializer\DateTime::class,
'datetime_immutable' => Serializer\DateTimeImmutable::class,
'datetimezone' => Serializer\DateTimeZone::class,
'json' => Serializer\Json::class,
'ip' => Serializer\Ip::class,
'geometry' => Serializer\Geometry::class,
'uuid' => Serializer\Uuid::class,
];

/**
* @param SerializerFactoryInterface $serializerFactory
* @param Serializer\SerializerFactoryInterface $serializerFactory
*/
public function __construct(SerializerFactoryInterface $serializerFactory)
public function __construct(Serializer\SerializerFactoryInterface $serializerFactory)
{
$this->serializerFactory = $serializerFactory;
}
Expand Down Expand Up @@ -530,7 +531,7 @@ protected function getColumnsFromCriteria(array $criteria)
* @param QueryFactoryInterface $queryFactory
* @param CollectionFactoryInterface $collectionFactory
* @param bool $forceMaster
* @return \CCMBenchmark\Ting\Query\Query
* @return \CCMBenchmark\Ting\Query\QueryInterface
*
* @internal
*/
Expand Down
32 changes: 32 additions & 0 deletions src/Ting/Serializer/DateTimeZone.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace CCMBenchmark\Ting\Serializer;


class DateTimeZone implements SerializerInterface
{
public function serialize($toSerialize, array $options = [])
{
if ($toSerialize === null) {
return null;
}

if (!($toSerialize instanceof \DateTimeZone)) {
throw new RuntimeException('datetimezone has to be an instance of \DateTimeZone');
}

return $toSerialize->getName();
}

public function unserialize($serialized, array $options = [])
{
if ($serialized === null) {
return null;
}
try {
return new \DateTimeZone($serialized);
} catch (\Exception $e) {
throw new RuntimeException('Cannot convert ' . $serialized . ' to DateTimeZone.');
}
}
}
31 changes: 31 additions & 0 deletions src/Ting/Serializer/Uuid.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace CCMBenchmark\Ting\Serializer;


class Uuid implements SerializerInterface
{
public function serialize($toSerialize, array $options = [])
{
if ($toSerialize === null) {
return null;
}
if (!($toSerialize instanceof \Symfony\Component\Uid\Uuid)) {
throw new RuntimeException('UUID has to be an instance of \Symfony\Component\Uid\Uuid . ' . gettype($toSerialize) . ' given.');
}

return $toSerialize->toRfc4122();
}

public function unserialize($serialized, array $options = [])
{
if ($serialized === null) {
return null;
}
try {
return \Symfony\Component\Uid\Uuid::fromString($serialized);
} catch (\InvalidArgumentException $e) {
throw new RuntimeException('Cannot convert ' . $serialized . ' to UUID.');
}
}
}
75 changes: 75 additions & 0 deletions tests/units/Ting/Serializer/DateTimeZone.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php
/***********************************************************************
*
* Ting - PHP Datamapper
* ==========================================
*
* Copyright (C) 2014 CCM Benchmark Group. (http://www.ccmbenchmark.com)
*
***********************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
**********************************************************************/

namespace tests\units\CCMBenchmark\Ting\Serializer;

use atoum;

class DateTimeZone extends atoum
{
public function testSerializeThenUnSerializeShouldReturnOriginalValue(): void
{
$datetime = new \DateTimeZone('Europe/Paris');
$this
->if($serializer = new \CCMBenchmark\Ting\Serializer\DateTimeZone())
->object($serializer->unserialize($serializer->serialize($datetime)))
->isInstanceOf(\DateTimeZone::class)
->string($serializer->unserialize($serializer->serialize($datetime))->getName())
->isEqualTo('Europe/Paris')
;
}

public function testUnserializeInvalidValueShouldRaiseException(): void
{
$this
->if($serializer = new \CCMBenchmark\Ting\Serializer\DateTimeZone())
->exception(function () use ($serializer) {
$serializer->unserialize('Not a timezone');
})
->isInstanceOf('CCMBenchmark\Ting\Serializer\RuntimeException')
;
}

public function testSerializeInvalidValueShouldRaiseException(): void
{
$this
->if($serializer = new \CCMBenchmark\Ting\Serializer\DateTimeZone())
->exception(function () use ($serializer) {
$serializer->serialize(new \StdClass());
})
->isInstanceOf('CCMBenchmark\Ting\Serializer\RuntimeException')
;
}

public function testNullValueShouldBeReturned(): void
{
$this
->if($serializer = new \CCMBenchmark\Ting\Serializer\DateTimeZone())
->variable($serializer->serialize(null))
->isNull()
->variable($serializer->unserialize(null))
->isNull()
;
}
}
77 changes: 77 additions & 0 deletions tests/units/Ting/Serializer/Uuid.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php
/***********************************************************************
*
* Ting - PHP Datamapper
* ==========================================
*
* Copyright (C) 2014 CCM Benchmark Group. (http://www.ccmbenchmark.com)
*
***********************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
**********************************************************************/

namespace tests\units\CCMBenchmark\Ting\Serializer;

use atoum;
use Symfony\Component\Uid\UuidV4;

class Uuid extends atoum
{
public function testSerializeThenUnSerializeShouldReturnOriginalValue(): void
{
$uuid = new UuidV4();
$this
->if($serializer = new \CCMBenchmark\Ting\Serializer\Uuid())
->dump($serializer->serialize($uuid))
->object($serializer->unserialize($serializer->serialize($uuid)))
->isInstanceOf(Uuidv4::class)
->string($serializer->unserialize($serializer->serialize($uuid))->toRfc4122())
->isEqualTo($uuid->toRfc4122())
;
}

public function testUnserializeInvalidValueShouldRaiseException(): void
{
$this
->if($serializer = new \CCMBenchmark\Ting\Serializer\Uuid())
->exception(function () use ($serializer) {
$serializer->unserialize('Invalid uuid');
})
->isInstanceOf('CCMBenchmark\Ting\Serializer\RuntimeException')
;
}

public function testSerializeInvalidValueShouldRaiseException(): void
{
$this
->if($serializer = new \CCMBenchmark\Ting\Serializer\Uuid())
->exception(function () use ($serializer) {
$serializer->serialize(new \StdClass());
})
->isInstanceOf('CCMBenchmark\Ting\Serializer\RuntimeException')
;
}

public function testNullValueShouldBeReturned(): void
{
$this
->if($serializer = new \CCMBenchmark\Ting\Serializer\Uuid())
->variable($serializer->serialize(null))
->isNull()
->variable($serializer->unserialize(null))
->isNull()
;
}
}

0 comments on commit 9aa676c

Please sign in to comment.