Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

editoast: allow Model fields order to differ from table columns' #9689

Merged
merged 4 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions editoast/editoast_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub fn search(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
/// This derive provides the implementation the `SearchConfigStore` trait.
/// Each struct that derives `Search` will be saved and the struct deriving
/// `SearchConfigStore` will implement a `find(name: &str)` function that
/// given a seach object name, returns the `SearchConfig` of the search object
/// given a search object name, returns the `SearchConfig` of the search object
/// matching.
///
/// ```ignore
Expand Down Expand Up @@ -188,10 +188,10 @@ pub fn search_config_store(input: proc_macro::TokenStream) -> proc_macro::TokenS
///
/// * `#[model(table = crate::table::osrd_yourtable")]` (**REQUIRED**): the path to the diesel table
/// * `#[model(row(type_name = "YourRowType"))]`: the name of the row struct (defaults to `ModelRow`)
/// * `#[model(row(derive(ADDITIONAL_DERIVES*,)))]`: additional derives for the row struct (always implicitely derives `Queryable` and `QueryableByName`)
/// * `#[model(row(derive(ADDITIONAL_DERIVES*,)))]`: additional derives for the row struct (always implicitly derives `Queryable` and `QueryableByName`)
/// * `#[model(row(public))]`: make the row struct fields `pub` (private by default)
/// * `#[model(changeset(type_name = "YourChangesetType"))]`: the name of the changeset struct (defaults to `ModelChangeset`)
/// * `#[model(changeset(derive(ADDITIONAL_DERIVES*,)))]`: additional derives for the changeset struct (always implicitely derives `Default, Queryable, QueryableByName, AsChangeset, Insertable`)
/// * `#[model(changeset(derive(ADDITIONAL_DERIVES*,)))]`: additional derives for the changeset struct (always implicitly derives `Default, Queryable, QueryableByName, AsChangeset, Insertable`)
/// * `#[model(changeset(public))]`: make the changeset struct fields `pub` (private by default)
/// * `#[model(identifier = IDENTIFIER)]` (multiple): just like `#[model(identifier)]` for fields, but at the struct level.
/// `IDENTIFIER` can be a compound identifier with the syntax `(field1, field2, ...)` (e.g.: `#[model(identifier = (infra_id, obj_id))]`).
Expand Down
8 changes: 8 additions & 0 deletions editoast/editoast_derive/src/model/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ impl ModelConfig {
table_mod: self.table.clone(),
row: self.row.ident(),
identifier: identifier.clone(),
columns: self.columns().cloned().collect(),
}
.tokens_if(self.impl_plan.ops.read)
})
Expand Down Expand Up @@ -296,6 +297,7 @@ impl ModelConfig {
row: self.row.ident(),
changeset: self.changeset.ident(),
identifier: identifier.clone(),
columns: self.columns().cloned().collect(),
}
.tokens_if(self.impl_plan.ops.update)
})
Expand Down Expand Up @@ -323,6 +325,7 @@ impl ModelConfig {
table_mod: self.table.clone(),
row: self.row.ident(),
changeset: self.changeset.ident(),
columns: self.columns().cloned().collect(),
}
.tokens_if(self.impl_plan.ops.create)
}
Expand All @@ -341,6 +344,7 @@ impl ModelConfig {
model: self.model.clone(),
table_mod: self.table.clone(),
row: self.row.ident(),
columns: self.columns().cloned().collect(),
}
.tokens_if(self.impl_plan.list)
}
Expand All @@ -362,6 +366,7 @@ impl ModelConfig {
row: self.row.ident(),
changeset: self.changeset.ident(),
field_count: self.changeset_fields().count(),
columns: self.columns().cloned().collect(),
}
.tokens_if(self.impl_plan.batch_ops.create)
}
Expand All @@ -379,6 +384,7 @@ impl ModelConfig {
changeset: self.changeset.ident(),
identifier: identifier.clone(),
field_count: self.changeset_fields().count(),
columns: self.columns().cloned().collect(),
}
.tokens_if(self.impl_plan.batch_ops.create)
})
Expand All @@ -396,6 +402,7 @@ impl ModelConfig {
chunk_size_limit: self.batch_chunk_size_limit,
row: self.row.ident(),
identifier: identifier.clone(),
columns: self.columns().cloned().collect(),
}
.tokens_if(self.impl_plan.batch_ops.read)
})
Expand All @@ -415,6 +422,7 @@ impl ModelConfig {
changeset: self.changeset.ident(),
identifier: identifier.clone(),
primary_key_column: self.get_primary_field_column(),
columns: self.columns().cloned().collect(),
}
.tokens_if(self.impl_plan.batch_ops.update)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub(crate) struct CreateBatchImpl {
pub(super) row: syn::Ident,
pub(super) changeset: syn::Ident,
pub(super) field_count: usize,
pub(super) columns: Vec<syn::Ident>,
}

