Skip to content

Commit

Permalink
add generated and autoincrement
Browse files Browse the repository at this point in the history
  • Loading branch information
soulww committed Jan 9, 2024
1 parent 013e9ec commit bd3af6d
Show file tree
Hide file tree
Showing 18 changed files with 431 additions and 336 deletions.
9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[package]
name = "luna-orm"
version = "0.3.4"
version = "0.3.5"
edition = "2021"
license-file = "LICENSE"
description = "ORM based on sqlx"
homepage = "https://github.com/thegenius/luna-orm"

[dependencies]
luna-orm-trait = { path = "luna-orm-trait", version = "0.3.4" }
luna-orm-macro = { path = "luna-orm-macro", version = "0.3.4" }
luna-orm-trait = { path = "luna-orm-trait", version = "0.3.5" }
luna-orm-macro = { path = "luna-orm-macro", version = "0.3.5" }
thiserror = {workspace = true}
sqlx = {workspace = true}
#async-trait = {workspace = true}
Expand All @@ -35,10 +35,11 @@ members = [
]

[workspace.package]
version = "0.3.4"
version = "0.3.5"


[workspace.dependencies]
tracing = {version = "0.1"}
thiserror = {version = "1.0"}
#async-trait = {version = "0.1.74"}
serde = {version = "1.0", features = ["derive"]}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ At that time, the api will be stable, and backward compatible will be promised.

## INSTALL
```toml
luna-orm = { version = "0.3.4" }
luna-orm = { version = "0.3.5" }

```

Expand Down
2 changes: 1 addition & 1 deletion luna-orm-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ syn = { version = "1.0", features = ["full"] }
proc-macro2 = "1.0"
case = "1.0"

luna-orm-trait = { path = "../luna-orm-trait", version = "0.3.4" }
luna-orm-trait = { path = "../luna-orm-trait", version = "0.3.5" }
sqlx = { workspace = true }
146 changes: 14 additions & 132 deletions luna-orm-macro/src/auto_entity.rs
Original file line number Diff line number Diff line change
@@ -1,151 +1,33 @@
use proc_macro::{self, TokenStream};
use quote::quote;
use quote::quote_spanned;

use crate::field_utils::*;
use crate::entity::generate_entity_impl;
use crate::fields_parser::FieldsParser;
use crate::location::generate_location;
use crate::mutation::generate_mutation;
use crate::primary::generate_primary;
use crate::selected_entity::generate_selected_entity;
use crate::selection::generate_selection;
use crate::type_check;
use crate::type_check::field_is_option;
use crate::utils::*;
use proc_macro2::{Ident, Span};
use syn::Attribute;
use syn::Field;
use syn::{
parse_macro_input, token, Data, DataEnum, DataStruct, DataUnion, DeriveInput, Error, Fields,
FieldsNamed, LitStr, Path, Result,
};
use proc_macro::{self, TokenStream};
use syn::{parse_macro_input, DeriveInput};

