Филтри
Филтрите определят кои данни се включват в моментната снимка. Изключвайте таблици с кеш, пренебрегвайте колони с променливи времеви отметки или пропускайте временни редове. Филтрите се прилагат при заснемането на моментната снимка и влияят на всички последващи операции (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
Определя кои таблици се включват в моментната снимка. Поддържа glob шаблони чрез PHP и неговия fnmatch().
Изключване на таблици
use Merql\Filter\TableFilter;
$filter = TableFilter::exclude(['sessions', 'cache_*', 'wp_*_log']);
Всяка таблица, която съвпада с шаблон за изключване, се пропуска от моментната снимка. Заместващият знак * съвпада с произволна поредица от символи.
Включване на таблици
$filter = TableFilter::include(['posts', 'comments', 'users']);
Заснемат се само таблиците, които съвпадат с шаблон за включване. Всички останали се изключват.
Как работи
Методът apply() на филтъра приема списък с имена на таблици и връща филтрираното подмножество:
$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']
Когато има шаблони за включване и изключване (чрез отделни екземпляри на филтъра), първо се обработва изключването. За да бъде запазена, една таблица не трябва да съвпада с нито един шаблон за изключване и трябва да съвпада поне с един шаблон за включване.
ColumnFilter
Премахва определени колони от данните на реда при заснемането. Полезно е за променливи колони, които се изменят при всяко записване и биха довели до фалшиви разлики.
use Merql\Filter\ColumnFilter;
$filter = ColumnFilter::ignore(['updated_at', 'modified_date', 'last_login']);
Често срещани случаи на употреба
updated_at/modified_atвремеви отметки, които се променят при всяко записване.revisionброячи, които се увеличават автоматично.session_tokenили други временни полета.
Как работи
Филтърът премахва посочените колони от всеки ред, след като бъде изчислен ключът на реда:
$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']
Ключът на реда (идентичността) се изчислява от нефилтрирания ред. Това означава, че филтърът за колони никога не засяга колоните за идентичност. Филтрират се само данните, използвани за изчисляване на отпечатъка и за сравняване на разликите.
RowFilter
Филтрира отделни редове чрез затваряне-предикат. Затварянето получава името на таблицата и пълните данни на реда, а връща true, за да включи реда, или false, за да го изключи.
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;
});
Как работи
Методът shouldInclude() се извиква за всеки ред при заснемането:
$include = $filter->shouldInclude('posts', ['id' => 1, 'status' => 'draft']);
// false
Изключените редове не се използват за изчисляване на отпечатък, не се съхраняват в моментната снимка и не се появяват в разликите или сливанията.
Комбиниране на филтри
Подайте няколко филтъра на capture(). Използва се най-много по един филтър от всеки тип:
$snapshot = $snapshotter->capture('baseline', filters: [
TableFilter::exclude(['cache_*']),
ColumnFilter::ignore(['updated_at']),
RowFilter::create(fn($table, $row) => ($row['active'] ?? '1') === '1'),
]);
Ред на обработка:
- TableFilter се изпълнява първи и определя кои таблици да бъдат заснети.
- За всяка таблица се прочитат редовете от базата данни.
- RowFilter се изпълнява за всеки ред и изключва несъответстващите редове.
- От нефилтрирания ред се изчислява ключът на реда (колоните за идентичност остават непокътнати).
- ColumnFilter премахва игнорираните колони от данните на реда.
- От филтрираните данни на реда се изчислява отпечатъкът.
Този ред на обработка гарантира, че колоните за идентичност винаги са налични при изчисляването на ключа, дори ако впоследствие бъдат премахнати от филтъра за колони.
Филтри и съгласуваност
За трите моментни снимки в едно сливане (base, ours, theirs) трябва да се използват едни и същи филтри. При различни филтри може да изглежда, че редове или колони са добавени или премахнати, когато всъщност просто са филтрирани по различен начин.
// 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);