use proc_macro2::TokenStream;
use quote::quote;
use super::context::Context;
use crate::{entity::parse::SqlLevel, utils::tracing::instrument};
impl Context<'_> {
pub fn save_method(&self) -> TokenStream {
if self.entity.sql != SqlLevel::Full {
return TokenStream::new();
}
if !self.entity.is_aggregate_root() {
return TokenStream::new();
}
let entity_name = self.entity_name;
let new_name = self.entity.ident_with("New", "");
let row_name = &self.row_name;
let insertable_name = &self.insertable_name;
let table = &self.table;
let columns_str = &self.columns_str;
let placeholders_str = &self.placeholders_str;
let bindings = super::helpers::insert_bindings(self.entity.all_fields());
let error_type = self.entity.error_type();
let span = instrument(&entity_name.to_string(), "save");
quote! {
#span
async fn save(&self, new: #new_name) -> Result<#entity_name, #error_type> {
let mut tx = self.begin().await?;
let mut entity: #entity_name = new.into();
let insertable = #insertable_name::from(&entity);
let row: #row_name = sqlx::query_as(
concat!("INSERT INTO ", #table, " (", #columns_str, ") VALUES (", #placeholders_str, ") RETURNING *")
)
#(#bindings)*
.fetch_one(&mut *tx).await?;
entity = #entity_name::from(row);
tx.commit().await?;
Ok(entity)
}
}
}
}