11use core:: {
2- cell:: Cell ,
32 ffi:: { CStr , c_char, c_int, c_void} ,
43 ptr:: null_mut,
54} ;
@@ -21,11 +20,7 @@ use crate::{constants::SUBTYPE_JSON, error::PowerSyncError, state::DatabaseState
2120/// The update hooks don't have to be uninstalled manually, that happens when the connection is
2221/// closed and the function is unregistered.
2322pub fn register ( db : * mut sqlite:: sqlite3 , state : Rc < DatabaseState > ) -> Result < ( ) , ResultCode > {
24- let state = Box :: new ( HookState {
25- has_registered_hooks : Cell :: new ( false ) ,
26- db,
27- state,
28- } ) ;
23+ let state = Box :: new ( HookState { db, state } ) ;
2924
3025 db. create_function_v2 (
3126 "powersync_update_hooks" ,
@@ -41,31 +36,13 @@ pub fn register(db: *mut sqlite::sqlite3, state: Rc<DatabaseState>) -> Result<()
4136}
4237
4338struct HookState {
44- has_registered_hooks : Cell < bool > ,
4539 db : * mut sqlite:: sqlite3 ,
4640 state : Rc < DatabaseState > ,
4741}
4842
4943extern "C" fn destroy_function ( ctx : * mut c_void ) {
5044 let state = unsafe { Box :: from_raw ( ctx as * mut HookState ) } ;
51-
52- if state. has_registered_hooks . get ( ) {
53- check_previous (
54- "update" ,
55- & state. state ,
56- state. db . update_hook ( None , null_mut ( ) ) ,
57- ) ;
58- check_previous (
59- "commit" ,
60- & state. state ,
61- state. db . commit_hook ( None , null_mut ( ) ) ,
62- ) ;
63- check_previous (
64- "rollback" ,
65- & state. state ,
66- state. db . rollback_hook ( None , null_mut ( ) ) ,
67- ) ;
68- }
45+ uninstall_update_hooks ( state. db , & state. state ) ;
6946}
7047
7148extern "C" fn powersync_update_hooks (
@@ -107,7 +84,7 @@ extern "C" fn powersync_update_hooks(
10784 Rc :: into_raw ( db_state. clone ( ) ) as * mut c_void ,
10885 ) ,
10986 ) ;
110- state . has_registered_hooks . set ( true ) ;
87+ db_state . core_extension_has_update_hooks . set ( true ) ;
11188 }
11289 "get" => {
11390 let state = unsafe { user_data. as_ref ( ) . unwrap_unchecked ( ) } ;
@@ -155,6 +132,14 @@ unsafe extern "C" fn rollback_hook_impl(ctx: *mut c_void) {
155132 state. track_rollback ( ) ;
156133}
157134
135+ pub fn uninstall_update_hooks ( db : * mut sqlite:: sqlite3 , state : & Rc < DatabaseState > ) {
136+ if state. core_extension_has_update_hooks . take ( ) {
137+ check_previous ( "update" , state, db. update_hook ( None , null_mut ( ) ) ) ;
138+ check_previous ( "commit" , state, db. commit_hook ( None , null_mut ( ) ) ) ;
139+ check_previous ( "rollback" , state, db. rollback_hook ( None , null_mut ( ) ) ) ;
140+ }
141+ }
142+
158143fn check_previous ( desc : & ' static str , expected : & Rc < DatabaseState > , previous : * const c_void ) {
159144 let expected = Rc :: as_ptr ( expected) ;
160145
0 commit comments