72 lines
2.7 KiB
Rust
72 lines
2.7 KiB
Rust
|
|
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<Vec<#resource_ident>, 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<String>) -> Result<Vec<#resource_ident>, sqlx::Error> {
|
||
|
|
if items_ids.is_empty() {
|
||
|
|
return Ok(vec![])
|
||
|
|
}
|
||
|
|
let placeholder_params: String = (1..=(items_ids.len()))
|
||
|
|
.map(|i| format!("${i}"))
|
||
|
|
.collect::<Vec<String>>()
|
||
|
|
.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
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|