impl ToTokens for CreateBatchImpl {
Expand All @@ -21,6 +22,7 @@ impl ToTokens for CreateBatchImpl {
row,
changeset,
field_count,
columns,
} = self;
let span_name = format!("model:create_batch<{}>", model);

Expand Down Expand Up @@ -51,6 +53,7 @@ impl ToTokens for CreateBatchImpl {
chunk => {
diesel::insert_into(dsl::#table_name)
.values(chunk)
.returning((#(dsl::#columns,)*))
.load_stream::<#row>(conn.write().await.deref_mut())
.await
.map(|s| s.map_ok(<#model as Model>::from_row).try_collect::<Vec<_>>())?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub(crate) struct CreateBatchWithKeyImpl {
pub(super) changeset: syn::Ident,
pub(super) field_count: usize,
pub(super) identifier: Identifier,
pub(super) columns: Vec<syn::Ident>,
}

impl ToTokens for CreateBatchWithKeyImpl {
Expand All @@ -25,6 +26,7 @@ impl ToTokens for CreateBatchWithKeyImpl {
changeset,
field_count,
identifier,
columns,
} = self;
let ty = identifier.get_type();
let span_name = format!("model:create_batch_with_key<{}>", model);
Expand Down Expand Up @@ -57,6 +59,7 @@ impl ToTokens for CreateBatchWithKeyImpl {
chunk => {
diesel::insert_into(dsl::#table_name)
.values(chunk)
.returning((#(dsl::#columns,)*))
.load_stream::<#row>(conn.write().await.deref_mut())
.await
.map(|s| {
Expand Down
4 changes: 4 additions & 0 deletions editoast/editoast_derive/src/model/codegen/create_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub(crate) struct CreateImpl {
pub(super) table_mod: syn::Path,
pub(super) row: syn::Ident,
pub(super) changeset: syn::Ident,
pub(super) columns: Vec<syn::Ident>,
}

impl ToTokens for CreateImpl {
Expand All @@ -15,6 +16,7 @@ impl ToTokens for CreateImpl {
table_mod,
row,
changeset,
columns,
} = self;
let span_name = format!("model:create<{}>", model);

Expand All @@ -28,9 +30,11 @@ impl ToTokens for CreateImpl {
conn: &mut editoast_models::DbConnection,
) -> crate::error::Result<#model> {
use diesel_async::RunQueryDsl;
use #table_mod::dsl;
use std::ops::DerefMut;
diesel::insert_into(#table_mod::table)
.values(&self)
.returning((#(dsl::#columns,)*))
.get_result::<#row>(conn.write().await.deref_mut())
.await
.map(Into::into)
Expand Down
4 changes: 4 additions & 0 deletions editoast/editoast_derive/src/model/codegen/list_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub(crate) struct ListImpl {
pub(super) model: syn::Ident,
pub(super) table_mod: syn::Path,
pub(super) row: syn::Ident,
pub(super) columns: Vec<syn::Ident>,
}

impl ToTokens for ListImpl {
Expand All @@ -13,6 +14,7 @@ impl ToTokens for ListImpl {
model,
table_mod,
row,
columns,
} = self;
let span_name = format!("model:list<{}>", model);

Expand All @@ -34,6 +36,7 @@ impl ToTokens for ListImpl {
use diesel::QueryDsl;
use diesel_async::RunQueryDsl;
use futures_util::stream::TryStreamExt;
use #table_mod::dsl;
use std::ops::DerefMut;

let mut query = #table_mod::table.into_boxed();
Expand All @@ -59,6 +62,7 @@ impl ToTokens for ListImpl {
}

let results: Vec<#model> = query
.select((#(dsl::#columns,)*))
.load_stream::<#row>(conn.write().await.deref_mut())
.await?
.map_ok(<#model as crate::models::prelude::Model>::from_row)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub(crate) struct RetrieveBatchImpl {
pub(super) chunk_size_limit: usize,
pub(super) row: syn::Ident,
pub(super) identifier: Identifier,
pub(super) columns: Vec<syn::Ident>,
}

impl ToTokens for RetrieveBatchImpl {
Expand All @@ -21,6 +22,7 @@ impl ToTokens for RetrieveBatchImpl {
chunk_size_limit,
row,
identifier,
columns,
} = self;
let ty = identifier.get_type();
let id_ident = identifier.get_lvalue();
Expand Down Expand Up @@ -63,6 +65,7 @@ impl ToTokens for RetrieveBatchImpl {
query = query.or_filter(#filters);
}
query
.select((#(dsl::#columns,)*))
.load_stream::<#row>(conn.write().await.deref_mut())
.await
.map(|s| s.map_ok(<#model as Model>::from_row).try_collect::<Vec<_>>())?
Expand Down Expand Up @@ -99,6 +102,7 @@ impl ToTokens for RetrieveBatchImpl {
query = query.or_filter(#filters);
}
query
.select((#(dsl::#columns,)*))
.load_stream::<#row>(conn.write().await.deref_mut())
.await
.map(|s| {
Expand Down
3 changes: 3 additions & 0 deletions editoast/editoast_derive/src/model/codegen/retrieve_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub(crate) struct RetrieveImpl {
pub(super) table_mod: syn::Path,
pub(super) row: syn::Ident,
pub(super) identifier: Identifier,
pub(super) columns: Vec<syn::Ident>,
}

impl ToTokens for RetrieveImpl {
Expand All @@ -19,6 +20,7 @@ impl ToTokens for RetrieveImpl {
table_mod,
row,
identifier,
columns,
} = self;
let ty = identifier.get_type();
let id_ident = identifier.get_lvalue();
Expand All @@ -42,6 +44,7 @@ impl ToTokens for RetrieveImpl {
tracing::Span::current().record("query_id", tracing::field::debug(#id_ref_ident));
dsl::#table_name
.#(filter(#eqs)).*
.select((#(dsl::#columns,)*))
.first::<#row>(conn.write().await.deref_mut())
.await
.map(Into::into)
Expand Down
2 changes: 1 addition & 1 deletion editoast/editoast_derive/src/model/codegen/row_decl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl ToTokens for RowDecl {
})
.unzip();
tokens.extend(quote! {
#[derive(Queryable, QueryableByName, #(#additional_derives),*)]
#[derive(Queryable, #(#additional_derives),*)]
#[diesel(table_name = #table)]
#vis struct #ident {
#(#[diesel(column_name = #field_column)] #field_vis #field_name: #field_type),*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub(crate) struct UpdateBatchImpl {
pub(super) changeset: syn::Ident,
pub(super) identifier: Identifier,
pub(super) primary_key_column: syn::Ident,
pub(super) columns: Vec<syn::Ident>,
}

impl ToTokens for UpdateBatchImpl {
Expand All @@ -25,6 +26,7 @@ impl ToTokens for UpdateBatchImpl {
identifier,
changeset,
primary_key_column,
columns,
} = self;
let ty = identifier.get_type();
let id_ident = identifier.get_lvalue();
Expand Down Expand Up @@ -70,6 +72,7 @@ impl ToTokens for UpdateBatchImpl {
diesel::update(dsl::#table_name)
.filter(dsl::#primary_key_column.eq_any(query))
.set(&self)
.returning((#(dsl::#columns,)*))
.load_stream::<#row>(conn.write().await.deref_mut())
.await
.map(|s| s.map_ok(<#model as Model>::from_row).try_collect::<Vec<_>>())?
Expand Down Expand Up @@ -111,6 +114,7 @@ impl ToTokens for UpdateBatchImpl {
diesel::update(dsl::#table_name)
.filter(dsl::#primary_key_column.eq_any(query))
.set(&self)
.returning((#(dsl::#columns,)*))
.load_stream::<#row>(conn.write().await.deref_mut())
.await
.map(|s| {
Expand Down
3 changes: 3 additions & 0 deletions editoast/editoast_derive/src/model/codegen/update_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub(crate) struct UpdateImpl {
pub(super) row: syn::Ident,
pub(super) changeset: syn::Ident,
pub(super) identifier: Identifier,
pub(super) columns: Vec<syn::Ident>,
}

impl ToTokens for UpdateImpl {
Expand All @@ -21,6 +22,7 @@ impl ToTokens for UpdateImpl {
row,
changeset,
identifier,
columns,
} = self;
let ty = identifier.get_type();
let id_ident = identifier.get_lvalue();
Expand All @@ -45,6 +47,7 @@ impl ToTokens for UpdateImpl {
tracing::Span::current().record("query_id", tracing::field::debug(#id_ref_ident));
diesel::update(dsl::#table_name.#(filter(#eqs)).*)
.set(&self)
.returning((#(dsl::#columns,)*))
.get_result::<#row>(conn.write().await.deref_mut())
.await
.map(Into::into)
Expand Down
4 changes: 4 additions & 0 deletions editoast/editoast_derive/src/model/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ impl ModelConfig {
.filter(|field| !self.is_primary(field))
.filter(|field| !field.builder_skip)
}

pub(super) fn columns(&self) -> impl Iterator<Item = &syn::Ident> {
self.fields.iter().map(ModelField::column_ident)
}
}

impl ModelField {
Expand Down
8 changes: 4 additions & 4 deletions editoast/editoast_derive/src/model/parsing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl ModelConfig {
.collect();

// collect identifiers from struct-level annotations...
let mut raw_identfiers: HashSet<_> = options
let mut raw_identifiers: HashSet<_> = options
.identifiers
.iter()
.cloned()
Expand Down Expand Up @@ -116,10 +116,10 @@ impl ModelConfig {
}
};

raw_identfiers.insert(primary_field.clone());
raw_identfiers.insert(preferred_identifier.clone());
raw_identifiers.insert(primary_field.clone());
raw_identifiers.insert(preferred_identifier.clone());

let typed_identifiers = raw_identfiers
let typed_identifiers = raw_identifiers
.iter()
.cloned()
.map(|id| Identifier::new(id, &fields))
Expand Down
Loading
Loading