Skip to content

Commit ba63201

Browse files
committed
refactor execute_many for better performance
1 parent 8ed0724 commit ba63201

File tree

1 file changed

+52
-32
lines changed

1 file changed

+52
-32
lines changed

src/connection/impls.rs

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -409,42 +409,62 @@ impl PSQLPyConnection {
409409
parameters: Option<Vec<pyo3::Py<PyAny>>>,
410410
prepared: Option<bool>,
411411
) -> PSQLPyResult<()> {
412-
let mut statements: Vec<PsqlpyStatement> = vec![];
413-
if let Some(parameters) = parameters {
414-
for vec_of_py_any in parameters {
415-
// TODO: Fix multiple qs creation
416-
let statement =
417-
StatementBuilder::new(&querystring, &Some(vec_of_py_any), self, prepared)
418-
.build()
419-
.await?;
420-
421-
statements.push(statement);
422-
}
423-
}
412+
let Some(parameters) = parameters else {
413+
return Ok(());
414+
};
424415

425416
let prepared = prepared.unwrap_or(true);
426417

427-
for statement in statements {
428-
let querystring_result = if prepared {
429-
let prepared_stmt = &self.prepare(statement.raw_query(), true).await;
430-
if let Err(error) = prepared_stmt {
431-
return Err(RustPSQLDriverError::ConnectionExecuteError(format!(
432-
"Cannot prepare statement in execute_many, operation rolled back {error}",
433-
)));
434-
}
435-
self.query(
436-
&self.prepare(statement.raw_query(), true).await?,
437-
&statement.params(),
438-
)
439-
.await
440-
} else {
441-
self.query(statement.raw_query(), &statement.params()).await
442-
};
418+
let mut statements: Vec<PsqlpyStatement> = Vec::with_capacity(parameters.len());
419+
420+
for param_set in parameters {
421+
let statement =
422+
StatementBuilder::new(&querystring, &Some(param_set), self, Some(prepared))
423+
.build()
424+
.await
425+
.map_err(|err| {
426+
RustPSQLDriverError::ConnectionExecuteError(format!(
427+
"Cannot build statement in execute_many: {err}"
428+
))
429+
})?;
430+
statements.push(statement);
431+
}
432+
433+
if statements.is_empty() {
434+
return Ok(());
435+
}
443436

444-
if let Err(error) = querystring_result {
445-
return Err(RustPSQLDriverError::ConnectionExecuteError(format!(
446-
"Error occured in `execute_many` statement: {error}"
447-
)));
437+
if prepared {
438+
let first_statement = &statements[0];
439+
let prepared_stmt = self
440+
.prepare(first_statement.raw_query(), true)
441+
.await
442+
.map_err(|err| {
443+
RustPSQLDriverError::ConnectionExecuteError(format!(
444+
"Cannot prepare statement in execute_many: {err}"
445+
))
446+
})?;
447+
448+
// Execute all statements using the same prepared statement
449+
for statement in statements {
450+
self.query(&prepared_stmt, &statement.params())
451+
.await
452+
.map_err(|err| {
453+
RustPSQLDriverError::ConnectionExecuteError(format!(
454+
"Error occurred in `execute_many` statement: {err}"
455+
))
456+
})?;
457+
}
458+
} else {
459+
// Execute each statement without preparation
460+
for statement in statements {
461+
self.query(statement.raw_query(), &statement.params())
462+
.await
463+
.map_err(|err| {
464+
RustPSQLDriverError::ConnectionExecuteError(format!(
465+
"Error occurred in `execute_many` statement: {err}"
466+
))
467+
})?;
448468
}
449469
}
450470

0 commit comments

Comments
 (0)