use proc_macro2::TokenStream; use quote::{format_ident, quote}; use crate::models::{Field, FieldForeignMode, Model}; pub fn gen_get_many_by_related_entity_method(model: &Model, foreign_key_field: &Field) -> TokenStream { let resource_ident = format_ident!("{}", &model.name); let foreign_ref_params = match &foreign_key_field.foreign_mode { FieldForeignMode::ForeignRef(params) => params, FieldForeignMode::NotRef => { panic!("Expected foreign key"); } }; let select_query = format!("SELECT * FROM {} WHERE {} = $1", model.table_name, foreign_key_field.name); let func_name_ident = format_ident!("get_many_{}_by_{}", foreign_ref_params.reverse_relation_name, foreign_ref_params.target_resource_name); quote! { pub async fn #func_name_ident(&self, item_id: &str) -> Result, sqlx::Error> { sqlx::query_as::<_, #resource_ident>(#select_query) .bind(item_id) .fetch_all(&self.db.0) .await } } } pub fn gen_get_many_by_related_entities_method(all_models: &[Model], model: &Model, foreign_key_field: &Field) -> TokenStream { let resource_ident = format_ident!("{}", &model.name); let foreign_ref_params = match &foreign_key_field.foreign_mode { FieldForeignMode::ForeignRef(params) => params, FieldForeignMode::NotRef => { panic!("Expected foreign key"); } }; let select_query = format!("SELECT * FROM {} WHERE {} IN ({{}})", model.table_name, foreign_key_field.name); let target_resource = all_models.iter() .find(|m| m.name.to_lowercase() == foreign_ref_params.target_resource_name.to_lowercase()) .expect("Could not find foreign ref target type associated resource"); let func_name_ident = format_ident!("get_many_{}_by_{}", foreign_ref_params.reverse_relation_name, target_resource.table_name); quote! { pub async fn #func_name_ident(&self, items_ids: Vec) -> Result, sqlx::Error> { if items_ids.is_empty() { return Ok(vec![]) } let placeholder_params: String = (1..=(items_ids.len())) .map(|i| format!("${i}")) .collect::>() .join(","); let query_tmpl = format!( #select_query, placeholder_params ); let mut query = sqlx::query_as::<_, #resource_ident>(&query_tmpl); for id in items_ids { query = query.bind(id) } query .fetch_all(&self.db.0) .await } } }