Gå til indhold

Filtre

Filtre styrer, hvilke data der medtages i et øjebliksbillede. Udeluk cachetabeller, ignorér flygtige tidsstempelkolonner, eller spring midlertidige rækker over. Filtre anvendes, når øjebliksbilledet tages, og påvirker alle efterfølgende handlinger (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

Styrer, hvilke tabeller der medtages i et øjebliksbillede. Understøtter glob-mønstre via PHPs fnmatch().

Udeluk tabeller

PHP
use Merql\Filter\TableFilter;

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

Enhver tabel, der matcher et udelukkelsesmønster, udelades fra øjebliksbilledet. Jokertegnet * matcher enhver sekvens af tegn.

Medtag tabeller

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

Kun tabeller, der matcher et medtagelsesmønster, indgår i optagelsen. Alle andre udelukkes.

Sådan fungerer det

Filterets metode apply() tager en liste over tabelnavne og returnerer det filtrerede udvalg:

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

Når både medtagelses- og udelukkelsesmønstre er angivet (via separate filterinstanser), evalueres udelukkelse først. En tabel skal hverken matche et udelukkelsesmønster eller undlade at matche mindst ét medtagelsesmønster for at blive medtaget.

ColumnFilter

Fjerner bestemte kolonner fra rækkedata under optagelsen. Nyttigt til flygtige kolonner, der ændres ved hver skrivning og ville medføre falske diff-resultater.

PHP
use Merql\Filter\ColumnFilter;

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

Almindelige anvendelser

  • updated_at / modified_at-tidsstempler, der ændres ved hver lagring.
  • revision-tællere, der automatisk tæller op.
  • session_token eller andre midlertidige felter.

Sådan fungerer det

Filteret fjerner navngivne kolonner fra hver række, efter at rækkenøglen er beregnet:

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

Rækkenøglen (identiteten) beregnes ud fra den ufiltrerede række. Det betyder, at identitetskolonner aldrig påvirkes af kolonnefilteret. Kun de data, der bruges til fingeraftryk og diff, filtreres.

RowFilter

Filtrerer enkelte rækker ved hjælp af et prædikat-closure. Closuren modtager tabelnavnet og de fulde rækkedata og returnerer true for at medtage rækken eller false for at udelukke den.

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

Sådan fungerer det

Metoden shouldInclude() kaldes for hver række under optagelsen:

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

Udelukkede rækker får ikke beregnet fingeraftryk, gemmes ikke i øjebliksbilledet og vises ikke i diff-resultater eller merges.

Kombination af filtre

Send flere filtre til capture(). Der bruges højst ét filter af hver type:

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

Behandlingsrækkefølge:

  1. TableFilter køres først og afgør, hvilke tabeller der skal medtages.
  2. For hver tabel læses rækkerne fra databasen.
  3. RowFilter køres på hver række og udelukker rækker, der ikke matcher.
  4. Rækkenøglen beregnes ud fra den ufiltrerede række (identitetskolonnerne er intakte).
  5. ColumnFilter fjerner ignorerede kolonner fra rækkedataene.
  6. Fingeraftrykket beregnes ud fra de filtrerede rækkedata.

Denne rækkefølge sikrer, at identitetskolonner altid er tilgængelige, når nøglen beregnes, også selvom kolonnerne senere fjernes af kolonnefilteret.

Filtre og konsistens

De samme filtre bør bruges til alle tre øjebliksbilleder i en merge (base, vores, deres). Hvis der bruges forskellige filtre, kan rækker eller kolonner se ud til at være tilføjet eller fjernet, selvom de blot er blevet filtreret forskelligt.

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