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).
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
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
$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:
$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.
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_tokeneller andre midlertidige felter.
Sådan fungerer det
Filteret fjerner navngivne kolonner fra hver række, efter at rækkenøglen er beregnet:
$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.
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:
$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:
$snapshot = $snapshotter->capture('baseline', filters: [
TableFilter::exclude(['cache_*']),
ColumnFilter::ignore(['updated_at']),
RowFilter::create(fn($table, $row) => ($row['active'] ?? '1') === '1'),
]);
Behandlingsrækkefølge:
- TableFilter køres først og afgør, hvilke tabeller der skal medtages.
- For hver tabel læses rækkerne fra databasen.
- RowFilter køres på hver række og udelukker rækker, der ikke matcher.
- Rækkenøglen beregnes ud fra den ufiltrerede række (identitetskolonnerne er intakte).
- ColumnFilter fjerner ignorerede kolonner fra rækkedataene.
- 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.
// 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);