Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow the primitive types of integer, string and float to be stored in a Jsonb field #66

Merged
merged 2 commits into from
Apr 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .php_cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ return PhpCsFixer\Config::create()
'php_unit_method_casing' => ['case' => 'snake_case'],
'php_unit_test_class_requires_covers' => false,
'phpdoc_types_order' => ['null_adjustment' => 'always_last'],
'simplified_null_return' => true,
Copy link
Owner Author

@martin-georgiev martin-georgiev Apr 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This had to change because PHP-CS-Fixer/PHP-CS-Fixer#2349 suddenly started showing its teeth here.

🤷

'simplified_null_return' => false,
'single_line_comment_style' => false,
'static_lambda' => true,
'yoda_style' => false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace MartinGeorgiev\Doctrine\DBAL\Types\Exceptions;

/**
* @since 1.5
*
* @author Martin Georgiev <martin.georgiev@gmail.com>
*/
abstract class TypeException extends \Exception
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace MartinGeorgiev\Doctrine\DBAL\Types\Exceptions;

/**
* @since 1.5
*
* @author Martin Georgiev <martin.georgiev@gmail.com>
*/
class UnexpectedTypeOfTransformedPHPValue extends TypeException
{
public function __construct(string $untransformedValue, string $typeOfTransformedPHPValue)
{
$message = \sprintf(
'Transforming a PostgreSql value "%s" results to an unexpected PHP value from type "%s".',
$untransformedValue,
$typeOfTransformedPHPValue
);
parent::__construct($message);
}
}
7 changes: 5 additions & 2 deletions src/MartinGeorgiev/Doctrine/DBAL/Types/JsonTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
trait JsonTransformer
{
/**
* @param mixed $phpValue Value bus be suitable for JSON encoding
* @param mixed $phpValue Value must be suitable for JSON encoding
*
* @throws ConversionException When given value cannot be encoded
*/
Expand All @@ -30,7 +30,10 @@ protected function transformToPostgresJson($phpValue): string
return $postgresValue;
}

protected function transformFromPostgresJson(string $postgresValue): array
/**
* @return array|float|int|string|null
*/
protected function transformFromPostgresJson(string $postgresValue)
{
return \json_decode($postgresValue, true);
}
Expand Down
4 changes: 3 additions & 1 deletion src/MartinGeorgiev/Doctrine/DBAL/Types/Jsonb.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform): ?str
* Converts a value from its database representation to its PHP representation of this type.
*
* @param string|null $value the value to convert
*
* @return array|float|int|string|null
*/
public function convertToPHPValue($value, AbstractPlatform $platform): ?array
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if ($value === null) {
return null;
Expand Down
9 changes: 8 additions & 1 deletion src/MartinGeorgiev/Doctrine/DBAL/Types/JsonbArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace MartinGeorgiev\Doctrine\DBAL\Types;

use MartinGeorgiev\Doctrine\DBAL\Types\Exceptions\UnexpectedTypeOfTransformedPHPValue;

/**
* Implementation of PostgreSql JSONB[] data type.
*
Expand Down Expand Up @@ -42,6 +44,11 @@ protected function transformPostgresArrayToPHPArray(string $postgresArray): arra

public function transformArrayItemForPHP($item): array
{
return $this->transformFromPostgresJson($item);
$transformedValue = $this->transformFromPostgresJson($item);
if (!\is_array($transformedValue)) {
throw new UnexpectedTypeOfTransformedPHPValue($item, \gettype($transformedValue));
}

return $transformedValue;
}
}
13 changes: 13 additions & 0 deletions tests/MartinGeorgiev/Doctrine/DBAL/Types/JsonbArrayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace MartinGeorgiev\Tests\Doctrine\DBAL\Types;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use MartinGeorgiev\Doctrine\DBAL\Types\Exceptions\UnexpectedTypeOfTransformedPHPValue;
use MartinGeorgiev\Doctrine\DBAL\Types\JsonbArray;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -89,4 +90,16 @@ public function can_transform_to_php_value(?array $phpValue, ?string $postgresVa
{
$this->assertEquals($phpValue, $this->fixture->convertToPHPValue($postgresValue, $this->platform));
}

/**
* @test
*/
public function throws_an_error_when_transformed_value_is_not_an_array(): void
{
$this->expectException(UnexpectedTypeOfTransformedPHPValue::class);

$postgresValue = '"a string encoded as json"';

$this->fixture->convertToPHPValue($postgresValue, $this->platform);
}
}
20 changes: 18 additions & 2 deletions tests/MartinGeorgiev/Doctrine/DBAL/Types/JsonbTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ public function validTransformations(): array
'phpValue' => [],
'postgresValue' => '[]',
],
[
'phpValue' => 13,
'postgresValue' => '13',
],
[
'phpValue' => 13.93,
'postgresValue' => '13.93',
],
[
'phpValue' => 'a string value',
'postgresValue' => '"a string value"',
],
[
'phpValue' => [681, 1185, 1878, 1989],
'postgresValue' => '[681,1185,1878,1989]',
Expand Down Expand Up @@ -70,17 +82,21 @@ public function has_name(): void
/**
* @test
* @dataProvider validTransformations
*
* @var array|float|int|string|null
*/
public function can_transform_from_php_value(?array $phpValue, ?string $postgresValue): void
public function can_transform_from_php_value($phpValue, ?string $postgresValue): void
{
$this->assertEquals($postgresValue, $this->fixture->convertToDatabaseValue($phpValue, $this->platform));
}

/**
* @test
* @dataProvider validTransformations
*
* @var array|float|int|string|null
*/
public function can_transform_to_php_value(?array $phpValue, ?string $postgresValue): void
public function can_transform_to_php_value($phpValue, ?string $postgresValue): void
{
$this->assertEquals($phpValue, $this->fixture->convertToPHPValue($postgresValue, $this->platform));
}
Expand Down