|
@@ -4,6 +4,8 @@ use syn::{parse_macro_input, DeriveInput};
|
|
|
|
|
|
use convert_case::{Case, Casing};
|
|
|
|
|
|
+use crate::index::generate_index_code;
|
|
|
+
|
|
|
fn parse_fk(attrs: &[syn::Attribute]) -> bool {
|
|
|
for attr in attrs {
|
|
|
if attr.path.segments.len() == 1
|
|
@@ -170,8 +172,8 @@ pub(crate) fn derive(tokens: TokenStream) -> TokenStream {
|
|
|
let mut value_references = Vec::new();
|
|
|
let mut build_clauses = Vec::new();
|
|
|
|
|
|
- // let mut foreign_keys = Vec::new();
|
|
|
- // let mut foreign_key_impls = Vec::new();
|
|
|
+ // let mut constraints = Vec::new();
|
|
|
+ let mut unique_columns = Vec::new();
|
|
|
|
|
|
let mut index: usize = 0;
|
|
|
|
|
@@ -198,31 +200,9 @@ pub(crate) fn derive(tokens: TokenStream) -> TokenStream {
|
|
|
index += 1;
|
|
|
build_clauses.push(quote! { #field_name: <#ty as #microrm_ref::model::Modelable>::build_from(stmt, #index)?.0 });
|
|
|
|
|
|
- /*
|
|
|
- if parse_fk(&name.attrs) {
|
|
|
- let fk_struct_name = format_ident!("{}{}ForeignKey", struct_name, converted_case);
|
|
|
- let ty = &name.ty;
|
|
|
- foreign_keys.push(quote! {
|
|
|
- &#fk_struct_name { col: #columns_name::#converted_case }
|
|
|
- });
|
|
|
- foreign_key_impls.push(quote!{
|
|
|
- struct #fk_struct_name {
|
|
|
- col: #columns_name
|
|
|
- }
|
|
|
- impl #microrm_ref::entity::EntityForeignKey<#columns_name> for #fk_struct_name {
|
|
|
- /*
|
|
|
- fn local_column(&self) -> &#columns_name { &self.col }
|
|
|
- fn foreign_table_name(&self) -> &'static str {
|
|
|
- <<#ty as #microrm_ref::entity::EntityID>::Entity as #microrm_ref::entity::Entity>::table_name()
|
|
|
- }
|
|
|
- fn foreign_column_name(&self) -> &'static str {
|
|
|
- "id"
|
|
|
- }
|
|
|
- */
|
|
|
- }
|
|
|
- });
|
|
|
+ if name.attrs.iter().filter(|a| a.path.is_ident("microrm_unique")).count() > 0 {
|
|
|
+ unique_columns.push(original_case);
|
|
|
}
|
|
|
- */
|
|
|
}
|
|
|
|
|
|
let columns_array_name = format_ident!(
|
|
@@ -233,12 +213,37 @@ pub(crate) fn derive(tokens: TokenStream) -> TokenStream {
|
|
|
let field_count = fields.named.iter().count();
|
|
|
|
|
|
let columns_name = format_ident!("_{}_columns", &input.ident.to_string().to_case(Case::Snake));
|
|
|
+ let constraints_mod = format_ident!("_{}_constraints", &input.ident.to_string().to_case(Case::Snake));
|
|
|
+
|
|
|
+ let (constraints, constraint_visitor) = if unique_columns.len() > 0 {
|
|
|
+ let instance_paths = unique_columns.iter().map(|id| {
|
|
|
+ let mut punc = syn::punctuated::Punctuated::new();
|
|
|
+ punc.push(format_ident!("super").into());
|
|
|
+ punc.push(format_ident!("{}", struct_name).into());
|
|
|
+ punc.push(format_ident!("{}", id.to_string().to_case(Case::UpperCamel)).into());
|
|
|
+ syn::ExprPath { attrs: vec![], qself: None, path: syn::Path { leading_colon: None, segments: punc } }
|
|
|
+ });
|
|
|
+
|
|
|
+ let index_ident = format_ident!("{}UniqueIndex", struct_name);
|
|
|
+ let index_impl = generate_index_code(index_ident.clone(), true, instance_paths, microrm_ref.clone());
|
|
|
+ (quote! {
|
|
|
+ pub mod #constraints_mod {
|
|
|
+ #index_impl
|
|
|
+ }
|
|
|
+ }, quote!{
|
|
|
+ cv.index::<#constraints_mod::#index_ident>();
|
|
|
+ })
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ (quote! { }, quote!{ })
|
|
|
+ };
|
|
|
|
|
|
quote!{
|
|
|
// Related types for #struct_name
|
|
|
|
|
|
#column_output
|
|
|
#id_output
|
|
|
+ #constraints
|
|
|
|
|
|
// Implementations for #struct_name
|
|
|
impl #microrm_ref::entity::Entity for #struct_name {
|
|
@@ -270,12 +275,9 @@ pub(crate) fn derive(tokens: TokenStream) -> TokenStream {
|
|
|
Self::ID
|
|
|
}
|
|
|
|
|
|
- /*fn foreign_keys() -> &'static [&'static dyn #microrm_ref::entity::EntityForeignKey<Self::Column>] {
|
|
|
- &[#(#foreign_keys),*]
|
|
|
- }*/
|
|
|
+ fn constraints<CV: #microrm_ref::entity::ConstraintVisitor>(cv: &mut CV) {
|
|
|
+ #constraint_visitor
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- // Foreign key struct implementations
|
|
|
- // #(#foreign_key_impls)*
|
|
|
}.into()
|
|
|
}
|