@@ -63,6 +63,7 @@ use core::ffi::{c_int, c_void, CStr};
6363use create_crr:: create_crr;
6464use db_version:: {
6565 crsql_fill_db_version_if_needed, crsql_next_db_version, crsql_peek_next_db_version,
66+ insert_db_version,
6667} ;
6768use is_crr:: * ;
6869use 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!
0 commit comments