@@ -7,8 +7,7 @@ use std::{
77
88use crate :: {
99 proxy:: {
10- convert_params_to_json, execute_sql_and_params, get_execution_result,
11- get_transaction_baton, QueryResult ,
10+ convert_params_to_json, execute_sql_and_params, get_execution_result, get_transaction_baton,
1211 } ,
1312 utils:: TursoConfig ,
1413} ;
@@ -158,6 +157,15 @@ impl SQLite3PreparedStmt {
158157 }
159158}
160159
160+ pub type SQLite3ExecCallback = Option <
161+ unsafe extern "C" fn (
162+ arg : * mut c_void ,
163+ column_count : c_int ,
164+ column_values : * mut * mut c_char ,
165+ column_names : * mut * mut c_char ,
166+ ) -> c_int ,
167+ > ;
168+
161169pub fn get_latest_error ( db : & SQLite3 ) -> Option < ( String , c_int ) > {
162170 if let Ok ( stack) = db. error_stack . lock ( ) {
163171 stack. last ( ) . cloned ( )
@@ -196,30 +204,7 @@ pub fn push_error(db: *mut SQLite3, error: (String, c_int)) {
196204 }
197205}
198206
199- pub async unsafe fn execute_statement (
200- stmt : & mut SQLite3PreparedStmt ,
201- ) -> Result < c_int , Box < dyn Error > > {
202- match execute_stmt ( stmt) . await {
203- Ok ( _) => Ok ( SQLITE_OK ) ,
204- Err ( e) => {
205- push_error ( stmt. db , ( e. to_string ( ) , SQLITE_ERROR ) ) ;
206- Err ( e)
207- }
208- }
209- }
210-
211- pub async unsafe fn handle_select ( stmt : & mut SQLite3PreparedStmt ) -> Result < c_int , Box < dyn Error > > {
212- let needs_execution = {
213- let result_rows = stmt. result_rows . lock ( ) . map_err ( |_| "lock error" ) ?;
214- result_rows. is_empty ( )
215- } ;
216-
217- if needs_execution {
218- if let Err ( err) = execute_stmt_and_populate_result_rows ( stmt) . await {
219- return Err ( err) ;
220- }
221- }
222-
207+ pub fn iterate_rows ( stmt : & mut SQLite3PreparedStmt ) -> Result < c_int , Box < dyn Error > > {
223208 let result_rows = stmt. result_rows . lock ( ) . unwrap ( ) ;
224209 let mut current_row = stmt. current_row . lock ( ) . unwrap ( ) ;
225210
@@ -266,7 +251,7 @@ pub async unsafe fn handle_select(stmt: &mut SQLite3PreparedStmt) -> Result<c_in
266251 }
267252}
268253
269- pub async unsafe fn handle_execute ( db : * mut SQLite3 , sql : & str ) -> Result < c_int , Box < dyn Error > > {
254+ pub async fn handle_execute ( db : * mut SQLite3 , sql : & str ) -> Result < c_int , Box < dyn Error > > {
270255 if db. is_null ( ) {
271256 return Err ( "Database pointer is null" . into ( ) ) ;
272257 }
@@ -279,7 +264,7 @@ pub async unsafe fn handle_execute(db: *mut SQLite3, sql: &str) -> Result<c_int,
279264 }
280265}
281266
282- pub async fn begin_tnx_on_db ( db : * mut SQLite3 ) -> Result < c_int , Box < dyn Error > > {
267+ pub async fn begin_tnx_on_db ( db : * mut SQLite3 , sql : & str ) -> Result < c_int , Box < dyn Error > > {
283268 if db. is_null ( ) {
284269 return Err ( "Database pointer is null" . into ( ) ) ;
285270 }
@@ -297,14 +282,14 @@ pub async fn begin_tnx_on_db(db: *mut SQLite3) -> Result<c_int, Box<dyn Error>>
297282 return Err ( "Database is busy" . into ( ) ) ;
298283 }
299284
300- let baton_value = get_transaction_baton ( & db. client , & db. turso_config ) . await ?;
285+ let baton_value = get_transaction_baton ( & db. client , & db. turso_config , & sql ) . await ?;
301286 db. transaction_baton . lock ( ) . unwrap ( ) . replace ( baton_value) ;
302287 * db. transaction_has_began . lock ( ) . unwrap ( ) = true ;
303288
304289 Ok ( SQLITE_OK )
305290}
306291
307- pub async fn commit_tnx_on_db ( db : * mut SQLite3 ) -> Result < c_int , Box < dyn Error > > {
292+ pub async fn commit_tnx_on_db ( db : * mut SQLite3 , sql : & str ) -> Result < c_int , Box < dyn Error > > {
308293 if db. is_null ( ) {
309294 return Err ( "Database pointer is null" . into ( ) ) ;
310295 }
@@ -324,7 +309,7 @@ pub async fn commit_tnx_on_db(db: *mut SQLite3) -> Result<c_int, Box<dyn Error>>
324309
325310 let baton = db. transaction_baton . lock ( ) . unwrap ( ) . clone ( ) ;
326311
327- execute_sql_and_params ( db, "COMMIT" , vec ! [ ] , baton. as_ref ( ) ) . await ?;
312+ execute_sql_and_params ( db, & sql , vec ! [ ] , baton. as_ref ( ) ) . await ?;
328313
329314 db. transaction_baton . lock ( ) . unwrap ( ) . take ( ) ;
330315
@@ -333,50 +318,46 @@ pub async fn commit_tnx_on_db(db: *mut SQLite3) -> Result<c_int, Box<dyn Error>>
333318 Ok ( SQLITE_OK )
334319}
335320
336- async unsafe fn execute_stmt (
337- stmt : & mut SQLite3PreparedStmt ,
338- ) -> Result < QueryResult , Box < dyn Error > > {
339- let db: & SQLite3 = & * stmt. db ;
321+ pub async fn execute_stmt ( stmt : & mut SQLite3PreparedStmt ) -> Result < c_int , Box < dyn Error > > {
322+ let db: & SQLite3 = unsafe { & * stmt. db } ;
340323 let baton_str = {
341324 let baton = db. transaction_baton . lock ( ) . unwrap ( ) ;
342325 baton. as_ref ( ) . map ( |s| s. as_str ( ) ) . map ( |s| s. to_owned ( ) )
343326 } ;
344327
345328 let params = convert_params_to_json ( & stmt. params ) ;
346329 let response = execute_sql_and_params ( db, & stmt. sql , params, baton_str. as_ref ( ) ) . await ?;
330+ let response = get_execution_result ( db, & response) ?;
347331
348- let result = get_execution_result ( db , & response ) ? ;
332+ stmt . column_names = response . cols . iter ( ) . map ( |col| col . name . clone ( ) ) . collect ( ) ;
349333
350- Ok ( result. clone ( ) )
351- }
352-
353- async unsafe fn execute_stmt_and_populate_result_rows (
354- stmt : & mut SQLite3PreparedStmt ,
355- ) -> Result < c_int , Box < dyn Error > > {
356- let response = execute_stmt ( stmt) . await ?;
357334 let mut result_rows = stmt. result_rows . lock ( ) . unwrap ( ) ;
358-
359- let rows = response. rows ;
360- let columns = response. cols ;
361- stmt. column_names = columns. iter ( ) . map ( |col| col. name . clone ( ) ) . collect ( ) ;
362-
363- * result_rows = rows
335+ * result_rows = response
336+ . rows
364337 . iter ( )
365338 . map ( |row| {
366339 let result = row
367340 . iter ( )
368- . map ( |row| match row. r#type . as_str ( ) {
369- "integer" => match & row. value {
370- serde_json:: Value :: String ( s) => {
371- Value :: Integer ( s. parse :: < i64 > ( ) . unwrap_or ( 0 ) )
372- }
373- serde_json:: Value :: Number ( n) => Value :: Integer ( n. as_i64 ( ) . unwrap_or ( 0 ) ) ,
374- _ => Value :: Integer ( 0 ) ,
375- } ,
376- "float" => Value :: Real ( row. value . as_f64 ( ) . unwrap_or ( 0.0 ) ) ,
377- "text" => Value :: Text ( row. value . as_str ( ) . unwrap_or ( "" ) . to_string ( ) ) ,
378- "null" => Value :: Null ,
379- _ => Value :: Null ,
341+ . map ( |row| {
342+ if row. value . is_none ( ) {
343+ return Value :: Null ;
344+ }
345+
346+ let value = row. value . as_ref ( ) . unwrap ( ) ;
347+
348+ match row. r#type . as_str ( ) {
349+ "integer" => match & value {
350+ serde_json:: Value :: String ( s) => {
351+ Value :: Integer ( s. parse :: < i64 > ( ) . unwrap_or ( 0 ) )
352+ }
353+ serde_json:: Value :: Number ( n) => Value :: Integer ( n. as_i64 ( ) . unwrap_or ( 0 ) ) ,
354+ _ => Value :: Integer ( 0 ) ,
355+ } ,
356+ "float" => Value :: Real ( value. as_f64 ( ) . unwrap_or ( 0.0 ) ) ,
357+ "text" => Value :: Text ( value. as_str ( ) . unwrap_or ( "" ) . to_string ( ) ) ,
358+ "null" => Value :: Null ,
359+ _ => Value :: Null ,
360+ }
380361 } )
381362 . collect ( ) ;
382363
0 commit comments