
# Zapytania

`RecordQuery` to filtr strumieniowy używany z `stream()`. Obsługuje wzorce dostępu związane z dopisywaniem: wznowienie od kursora, odczyt z określonego przedziału czasu, filtrowanie według zgodności wartości pola i zatrzymanie po osiągnięciu limitu. W przypadku bardziej złożonych warunków, sortowania i wyszukiwania z użyciem indeksów skorzystaj z [konstruktora zapytań](https://storh.inline0.dev/pl/docs/query-builder); do wszystkiego, co można zrobić za pomocą zwykłego `foreach` na strumieniu, `RecordQuery` jest tańszym narzędziem.

`RecordQuery` jest niezmienne. Każdy modyfikator zwraca sklonowane zapytanie:

```php
$query = Storh\RecordQuery::all()
    ->after($lastSeenId)
    ->time_range_ms($fromMs, $untilMs)
    ->where_equal('kind', 'page')
    ->limit(100);

foreach ($store->stream($query) as $record) {
    // Records are yielded lazily.
}
```

`after()` i `time_range_ms()` używają sortowania UUID, więc nie potrzebują pola znacznika czasu w danych rekordu. W `SegmentedLog` pomijają też zbędną pracę: segmenty,
których zakres identyfikatorów wypada poza oknem, nigdy nie są otwierane, a rzadkie
indeksy dla poszczególnych segmentów pozwalają szybko przejść do pierwszego pasującego rekordu zamiast
skanować od początku.

`where_equal()` porównuje pole danych najwyższego poziomu z `===` i akceptuje wartości skalarne lub `null`. Filtr `null` dopasowuje rekordy, w których pole istnieje
i ma wartość null; rekordy bez tego pola nie zostaną dopasowane.

## Stronicowanie za pomocą kursora

Identyfikatory są sortowane według czasu utworzenia, więc ostatni identyfikator jednej strony jest kursorem dla
następnej:

```php
$page = iterator_to_array($store->stream(
    Storh\RecordQuery::all()->after($lastSeenId)->limit(100)
), false);

$lastSeenId = [] === $page ? $lastSeenId : end($page)->id();
```

## Obsługa uszkodzonych rekordów

Domyślnie skanowanie kończy się błędem przy pierwszym nieczytelnym rekordzie. Użyj
`continue_on_error()`, jeśli skanowanie ma go pominąć i zgłosić błąd
zamiast tego:

```php
$query = Storh\RecordQuery::all()->continue_on_error(
    static function (string $location, Throwable $error): void {
        error_log($location . ': ' . $error->getMessage());
    },
);
```

Lokalizacja to identyfikator rekordu dla `DocStore` i `segment-file:byte-offset`
w przypadku `SegmentedLog`. `repair()` służy do faktycznego czyszczenia uszkodzonych
rekordów; zobacz [CLI](https://storh.inline0.dev/pl/docs/cli).
