Filtros
Los filtros controlan qué datos se incluyen en una instantánea. Excluya tablas de caché, ignore columnas de marcas de tiempo volátiles u omita filas transitorias. Los filtros se aplican durante la captura y afectan a todas las operaciones posteriores (comparación, combinación, aplicación).
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
Controla qué tablas se incluyen en una instantánea. Admite patrones glob mediante el fnmatch() de PHP.
Excluir tablas
use Merql\Filter\TableFilter;
$filter = TableFilter::exclude(['sessions', 'cache_*', 'wp_*_log']);
Toda tabla que coincida con un patrón de exclusión se omite de la instantánea. El comodín * coincide con cualquier secuencia de caracteres.
Incluir tablas
$filter = TableFilter::include(['posts', 'comments', 'users']);
Solo se capturan las tablas que coinciden con un patrón de inclusión. Todas las demás se excluyen.
Cómo funciona
El método apply() del filtro recibe una lista de nombres de tablas y devuelve el subconjunto filtrado:
$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']
Cuando hay patrones de inclusión y exclusión (en instancias de filtro distintas), la exclusión se evalúa primero. Para conservar una tabla, esta no debe coincidir con ningún patrón de exclusión y debe coincidir con al menos uno de inclusión.
ColumnFilter
Quita columnas concretas de los datos de las filas durante la captura. Es útil para columnas volátiles que cambian con cada escritura y provocarían diferencias falsas.
use Merql\Filter\ColumnFilter;
$filter = ColumnFilter::ignore(['updated_at', 'modified_date', 'last_login']);
Casos de uso habituales
- Marcas de tiempo
updated_at/modified_atque cambian con cada guardado. - Contadores
revisionque se incrementan automáticamente. session_tokenu otros campos transitorios.
Cómo funciona
El filtro elimina las columnas indicadas de cada fila después de calcular su clave:
$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']
La clave de fila (identidad) se calcula a partir de la fila sin filtrar. Esto significa que el filtro de columnas nunca afecta a las columnas de identidad. Solo se filtran los datos usados para calcular huellas digitales y comparar.
RowFilter
Filtra filas individuales mediante un cierre predicado. El cierre recibe el nombre de la tabla y todos los datos de la fila, y devuelve true para incluirla o false para excluirla.
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;
});
Cómo funciona
El método shouldInclude() se llama para cada fila durante la captura:
$include = $filter->shouldInclude('posts', ['id' => 1, 'status' => 'draft']);
// false
Las filas excluidas no se someten a cálculo de huellas digitales, no se guardan en la instantánea ni aparecen en comparaciones o combinaciones.
Combinar filtros
Pase varios filtros a capture(). Se usa como máximo un filtro de cada tipo:
$snapshot = $snapshotter->capture('baseline', filters: [
TableFilter::exclude(['cache_*']),
ColumnFilter::ignore(['updated_at']),
RowFilter::create(fn($table, $row) => ($row['active'] ?? '1') === '1'),
]);
Orden de procesamiento:
- TableFilter se ejecuta primero y determina qué tablas se capturan.
- Se leen las filas de cada tabla de la base de datos.
- RowFilter se aplica a cada fila y excluye las que no coinciden.
- Se calcula la clave de fila a partir de la fila sin filtrar (con las columnas de identidad intactas).
- ColumnFilter elimina las columnas ignoradas de los datos de la fila.
- Se calcula la huella digital a partir de los datos filtrados de la fila.
Este orden garantiza que las columnas de identidad estén siempre disponibles para calcular la clave, aunque el filtro de columnas las elimine posteriormente.
Filtros y coherencia
Se deben usar los mismos filtros para las tres instantáneas de una combinación (base, nuestra y suya). Si se usan filtros distintos, puede parecer que se han añadido o eliminado filas o columnas cuando, en realidad, solo se filtraron de manera diferente.
// 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);