Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
16 changes: 13 additions & 3 deletions src/MartinGeorgiev/Doctrine/DBAL/Types/JsonbArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@

namespace MartinGeorgiev\Doctrine\DBAL\Types;

use MartinGeorgiev\Utils\PostgresArrayToPHPArrayTransformer;
use MartinGeorgiev\Utils\PostgresJsonToPHPArrayTransformer;

/**
* Implementation of PostgreSQL JSONB[] data type.
*
* @see https://www.postgresql.org/docs/9.4/static/arrays.html
* @see https://www.postgresql.org/docs/17/arrays.html
* @since 0.1
*
* @author Martin Georgiev <martin.georgiev@gmail.com>
Expand All @@ -22,12 +23,21 @@ class JsonbArray extends BaseArray

protected function transformArrayItemForPostgres(mixed $item): string
{
return $this->transformToPostgresJson($item);
// Quote each JSON value as a PostgreSQL array element and escape inner quotes and backslashes
$json = $this->transformToPostgresJson($item);
$escaped = \str_replace(['\\', '"'], ['\\\\', '\\"'], $json);

return '"'.$escaped.'"';
}

protected function transformPostgresArrayToPHPArray(string $postgresArray): array
{
return PostgresJsonToPHPArrayTransformer::transformPostgresArrayToPHPArray($postgresArray);
$trimmed = \trim($postgresArray);
if ($trimmed === '{}') {
return [];
}

return PostgresArrayToPHPArrayTransformer::transformPostgresArrayToPHPArray($postgresArray);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

namespace Tests\Integration\MartinGeorgiev\Doctrine\DBAL\Types;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;

class JsonbArrayTypeTest extends ArrayTypeTestCase
{
protected function getTypeName(): string
{
return 'jsonb[]';
}

protected function getPostgresTypeName(): string
{
return 'JSONB[]';
}

#[DataProvider('provideValidTransformations')]
#[Test]
public function can_handle_array_values(string $testName, array $arrayValue): void
{
parent::can_handle_array_values($testName, $arrayValue);
}

/**
* @return array<string, array{string, array<int, array<string, mixed>>}>
*/
public static function provideValidTransformations(): array
{
return [
'simple jsonb array' => ['simple jsonb array', [
['key1' => 'value1', 'key2' => false],
['key1' => 'value2', 'key2' => true],
]],
'jsonb array with nested structures' => ['jsonb array with nested structures', [
[
'user' => ['id' => 1, 'name' => 'John'],
'meta' => ['active' => true, 'roles' => ['admin', 'user']],
],
[
'user' => ['id' => 2, 'name' => 'Jane'],
'meta' => ['active' => false, 'roles' => ['user']],
],
]],
'jsonb array with mixed types' => ['jsonb array with mixed types', [
[
'string' => 'value',
'number' => 42,
'boolean' => false,
'null' => null,
'array' => [1, 2, 3],
'object' => ['a' => 1],
],
[
'different' => 'structure',
'count' => 999,
'enabled' => true,
],
]],
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public static function provideValidTransformations(): array
'key5' => [304, 404, 504, 604],
],
],
'postgresValue' => '{{"key1":"value1","key2":false,"key3":"15","key4":15,"key5":[112,242,309,310]},{"key1":"value2","key2":true,"key3":"115","key4":115,"key5":[304,404,504,604]}}',
'postgresValue' => '{"{\"key1\":\"value1\",\"key2\":false,\"key3\":\"15\",\"key4\":15,\"key5\":[112,242,309,310]}","{\"key1\":\"value2\",\"key2\":true,\"key3\":\"115\",\"key4\":115,\"key5\":[304,404,504,604]}"}',
],
];
}
Expand Down
Loading