Skip to content

Commit

Permalink
switch tie-breaker to site_id
Browse files Browse the repository at this point in the history
This is to allow us to preserve transactionality of mutations.

In conjunction with #386, this'll allow fields to be all set together or all reverted together.

Useful for cases where `x` & `y` coordinates are supposed to be updated together or not at all or some such thing.
  • Loading branch information
tantaman committed Oct 30, 2023
1 parent 5364963 commit c371419
Showing 1 changed file with 10 additions and 34 deletions.
44 changes: 10 additions & 34 deletions core/rs/core/src/changes_vtab_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ use crate::util::slab_rowid;
*/
fn did_cid_win(
db: *mut sqlite3,
ext_data: *mut crsql_ExtData,
insert_tbl: &str,
tbl_info: &TableInfo,
unpacked_pks: &Vec<ColumnValue>,
key: sqlite::int64,
insert_site_id: &[u8],
col_name: &str,
insert_val: *mut sqlite::value,
col_version: sqlite::int64,
errmsg: *mut *mut c_char,
) -> Result<bool, ResultCode> {
Expand Down Expand Up @@ -76,38 +77,12 @@ fn did_cid_win(
}

// versions are equal
// need to pull the current value and compare
// we could compare on site_id if we can guarantee site_id is always provided.
// would be slightly more performant..
let col_val_stmt_ref = tbl_info.get_col_value_stmt(db, col_name)?;
let col_val_stmt = col_val_stmt_ref.as_ref().ok_or(ResultCode::ERROR)?;

let bind_result = bind_package_to_stmt(col_val_stmt.stmt, &unpacked_pks, 0);
if let Err(rc) = bind_result {
reset_cached_stmt(col_val_stmt.stmt)?;
return Err(rc);
}

let step_result = col_val_stmt.step();
match step_result {
Ok(ResultCode::ROW) => {
let local_value = col_val_stmt.column_value(0)?;
let ret = crsql_compare_sqlite_values(insert_val, local_value);
reset_cached_stmt(col_val_stmt.stmt)?;
return Ok(ret > 0);
}
_ => {
// ResultCode::DONE would happen if clock values exist but actual values are missing.
// should we just allow the insert anyway?
reset_cached_stmt(col_val_stmt.stmt)?;
let err = CString::new(format!(
"could not find row to merge with for tbl {}",
insert_tbl
))?;
unsafe { *errmsg = err.into_raw() };
return Err(ResultCode::ERROR);
}
}
// need to compare site ids
let ret = unsafe {
let my_site_id = core::slice::from_raw_parts((*ext_data).siteId, 16);
insert_site_id.cmp(my_site_id) as c_int
};
return Ok(ret > 0);
}

fn set_winner_clock(
Expand Down Expand Up @@ -585,12 +560,13 @@ unsafe fn merge_insert(
|| !row_exists_locally
|| did_cid_win(
db,
(*tab).pExtData,
insert_tbl,
&tbl_info,
&unpacked_pks,
key,
insert_site_id,
insert_col,
insert_val,
insert_col_vrsn,
errmsg,
)?;
Expand Down

0 comments on commit c371419

Please sign in to comment.