小巧、快速、可靠。
任選三項。

Session 模組 C 介面

重新設定變更集

typedef struct sqlite3_rebaser sqlite3_rebaser;

重要:此介面為 實驗性質,可能會在不另行通知的情況下變更。

假設有一個網站,在狀態 S0 中存放一個資料庫。然後,進行修改,將資料庫移至狀態 S1,並記錄一個變更集(「本機」變更集)。接著,從另一個網站接收一個基於 S0 的變更集(「遠端」變更集),並將其套用至資料庫。然後,資料庫會進入狀態 (S1 +「遠端」),其中確切的狀態取決於套用「遠端」時所做的任何衝突解決決定(略過或取代)。重新設定變更集是為了更新變更集,以考量這些衝突解決決定,這樣就不必在網路中的其他地方解決相同的衝突。

例如,如果本機和遠端變更集都包含在「CREATE TABLE t1(a PRIMARY KEY, b)」上插入相同金鑰的 INSERT

本機:INSERT INTO t1 VALUES(1, 'v1'); 遠端:INSERT INTO t1 VALUES(1, 'v2');

且衝突解決為取代,則會從本機變更集中移除 INSERT 變更(已覆寫)。或者,如果衝突解決為「略過」,則會修改本機變更集,改為包含

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,則 old.* 值會使用遠端變更中的 new.* 值重新建立。或者,如果解決方案為 REPLACE,則變更會複製至重新建立的變更集中,並移除與衝突的遠端 UPDATE 也更新的欄位。如果這表示不會更新任何欄位,則會省略變更。

本機變更可能會同時針對多個遠端變更重新建立。如果單一金鑰由多個遠端變更集修改,則在重新建立本機變更集之前,會將它們合併如下

請注意,來自多個遠端變更集的衝突解析度會根據每個欄位合併,而不是根據每列合併。這表示在多個遠端 UPDATE 操作的情況下,單一本機變更的某些欄位可能會重新建立為 REPLACE,而其他欄位則重新建立為 OMIT。

為了重新建立本機變更集,必須先使用 sqlite3changeset_apply_v2() 將遠端變更集套用至本機資料庫,並擷取重新建立資訊的緩衝區。然後

  1. 透過呼叫 sqlite3rebaser_create() 來建立一個 sqlite3_rebaser 物件。
  2. 透過呼叫 sqlite3rebaser_configure(),使用從 sqlite3changeset_apply_v2() 取得的重新建立緩衝區來設定新物件。如果要針對多個遠端變更集重新建立本機變更集,則應以與執行多個 sqlite3changeset_apply_v2() 呼叫相同的順序,多次呼叫 sqlite3rebaser_configure()。
  3. 透過呼叫 sqlite3rebaser_rebase() 來重新建立每個本機變更集。
  4. 透過呼叫 sqlite3rebaser_delete() 來刪除 sqlite3_rebaser 物件。

另請參閱 物件常數函數 清單。