@@ -63,6 +63,7 @@ use core::ffi::{c_int, c_void, CStr};
63
63
use create_crr:: create_crr;
64
64
use db_version:: {
65
65
crsql_fill_db_version_if_needed, crsql_next_db_version, crsql_peek_next_db_version,
66
+ insert_db_version,
66
67
} ;
67
68
use is_crr:: * ;
68
69
use local_writes:: after_delete:: x_crsql_after_delete;
@@ -369,34 +370,51 @@ pub extern "C" fn sqlite3_crsqlcore_init(
369
370
}
370
371
371
372
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 ) ;
383
401
if rc != ResultCode :: OK {
384
402
unsafe { crsql_freeExtData ( ext_data) } ;
385
403
return null_mut ( ) ;
386
404
}
387
405
388
406
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 ) ;
400
418
if rc != ResultCode :: OK {
401
419
unsafe { crsql_freeExtData ( ext_data) } ;
402
420
return null_mut ( ) ;
@@ -883,6 +901,40 @@ unsafe extern "C" fn x_crsql_next_db_version(
883
901
ctx. result_int64 ( ret) ;
884
902
}
885
903
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
+
886
938
/**
887
939
* Return the next version of the database for use in inserts/updates/deletes
888
940
* without updating the the database or value in ext_data.
@@ -898,7 +950,6 @@ unsafe extern "C" fn x_crsql_peek_next_db_version(
898
950
let db = ctx. db_handle ( ) ;
899
951
let mut err_msg = null_mut ( ) ;
900
952
901
-
902
953
let ret = crsql_peek_next_db_version ( db, ext_data, & mut err_msg as * mut _ ) ;
903
954
if ret < 0 {
904
955
// TODO: use err_msg!
0 commit comments