pub fn impl_auto_entity_macro(input: TokenStream) -> TokenStream {
let DeriveInput {
attrs, ident, data, ..
} = parse_macro_input!(input);

let fields = extract_fields(&data).unwrap();
let mut output = generate_entity_impl(&ident, &attrs, &fields);

let _fields_name = extract_fields_name(&fields);
let primary_fields = extract_annotated_fields(&fields, "PrimaryKey");
if primary_fields.is_empty() {
panic!("Entity must has at least one PrimaryKey!")
}

let primary_fields_name = build_fields_name(&primary_fields);

let body_fields = extract_not_annotated_fields(&fields, "PrimaryKey");
//let body_fields_name = build_fields_name(&body_fields);
let body_fields_name = build_fields_name_with_option(&body_fields);

let generated_fields = extract_annotated_fields(&fields, "Generated");
let generated_fields_name = build_fields_name(&generated_fields);
let name = extract_table_name(&ident, &attrs);

let generated_primary = generate_primary(&name, &primary_fields);
let generated_mutation = generate_mutation(&name, &body_fields);

let primary_args_add_ref: Vec<proc_macro2::TokenStream> =
gen_args_add_maybe_option(&primary_fields);

let body_args_add_ref: Vec<proc_macro2::TokenStream> = gen_args_add_maybe_option(&body_fields);

let mut full_fields: Vec<Field> = Vec::new();
full_fields.extend(primary_fields);
full_fields.extend(body_fields);

let clone_full_fields = full_fields.clone();
let generated_selection = generate_selection(&name, &clone_full_fields);
let generated_selected_entity = generate_selected_entity(&name, &clone_full_fields);
let unique_indexes = extract_unique_index(&attrs);
let generated_location = generate_location(&name, &clone_full_fields, &attrs);

let from_row_get_statement_members = map_fields(&fields, &|field: Field| {
if field_is_option(&field) {
map_field(field, FieldMapType::RowGetOption)
} else {
map_field(field, FieldMapType::RowGet)
}
});

let clone_full_fields = full_fields.clone();
let from_row_field_members = clone_full_fields.into_iter().map(|field| {
let field_name = field.ident.unwrap();
let span = field_name.span();
quote_spanned! { span =>
#field_name
}
});

let cloned_fields = full_fields.clone();
let option_fields: Vec<String> = cloned_fields
.iter()
.filter(|f| type_check::field_is_option(f))
.map(|f| f.ident.as_ref().unwrap().to_string())
.collect();

let mut output = quote! {
impl Entity for #ident {

fn get_generated_fields_name(&self) -> &'static [&'static str] {
&[ #(#generated_fields_name, )* ]
}

fn get_table_name(&self) -> &'static str {
#name
}

fn from_any_row(row: AnyRow) -> Result<Self, SqlxError> where Self: Sized {
#(#from_row_get_statement_members ;)*
let result = #ident{ #(#from_row_field_members ,)* };
return Ok(result);
}

fn get_primary_fields_name(&self) -> Vec<String> {
vec![
#(#primary_fields_name, )*
]
}

fn get_body_fields_name(&self) -> Vec<String> {
#(#body_fields_name)*
}

fn get_primary_args(&self) -> AnyArguments<'_> {
let mut arguments = AnyArguments::default();
#(#primary_args_add_ref; )*
return arguments;
}

fn get_body_args(&self) -> AnyArguments<'_> {
let mut arguments = AnyArguments::default();
#(#body_args_add_ref; )*
return arguments;
}

fn any_arguments_of_insert(&self) -> AnyArguments<'_> {
let mut arguments = AnyArguments::default();
#(#primary_args_add_ref; )*
#(#body_args_add_ref; )*
return arguments;
}
let primary_fields = FieldsParser::from_named(&fields).filter_annotated_fields("PrimaryKey");
let body_fields = FieldsParser::from_named(&fields).filter_not_annotated_fields("PrimaryKey");
let full_fields = FieldsParser::from_named(&fields).get_sorted_fields();

fn any_arguments_of_upsert(&self) -> AnyArguments<'_> {
let mut arguments = AnyArguments::default();
#(#primary_args_add_ref; )*
#(#body_args_add_ref; )*
#(#body_args_add_ref; )*
return arguments;
}
let table_name = extract_table_name(&ident, &attrs);
let generated_primary = generate_primary(&table_name, &primary_fields);
let generated_mutation = generate_mutation(&table_name, &body_fields);
let generated_selection = generate_selection(&table_name, &full_fields);
let generated_selected_entity = generate_selected_entity(&table_name, &full_fields);
let generated_location = generate_location(&table_name, &full_fields, &attrs);

fn any_arguments_of_update(&self) -> AnyArguments<'_> {
let mut arguments = AnyArguments::default();
#(#body_args_add_ref; )*
#(#primary_args_add_ref; )*
return arguments;
}
}
};
output.extend(generated_primary);
output.extend(generated_selection);
output.extend(generated_selected_entity);
Expand Down
Loading

0 comments on commit bd3af6d

Please sign in to comment.