
# Filtrid

Filtrid määravad, millised andmed hetktõmmisesse kaasatakse. Jäta vahemälutabelid välja, eira muutuvaid ajatempliveerge või jäta ajutised read vahele. Filtreid rakendatakse hetktõmmise jäädvustamisel ning need mõjutavad kõiki järgnevaid toiminguid (erinevuste leidmine, ühendamine, rakendamine).

```php
use Merql\Filter\TableFilter;
use Merql\Filter\ColumnFilter;
use Merql\Snapshot\Snapshotter;

$snapshotter = new Snapshotter($connection);

$snapshot = $snapshotter->capture('baseline', filters: [
    TableFilter::exclude(['sessions', 'cache_*']),
    ColumnFilter::ignore(['updated_at', 'modified_date']),
]);
```

## TableFilter

Määrab, millised tabelid hetktõmmisesse kaasatakse. Toetab globaalseid mustreid, kasutades PHP `fnmatch()`.

### Tabelite väljajätmine

```php
use Merql\Filter\TableFilter;

$filter = TableFilter::exclude(['sessions', 'cache_*', 'wp_*_log']);
```

Kõik välistamismustrile vastavad tabelid jäetakse hetktõmmisest välja. Metamärk `*` tähistab mis tahes pikkusega märgijada.

### Tabelite kaasamine

```php
$filter = TableFilter::include(['posts', 'comments', 'users']);
```

Jäädvustatakse ainult kaasamismustrile vastavad tabelid. Kõik ülejäänud jäetakse välja.

### Kuidas see töötab

Filtri meetod `apply()` võtab tabelinimede loendi ja tagastab filtreeritud alamhulga:

```php
$allTables = ['posts', 'comments', 'sessions', 'cache_pages', 'users'];

$filter = TableFilter::exclude(['sessions', 'cache_*']);
$filtered = $filter->apply($allTables);
// ['posts', 'comments', 'users']

$filter = TableFilter::include(['posts', 'users']);
$filtered = $filter->apply($allTables);
// ['posts', 'users']
```

Kui olemas on nii kaasamis- kui ka välistamismustrid (eraldi filtrieksemplaride kaudu), hinnatakse esmalt välistamist. Tabel jäetakse alles ainult siis, kui see ei vasta ühelegi välistamismustrile ja vastab vähemalt ühele kaasamismustrile.

## ColumnFilter

Eemaldab jäädvustamise ajal reaandmetest kindlad veerud. Kasulik muutuvate veergude puhul, mis muutuvad iga kirjutamisega ja põhjustaksid valesid erinevusi.

```php
use Merql\Filter\ColumnFilter;

$filter = ColumnFilter::ignore(['updated_at', 'modified_date', 'last_login']);
```

### Levinud kasutusjuhud

- `updated_at` / `modified_at` ajatemplid, mis muutuvad iga salvestamisega.
- `revision` loendurid, mis suurenevad automaatselt.
- `session_token` või muud ajutised väljad.

### Kuidas see töötab

Filter eemaldab iga rea nimetatud veerud pärast reavõtme arvutamist:

```php
$filter = ColumnFilter::ignore(['updated_at']);

$row = ['id' => 1, 'title' => 'Hello', 'updated_at' => '2026-01-15 10:30:00'];
$filtered = $filter->applyToRow($row);
// ['id' => 1, 'title' => 'Hello']
```

Reavõti (identiteet) arvutatakse filtreerimata reast. See tähendab, et veerufilter ei mõjuta kunagi identiteediveerge. Filtreeritakse ainult sõrmejälje ja erinevuste leidmiseks kasutatavaid andmeid.

## RowFilter

Filtreerib üksikuid ridu predikaat-closure'i abil. Closure saab tabelinime ja kõik rea andmed ning tagastab `true` rea kaasamiseks või `false` selle väljajätmiseks.

```php
use Merql\Filter\RowFilter;

// Exclude draft posts.
$filter = RowFilter::create(function (string $table, array $row): bool {
    if ($table === 'posts' && ($row['status'] ?? '') === 'draft') {
        return false;
    }
    return true;
});

// Exclude rows with NULL email.
$filter = RowFilter::create(function (string $table, array $row): bool {
    if ($table === 'users') {
        return $row['email'] !== null;
    }
    return true;
});
```

### Kuidas see töötab

Meetodit `shouldInclude()` kutsutakse jäädvustamisel iga rea puhul:

```php
$include = $filter->shouldInclude('posts', ['id' => 1, 'status' => 'draft']);
// false
```

Väljajäetud ridu ei sõrmejäljestata ega salvestata hetktõmmisesse ning need ei ilmu erinevustes ega ühendustes.

## Filtrite kombineerimine

Edasta `capture()`-le mitu filtrit. Iga filtritüübi kohta kasutatakse kõige rohkem üht filtrit:

```php
$snapshot = $snapshotter->capture('baseline', filters: [
    TableFilter::exclude(['cache_*']),
    ColumnFilter::ignore(['updated_at']),
    RowFilter::create(fn($table, $row) => ($row['active'] ?? '1') === '1'),
]);
```

Töötlemise järjekord:

1. **TableFilter** käivitub esimesena ja määrab, millised tabelid jäädvustada.
2. Iga tabeli puhul loetakse read andmebaasist.
3. **RowFilter** käivitub iga rea puhul ja jätab mittevastavad read välja.
4. **Reavõti** arvutatakse filtreerimata reast (identiteediveerud on alles).
5. **ColumnFilter** eemaldab reaandmetest eiratavad veerud.
6. **Sõrmejälg** arvutatakse filtreeritud reaandmetest.

See järjekord tagab, et identiteediveerud on võtme arvutamiseks alati saadaval, isegi kui veerufilter need hiljem eemaldab.

## Filtrid ja kooskõla

Ühendamise kõigi kolme hetktõmmise (alus, meie oma, nende oma) puhul tuleks kasutada samu filtreid. Erinevate filtrite kasutamisel võivad read või veerud näida lisatute või eemaldatutena, kuigi tegelikult filtreeriti neid lihtsalt erinevalt.

```php
// Use the same filter set for all snapshots.
$filters = [
    TableFilter::exclude(['sessions']),
    ColumnFilter::ignore(['updated_at']),
];

$base   = $snapshotter->capture('base', filters: $filters);
$ours   = $snapshotter->capture('ours', filters: $filters);
$theirs = $snapshotter->capture('theirs', filters: $filters);
```
