@@ -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 {
@@ -79,6 +82,15 @@ impl VirtualTable {
7982 . as_ref ( )
8083 . ok_or_else ( || SQLiteError ( ResultCode :: MISUSE , Some ( String :: from ( "No tx_id" ) ) ) ) ?;
8184
85+ if self . state . is_in_sync_local . load ( Ordering :: Relaxed ) {
86+ // Don't collect CRUD writes while we're syncing the local database - writes made here
87+ // aren't writes we should upload.
88+ // This normally doesn't happen because we insert directly into the data tables, but
89+ // users might have custom raw tables used for sycing with triggers on them to call
90+ // this function. And those specifically should not trigger here.
91+ return Ok ( ( ) ) ;
92+ }
93+
8294 match & current_tx. mode {
8395 CrudTransactionMode :: Manual { stmt } => {
8496 // Columns are (data TEXT, options INT HIDDEN)
@@ -213,7 +225,7 @@ SELECT * FROM insertion WHERE (NOT (?3 & {})) OR data->>'op' != 'PATCH' OR data-
213225
214226extern "C" fn connect (
215227 db : * mut sqlite:: sqlite3 ,
216- _aux : * mut c_void ,
228+ aux : * mut c_void ,
217229 argc : c_int ,
218230 argv : * const * const c_char ,
219231 vtab : * mut * mut sqlite:: vtab ,
@@ -244,6 +256,14 @@ extern "C" fn connect(
244256 pModule : core:: ptr:: null ( ) ,
245257 zErrMsg : core:: ptr:: null_mut ( ) ,
246258 } ,
259+ state : {
260+ // Increase refcount - we can't use from_raw alone because we don't own the aux
261+ // data (connect could be called multiple times).
262+ let state = Arc :: from_raw ( aux as * mut DatabaseState ) ;
263+ let clone = state. clone ( ) ;
264+ core:: mem:: forget ( state) ;
265+ clone
266+ } ,
247267 db,
248268 current_tx : None ,
249269 is_simple,
@@ -335,20 +355,20 @@ static MODULE: sqlite_nostd::module = sqlite_nostd::module {
335355 xIntegrity : None ,
336356} ;
337357
338- pub fn register ( db : * mut sqlite:: sqlite3 ) -> Result < ( ) , ResultCode > {
358+ pub fn register ( db : * mut sqlite:: sqlite3 , state : Arc < DatabaseState > ) -> Result < ( ) , ResultCode > {
339359 sqlite:: convert_rc ( sqlite:: create_module_v2 (
340360 db,
341361 SIMPLE_NAME . as_ptr ( ) ,
342362 & MODULE ,
343- null_mut ( ) ,
344- None ,
363+ Arc :: into_raw ( state . clone ( ) ) as * mut c_void ,
364+ Some ( DatabaseState :: destroy_arc ) ,
345365 ) ) ?;
346366 sqlite:: convert_rc ( sqlite:: create_module_v2 (
347367 db,
348368 MANUAL_NAME . as_ptr ( ) ,
349369 & MODULE ,
350- null_mut ( ) ,
351- None ,
370+ Arc :: into_raw ( state ) as * mut c_void ,
371+ Some ( DatabaseState :: destroy_arc ) ,
352372 ) ) ?;
353373
354374 Ok ( ( ) )
0 commit comments