Skip to content

Commit 5409cd1

Browse files
authored
Refactors-and-upgrades (#36)
* Cleaning the Result error handling by applying the operator ? whenever is possible * Refactored the parsing of the canyon entity macro
1 parent c82a8af commit 5409cd1

8 files changed

Lines changed: 169 additions & 220 deletions

File tree

canyon_crud/src/crud.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ mod postgres_query_launcher {
164164

165165
pub async fn launch<'a, T>(
166166
db_conn: &DatabaseConnection,
167-
// datasource_name: &str,
168167
stmt: String,
169168
params: &'a [&'_ dyn QueryParameter<'_>],
170169
) -> Result<DatabaseResult<T>, Box<(dyn std::error::Error + Send + Sync + 'static)>> {
@@ -173,21 +172,15 @@ mod postgres_query_launcher {
173172
m_params.push(param.as_postgres_param());
174173
}
175174

176-
let query_result = db_conn
177-
.postgres_connection
178-
.as_ref()
179-
.unwrap()
180-
.client
181-
.query(&stmt, m_params.as_slice())
182-
.await;
183-
184-
if let Err(error) = query_result {
185-
Err(Box::new(error))
186-
} else {
187-
Ok(DatabaseResult::new_postgresql(
188-
query_result.expect("A really bad error happened querying PostgreSQL"),
189-
))
190-
}
175+
Ok(DatabaseResult::new_postgresql(
176+
db_conn
177+
.postgres_connection
178+
.as_ref()
179+
.unwrap()
180+
.client
181+
.query(&stmt, m_params.as_slice())
182+
.await?,
183+
))
191184
}
192185
}
193186

canyon_crud/src/query_elements/query_builder.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -163,25 +163,18 @@ where
163163

164164
/// Launches the generated query against the database targeted
165165
/// by the selected datasource
166-
#[allow(clippy::question_mark)]
167166
pub async fn query(
168167
&'a mut self,
169168
) -> Result<Vec<T>, Box<(dyn std::error::Error + Sync + Send + 'static)>> {
170-
// Close the query, we are ready to go
171169
self.query.sql.push(';');
172170

173-
let result = T::query(
171+
Ok(T::query(
174172
self.query.sql.clone(),
175173
self.query.params.to_vec(),
176174
self.datasource_name,
177175
)
178-
.await;
179-
180-
if let Err(error) = result {
181-
Err(error)
182-
} else {
183-
Ok(result.ok().unwrap().get_entities::<T>())
184-
}
176+
.await?
177+
.get_entities::<T>())
185178
}
186179

187180
pub fn r#where<Z: FieldValueIdentifier<'a, T>>(&mut self, r#where: Z, op: impl Operator) {
@@ -511,8 +504,7 @@ where
511504
)
512505
}
513506

514-
let cap = columns.len() * 50; // Reserving an enough initial capacity per set clause
515-
let mut set_clause = String::with_capacity(cap);
507+
let mut set_clause = String::new();
516508
set_clause.push_str(" SET ");
517509

