Φίλτρα
Τα φίλτρα ελέγχουν ποια δεδομένα περιλαμβάνονται σε ένα στιγμιότυπο. Εξαιρέστε πίνακες προσωρινής αποθήκευσης, αγνοήστε ασταθείς στήλες χρονοσήμανσης ή παραλείψτε προσωρινές γραμμές. Τα φίλτρα εφαρμόζονται κατά τη λήψη του στιγμιότυπου και επηρεάζουν όλες τις επόμενες λειτουργίες (σύγκριση διαφορών, συγχώνευση, εφαρμογή).
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 μέσω του fnmatch() του PHP.
Εξαίρεση πινάκων
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 αφαιρεί τις αγνοούμενες στήλες από τα δεδομένα της γραμμής.
- Το αποτύπωμα υπολογίζεται από τα φιλτραρισμένα δεδομένα της γραμμής.
Αυτή η σειρά διασφαλίζει ότι οι στήλες ταυτότητας είναι πάντα διαθέσιμες για τον υπολογισμό του κλειδιού, ακόμη κι αν αφαιρεθούν αργότερα από το φίλτρο στηλών.
Φίλτρα και συνέπεια
Τα ίδια φίλτρα πρέπει να χρησιμοποιούνται και στα τρία στιγμιότυπα μιας συγχώνευσης (βάση, δικό μας, δικό τους). Αν χρησιμοποιηθούν διαφορετικά φίλτρα, μπορεί να φαίνεται ότι προστέθηκαν ή αφαιρέθηκαν γραμμές ή στήλες, ενώ στην πραγματικότητα φιλτραρίστηκαν διαφορετικά.
// 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);