
# Introduktion

merql är ett rent PHP-bibliotek som utför trevägssammanfogningar av databastillstånd. Det tar snapshots av tabeller, beräknar ändringsuppsättningar mellan snapshots, sammanfogar två ändringsuppsättningar mot en gemensam bas och upptäcker konflikter på kolumnnivå. Samma algoritm som git använder för källfiler, tillämpad på rader och kolumner i stället för rader i text.

Inga externa verktyg. Stöder MySQL och SQLite via anslutningsadaptrar och dialektdrivrutiner som kan kopplas in.

## Snabbexempel

En sammanfogning kräver tre tillstånd av samma data: basen som båda kopiorna utgick från och de två kopiorna efter att de ändrats oberoende av varandra. Här kopierades en sandlåda från den aktiva databasen, och båda har redigerats sedan dess.

```php
use Merql\Connection;
use Merql\Merql;

$live    = Connection::sqlite('/data/live.sqlite');
$sandbox = Connection::sqlite('/data/sandbox.sqlite');

// Base: live at the moment the sandbox was copied from it.
Merql::init($live);
Merql::snapshot('base');

// ... copy live.sqlite to sandbox.sqlite, then both databases change ...

// Ours: the sandbox with our edits. Theirs: live with its own changes.
Merql::init($sandbox);
Merql::snapshot('ours');
Merql::init($live);
Merql::snapshot('theirs');

$result = Merql::merge('base', 'ours', 'theirs');

if ($result->isClean()) {
    foreach ($result->operations() as $operation) {
        echo "{$operation->type} {$operation->table} #{$operation->rowKey} ({$operation->source})\n";
    }
} else {
    echo "Conflicts: {$result->conflictCount()}\n";
}
```

Varje ögonblicksbild hämtas från databasen som innehåller det aktuella tillståndet. Att ta alla tre från en och samma databas i följd beskriver inte två förgrenade kopior: deras skulle redan innehålla våra ändringar, och varje rad som vi infogat skulle rapporteras som en `insert_insert`-konflikt.

Resultatet listar åtgärderna som omvandlar basen till det sammanslagna tillståndet, från båda sidorna, var och en märkt med sin källa (`ours`, `theirs` eller `merged`). Om du vill skriva sandlådans ändringar till live tillämpar du de åtgärder som live ännu inte har med [Tillämpa med skydd](https://merql.inline0.dev/sv/docs/apply/guarded).

Eller från CLI, som ansluter till databasen som anges i `MERQL_DB_DSN` för varje `snapshot`:

```bash
MERQL_DB_DSN="sqlite:/data/live.sqlite" vendor/bin/merql snapshot base
# ... copy live.sqlite to sandbox.sqlite, then both databases change ...
MERQL_DB_DSN="sqlite:/data/sandbox.sqlite" vendor/bin/merql snapshot ours
MERQL_DB_DSN="sqlite:/data/live.sqlite" vendor/bin/merql snapshot theirs

vendor/bin/merql merge base ours theirs --dry-run
```

## Varför merql

De flesta databasverktyg som jämför tillstånd arbetar på radnivå: om någon kolumn i en rad skiljer sig mellan två versioner markeras hela raden som en konflikt. Det leder till falska konflikter när två personer redigerar olika kolumner i samma rad.

merql slår samman på kolumnnivå. Om den ena sidan ändrade `title` och den andra ändrade `status` slås ändringarna samman utan konflikt. En konflikt uppstår bara när båda sidorna ändrar samma kolumn till olika värden.

För kolumner av typen TEXT och JSON kan merql gå ett steg djupare med sammanslagning på cellnivå. Två ändringar på olika rader i en textkolumn, eller på olika nycklar i en kolumn av typen JSON, kan slås samman utan konflikt med samma trevägsalgoritm. Sammanslagning på cellnivå är valfri: skicka med en `CellMergeConfig` till `ThreeWayMerge`. Gränssnittet `Merql` och CLI-verktyget slår endast samman på kolumnnivå. Se [Sammanslagning på cellnivå](https://merql.inline0.dev/sv/docs/merge/cell-level).

## Sammanslagningsmodellen

```
         Base (snapshot at fork time)
        /                              \
   Ours (one copy's changes)            Theirs (the other copy's changes)
        \                              /
         --------- MERGE ----------
                     |
              Merged result
              + conflicts (if any)
```

Tre tillstånd, precis som i git. Basen är den gemensamma förfadern. Vår och deras är de två kopiorna efter att de förgrenats, var och en hämtad från sin egen databas. Sammanslagningsreglerna behandlar båda sidor lika. Namnen förekommer i varje åtgärds `source`, i konflikttyper (`update_delete` betyder att vi uppdaterade och de tog bort) och i lösningsprinciperna `OursWins` och `TheirsWins`. Utan en gemensam bas går det inte att skilja mellan ”tillagd” och ”oförändrad”.

En sammanslagning skriver ingenting i sig. Dess åtgärder omvandlar basen till det sammanslagna tillståndet, så `Merql::apply()` kör dem alla utan problem endast mot en databas som fortfarande innehåller basen. Om du vill föra in den ena sidans ändringar i en databas som redan innehåller den andra sidans ändringar, till exempel genom att föra över ändringar från sandlådan till live, tillämpar du endast de åtgärder som saknas där; se [Tillämpa med skydd](https://merql.inline0.dev/sv/docs/apply/guarded).

## Krav

- PHP 8.2 eller senare.
- `ext-mbstring` och `ext-zlib`, som krävs av beroendet `pitmaster/pitmaster` för textjämförelsen.
- Ett databastillägg för den adapter du använder: `ext-pdo` med `ext-pdo_sqlite` eller `ext-pdo_mysql`, eller `ext-mysqli`. merql:s `composer.json` föreslår endast `ext-pdo` och `ext-mysqli`, så Composer kontrollerar inte om de finns.
- En databas av typen MySQL eller SQLite. Andra databasmotorer kräver en anpassad [drivrutin](https://merql.inline0.dev/sv/docs/apply/drivers).

## Vad det inte är

merql är inte ett verktyg för schemamigrering. Det replikerar inte databaser och synkroniserar dem inte i realtid. Det löser ett specifikt problem: givet tre databastillstånd skapar det ett fjärde, sammanslaget tillstånd där konflikterna identifieras.

## Dokumentation

- [Komma igång](https://merql.inline0.dev/sv/docs/getting-started) -- installation, första ögonblicksbilden, första sammanslagningen.
- [CLI Referens](https://merql.inline0.dev/sv/docs/cli) -- fullständig referens för kommandot `vendor/bin/merql`.
- [PHP API Referens](https://merql.inline0.dev/sv/docs/api) -- fullständig API dokumentation för alla klasser.
- [Sammanslagningsplaner](https://merql.inline0.dev/sv/docs/merge/plans) -- stabila operations-ID:n, ändringsgrupper och urval.
- [Skyddad tillämpning](https://merql.inline0.dev/sv/docs/apply/guarded) -- valda skrivningar med förvillkor för live-rader.
- [Återställning](https://merql.inline0.dev/sv/docs/apply/rollback) -- återställningsartefakter och avvikelsekontroller.
