Přejít k obsahu

Filtry

Filtry určují, která data budou zahrnuta do snímku. Můžete vyloučit tabulky mezipaměti, ignorovat proměnlivé sloupce s časovými razítky nebo přeskočit dočasné řádky. Filtry se použijí při pořizování snímku a ovlivní všechny následující operace (diff, merge, apply).

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

Určuje, které tabulky se zahrnou do snímku. Podporuje vzory glob pomocí PHP fnmatch().

Vyloučení tabulek

PHP
use Merql\Filter\TableFilter;

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

Každá tabulka odpovídající vzoru vyloučení se ze snímku vynechá. Zástupný znak * odpovídá libovolné posloupnosti znaků.

Zahrnutí tabulek

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

Zaznamenají se pouze tabulky odpovídající vzoru zahrnutí. Všechny ostatní se vyloučí.

Jak to funguje

Metoda apply() filtru přijímá seznam názvů tabulek a vrací vyfiltrovanou podmnožinu:

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']

Pokud jsou přítomny vzory zahrnutí i vyloučení (v samostatných instancích filtrů), nejprve se vyhodnotí vyloučení. Tabulka nesmí odpovídat žádnému vzoru vyloučení a musí odpovídat alespoň jednomu vzoru zahrnutí, aby byla zachována.

ColumnFilter

Při pořizování snímku odstraňuje konkrétní sloupce z dat řádků. Hodí se pro proměnlivé sloupce, které se mění při každém zápisu a způsobovaly by falešné rozdíly.

PHP
use Merql\Filter\ColumnFilter;

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

Běžné případy použití

  • Časová razítka updated_at / modified_at, která se mění při každém uložení.
  • Počítadla revision s automatickým navyšováním.
  • session_token nebo jiná přechodná pole.

Jak to funguje

Filtr odstraní pojmenované sloupce z každého řádku poté, co se vypočítá klíč řádku:

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']

Klíč řádku (identita) se vypočítá z nefiltrovaného řádku. Filtr sloupců proto nikdy neovlivní identifikační sloupce. Filtrují se pouze data použitá k výpočtu otisku a porovnání rozdílů.

RowFilter

Filtruje jednotlivé řádky pomocí predikátové uzávěry. Uzávěra obdrží název tabulky a úplná data řádku a vrátí true, pokud má být řádek zahrnut, nebo false, pokud má být vyloučen.

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;
});

Jak to funguje

Metoda shouldInclude() se při pořizování snímku zavolá pro každý řádek:

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

Vyloučené řádky se nezahrnou do výpočtu otisku ani do snímku a neobjeví se v rozdílech ani sloučeních.

Kombinování filtrů

Předejte metodě capture() více filtrů. Použije se nejvýše jeden filtr každého typu:

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

Pořadí zpracování:

  1. Nejprve se spustí TableFilter, který určí, které tabulky se zaznamenají.
  2. Pro každou tabulku se z databáze načtou řádky.
  3. RowFilter se spustí pro každý řádek a vyloučí řádky, které nevyhovují.
  4. Z nefiltrovaného řádku se vypočítá klíč řádku (identifikační sloupce zůstávají zachovány).
  5. ColumnFilter odstraní z dat řádku ignorované sloupce.
  6. Z filtrovaných dat řádku se vypočítá otisk.

Toto pořadí zajišťuje, že identifikační sloupce jsou vždy dostupné pro výpočet klíče, i když je filtr sloupců později odstraní.

Filtry a konzistence

Pro všechna tři snímkování při sloučení (base, ours, theirs) by se měly používat stejné filtry. Při použití různých filtrů se mohou řádky nebo sloupce jevit jako přidané či odebrané, přestože byly pouze odlišně vyfiltrovány.

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);