Pereiti prie turinio

Filtrai

Filtrai nustato, kurie duomenys įtraukiami į momentinę kopiją. Neįtraukite talpyklos lentelių, ignoruokite kintančius laiko žymų stulpelius arba praleiskite laikinas eilutes. Filtrai taikomi fiksuojant momentinę kopiją ir veikia visas tolesnes operacijas (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

Nustato, kurios lentelės įtraukiamos į momentinę kopiją. Palaiko glob šablonus naudojant PHP fnmatch().

Lentelių neįtraukimas

PHP
use Merql\Filter\TableFilter;

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

Bet kuri lentelė, atitinkanti neįtraukimo šabloną, į momentinę kopiją neįtraukiama. Pakaitos simbolis * atitinka bet kokią simbolių seką.

Lentelių įtraukimas

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

Užfiksuojamos tik lentelės, atitinkančios įtraukimo šabloną. Visos kitos neįtraukiamos.

Kaip tai veikia

Filtro metodas apply() priima lentelių pavadinimų sąrašą ir grąžina filtruotą jo dalį:

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

Kai yra ir įtraukimo, ir neįtraukimo šablonų (atskiruose filtrų egzemplioriuose), pirmiausia įvertinamas neįtraukimas. Kad lentelė būtų palikta, ji negali atitikti nė vieno neįtraukimo šablono ir turi atitikti bent vieną įtraukimo šabloną.

ColumnFilter

Fiksuojant kopiją iš eilučių duomenų pašalinami konkretūs stulpeliai. Tai naudinga kintantiems stulpeliams, kurių reikšmės keičiasi kiekvieną kartą įrašant ir dėl to atsirastų klaidingų skirtumų.

PHP
use Merql\Filter\ColumnFilter;

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

Dažniausi naudojimo atvejai

  • updated_at / modified_at laiko žymos, kurios keičiasi kaskart įrašant.
  • revision skaitikliai, kurie didėja automatiškai.
  • session_token ar kiti laikini laukai.

Kaip tai veikia

Filtras pašalina nurodytus stulpelius iš kiekvienos eilutės, apskaičiavus eilutės raktą:

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

Eilutės raktas (tapatybė) apskaičiuojamas iš nefiltruotos eilutės. Tai reiškia, kad stulpelių filtras niekada nepaveikia tapatybės stulpelių. Filtruojami tik duomenys, naudojami kontrolinei sumai ir skirtumams apskaičiuoti.

RowFilter

Filtruoja atskiras eilutes pagal predikato uždarymą. Uždarymas gauna lentelės pavadinimą ir visus eilutės duomenis, o grąžina true, kad eilutė būtų įtraukta, arba false, kad ji būtų neįtraukta.

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

Kaip tai veikia

Fiksuojant kopiją kiekvienai eilutei iškviečiamas metodas shouldInclude():

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

Neįtrauktų eilučių kontrolinės sumos neskaičiuojamos, jos neišsaugomos momentinėje kopijoje ir nerodomos skirtumuose ar sujungimuose.

Filtrų derinimas

Perduokite capture() kelis filtrus. Naudojamas ne daugiau kaip vienas kiekvieno tipo filtras:

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

Apdorojimo tvarka:

  1. TableFilter vykdomas pirmiausia ir nustato, kurios lentelės bus užfiksuotos.
  2. Iš duomenų bazės nuskaitomos kiekvienos lentelės eilutės.
  3. RowFilter taikomas kiekvienai eilutei ir pašalina neatitinkančias.
  4. Eilutės raktas apskaičiuojamas iš nefiltruotos eilutės (tapatybės stulpeliai išsaugomi).
  5. ColumnFilter pašalina ignoruojamus stulpelius iš eilutės duomenų.
  6. Kontrolinė suma apskaičiuojama pagal filtruotus eilutės duomenis.

Tokia tvarka užtikrina, kad tapatybės stulpeliai visada būtų prieinami raktui apskaičiuoti, net jei stulpelių filtras juos vėliau pašalina.

Filtrai ir nuoseklumas

Visoms trims momentinėms kopijoms (base, ours, theirs) sujungimo metu reikėtų naudoti tuos pačius filtrus. Naudojant skirtingus filtrus, eilutės ar stulpeliai gali atrodyti pridėti arba pašalinti, nors iš tikrųjų jie buvo filtruoti skirtingai.

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