Browse Source

Tweak Index implementation to work with new EntityColumn types.

Kestrel 2 years ago
parent
commit
462db8e2d1
4 changed files with 40 additions and 19 deletions
  1. 3 0
      microrm-macros/src/entity.rs
  2. 22 10
      microrm-macros/src/index.rs
  3. 10 2
      microrm/src/entity.rs
  4. 5 7
      microrm/src/schema/create.rs

+ 3 - 0
microrm-macros/src/entity.rs

@@ -60,6 +60,9 @@ fn derive_columns<'a, I: Iterator<Item=&'a syn::Field>>(input: &DeriveInput, mic
         });
         column_consts.push(quote! { const #converted_case : #columns_name::#converted_case = #columns_name::#converted_case(); });
 
+        let constructor_ident = format_ident!("{}{}", converted_case, "Column");
+
+
         column_array.push(quote! { & #columns_name::#converted_case() });
     }
 

+ 22 - 10
microrm-macros/src/index.rs

@@ -1,5 +1,5 @@
 use proc_macro::TokenStream;
-use quote::{quote};
+use quote::{quote, format_ident};
 use syn::parse_macro_input;
 
 use convert_case::{Case, Casing};
@@ -31,27 +31,39 @@ pub(crate) fn do_make_index(
     let input = parse_macro_input!(tokens as MakeIndexParams);
 
     let index_struct_name = input.name;
+    let index_sql_name = format!("{}", index_struct_name).to_case(Case::Snake);
 
     let columns = input.columns.clone().into_iter();
 
-    let index_sql_name = format!("{}", index_struct_name).to_case(Case::Snake);
-
     let unique = input.unique.is_some();
 
-    let first_column = columns.clone().next();
+    let first_column = columns.clone().next().unwrap();
+
+    let columns_array_name = format_ident!("INDEX_COLUMN_NAMES_{}", index_struct_name.to_string().to_case(Case::ScreamingSnake));
+    let column_count = columns.clone().len();
 
     quote!{
-        pub struct #index_struct_name {}
-        // type #index_entity_type_name = <#column_type_path as #microrm_ref::entity::EntityColumn>::Entity;
-        // type IndexType = <#first_column as #microrm_ref::entity::EntityColumn>::Entity;
+        pub struct #index_struct_name ();
+
+        #microrm_ref::re_export::lazy_static::lazy_static!{
+            static ref #columns_array_name : [&'static str; #column_count] = {
+                use #microrm_ref::entity::EntityColumn;
+                [
+                    #( #columns . name() ),*
+                ]
+            };
+        }
 
         impl #microrm_ref::entity::Index for #index_struct_name {
-            type IndexedEntity = <#first_column as #microrm_ref::entity::EntityColumn>::Entity;
             fn index_name() -> &'static str {
                 #index_sql_name
             }
-            fn columns() -> &'static [&'static dyn #microrm_ref::entity::EntityColumn<Entity = Self::IndexedEntity>] where Self: Sized {
-                &[#(&#columns),*]
+            fn table_name() -> &'static str {
+                use #microrm_ref::entity::EntityColumn;
+                #first_column.table_name()
+            }
+            fn column_names() -> &'static [&'static str] {
+                #columns_array_name.as_ref()
             }
             fn unique() -> bool where Self: Sized {
                 #unique

+ 10 - 2
microrm/src/entity.rs

@@ -21,6 +21,8 @@ pub trait Entity: 'static + for<'de> serde::Deserialize<'de> + serde::Serialize
 pub trait EntityColumn: 'static + Send + Sync {
     type Entity: Entity;
 
+    fn table_name(&self) -> &'static str { <Self::Entity as Entity>::table_name() }
+
     fn sql_type(&self) -> &'static str;
     fn index(&self) -> usize;
     fn name(&self) -> &'static str;
@@ -44,14 +46,20 @@ pub trait EntityForeignKey {
 
 /// Trait for an index over a column
 pub trait Index {
-    type IndexedEntity: Entity;
+    // type IndexedEntity: Entity;
 
     fn index_name() -> &'static str
     where
         Self: Sized;
-    fn columns() -> &'static [&'static dyn EntityColumn<Entity = Self::IndexedEntity>]
+    fn table_name() -> &'static str
+    where
+        Self: Sized;
+    fn column_names() -> &'static [&'static str]
     where
         Self: Sized;
+    /*fn columns() -> &'static [&'static dyn EntityColumn<Entity = Self::IndexedEntity>]
+    where
+        Self: Sized;*/
     fn unique() -> bool
     where
         Self: Sized;

+ 5 - 7
microrm/src/schema/create.rs

@@ -38,10 +38,10 @@ pub fn sql_for_index<I: Index>() -> (String, String) {
             "CREATE {}INDEX \"{}\" ON \"{}\" ({})",
             if I::unique() { "UNIQUE " } else { "" },
             I::index_name(),
-            I::IndexedEntity::table_name(),
-            I::columns()
+            I::table_name(),
+            I::column_names()
                 .iter()
-                .map(|x| format!("\"{}\"", x.name()))
+                .map(|x| format!("\"{}\"", x))
                 .collect::<Vec<_>>()
                 .join(",")
         ),
@@ -130,8 +130,7 @@ mod test {
             super::sql_for_table::<NonUnitNewtype>(),
             (
                 r#"DROP TABLE IF EXISTS "non_unit_newtype""#.to_owned(),
-                r#"CREATE TABLE IF NOT EXISTS "non_unit_newtype" (id integer primary key,"newtype" blob)"#
-                    .to_owned()
+                r#"CREATE TABLE IF NOT EXISTS "non_unit_newtype" (id integer primary key,"newtype" blob)"#.to_owned()
             )
         )
     }
@@ -161,12 +160,12 @@ mod test {
         value: String,
     }
 
-    /* XXX
     microrm_macros::make_index_internal!(ValueIndex, KeyValue::Value);
     microrm_macros::make_index_internal!(!UniqueValueIndex, KeyValue::Value);
 
     #[test]
     fn test_indexes() {
+        println!("{:?}", super::sql_for_index::<ValueIndex>());
         assert_eq!(
             super::sql_for_index::<ValueIndex>(),
             (
@@ -182,7 +181,6 @@ mod test {
             )
         )
     }
-    */
 
     #[derive(serde::Serialize, serde::Deserialize, crate::Entity)]
     #[microrm_internal]