use quote::quote;
use crate::sql_expand::SqlExpand;
pub struct Page;
impl SqlExpand for Page {
fn expand(&self, st: &crate::SqlClosure) -> syn::Result<proc_macro2::TokenStream> {
let dto = &st.dto;
let cot = &st.cot;
let ret_type = &st.ret_type;
let cot_ref = if st.is_cot_ref_mut {
quote!(&mut )
} else if st.is_cot_ref {
quote!(&)
} else {
quote!()
};
let (param_strings, param_idents) = self.extra_params(st)?;
let count_sql = format!("SELECT count(*) FROM ({}) as _tmp", &st.body);
let declare_rt = self.gen_declare_rt(st, Some(&count_sql), false)?;
let rst_count = match dto {
Some(_) => quote!(
#declare_rt
let mut query = sqlx::query_scalar::<_, i64>(&sql);
for i in 0..param_names.len() {
#(
if param_names[i] == #param_strings {
query = query.bind(&#dto.#param_idents);
}
)*
}
let rst = query.fetch_one(#cot_ref #cot).await;
if let Err(e) = rst {
break 'rst_block Err(dysql::DySqlError(dysql::ErrorInner::new(dysql::Kind::QueryError, Some(Box::new(e)))))
}
let count = rst.expect("Unexpected error");
let mut _tmp_pg_dto = #dto.clone();
_tmp_pg_dto.init(count as u64);
),
None => quote!(
#declare_rt
let mut query = sqlx::query_scalar::<_, #ret_type>(&sql);
let rst = query.fetch_one(#cot_ref #cot).await;
if let Err(e) = rst {
break 'rst_block Err(dysql::DySqlError(dysql::ErrorInner::new(dysql::Kind::QueryError, Some(Box::new(e)))))
}
let count = rst.expect("Unexpected error");
let mut _tmp_pg_dto = #dto.clone();
_tmp_pg_dto.init(count as u64);
),
};
let mut page_sql = st.body.to_owned();
page_sql.push_str(" LIMIT {{page_size}} OFFSET {{start}}");
let declare_rt = self.gen_declare_rt(st, Some(&page_sql), true)?;
let rst_page = match dto {
Some(_) => quote!(
#declare_rt
let mut query = sqlx::query_as::<_, #ret_type>(&sql);
for i in 0..param_names.len() {
#(
if param_names[i] == #param_strings {
query = query.bind(&#dto.#param_idents);
}
)*
}
let rst = query.fetch_all(#cot_ref #cot).await;
if let Err(e) = rst {
break 'rst_block Err(dysql::DySqlError(dysql::ErrorInner::new(dysql::Kind::QueryError, Some(Box::new(e)))))
}
let rst = rst.expect("Unexpected error");
let pg_data = dysql::Pagination::from_dto(&_tmp_pg_dto, rst);
Ok(pg_data)
),
None => quote!(
#declare_rt
let mut query = sqlx::query_as::<_, #ret_type>(&sql);
let rst = query.fetch_all(#cot_ref #cot).await;
if let Err(e) = rst {
break 'rst_block Err(dysql::DySqlError(dysql::ErrorInner::new(dysql::Kind::QueryError, Some(Box::new(e)))))
}
let rst = rst.expect("Unexpected error");
let pg_data = dysql::Pagination::from_dto(&_tmp_pg_dto, rst);
Ok(pg_data)
),
};
let ret = quote!('rst_block: {
#rst_count
#rst_page
});
Ok(ret)
}
}