diff --git a/src/Client.php b/src/Client.php index ca07d77..638ce9e 100644 --- a/src/Client.php +++ b/src/Client.php @@ -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}"); + } + } + } } diff --git a/tests/RunEventQlQueryTest.php b/tests/RunEventQlQueryTest.php new file mode 100644 index 0000000..3fdb845 --- /dev/null +++ b/tests/RunEventQlQueryTest.php @@ -0,0 +1,59 @@ +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']); + } +}