Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions core/rs/bundle_static/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions core/rs/core/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions core/rs/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ sqlite_nostd = { path="../sqlite-rs-embedded/sqlite_nostd" }
bytes = { version = "1.5", default-features = false }
num-traits = { version = "0.2.17", default-features = false }
num-derive = "0.4.1"
libc-print = "0.1.22"

[dev-dependencies]

Expand Down
139 changes: 71 additions & 68 deletions core/rs/core/src/changes_vtab_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,13 @@ fn did_cid_win(
let col_vrsn_stmt_ref = tbl_info.get_col_version_stmt(db)?;
let col_vrsn_stmt = col_vrsn_stmt_ref.as_ref().ok_or(ResultCode::ERROR)?;

let bind_result = col_vrsn_stmt.bind_int64(1, key);
let bind_result = col_vrsn_stmt
.bind_int64(1, key)
.and_then(|_| col_vrsn_stmt.bind_text(2, col_name, sqlite::Destructor::STATIC));
if let Err(rc) = bind_result {
reset_cached_stmt(col_vrsn_stmt.stmt)?;
return Err(rc);
}
if let Err(rc) = col_vrsn_stmt.bind_text(2, col_name, sqlite::Destructor::STATIC) {
reset_cached_stmt(col_vrsn_stmt.stmt)?;
return Err(rc);
}

match col_vrsn_stmt.step() {
Ok(ResultCode::ROW) => {
Expand Down Expand Up @@ -98,16 +96,13 @@ fn did_cid_win(
let col_site_id_stmt_ref = tbl_info.get_col_site_id_stmt(db)?;
let col_site_id_stmt = col_site_id_stmt_ref.as_ref().ok_or(ResultCode::ERROR)?;

let bind_result = col_site_id_stmt.bind_int64(1, key);
let bind_result = col_site_id_stmt.bind_int64(1, key).and_then(|_| {
col_site_id_stmt.bind_text(2, col_name, sqlite::Destructor::STATIC)
});
if let Err(rc) = bind_result {
reset_cached_stmt(col_site_id_stmt.stmt)?;
return Err(rc);
}
if let Err(rc) = col_site_id_stmt.bind_text(2, col_name, sqlite::Destructor::STATIC)
{
reset_cached_stmt(col_site_id_stmt.stmt)?;
return Err(rc);
}

match col_site_id_stmt.step() {
Ok(ResultCode::ROW) => {
Expand Down Expand Up @@ -171,52 +166,68 @@ fn set_winner_clock(
if insert_site_id.is_empty() {
None
} else {
(*ext_data).pSelectSiteIdOrdinalStmt.bind_blob(
let bind_result = (*ext_data).pSelectSiteIdOrdinalStmt.bind_blob(
1,
insert_site_id,
sqlite::Destructor::STATIC,
)?;
let rc = (*ext_data).pSelectSiteIdOrdinalStmt.step()?;
if rc == ResultCode::ROW {
let ordinal = (*ext_data).pSelectSiteIdOrdinalStmt.column_int64(0);
(*ext_data).pSelectSiteIdOrdinalStmt.clear_bindings()?;
(*ext_data).pSelectSiteIdOrdinalStmt.reset()?;

Some(ordinal)
} else {
(*ext_data).pSelectSiteIdOrdinalStmt.clear_bindings()?;
(*ext_data).pSelectSiteIdOrdinalStmt.reset()?;
// site id had no ordinal yet.
// set one and return the ordinal.
(*ext_data).pSetSiteIdOrdinalStmt.bind_blob(
1,
insert_site_id,
sqlite::Destructor::STATIC,
)?;
let rc = (*ext_data).pSetSiteIdOrdinalStmt.step()?;
if rc == ResultCode::DONE {
(*ext_data).pSetSiteIdOrdinalStmt.clear_bindings()?;
(*ext_data).pSetSiteIdOrdinalStmt.reset()?;
return Err(ResultCode::ABORT);
);

if let Err(rc) = bind_result {
reset_cached_stmt((*ext_data).pSelectSiteIdOrdinalStmt)?;
return Err(rc);
}

match (*ext_data).pSelectSiteIdOrdinalStmt.step() {
Ok(ResultCode::ROW) => {
let ordinal = (*ext_data).pSelectSiteIdOrdinalStmt.column_int64(0);
reset_cached_stmt((*ext_data).pSelectSiteIdOrdinalStmt)?;
Some(ordinal)
}
Ok(_) => {
reset_cached_stmt((*ext_data).pSelectSiteIdOrdinalStmt)?;
// site id had no ordinal yet.
// set one and return the ordinal.
let bind_result = (*ext_data).pSetSiteIdOrdinalStmt.bind_blob(
1,
insert_site_id,
sqlite::Destructor::STATIC,
);

if let Err(rc) = bind_result {
reset_cached_stmt((*ext_data).pSetSiteIdOrdinalStmt);
return Err(rc);
}

match (*ext_data).pSetSiteIdOrdinalStmt.step() {
Ok(ResultCode::DONE) => {
reset_cached_stmt((*ext_data).pSetSiteIdOrdinalStmt)?;
return Err(ResultCode::ABORT);
}
Ok(_) => {
let ordinal = (*ext_data).pSetSiteIdOrdinalStmt.column_int64(0);
reset_cached_stmt((*ext_data).pSetSiteIdOrdinalStmt)?;
Some(ordinal)
}
Err(rc) => {
reset_cached_stmt((*ext_data).pSetSiteIdOrdinalStmt)?;
return Err(rc);
}
}
}
Err(rc) => {
reset_cached_stmt((*ext_data).pSetSiteIdOrdinalStmt)?;
return Err(rc);
}
let ordinal = (*ext_data).pSetSiteIdOrdinalStmt.column_int64(0);
(*ext_data).pSetSiteIdOrdinalStmt.clear_bindings()?;
(*ext_data).pSetSiteIdOrdinalStmt.reset()?;
Some(ordinal)
}
}
};

let set_stmt_ref = tbl_info.get_set_winner_clock_stmt(db)?;
let set_stmt = set_stmt_ref.as_ref().ok_or(ResultCode::ERROR)?;

let bind_result = set_stmt.bind_int64(1, key);
if let Err(rc) = bind_result {
reset_cached_stmt(set_stmt.stmt)?;
return Err(rc);
}
let bind_result = set_stmt
.bind_text(2, insert_col_name, sqlite::Destructor::STATIC)
.bind_int64(1, key)
.and_then(|_| set_stmt.bind_text(2, insert_col_name, sqlite::Destructor::STATIC))
.and_then(|_| set_stmt.bind_int64(3, insert_col_vrsn))
.and_then(|_| set_stmt.bind_int64(4, insert_db_vrsn))
.and_then(|_| set_stmt.bind_int64(5, insert_seq))
Expand Down Expand Up @@ -266,18 +277,16 @@ fn merge_sentinel_only_insert(
(*ext_data)
.pSetSyncBitStmt
.step()
.and_then(|_| (*ext_data).pSetSyncBitStmt.reset())
.and_then(|_| merge_stmt.step())
};

// TODO: report err?
let _ = reset_cached_stmt(merge_stmt.stmt);
unsafe { (*ext_data).pSetSyncBitStmt.reset()? };
reset_cached_stmt(merge_stmt.stmt)?;

let sync_rc = unsafe {
(*ext_data)
.pClearSyncBitStmt
.step()
.and_then(|_| (*ext_data).pClearSyncBitStmt.reset())
let rc = (*ext_data).pClearSyncBitStmt.step();
(*ext_data).pClearSyncBitStmt.reset()?;
rc
};

if let Err(sync_rc) = sync_rc {
Expand Down Expand Up @@ -343,16 +352,14 @@ unsafe fn merge_delete(
let rc = (*ext_data)
.pSetSyncBitStmt
.step()
.and_then(|_| (*ext_data).pSetSyncBitStmt.reset())
.and_then(|_| delete_stmt.step());

(*ext_data).pSetSyncBitStmt.reset()?;
reset_cached_stmt(delete_stmt.stmt)?;

let sync_rc = (*ext_data)
.pClearSyncBitStmt
.step()
.and_then(|_| (*ext_data).pClearSyncBitStmt.reset());
let sync_rc = (*ext_data).pClearSyncBitStmt.step();

(*ext_data).pClearSyncBitStmt.reset()?;
if let Err(sync_rc) = sync_rc {
return Err(sync_rc);
}
Expand Down Expand Up @@ -407,12 +414,9 @@ fn get_local_cl(
let local_cl_stmt_ref = tbl_info.get_local_cl_stmt(db)?;
let local_cl_stmt = local_cl_stmt_ref.as_ref().ok_or(ResultCode::ERROR)?;

let rc = local_cl_stmt.bind_int64(1, key);
if let Err(rc) = rc {
reset_cached_stmt(local_cl_stmt.stmt)?;
return Err(rc);
}
let rc = local_cl_stmt.bind_int64(2, key);
let rc = local_cl_stmt
.bind_int64(1, key)
.and_then(|_| local_cl_stmt.bind_int64(2, key));
if let Err(rc) = rc {
reset_cached_stmt(local_cl_stmt.stmt)?;
return Err(rc);
Expand Down Expand Up @@ -661,15 +665,14 @@ unsafe fn merge_insert(
let rc = (*(*tab).pExtData)
.pSetSyncBitStmt
.step()
.and_then(|_| (*(*tab).pExtData).pSetSyncBitStmt.reset())
.and_then(|_| merge_stmt.step());

reset_cached_stmt(merge_stmt.stmt)?;

let sync_rc = (*(*tab).pExtData)
.pClearSyncBitStmt
.step()
.and_then(|_| (*(*tab).pExtData).pClearSyncBitStmt.reset());
let sync_rc = (*(*tab).pExtData).pClearSyncBitStmt.step();

(*(*tab).pExtData).pSetSyncBitStmt.reset();
(*(*tab).pExtData).pClearSyncBitStmt.reset();

if let Err(rc) = rc {
return Err(rc);
Expand Down
39 changes: 39 additions & 0 deletions core/rs/core/src/debug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use alloc::format;
use alloc::string::String;
use core::ffi::c_void;
use sqlite::{context, value};
use sqlite_nostd as sqlite;

// Global context for logging - will be set during initialization
static mut DEBUG_ENABLED: bool = false;

pub fn debug_log(msg: &str) {
unsafe {
if DEBUG_ENABLED {
libc_print::libc_println!("[DEBUG] {}", msg);
}
}
}

pub unsafe extern "C" fn x_crsql_set_debug(ctx: *mut context, argc: i32, argv: *mut *mut value) {
if argc == 0 {
// If no arguments, return current state
sqlite::result_int(ctx, if DEBUG_ENABLED { 1 } else { 0 });
return;
}

if argc > 1 {
// Too many arguments
return;
}

let enabled = {
let arg = *argv;
sqlite::value_int(arg) != 0
};

DEBUG_ENABLED = enabled;

// Return success (the new state)
sqlite::result_int(ctx, if enabled { 1 } else { 0 });
}
19 changes: 19 additions & 0 deletions core/rs/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ mod create_crr;
pub mod db_version;
#[cfg(not(feature = "test"))]
mod db_version;
mod debug;
mod ext_data;
mod is_crr;
mod local_writes;
Expand Down Expand Up @@ -69,6 +70,8 @@ use tableinfo::{crsql_ensure_table_infos_are_up_to_date, is_table_compatible, pu
use teardown::*;
use triggers::create_triggers;

pub use debug::debug_log;

pub extern "C" fn crsql_as_table(
ctx: *mut sqlite::context,
argc: i32,
Expand Down Expand Up @@ -109,6 +112,22 @@ pub extern "C" fn sqlite3_crsqlcore_init(
) -> *mut c_void {
sqlite::EXTENSION_INIT2(api);

let rc = db
.create_function_v2(
"crsql_set_debug",
1,
sqlite::UTF8 | sqlite::DIRECTONLY,
None,
Some(debug::x_crsql_set_debug),
None,
None,
None,
)
.unwrap_or(sqlite::ResultCode::ERROR);
if rc != ResultCode::OK {
return null_mut();
}

let rc = db
.create_function_v2(
"crsql_automigrate",
Expand Down
Loading
Loading