66extern crate napi_derive;
77
88use napi:: bindgen_prelude:: { Array , FromNapiValue , JsFunction } ;
9- use napi:: { Env , JsObject , JsUnknown , Result , ValueType } ;
9+ use napi:: { Env , JsUnknown , Result , ValueType } ;
1010use once_cell:: sync:: OnceCell ;
1111use tracing_subscriber:: { EnvFilter , filter:: LevelFilter } ;
1212use std:: sync:: atomic:: { AtomicBool , Ordering } ;
@@ -349,7 +349,7 @@ pub fn database_prepare_sync(db: &Database, sql: String) -> Result<Statement> {
349349
350350#[ napi]
351351pub struct Statement {
352- stmt : Arc < std :: sync:: Mutex < libsql:: Statement > > ,
352+ stmt : Arc < tokio :: sync:: Mutex < libsql:: Statement > > ,
353353 conn : Arc < tokio:: sync:: Mutex < libsql:: Connection > > ,
354354 safe_ints : AtomicBool ,
355355 raw : AtomicBool ,
@@ -365,7 +365,7 @@ impl Statement {
365365 pluck : bool ,
366366 ) -> Self {
367367 Self {
368- stmt : Arc :: new ( std :: sync:: Mutex :: new ( stmt) ) ,
368+ stmt : Arc :: new ( tokio :: sync:: Mutex :: new ( stmt) ) ,
369369 conn,
370370 safe_ints : AtomicBool :: new ( safe_ints) ,
371371 raw : AtomicBool :: new ( raw) ,
@@ -521,39 +521,42 @@ fn map_value(value: JsUnknown) -> Result<libsql::Value> {
521521impl Statement {
522522 #[ napi]
523523 pub fn columns ( & self , env : Env ) -> Result < Array > {
524- let stmt = self . stmt . lock ( ) . unwrap ( ) ;
525- let columns = stmt. columns ( ) ;
526- let mut js_array = env. create_array ( columns. len ( ) as u32 ) ?;
527- for ( i, col) in columns. iter ( ) . enumerate ( ) {
528- let mut js_obj = env. create_object ( ) ?;
529- js_obj. set_named_property ( "name" , env. create_string ( col. name ( ) ) ?) ?;
530- // origin_name -> column
531- if let Some ( origin_name) = col. origin_name ( ) {
532- js_obj. set_named_property ( "column" , env. create_string ( origin_name) ?) ?;
533- } else {
534- js_obj. set_named_property ( "column" , env. get_null ( ) ?) ?;
535- }
536- // table_name -> table
537- if let Some ( table_name) = col. table_name ( ) {
538- js_obj. set_named_property ( "table" , env. create_string ( table_name) ?) ?;
539- } else {
540- js_obj. set_named_property ( "table" , env. get_null ( ) ?) ?;
541- }
542- // database_name -> database
543- if let Some ( database_name) = col. database_name ( ) {
544- js_obj. set_named_property ( "database" , env. create_string ( database_name) ?) ?;
545- } else {
546- js_obj. set_named_property ( "database" , env. get_null ( ) ?) ?;
547- }
548- // decl_type -> type
549- if let Some ( decl_type) = col. decl_type ( ) {
550- js_obj. set_named_property ( "type" , env. create_string ( decl_type) ?) ?;
551- } else {
552- js_obj. set_named_property ( "type" , env. get_null ( ) ?) ?;
524+ let rt = runtime ( ) ?;
525+ rt. block_on ( async move {
526+ let stmt = self . stmt . lock ( ) . await ;
527+ let columns = stmt. columns ( ) ;
528+ let mut js_array = env. create_array ( columns. len ( ) as u32 ) ?;
529+ for ( i, col) in columns. iter ( ) . enumerate ( ) {
530+ let mut js_obj = env. create_object ( ) ?;
531+ js_obj. set_named_property ( "name" , env. create_string ( col. name ( ) ) ?) ?;
532+ // origin_name -> column
533+ if let Some ( origin_name) = col. origin_name ( ) {
534+ js_obj. set_named_property ( "column" , env. create_string ( origin_name) ?) ?;
535+ } else {
536+ js_obj. set_named_property ( "column" , env. get_null ( ) ?) ?;
537+ }
538+ // table_name -> table
539+ if let Some ( table_name) = col. table_name ( ) {
540+ js_obj. set_named_property ( "table" , env. create_string ( table_name) ?) ?;
541+ } else {
542+ js_obj. set_named_property ( "table" , env. get_null ( ) ?) ?;
543+ }
544+ // database_name -> database
545+ if let Some ( database_name) = col. database_name ( ) {
546+ js_obj. set_named_property ( "database" , env. create_string ( database_name) ?) ?;
547+ } else {
548+ js_obj. set_named_property ( "database" , env. get_null ( ) ?) ?;
549+ }
550+ // decl_type -> type
551+ if let Some ( decl_type) = col. decl_type ( ) {
552+ js_obj. set_named_property ( "type" , env. create_string ( decl_type) ?) ?;
553+ } else {
554+ js_obj. set_named_property ( "type" , env. get_null ( ) ?) ?;
555+ }
556+ js_array. set ( i as u32 , js_obj) ?;
553557 }
554- js_array. set ( i as u32 , js_obj) ?;
555- }
556- Ok ( js_array)
558+ Ok ( js_array)
559+ } )
557560 }
558561
559562 #[ napi]
@@ -562,19 +565,31 @@ impl Statement {
562565 let safe_ints = self . safe_ints . load ( Ordering :: SeqCst ) ;
563566 let raw = self . raw . load ( Ordering :: SeqCst ) ;
564567 let pluck = self . pluck . load ( Ordering :: SeqCst ) ;
568+ let params = {
569+ let stmt = self . stmt . clone ( ) ;
570+ rt. block_on ( async move {
571+ let mut stmt = stmt. lock ( ) . await ;
572+ stmt. reset ( ) ;
573+ let params = if let Some ( params) = params {
574+ map_params ( & stmt, Some ( params) ) . unwrap ( )
575+ } else {
576+ libsql:: params:: Params :: None
577+ } ;
578+ params
579+ } )
580+ } ;
565581 let stmt = self . stmt . clone ( ) ;
566- // Lock statement and run query synchronously
567- let rows = rt. block_on ( async {
568- let mut stmt = stmt. lock ( ) . unwrap ( ) ;
569- stmt. reset ( ) ;
570- let params = if let Some ( params) = params {
571- map_params ( & stmt, Some ( params) ) . unwrap ( )
572- } else {
573- libsql:: params:: Params :: None
574- } ;
575- stmt. query ( params) . await . map_err ( Error :: from)
576- } ) ?;
577- RowsIterator :: new ( env, Arc :: new ( tokio:: sync:: Mutex :: new ( rows) ) , safe_ints, raw, pluck)
582+ let future = async move {
583+ let rows = stmt. lock ( ) . await . query ( params) . await . map_err ( Error :: from) ?;
584+ Ok :: < _ , napi:: Error > ( rows)
585+ } ;
586+ env. execute_tokio_future (
587+ future,
588+ move |& mut env, result| {
589+ let iter = RowsIterator :: new ( env, Arc :: new ( tokio:: sync:: Mutex :: new ( result) ) , safe_ints, raw, pluck) ?;
590+ Ok ( iter)
591+ } ,
592+ )
578593 }
579594
580595 #[ napi]
@@ -586,7 +601,7 @@ impl Statement {
586601 // Get start time
587602 let start = std:: time:: Instant :: now ( ) ;
588603
589- let mut stmt = self . stmt . lock ( ) . unwrap ( ) ;
604+ let mut stmt = self . stmt . lock ( ) . await ;
590605 stmt. reset ( ) ;
591606 let params = if let Some ( params) = params {
592607 map_params ( & stmt, Some ( params) ) ?
@@ -621,7 +636,7 @@ impl Statement {
621636 pub fn raw ( & self , raw : Option < bool > ) -> Result < & Self > {
622637 let rt = runtime ( ) ?;
623638 let returns_data = rt. block_on ( async move {
624- let stmt = self . stmt . lock ( ) . unwrap ( ) ;
639+ let stmt = self . stmt . lock ( ) . await ;
625640 !stmt. columns ( ) . is_empty ( )
626641 } ) ;
627642 if !returns_data {
@@ -643,7 +658,7 @@ impl Statement {
643658
644659 let start = std:: time:: Instant :: now ( ) ;
645660 rt. block_on ( async move {
646- let mut stmt = self . stmt . lock ( ) . unwrap ( ) ;
661+ let mut stmt = self . stmt . lock ( ) . await ;
647662 stmt. reset ( ) ;
648663 let params = if let Some ( params) = params {
649664 map_params ( & stmt, Some ( params) ) ?
0 commit comments