Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a766032
chore: Add .idea to .gitignore
Jul 15, 2025
ca127a4
chore: rectorphp was implemented and the following adjustments
Jul 18, 2025
cad1ad3
feat: Add ReadEvents with the associated dependencies and the test cl…
Jul 18, 2025
6c0326e
chore: remove .idea from .gitignore and clean up configuration files
Jul 18, 2025
28b7de2
chore: ractor config adjustement - skip SimplifyUselessVariableRector
Jul 18, 2025
484bdd4
feat: refactoring the ReadEventsOptions jsonSerialize method
Jul 18, 2025
5cce131
chore: replace iterator_to_array with iterator_count in write and rea…
Jul 18, 2025
2329365
feat: implement ReadEventLine and Utils for reading NDJSON streams
Jul 19, 2025
c1a6660
Merge branch 'main' into reading
Jul 19, 2025
3e9b132
Merge branch 'thenativeweb:main' into main
wundii Jul 19, 2025
ff364c4
Merge branch 'main' into reading
Jul 19, 2025
bafe2c5
chore: remove commented-out blueprint code from Utils.php
Jul 19, 2025
28333f2
feat: implement runEventQlQuery method and add corresponding tests
Jul 19, 2025
0f64f0c
chore: rename Utils.php to NdJson.php and update method references
Jul 20, 2025
b54e2f1
test: add unit tests for NdJson stream reading functionality
Jul 20, 2025
3522cc6
Merge branch 'reading' into RunEventQlQuery
Jul 20, 2025
1db4811
Merge branch 'thenativeweb:main' into main
wundii Jul 20, 2025
662ce77
Merge branch 'refs/heads/main' into RunEventQlQuery
Jul 20, 2025
3c14f3e
chore: merge
Jul 20, 2025
1293e87
chore: rename variable in RunEventQlQueryTest for clarity
Jul 20, 2025
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
40 changes: 40 additions & 0 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,4 +184,44 @@ public function readEvents(string $subject, ReadEventsOptions $readEventsOptions
}
}
}

public function runEventQlQuery(string $query): iterable
{
$requestBody = [
'query' => $query,
];

$response = $this->httpClient->post(
'/api/v1/run-eventql-query',
[
'headers' => [
'Authorization' => 'Bearer ' . $this->apiToken,
'Content-Type' => 'application/json',
],
'json' => $requestBody,
],
);
$status = $response->getStatusCode();

if ($status !== 200) {
throw new RuntimeException(sprintf(
"Failed to run EventQL query, got HTTP status code '%d', expected '200'",
$status
));
}

foreach (NdJson::readStream($response->getBody()) as $eventLine) {
switch ($eventLine->type) {
case 'row':
$row = $eventLine->payload;
yield $row;

break;
case 'error':
throw new RuntimeException($eventLine->payload['error'] ?? 'unknown error');
default:
throw new RuntimeException("Failed to handle unsupported line type {$eventLine->type}");
}
}
}
}
59 changes: 59 additions & 0 deletions tests/RunEventQlQueryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

use PHPUnit\Framework\TestCase;
use Thenativeweb\Eventsourcingdb\EventCandidate;
use Thenativeweb\Eventsourcingdb\Tests\ClientTestTrait;

final class RunEventQlQueryTest extends TestCase
{
use ClientTestTrait;

public function testNoRowsIfTheQueryDoesNotReturnAnyRows(): void
{
$didReadRows = false;
foreach ($this->client->runEventQlQuery('FROM e IN events PROJECT INTO e') as $event) {
$didReadRows = true;
}

$this->assertFalse($didReadRows, 'Expected no rows to be read, but some were found.');
}

public function testReadsAllRowsTheQueryReturn(): void
{
$firstEvent = new EventCandidate(
source: 'https://www.eventsourcingdb.io',
subject: '/test',
type: 'io.eventsourcingdb.test',
data: [
'value' => 23,
],
);

$secondEvent = new EventCandidate(
source: 'https://www.eventsourcingdb.io',
subject: '/test',
type: 'io.eventsourcingdb.test',
data: [
'value' => 42,
],
);

iterator_count($this->client->writeEvents([
$firstEvent,
$secondEvent,
]));

$rowsRead = [];
foreach ($this->client->runEventQlQuery('FROM e IN events PROJECT INTO e') as $row) {
$rowsRead[] = $row;
}

$this->assertCount(2, $rowsRead);
$this->assertSame('0', $rowsRead[0]['id']);
$this->assertSame(23, $rowsRead[0]['data']['value']);
$this->assertSame('1', $rowsRead[1]['id']);
$this->assertSame(42, $rowsRead[1]['data']['value']);
}
}