Skip to content

Commit

Permalink
feat: batch_insertを実装する
Browse files Browse the repository at this point in the history
  • Loading branch information
rito528 committed Oct 20, 2023
1 parent 1b7ef5e commit 9351f14
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 11 deletions.
32 changes: 32 additions & 0 deletions server/infra/resource/src/database/connection.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use async_trait::async_trait;
use itertools::Itertools;
use migration::MigratorTrait;
use regex::Regex;
use sea_orm::{
ConnectionTrait, Database, DatabaseBackend, DatabaseConnection, DatabaseTransaction, DbErr,
ExecResult, QueryResult, Statement, TransactionTrait, Value,
Expand Down Expand Up @@ -82,6 +84,36 @@ impl ConnectionPool {
))
.await
}

pub async fn batch_insert<I>(&self, sql: &str, params: I) -> Result<ExecResult, DbErr>
where
I: IntoIterator<Item = Value>,
{
let regex = Regex::new(r"\((\?,\s*)+\?\)").unwrap();
let insert_part_opt = regex.find(sql);

assert!(
insert_part_opt.is_some(),
"SQL insert params must be exists."
);

let insert_part = insert_part_opt.unwrap().as_str();

let params_vec = params.into_iter().collect::<Vec<_>>();

self.pool
.execute(Statement::from_sql_and_values(
DatabaseBackend::MySql,
sql.replace(
insert_part,
&vec![insert_part; params_vec.len() / insert_part.matches('?').count()]
.iter()
.join(", "),
),
params_vec,
))
.await
}
}

#[async_trait]
Expand Down
15 changes: 4 additions & 11 deletions server/infra/resource/src/database/form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ impl FormDatabase for ConnectionPool {
let params = answer
.answers
.into_iter()
.map(|answer| {
.flat_map(|answer| {
vec![
id.to_string(),
answer.question_id.to_string(),
Expand All @@ -421,16 +421,9 @@ impl FormDatabase for ConnectionPool {
})
.collect_vec();

self.execute_and_values(
&format!(
"INSERT INTO real_answers (answer_id, question_id, answer) VALUES {}",
vec!["(?, ?, ?)"; params.len()].iter().join(", ")
),
params
.iter()
.flatten()
.map(|value| value.into())
.collect_vec(),
self.batch_insert(
"INSERT INTO real_answers (answer_id, question_id, answer) VALUES (?, ?, ?)",
params.iter().map(|value| value.into()),
)
.await?;

Expand Down

0 comments on commit 9351f14

Please sign in to comment.