Skip to content

Commit 03821da

Browse files
committed
add fn to set crsql db_version
1 parent 34c56ba commit 03821da

File tree

4 files changed

+92
-28
lines changed

4 files changed

+92
-28
lines changed

core/rs/core/src/lib.rs

Lines changed: 74 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ use core::ffi::{c_int, c_void, CStr};
6363
use create_crr::create_crr;
6464
use db_version::{
6565
crsql_fill_db_version_if_needed, crsql_next_db_version, crsql_peek_next_db_version,
66+
insert_db_version,
6667
};
6768
use is_crr::*;
6869
use local_writes::after_delete::x_crsql_after_delete;
@@ -369,34 +370,51 @@ pub extern "C" fn sqlite3_crsqlcore_init(
369370
}
370371

371372
let rc = db
372-
.create_function_v2(
373-
"crsql_set_ts",
374-
-1,
375-
sqlite::UTF8 | sqlite::DETERMINISTIC,
376-
Some(ext_data as *mut c_void),
377-
Some(x_crsql_set_ts),
378-
None,
379-
None,
380-
None,
381-
)
382-
.unwrap_or(ResultCode::ERROR);
373+
.create_function_v2(
374+
"crsql_set_ts",
375+
-1,
376+
sqlite::UTF8 | sqlite::DETERMINISTIC,
377+
Some(ext_data as *mut c_void),
378+
Some(x_crsql_set_ts),
379+
None,
380+
None,
381+
None,
382+
)
383+
.unwrap_or(ResultCode::ERROR);
384+
if rc != ResultCode::OK {
385+
unsafe { crsql_freeExtData(ext_data) };
386+
return null_mut();
387+
}
388+
389+
let rc = db
390+
.create_function_v2(
391+
"crsql_set_db_version",
392+
-1,
393+
sqlite::UTF8 | sqlite::DETERMINISTIC,
394+
Some(ext_data as *mut c_void),
395+
Some(x_crsql_set_db_version),
396+
None,
397+
None,
398+
None,
399+
)
400+
.unwrap_or(ResultCode::ERROR);
383401
if rc != ResultCode::OK {
384402
unsafe { crsql_freeExtData(ext_data) };
385403
return null_mut();
386404
}
387405

388406
let rc = db
389-
.create_function_v2(
390-
"crsql_get_ts",
391-
-1,
392-
sqlite::UTF8 | sqlite::DETERMINISTIC,
393-
Some(ext_data as *mut c_void),
394-
Some(x_crsql_get_ts),
395-
None,
396-
None,
397-
None,
398-
)
399-
.unwrap_or(ResultCode::ERROR);
407+
.create_function_v2(
408+
"crsql_get_ts",
409+
-1,
410+
sqlite::UTF8 | sqlite::DETERMINISTIC,
411+
Some(ext_data as *mut c_void),
412+
Some(x_crsql_get_ts),
413+
None,
414+
None,
415+
None,
416+
)
417+
.unwrap_or(ResultCode::ERROR);
400418
if rc != ResultCode::OK {
401419
unsafe { crsql_freeExtData(ext_data) };
402420
return null_mut();
@@ -883,6 +901,40 @@ unsafe extern "C" fn x_crsql_next_db_version(
883901
ctx.result_int64(ret);
884902
}
885903

904+
/**
905+
* Return the next version of the database for use in inserts/updates/deletes
906+
*
907+
* `select crsql_set_db_version()`
908+
*
909+
* This is used to set the db version for a particular site_id.
910+
* This is useful for exposing a way for the application to set a db_version
911+
* that might not get passed to crsqlite.
912+
*/
913+
unsafe extern "C" fn x_crsql_set_db_version(
914+
ctx: *mut sqlite::context,
915+
argc: i32,
916+
argv: *mut *mut sqlite::value,
917+
) {
918+
if argc < 2 {
919+
ctx.result_error(
920+
"Wrong number of args provided to crsql_set_db_version. Provide the
921+
site id and db version.",
922+
);
923+
return;
924+
}
925+
926+
let args = sqlite::args!(argc, argv);
927+
let (site_id, db_version) = (args[0].blob(), args[1].int64());
928+
let ext_data = ctx.user_data() as *mut c::crsql_ExtData;
929+
930+
let ret = insert_db_version(ext_data, site_id, db_version);
931+
if ret.is_err() {
932+
ctx.result_error("Unable to set the db version");
933+
return;
934+
}
935+
ctx.result_text_static("OK");
936+
}
937+
886938
/**
887939
* Return the next version of the database for use in inserts/updates/deletes
888940
* without updating the the database or value in ext_data.
@@ -898,7 +950,6 @@ unsafe extern "C" fn x_crsql_peek_next_db_version(
898950
let db = ctx.db_handle();
899951
let mut err_msg = null_mut();
900952

901-
902953
let ret = crsql_peek_next_db_version(db, ext_data, &mut err_msg as *mut _);
903954
if ret < 0 {
904955
// TODO: use err_msg!

core/rs/core/src/local_writes/after_update.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,14 @@ fn after_update(
8888
let next_seq = super::bump_seq(ext_data);
8989
changed = true;
9090
// Record the delete of the row identified by the old primary keys
91-
after_update__mark_old_pk_row_deleted(db, tbl_info, old_key, next_db_version, next_seq, &ts)?;
91+
after_update__mark_old_pk_row_deleted(
92+
db,
93+
tbl_info,
94+
old_key,
95+
next_db_version,
96+
next_seq,
97+
&ts,
98+
)?;
9299
let next_seq = super::bump_seq(ext_data);
93100
// todo: we don't need to this, if there's no existing row (cl is assumed to be 1).
94101
super::mark_new_pk_row_created(db, tbl_info, new_key, next_db_version, next_seq, &ts)?;

core/rs/core/src/local_writes/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,13 @@ fn mark_locally_inserted(
170170
})
171171
.and_then(|_| combo_insert_clock_stmt.bind_int64(offset + 3, db_version))
172172
.and_then(|_| combo_insert_clock_stmt.bind_int(offset + 4, seq))
173-
.and_then(|_| combo_insert_clock_stmt.bind_text(offset + 5, ts, sqlite::Destructor::STATIC))
173+
.and_then(|_| {
174+
combo_insert_clock_stmt.bind_text(
175+
offset + 5,
176+
ts,
177+
sqlite::Destructor::STATIC,
178+
)
179+
})
174180
.map_err(|code| {
175181
format!("failed binding to combo_insert_clock_stmt, code: {code}")
176182
})?;

core/src/ext-data.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ crsql_ExtData *crsql_newExtData(sqlite3 *db, unsigned char *siteIdBuffer) {
5555
// printf("instantiating pSetDbVersionStmt... current rc: %d\n", rc);
5656
rc += sqlite3_prepare_v3(
5757
db,
58-
"INSERT OR REPLACE INTO crsql_db_versions (site_id, db_version) VALUES "
58+
"INSERT INTO crsql_db_versions (site_id, db_version) VALUES "
5959
"(?, ?) ON "
60-
"CONFLICT (site_id) DO UPDATE SET db_version = max(excluded.db_version, "
61-
"crsql_db_versions.db_version) RETURNING db_version",
60+
"CONFLICT (site_id) DO UPDATE SET db_version = excluded.db_version "
61+
"WHERE crsql_db_versions.db_version < excluded.db_version RETURNING db_version",
6262
-1, SQLITE_PREPARE_PERSISTENT, &(pExtData->pSetDbVersionStmt), 0);
6363

6464
// printf("instantiated pSetDbVersionStmt, rc: %d\n", rc);

0 commit comments

Comments
 (0)