feat(repositories): add insert_many method generation
This commit is contained in:
parent
09791951d9
commit
3b134cdb6c
1 changed files with 53 additions and 0 deletions
|
@ -80,6 +80,56 @@ fn gen_insert_method(model: &Model) -> TokenStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gen_insert_many_method(model: &Model) -> TokenStream {
|
||||||
|
let resource_ident = format_ident!("{}", &model.name);
|
||||||
|
let error_msg = format!("Failed to insert many entities of resource {:?}", model.name.clone());
|
||||||
|
let sql_columns = model.fields.iter()
|
||||||
|
.map(|f| f.name.clone())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(", ");
|
||||||
|
let base_insert_query = format!(
|
||||||
|
"INSERT INTO {} ({}) VALUES {{}} ON CONFLICT DO NOTHING",
|
||||||
|
model.table_name,
|
||||||
|
sql_columns
|
||||||
|
);
|
||||||
|
let field_names: Vec<proc_macro2::Ident> = model.fields.iter()
|
||||||
|
.map(|f| format_ident!("{}", &f.name))
|
||||||
|
.collect();
|
||||||
|
let fields_count: usize = model.fields.len();
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
pub async fn insert_many(&self, entities: &Vec<#resource_ident>) -> Result<()> {
|
||||||
|
let values_templates: String = (1..(#fields_count*entities.len()+1))
|
||||||
|
.collect::<Vec<usize>>()
|
||||||
|
.chunks(#fields_count)
|
||||||
|
.map(|c| c.to_vec())
|
||||||
|
.map(|x| format!(
|
||||||
|
"({})",
|
||||||
|
x.iter()
|
||||||
|
.map(|i| format!("${}", i))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(", ")
|
||||||
|
))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(", ");
|
||||||
|
let query_sql = format!(#base_insert_query, values_templates);
|
||||||
|
|
||||||
|
let mut query = sqlx::query(&query_sql);
|
||||||
|
for entity in entities {
|
||||||
|
query = query
|
||||||
|
#( .bind( &entity.#field_names ) )*;
|
||||||
|
}
|
||||||
|
query
|
||||||
|
.execute(&self.db.0)
|
||||||
|
.await
|
||||||
|
.context(#error_msg)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn generate_repository_file(model: &Model) -> Result<SourceNodeContainer> {
|
fn generate_repository_file(model: &Model) -> Result<SourceNodeContainer> {
|
||||||
let resource_name = model.name.clone();
|
let resource_name = model.name.clone();
|
||||||
|
|
||||||
|
@ -91,6 +141,7 @@ fn generate_repository_file(model: &Model) -> Result<SourceNodeContainer> {
|
||||||
let get_all_method_code = gen_get_all_method(&model);
|
let get_all_method_code = gen_get_all_method(&model);
|
||||||
let get_by_id_method_code = gen_get_by_id_method(&model);
|
let get_by_id_method_code = gen_get_by_id_method(&model);
|
||||||
let insert_method_code = gen_insert_method(&model);
|
let insert_method_code = gen_insert_method(&model);
|
||||||
|
let insert_many_method_code = gen_insert_many_method(&model);
|
||||||
|
|
||||||
// TODO: add import line
|
// TODO: add import line
|
||||||
|
|
||||||
|
@ -115,6 +166,8 @@ fn generate_repository_file(model: &Model) -> Result<SourceNodeContainer> {
|
||||||
#get_by_id_method_code
|
#get_by_id_method_code
|
||||||
|
|
||||||
#insert_method_code
|
#insert_method_code
|
||||||
|
|
||||||
|
#insert_many_method_code
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// convert TokenStream into rust code as string
|
// convert TokenStream into rust code as string
|
||||||
|
|
Loading…
Reference in a new issue