Pular para o conteúdo

Filtros

Os filtros controlam quais dados são incluídos em um snapshot. Exclua tabelas de cache, ignore colunas de data e hora voláteis ou pule linhas temporárias. Os filtros são aplicados durante a captura do snapshot e afetam todas as operações subsequentes (diff, merge, apply).

PHP
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 quais tabelas são incluídas em um snapshot. Aceita padrões glob usando o fnmatch() de PHP.

Excluir tabelas

PHP
use Merql\Filter\TableFilter;

$filter = TableFilter::exclude(['sessions', 'cache_*', 'wp_*_log']);

Qualquer tabela que corresponda a um padrão de exclusão é omitida do snapshot. O curinga * corresponde a qualquer sequência de caracteres.

Incluir tabelas

PHP
$filter = TableFilter::include(['posts', 'comments', 'users']);

Somente as tabelas que correspondem a um padrão de inclusão são capturadas. Todas as outras são excluídas.

Como funciona

O método apply() do filtro recebe uma lista de nomes de tabelas e retorna o subconjunto filtrado:

PHP
$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']

Quando há padrões de inclusão e exclusão (em instâncias de filtro separadas), a exclusão é avaliada primeiro. Para ser mantida, uma tabela não pode corresponder a nenhum padrão de exclusão e deve corresponder a pelo menos um padrão de inclusão.

ColumnFilter

Remove colunas específicas dos dados das linhas durante a captura. É útil para colunas voláteis que mudam a cada gravação e causariam diferenças falsas.

PHP
use Merql\Filter\ColumnFilter;

$filter = ColumnFilter::ignore(['updated_at', 'modified_date', 'last_login']);

Casos de uso comuns

  • Timestamps updated_at / modified_at que mudam a cada salvamento.
  • Contadores revision que são incrementados automaticamente.
  • Campos session_token ou outros campos temporários.

Como funciona

O filtro remove as colunas nomeadas de cada linha depois que a chave da linha é calculada:

PHP
$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']

A chave (identidade) da linha é calculada a partir da linha não filtrada. Isso significa que o filtro de colunas nunca afeta as colunas de identidade. Somente os dados usados para calcular a impressão digital e as diferenças são filtrados.

RowFilter

Filtra linhas individuais usando uma função de predicado. A função recebe o nome da tabela e os dados completos da linha e retorna true para incluir a linha ou false para excluí-la.

PHP
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;
});

Como funciona

O método shouldInclude() é chamado para cada linha durante a captura:

PHP
$include = $filter->shouldInclude('posts', ['id' => 1, 'status' => 'draft']);
// false

As linhas excluídas não têm sua impressão digital calculada, não são armazenadas no snapshot e não aparecem em diferenças nem em mesclagens.

Combinar filtros

Passe vários filtros para capture(). No máximo um filtro de cada tipo é usado:

PHP
$snapshot = $snapshotter->capture('baseline', filters: [
    TableFilter::exclude(['cache_*']),
    ColumnFilter::ignore(['updated_at']),
    RowFilter::create(fn($table, $row) => ($row['active'] ?? '1') === '1'),
]);

Ordem de processamento:

  1. TableFilter é executado primeiro e determina quais tabelas serão capturadas.
  2. Os dados das linhas são lidos do banco de dados para cada tabela.
  3. RowFilter é executado em cada linha e exclui as linhas que não correspondem ao filtro.
  4. A chave da linha é calculada a partir da linha não filtrada (com as colunas de identidade intactas).
  5. ColumnFilter remove as colunas ignoradas dos dados da linha.
  6. A impressão digital é calculada a partir dos dados filtrados da linha.

Essa ordem garante que as colunas de identidade estejam sempre disponíveis para o cálculo da chave, mesmo que sejam removidas posteriormente pelo filtro de colunas.

Filtros e consistência

Os mesmos filtros devem ser usados nos três snapshots de uma mesclagem (base, ours, theirs). Se forem usados filtros diferentes, linhas ou colunas podem parecer adicionadas ou removidas quando, na verdade, apenas foram filtradas de maneiras diferentes.

PHP
// 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);