Kestrel 2 rokov pred
rodič
commit
c530b985eb

+ 16 - 9
microrm-macros/src/entity.rs

@@ -16,7 +16,11 @@ fn parse_fk(attrs: &[syn::Attribute]) -> bool {
     false
 }
 
-fn derive_columns<'a, I: Iterator<Item=&'a syn::Field>>(input: &DeriveInput, microrm_ref: &proc_macro2::TokenStream, fields: I) -> proc_macro2::TokenStream {
+fn derive_columns<'a, I: Iterator<Item = &'a syn::Field>>(
+    input: &DeriveInput,
+    microrm_ref: &proc_macro2::TokenStream,
+    fields: I,
+) -> proc_macro2::TokenStream {
     let struct_name = &input.ident;
     let columns_name = format_ident!("_{}_columns", &input.ident.to_string().to_case(Case::Snake));
     let mut index = 0usize;
@@ -30,10 +34,11 @@ fn derive_columns<'a, I: Iterator<Item=&'a syn::Field>>(input: &DeriveInput, mic
         let original_case = name.ident.as_ref().unwrap().clone();
         let snake_case = original_case.to_string();
         if snake_case != snake_case.to_case(Case::Snake) {
-            return quote::quote_spanned!(original_case.span() => compile_error!("Names must be in snake_case")).into()
+            return quote::quote_spanned!(original_case.span() => compile_error!("Names must be in snake_case")).into();
         }
 
-        let converted_case = format_ident!("{}", original_case.to_string().to_case(Case::UpperCamel));
+        let converted_case =
+            format_ident!("{}", original_case.to_string().to_case(Case::UpperCamel));
 
         let ty = &name.ty;
 
@@ -72,7 +77,7 @@ fn derive_columns<'a, I: Iterator<Item=&'a syn::Field>>(input: &DeriveInput, mic
         struct_name.to_string().to_case(Case::ScreamingSnake)
     );
 
-    quote!{
+    quote! {
         pub mod #columns_name {
             pub struct ID ();
             #(#column_types)*
@@ -102,7 +107,10 @@ fn derive_columns<'a, I: Iterator<Item=&'a syn::Field>>(input: &DeriveInput, mic
     }
 }
 
-fn derive_id(input: &DeriveInput, microrm_ref: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {
+fn derive_id(
+    input: &DeriveInput,
+    microrm_ref: &proc_macro2::TokenStream,
+) -> proc_macro2::TokenStream {
     let struct_name = &input.ident;
     let id_name = format_ident!("{}ID", &input.ident);
 
@@ -168,10 +176,11 @@ pub(crate) fn derive(tokens: TokenStream) -> TokenStream {
         let snake_case = original_case.to_string().to_case(Case::Snake);
 
         if original_case.to_string() != snake_case {
-            return quote::quote_spanned!(original_case.span() => compile_error!("Names must be in snake_case")).into()
+            return quote::quote_spanned!(original_case.span() => compile_error!("Names must be in snake_case")).into();
         }
 
-        let converted_case = format_ident!("{}", original_case.to_string().to_case(Case::UpperCamel));
+        let converted_case =
+            format_ident!("{}", original_case.to_string().to_case(Case::UpperCamel));
         variants.push(converted_case.clone());
 
         let field_name = name.ident.as_ref().unwrap().clone();
@@ -182,7 +191,6 @@ 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);
@@ -208,7 +216,6 @@ pub(crate) fn derive(tokens: TokenStream) -> TokenStream {
             });
         }
         */
-
     }
 
     let columns_array_name = format_ident!(

+ 8 - 4
microrm-macros/src/index.rs

@@ -1,5 +1,5 @@
 use proc_macro::TokenStream;
-use quote::{quote, format_ident};
+use quote::{format_ident, quote};
 use syn::parse_macro_input;
 
 use convert_case::{Case, Casing};
@@ -39,10 +39,13 @@ pub(crate) fn do_make_index(
 
     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 columns_array_name = format_ident!(
+        "INDEX_COLUMN_NAMES_{}",
+        index_struct_name.to_string().to_case(Case::ScreamingSnake)
+    );
     let column_count = columns.clone().len();
 
-    quote!{
+    quote! {
         pub struct #index_struct_name ();
 
         #microrm_ref::re_export::lazy_static::lazy_static!{
@@ -69,5 +72,6 @@ pub(crate) fn do_make_index(
                 #unique
             }
         }
-    }.into()
+    }
+    .into()
 }

+ 6 - 2
microrm/src/entity.rs

@@ -21,9 +21,13 @@ 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 table_name(&self) -> &'static str {
+        <Self::Entity as Entity>::table_name()
+    }
 
-    fn column_typeid(&self) -> std::any::TypeId { std::any::TypeId::of::<Self>() }
+    fn column_typeid(&self) -> std::any::TypeId {
+        std::any::TypeId::of::<Self>()
+    }
 
     fn sql_type(&self) -> &'static str;
     fn index(&self) -> usize;

+ 14 - 12
microrm/src/lib.rs

@@ -1,20 +1,20 @@
 #![doc = include_str!("../README.md")]
 
+pub mod entity;
 mod error;
 mod meta;
 pub mod model;
 pub mod query;
-pub mod entity;
 pub mod schema;
 
-use meta::Metaschema;
 use entity::Entity;
+use meta::Metaschema;
 
 pub use microrm_macros::{make_index, Entity, Modelable};
 
-pub use schema::Schema;
-pub use query::{QueryInterface, WithID};
 pub use error::Error;
+pub use query::{QueryInterface, WithID};
+pub use schema::Schema;
 
 #[macro_export]
 macro_rules! value_list {
@@ -262,7 +262,6 @@ mod pool_test {
     impl<'a> IsSendAndSync for super::DBPool<'a> {}
 }
 
-
 #[cfg(test)]
 mod test {
     use super::DB;
@@ -356,26 +355,25 @@ mod delete_test {
 
     #[test]
     fn delete_test() {
-        let schema = crate::Schema::new()
-            .entity::<KVStore>();
+        let schema = crate::Schema::new().entity::<KVStore>();
 
         let db = crate::DB::new_in_memory(schema).unwrap();
         let qi = db.query_interface();
 
         qi.add(&KVStore {
             key: "a".to_string(),
-            value: "a_value".to_string()
+            value: "a_value".to_string(),
         });
 
         let insert_two = || {
             qi.add(&KVStore {
                 key: "a".to_string(),
-                value: "a_value".to_string()
+                value: "a_value".to_string(),
             });
 
             qi.add(&KVStore {
                 key: "a".to_string(),
-                value: "another_value".to_string()
+                value: "another_value".to_string(),
             });
         };
 
@@ -398,7 +396,12 @@ mod delete_test {
         assert!(all.is_some());
         assert_eq!(all.unwrap().len(), 2);
 
-        assert!(qi.delete_by_multi(&[&KVStore::Key, &KVStore::Value], &crate::value_list![&"a", &"another_value"]).is_some());
+        assert!(qi
+            .delete_by_multi(
+                &[&KVStore::Key, &KVStore::Value],
+                &crate::value_list![&"a", &"another_value"]
+            )
+            .is_some());
         let one = qi.get_one_by(KVStore::Key, "a");
         assert!(one.is_some());
         assert_eq!(one.unwrap().value, "a_value");
@@ -416,4 +419,3 @@ mod query_macro_test {
     }
 }
 */
-

+ 8 - 3
microrm/src/model.rs

@@ -8,9 +8,14 @@ pub trait Modelable {
     fn bind_to(&self, stmt: &mut sqlite::Statement, col: usize) -> sqlite::Result<()>;
     fn build_from(_stmt: &sqlite::Statement, _col_offset: usize) -> sqlite::Result<(Self, usize)>
     where
-        Self: Sized { unreachable!() }
+        Self: Sized,
+    {
+        unreachable!()
+    }
     fn column_type() -> &'static str
     where
-        Self: Sized { unreachable!() }
+        Self: Sized,
+    {
+        unreachable!()
+    }
 }
-

+ 30 - 57
microrm/src/query.rs

@@ -112,12 +112,9 @@ impl<'l> QueryInterface<'l> {
 
     /// Helper function to process an expected zero results
     /// Note that this errors out if there is any result
-    fn expect_no_result(
-        &self,
-        stmt: &mut sqlite::Statement
-    ) -> Option<()> {
+    fn expect_no_result(&self, stmt: &mut sqlite::Statement) -> Option<()> {
         let state = stmt.next().ok()?;
-        if state != sqlite::State::Done{
+        if state != sqlite::State::Done {
             return None;
         }
 
@@ -165,15 +162,11 @@ impl<'l> QueryInterface<'l> {
         with(query)
     }
 
-
     /// Search for an entity by a property
-    pub fn get_one_by<
-        C: EntityColumn,
-        V: Modelable
-    >(
+    pub fn get_one_by<C: EntityColumn, V: Modelable>(
         &self,
         col: C,
-        val: V
+        val: V,
     ) -> Option<WithID<C::Entity>> {
         let table_name = <C::Entity>::table_name();
         let column_name = col.name();
@@ -196,16 +189,17 @@ impl<'l> QueryInterface<'l> {
 
                 self.expect_one_result(stmt, &mut |stmt| {
                     let id: i64 = stmt.read(0).ok()?;
-                    Some(WithID::wrap(<<C as EntityColumn>::Entity>::build_from(stmt).ok()?, id))
+                    Some(WithID::wrap(
+                        <<C as EntityColumn>::Entity>::build_from(stmt).ok()?,
+                        id,
+                    ))
                 })
             },
         )
     }
 
     /// Search for an entity by multiple properties
-    pub fn get_one_by_multi<
-        T: Entity
-    >(
+    pub fn get_one_by_multi<T: Entity>(
         &self,
         c: &[&dyn EntityColumn<Entity = T>],
         val: &[&dyn crate::model::Modelable],
@@ -220,13 +214,13 @@ impl<'l> QueryInterface<'l> {
             c,
             &|| {
                 let query = format!(
-                        "SELECT * FROM \"{}\" WHERE {}",
-                        table_name,
-                        c.iter()
-                            .map(|col| format!("\"{}\" = ?", col.name()))
-                            .collect::<Vec<_>>()
-                            .join(" AND ")
-                    );
+                    "SELECT * FROM \"{}\" WHERE {}",
+                    table_name,
+                    c.iter()
+                        .map(|col| format!("\"{}\" = ?", col.name()))
+                        .collect::<Vec<_>>()
+                        .join(" AND ")
+                );
                 self.db
                     .conn
                     .prepare(&query)
@@ -246,15 +240,8 @@ impl<'l> QueryInterface<'l> {
     }
 
     /// Delete entities by searching with a single property
-    pub fn delete_by<
-        C: EntityColumn,
-        V: Modelable
-    >(
-        &self,
-        c: C,
-        val: V
-    ) -> Option<()> {
-        let table_name  = <C::Entity>::table_name();
+    pub fn delete_by<C: EntityColumn, V: Modelable>(&self, c: C, val: V) -> Option<()> {
+        let table_name = <C::Entity>::table_name();
         let column_name = c.name();
 
         self.cached_query_column(
@@ -262,10 +249,7 @@ impl<'l> QueryInterface<'l> {
             std::any::TypeId::of::<C::Entity>(),
             &[&c],
             &|| {
-                let query = format!(
-                        "DELETE FROM \"{}\" WHERE {} = ?",
-                        table_name,
-                        column_name);
+                let query = format!("DELETE FROM \"{}\" WHERE {} = ?", table_name, column_name);
                 self.db
                     .conn
                     .prepare(&query)
@@ -280,10 +264,7 @@ impl<'l> QueryInterface<'l> {
     }
 
     /// Delete entities by searching with a single property
-    pub fn delete_by_id<
-        I: EntityID<Entity = T>,
-        T: Entity<ID = I>,
-    >(
+    pub fn delete_by_id<I: EntityID<Entity = T>, T: Entity<ID = I>>(
         &self,
         id: <T as Entity>::ID,
     ) -> Option<()> {
@@ -293,9 +274,7 @@ impl<'l> QueryInterface<'l> {
             "delete_by_id",
             std::any::TypeId::of::<T>(),
             &|| {
-                let query = format!(
-                        "DELETE FROM \"{}\" WHERE id = ?",
-                        table_name);
+                let query = format!("DELETE FROM \"{}\" WHERE id = ?", table_name);
                 self.db
                     .conn
                     .prepare(&query)
@@ -309,11 +288,8 @@ impl<'l> QueryInterface<'l> {
         )
     }
 
-
     /// Delete entities by searching with multiple properties
-    pub fn delete_by_multi<
-        T: Entity
-    >(
+    pub fn delete_by_multi<T: Entity>(
         &self,
         c: &[&dyn EntityColumn<Entity = T>],
         val: &[&dyn crate::model::Modelable],
@@ -328,13 +304,13 @@ impl<'l> QueryInterface<'l> {
             c,
             &|| {
                 let query = format!(
-                        "DELETE FROM \"{}\" WHERE {}",
-                        table_name,
-                        c.iter()
-                            .map(|col| format!("\"{}\" = ?", col.name()))
-                            .collect::<Vec<_>>()
-                            .join(" AND ")
-                    );
+                    "DELETE FROM \"{}\" WHERE {}",
+                    table_name,
+                    c.iter()
+                        .map(|col| format!("\"{}\" = ?", col.name()))
+                        .collect::<Vec<_>>()
+                        .join(" AND ")
+                );
                 self.db
                     .conn
                     .prepare(&query)
@@ -375,10 +351,7 @@ impl<'l> QueryInterface<'l> {
     }
 
     /// Search for all entities matching a property
-    pub fn get_all_by<
-        C: EntityColumn,
-        V: Modelable,
-    >(
+    pub fn get_all_by<C: EntityColumn, V: Modelable>(
         &self,
         c: C,
         val: V,

+ 142 - 34
microrm/src/query/builder.rs

@@ -1,16 +1,26 @@
-use crate::{Entity, model::Modelable, entity::EntityColumn};
+use crate::{entity::EntityColumn, model::Modelable, Entity};
 
 use std::marker::PhantomData;
 
 pub trait BuildingBlock {
-    fn build_query(&self) -> String { String::new() }
+    fn build_query(&self) -> String {
+        String::new()
+    }
 }
 
-pub struct Builder { }
+pub struct Builder {}
 
 impl Builder {
-    pub fn get<T: Entity>() -> Select<T> { Select { _ghost: PhantomData } }
-    pub fn update<T: Entity>() -> Update<T> { Update { _ghost: PhantomData } }
+    pub fn get<T: Entity>() -> Select<T> {
+        Select {
+            _ghost: PhantomData,
+        }
+    }
+    pub fn update<T: Entity>() -> Update<T> {
+        Update {
+            _ghost: PhantomData,
+        }
+    }
 }
 
 pub struct Select<T: Entity> {
@@ -20,8 +30,19 @@ pub struct Select<T: Entity> {
 pub trait Conditionable: BuildingBlock {
     type Table: Entity;
 
-    fn with<G: Modelable, Col: EntityColumn<Entity = Self::Table>>(self, column: Col, _given: G) -> WhereClause<Self, Col, Self::Table, G> where Self: Sized {
-        WhereClause { conditionable: self, column, _ghost: PhantomData }
+    fn with<G: Modelable, Col: EntityColumn<Entity = Self::Table>>(
+        self,
+        column: Col,
+        _given: G,
+    ) -> WhereClause<Self, Col, Self::Table, G>
+    where
+        Self: Sized,
+    {
+        WhereClause {
+            conditionable: self,
+            column,
+            _ghost: PhantomData,
+        }
     }
 }
 
@@ -29,36 +50,71 @@ impl<T: Entity> Conditionable for Select<T> {
     type Table = T;
 }
 
-pub struct WhereClause<S: Conditionable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable> {
+pub struct WhereClause<
+    S: Conditionable<Table = T>,
+    Col: EntityColumn<Entity = T>,
+    T: Entity,
+    Given: Modelable,
+> {
     conditionable: S,
     column: Col,
-    _ghost: PhantomData<(S,Col,Given)>
+    _ghost: PhantomData<(S, Col, Given)>,
 }
 
-impl<S: Conditionable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable> Conditionable for WhereClause<S, Col, T, Given> {
+impl<S: Conditionable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable>
+    Conditionable for WhereClause<S, Col, T, Given>
+{
     type Table = T;
 }
 
 pub trait Joinable: BuildingBlock {
     type Table: Entity;
 
-    fn join<BaseColumn: EntityColumn<Entity = Self::Table>, Target: Entity, TargetColumn: EntityColumn<Entity = Target>>(self, base_column: BaseColumn, target_column: TargetColumn) -> JoinClause<Self::Table, Self, BaseColumn, Target, TargetColumn> where Self: Sized {
-        JoinClause { joinable: self, base_column, target_column, _ghost: PhantomData }
+    fn join<
+        BaseColumn: EntityColumn<Entity = Self::Table>,
+        Target: Entity,
+        TargetColumn: EntityColumn<Entity = Target>,
+    >(
+        self,
+        base_column: BaseColumn,
+        target_column: TargetColumn,
+    ) -> JoinClause<Self::Table, Self, BaseColumn, Target, TargetColumn>
+    where
+        Self: Sized,
+    {
+        JoinClause {
+            joinable: self,
+            base_column,
+            target_column,
+            _ghost: PhantomData,
+        }
     }
 }
 
-pub struct JoinClause<T: Entity, Base: Joinable<Table = T>, BaseColumn: EntityColumn<Entity = T>, Target: Entity, TargetColumn: EntityColumn<Entity = Target>> {
+pub struct JoinClause<
+    T: Entity,
+    Base: Joinable<Table = T>,
+    BaseColumn: EntityColumn<Entity = T>,
+    Target: Entity,
+    TargetColumn: EntityColumn<Entity = Target>,
+> {
     joinable: Base,
     base_column: BaseColumn,
     target_column: TargetColumn,
-    _ghost: PhantomData<(Base, BaseColumn, Target, TargetColumn)>
+    _ghost: PhantomData<(Base, BaseColumn, Target, TargetColumn)>,
 }
 
 impl<T: Entity> Joinable for Select<T> {
     type Table = T;
 }
 
-impl<S: Joinable + Conditionable<Table = T>, T: Entity, Col: EntityColumn<Entity = T>, Given: Modelable> Joinable for WhereClause<S, Col, T, Given> {
+impl<
+        S: Joinable + Conditionable<Table = T>,
+        T: Entity,
+        Col: EntityColumn<Entity = T>,
+        Given: Modelable,
+    > Joinable for WhereClause<S, Col, T, Given>
+{
     type Table = T;
 }
 
@@ -77,22 +133,39 @@ impl<T: Entity> Settable for Update<T> {
 pub trait Settable {
     type Table: Entity;
 
-    fn update<G: Modelable, Col: EntityColumn<Entity = Self::Table>>(self, column: Col, _given: G) -> SetClause<Self, Col, Self::Table, G> where Self: Sized {
-        SetClause { settable: self, column, _ghost: (PhantomData, PhantomData, PhantomData) }
+    fn update<G: Modelable, Col: EntityColumn<Entity = Self::Table>>(
+        self,
+        column: Col,
+        _given: G,
+    ) -> SetClause<Self, Col, Self::Table, G>
+    where
+        Self: Sized,
+    {
+        SetClause {
+            settable: self,
+            column,
+            _ghost: (PhantomData, PhantomData, PhantomData),
+        }
     }
 }
 
-pub struct SetClause<S: Settable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable> {
+pub struct SetClause<
+    S: Settable<Table = T>,
+    Col: EntityColumn<Entity = T>,
+    T: Entity,
+    Given: Modelable,
+> {
     settable: S,
     column: Col,
-    _ghost: (PhantomData<S>, PhantomData<Col>, PhantomData<Given>)
+    _ghost: (PhantomData<S>, PhantomData<Col>, PhantomData<Given>),
 }
 
-impl<S: Settable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable> Conditionable for SetClause<S, Col, T, Given> {
+impl<S: Settable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable>
+    Conditionable for SetClause<S, Col, T, Given>
+{
     type Table = T;
 }
 
-
 // BuildingBlock implementations
 impl<T: Entity> BuildingBlock for Select<T> {
     fn build_query(&self) -> String {
@@ -100,21 +173,36 @@ impl<T: Entity> BuildingBlock for Select<T> {
     }
 }
 
-impl<S: Conditionable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable> BuildingBlock for WhereClause<S, Col, T, Given> {
+impl<S: Conditionable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable>
+    BuildingBlock for WhereClause<S, Col, T, Given>
+{
     fn build_query(&self) -> String {
-        format!("{} AND {} = ?", self.conditionable.build_query(), self.column.name())
+        format!(
+            "{} AND {} = ?",
+            self.conditionable.build_query(),
+            self.column.name()
+        )
     }
 }
 
-impl<T: Entity, Base: Joinable<Table = T>, BaseColumn: EntityColumn<Entity = T>, Target: Entity, TargetColumn: EntityColumn<Entity = Target>> BuildingBlock for JoinClause<T, Base, BaseColumn, Target, TargetColumn> {
+impl<
+        T: Entity,
+        Base: Joinable<Table = T>,
+        BaseColumn: EntityColumn<Entity = T>,
+        Target: Entity,
+        TargetColumn: EntityColumn<Entity = Target>,
+    > BuildingBlock for JoinClause<T, Base, BaseColumn, Target, TargetColumn>
+{
     fn build_query(&self) -> String {
-        format!("{} JOIN {} ON {}.{} = {}.{}",
+        format!(
+            "{} JOIN {} ON {}.{} = {}.{}",
             self.joinable.build_query(),
             self.target_column.table_name(),
             self.base_column.table_name(),
             self.base_column.name(),
             self.target_column.table_name(),
-            self.target_column.name())
+            self.target_column.name()
+        )
     }
 }
 
@@ -124,7 +212,9 @@ impl<T: Entity> BuildingBlock for Update<T> {
     }
 }
 
-impl<S: Settable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable> BuildingBlock for SetClause<S, Col, T, Given> {
+impl<S: Settable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable>
+    BuildingBlock for SetClause<S, Col, T, Given>
+{
     fn build_query(&self) -> String {
         //format!("UPDATE {} SET {} = ? WHERE true", T::table_name(), self.column.name())
         format!("<>")
@@ -139,23 +229,41 @@ mod builder_test {
     #[microrm_internal]
     pub struct SimpleEntity {
         a: usize,
-        b: usize
+        b: usize,
     }
 
     #[derive(crate::Entity, serde::Deserialize, serde::Serialize)]
     #[microrm_internal]
     pub struct ChildType {
         r: SimpleEntityID,
-        b: usize
+        b: usize,
     }
 
     #[test]
     fn simple_builder_select_test() {
         println!("{}", Builder::get::<SimpleEntity>().build_query());
-        println!("{}", Builder::get::<SimpleEntity>().with(SimpleEntity::A, 0u8).with(SimpleEntity::B, 1u8).build_query());
-
-        println!("{}", Builder::get::<SimpleEntity>().with(SimpleEntity::A, 0u8).join(SimpleEntity::ID, ChildType::R).build_query());
-
-        println!("{}", Builder::update::<SimpleEntity>().update(SimpleEntity::A, 1u8).with(SimpleEntity::ID, 1u8).build_query());
+        println!(
+            "{}",
+            Builder::get::<SimpleEntity>()
+                .with(SimpleEntity::A, 0u8)
+                .with(SimpleEntity::B, 1u8)
+                .build_query()
+        );
+
+        println!(
+            "{}",
+            Builder::get::<SimpleEntity>()
+                .with(SimpleEntity::A, 0u8)
+                .join(SimpleEntity::ID, ChildType::R)
+                .build_query()
+        );
+
+        println!(
+            "{}",
+            Builder::update::<SimpleEntity>()
+                .update(SimpleEntity::A, 1u8)
+                .with(SimpleEntity::ID, 1u8)
+                .build_query()
+        );
     }
 }

+ 1 - 1
microrm/src/schema.rs

@@ -1,6 +1,6 @@
 mod create;
 
-use crate::entity::{Entity,Index};
+use crate::entity::{Entity, Index};
 
 /// How we describe an entire schema
 #[derive(Debug)]

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

@@ -1,4 +1,4 @@
-use crate::entity::{Entity,Index};
+use crate::entity::{Entity, Index};
 
 pub fn sql_for_table<T: Entity>() -> (String, String) {
     let all_columns = T::columns();
@@ -12,17 +12,19 @@ pub fn sql_for_table<T: Entity>() -> (String, String) {
             col.name(),
             col.sql_type(),
             if col.fk_table_name().is_some() {
-                format!(" REFERENCES \"{}\"(\"{}\") ON DELETE CASCADE", col.fk_table_name().unwrap(), col.fk_column_name().unwrap())
+                format!(
+                    " REFERENCES \"{}\"(\"{}\") ON DELETE CASCADE",
+                    col.fk_table_name().unwrap(),
+                    col.fk_column_name().unwrap()
+                )
+            } else {
+                "".to_owned()
             }
-            else { "".to_owned() }
         ));
     }
 
     (
-        format!(
-            "DROP TABLE IF EXISTS \"{}\"",
-            <T as Entity>::table_name()
-        ),
+        format!("DROP TABLE IF EXISTS \"{}\"", <T as Entity>::table_name()),
         format!(
             "CREATE TABLE IF NOT EXISTS \"{}\" ({})",
             <T as Entity>::table_name(),