小巧、快速、可靠。
三者选其二。

会话模块 C 接口

重新基线变更集

typedef struct sqlite3_rebaser sqlite3_rebaser;

重要提示:此接口为 实验性 接口,可能会在未经通知的情况下更改。

假设有一个网站托管着一个处于状态 S0 的数据库。然后进行了一些修改,将该数据库移到状态 S1,并记录了一个变更集(“本地”变更集)。接着,从另一个网站收到基于 S0 的变更集(“远程”变更集)并将其应用到数据库中。此时数据库便处于 (S1+"远程") 状态,具体状态取决于应用“远程”变更集时进行的任何冲突解决决策 (OMIT 或 REPLACE)。重新基线变更集是指更新变更集,使其能考虑到这些冲突解决决策,从而避免在网络中其他地方重复解决相同的冲突。

例如,如果本地和远程变更集都包含对 "CREATE TABLE t1(a PRIMARY KEY, b)" 的相同键的 INSERT 操作

本地:INSERT INTO t1 VALUES(1, 'v1'); 远程:INSERT INTO t1 VALUES(1, 'v2');

并且冲突解决决策为 REPLACE,那么 INSERT 更改将从本地变更集中删除(已被覆盖)。或者,如果冲突解决决策为 "OMIT",那么本地变更集将修改为包含以下内容

UPDATE t1 SET b = 'v2' WHERE a=1;

本地变更集中的更改将按以下方式重新基线

本地 INSERT
这可能只与远程 INSERT 冲突。如果冲突解决决策为 OMIT,那么将向重新基线变更集中添加 UPDATE 更改。或者,如果冲突解决决策为 REPLACE,那么不向重新基线变更集中添加任何内容。

本地 DELETE
这可能与远程 UPDATE 或 DELETE 冲突。在这两种情况下,唯一可能的解决方法都是 OMIT。如果远程操作为 DELETE,那么不向重新基线变更集中添加任何更改。如果远程操作为 UPDATE,那么更改的 old.* 字段将更新为反映 UPDATE 中的 new.* 值。

本地 UPDATE
这可能与远程 UPDATE 或 DELETE 冲突。如果它与 DELETE 冲突,并且冲突解决决策为 OMIT,那么更新将更改为 INSERT。更新更改中的 new.* 记录中任何未定义的值都将使用冲突 DELETE 中的 old.* 值填充。或者,如果冲突解决决策为 REPLACE,那么 UPDATE 更改将简单地从重新基线变更集中省略。

如果冲突是与远程 UPDATE 冲突,并且解决方法为 OMIT,那么将使用远程更改中的 new.* 值重新基线 old.* 值。或者,如果解决方法为 REPLACE,那么更改将被复制到重新基线变更集中,同时删除由冲突的远程 UPDATE 更新的列的更新。如果这意味着没有列将被更新,那么更改将被省略。

本地更改可以同时针对多个远程更改进行重新基线。如果多个远程变更集修改了同一个键,那么在重新基线本地变更集之前,它们将按以下方式组合

请注意,来自多个远程变更集的冲突解决是在每个字段的基础上组合的,而不是在每行基础上组合的。这意味着在多个远程 UPDATE 操作的情况下,单个本地更改的某些字段可能会根据 REPLACE 进行重新基线,而其他字段可能会根据 OMIT 进行重新基线。

为了重新基线本地变更集,必须首先使用 sqlite3changeset_apply_v2() 将远程变更集应用到本地数据库,并捕获重新基线信息的缓冲区。然后

  1. 通过调用 sqlite3rebaser_create() 创建一个 sqlite3_rebaser 对象。
  2. 通过调用 sqlite3rebaser_configure(),使用从 sqlite3changeset_apply_v2() 获得的重新基线缓冲区配置新对象。如果本地变更集要针对多个远程变更集进行重新基线,那么应该多次调用 sqlite3rebaser_configure(),调用顺序与多个 sqlite3changeset_apply_v2() 调用的顺序相同。
  3. 通过调用 sqlite3rebaser_rebase() 对每个本地变更集进行重新基线。
  4. 通过调用 sqlite3rebaser_delete() 删除 sqlite3_rebaser 对象。

另请参阅 对象常量函数 列表。