518510
for (idx, column) in columns.iter().enumerate() {
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use proc_macro2::{Span, TokenStream};
2+
use syn::NestedMeta;
3+
4+
pub(crate) fn parse_canyon_entity_proc_macro_attr(
5+
attrs: Vec<NestedMeta>,
6+
) -> (
7+
Option<&'static str>,
8+
Option<&'static str>,
9+
Option<TokenStream>,
10+
) {
11+
let mut table_name: Option<&str> = None;
12+
let mut schema_name: Option<&str> = None;
13+
14+
let mut parsing_attribute_error: Option<TokenStream> = None;
15+
16+
// The parse of the available options to configure the Canyon Entity
17+
for element in attrs {
18+
match element {
19+
syn::NestedMeta::Meta(m) => {
20+
match m {
21+
syn::Meta::NameValue(nv) => {
22+
let attr_arg_ident = nv
23+
.path
24+
.get_ident()
25+
.expect("Something went wrong parsing the `table_name` argument")
26+
.to_string();
27+
28+
if &attr_arg_ident == "table_name" || &attr_arg_ident == "schema" {
29+
match nv.lit {
30+
syn::Lit::Str(ref l) => {
31+
if &attr_arg_ident == "table_name" {
32+
table_name = Some(Box::leak(l.value().into_boxed_str()))
33+
} else {
34+
schema_name = Some(Box::leak(l.value().into_boxed_str()))
35+
}
36+
}
37+
_ => {
38+
parsing_attribute_error = Some(syn::Error::new(
39+
Span::call_site(),
40+
"Only string literals are valid values for the attributes"
41+
).into_compile_error());
42+
}
43+
}
44+
} else {
45+
parsing_attribute_error = Some(
46+
syn::Error::new(
47+
Span::call_site(),
48+
format!(
49+
"Argument: `{:?}` are not allowed in the canyon_macro attr",
50+
&attr_arg_ident
51+
),
52+
)
53+
.into_compile_error(),
54+
);
55+
}
56+
}
57+
_ => {
58+
parsing_attribute_error = Some(syn::Error::new(
59+
Span::call_site(),
60+
"Only argument identifiers with a value after an `=` sign are allowed on the `canyon_macros::canyon_entity` proc macro"
61+
).into_compile_error());
62+
}
63+
}
64+
}
65+
syn::NestedMeta::Lit(_) => {
66+
parsing_attribute_error = Some(syn::Error::new(
67+
Span::call_site(),
68+
"No literal values allowed on the `canyon_macros::canyon_entity` proc macro"
69+
).into_compile_error());
70+
}
71+
}
72+
}
73+
74+
(table_name, schema_name, parsing_attribute_error)
75+
}

canyon_macros/src/lib.rs

Lines changed: 5 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
extern crate proc_macro;
22

3+
mod canyon_entity_macro;
34
mod canyon_macro;
45
mod query_operations;
56
mod utils;
67

78
use canyon_connection::CANYON_TOKIO_RUNTIME;
8-
use proc_macro::{Span, TokenStream as CompilerTokenStream};
9+
use canyon_entity_macro::parse_canyon_entity_proc_macro_attr;
10+
use proc_macro::TokenStream as CompilerTokenStream;
911
use proc_macro2::{Ident, TokenStream};
1012
use quote::{quote, ToTokens};
1113
use syn::{DeriveInput, Fields, Type, Visibility};
@@ -179,68 +181,8 @@ pub fn canyon_entity(
179181
) -> CompilerTokenStream {
180182
let attrs = syn::parse_macro_input!(_meta as syn::AttributeArgs);
181183

182-
let mut table_name: Option<&str> = None;
183-
let mut schema_name: Option<&str> = None;
184-
185-
let mut parsing_attribute_error: Option<TokenStream> = None;
186-
187-
// The parse of the available options to configure the Canyon Entity
188-
for element in &attrs {
189-
match element {
190-
syn::NestedMeta::Meta(m) => {
191-
match m {
192-
syn::Meta::NameValue(nv) => {
193-
let attr_arg_ident = nv
194-
.path
195-
.get_ident()
196-
.expect("Something went wrong parsing the `table_name` argument")
197-
.to_string();
198-
199-
if &attr_arg_ident == "table_name" || &attr_arg_ident == "schema" {
200-
match nv.lit {
201-
syn::Lit::Str(ref l) => {
202-
if &attr_arg_ident == "table_name" {
203-
table_name = Some(Box::leak(l.value().into_boxed_str()))
204-
} else {
205-
schema_name = Some(Box::leak(l.value().into_boxed_str()))
206-
}
207-
}
208-
_ => {
209-
parsing_attribute_error = Some(syn::Error::new(
210-
Span::call_site().into(),
211-
"Only string literals are valid values for the attributes"
212-
).into_compile_error());
213-
}
214-
}
215-
} else {
216-
parsing_attribute_error = Some(
217-
syn::Error::new(
218-
Span::call_site().into(),
219-
format!(
220-
"Argument: `{:?}` are not allowed in the canyon_macro attr",
221-
&attr_arg_ident
222-
),
223-
)
224-
.into_compile_error(),
225-
);
226-
}
227-
}
228-
_ => {
229-
parsing_attribute_error = Some(syn::Error::new(
230-
Span::call_site().into(),
231-
"Only argument identifiers with a value after an `=` sign are allowed on the `canyon_macros::canyon_entity` proc macro"
232-
).into_compile_error());
233-
}
234-
}
235-
}
236-
syn::NestedMeta::Lit(_) => {
237-
parsing_attribute_error = Some(syn::Error::new(
238-
Span::call_site().into(),
239-
"No literal values allowed on the `canyon_macros::canyon_entity` proc macro"
240-
).into_compile_error());
241-
}
242-
}
243-
}
184+
let (table_name, schema_name, parsing_attribute_error) =
185+
parse_canyon_entity_proc_macro_attr(attrs);
244186

245187
let entity_res = syn::parse::<CanyonEntity>(input);
246188

canyon_macros/src/query_operations/delete.rs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,13 @@ pub fn generate_delete_tokens(macro_data: &MacroTokens, table_schema_data: &Stri
2626
/// the current instance of a T type, returning a result
2727
/// indicating a possible failure querying the database.
2828
async fn delete(&self) -> Result<(), Box<(dyn std::error::Error + Send + Sync + 'static)>> {
29-
let stmt = format!("DELETE FROM {} WHERE {:?} = $1", #table_schema_data, #primary_key);
30-
31-
let result = <#ty as canyon_sql::crud::Transaction<#ty>>::query(
32-
stmt,
29+
<#ty as canyon_sql::crud::Transaction<#ty>>::query(
30+
format!("DELETE FROM {} WHERE {:?} = $1", #table_schema_data, #primary_key),
3331
&[#pk_field_value],
3432
""
35-
).await;
33+
).await?;
3634

37-
if let Err(error) = result {
38-
Err(error)
39-
} else { Ok(()) }
35+
Ok(())
4036
}
4137

4238
/// Deletes from a database entity the row that matches
@@ -45,17 +41,13 @@ pub fn generate_delete_tokens(macro_data: &MacroTokens, table_schema_data: &Stri
4541
async fn delete_datasource<'a>(&self, datasource_name: &'a str)
4642
-> Result<(), Box<(dyn std::error::Error + Send + Sync + 'static)>>
4743
{
48-
let stmt = format!("DELETE FROM {} WHERE {:?} = $1", #table_schema_data, #primary_key);
49-
50-
let result = <#ty as canyon_sql::crud::Transaction<#ty>>::query(
51-
stmt,
44+
<#ty as canyon_sql::crud::Transaction<#ty>>::query(
45+
format!("DELETE FROM {} WHERE {:?} = $1", #table_schema_data, #primary_key),
5246
&[#pk_field_value],
5347
datasource_name
54-
).await;
48+
).await?;
5549

56-
if let Err(error) = result {
57-
Err(error)
58-
} else { Ok(()) }
50+
Ok(())
5951
}
6052
}
6153
} else {

canyon_macros/src/query_operations/insert.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,13 @@ pub fn generate_insert_tokens(macro_data: &MacroTokens, table_schema_data: &Stri
9191
#primary_key
9292
);
9393

94-
let result = <#ty as canyon_sql::crud::Transaction<#ty>>::query(
94+
<#ty as canyon_sql::crud::Transaction<#ty>>::query(
9595
stmt,
9696
values,
9797
datasource_name
98-
).await;
98+
).await?;
9999

100-
if let Err(error) = result {
101-
Err(error)
102-
} else {
103-
Ok(())
104-
}
100+
Ok(())
105101
}
106102
};
107103

0 commit comments

Comments
 (0)