From 85bbe5ab78e716e2d00aa6d947a79d03464efd20 Mon Sep 17 00:00:00 2001 From: meh Date: Wed, 15 Apr 2020 20:23:48 +0200 Subject: [PATCH] Add query_unchecked and query_file_unchecked macros --- sqlx-macros/src/lib.rs | 18 +++++++++-- sqlx-macros/src/query_macros/mod.rs | 3 +- sqlx-macros/src/query_macros/query.rs | 12 ++++++-- src/macros.rs | 44 +++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/sqlx-macros/src/lib.rs b/sqlx-macros/src/lib.rs index 5acd6436f5..f6d225dc97 100644 --- a/sqlx-macros/src/lib.rs +++ b/sqlx-macros/src/lib.rs @@ -127,14 +127,28 @@ macro_rules! async_macro ( #[allow(unused_variables)] pub fn query(input: TokenStream) -> TokenStream { #[allow(unused_variables)] - async_macro!(db, input: QueryMacroInput => expand_query(input, db)) + async_macro!(db, input: QueryMacroInput => expand_query(input, db, true)) +} + +#[proc_macro] +#[allow(unused_variables)] +pub fn query_unchecked(input: TokenStream) -> TokenStream { + #[allow(unused_variables)] + async_macro!(db, input: QueryMacroInput => expand_query(input, db, false)) } #[proc_macro] #[allow(unused_variables)] pub fn query_file(input: TokenStream) -> TokenStream { #[allow(unused_variables)] - async_macro!(db, input: QueryMacroInput => expand_query_file(input, db)) + async_macro!(db, input: QueryMacroInput => expand_query_file(input, db, true)) +} + +#[proc_macro] +#[allow(unused_variables)] +pub fn query_file_unchecked(input: TokenStream) -> TokenStream { + #[allow(unused_variables)] + async_macro!(db, input: QueryMacroInput => expand_query_file(input, db, false)) } #[proc_macro] diff --git a/sqlx-macros/src/query_macros/mod.rs b/sqlx-macros/src/query_macros/mod.rs index 8eb2c52fec..e2eeca7bb2 100644 --- a/sqlx-macros/src/query_macros/mod.rs +++ b/sqlx-macros/src/query_macros/mod.rs @@ -19,12 +19,13 @@ mod query; pub async fn expand_query_file( input: QueryMacroInput, conn: C, + checked: bool, ) -> crate::Result where C::Database: DatabaseExt + Sized, ::TypeInfo: Display, { - expand_query(input.expand_file_src().await?, conn).await + expand_query(input.expand_file_src().await?, conn, checked).await } pub async fn expand_query_as( diff --git a/sqlx-macros/src/query_macros/query.rs b/sqlx-macros/src/query_macros/query.rs index e913fec8b3..5400406720 100644 --- a/sqlx-macros/src/query_macros/query.rs +++ b/sqlx-macros/src/query_macros/query.rs @@ -15,6 +15,7 @@ use crate::database::DatabaseExt; pub async fn expand_query( input: QueryMacroInput, mut conn: C, + checked: bool, ) -> crate::Result where C::Database: DatabaseExt + Sized, @@ -23,7 +24,7 @@ where let describe = input.describe_validate(&mut conn).await?; let sql = &input.source; - let args = args::quote_args(&input, &describe, true)?; + let args = args::quote_args(&input, &describe, checked)?; let arg_names = &input.arg_names; let db_path = ::db_path(); @@ -57,8 +58,13 @@ where .collect::(); let query_args = format_ident!("query_args"); - let output = - output::quote_query_as::(sql, &record_type, &query_args, &columns, true); + let output = output::quote_query_as::( + sql, + &record_type, + &query_args, + if checked { &columns } else { &[] }, + checked, + ); Ok(quote! { macro_rules! macro_result { diff --git a/src/macros.rs b/src/macros.rs index c50a3aa5fb..ade4105ba2 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -135,6 +135,29 @@ macro_rules! query ( }) ); +/// A variant of [query!] which does not check the input or output types. This still does parse +/// the query to ensure it's syntactically and semantically valid for the current database. +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "macros")))] +macro_rules! query_unchecked ( + // by emitting a macro definition from our proc-macro containing the result tokens, + // we no longer have a need for `proc-macro-hack` + ($query:literal) => ({ + #[macro_use] + mod _macro_result { + $crate::sqlx_macros::query_unchecked!($query); + } + macro_result!() + }); + ($query:literal, $($args:expr),*$(,)?) => ({ + #[macro_use] + mod _macro_result { + $crate::sqlx_macros::query_unchecked!($query, $($args),*); + } + macro_result!($($args),*) + }) +); + /// A variant of [query!] where the SQL query is stored in a separate file. /// /// Useful for large queries and potentially cleaner than multiline strings. @@ -196,6 +219,27 @@ macro_rules! query_file ( }) ); +/// A variant of [query_file!] which does not check the input or output types. This still does parse +/// the query to ensure it's syntactically and semantically valid for the current database. +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "macros")))] +macro_rules! query_file_unchecked ( + ($query:literal) => (#[allow(dead_code)]{ + #[macro_use] + mod _macro_result { + $crate::sqlx_macros::query_file_unchecked!($query); + } + macro_result!() + }); + ($query:literal, $($args:expr),*$(,)?) => (#[allow(dead_code)]{ + #[macro_use] + mod _macro_result { + $crate::sqlx_macros::query_file_unchecked!($query, $($args),*); + } + macro_result!($($args),*) + }) +); + /// A variant of [query!] which takes a path to an explicitly defined struct as the output type. /// /// This lets you return the struct from a function or add your own trait implementations.