@@ -2,8 +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} ;
8+ use core:: sync:: atomic:: Ordering ;
79
810use sqlite:: { Connection , ResultCode , Value } ;
911use sqlite_nostd as sqlite;
@@ -13,6 +15,7 @@ use sqlite_nostd::ResultCode::NULL;
1315use crate :: error:: SQLiteError ;
1416use crate :: ext:: SafeManagedStmt ;
1517use crate :: schema:: TableInfoFlags ;
18+ use crate :: state:: DatabaseState ;
1619use crate :: vtab_util:: * ;
1720
1821// Structure:
@@ -31,11 +34,12 @@ struct VirtualTable {
3134 db : * mut sqlite:: sqlite3 ,
3235 current_tx : Option < i64 > ,
3336 insert_statement : Option < ManagedStmt > ,
37+ state : Arc < DatabaseState > ,
3438}
3539
3640extern "C" fn connect (
3741 db : * mut sqlite:: sqlite3 ,
38- _aux : * mut c_void ,
42+ aux : * mut c_void ,
3943 _argc : c_int ,
4044 _argv : * const * const c_char ,
4145 vtab : * mut * mut sqlite:: vtab ,
@@ -58,6 +62,14 @@ extern "C" fn connect(
5862 db,
5963 current_tx : None ,
6064 insert_statement : None ,
65+ state : {
66+ // Increase refcount - we can't use from_raw alone because we don't own the aux
67+ // data (connect could be called multiple times).
68+ let state = Arc :: from_raw ( aux as * mut DatabaseState ) ;
69+ let clone = state. clone ( ) ;
70+ core:: mem:: forget ( state) ;
71+ clone
72+ } ,
6173 } ) ) ;
6274 * vtab = tab. cast :: < sqlite:: vtab > ( ) ;
6375 let _ = sqlite:: vtab_config ( db, 0 ) ;
@@ -127,13 +139,20 @@ fn insert_operation(
127139 flags : TableInfoFlags ,
128140) -> Result < ( ) , SQLiteError > {
129141 let tab = unsafe { & mut * ( vtab. cast :: < VirtualTable > ( ) ) } ;
130- if tab. current_tx . is_none ( ) {
142+ if tab. state . is_in_sync_local . load ( Ordering :: Relaxed ) {
131143 return Err ( SQLiteError (
132144 ResultCode :: MISUSE ,
133- Some ( String :: from ( "No tx_id " ) ) ,
145+ Some ( String :: from ( "Using ps_crud during sync operation " ) ) ,
134146 ) ) ;
135147 }
136- let current_tx = tab. current_tx . unwrap ( ) ;
148+
149+ let Some ( current_tx) = tab. current_tx else {
150+ return Err ( SQLiteError (
151+ ResultCode :: MISUSE ,
152+ Some ( String :: from ( "No tx_id" ) ) ,
153+ ) ) ;
154+ } ;
155+
137156 // language=SQLite
138157 let statement = tab
139158 . insert_statement
@@ -206,8 +225,13 @@ static MODULE: sqlite_nostd::module = sqlite_nostd::module {
206225 xIntegrity : None ,
207226} ;
208227
209- pub fn register ( db : * mut sqlite:: sqlite3 ) -> Result < ( ) , ResultCode > {
210- db. create_module_v2 ( "powersync_crud_" , & MODULE , None , None ) ?;
228+ pub fn register ( db : * mut sqlite:: sqlite3 , state : Arc < DatabaseState > ) -> Result < ( ) , ResultCode > {
229+ db. create_module_v2 (
230+ "powersync_crud_" ,
231+ & MODULE ,
232+ Some ( Arc :: into_raw ( state) as * mut c_void ) ,
233+ Some ( DatabaseState :: destroy_arc) ,
234+ ) ?;
211235
212236 Ok ( ( ) )
213237}
0 commit comments