From 6aceb332312ac3a80070dd944e0256c83315814b Mon Sep 17 00:00:00 2001 From: hasezoey Date: Thu, 8 Feb 2024 15:17:01 +0100 Subject: [PATCH 1/9] deps(quote): add dependency --- Cargo.lock | 13 +++++++------ Cargo.toml | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0dd4197c..f62765c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -121,6 +121,7 @@ dependencies = [ "heck", "indoc", "proc-macro2", + "quote", "syn", "thiserror", ] @@ -161,18 +162,18 @@ checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -198,9 +199,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.38" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index d7719beb..dc9092b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ advanced-queries = [] clap = { version = "4.4", features = ["derive", "wrap_help"] } clap_complete = "4.4" syn = { version = "2", features = ["extra-traits", "full"] } +quote = "1" proc-macro2 = "1" indoc = "2.0.4" heck = "0.4" # same case converter diesel uses From 3b8cab934e98b032c65ef9ec17a19a05920d954a Mon Sep 17 00:00:00 2001 From: hasezoey Date: Thu, 8 Feb 2024 15:17:25 +0100 Subject: [PATCH 2/9] deps(prettyplease): add dependency --- Cargo.lock | 11 +++++++++++ Cargo.toml | 1 + 2 files changed, 12 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index f62765c8..fddde293 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -120,6 +120,7 @@ dependencies = [ "clap_complete", "heck", "indoc", + "prettyplease", "proc-macro2", "quote", "syn", @@ -160,6 +161,16 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +[[package]] +name = "prettyplease" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.78" diff --git a/Cargo.toml b/Cargo.toml index dc9092b0..98a8a561 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ clap = { version = "4.4", features = ["derive", "wrap_help"] } clap_complete = "4.4" syn = { version = "2", features = ["extra-traits", "full"] } quote = "1" +prettyplease = "0.2" proc-macro2 = "1" indoc = "2.0.4" heck = "0.4" # same case converter diesel uses From f08dc8c3265cf3d831dc0eed0a3d3bd8e4d7199d Mon Sep 17 00:00:00 2001 From: hasezoey Date: Thu, 8 Feb 2024 16:11:43 +0100 Subject: [PATCH 3/9] test: WIP: add extra schema to test quicker --- test/simple_table_pg/models/mod.rs | 1 + .../models/todos2/generated.rs | 52 +++++++++++++++++++ test/simple_table_pg/models/todos2/mod.rs | 2 + test/simple_table_pg/schema.rs | 6 +++ 4 files changed, 61 insertions(+) create mode 100644 test/simple_table_pg/models/todos2/generated.rs create mode 100644 test/simple_table_pg/models/todos2/mod.rs diff --git a/test/simple_table_pg/models/mod.rs b/test/simple_table_pg/models/mod.rs index 015a6a2b..82fce1a2 100644 --- a/test/simple_table_pg/models/mod.rs +++ b/test/simple_table_pg/models/mod.rs @@ -1 +1,2 @@ pub mod todos; +pub mod todos2; diff --git a/test/simple_table_pg/models/todos2/generated.rs b/test/simple_table_pg/models/todos2/generated.rs new file mode 100644 index 00000000..8889a88f --- /dev/null +++ b/test/simple_table_pg/models/todos2/generated.rs @@ -0,0 +1,52 @@ +/* @generated and managed by dsync */ + +use crate::diesel::*; +use crate::schema::*; + +pub type ConnectionType = diesel::r2d2::PooledConnection>; + +/// Struct representing a row in table `todos2` +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName)] +#[diesel(table_name=todos2, primary_key(id))] +pub struct Todos2 { + /// Field representing column `id` + pub id: i32, +} + +/// Result of a `.paginate` function +#[derive(Debug, serde::Serialize)] +pub struct PaginationResult { + /// Resulting items that are from the current page + pub items: Vec, + /// The count of total items there are + pub total_items: i64, + /// Current page, 0-based index + pub page: i64, + /// Size of a page + pub page_size: i64, + /// Number of total possible pages, given the `page_size` and `total_items` + pub num_pages: i64, +} + +impl Todos2 { + /// Insert a new row into `todos2` with all default values + pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { + use crate::schema::todos2::dsl::*; + + diesel::insert_into(todos2).default_values().get_result::(db) + } + + /// Get a row from `todos2`, identified by the primary key + pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { + use crate::schema::todos2::dsl::*; + + todos2.filter(id.eq(param_id)).first::(db) + } + + /// Delete a row in `todos2`, identified by the primary key + pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { + use crate::schema::todos2::dsl::*; + + diesel::delete(todos2.filter(id.eq(param_id))).execute(db) + } +} diff --git a/test/simple_table_pg/models/todos2/mod.rs b/test/simple_table_pg/models/todos2/mod.rs new file mode 100644 index 00000000..136e9a24 --- /dev/null +++ b/test/simple_table_pg/models/todos2/mod.rs @@ -0,0 +1,2 @@ +pub mod generated; +pub use generated::*; diff --git a/test/simple_table_pg/schema.rs b/test/simple_table_pg/schema.rs index c66e8219..c95bdbdc 100644 --- a/test/simple_table_pg/schema.rs +++ b/test/simple_table_pg/schema.rs @@ -12,3 +12,9 @@ diesel::table! { updated_at -> Timestamp, } } + +diesel::table! { + todos2 (id) { + id -> Int4, + } +} From 9aafdc9170bcddff6284a2dec30f935f75f91979 Mon Sep 17 00:00:00 2001 From: hasezoey Date: Thu, 8 Feb 2024 16:46:35 +0100 Subject: [PATCH 4/9] refactor(code::build_table_fns): use quote part 1 --- src/code.rs | 78 ++++++++++++++----- .../simple_table_pg/models/todos/generated.rs | 1 - .../models/todos2/generated.rs | 1 - test/simple_table_pg/schema.rs | 1 - 4 files changed, 60 insertions(+), 21 deletions(-) diff --git a/src/code.rs b/src/code.rs index d6dc65f6..babecf15 100644 --- a/src/code.rs +++ b/src/code.rs @@ -1,5 +1,7 @@ use heck::ToPascalCase; use indoc::formatdoc; +use proc_macro2::Ident; +use quote::{quote, ToTokens}; use std::borrow::Cow; use crate::parser::{ParsedColumnMacro, ParsedTableMacro, FILE_SIGNATURE}; @@ -425,6 +427,23 @@ fn get_async(table_options: &TableOptions<'_>) -> (&'static str, &'static str) { ("", "") } +/// Debug function to indent [prettyplease] output again to match surrounding code +/// always adds a newline at the end of each line +// DEBUG: this function is only for transitional from string to tokenstream +fn indent(str: &str, by: usize) -> String { + let mut string = String::with_capacity(str.len() + by); + + for line in str.lines() { + string.push_str(&format!("{:by$}{line}\n", "")) + } + + string +} + +/// Common error text for `syn::parse2().expect()` +/// NOTE: This should be removed again and is only temporary for transition +const SYN_PARSE_ERR: &str = "Expected syn to parse static input"; + /// Generate all functions (insides of the `impl StuctName { here }`) fn build_table_fns( table: &ParsedTableMacro, @@ -489,28 +508,51 @@ fn build_table_fns( buffer.push_str(&format!("impl {struct_name} {{")); + // the following section is for quote variables + let import_path_syn: syn::Path = + syn::parse_str(&format!("{schema_path}{table_name}")).expect(SYN_PARSE_ERR); + let await_keyword_syn: Option = syn::parse2(await_keyword.to_token_stream()).ok(); + let async_keyword_syn: Option = syn::parse2(async_keyword.to_token_stream()).ok(); + let table_name_syn: Ident = syn::parse_str(&table_name).expect(SYN_PARSE_ERR); + if !is_readonly { if create_struct.has_fields() { - buffer.push_str(&format!( - r##" - /// Insert a new row into `{table_name}` with a given [`{create_struct_identifier}`] - pub{async_keyword} fn create(db: &mut ConnectionType, item: &{create_struct_identifier}) -> diesel::QueryResult {{ - use {schema_path}{table_name}::dsl::*; - - diesel::insert_into({table_name}).values(item).get_result::(db){await_keyword} - }} -"## - )); + // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream + buffer.push('\n'); + let doc = format!( + " Insert a new row into `{table_name}` with a given [`{create_struct_identifier}`]" + ); + let create_struct_identifier: Ident = + syn::parse_str(create_struct_identifier).expect(SYN_PARSE_ERR); + + let code = quote! { + #[doc = #doc] + pub #async_keyword_syn fn create(db: &mut ConnectionType, item: &#create_struct_identifier) -> diesel::QueryResult { + use #import_path_syn::dsl::*; + + diesel::insert_into(#table_name_syn).values(item).get_result::(db)#await_keyword_syn + } + }; + buffer.push_str(&indent( + &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), + 4, + )); } else { - buffer.push_str(&format!( - r##" - /// Insert a new row into `{table_name}` with all default values - pub{async_keyword} fn create(db: &mut ConnectionType) -> diesel::QueryResult {{ - use {schema_path}{table_name}::dsl::*; + // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream + buffer.push('\n'); + let doc = format!(" Insert a new row into `{table_name}` with all default values"); - diesel::insert_into({table_name}).default_values().get_result::(db){await_keyword} - }} -"## + let code = quote! { + #[doc = #doc] + pub #async_keyword_syn fn create(db: &mut ConnectionType) -> diesel::QueryResult { + use #import_path_syn::dsl::*; + + diesel::insert_into(#table_name_syn).default_values().get_result::(db)#await_keyword_syn + } + }; + buffer.push_str(&indent( + &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), + 4, )); } } diff --git a/test/simple_table_pg/models/todos/generated.rs b/test/simple_table_pg/models/todos/generated.rs index 2e777ec2..cd55351d 100644 --- a/test/simple_table_pg/models/todos/generated.rs +++ b/test/simple_table_pg/models/todos/generated.rs @@ -82,7 +82,6 @@ impl Todos { /// Insert a new row into `todos` with a given [`CreateTodos`] pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { use crate::schema::todos::dsl::*; - diesel::insert_into(todos).values(item).get_result::(db) } diff --git a/test/simple_table_pg/models/todos2/generated.rs b/test/simple_table_pg/models/todos2/generated.rs index 8889a88f..4e4c09c3 100644 --- a/test/simple_table_pg/models/todos2/generated.rs +++ b/test/simple_table_pg/models/todos2/generated.rs @@ -32,7 +32,6 @@ impl Todos2 { /// Insert a new row into `todos2` with all default values pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { use crate::schema::todos2::dsl::*; - diesel::insert_into(todos2).default_values().get_result::(db) } diff --git a/test/simple_table_pg/schema.rs b/test/simple_table_pg/schema.rs index c95bdbdc..1db7d283 100644 --- a/test/simple_table_pg/schema.rs +++ b/test/simple_table_pg/schema.rs @@ -12,7 +12,6 @@ diesel::table! { updated_at -> Timestamp, } } - diesel::table! { todos2 (id) { id -> Int4, From 865efc6a6eb8cf99248aa7bd3147b910c0285265 Mon Sep 17 00:00:00 2001 From: hasezoey Date: Thu, 8 Feb 2024 17:07:54 +0100 Subject: [PATCH 5/9] refactor(code::build_table_fns): use quote part 2 --- src/code.rs | 61 +++++++++++++------ .../simple_table_pg/models/todos/generated.rs | 9 ++- .../models/todos2/generated.rs | 5 +- 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/src/code.rs b/src/code.rs index babecf15..c91c7b03 100644 --- a/src/code.rs +++ b/src/code.rs @@ -467,27 +467,40 @@ fn build_table_fns( }) .collect(); - let item_id_params = primary_column_name_and_type + let item_id_params_syn = primary_column_name_and_type .iter() .map(|name_and_type| { - format!( + syn::parse_str(&format!( "param_{name}: {ty}", name = name_and_type.0, ty = name_and_type.1 - ) + )) + .expect(SYN_PARSE_ERR) }) - .collect::>() - .join(", "); - let item_id_filters = primary_column_name_and_type + .collect::>(); + + let item_id_params: String = item_id_params_syn + .iter() + .map(|v| v.into_token_stream().to_string()) + .reduce(|a, b| a + &b + ", ") + .expect(SYN_PARSE_ERR); + + let item_id_filters_syn = primary_column_name_and_type .iter() .map(|name_and_type| { - format!( + syn::parse_str(&format!( "filter({name}.eq(param_{name}))", name = name_and_type.0.to_string() - ) + )) + .expect(SYN_PARSE_ERR) }) - .collect::>() - .join("."); + .collect::>(); + + let item_id_filters: String = item_id_filters_syn + .iter() + .map(|v| v.into_token_stream().to_string()) + .reduce(|a, b| a + &b + ".") + .expect(SYN_PARSE_ERR); // template variables let table_name = table.name.to_string(); @@ -564,16 +577,26 @@ fn build_table_fns( "keys" }; - buffer.push_str(&format!( - r##" - /// Get a row from `{table_name}`, identified by the primary {key_maybe_multiple} - pub{async_keyword} fn read(db: &mut ConnectionType, {item_id_params}) -> diesel::QueryResult {{ - use {schema_path}{table_name}::dsl::*; + { + // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream + buffer.push('\n'); + let doc = format!( + " Get a row from `{table_name}`, identified by the primary {key_maybe_multiple}" + ); - {table_name}.{item_id_filters}.first::(db){await_keyword} - }} -"## - )); + let code = quote! { + #[doc = #doc] + pub #async_keyword_syn fn read(db: &mut ConnectionType, #(#item_id_params_syn), *) -> diesel::QueryResult { + use #import_path_syn::dsl::*; + + #table_name_syn.#(#item_id_filters_syn).*.first::(db)#await_keyword_syn + } + }; + buffer.push_str(&indent( + &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), + 4, + )); + } #[cfg(feature = "advanced-queries")] buffer.push_str(&format!(r##" diff --git a/test/simple_table_pg/models/todos/generated.rs b/test/simple_table_pg/models/todos/generated.rs index cd55351d..c0a4ec2a 100644 --- a/test/simple_table_pg/models/todos/generated.rs +++ b/test/simple_table_pg/models/todos/generated.rs @@ -88,21 +88,20 @@ impl Todos { /// Get a row from `todos`, identified by the primary key pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { use crate::schema::todos::dsl::*; - todos.filter(id.eq(param_id)).first::(db) } /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] - pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateTodos) -> diesel::QueryResult { + pub fn update(db: &mut ConnectionType, param_id : i32, item: &UpdateTodos) -> diesel::QueryResult { use crate::schema::todos::dsl::*; - diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) + diesel::update(todos.filter (id . eq (param_id))).set(item).get_result(db) } /// Delete a row in `todos`, identified by the primary key - pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { + pub fn delete(db: &mut ConnectionType, param_id : i32) -> diesel::QueryResult { use crate::schema::todos::dsl::*; - diesel::delete(todos.filter(id.eq(param_id))).execute(db) + diesel::delete(todos.filter (id . eq (param_id))).execute(db) } } diff --git a/test/simple_table_pg/models/todos2/generated.rs b/test/simple_table_pg/models/todos2/generated.rs index 4e4c09c3..3eb5ed8d 100644 --- a/test/simple_table_pg/models/todos2/generated.rs +++ b/test/simple_table_pg/models/todos2/generated.rs @@ -38,14 +38,13 @@ impl Todos2 { /// Get a row from `todos2`, identified by the primary key pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { use crate::schema::todos2::dsl::*; - todos2.filter(id.eq(param_id)).first::(db) } /// Delete a row in `todos2`, identified by the primary key - pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { + pub fn delete(db: &mut ConnectionType, param_id : i32) -> diesel::QueryResult { use crate::schema::todos2::dsl::*; - diesel::delete(todos2.filter(id.eq(param_id))).execute(db) + diesel::delete(todos2.filter (id . eq (param_id))).execute(db) } } From 57e415996f759370204430114f297d316c04a0cd Mon Sep 17 00:00:00 2001 From: hasezoey Date: Thu, 8 Feb 2024 17:14:55 +0100 Subject: [PATCH 6/9] refactor(code::build_table_fns): use quote part 3 --- src/code.rs | 62 +++++++++++-------- .../simple_table_pg/models/todos/generated.rs | 14 +++-- .../models/todos2/generated.rs | 5 +- 3 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/code.rs b/src/code.rs index c91c7b03..36fff5c6 100644 --- a/src/code.rs +++ b/src/code.rs @@ -479,12 +479,6 @@ fn build_table_fns( }) .collect::>(); - let item_id_params: String = item_id_params_syn - .iter() - .map(|v| v.into_token_stream().to_string()) - .reduce(|a, b| a + &b + ", ") - .expect(SYN_PARSE_ERR); - let item_id_filters_syn = primary_column_name_and_type .iter() .map(|name_and_type| { @@ -496,12 +490,6 @@ fn build_table_fns( }) .collect::>(); - let item_id_filters: String = item_id_filters_syn - .iter() - .map(|v| v.into_token_stream().to_string()) - .reduce(|a, b| a + &b + ".") - .expect(SYN_PARSE_ERR); - // template variables let table_name = table.name.to_string(); let (async_keyword, await_keyword) = get_async(&table_options); @@ -690,26 +678,46 @@ fn build_table_fns( // In this scenario, we also have to check whether there are any updatable columns for which // we should generate an update() method. - buffer.push_str(&format!(r##" - /// Update a row in `{table_name}`, identified by the primary {key_maybe_multiple} with [`{update_struct_identifier}`] - pub{async_keyword} fn update(db: &mut ConnectionType, {item_id_params}, item: &{update_struct_identifier}) -> diesel::QueryResult {{ - use {schema_path}{table_name}::dsl::*; + // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream + buffer.push('\n'); + let doc = format!( + " Update a row in `{table_name}`, identified by the primary {key_maybe_multiple} with [`{update_struct_identifier}`]" + ); + let update_struct_identifier: Ident = + syn::parse_str(&update_struct_identifier).expect(SYN_PARSE_ERR); - diesel::update({table_name}.{item_id_filters}).set(item).get_result(db){await_keyword} - }} -"##)); + let code = quote! { + #[doc = #doc] + pub #async_keyword_syn fn update(db: &mut ConnectionType, #(#item_id_params_syn), *, item: &#update_struct_identifier) -> diesel::QueryResult { + use #import_path_syn::dsl::*; + + diesel::update(#table_name_syn.#(#item_id_filters_syn).*).set(item).get_result(db)#await_keyword_syn + } + }; + buffer.push_str(&indent( + &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), + 4, + )); } if !is_readonly { - buffer.push_str(&format!( - r##" - /// Delete a row in `{table_name}`, identified by the primary {key_maybe_multiple} - pub{async_keyword} fn delete(db: &mut ConnectionType, {item_id_params}) -> diesel::QueryResult {{ - use {schema_path}{table_name}::dsl::*; + // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream + buffer.push('\n'); + let doc = format!( + " Delete a row in `{table_name}`, identified by the primary {key_maybe_multiple}" + ); - diesel::delete({table_name}.{item_id_filters}).execute(db){await_keyword} - }} -"## + let code = quote! { + #[doc = #doc] + pub #async_keyword_syn fn delete(db: &mut ConnectionType, #(#item_id_params_syn), *) -> diesel::QueryResult { + use #import_path_syn::dsl::*; + + diesel::delete(#table_name_syn.#(#item_id_filters_syn).*).execute(db)#await_keyword_syn + } + }; + buffer.push_str(&indent( + &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), + 4, )); } diff --git a/test/simple_table_pg/models/todos/generated.rs b/test/simple_table_pg/models/todos/generated.rs index c0a4ec2a..06a984a9 100644 --- a/test/simple_table_pg/models/todos/generated.rs +++ b/test/simple_table_pg/models/todos/generated.rs @@ -92,16 +92,18 @@ impl Todos { } /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] - pub fn update(db: &mut ConnectionType, param_id : i32, item: &UpdateTodos) -> diesel::QueryResult { + pub fn update( + db: &mut ConnectionType, + param_id: i32, + item: &UpdateTodos, + ) -> diesel::QueryResult { use crate::schema::todos::dsl::*; - - diesel::update(todos.filter (id . eq (param_id))).set(item).get_result(db) + diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) } /// Delete a row in `todos`, identified by the primary key - pub fn delete(db: &mut ConnectionType, param_id : i32) -> diesel::QueryResult { + pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { use crate::schema::todos::dsl::*; - - diesel::delete(todos.filter (id . eq (param_id))).execute(db) + diesel::delete(todos.filter(id.eq(param_id))).execute(db) } } diff --git a/test/simple_table_pg/models/todos2/generated.rs b/test/simple_table_pg/models/todos2/generated.rs index 3eb5ed8d..4613c2f6 100644 --- a/test/simple_table_pg/models/todos2/generated.rs +++ b/test/simple_table_pg/models/todos2/generated.rs @@ -42,9 +42,8 @@ impl Todos2 { } /// Delete a row in `todos2`, identified by the primary key - pub fn delete(db: &mut ConnectionType, param_id : i32) -> diesel::QueryResult { + pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { use crate::schema::todos2::dsl::*; - - diesel::delete(todos2.filter (id . eq (param_id))).execute(db) + diesel::delete(todos2.filter(id.eq(param_id))).execute(db) } } From 372081464148652f6038a4bdb3ab2d4eecfd6979 Mon Sep 17 00:00:00 2001 From: hasezoey Date: Thu, 8 Feb 2024 17:49:22 +0100 Subject: [PATCH 7/9] refactor(code::build_table_fns): use quote part 4 --- src/code.rs | 198 ++++++++++-------- .../models/todos/generated.rs | 58 ++--- 2 files changed, 144 insertions(+), 112 deletions(-) diff --git a/src/code.rs b/src/code.rs index 36fff5c6..0676d99a 100644 --- a/src/code.rs +++ b/src/code.rs @@ -1,8 +1,9 @@ use heck::ToPascalCase; use indoc::formatdoc; -use proc_macro2::Ident; -use quote::{quote, ToTokens}; +use proc_macro2::{Ident, TokenStream}; +use quote::{format_ident, quote, ToTokens}; use std::borrow::Cow; +use syn::parse::Parser; use crate::parser::{ParsedColumnMacro, ParsedTableMacro, FILE_SIGNATURE}; use crate::{get_table_module_name, GenerationConfig, TableOptions}; @@ -587,85 +588,105 @@ fn build_table_fns( } #[cfg(feature = "advanced-queries")] - buffer.push_str(&format!(r##" - /// Paginates through the table where page is a 0-based index (i.e. page 0 is the first page) - pub{async_keyword} fn paginate(db: &mut ConnectionType, page: i64, page_size: i64, filter: {struct_name}Filter) -> diesel::QueryResult> {{ - use {schema_path}{table_name}::dsl::*; - - let page = page.max(0); - let page_size = page_size.max(1); - let total_items = Self::filter(filter.clone()).count().get_result(db)?; - let items = Self::filter(filter).limit(page_size).offset(page * page_size).load::(db){await_keyword}?; - - Ok(PaginationResult {{ - items, - total_items, - page, - page_size, - /* ceiling division of integers */ - num_pages: total_items / page_size + i64::from(total_items % page_size != 0) - }}) - }} -"##)); + { + // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream + buffer.push('\n'); + let doc = " Paginates through the table where page is a 0-based index (i.e. page 0 is the first page)"; + let filter_struct = format_ident!("{struct_name}Filter"); + + let code = quote! { + #[doc = #doc] + pub #async_keyword_syn fn paginate(db: &mut ConnectionType, page: i64, page_size: i64, filter: #filter_struct) -> diesel::QueryResult> { + use #import_path_syn::dsl::*; + + let page = page.max(0); + let page_size = page_size.max(1); + let total_items = Self::filter(filter.clone()).count().get_result(db)?; + let items = Self::filter(filter).limit(page_size).offset(page * page_size).load::(db)#await_keyword_syn?; + + Ok(PaginationResult { + items, + total_items, + page, + page_size, + /* ceiling division of integers */ + num_pages: total_items / page_size + i64::from(total_items % page_size != 0) + }) + } + }; + buffer.push_str(&indent( + &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), + 4, + )); + } #[cfg(feature = "advanced-queries")] // Table::filter() helper fn { - let diesel_backend = &config.diesel_backend; + let diesel_backend: syn::Path = + syn::parse_str(&config.diesel_backend).expect(SYN_PARSE_ERR); let filters = table .columns .iter() .map(|column| { - let column_name = column.name.to_string(); + let column_name = column.name.clone(); + let filter_ident = format_ident!("filter_{column_name}"); if column.is_nullable { // "Option::None" will never match anything, and "is_null" is required to be used, see https://docs.diesel.rs/master/diesel/expression_methods/trait.ExpressionMethods.html#method.eq - format!( - r##" - if let Some(filter_{column_name}) = filter.{column_name} {{ - query = if filter_{column_name}.is_some() {{ - query.filter({schema_path}{table_name}::{column_name}.eq(filter_{column_name})) - }} else {{ - query.filter({schema_path}{table_name}::{column_name}.is_null()) - }}; - }}"## - ) + quote! { + if let Some(#filter_ident) = filter.#column_name { + query = if #filter_ident.is_some() { + query.filter(#import_path_syn::#column_name.eq(#filter_ident)) + } else { + query.filter(#import_path_syn::#column_name.is_null()) + }; + } + } } else { - format!( - r##" - if let Some(filter_{column_name}) = filter.{column_name} {{ - query = query.filter({schema_path}{table_name}::{column_name}.eq(filter_{column_name})); - }}"## - ) + quote! { + if let Some(#filter_ident) = filter.#column_name { + query = query.filter(#import_path_syn::#column_name.eq(#filter_ident)); + } + } } }) - .collect::>() - .join(""); - buffer.push_str(&format!( - r##" - /// A utility function to help build custom search queries - /// - /// Example: - /// - /// ``` - /// // create a filter for completed todos - /// let query = Todo::filter(TodoFilter {{ - /// completed: Some(true), - /// ..Default::default() - /// }}); - /// - /// // delete completed todos - /// diesel::delete(query).execute(db)?; - /// ``` - pub fn filter<'a>( - filter: {struct_name}Filter, - ) -> {schema_path}{table_name}::BoxedQuery<'a, {diesel_backend}> {{ - let mut query = {schema_path}{table_name}::table.into_boxed(); - {filters} - - query - }} -"## + .collect::(); + + // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream + buffer.push('\n'); + let doc = formatdoc!( + r#" A utility function to help build custom search queries + + Example: + + ``` + // create a filter for completed todos + let query = Todo::filter(TodoFilter {{ + completed: Some(true), + ..Default::default() + }}); + + // delete completed todos + diesel::delete(query).execute(db)?; + ```"# + ); + let filter_struct = format_ident!("{struct_name}Filter"); + + let code = quote! { + #[doc = #doc] + pub fn filter<'a>( + filter: #filter_struct, + ) -> #import_path_syn::BoxedQuery<'a, #diesel_backend> { + let mut query = #import_path_syn::table.into_boxed(); + #filters + + query + } + }; + buffer.push_str(&indent( + &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), + 4, )); } @@ -684,13 +705,13 @@ fn build_table_fns( " Update a row in `{table_name}`, identified by the primary {key_maybe_multiple} with [`{update_struct_identifier}`]" ); let update_struct_identifier: Ident = - syn::parse_str(&update_struct_identifier).expect(SYN_PARSE_ERR); + syn::parse_str(update_struct_identifier).expect(SYN_PARSE_ERR); let code = quote! { #[doc = #doc] pub #async_keyword_syn fn update(db: &mut ConnectionType, #(#item_id_params_syn), *, item: &#update_struct_identifier) -> diesel::QueryResult { use #import_path_syn::dsl::*; - + diesel::update(#table_name_syn.#(#item_id_filters_syn).*).set(item).get_result(db)#await_keyword_syn } }; @@ -711,7 +732,7 @@ fn build_table_fns( #[doc = #doc] pub #async_keyword_syn fn delete(db: &mut ConnectionType, #(#item_id_params_syn), *) -> diesel::QueryResult { use #import_path_syn::dsl::*; - + diesel::delete(#table_name_syn.#(#item_id_filters_syn).*).execute(db)#await_keyword_syn } }; @@ -731,22 +752,29 @@ fn build_table_fns( .iter() .map(|column| { let struct_field = StructField::from(column); - format!( - "pub {column_name}: Option<{column_type}>,", - column_name = struct_field.name, - column_type = struct_field.to_rust_type() - ) + syn::Field::parse_named + .parse_str(&format!( + "pub {column_name}: Option<{column_type}>", + column_name = struct_field.name, + column_type = struct_field.to_rust_type() + )) + .expect(SYN_PARSE_ERR) }) - .collect::>() - .join("\n "); - - buffer.push_str(&formatdoc!( - r##" - #[derive(Debug, Default, Clone)] - pub struct {struct_name}Filter {{ - {filter_fields} - }} - "## + .collect::>(); + + // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream + buffer.push('\n'); + let filter_struct = format_ident!("{struct_name}Filter"); + + let code = quote! { + #[derive(Debug, Default, Clone)] + pub struct #filter_struct { + #(#filter_fields),* + } + }; + buffer.push_str(&indent( + &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), + 0, )); } diff --git a/test/advanced_queries/models/todos/generated.rs b/test/advanced_queries/models/todos/generated.rs index cd2c9c80..4c11a39b 100644 --- a/test/advanced_queries/models/todos/generated.rs +++ b/test/advanced_queries/models/todos/generated.rs @@ -82,55 +82,57 @@ impl Todos { /// Insert a new row into `todos` with a given [`CreateTodos`] pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { use crate::schema::todos::dsl::*; - diesel::insert_into(todos).values(item).get_result::(db) } /// Get a row from `todos`, identified by the primary key pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { use crate::schema::todos::dsl::*; - todos.filter(id.eq(param_id)).first::(db) } /// Paginates through the table where page is a 0-based index (i.e. page 0 is the first page) - pub fn paginate(db: &mut ConnectionType, page: i64, page_size: i64, filter: TodosFilter) -> diesel::QueryResult> { + pub fn paginate( + db: &mut ConnectionType, + page: i64, + page_size: i64, + filter: TodosFilter, + ) -> diesel::QueryResult> { use crate::schema::todos::dsl::*; - let page = page.max(0); let page_size = page_size.max(1); let total_items = Self::filter(filter.clone()).count().get_result(db)?; - let items = Self::filter(filter).limit(page_size).offset(page * page_size).load::(db)?; - + let items = Self::filter(filter) + .limit(page_size) + .offset(page * page_size) + .load::(db)?; Ok(PaginationResult { items, total_items, page, page_size, - /* ceiling division of integers */ - num_pages: total_items / page_size + i64::from(total_items % page_size != 0) + num_pages: total_items / page_size + i64::from(total_items % page_size != 0), }) } - /// A utility function to help build custom search queries - /// - /// Example: - /// - /// ``` - /// // create a filter for completed todos - /// let query = Todo::filter(TodoFilter { - /// completed: Some(true), - /// ..Default::default() - /// }); - /// - /// // delete completed todos - /// diesel::delete(query).execute(db)?; - /// ``` + /** A utility function to help build custom search queries + + Example: + + ``` + // create a filter for completed todos + let query = Todo::filter(TodoFilter { + completed: Some(true), + ..Default::default() + }); + + // delete completed todos + diesel::delete(query).execute(db)?; + ```*/ pub fn filter<'a>( filter: TodosFilter, ) -> crate::schema::todos::BoxedQuery<'a, diesel::pg::Pg> { let mut query = crate::schema::todos::table.into_boxed(); - if let Some(filter_id) = filter.id { query = query.filter(crate::schema::todos::id.eq(filter_id)); } @@ -155,24 +157,26 @@ impl Todos { if let Some(filter_updated_at) = filter.updated_at { query = query.filter(crate::schema::todos::updated_at.eq(filter_updated_at)); } - query } /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] - pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateTodos) -> diesel::QueryResult { + pub fn update( + db: &mut ConnectionType, + param_id: i32, + item: &UpdateTodos, + ) -> diesel::QueryResult { use crate::schema::todos::dsl::*; - diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) } /// Delete a row in `todos`, identified by the primary key pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { use crate::schema::todos::dsl::*; - diesel::delete(todos.filter(id.eq(param_id))).execute(db) } } + #[derive(Debug, Default, Clone)] pub struct TodosFilter { pub id: Option, From c82e39cda4607db29ef4bb2d2db230af9060ab1a Mon Sep 17 00:00:00 2001 From: hasezoey Date: Thu, 8 Feb 2024 18:12:20 +0100 Subject: [PATCH 8/9] refactor(code::build_table_fns): use quote part 5 (final) --- src/code.rs | 89 +++++-------------- .../models/todos/generated.rs | 38 ++++---- 2 files changed, 38 insertions(+), 89 deletions(-) diff --git a/src/code.rs b/src/code.rs index 0676d99a..f52e6aef 100644 --- a/src/code.rs +++ b/src/code.rs @@ -428,19 +428,6 @@ fn get_async(table_options: &TableOptions<'_>) -> (&'static str, &'static str) { ("", "") } -/// Debug function to indent [prettyplease] output again to match surrounding code -/// always adds a newline at the end of each line -// DEBUG: this function is only for transitional from string to tokenstream -fn indent(str: &str, by: usize) -> String { - let mut string = String::with_capacity(str.len() + by); - - for line in str.lines() { - string.push_str(&format!("{:by$}{line}\n", "")) - } - - string -} - /// Common error text for `syn::parse2().expect()` /// NOTE: This should be removed again and is only temporary for transition const SYN_PARSE_ERR: &str = "Expected syn to parse static input"; @@ -496,20 +483,22 @@ fn build_table_fns( let (async_keyword, await_keyword) = get_async(&table_options); let struct_name = &table.struct_name; + let struct_name_syn: proc_macro2::Ident = syn::parse_str(struct_name).expect(SYN_PARSE_ERR); let schema_path = config.get_schema_path(); let create_struct_identifier = &create_struct.identifier; let update_struct_identifier = &update_struct.identifier; let is_readonly = table_options.get_readonly(); - let mut buffer = String::new(); + let mut buffer_main = TokenStream::new(); + let mut buffer_impl = TokenStream::new(); if !config.get_once_common_structs() { - buffer.push_str(&generate_common_structs(&table_options)); - buffer.push('\n'); + buffer_main.extend( + syn::parse_str::(&generate_common_structs(&table_options)) + .expect(SYN_PARSE_ERR), + ); } - buffer.push_str(&format!("impl {struct_name} {{")); - // the following section is for quote variables let import_path_syn: syn::Path = syn::parse_str(&format!("{schema_path}{table_name}")).expect(SYN_PARSE_ERR); @@ -519,8 +508,6 @@ fn build_table_fns( if !is_readonly { if create_struct.has_fields() { - // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream - buffer.push('\n'); let doc = format!( " Insert a new row into `{table_name}` with a given [`{create_struct_identifier}`]" ); @@ -535,13 +522,8 @@ fn build_table_fns( diesel::insert_into(#table_name_syn).values(item).get_result::(db)#await_keyword_syn } }; - buffer.push_str(&indent( - &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), - 4, - )); + buffer_impl.extend(code); } else { - // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream - buffer.push('\n'); let doc = format!(" Insert a new row into `{table_name}` with all default values"); let code = quote! { @@ -552,10 +534,7 @@ fn build_table_fns( diesel::insert_into(#table_name_syn).default_values().get_result::(db)#await_keyword_syn } }; - buffer.push_str(&indent( - &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), - 4, - )); + buffer_impl.extend(code); } } @@ -567,8 +546,6 @@ fn build_table_fns( }; { - // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream - buffer.push('\n'); let doc = format!( " Get a row from `{table_name}`, identified by the primary {key_maybe_multiple}" ); @@ -581,16 +558,11 @@ fn build_table_fns( #table_name_syn.#(#item_id_filters_syn).*.first::(db)#await_keyword_syn } }; - buffer.push_str(&indent( - &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), - 4, - )); + buffer_impl.extend(code); } #[cfg(feature = "advanced-queries")] { - // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream - buffer.push('\n'); let doc = " Paginates through the table where page is a 0-based index (i.e. page 0 is the first page)"; let filter_struct = format_ident!("{struct_name}Filter"); @@ -614,10 +586,7 @@ fn build_table_fns( }) } }; - buffer.push_str(&indent( - &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), - 4, - )); + buffer_impl.extend(code); } #[cfg(feature = "advanced-queries")] @@ -653,8 +622,6 @@ fn build_table_fns( }) .collect::(); - // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream - buffer.push('\n'); let doc = formatdoc!( r#" A utility function to help build custom search queries @@ -684,10 +651,7 @@ fn build_table_fns( query } }; - buffer.push_str(&indent( - &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), - 4, - )); + buffer_impl.extend(code); } // TODO: If primary key columns are attached to the form struct (not optionally) @@ -699,8 +663,6 @@ fn build_table_fns( // In this scenario, we also have to check whether there are any updatable columns for which // we should generate an update() method. - // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream - buffer.push('\n'); let doc = format!( " Update a row in `{table_name}`, identified by the primary {key_maybe_multiple} with [`{update_struct_identifier}`]" ); @@ -715,15 +677,10 @@ fn build_table_fns( diesel::update(#table_name_syn.#(#item_id_filters_syn).*).set(item).get_result(db)#await_keyword_syn } }; - buffer.push_str(&indent( - &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), - 4, - )); + buffer_impl.extend(code); } if !is_readonly { - // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream - buffer.push('\n'); let doc = format!( " Delete a row in `{table_name}`, identified by the primary {key_maybe_multiple}" ); @@ -736,13 +693,14 @@ fn build_table_fns( diesel::delete(#table_name_syn.#(#item_id_filters_syn).*).execute(db)#await_keyword_syn } }; - buffer.push_str(&indent( - &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), - 4, - )); + buffer_impl.extend(code); } - buffer.push_str("}\n"); + buffer_main.extend(quote! { + impl #struct_name_syn { + #buffer_impl + } + }); #[cfg(feature = "advanced-queries")] // generate filter struct for filter() helper function @@ -762,8 +720,6 @@ fn build_table_fns( }) .collect::>(); - // DEBUG: debug newline, previous code had newlines, will stay until buffer is converted to stream - buffer.push('\n'); let filter_struct = format_ident!("{struct_name}Filter"); let code = quote! { @@ -772,13 +728,10 @@ fn build_table_fns( #(#filter_fields),* } }; - buffer.push_str(&indent( - &prettyplease::unparse(&syn::parse2(code).expect(SYN_PARSE_ERR)), - 0, - )); + buffer_main.extend(code); } - buffer + prettyplease::unparse(&syn::parse2(buffer_main).expect(SYN_PARSE_ERR)) } /// Generate common structs diff --git a/test/advanced_queries/models/todos/generated.rs b/test/advanced_queries/models/todos/generated.rs index 4c11a39b..278fdcae 100644 --- a/test/advanced_queries/models/todos/generated.rs +++ b/test/advanced_queries/models/todos/generated.rs @@ -77,20 +77,20 @@ pub struct PaginationResult { /// Number of total possible pages, given the `page_size` and `total_items` pub num_pages: i64, } - impl Todos { /// Insert a new row into `todos` with a given [`CreateTodos`] - pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { + pub fn create( + db: &mut ConnectionType, + item: &CreateTodos, + ) -> diesel::QueryResult { use crate::schema::todos::dsl::*; diesel::insert_into(todos).values(item).get_result::(db) } - /// Get a row from `todos`, identified by the primary key pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { use crate::schema::todos::dsl::*; todos.filter(id.eq(param_id)).first::(db) } - /// Paginates through the table where page is a 0-based index (i.e. page 0 is the first page) pub fn paginate( db: &mut ConnectionType, @@ -114,21 +114,20 @@ impl Todos { num_pages: total_items / page_size + i64::from(total_items % page_size != 0), }) } - /** A utility function to help build custom search queries - - Example: - - ``` - // create a filter for completed todos - let query = Todo::filter(TodoFilter { - completed: Some(true), - ..Default::default() - }); - - // delete completed todos - diesel::delete(query).execute(db)?; - ```*/ + +Example: + +``` +// create a filter for completed todos +let query = Todo::filter(TodoFilter { + completed: Some(true), + ..Default::default() +}); + +// delete completed todos +diesel::delete(query).execute(db)?; +```*/ pub fn filter<'a>( filter: TodosFilter, ) -> crate::schema::todos::BoxedQuery<'a, diesel::pg::Pg> { @@ -159,7 +158,6 @@ impl Todos { } query } - /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] pub fn update( db: &mut ConnectionType, @@ -169,14 +167,12 @@ impl Todos { use crate::schema::todos::dsl::*; diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) } - /// Delete a row in `todos`, identified by the primary key pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { use crate::schema::todos::dsl::*; diesel::delete(todos.filter(id.eq(param_id))).execute(db) } } - #[derive(Debug, Default, Clone)] pub struct TodosFilter { pub id: Option, From 8b7e3426aafac7db7c896ba4a8b3c3b48bdbe95c Mon Sep 17 00:00:00 2001 From: hasezoey Date: Thu, 8 Feb 2024 18:13:15 +0100 Subject: [PATCH 9/9] test: WIP: format too --- test/simple_table_pg/models/todos/generated.rs | 9 ++++----- test/simple_table_pg/models/todos2/generated.rs | 3 --- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/test/simple_table_pg/models/todos/generated.rs b/test/simple_table_pg/models/todos/generated.rs index 06a984a9..272d153a 100644 --- a/test/simple_table_pg/models/todos/generated.rs +++ b/test/simple_table_pg/models/todos/generated.rs @@ -77,20 +77,20 @@ pub struct PaginationResult { /// Number of total possible pages, given the `page_size` and `total_items` pub num_pages: i64, } - impl Todos { /// Insert a new row into `todos` with a given [`CreateTodos`] - pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { + pub fn create( + db: &mut ConnectionType, + item: &CreateTodos, + ) -> diesel::QueryResult { use crate::schema::todos::dsl::*; diesel::insert_into(todos).values(item).get_result::(db) } - /// Get a row from `todos`, identified by the primary key pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { use crate::schema::todos::dsl::*; todos.filter(id.eq(param_id)).first::(db) } - /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] pub fn update( db: &mut ConnectionType, @@ -100,7 +100,6 @@ impl Todos { use crate::schema::todos::dsl::*; diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) } - /// Delete a row in `todos`, identified by the primary key pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { use crate::schema::todos::dsl::*; diff --git a/test/simple_table_pg/models/todos2/generated.rs b/test/simple_table_pg/models/todos2/generated.rs index 4613c2f6..3ed0c434 100644 --- a/test/simple_table_pg/models/todos2/generated.rs +++ b/test/simple_table_pg/models/todos2/generated.rs @@ -27,20 +27,17 @@ pub struct PaginationResult { /// Number of total possible pages, given the `page_size` and `total_items` pub num_pages: i64, } - impl Todos2 { /// Insert a new row into `todos2` with all default values pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { use crate::schema::todos2::dsl::*; diesel::insert_into(todos2).default_values().get_result::(db) } - /// Get a row from `todos2`, identified by the primary key pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { use crate::schema::todos2::dsl::*; todos2.filter(id.eq(param_id)).first::(db) } - /// Delete a row in `todos2`, identified by the primary key pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { use crate::schema::todos2::dsl::*;