试运行预览
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() 一样,是列级合并。