Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,18 @@ protected function insertTestDataForJsonFixture(): void
{
$json1 = '{"name": "John", "age": 30, "tags": ["developer", "manager"], "address": {"city": "New York"}}';
$json2 = '{"name": "Jane", "age": 25, "tags": ["designer"], "address": {"city": "Boston"}}';
$json3 = '{"name": "Micky", "age": 30, "tags": [], "address": {"city": "New York"}}';
$json4 = '{}';
$json5 = '{"name": "John", "age": null, "tags": ["developer"], "address": {"city": "New York", "zip": null}}';

$sql = \sprintf('
INSERT INTO %s.containsjsons (object1, object2) VALUES
(\'%s\', \'%s\'),
(\'%s\', \'%s\'),
(\'%s\', \'%s\'),
(\'%s\', \'%s\'),
(\'%s\', \'%s\')
', self::DATABASE_SCHEMA, $json1, $json1, $json2, $json2);
', self::DATABASE_SCHEMA, $json1, $json1, $json2, $json2, $json3, $json3, $json4, $json4, $json5, $json5);
$this->connection->executeStatement($sql);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,35 +31,11 @@ public function test_jsonb_agg_with_single_row(): void
$this->assertEqualsCanonicalizing($expected, $actual);
}

public function test_jsonb_agg_with_all_rows(): void
public function test_jsonb_agg_with_multiple_rows(): void
{
$dql = 'SELECT JSONB_AGG(t.object1) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t';
$result = $this->executeDqlQuery($dql);
$this->assertIsString($result[0]['result']);
$actual = \json_decode($result[0]['result'], true);
$this->assertIsArray($actual);
$expected = [
[
'name' => 'John',
'age' => 30,
'tags' => ['developer', 'manager'],
'address' => ['city' => 'New York'],
],
[
'name' => 'Jane',
'age' => 25,
'tags' => ['designer'],
'address' => ['city' => 'Boston'],
],
];
$this->assertEqualsCanonicalizing($expected, $actual);
}

public function test_jsonb_agg_with_object2_column(): void
{
$dql = 'SELECT JSONB_AGG(t.object2) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t';
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id IN (1, 2)';
$result = $this->executeDqlQuery($dql);
$this->assertIsString($result[0]['result']);
$actual = \json_decode($result[0]['result'], true);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;

use Doctrine\DBAL\Exception;
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbInsert;

class JsonbInsertTest extends JsonTestCase
{
protected function getStringFunctions(): array
{
return [
'JSONB_INSERT' => JsonbInsert::class,
];
}

public function test_jsonb_insert_new_value(): void
{
$dql = 'SELECT JSONB_INSERT(t.object1, :path, :value) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 1';
$result = $this->executeDqlQuery($dql, [
'path' => '{email}',
'value' => '"john@example.com"',
]);
$this->assertIsString($result[0]['result']);
$decoded = \json_decode($result[0]['result'], true);
$this->assertIsArray($decoded);
$this->assertArrayHasKey('email', $decoded);
$this->assertSame('john@example.com', $decoded['email']);
}

public function test_jsonb_insert_nested_path(): void
{
$dql = 'SELECT JSONB_INSERT(t.object1, :path, :value) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 1';
$result = $this->executeDqlQuery($dql, [
'path' => '{address,zip}',
'value' => '"10001"',
]);
$this->assertIsString($result[0]['result']);
$decoded = \json_decode($result[0]['result'], true);
$this->assertIsArray($decoded);
$this->assertArrayHasKey('address', $decoded);
$this->assertIsArray($decoded['address']);
$this->assertArrayHasKey('zip', $decoded['address']);
$this->assertSame('10001', $decoded['address']['zip']);
}

public function test_throws_exception_when_inserting_at_existing_object_key(): void
{
$this->expectException(Exception::class);
$dql = 'SELECT JSONB_INSERT(t.object1, :path, :value) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 1';
$this->executeDqlQuery($dql, [
'path' => '{name}',
'value' => '"John Doe"',
]);
}

public function test_throws_exception_when_inserting_at_existing_nested_path(): void
{
$this->expectException(Exception::class);

$dql = 'SELECT JSONB_INSERT(t.object1, :path, :value) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 5';

$this->executeDqlQuery($dql, [
'path' => '{address,zip}',
'value' => '"10001"',
]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;

use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbObjectAgg;

class JsonbObjectAggTest extends JsonTestCase
{
protected function getStringFunctions(): array
{
return [
'JSONB_OBJECT_AGG' => JsonbObjectAgg::class,
];
}

public function test_jsonb_object_agg(): void
{
$dql = "SELECT JSONB_OBJECT_AGG('key', 'value') as result
FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t
WHERE t.id = 1";
$result = $this->executeDqlQuery($dql);
$this->assertIsString($result[0]['result']);
$decoded = \json_decode($result[0]['result'], true);
$this->assertIsArray($decoded);
$this->assertSame(['key' => 'value'], $decoded);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;

use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbObjectKeys;

class JsonbObjectKeysTest extends JsonTestCase
{
protected function getStringFunctions(): array
{
return [
'JSONB_OBJECT_KEYS' => JsonbObjectKeys::class,
];
}

public function test_jsonb_object_keys(): void
{
$dql = 'SELECT JSONB_OBJECT_KEYS(t.object1) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 1';
$result = $this->executeDqlQuery($dql);
$this->assertIsString($result[0]['result']);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

declare(strict_types=1);

namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;

use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbPathQueryArray;

class JsonbPathQueryArrayTest extends JsonTestCase
{
protected function getStringFunctions(): array
{
return [
'JSONB_PATH_QUERY_ARRAY' => JsonbPathQueryArray::class,
];
}

public function test_jsonb_path_query_array_simple(): void
{
$dql = 'SELECT JSONB_PATH_QUERY_ARRAY(:json, :path) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 1';
$result = $this->executeDqlQuery($dql, [
'json' => '{"a": 1, "b": 2}',
'path' => '$.b',
]);
$this->assertIsString($result[0]['result']);
$decoded = \json_decode($result[0]['result'], true);
$this->assertIsArray($decoded);
$this->assertCount(1, $decoded);
$this->assertSame(2, $decoded[0]);
}

public function test_jsonb_path_query_array_multiple_values(): void
{
$dql = 'SELECT JSONB_PATH_QUERY_ARRAY(:json, :path) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 1';
$result = $this->executeDqlQuery($dql, [
'json' => '{"items": [1, 2, 3]}',
'path' => '$.items[*]',
]);
$this->assertIsString($result[0]['result']);
$decoded = \json_decode($result[0]['result'], true);
$this->assertIsArray($decoded);
$this->assertCount(3, $decoded);
$this->assertSame([1, 2, 3], $decoded);
}

public function test_jsonb_path_query_array_with_filter(): void
{
$dql = 'SELECT JSONB_PATH_QUERY_ARRAY(:json, :path) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 1';
$result = $this->executeDqlQuery($dql, [
'json' => '{"items": [{"id": 1}, {"id": 2}, {"id": 3}]}',
'path' => '$.items[*] ? (@.id > 1)',
]);
$this->assertIsString($result[0]['result']);
$decoded = \json_decode($result[0]['result'], true);
$this->assertIsArray($decoded);
$this->assertCount(2, $decoded);
$this->assertSame(['id' => 2], $decoded[0]);
$this->assertSame(['id' => 3], $decoded[1]);
}

public function test_jsonb_path_query_array_with_column_reference(): void
{
$dql = 'SELECT JSONB_PATH_QUERY_ARRAY(t.object1, :path) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 1';
$result = $this->executeDqlQuery($dql, ['path' => '$.tags[*]']);
$this->assertIsString($result[0]['result']);
$decoded = \json_decode($result[0]['result'], true);
$this->assertIsArray($decoded);
$this->assertCount(2, $decoded);
$this->assertSame(['developer', 'manager'], $decoded);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;

use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbPathQueryFirst;

class JsonbPathQueryFirstTest extends JsonTestCase
{
protected function getStringFunctions(): array
{
return [
'JSONB_PATH_QUERY_FIRST' => JsonbPathQueryFirst::class,
];
}

public function test_jsonb_path_query_first_simple(): void
{
$dql = 'SELECT JSONB_PATH_QUERY_FIRST(:json, :path) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 1';
$result = $this->executeDqlQuery($dql, [
'json' => '{"a": 1, "b": 2}',
'path' => '$.b',
]);
$this->assertIsString($result[0]['result']);
$this->assertSame('2', $result[0]['result']);
}

public function test_jsonb_path_query_first_array(): void
{
$dql = 'SELECT JSONB_PATH_QUERY_FIRST(:json, :path) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 1';
$result = $this->executeDqlQuery($dql, [
'json' => '{"items": [1, 2, 3]}',
'path' => '$.items[*]',
]);
$this->assertIsString($result[0]['result']);
$this->assertSame('1', $result[0]['result']);
}

public function test_jsonb_path_query_first_with_filter(): void
{
$dql = 'SELECT JSONB_PATH_QUERY_FIRST(:json, :path) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 1';
$result = $this->executeDqlQuery($dql, [
'json' => '{"items": [{"id": 1}, {"id": 2}, {"id": 3}]}',
'path' => '$.items[*] ? (@.id > 1)',
]);
$this->assertIsString($result[0]['result']);
$this->assertSame('{"id": 2}', $result[0]['result']);
}

public function test_jsonb_path_query_first_with_no_match(): void
{
$dql = 'SELECT JSONB_PATH_QUERY_FIRST(:json, :path) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 1';
$result = $this->executeDqlQuery($dql, [
'json' => '{"items": [{"id": 1}]}',
'path' => '$.items[*] ? (@.id > 1)',
]);
$this->assertNull($result[0]['result']);
}

public function test_jsonb_path_query_first_with_column_reference(): void
{
$dql = 'SELECT JSONB_PATH_QUERY_FIRST(t.object1, :path) as result
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
WHERE t.id = 1';
$result = $this->executeDqlQuery($dql, ['path' => '$.tags[*]']);
$this->assertIsString($result[0]['result']);
$this->assertSame('"developer"', $result[0]['result']);
}
}
Loading
Loading