跳转到正文

试运行预览

DryRun::generate() 会生成易读的 SQL 语句,并将值内插到语句中。应用到数据库之前,可用它检查合并将执行的操作。

PHP
use Merql\Apply\DryRun;

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

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

预览会为结果中的每个操作生成一条语句,并按照 Applier 的分组方式排列:先插入,再更新,最后删除。对于完整的合并结果,这些语句涵盖两侧相对于 base 的所有变更,也就是在数据库仍保存 base 时 Merql::apply() 将执行的操作。预览所选结果,即可查看你计划应用的操作对应的语句。

输出示例

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 用于为标识符加引号的数据库驱动。

试运行与 SqlGenerator 的区别

DryRun 对 SqlGenerator 进行了封装。区别如下:

  • SqlGenerator::generate() 返回供适配器执行预处理语句使用的 ['sql' => '...', 'params' => [...]] 数组。
  • DryRun::generate() 返回值已内联的普通字符串,供人阅读。

不要将试运行输出作为 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 标志:

命令行
vendor/bin/merql merge base ours theirs --dry-run

CLI 不使用外键排序或驱动来打印语句,因此无论数据库类型如何,标识符都使用默认的反引号引号格式。它会传入基础快照以处理标识列。其合并方式与 Merql::merge() 一样,是列级合并。