
# ドライランのプレビュー

`DryRun::generate()`は、値をインラインで埋め込んだ、人が読みやすいSQL文を生成します。データベースに適用する前に、マージで何が行われるかを確認できます。

```php
use Merql\Apply\DryRun;

$statements = DryRun::generate($result);

foreach ($statements as $sql) {
    echo "{$sql};\n";
}
```

プレビューには、結果内の各操作に対応する文が含まれ、`Applier`と同じ順序で、挿入、更新、削除にグループ化されます。マージ全体の結果では、baseに対する両側のすべての変更が対象となり、baseの状態が保持されたデータベースに対して`Merql::apply()`が実行する内容が示されます。適用する予定の操作に対応する文だけを確認するには、[選択した結果](https://merql.inline0.dev/ja/docs/merge/plans)をプレビューしてください。

## 出力例

```sql
INSERT INTO `posts` (`id`, `title`, `content`, `status`) VALUES ('42', 'New Post', 'Body text', 'draft');
UPDATE `posts` SET `title` = 'Updated Title', `status` = 'publish' WHERE `id` = '42';
DELETE FROM `posts` WHERE `id` = '99';
```

更新では、操作に含まれる非識別列がすべて設定され、変更された列だけに限定されません。また、設定する列がない更新は省略されます。

## 値のフォーマット

すべての値はシングルクォートで囲まれます。安全に表示できるよう、特殊文字はエスケープされます:

| 文字 | エスケープ後 |
|---|---|
| `\` (バックスラッシュ) | `\\` |
| `'` (シングルクォート) | `''` |
| `\0` (ヌル文字) | `\0` |
| `\n` (改行) | `\n` |
| `\r` (キャリッジリターン) | `\r` |

NULL値は、引用符で囲まないリテラル`NULL`として出力されます:

```sql
UPDATE `posts` SET `subtitle` = NULL WHERE `id` = '42';
```

## パラメーター

`DryRun::generate()`は`SqlGenerator::generate()`と同じパラメーターを受け取ります:

```php
$statements = DryRun::generate(
    $result,
    base: $baseSnapshot,
    fkDependencies: ['comments' => ['posts']],
    driver: new SqliteDriver(),
);
```

| パラメーター | 型 | 説明 |
|---|---|---|
| `$result` | `MergeResult` | プレビューするマージ結果。 |
| `$base` | `?Snapshot` | 識別列用のベーススナップショット。`$result->baseSnapshot()`にフォールバックします。 |
| `$fkDependencies` | `array` | 順序付けに使用する外部キー依存関係マップ。 |
| `$driver` | `?Driver` | 識別子の引用符付けに使用するデータベースドライバー。 |

## Dry runとSqlGeneratorの比較

`DryRun`は`SqlGenerator`をラップします。違いは次のとおりです:

- `SqlGenerator::generate()`は、アダプターによるプリペアドステートメント実行を目的とした`['sql' => '...', 'params' => [...]]`配列を返します。
- `DryRun::generate()`は、人が読めるように値を埋め込んだフラットな文字列を返します。

dry runの出力をSQLとして実行しないでください。これは表示用にフォーマットされており、安全な実行を目的としていません。マージを実行するには、`Applier`または`SqlGenerator`をプリペアドステートメントとともに直接使用してください。

## ファサードでの使用

ファサード経由でマージ結果を取得し、プレビューします:

```php
use Merql\Merql;
use Merql\Apply\DryRun;

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

$statements = DryRun::generate($result);

foreach ($statements as $sql) {
    echo "{$sql};\n";
}
```

またはCLIから`--dry-run`フラグを使います:

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

CLIは外部キーの順序付けやドライバー指定なしで文を出力するため、データベースにかかわらず識別子には既定のバッククォートによる引用符付けが使われます。識別列にはベーススナップショットが渡されます。マージは`Merql::merge()`と同様に列単位です。
