@@ -2,9 +2,10 @@ extern crate alloc;
22
33use alloc:: boxed:: Box ;
44use alloc:: string:: String ;
5+ use alloc:: sync:: Arc ;
56use const_format:: formatcp;
67use core:: ffi:: { c_char, c_int, c_void, CStr } ;
7- use core:: ptr :: null_mut ;
8+ use core:: sync :: atomic :: Ordering ;
89use serde:: Serialize ;
910use serde_json:: value:: RawValue ;
1011
@@ -15,6 +16,7 @@ use sqlite_nostd::{self as sqlite, ColumnType};
1516use crate :: error:: SQLiteError ;
1617use crate :: ext:: SafeManagedStmt ;
1718use crate :: schema:: TableInfoFlags ;
19+ use crate :: state:: DatabaseState ;
1820use crate :: util:: MAX_OP_ID ;
1921use crate :: vtab_util:: * ;
2022
@@ -41,6 +43,7 @@ struct VirtualTable {
4143 db : * mut sqlite:: sqlite3 ,
4244 current_tx : Option < ActiveCrudTransaction > ,
4345 is_simple : bool ,
46+ state : Arc < DatabaseState > ,
4447}
4548
4649struct ActiveCrudTransaction {
@@ -86,6 +89,15 @@ impl VirtualTable {
8689 . ok_or_else ( || SQLiteError ( ResultCode :: MISUSE , Some ( String :: from ( "No tx_id" ) ) ) ) ?;
8790 let db = self . db ;
8891
92+ if self . state . is_in_sync_local . load ( Ordering :: Relaxed ) {
93+ // Don't collect CRUD writes while we're syncing the local database - writes made here
94+ // aren't writes we should upload.
95+ // This normally doesn't happen because we insert directly into the data tables, but
96+ // users might have custom raw tables used for sycing with triggers on them to call
97+ // this function. And those specifically should not trigger here.
98+ return Ok ( ( ) ) ;
99+ }
100+
89101 match & mut current_tx. mode {
90102 CrudTransactionMode :: Manual ( manual) => {
91103 // Columns are (data TEXT, options INT HIDDEN)
@@ -258,7 +270,7 @@ fn prepare_lazy(
258270
259271extern "C" fn connect (
260272 db : * mut sqlite:: sqlite3 ,
261- _aux : * mut c_void ,
273+ aux : * mut c_void ,
262274 argc : c_int ,
263275 argv : * const * const c_char ,
264276 vtab : * mut * mut sqlite:: vtab ,
@@ -289,6 +301,14 @@ extern "C" fn connect(
289301 pModule : core:: ptr:: null ( ) ,
290302 zErrMsg : core:: ptr:: null_mut ( ) ,
291303 } ,
304+ state : {
305+ // Increase refcount - we can't use from_raw alone because we don't own the aux
306+ // data (connect could be called multiple times).
307+ let state = Arc :: from_raw ( aux as * mut DatabaseState ) ;
308+ let clone = state. clone ( ) ;
309+ core:: mem:: forget ( state) ;
310+ clone
311+ } ,
292312 db,
293313 current_tx : None ,
294314 is_simple,
@@ -380,20 +400,20 @@ static MODULE: sqlite_nostd::module = sqlite_nostd::module {
380400 xIntegrity : None ,
381401} ;
382402
383- pub fn register ( db : * mut sqlite:: sqlite3 ) -> Result < ( ) , ResultCode > {
403+ pub fn register ( db : * mut sqlite:: sqlite3 , state : Arc < DatabaseState > ) -> Result < ( ) , ResultCode > {
384404 sqlite:: convert_rc ( sqlite:: create_module_v2 (
385405 db,
386406 SIMPLE_NAME . as_ptr ( ) ,
387407 & MODULE ,
388- null_mut ( ) ,
389- None ,
408+ Arc :: into_raw ( state . clone ( ) ) as * mut c_void ,
409+ Some ( DatabaseState :: destroy_arc ) ,
390410 ) ) ?;
391411 sqlite:: convert_rc ( sqlite:: create_module_v2 (
392412 db,
393413 MANUAL_NAME . as_ptr ( ) ,
394414 & MODULE ,
395- null_mut ( ) ,
396- None ,
415+ Arc :: into_raw ( state ) as * mut c_void ,
416+ Some ( DatabaseState :: destroy_arc ) ,
397417 ) ) ?;
398418
399419 Ok ( ( ) )
0 commit comments