1- use std:: ffi:: { c_char , CStr , CString } ;
1+ use std:: ffi:: { CStr , CString , c_char } ;
22use std:: ptr;
33use std:: sync:: { Arc , Mutex } ;
44
55use async_trait:: async_trait;
66use libsqlite3_sys:: {
7- sqlite3 , sqlite3_bind_blob , sqlite3_bind_double , sqlite3_bind_int64 , sqlite3_bind_null ,
8- sqlite3_bind_text , sqlite3_changes , sqlite3_column_blob , sqlite3_column_bytes ,
9- sqlite3_column_count , sqlite3_column_double , sqlite3_column_int64 , sqlite3_column_name ,
10- sqlite3_column_text , sqlite3_column_type , sqlite3_errmsg , sqlite3_finalize ,
11- sqlite3_prepare_v2 , sqlite3_step , SQLITE_BLOB , SQLITE_DONE , SQLITE_FLOAT , SQLITE_INTEGER ,
12- SQLITE_NULL , SQLITE_OK , SQLITE_ROW , SQLITE_TEXT , SQLITE_TRANSIENT ,
7+ SQLITE_BLOB , SQLITE_DONE , SQLITE_FLOAT , SQLITE_INTEGER , SQLITE_NULL , SQLITE_OK , SQLITE_ROW ,
8+ SQLITE_TEXT , SQLITE_TRANSIENT , sqlite3 , sqlite3_bind_blob , sqlite3_bind_double ,
9+ sqlite3_bind_int64 , sqlite3_bind_null , sqlite3_bind_text , sqlite3_changes , sqlite3_column_blob ,
10+ sqlite3_column_bytes , sqlite3_column_count , sqlite3_column_double , sqlite3_column_int64 ,
11+ sqlite3_column_name , sqlite3_column_text , sqlite3_column_type , sqlite3_errmsg ,
12+ sqlite3_finalize , sqlite3_prepare_v2 , sqlite3_step ,
1313} ;
1414use napi:: bindgen_prelude:: Buffer ;
1515use napi_derive:: napi;
@@ -34,6 +34,10 @@ impl EnvoyKv {
3434
3535#[ async_trait]
3636impl SqliteKv for EnvoyKv {
37+ fn on_error ( & self , actor_id : & str , error : & SqliteKvError ) {
38+ tracing:: error!( %actor_id, %error, "native sqlite kv operation failed" ) ;
39+ }
40+
3741 async fn on_open ( & self , _actor_id : & str ) -> Result < ( ) , SqliteKvError > {
3842 Ok ( ( ) )
3943 }
@@ -109,13 +113,19 @@ pub struct JsNativeDatabase {
109113
110114impl JsNativeDatabase {
111115 pub fn as_ptr ( & self ) -> * mut libsqlite3_sys:: sqlite3 {
112- self
113- . db
116+ self . db
114117 . lock ( )
115118 . ok ( )
116119 . and_then ( |guard| guard. as_ref ( ) . map ( NativeDatabase :: as_ptr) )
117120 . unwrap_or ( ptr:: null_mut ( ) )
118121 }
122+
123+ fn take_last_kv_error_inner ( & self ) -> Option < String > {
124+ self . db
125+ . lock ( )
126+ . ok ( )
127+ . and_then ( |guard| guard. as_ref ( ) . and_then ( NativeDatabase :: take_last_kv_error) )
128+ }
119129}
120130
121131#[ napi( object) ]
@@ -140,6 +150,11 @@ pub struct QueryResult {
140150
141151#[ napi]
142152impl JsNativeDatabase {
153+ #[ napi]
154+ pub fn take_last_kv_error ( & self ) -> Option < String > {
155+ self . take_last_kv_error_inner ( )
156+ }
157+
143158 #[ napi]
144159 pub async fn run (
145160 & self ,
@@ -243,13 +258,7 @@ fn bind_params(
243258 let text = CString :: new ( param. text_value . clone ( ) . unwrap_or_default ( ) )
244259 . map_err ( |err| napi:: Error :: from_reason ( err. to_string ( ) ) ) ?;
245260 unsafe {
246- sqlite3_bind_text (
247- stmt,
248- bind_index,
249- text. as_ptr ( ) ,
250- -1 ,
251- SQLITE_TRANSIENT ( ) ,
252- )
261+ sqlite3_bind_text ( stmt, bind_index, text. as_ptr ( ) , -1 , SQLITE_TRANSIENT ( ) )
253262 }
254263 }
255264 "blob" => {
@@ -291,26 +300,17 @@ fn collect_columns(stmt: *mut libsqlite3_sys::sqlite3_stmt) -> Vec<String> {
291300 if name_ptr. is_null ( ) {
292301 String :: new ( )
293302 } else {
294- CStr :: from_ptr ( name_ptr)
295- . to_string_lossy ( )
296- . into_owned ( )
303+ CStr :: from_ptr ( name_ptr) . to_string_lossy ( ) . into_owned ( )
297304 }
298305 } )
299306 . collect ( )
300307}
301308
302- fn column_value (
303- stmt : * mut libsqlite3_sys:: sqlite3_stmt ,
304- index : i32 ,
305- ) -> serde_json:: Value {
309+ fn column_value ( stmt : * mut libsqlite3_sys:: sqlite3_stmt , index : i32 ) -> serde_json:: Value {
306310 match unsafe { sqlite3_column_type ( stmt, index) } {
307311 SQLITE_NULL => serde_json:: Value :: Null ,
308- SQLITE_INTEGER => {
309- serde_json:: Value :: from ( unsafe { sqlite3_column_int64 ( stmt, index) } )
310- }
311- SQLITE_FLOAT => {
312- serde_json:: Value :: from ( unsafe { sqlite3_column_double ( stmt, index) } )
313- }
312+ SQLITE_INTEGER => serde_json:: Value :: from ( unsafe { sqlite3_column_int64 ( stmt, index) } ) ,
313+ SQLITE_FLOAT => serde_json:: Value :: from ( unsafe { sqlite3_column_double ( stmt, index) } ) ,
314314 SQLITE_TEXT => {
315315 let text_ptr = unsafe { sqlite3_column_text ( stmt, index) } ;
316316 if text_ptr. is_null ( ) {
@@ -328,9 +328,7 @@ fn column_value(
328328 serde_json:: Value :: Null
329329 } else {
330330 let blob_len = unsafe { sqlite3_column_bytes ( stmt, index) } as usize ;
331- let blob = unsafe {
332- std:: slice:: from_raw_parts ( blob_ptr as * const u8 , blob_len)
333- } ;
331+ let blob = unsafe { std:: slice:: from_raw_parts ( blob_ptr as * const u8 , blob_len) } ;
334332 serde_json:: Value :: Array (
335333 blob. iter ( )
336334 . map ( |byte| serde_json:: Value :: from ( * byte) )
@@ -349,9 +347,7 @@ fn execute_statement(
349347) -> napi:: Result < ExecuteResult > {
350348 let c_sql = CString :: new ( sql) . map_err ( |err| napi:: Error :: from_reason ( err. to_string ( ) ) ) ?;
351349 let mut stmt = ptr:: null_mut ( ) ;
352- let rc = unsafe {
353- sqlite3_prepare_v2 ( db, c_sql. as_ptr ( ) , -1 , & mut stmt, ptr:: null_mut ( ) )
354- } ;
350+ let rc = unsafe { sqlite3_prepare_v2 ( db, c_sql. as_ptr ( ) , -1 , & mut stmt, ptr:: null_mut ( ) ) } ;
355351 if rc != SQLITE_OK {
356352 return Err ( sqlite_error ( db, "failed to prepare sqlite statement" ) ) ;
357353 }
@@ -393,9 +389,7 @@ fn query_statement(
393389) -> napi:: Result < QueryResult > {
394390 let c_sql = CString :: new ( sql) . map_err ( |err| napi:: Error :: from_reason ( err. to_string ( ) ) ) ?;
395391 let mut stmt = ptr:: null_mut ( ) ;
396- let rc = unsafe {
397- sqlite3_prepare_v2 ( db, c_sql. as_ptr ( ) , -1 , & mut stmt, ptr:: null_mut ( ) )
398- } ;
392+ let rc = unsafe { sqlite3_prepare_v2 ( db, c_sql. as_ptr ( ) , -1 , & mut stmt, ptr:: null_mut ( ) ) } ;
399393 if rc != SQLITE_OK {
400394 return Err ( sqlite_error ( db, "failed to prepare sqlite query" ) ) ;
401395 }
0 commit comments