Filter
Filter mengontrol data yang disertakan dalam snapshot. Kecualikan tabel cache, abaikan kolom cap waktu yang berubah-ubah, atau lewati baris sementara. Filter diterapkan saat pengambilan snapshot dan memengaruhi semua operasi selanjutnya (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
Mengontrol tabel yang disertakan dalam snapshot. Mendukung pola glob melalui PHP fnmatch().
Kecualikan tabel
use Merql\Filter\TableFilter;
$filter = TableFilter::exclude(['sessions', 'cache_*', 'wp_*_log']);
Tabel apa pun yang cocok dengan pola pengecualian tidak disertakan dalam snapshot. Wildcard * cocok dengan rangkaian karakter apa pun.
Sertakan tabel
$filter = TableFilter::include(['posts', 'comments', 'users']);
Hanya tabel yang cocok dengan pola penyertaan yang diambil. Semua tabel lainnya dikecualikan.
Cara kerjanya
Metode apply() pada filter menerima daftar nama tabel dan mengembalikan subset yang telah difilter:
$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']
Jika pola penyertaan dan pengecualian sama-sama ada (melalui instance filter terpisah), pengecualian dievaluasi terlebih dahulu. Agar dipertahankan, tabel tidak boleh cocok dengan pola pengecualian mana pun dan harus cocok dengan setidaknya satu pola penyertaan.
ColumnFilter
Menghapus kolom tertentu dari data baris saat pengambilan. Berguna untuk kolom yang berubah-ubah setiap kali ditulis dan dapat menimbulkan diff palsu.
use Merql\Filter\ColumnFilter;
$filter = ColumnFilter::ignore(['updated_at', 'modified_date', 'last_login']);
Kasus penggunaan umum
- Cap waktu
updated_at/modified_atyang berubah setiap kali disimpan. - Penghitung
revisionyang bertambah otomatis. session_tokenatau kolom sementara lainnya.
Cara kerjanya
Filter menghapus kolom bernama dari setiap baris setelah kunci baris dihitung:
$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']
Kunci baris (identitas) dihitung dari baris yang belum difilter. Artinya, kolom identitas tidak pernah terpengaruh oleh filter kolom. Hanya data yang digunakan untuk sidik jari dan diff yang difilter.
RowFilter
Memfilter baris satu per satu menggunakan closure predikat. Closure menerima nama tabel dan seluruh data baris, lalu mengembalikan true untuk menyertakan baris atau false untuk mengecualikannya.
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;
});
Cara kerjanya
Metode shouldInclude() dipanggil untuk setiap baris selama pengambilan:
$include = $filter->shouldInclude('posts', ['id' => 1, 'status' => 'draft']);
// false
Baris yang dikecualikan tidak dibuatkan sidik jari, tidak disimpan dalam snapshot, dan tidak muncul dalam diff atau merge.
Menggabungkan filter
Berikan beberapa filter ke capture(). Maksimal satu filter untuk setiap jenis yang digunakan:
$snapshot = $snapshotter->capture('baseline', filters: [
TableFilter::exclude(['cache_*']),
ColumnFilter::ignore(['updated_at']),
RowFilter::create(fn($table, $row) => ($row['active'] ?? '1') === '1'),
]);
Urutan pemrosesan:
- TableFilter dijalankan terlebih dahulu untuk menentukan tabel yang akan diambil.
- Untuk setiap tabel, baris dibaca dari database.
- RowFilter dijalankan pada setiap baris untuk mengecualikan baris yang tidak cocok.
- Kunci baris dihitung dari baris yang belum difilter (kolom identitas tetap utuh).
- ColumnFilter menghapus kolom yang diabaikan dari data baris.
- Sidik jari dihitung dari data baris yang telah difilter.
Urutan ini memastikan kolom identitas selalu tersedia untuk penghitungan kunci, meskipun kolom tersebut kemudian dihapus oleh filter kolom.
Filter dan konsistensi
Filter yang sama sebaiknya digunakan untuk ketiga snapshot dalam sebuah merge (base, ours, theirs). Jika filter berbeda digunakan, baris atau kolom mungkin tampak ditambahkan atau dihapus padahal sebenarnya hanya difilter secara berbeda.
// 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);