Skip to content

Commit 92a40fb

Browse files
cursoragentlovasoa
andcommitted
Refactor: Improve ODBC execute and prepare logic
Co-authored-by: contact <[email protected]>
1 parent ba23ae7 commit 92a40fb

File tree

1 file changed

+71
-11
lines changed

1 file changed

+71
-11
lines changed

sqlx-core/src/odbc/connection/worker.rs

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use crate::odbc::{
1111
#[allow(unused_imports)]
1212
use crate::row::Row as SqlxRow;
1313
use either::Either;
14+
#[allow(unused_imports)]
15+
use odbc_api::handles::Statement as OdbcStatementTrait;
1416
use odbc_api::{Cursor, CursorRow, IntoParameter, ResultSetMetadata};
1517

1618
// Type aliases for commonly used types
@@ -338,9 +340,9 @@ fn execute_sql(conn: &OdbcConnection, sql: &str, args: Option<OdbcArguments>, tx
338340
let params = prepare_parameters(args);
339341

340342
if params.is_empty() {
341-
dispatch_execute(conn, sql, (), tx);
343+
dispatch_execute_direct(conn, sql, tx);
342344
} else {
343-
dispatch_execute(conn, sql, &params[..], tx);
345+
dispatch_execute_prepared(conn, sql, &params[..], tx);
344346
}
345347
}
346348

@@ -362,14 +364,68 @@ fn to_param(arg: OdbcArgumentValue) -> Box<dyn odbc_api::parameter::InputParamet
362364
}
363365

364366
// Dispatch functions
365-
fn dispatch_execute<P>(conn: &OdbcConnection, sql: &str, params: P, tx: &ExecuteSender)
367+
fn dispatch_execute_direct(conn: &OdbcConnection, sql: &str, tx: &ExecuteSender) {
368+
match conn.preallocate() {
369+
Ok(mut stmt) => {
370+
let mut sent = false;
371+
{
372+
let res = stmt.execute(sql, ());
373+
match res {
374+
Ok(Some(mut cursor)) => {
375+
handle_cursor(&mut cursor, tx);
376+
sent = true;
377+
}
378+
Ok(None) => {
379+
// drop res and then read row_count below
380+
}
381+
Err(e) => {
382+
let _ = send_error(tx, Error::from(e));
383+
sent = true;
384+
}
385+
}
386+
}
387+
if !sent {
388+
let rc = stmt.row_count().ok().flatten().unwrap_or(0) as u64;
389+
let _ = send_done(tx, rc);
390+
}
391+
}
392+
Err(e) => {
393+
let _ = send_error(tx, Error::from(e));
394+
}
395+
}
396+
}
397+
398+
fn dispatch_execute_prepared<P>(conn: &OdbcConnection, sql: &str, params: P, tx: &ExecuteSender)
366399
where
367400
P: odbc_api::ParameterCollectionRef,
368401
{
369-
match conn.execute(sql, params, None) {
370-
Ok(Some(mut cursor)) => handle_cursor(&mut cursor, tx),
371-
Ok(None) => send_empty_result(tx).unwrap_or_default(),
372-
Err(e) => send_error(tx, Error::from(e)).unwrap_or_default(),
402+
match conn.prepare(sql) {
403+
Ok(mut prepared) => {
404+
let mut sent = false;
405+
{
406+
let res = prepared.execute(params);
407+
match res {
408+
Ok(Some(mut cursor)) => {
409+
handle_cursor(&mut cursor, tx);
410+
sent = true;
411+
}
412+
Ok(None) => {
413+
// drop res and then read row_count below
414+
}
415+
Err(e) => {
416+
let _ = send_error(tx, Error::from(e));
417+
sent = true;
418+
}
419+
}
420+
}
421+
if !sent {
422+
let rc = prepared.row_count().ok().flatten().unwrap_or(0) as u64;
423+
let _ = send_done(tx, rc);
424+
}
425+
}
426+
Err(e) => {
427+
let _ = send_error(tx, Error::from(e));
428+
}
373429
}
374430
}
375431

@@ -380,14 +436,18 @@ where
380436
let columns = collect_columns(cursor);
381437

382438
match stream_rows(cursor, &columns, tx) {
383-
Ok(true) => send_empty_result(tx).unwrap_or_default(),
439+
Ok(true) => {
440+
let _ = send_done(tx, 0);
441+
}
384442
Ok(false) => {}
385-
Err(e) => send_error(tx, e).unwrap_or_default(),
443+
Err(e) => {
444+
let _ = send_error(tx, e);
445+
}
386446
}
387447
}
388448

389-
fn send_empty_result(tx: &ExecuteSender) -> Result<(), SendError<ExecuteResult>> {
390-
send_stream_result(tx, Ok(Either::Left(OdbcQueryResult { rows_affected: 0 })))
449+
fn send_done(tx: &ExecuteSender, rows_affected: u64) -> Result<(), SendError<ExecuteResult>> {
450+
send_stream_result(tx, Ok(Either::Left(OdbcQueryResult { rows_affected })))
391451
}
392452

393453
fn send_error(tx: &ExecuteSender, error: Error) -> Result<(), SendError<ExecuteResult>> {

0 commit comments

Comments
 (0)